pax_global_header00006660000000000000000000000064114266664060014525gustar00rootroot0000000000000052 comment=cee42e46c71241eb317f52e8bfd1205651a703bd jansi-1.4/000077500000000000000000000000001142666640600124755ustar00rootroot00000000000000jansi-1.4/.gitignore000066400000000000000000000001111142666640600144560ustar00rootroot00000000000000.classpath .project .settings docs/out docs/webgen.cache target .DS_Storejansi-1.4/KEYS000066400000000000000000000030771142666640600132020ustar00rootroot00000000000000pub 1024D/F5BA7E4F 2006-02-10 uid Hiram Chirino sig 3 F5BA7E4F 2006-02-10 Hiram Chirino sub 1024g/6733C080 2006-02-10 sig F5BA7E4F 2006-02-10 Hiram Chirino -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.1 (Darwin) mQGiBEPspSsRBADdguKAxMQbA32vTQrCyONR6Zs/YGdvau2Zrr3SSSSR0Ge4FMjZ 4tzwpf6+32m4Bsf7YIwdLl0H5hI1CgT5gDl9kXvfaFUehFnwR+FDyiBRiyHjUpGF 4dgkQfWy9diYeWGtsvszsvWHXtED4SXb322StX4MfJj+YesA1iEdTiXK6wCg1QDa RucfjC+kx4zPsJwkJOgYpyMEAMTiXtNwQcke6nIFb/lb5374NjwwVAuuMTrRWLyq 5HodugEIHaw3EitQWtnFfXNkXTJZzS6t2HAGv29UTfhiBzKdkydgCkOk2MLWISOV fqcg0tNIp5ZJCmUHg3s+OFNSH4oUi65u+FyDseUid3OKtPI+ZhIk8N+DjOIg2Kvo /UALA/9q+WfBd7re+W3iUtU7TutUcwbKsjP+jpaJeUHg2ChOBxVfQKt4YlPHVdrR iCrfNi90Z8qbsZ0iAXuqexrfMq20pAPmpHRpe54mmP1CMT5m+Gq71eKIfkUrb3LC /zv08dLG2vm9oghd242wbcifaX+t7AhNAIpe/WTvQsB0gpdO4LQmSGlyYW0gQ2hp cmlubyA8aGlyYW1AaGlyYW1jaGlyaW5vLmNvbT6IWwQTEQIAGwUCQ+ylKwYLCQgH AwIDFQIDAxYCAQIeAQIXgAAKCRCf8lmA9bp+T/G/AKDM1QDs7il/CJhTycgDvE3c EOgUBwCfelsVK4sgBCooZptoaCCDgVtt71G5AQ0EQ+ylLhAEAJD25AWgwcNgBFKY svExQaGIojIGJyn4Cf/5U30cui/K7fIU7JtyNhKcfZdCrh2hKx+x3H/dTF6e0SrR hzKV7Dx0j76yhHHB1Ak25kjRxoU4Jk+CG0m+bRNTF9xz9k1ALSm3Y+A5RqNU10K6 e/5KsPuXMGSGoQgJ1H6g/i80Wf8PAAMFA/9mIxu7lMaqE1OE7EeAsHgLslNbi0h9 pjDUVNv8bc1Os2gBPaJD8B89EeheTHw6NMNIe75HVOpKk4UA0gvOBrxJqCr18yFJ BM5sIlaEmuJwZOW4dDGOR1oS5qgE9NzpmyKhE+fu/S1wmy0coL667+1xZcnrPbUF D4i7/aD1r8qJhohGBBgRAgAGBQJD7KUuAAoJEJ/yWYD1un5Pth0An0QEUs5cxpl8 zL5kZCj7c8MN8YZDAKDR9LTb6woveul50+uGtUl2fIH1uA== =RBPl -----END PGP PUBLIC KEY BLOCK-----jansi-1.4/changelog.md000066400000000000000000000040771142666640600147560ustar00rootroot00000000000000# ![Jansi][logo] [logo]: http://jansi.fusesource.org/images/project-logo.png "Jansi" ## [Jansi 1.4][1_4], released 2010-07-15 [1_4]: http://repo.fusesource.com/nexus/content/groups/public/org/fusesource/jansi/jansi/1.4 * JNI libs are now bundled in the jansi jar * Windows: added support for save and restore of cursor position ## [Jansi 1.3][1_3], released 2010-03-08 [1_3]: http://repo.fusesource.com/nexus/content/groups/public/org/fusesource/jansi/jansi/1.3 * Switched to a HawtJNI generated native library instead of using JNA to access native functions ## [Jansi 1.2.1][1_2_1], released 2010-03-08 [1_2_1]: http://repo.fusesource.com/nexus/content/groups/public/org/fusesource/jansi/jansi/1.2.1 * Released to Maven Central ## [Jansi 1.2][1_2], released 2010-02-09 [1_2]: http://jansi.fusesource.org/repo/release/org/fusesource/jansi/jansi/1.2 * Improved Java Docs * Better windows ansi handling of: erase screen and line and move to col * new method: Ansi.newline() * Fixed missing return statement in cursor up case.. * Reset the attributes when the ansi output stream is closed on unix. ## [Jansi 1.1][1_1], released 2009-11-23 [1_1]: http://jansi.fusesource.org/repo/release/org/fusesource/jansi/jansi/1.1 * AnsiRender can now be used in a static way and made easier to use with the Ansi builder. * Merged [Jason Dillon's Fork](http://github.com/jdillon/jansi/tree/bb86e0e79bec850167ddfd8c4a86fb9ffef704e5): * Pluggable ASNI support detection * ANSI builder can be configured to not generate ANSI escapes. * AnsiRender provides an easier way to generate escape sequences. * [JANSI-5](http://fusesource.com/issues/browse/JANSI-5): Attribute Reset escape should respect original console colors * [JANSI-4](http://fusesource.com/issues/browse/JANSI-4): Restore command console after closing wrapped OutputStream on Windows. * [JANSI-1](http://fusesource.com/issues/browse/JANSI-1): Added extensions for colors and other attributes to Ansi builder. ## [Jansi 1.0][1_0], released 2009-08-25 [1_0]: http://jansi.fusesource.org/repo/release/org/fusesource/jansi/jansi/1.0 * Initial Release jansi-1.4/docs/000077500000000000000000000000001142666640600134255ustar00rootroot00000000000000jansi-1.4/docs/README000077500000000000000000000024761142666640600143210ustar00rootroot00000000000000--- # Copyright (C) 2009, Progress Software Corporation and/or its # subsidiaries or affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. title: Generating the Docs --- Overview ============================= We are using [webgen](http://webgen.rubyforge.org/) for generating nice HTML based documentation. Installing ----------------------------- You first need ruby and rubygems installed on your system. You should have gems version of 1.3.4 or greater. You can check this via gem --version To update gems do gem update --system Then you can install webgen with the following command. `sudo gem install webgen coderay feedtools haml RedCloth` Building ----------------------------- It's as simple as running `webgen` in the current directory. Output is stored in the `out` directory. jansi-1.4/docs/config.yaml000066400000000000000000000016211142666640600155560ustar00rootroot00000000000000# Copyright (C) 2009, Progress Software Corporation and/or its # subsidiaries or affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # The available configuration options can be listed using the `webgen config` # command, for example: `webgen config sourcehandler` will list all options starting # with sourcehandler. # lets turn off line numbers tag.coderay.line_numbers: false jansi-1.4/docs/src/000077500000000000000000000000001142666640600142145ustar00rootroot00000000000000jansi-1.4/docs/src/downloads/000077500000000000000000000000001142666640600162065ustar00rootroot00000000000000jansi-1.4/docs/src/downloads/index.page000066400000000000000000000040311142666640600201510ustar00rootroot00000000000000--- # Copyright (C) 2009, Progress Software Corporation and/or its # subsidiaries or affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. title: Downloads in_menu: true sort_info: 1 --- name:overview # {project_name:} Download it Today! --- name:content pipeline:haml,tags .left %h1 Just need a jar? .right The latest released version is {project_version:}: %ul %li %a{:href => "http://repo.fusesource.com/nexus/content/repositories/releases-to-central/org/fusesource/{project_id:}/{project_id:}/{project_version:}/{project_id:}-{project_version:}.jar"} {project_id:}-{project_version:}.jar .left %h1 Are you a Maven User? .right :markdown Just the following to your `pom.xml` file: :plain {coderay:: xml} org.fusesource.{project_id:} {project_id:} {project_version:} {coderay} %h3 Building Against Snapshots :markdown If you want to run against a SNAPSHOT which has not made it into the maven central repository, just add the Fusesource snapshot repository to your `pom.xml` file: :plain {coderay:: xml} fusesource.snapshot http://repo.fusesource.com/nexus/content/repositories/snapshots/ true false {coderay} jansi-1.4/docs/src/images/000077500000000000000000000000001142666640600154615ustar00rootroot00000000000000jansi-1.4/docs/src/images/after-jansi-windows.png000066400000000000000000000154211142666640600220650ustar00rootroot00000000000000PNG  IHDRƎ#IDATx\qƇC 2!t2`J(ACXI, Je!q(@$DJ"s! # yYr ښ^޼vWW}U뷥Y`0wop';/vṕ!Rh輚  0  j<d[]]u,$!`v^ROv.r]dT 245qHeG G%lXYlYis eLHYe㦼TND̴TU0)2^0Umá^-|5gN>eV[8V\ܵwMGMς #B?sqM 'S9<E쿄<+m  f yο7^T'EX($@?__<'  LRrV?_3O;2:Ʃ%ϣ9Í6.?qHJOogOaY@yxHlS[|Wv~2Xj w_l+'p&  O 'lW:[v3+;o﴾P 5yySߧe9詻ngQqkq񭥗I#g?;/m,7ٵ;ׇ:H[]<{nt.mک B,186O}ˣ;Ii廧џço/+=sՋ⟹Pa+#/|Jѕ?}ׯ@OT}&K}/3:@~ g7NƓW]2xg 7/\{6E߿4xnds āߙ]9;Zxs`w>ޥۍ6~85>yK7P}o_PwW.NtWo⻛.rR:_O쬟o<%n>L v^[҂wH~`0|a{oyO4m{GGVGϧkG]סqae5+|ⳏ=c/~;[n:sb:|]\zG>˧]^zvGGgNI'_=A[[,=6*~8޸5/QlI)@/D<_8ڼɛ&vJg szq_i@۝p  A3/7Ynqyed}ۇ/{Skg~gOhɊ-^JLOerWzQM=ml:weV :)y}K)@:/>R﮼󲖵sZK,z8m=xMis[JQd`HA/Y]ײ'>m/I=-W}AT? Sbu:*h#'" %md7ZҼȉtjYN?ҒA|i)hFjX}JXEKt`"'e"F g 윑(R)zg6T'/ A%RRPYd b@Hv(]*֑UaY2-Yn_ Y$ db!71ɽ{cN&iS[fk)! %4H[U~cсDAq&"(cI}p+VkǷxUGŎE_QՠBz:BJj-]ƎLyP\8SI\ұz,QA#c*YC3oP7ChjV/cb* 2R(!wׯ-Nd5b$uJ%UV"3rҨzH?ʿ4SoaqqJHnʜB2„Iֱԗ*R |q"[QH)t1(/+  t(V)]&:,II%e[eKlTPPORqХK-{]cg,:~,}.[v-">dZd/L.E"x4r KHr+GDk)?Mş=AEMEY;QRȀX4 YYrJt1ZSvW ׉Xk7C/]'[HZq]:Hcߟ*J^(mwHUmY CS'D zL>%ΎsOSq:jZ]Gik#ijdxT$A=NkX97RNso SNڗg߶z,A6FݢVhC@VM `j ?a[b#  -9 #=:ll@%y[r(@Gy{t*@K P@谱U@mA @ac -!ے@ ="ۣVAZB%2@zDG:oKe:o[h tޖ=:[ToL_i:--oiζ t!z;Cͮꌊ봲~L*;o]݆ u %8K.9ā@]u!@@Kq  PP ܿqFOWW[ [d٫żJlGᙷ:+x@i8B@@  :oP [uVI 󹜕kwNk]W];E7MP*^f6Qi8UaW磌VՓC %ݳC ]%ՓC %ݳC ]%ՓC %6trwݦ|+eZ"nQՕ[Ȥۗ6N]LwYNJgWyIj)uM3V,7z,`=xZc'+o,T:MzRJ'վ,t^LWM6xSڧ7V?NSy^,TI/K"U{Z#SJ]?[*TRڗk骽oTi*o?T:eZdjWv${}ZycS4rK埊[*Tty-2]s3 M),48Sqi/g '9s._- \ZTySn"U^;gJ>l[Ne鐝uA~*gtT$ۮ?r_ =Kl=t:-{ZؼNn;:on-җnTʍ X}?UT:V=wXT~-{l^K'7+oG곹bշSMcisOoײtrysn<:g*7n*{c[ұkcZ:輹 K>O嗮r&K7<ƽbqSMycSCl=A A,2Z_ njsO)R 򒎕E5p :V=A{7ۈg܄ۢoʛJǪӲگek䶣&"՗ X}?UT:V=wXT~-{l^K'7+oGz@mE[O*o*N˞;o~*k=6ێΛp[c_X*շSMcisOoײtrysn~qmE[O*o*N˞;o~*k=6Վ6d"q~bշSMcisOoײtr̛0A@%@r@M  @u`  ܄֟ܦ7UgtlBTyS鄫oZ2TAFަl*!7PxatNX( u @'vP$B@]f@:ADŽ"A:B'6 輝8&  Py8N@1H"λPlj̀t:o' E,tޅ:Nl@y;qL(@`.qb3  ۉcB  EwtNX( u @'vP$B@]f@:ADŽ"A:B'6 輝8&  Py8N@1H"λPlj̀t:o' E,tޅ:Nl@y;qL(@`|nn޼)Ǐq+pWWfl٦ٸ3Z"}K½@ +w:;[c5Wc]qgZ[vnWm\] P@yVҹɢC(,"is[JQ|b f!PL9 MWĒuT.FND"Kn$n+/4` Բd]р.Iʲ$%vנeZsI t,O,i}TJ:/vX\2(-NL/_ڍ,4?zHegq-ž?y)gqrpiݷ2W9v(4MS)$QìyY\:!VZV|XG/ie1%_c?Db yʪQ+cyXGRzɷU;bb4 m1O95K\X]LyTy\z.q:y i)XjqVA wTǓVف<}X^:<*q*eʲăs.xM%jo^y\ZCCiNT HKWֱ౓hr1:S)Hj-Iٶ_jf z jW^.vj@m(޽{vVY]]|[677w*;Ϗv.S#E,=h tVPh=Rd8%6?{Di1 Mv-Li@ x^%s%b̯YdnRO?+_N (SpL1$v$ B@?=9?): 0{(O@?v`?aZ {EU*WA?7g~;v  $t@? ܱk& 6IAI]4II  OzN%.ܑ?pT.W<;5;ph ]?@^=} ʫ_z}qdX\OgֶysG.\<<;0kp-7=Yœ,K#=vշtq;p:^}n3&\H?뫂7KO}x{;_wȃ/,.GOs<,z^_=zbYrw^xҊ\Ww}io,zûLǾޙ{O?v.i=ީ+JC!4]y=鯼G~=N"Ё>x#\}tC Хw.;>MXϋ_zɧw_n}[z/}#H祉;кH_:PJW]԰w}/عo]W?Ïka>/7{}O|'|Xsrvuѳ// -{/>o=s;ǨɻW;Ϟgn?[='-vg%~fXVƒ>t&sgj zMH?4h,X<ʻx_<\/]|@ ( yȝ~??czL.37nY"_[NԐrwūoW]|;B3koW.y1Yܜ؁OL&߿pn|/@tsܹܿ%Irgxs߾owqı_ Fx_~_z^3yc:1)#I+_⧗ݏ%;Wvä[ܸq¿4;=E3 9&ҧtŁyQ$7ӨtV寞_%3KX4dAۂͅ+}0 ;ڼ/KrClAV+9>8:PpcrEj`6NjE{A7;{ _;%-1b&Mf~0W(q_?@i/xj<;0sJ{3_s܁Q豻{$gvA\;0Lduf3 . &2ۺ3s]Lm݁9{.q&r`f9{D{[w`f^0 r܁`"㽭;03꿛D/_{Wq{@ڸa3H4̮7̸K`G̬բ<k: 8ΦOTA`vîzo^:vկ®A`ؕMWjrWI S[ x-,ufwVr[iApz9{A/ۼ8t &X`T#u!lkId|y*)&IL Ov;@y/g7.3L[9{ -ywޒmYc܁A}yU0eM 06Ь , q.!T\Tf=v@^~Z[Ye3ɘz#8PNz:KUA\70׷^z[ ٪B6T30 E%DZ8!٩1R3JT~CLqb1fȫ&<] A1 $j1,Jr*ϭ9;Z2l6cmH\֙cBMF'ą,7᙮4ו[v]Zx݁@S]e6;{ry[:-K fp$[$^ѐpVk9^{-lUl J`b'X8i_go7p9ys-:ejJTtMen[]~p #؅Y OcRL|KdW?s<]_ɯW9w܁C8jTyOO+aT^; 2-ǹny\~,=9c 5uvb0e3)YY%_Mj]UUK(AE5V)ZaHČei9`vU@035] }s:suHmþBN:©U.| ?1{Tf'̶j]~W;7sӳ+R8vX07>0˼9Uv,n47s;6mf&ݣ `\nmFrPɾSAa-)rbJ@"I|NP0Pf%QI- .-Vɩ !<3i{[LRkia=bQȒ~>P6Z doy*af@!+ Á"1%+f6s~oQ̪j\N]6C'ax,d ZtMǒIc3М{~C 3րc}-r{EbEoS(ii6.4-L S ?SeFۛ16_`@ ݗ$S\^߮S%sDzbʌG3 r-׸+pul?oI37j`x wցq>#L]7xHa2^]>wūQ,Ú \\>(>˷Q`Ձ{9Z`^@#ORX*J $yIZgq&$$ Nn,TMJ] @9@ $K;&٢U$ m^@D<+ZH `)8- Yq_ +NC `1ŘU||b#C)$am@rPRRw A33q(N`GBi I3 Ip2ٺP%$ڙma{Uf˜1gw2O߼υ%l^gA 6goM{A y@X'=]VQΘzJ,[8WٕgBʕl9x;DO3VX:{ 1(GX}vs]j!j̝HJYA:T+ G!gb$yV`6N&ȉAUb$A 1+ ` J08䬝B$ lq;ۑ{f맇G,*H-̶eh ~Tbp_ZԷq DQdFIcRb),&o\! I=U~FX:i٤gX!} 9 KgȂLgþ l.lAY0Ԣ fkVl?wi67Xr>5\orp=9\~o{AN;qeӛ<NR5sl]̱1`}v Tܮ}ۢG(8UMD#> GBXd5}_lmɤ-mg|۵k>oy3gLcrRh13#A5C\13QۨDhWaC/laf,RJ 6ؤO\W.!7e0ġaFw`bZ?#*U]K8^G`#XmWI 8P/3@G; `kq;ہ{[>]yrf@wl*} h PI/CTl*xktWGZjqIUa4ZA.`(LinJ܆V4䴂!  z SJކ\v;xڎ?Ͽ;xE-6 ,Ix>Obᵟp<~T4qa"J!1o~|׳/腺 L )qVR0)'ch(B)DV*_}L܋ b?J74|" !x"t<}@HmMm^`%dGV܃} 1 i^TTXg|VJ吓T Ɯ_/zŭWkxU/i/SbPO/A8RD𔪠RD 9M(K(|+_ {x);v \w>0ԈԈYSֶȬp%M>zI=/Jz/0&ʌ-|p?J^*Եke׭eԫEqR%՞GNClyHγ WC\`QsOʔ|з\{r2tI$HK3)])}K}&)AtAjNL(s-?{\`fkǿߞ!e lv- @66HtH8-yOn$n漓BQyg퍕S7C1˺+ ?~0wͿO>]C_Wۧ6ʩbnsfwnC W~9VU[n";C˫]u+? [IpSQ*-LYhLRWB[whW%H*]@*SK,fm-z:Cc,W}Q_G?VV>V;?4_װ'>zTiGjU}w?]gYV QQsd?utTC?+&$|iݜ-eDYt1/4j,[6mwv-~9~wI30ґ`ٔ_`1kNU)}8wy\2T;6HUb P5d\D>O` o @2 Zg;󟆃 J!:[du$ 􌫋) +56J.@!-02%9K_0}$H\[KQѷ!yO݃;RIQid١[ `n2سhAF$7Hnɷ&ou72Y_"Q|vʑ>4v 8Xo<3-{?,aXr7%|ݨ-chV9 Se^F>1'Mɝ $N(,o#oWS+ڈO}[w3kɝ!ݙKI5 KS;TkR^}|wKnyAg Q+vBS]|g^_XJe}tCn\ј6Xn J5NqPYRS )OKN Ry;`< HOaAW(r@ ե;`;(,9 zC͑JMPdf6Wj8i.4}ugͰ[K/5#e.Sv^ >QPPo\9Ko]D{ЋGaU3*"/"WYk- o=h'7 3NmQ'; 7u=Qa u|+ن?6-n- " 5?N, Gv]oko*m^*\_|ej׿w=Q[e!}ƅ=}MjN=~f&6BbpF"=f tCΞ }xȿɏ>a~ 3n^w鯕 } 0 0 0 Se![nHmkBF)39KmkTSx}YwF.n:#Nz<u]D(Jh`- X'ҒCa*@ ۈ cշw}{]/ًb_ /f7؍m<-w~~Wyygz1?8П`xv't>7:}gwgt5Ӿƚ:]i7?<9`{/t>螎;'th9u̚wSP_:=:iNtsě_h{"nףзހ6's؇sygG|ѐr[՘wOulNtOM`7&nyf}>¾6&EH gmG}sK1*Ah$:G@{Ua:>Dhr1f0B#d1B#d͇_Y!|ư㔻1Ҏ2>@ /3P)Z>z[@iPzCIW..([~\ISw!L]Z,LzRFΰ$"黅Gt 'Э CxtIE#\ɮdU' <+e3@X-_@`jXc8!"NT+*[@:@ptL}rj;KJtZING_&16ϰavR0 h 'i.MO^1[^y +03'VaY}P e ԔGO h-o~`9џ(dmHI#7 $7vK,%Ai'2XN:w*<n7 p5SL6Uqդhعg{l cX ;}ZC3t[!thA>-%C3 *> d^ %2 ZMFh5y(3⇱/ e18W}Aaی"h1EbYŔ0.hh7D-mPм& Ng9H~/3 ie1Y4Pd`h @▆mb`~CLWŎ,HWU(=Sԥ\a}Wq2ք'+Nq qyv`z#MoءHiKH#qSʑUFŢqw*G!Dي&<ՈĬu&mE1zd,G$T)LKy?_{,4a`!q`━AoEޕ[8E0RhBA:X<,pCl|&G>n)1 1cCS]W`+)frfὦ \IBw-c$vHr6r~#!L:,1o"2S"R'Rol6YtY:jhWRr)78z/KJΓW>~%|:UidC 콆Ocdpc-oZ"f# p–L-X(`71q-y!oA jʇnzj32.uzƫ|,|ITLMJŲ7R^WKcIm }rn5-D23&(W|v1.6id8*=`.:4UsF4~9@,n6VQC G((l+$NK4A5\0m1l&1tK@Tҩ*^MI4֤-ަA 'IS5h2IuioXœa"M#^_;S_~0GrңA]`Cc+\W&εׄA LMX"E&g(, ;Q̙Klh_KezU}cXDćJ=C(ZnphXn"הZt.0l/6AyN/i:+\*)MdCSS84bylVW`f,2oxD"_gWg9̃7di-7t'1MImTƐ%8ZC+0BZt*`/I"OƼKyp~RxA3^U^20户#)O'b+$ؒ7E4@M#2Ej%B;;9VMr>KO4QFSmuIoh.oF>~xF"ӋۮC57+mw)]EM5#cthCqEmtPb~6v[ɣ7kyr.ke%x "N98@|)Z5NiXEH6LEJ$–$?8Z𿂊p)Ex&ajhV iZFm-}>|FNjƺܢBJqi&7&+b 鋔T g$;yRtzȦ~(R!7—[Lr@YSUn!':1L  }SJs E)jMe5u7[3xx9ѦgLu7Iq3Mؔ8K;`FAY,Np8y-_K}K~Ц~*f`Σߝ9*Uذl^'@کx?oF,UioqM5ennPK"絪@Y,]]ng BS>vmc7kfYebc{lX+ Ě? &SS{{^{35 TԌ{Co `*]P?of=2U{O 1:ԮDxowk&=Wj]qfZ65 >{? Ł}-8Ҡ?l:oS~j#Gk$|;%OBoE .9;^l=+tzy--g17r _R{O]W+>f/?!z[cWɥ*4d7oAkR4MIAO4v1f^&_-e]Kz_/4'٣'OH߂?S%,wxHwx+ +$qBP]kݞ/G.Cr1$]$1GW)FԮi I3`82Sc++q-ߡ=”ܩK!Sx[]~;4/a_^*0ƺ1%п[5C͚kC 5;rvf皝kvV5Grj9BiZB 9UsQsv5gz h}qyl\s%f >\5C5C ]3t Mj+Cוw5C i2멼.0t]yW3tE몼.s]yWsEk9.pt]yWstE89npv]yWsve_G]wʻkv.3kT }f舡pLWN^vښbY])~zQu\~f. stӓ4G i;+eu/݄Ut)٩SZ1>cm{"-nwdo{oHdrD~l+$>GOTvfOch߂ Bfh׬f蚡\rqħ$&M{ I:t,~ż;HGğS]J:wn׀墾[<ç0;g]C ߯Io4WboI^|VAK%ֆn.d K퓍FKނ? t˄OcҮI.y>i!ZlW9Җ* qz r@`̑!W!{U׻"^_SbL-dXJk Z֛>Q2#g; w p:bQko oM@r 6_^-LtE?S/@wyTSL@He ĘK|#&C6Hޱtkұ'ݽUҕ-!vIػA[1ZVUIׂ_ߴqē׼z/hUf]|şw|`慄ّGW}z'{,igYWD¢'>U"Qih#gtԈ5Dud&S=QbIH;?G>$fe>s,~OBm9]IX\{e>{tnmDۜoKPmP;m&l'aA j@.@+̣}m^0O˼磈חz߇K.p#e>᭽_=~;fkky=psB,P{v֡-ѫq4Lӵsegr-\4SKZ|;&d~ʧ1)țyYΨb}Ii$w>͏F\ (Zbu1?`}vM3=jV#Ž_T g5Y&*@c>+G.Q/7Ȃ#&[uޢlұXcO{k=+E?P;ǥ2 5?f^/غۄu|&lld/5eǝqǝϴ}hGʠ]Ь2Fa<oѸy礰6qFǰ e57Ļ( z{ 1& $@xW'~1s wMy~Wϻω]\wwjĺͼ6n>~Sm s/o4)á-5.ku+,jqK)}L-/u8c<4㈏%#F^:W[u}E}_=H5eBh2ז.IY`ێTַ)iNjuǔgHL_V$տhkd1^u>tkxNpV1i =_u Ԗ_:dJL]x.]h!Ve+z!Ϛk }]Amƪ 5 ;_ |k.ֱ2ߒW?[cnE(ęֲMimgb$JnO'?]S#'MAmJ"s t[Jݧ(KdΙܔlk~5=6GG|Ɛ}*.4B//'ѷKpiTZTբ(IMqIvyHOz=7X'F퉑 xj8_4xƧgtE Y|x!<69/b=ߒŲ^a~<;Ygb oo߼=ͻލ$$}/,g=ணnz_ 6ޠK |7縙;7AxC'~9Nc~ p?Z=:^Zߣrn4;z#7#I@=:ޤ? }?;Kvmpf/Ǜ6bfv_Oy{qa_Gx ;Q=p 7]$;tHlǼ݅F ҹc`vc?ޛ-Waq?k oq? =1y`.xuTrD4:;tvԙw3k9>FwsL} !ao~q=鑩!x7GC~1ߏ7;lS=56S6=nyl6JFiU@{Y[h[G%:j'B#cTF6#ÿHtI`o¬ ca;Ob|B|+O#i$rYYaW-7܍vkEzf*ERo (WJa(i4|"ܥ,\)?䂩Qi_oXav$>@$}5XX4v5a !Kr(yҨHv ?ar3e3@X-_@`jXc8!"NT+*[@:@}fz{z\=N`k%:-I$#/Kg0;)+YRHV@&$d8"|Arc$Ȳ_|~2(/ٌsi|3vsWc:edYYM {F1Ƕ1Űӧ1T$8 ? @ĤX)a:]E[ R.D?w5#Wb bA"ikҖfHGIE}/xOK ?vPll1̊|;RlpV9pt?̑bQCU )]F@ik7S [q`,,Ԁ5+)9pN+a%%+gb>@RQ42BVdMzs=[ &9r%b xT3dnB )S俴mA y[ \Tƾa^L> @:)G]jq _Dd\"n/%pp6>LT"ΙGm> NcfDR42rhsFf0kXS9#Ycer_x~{  7oRBxN_A{'% `sP-ư-aSJ~x5& jH[UV^~LK{f9,`E#(;\烴}K>N3gozTOgpt|E2%V*_ ɂStVX~lOJ!oJlS4,5ZJWX$RS>/}LbyB6]3dƣ+ӰB)O'b+$ؒ7E4@M#2Ej%B$Ƣ܊]uiFK3BC_gfqٵHON{/դbijiUV~I$J,c5i9,-Vi=-<Qqjl,۵,e&S)V?|e8䱜ZNew8VxGG<:RMf٤YRV-,i-*v? }w?vs|hأP] -8^ⶫޣk$oV:S>jG6D%=MvjQφ5n+yԲ|m3VΥ"y||~_°B)(= I4d"$M"%xaBAp-_AEߔ"<GG4+I4T} W-R azɶQ>BUZ>|St^CB5}c]nQ!ߴRAEJa*3 BҐJާRϷ5o)f.ؙTy-^|A\KWN~S_7U=R-d55_n؟|txįO\nOh |ܢ5bH'Hbrq=h-&)R!]]gj`u82Sc++q-ߥw;ƹo/f-ο[5C͚kC?H3f]s9ڪ9蚣K8kv^=;5;\sPᘫfU3tf蚡k.?½x4iO8֜]s9ۨ9욳Kx1ήf3̵5C 53B;f;u]_:;Gyv*j ]W ]3t+j ]W]stQyW]`f皝8ʻCוw5C ]ʻgוw5gל]ƫz*j ]W ]3t]8 ?&ի[E_'Z/[om͂ Y [k=H\:~._3bKY:I#M@^ЁZS,OלҺވkmq#{ }Ü؍/ؔ4&ciO2=Q]۵'Ϗ">} ./e_f蚡ksej\~6\m,n{X[/Sp-5B}x&ݧz^S,;B(SdijZ>Jis*[x>ZgյlV`J{*m{Oi34p6H҃{ihfP|b8;7k@rQ-OkS ^ó.Л_1Q߷]iG@ߓZ6)G=$b߄<M񑞰OecG!_U d q.:JE# XgGsA80 w%z ƙx7O^賝8v~lq+_/if~RV">~de7-,; JU(PXħJ$Jz]Y%U{eeBIgb/ԥIJ| ސV/! wTMr:y74>h4v}t?O4,R0cKv@};pHZAV^OBm7RS/R賦YgYtnJzoJڨd u;Dk* [8ӻV<><ғ #Lw.3ouVJ?+q -NC>~&` ȢzvFh¿Ql-EMPŪXV΋{<~\3S%SP>D 曵oÙG>^oCV8cDw/z p19]iWm&pC>RdwAa˖7B_ܼsRXxJ:~v`/ɯsicXigFdn/q$搥n"M*->u*Zs W[O.8+ES{~\Umkr9 YG6ؠ; 8d&I&X>~oMk!c ׾cMM|<@ij"-ְ!4Av׷144&.iNɠ,zЂ^^9:K)}L-/u9FX ˱KH}j%թϧLg4 [)+ٽޜ$B;>QWed4bhdQWυ?E-xMY+Z :*Ƶ%)뼵KR^fjq+;d#mJha=ʲ5 zNbO}tbQyG+l=K- g pO'v2+ Vl'{zfy=aJ+h|ʹʧi| lZ[J}B>u|6IIT;!1E>HD]ןD_y'l i`uБj/FxaHܡ|˔F8{gx\L"}Zn{|\FF[]rd3}S{dT鍨o^CV?腈 W4Ih6oiTZlQ>m;Z|ҽ]DSPF6yV)R&O.=J{%*xJ޻OsØd]c[4^o`q=ʠoϷ y%I+=P+1]wG\ʫ狼DXF[^Z$J5dxwEfj%fᚅ<v :ɓ`ygt3]|A{!OOsm7s3螎gpQ7{= /f|]yoХS>vsG睛Y}~9Nc~ p?Z=:^Zsyf;avQO;p:|9ޤ? }?;Kvmpf/Ǜ6bfv_Oy{qa_Gx ;Q=p 7]$;Op3]E1T яjV2ڃ-p uyGpodl`d/e>v 9]Aݩ6ٞGÃT{1H QlH':iуŏpa'D:__CEymkBT8x횉m0]HI!)$FR?6c>>~sm+vuՑνYu8uN?WP>1JsWiV_uKEϸ/rˆ_gKW]ױEYcl,[TYHT}xL#}A GV7^}>iҞ-i;}LJX&TP3T#ߨgJl e'=?͘ona|7>?ǐU%;/mN/IfQփz{G}?v✽3X~j{zTAO^ʰ>?sy|G)P$C,_;RC0HJ k`G>uf7o([9rH١mO PFDf`\B",9!q#Sr%ԴAYkf9Ċy,X:sIУhYYYQEa?,,ׯ_'$$x '&&$ƣ"8k7|ï_.{Yb۶mƍr_ }ݻwe/]į^*⾃awD\T٠"REꫯdnݺUʯEaSt>'O,~~>w)S,|ԩrLK5 =/..#FyÇ}_U=z:tF엇.}W_U׍ˇyW˗_M2ĉadh_?"""I'o7n\)M^.ӧGkɽ{v 2 .hx ⚢ 'l8sUпo߾|n/EHC,̽⣭iYJq\ ֐@jeƌ;w̘//vL0'&% 𼤯kp09Cn,9lsA{|}C˄Z |.k5k)m0-_~AZ¬v#ԙsSߟO4ɭ׵ܤ3́=q@'Nu𥥧3"ǭ?xwiL>52F?22R^xA;|!un󁽁Y/Ѿ},6M,`gFb/ǎ+Z? lp}=Xc}C"{mV[_/==]ҰaCۮ]o7n(cDcZ= i|c ,k׮<}nrssX\9c%VIӫV6sΕ׵A?jQ|Ν9i2=qKPG1;vHM6I`A27o_fogϞ{gΜsdǼ%MaBbnLƌʛ0vp_ 0@W}7f֭{(bMFh|_N砎K.ׯ_/+((oE=c>D;߬XBuVYo'ybzl1_> .ԩSO&jO"=^;BۡPE~BS9J-}X11>Gze̸&DQ^2@?ذazjiW@ѧ^l`߫W/=%ʅ8P᪬㿝j'߲ekSr'Ƈ[_3A~lЗa8M B'|޽ql]r_3Tz1U+|c.Gx|d.:* T c}lkJu.|h|U)&s<`zRy=[Ν-Ϡ>mPtU[6y~1D~4 Dzsf ` ګb_+*( 38c 3R39t@Lh+/ʕ+圆|ģlݳ~(1;\Aoب>)>AL bSmsNZ' bP6kW՝u&m/5>:i1?zU&c>=j1J{N/dħ)h vK,!Fī|;țQ CwyG}$mT9>06GjAW|~ȡrFݕ 42 rGjL@?yqv[A\~fk=9Uf7o\9{ #G+h9 a?l0 D#EO1a{@sK`|sr[io# `FlsQ>սqF,6fhӦ3MЏF oGnrbcȋ)))rT6 ú rp.ëWwh`E-Y^x+S=?v ƌr(x7~v{9gAn>`\opI/oC[o=t%8s? M̛}ј{>lƄH8 C]02g5]m  hlZQas                                            ;$Xj GmkBTxx흍) q ĉ8D^>׻gI@XjjgiЃ`0 `0 ?ϟ|:seQ3|ӧO|:2|.};7eGFO6_Qv]T]^ˮg{>pjzkuo{yye?{-x/ D:3D&򈼹e^Hyi#/OGzϪ߯_~ :sMe#M3Y#=2 QЙ[\s=E8}E>GȩT ڲTg-}VfoSVwzV}./>~!?U1<#}=F[ ~QڋBN..+푹^edLo+[\-k dW(}6q$#?z6Bөi?L7!3O_Q}Пuo[=tkȋM!'}/Ƈdr2_Cﲨ: `0 :8o=+8-4}۞cĥXdq{bUq©ήm!ƶg*ΪU\z[GA=^+ru{LV U?)V>ғ)x|Yҁgi\yi^cUo*= !TY?rfgWsʽVn*VX#=Fϫ+[F~yH\L~[O҇h5ݵTow|Sfӟ+);F;:x )/OS yUo2e)Ve3'wgGg=J^`0  ľu kU,Ksؑ5nY,bXw{ w&3QהNQev ]ƷgcH˞i{A3I8hwduwUIWq8I>+@pQşGcZ\ƪUߝ]/:3d;ɫ:gB9R|GW~w2;fzt|+i5nΟgZY|<1NyŬ|E7k?z/k><=Α}N΅>uWydʬdz `0 *\?W8GY:Dgcg< 2+'W6qn؟{ru"wU쏘~c#T?+y{Q,,^qF/Xv8.֩g3}ȸOP ~n%hUG4(_sn|W}Tg&x^c,Fѭ+ <#+}/Uw8BRh_|33!mr\7U9m({ѝpvew[xG]߱?g;,nҽow8]וb?OV=Z_#ve?vN_WrYLo;1g9pV^G~>[_vNOS3 `0Q[ veO\k^8֔v<Zbz\Opbn$~}oz3ј mK vU]^iNWA#x딫jt q :E= z%օq)CcYEqyRG-+u (K\hP'*^ء^q=m=y|Kvūe\rȊ4={W1;=ݷxp;o@>ȘT\Ԏ+C=*ɫ|GJOCW]x1.ﵠ9_Eб Vq)v(ʑ}[GwǺ{-oSdו_˞׃2;iT&w*w:g׭SOsj%Z[~_˯d֮+w]7 `0]kIu+eL]ւoA^;=GR?v쯱;<y o$N1紈=:ߥPVu< <&3KyC/4r)i=*/|Ύ^]QNН1qGw>ù{ ?Kv:A}E:_n+{u=rq͓̳]>>d}+|L01`0 leg:׺񶊝`W,3O?]\9P~[kOWiGc~)-<w.3q}'vuw$Vnv(r52S;Wk_Kϔ8B/hEՠ'9w?K;x:x<|@cϽVyc@ۖSw8Bq]=2lBe6V}eR( VeZT4ade2ޒ+nYBTqSߔ<[&=f[|szP)G}{Zׅ3n7jpWwftEw[ǽ;`l? `0 `0 `{~i`oLy>uoi\qK|}7Svu9G쯿c¾#>,jow{ՆݲL=mW2u_8دjo?kD߱mw>#}E:OۡO;y`$j?tU mkBTYxoKw׻ΉsΘs69$D$@qWa[fzfV~W)#͙L>2!/_D uؑϟ?uqӧOQ"@ȇ߉%/=ǎ{a!?~,'Xˉe f ?n\qF5r445 ]S a/gRYY)M(55RWW'R__/RW[~?,U͛'ӧO*ջW^=u K>}g:3Guޭj?tҮ\YoW;Bh[ܰA{k>bD?>cvâ[r?XwLsBJM'Twҿa-?,\q?n\q?n\qFvmmȞS=seE '=Ш3gΔ ʨQtߠAda0a6m3f,[L٣ѝ rm{ƬnԩSʛ7oرcrA׮]Sp<|P={&vǏ͛7N #{D/^u:w۷O@a!wYfo|}V^~i4} ~zߠr-}E`Qx|)SdС2~xK,~_b{{gGlڴI.X@-ZߗwB}x{ _yn sy5==rӻt?,>oqg׿7?LoOSL#wvv \}e:^ǯYF6FD[4eLO@o<rEv8獜ɓ'޽{K9r$g^r;k׮s?zH cD?VO\ /^ȃdܸq?~u\7j|eҥG :Ԟ8ߏ1B X<9|=Νy"73glި;3JΌtâ=sgt&_nv6 _a}5|֭sNN휶O[`G}<d`sFon-A"^ׯ`ժU؏:{>{ܹsGQNزe֕hg@Ā ų]>n#2wءm~:`Li>ߜ=.tCvM~9#G[r=aԲ$}> ?,4Z.gmwqǍ7t}5\o]ڭV< ,kAʱ+WTw&9"քx'ht}/{wP^r=Rjr&dk}K}Ir[kmO{i?h~tl?n\q?n\q?n\ߗ.R|WGF4F?ضmb=grFzݫ}8˞/,{M~Goଗk΄oٙrC_#hvx7ܸqǍ7ܸqǍ7ܸqǍ7ܠG9yp2%q*rq"ac؄z׿Ǚ_墥=qz(v9qqqq?g40J mkBT~x흍8 FSHI!)$FRHnw HYx3ꇤsaaaaxIǏ'U{o_ھgW9 o'GW {>~Jlo߾)*/N\ϱov[iZ_ձaJΝ/:6O- 92b?Tlk%?_21B sY5>:>c=1Ow y^- ڶ,XzusM#גU]>H_yYv!ۉ_mi Rus]Xm_g)YY)m]y,m z1aaaxEߓGקo/Y\k6xjgH|yu.\aæM&wk#ϐ$?]Mo\Ⱦ,/ڥQ@~6s?)}, l gX #vQg Bٙ^uのuhm?}{].~}v_J;xogJY]޳@.)oqC?}>@Xߘ'-(W? źvƔOʙRv[K?[A}?-wmՑ}g\=c}M ggg DŽ-B^k_g?F? v0||؎=ǧHPgs/hؑI t~{n^}ZyD5XWvO)"c0vY Z|~_%/,p\ɹyΰZ/;/xs_9?Pܯ5ݻ\[y|č8gʱL{? 0 0 _k3>z_\S |<)b|7aaaxn.ta?l^Cvkؽ#~e)3<3^kdlc&jK+o"e<.ʞ`^(3zu l+6v<ï k7]/lc[`On}򚄫 G뎱zt^v2)?;Wmr5ocIz?Ozx{&!ez."ѯ 1Gg{+ҏlw<=}GݽFƨ^)zIpG K֜{{e G12ۭqiumf>.}~a? 0 0 [u+7Svq֭y΅ ?ނ}XwŶv?ߩDZۓ-q/?߳=<~#>Fk"qzrQo 9r,nY[;o:)@-`ק-7({߯S@µK9֠ɸ>:n3 _[_*mtcmC>qSL=<6;ǫsaaa{xˌ\ފpx?0׋#5zяc]x^l򼠕(f:~٣^lin59W~\;?vn6erUbS~v^U O7O(|;+SG4|?f*?rW~2oNٟS9~daևmH6mX[J~s.ym4ٶO|Bd/b5ɿyU? 0 0 0 0 0 0 0.P~*1@G\⟿KrKXs2(ߥ纎J8'>X@▼QQbqwx b)_K|v 1M6kee-2Ǜ59?K^E~9ϱQﱮYF8N?~;:=J<-tĒyNAgC \NXKs)'^Kg\~2}6}Գ)n]Or^j~"{p29w6/.z-v:+M{WJYZ굢`% Ҥl9ힶկ#OUz+U?;sd~vND7*.Y+v:ye;8}~|+ÑޅN9}{Bƞ#txխsXɿkSV/uJ=o G<ջL'L:D]6jfgLz/+ؽ[{rCMYq~[{yy czA;w9zszWHVax3 ףMmkBT&xeɖy1Y)f,13CJLQ %TW*PIůك~; =ӽkvج7͛^T=O?<ÏsB.v\/ӟ??˿˿??(?!*Ҷ\ _ɿ$) sשׁqm]UY}wwQ*CU}0mHSEӟO?U1||7~'ܕ.?(?Z~$oN/nΓ3ȇ?2|\>S˯믴{ y ۏ>X>/˯O?Sg6:/?/>L^"7o|/t/ }1O7Wq|!_~)_h׿yQz^N,S|ч믿tL\<#W}^~yO^{grd.ٱ砼cY|\}_*/=}]V,Y(/|]Yz|7:ϬD6깣v^9{lؼW~ Yl\}@;VGOդޗw׌H?nhf|^ig4[n%RRG9p||rG>|ruIwc6[ׯ+7^˧Ɇ-s2{L9~L9Wv" -;wdæm:drS;oȮ]SO(oɮkdur~yreu"7_~Y^~u-=}IQT$瞹&+W']5W:Hk y䥛7W^^)W>+/ -۷dӦMr9Y~8}J~z Gu;6qǟʇw׾K}~-=̞6E ,w?{e}o߮0߿կW:7sDooMxC^}sl/ˇ'˛>TߔM7'F[v}8BN\\:VN>-gNgˇ'N-׭e+5eDaO՜Ke뀾smrO䙫Srs┼x筗3gȼJk붭yVt 8\_)쐲[o5e¸by7w~%Ξ3giӥ+ꅓ2qHovT=.OzWy¤|K"Wc0ׯ]_{U+oooݐ^zE^\~Z %/^e]t>_qy>|B/yQ}rBΟ=)k_9\8rwݏ>?Hqݻ[Zޒ߽#|{rm]O;w>0L]mi?;;LϻoC1|gWO?Q|-w*[:_|_wm~>ﻭq?sӦNiӦԩRRZ*SJKXk:EN)%ӭT^ORbMM iL2MOfJ1NuK(%vįد]Mfϙc}Z@bߓ>*^]Z\nS Fߴ3~JyeB7\"q#?A_j!}QSjw0៾IaB[4.l,ՓFIZ7l(ԗ HC-7lGu:룰kWF4/4jLzo|ƫ^gz޻R4qCsnXSN0q^WõyghGvϻeӵ ˝S7mTUmer6lL1]Fii2e;nM(Edzm3ZJȈe2x`)+/>f͐!z>l NSeQJJ1R4H&)1E4Tیiӧ33T6:|,)#F2|06cn5x7N&Mx;vL=ZeȑF;qLqq͘a3gΔ!C#FXQF5qD;6Ç۳cذa.jh+cyD_Tf̩YO'sεusH,ѨDc:*h ǩ%ن:柧<q,%+fϻ{\PǼ:81E+H$x?`q{ /p}r=C ~{O>+>ow,Eii^~j{] >ggg44|TvmѢ=i۶Ǧ:xtŊҿ?U 2Tv{Bw.={mOo^z- 4aÇImeҬE3T4Qhn}veVҧoֽtQ>U'mڴOt*5C2i$6V[),g-dґɘcdҥky'l|}5\ ͚5Z>}=p:}kn::]G:6o.]d2p@#\9p;'w(R~ε5o\9v̟?OfϞ-<̝7ӕΝ7O$YllظA-Y$V|,WȆMd,5_Q>L&N`oڼQ,],gϝ-[7ˊd5J˱G-eMlµK-3dr#R^^.{5 e ԬYS:t W^C… eʕm673glRf͚%k֬SNY_WsC5 dן~iY`_?0ܳ޹;w$z}ze;}ܷ__oZ]:رs^ dБ~0qty=zty}gsmx=vse4yC9Q/?` /Y).}۩S'W^&M0go8:uֶ߀5kར"{ \㞁wNj׮͖' jHZ5vŝרY#q|wvеį)t2;.}5:s=IVJdeeI~^(!RFMc'yy66\㘶ܯQoC_<[VLh[V-i :775JVVh?t|{93:F׮Sq At5ȀgaFRN-LYdZu|:''"HB/Odad5lsrrrb=Ξvs G/`>6E{s~3&ތ B7=7Nj18 xym#|<nڢKYt̝;{3?iRG}_lJ/ɡ#Bfoۗ?kN.\ @kgPޫL2w81`]*=Yz}Sfso>QM&gΜ1m͆lb|Kѹsg#O8!6lq҆<}tNWSرG{hѣGeuVYx}?w ?C~d͖?`3tP{}:ڱsU+g6|Ntn޶hk|vuWhDJu9Mr[h:X(^k.[c~!޳g@k9yBVO ' qɒ%'3|ݺuf tM Gygʕ+[Iޅ pe/]dVw ߸{nk,-cnMҥKMSNV-M'ٺuUY+}߁x.VdL\enQp4,y/ լUt T>]q8m;Y8[hiYo!!{ [YEE'EFۻ~ugm/2'\"onq}韵 oӎ=+:FP3>Y=&ߌEu0> ;Jux`۠'J6%ǒhY5`qt>5`x*{ Ru/QOɾJkaSǧ_(w%Zme}T _"WX[ׁ{1QpJG 09Kncñ@)0O gC8J+?tOW:̓G2hZIok8?U %P}h0}Jh.\Q*<`o`pN/mVk> g@YLYlM*R/YgMXƌ-Æ a#Irr/Z?J~: wYsW*}XYG`_ Cf>>ȝf ;~aac;LtЄp,uE y&`{~`_{[vΎݣ+U<"Y<JgzVZɎ(|ŇuNEx)9xjMg%y{.5oNaQoDO}8輸B=;tkZ`97+8禖D_uр ^AѴ~O益9.۵e\W*+Y, hL^ÇBϞpy*7Nʾ%J:#xͧ?}Uq= 9_Vs><;/Yv{v^dyv~]Oܬsm%}./= +|ݙ/D,zOzM];Ng`DS`mzXLjJ_ík@*M/6deW jٵSNo=^N{d=h .rAiڬwիo K/㛿ong[je8 zպu+ [@ֺ}vU:{ljԯ/^L4]Oh׶ԭ0͛I;n*v,_n޲dXcش6_fl-[^ǐpf⋀_|[^rŚƷ>}If5qYkwe3eyπwv^YgE 婫eŪ`ٵ{9,)֯5;O._bqBc'#-{3}GA, x:} <6m(s͕zѤ)eeo^)Yf+O'ѓ9rDN0{ޙglM.^خ^Z9T?&l~Akx%դi:} \ d5kg^{3A=?]7Z(\ʙ3#Vk6̘Ѳzjݻ@_('NŜ/Z|;nβve~?I@;ݧ1?e̙eǂ?R\WxrDpvlY5`OG>k,-9cS}vYm2N>Q|cG흌yQ6CmXg~\ӶlV۔eb1/NwlѮ+̸{8n8d> ?biXmRljl+ á>?]H?N¡c;X^Z ?v!^ >ps\w6:gI}ve%jJʽX ?tL8x̞]nG3x2Ne"s8T]q[obɌ5q<ъŃķϥ="gCN8 $Ck׭-e3,fa|rr<{.  ?z<3A?@ L~"/ӵ5g\9yzկ_taN.>3g duk^PH??;O xdSrC8Z|=qt'J$DnZӭK}tĂjJc}N ʩ.YX T\ 5y{?US\Vu # ޱL=;GgvD[<x/jq=c}>v]fݹMW_ӯYb=O;uh{< .xzB>Lx&+;nΉKæ _n,RG4jШ|5gxcK[]7 7Zukٳ;VmZruR gq8Z`qco;X3_uem&[6o^zp7q]9?=CΞ˗/Yl_2zztEnf}uQ^^f₅qӦ{yP*1:vrWb#7ztgXn92glC1Wh~޻_o7CZ;!5S ;;h_u{9QY\\bc_hjco yDw&_ `fW#G#b;rPU:#sy!6_k)gKܹq͍7:st Yxcd_x]ϸuhgN]Ե[/}V ~'gķ3gZ 7|7h,h8qh |kpS2=Hr 74vN+5`Cb[a/~kz&w6GQwz}'5|3hJPOJi 88~Y8cx;}vwh''ݔG9w3v$~aȒf/6 ?"iܩ1NV/&3sJ^n3ÿ2<?=P 7 /@SYH]'Xt]!w$tBo" _;{&Mx<=;pX`G|{W7;~s\y,'9 ù.njgdt;{h\Ǐz. iK W7OܤIc}v5xF Mq]Œzh&kԕuwߨͭ ܃oڼjt>>/׍<=t9YZ<Ц]ok{"O8jnoxrqO`ıf@V.>1ǘ^*m٧;q8xȪ5e䘑kV\㯧 a`?=[Y-}`رc; 2eo9|YK5z`iT9s̷~xЏ=wk>gi>U9BYh5ufk9 0:"ڢ70[6a8=. ۷H6u[h.ykA*%WvYRM7RX{`b=zx?tJ'{nx};v-Mmczg͵力k>&u}vFc?=kڼSӡ=zv\LԪe+ӷXW|KԫkuE\=LGOީK'ړw|/ѓCE{8.ދ.C07~1sߡ9kXqOsi.*._rox21#/(U}?L +Skf<= [k ݿE8wzJlGr.G?Mog8={x'"W0xk~~:/e=Ña},^e}/sxtv7e3P6m/kcT>.=\RWqO]?a[(jO\8[kmרU``WeIÎ<ȳ/ҲuK żKA_V-UV[F]ސw0b0`3tt}?5ۧ`Iq H榭k<< 6Ϝ6sNkY;FfïA``#:r7 N};FY+14;Ͽ`5V,{vߩ#N9<?-Y;b-c9Ԫ5+Lw1? \u˜,]r=.ϸLy /-Fѱ#)oݲUz-Ye/ɾf]?~ ^Wbm?ح';^q;o|[9+^?iQ|G.YԜslbq[;AG 8T(96_oQVfV=!q!8x]0[jL8k,9z2f90T9wJ)?yFs5ߏv0f+ >ف5Fu;vm~o(I)5 k}dϳG߀'xyAx!d};?b;wL>z.MR g/|w ͂&oOL]C<,%9}gوnp<*sX~N|?+pǻXnt?<mkp:wN)ؔ)gyckΎIaӆJK-O8sb)9\q$gO|!~%9l C1/ 1_|%Kyߑe6)#."!?o/Ii<+'U[n_+.״ISsbc{qy.CE?ptyپnϝ'Jg/_*Oe^}/ +9vpAέ K's}:q{}XAB,8xY… wtgF) Gyכ xAv6@ 9ւk]s.~Q+y1L~UY23,+ICQ(9ݧ<BA\;2&|p[|&tTߘȒ#A5k䩓FM}%ps#fʭTqs+V%j Tfpx'Ï@g?XУs t@Eҡ}?yހ}wD^/s: .66+NLncOVI\ Zo d=B;љ˸͇ƹ8 r˥g{dxm7b  x Sh﯑[y: dNq?ߋ j+q&Oc8*/~SKMn'fNjI].#sG2v u wuz_N˞Gߧ>ex}zf} #ρ 6r(\= E.FLȠZdh/&Ȧ胨+ѱHڡ 0s@;g}yCݷüOf+ӯrcȑFX_u'0hԉ۹=}=4d5 Xe61cFٳo+*XFG7_1cLǃ 2>`3:'>|`| УspN\?X;GCYDL|DS1A?i6.nݧ=Vm8Kg/^F1S_Ms؊w`Oov|U:J|ikkpyLMWK(x!D'E琎 dzڵ< |2 rǯ{=Rg 8>|-{6^cqhmڶ=?>#I+aQ9BhL;mN/l <)q/wƫe \ڽ̼3d"kx&tgl+xq9Q?>\O(+~ݠVF5_8nbfyWaB׏.gHr@&)帒ؘ؀W+/'O{>.h*0\zX\&*@4|qcYr=4KW,u3X\Rb986'|".x2<׌m{?;33xPAeuv| .#?:gl-[Y?e}ׯtv6=d tH 4pτs:ʧ{ yذLl+Ô/3t'e撔=>{@ۼ_}^l.d}krz6|,ԙdlvXa>)Deׁ dzYz8 '? W\ 1RPuV a2u*TU*{EME7ckpJ 9@Gxmp9"\-ؿWIt1[No ?ɀ9X'EDTW]*a œ9q(vݳ+ǜ<חٱC8~+~ޗ%KKM- t&=_ 4^ZOwK0V'W=#>/0S.o≦X &_X_X;5z>[s2Cazʐa'~8A:z)2b}u 6Hf^7#F |'뷎5^soy :'yD,~wb^ϑ0O>n-}83閆}@ؼYsC`ʌZ-}z jt@xȻ>>C r}XD?aaB!5nM $5w4qЧW{m迣A#ҋ߶M}zc룙4,ldĦط6qCwJ-lE>`򀣣jܤҧ~?Ɖ3Ө9G755ڶ'k+x|y}y ؤ`ˁJJzkk!?;UMWge/b{% {89&)[!6̭1'*߇=~l~ˍ><8|IrNglKB&ɤ≲yF_tLcVrRAu4A\I#?߽Vw0wNg%{׏^灞[yBeG >ӹѻy^gᏠP=;NDX %_Y^-_Jߡ w'B _P+g}gzg=B yx&'?p*/ kQ* ;N )!t^ ya?3H_c*y✠gs*Av9'%J-ܼlEjIy:kuדzϿk[b{cvy6c悚yңw7DiӾP^c!z4olq ֓ uߴYc)lQN~&W0|sS:mr&ߵW-9@,U6KGlQ9sʋ.4=Ƒ'{lcmdղS*]۟mJɏZR߶M[HL2q\QӉg%_2RfbJ*7ͮ@L[ޒǎ˚uNoM e^G'8ߝӵAx-k>?P)tb)G5t=O=鉸N vW!7%`YzlڼAycC8ix#{n }!& eμ2(S/ϱqˇ 7G?\}zn*\ßg i{zlgoWtI(|E.̎Iӏ4Xjtn)NRWBʶ(~nt9"|_\e%[KchScF::A6 Xw{.\g%'Z@ҵ2?%X9#k0vN!Fm {xܣUU16e_cXDƒ6|]~O {9kz:u>?Ȁw9[Ξ}ã , ~S {. C\/ y'SU A%.LxyG9?JkwW<Ϳѥc;\NxTy-'(RtVrS4U3Xzpʃ[Yk#b3B?n`cGowEyM zy}f>u䅳n{U'Ft=S)xĕ]rb?*OCZ9ȑCg7vD`| &7칳- ;%|> Ǐ+Tt ĝ''2?Tݒ?¿w2~MOOa,.-\cSJS;IB'F?t"0 60? 8#ız W+?sg_y?=g ĕ"ù6xqs35 Q =>#A 0x+lȧ-[4t|6_$bU*i%+?\\Rz$7=}ɧB9>!kΨt< - >ER AmP3'%Ot>d̸g~~qmb='qInx#dy(q5yͮ1^~=OOd4)qyg_??|l?kňy|wx$'|z" |Q/m4ӽX$|4q=YA+4wSs'}di~=\ 7utG-(\,(`۔L0z_`_Ԏ':zlm! r ~>/⻦+_M4^ƌ&}w?t`O6o+S30ˌ?FO2Y3B->Bl9`:;9ƥ>gcKL+1}#} 6Ⱦyp|Ɉ59L&M`VP4lSc|F q"W><^>s;ⷠ ^kΟEOB{9\;` @CF|L5rayx7b&MkV]cjk;<mwjWJ{֯k&X.EŜPhufu~}"Ԫc}r\듶g y~kZ_5^Yv'umgji|r-<sj2׃+qϸyO#6XöF2i-_#r3c#3OtՙJgQ'|=c.+@Jk_7ŤSHUu>?|HN*?b%Y pv&/ H8_`rȏQqWc2^> UQRIȽKE?$xAF*?aH_1 H&9U;<6,<?d+,=TG DkS@ Okx7T{<\,+zϷ MHm2_K^Zi7?pe!ZjYetmMDtQJ?'.z>VH⊡z>Zkt# Kai:, k'|VHzy:#aCƍ2aBXez|32`@X*㣪t=r/T̸ ւa5g~7>/% q>lu=] l儖-}wF@J47('+窼4*Jzaa))%|H-i!yh`cWXf ˶m!>3$7uhkDd֜Ma:5 $ׄlM5ѤG;hϛN1eaJЄdp`-x2h^Cc R!Z:4ZI jmVZ:jiz 뺺LW*h]#F/UNt>};IaixZݞa-!igOV<4iM^yrF~:mR+V7ߗNx>+VBurBG_K &mתL3Y|{a(8X_y}~0O3kP̻Cmp-ClЋeMYcﰏs{ 1zH2sG|orw@f Mxqr`PN ="dÄۃ8>.?6K.%xpqKTe~֗x4?|P=q@jn=&?`~k׮)[&؃: k2#~7ܓ%x^W\N'̱I)K)~>?ᏽ[~@dufZ|a#p,!N[Y k d '-_OtV@@Wր+? ; t  *քÇmS/-Krq*Zi)ҲDodix`7U"!o uqy\qy\qy\5b})MnmkBTxe]GyX%fYU%3333%ٖI dnl7w#ݷ߻wL733kַs9uTRے{rΝ+sZ[.~\('////?I?OZ/'_*_M'Yx{ge//iϊkR8*{No_!mL}_'Oŷ}+}?;wGƥK͏???ɛ/"'oxI>o'g.Cw??oF>r-}ܣo|o׵ͽ{slmQym{ogRјo{^}߳w޻W׷~t?8(~S<}h5W!L>sJ[YKqjygo9P2U?<☼<ژV>~'A֛sV }CO?Lkk-:~Sv?O>TKϽ{rjA9kF͗_<~KWWߑ7򕶡/~ڛ:/ =ꫯK-_:?Ws O>H>|ًgs/ȏ:}Vk0/\)wt,- ןw~g ŷޗ￸+VmϾV\=wTl#gO;)˖.s^>X?uϬ VѣEu[ʫ#;yo_.:Rn){yeꙧ?͒m^-}}ܑt>_\~]qxukʍ򩃲~6~̚>C?/Ǐ3ec.9g߸UڼNxZ>xMٹs\׹}d߶ o1ٹm,YV?"矹*_9DrWWnںB3 ddʵrd>ٹ\{%'u~)o|7ܕ%ceem69}lܸQ='׭O~G]娎R4f3qi|oYS'ˠdӮ'xhYWV\7F'rȶqқok~*w͗Dyy֭7eA Oȝw?z{~ŋ]7ޒkW+dR2Hm٦sK/(kȪe%mY6gLX6k[vl#ʲ sⳗdź2k88|:S_';9Ⱥ d?+ΟO˙SSvɦd%b"gu5{٪گܼeSye9y=8%)yeΌ2w^ڲulZE.9*oʱۥtRy[a:7H{Myȹg̙rZt5sCzᤌ9\.kkgرS卷ߓw߹0)?/Dy5D)gk_u{[+7ŗ_o%_8%|FnZ9NeoK/d>lymz}Ezu\gCNȁdݺ?/sO_g.۷˵O8}\tA//\^[_KirhNٿ\~E\yZhۃ9<}oi7U]kV+ʩd3'ʾG҅+%r{_(}}MyK+rء}r)۶5I^^Wzw?x@ rrAK5-=-׮\CO'e˺>^1gwSnG+D޹{W޹uK{w?O?x_n閖z~·?~kᆬ}zmw>P?Eǩ|~so(4޽c;JS|~ӵ+c4O?6:>}~Zm{+>cS{}yy2s:O={<*_٧ߕ߾ensvKo8>}?gzn)2u2DKJdrIi͹])2xܛ+㒢V){2Օ)ZʴS5[?)z1خ+S)߬ٳOkh^{2TGKߍh}x&O7/S\(zR'.֑p>W) +GU_t QԮ]K6:uH N]חJ7ݣML-}QHx}նaוZ4I>Ynmv]}uu|YḾ9 Z7lU\]XX83S_uf#X2Ω7n,x?M2sV 2XM&G 74bpM"SOs͸&M1cĉU+GIt|#GJQQ >h:i:΁:|ƌ2h >l0k?b{Əo\:tP{} 2E me <Ϙk׌9u}=K_9|Μ9.~ %qs4h,VG%X8$PǣV8ŵdywkW67hD8x,n߷ιO[g(ou gE-~_(-3Z%~k쬟:1͚5o`?[ش_c._\ʖK.OI׮]{VnZmJϞ=`;diӶ7V4k"'͚Z]vQKt";Ou>}HV-S]:KA|i׾L4Q縕EJn~٬y3tm62j(ׯtIz)_޽f/pm&M}-W^vγݻ{ڥsg֭|j۩S'ٷoyY _rm͝;G;*͕Yfɳ>+s6}4sU:6Q,],7U+m0|Ū~z2|2'w(Y*'7n ,-dfju؉v iF]lµK.eera)++={mW.ڵWeb ٺuX͞=[7o.3gΔիW˩SUV9nx  <̟?Y GW;w={H^=ee2l0]{>ݧ-KNm l߱ /a12ZyCKm?N:=nݺ<ӾZ[x~3C6~=RI2{, ?EAx]Oިy℅~(m{ξСo߾vQFv ~ ٷjs޲eKouބ ]+p{<:YC?;7[+,^ jTw^zyZ~^yw~zNF/v"m۵Eq*A^%yRJj H^^IV\scRsZj }l50m51x\[*(YYqIWgdjv\VM54}#KrrslHZ5Ot09g j" 9^x<_“͝^ɱo?9O8{͍/7| 8/5g ~y1jԨx36hx݀+80;xo٦M÷XsWwh.eŊ[0glٻĉ/282⥋wWzT>h2{޾x9}ݷVurZS6k^ed'Q vީ2~:V7*mf0{UnR|6mdxmqQNyX+ŋmݻ>y}9`pB_9p;t萷cǎ6Fڟ8qB֯_o yޫپ}ƣGʺud˖-h"~ ^x[.[6Zf.7|u}6+W3=ccHRб Mݴu5$q٬RkVɄI㍇+V,6y:,f2ʁM׳vZpcY|#+{8^Ν;m/e_3{ݶ^Gm Y>+[7 xŋ̜k{8gš&'0^5'瞓+Wl'mx~"/:t钝\3|] 871K,1oL;-Z47d˖$7'Wes3~Q#Zr 2:Zp={GKѰxkP+T\VFuSw1HX>dZncpf lެc̫Od9>1p2{oem]{nRC~/{Ȝ7sɻ&N;8z`#f@cy'Cwgx0_|3mf/l*UUmp(ڔ:Kښ UGh\Pkfsր>}ӭ<׀.Wrjӿ_+>JrnD#1D=}$+Y ~WykQ!\#^am_<;DyW)7~n, ~Bػ}_y}<3_P*MK8Pî zx>&?]dޗhza2v]r_@yD;x`OQө8(Wys`}{&8?#C4Xf{EwpTs{<`K-YlYvn2+2LVl=FezlU>ۿ:|toЃ;`~8?H pa,0wbg.5}l;+Wf:a܉n@ϱ64NMB X}>igpO7e}J{iq~|^9/ |?t6g'X|X甇wCq_[$ T؇2?$0t>߳SM%Jƹ>sRnjIX {pMNOTrZ]Xvpi0u<UŒ:?z')=O{P=A;| W%ףrC%ju<7p ̳ \eY geKggDJ=vZ2〿۝BĢ)ԵtFH4֦gŤF4=z a BܴkkO^8;p<,O]Ki85sxGcF~g$M~Nf;7~Py{=۹{>'Ymtƀtϓ3fΗ  pbJ_]˅jmݾU~f]TW==3 Mގ4vt4׭7Wd:t]y9>LM b42~|;gP<:Ag/ad;78{K}& r*(b $2y2kVs >d{⹋&`H'|rc;wdBus㿎n!df|DF'3bpFG>p}p_: y\YMʲ+܍g- ,Vd,tC 1(5~Ts,vUnmӅ9ϰ}'X<֕xA#?j'ptV CZmmaK %(^&N]ڵkL.!g Nʕ+,A,;}ۣ?+bɯd $S~-D=F+VM[Nrr[es׉7X&7c?{^,3 2 kŶHaثO/נ#~^zfSg#)/mmtoXOjԮa϶mZZjn~..K+Ğ}lPh/k}uC`|sn{jcۺml޴I^~%ącw!x޼ 9{._d[}=\ұc'ٲuŦ"GYYKOA%_ >İkK:_]pщ7nifٳ Q$^uyFssG_K\x>=D9hx䲃OB,4d}7LOn"FodQQ}1=ޙ|y6!굫nD^9؏f-C!VXu`b~vڊ^=N<,q.ƕ67nHUg͟kW]:.<ر+nݺli7nPo>5w\VrJo"LElם~--*?-Xzxx~Z.L»kO1)yMޣ6k֯5g;2;gɜsk&߯b/J9V{ zؒ&Mh1bZn?zA 70ؓ[,u=sڒ}\Ɂ=&u@7x>Xs 8Ϻjjl Y. 5~DsNLc=il-<9^jrooG30&8m"Ob"Ilbc9D>wb=X5kג:zԵ[W6|BN6X XM2h1|wZ{v8Z;B/!oȫWb2㍑}uy?jӮ:%wQ.lHǾ[%\.8\9k  ݠ `~|A~ rq/]f_cZ^x\U) X/l9m;c`g&[Q$c_=yObcԋ2X$7ϙm)J㡏m<с'iq<6x@s1㮝9|:jC~֙Q̉;O^`oYgWlcW uXDgAɌ{>>' {b-gu$gq7[yl{nrΗd;=/skm rXm)MJwu?s_xt\W:na=L>hl0o o,?9+]$x}ɒ^ޔ}-9郵8묱Bq;֯[fؽR2 > mۇirvoI6*uz[KGO|`)Ad^{葖sB!KX?ϊsh8}[E6̰M+{U/ @ Be4$ ^=NE#tINb1iwܙ.?s4 Έ|d~=:7s>=bak"A\^'b W]9sx sszw籜~; +J3nAHnJs?:v0-y2_@>esF M_D=׌7]JuKvycթW[ށ?º6'p>qF}_\LdP!dk)j@6Lɯ݋x>Դw[j.ݟQGzCء#:j{`_N '!<M dD;[r3:"p=-*d;^ Vk֭>pێ`|Gǃ=o>[V(lӲelY KnKspB]{^w[.L'|29ἽoIRVZfl-9 _:7\✵cq/>ky臼r¿е[;f=s?Y^zhwΑe/UWO:pS &F\ح{7C*t~[7ױcҸIVw7oTn8crQKj֭i4 гMk?5,i?ѭ{W[D-0}M~VچXWu:u=yW=9quhgX, <3rKp8]sg9>,6 O4b*h>-9΍.:*3®]SdoP2vosܧbΰ [sq0Fh}=-wrD;ыVl|ӽU|/Y.rнXcrP118=N'^]x?׈'@n7zS:]g? l"8 M/iY`ֽ%VFپo޲k[~/ {^x1HC^<"[670] WQm߂ ^k5lE 9y/Ƽ0cAASsL }$+0xdn&S@?hsi9;v0,icdv7x [v@6ÇY[x#lnkC#}‹_tRٱ{>┘^lLQpGln—m{7wlo V^nNsM gMƿATY:B9%FA~:Rd?6IEeYRMe™sf̗4Kw̸і̹SrPA 0ŸEq~;'81^Oy)lWm5ڮݾsQ~#,5OyOJgX3'{= |8f?3 q۱cd:GՃoCLTUmѾp9{ _h4|}dJ\zaq(5= =|~ Fw7__vLY9~l?r8toπ^бcODLq<ˋG[kvvL WZ2hyDZ#K@Nw17Є %9{ .`F^4pxyMNgXj+_".,xNq9$ yG|{HOC\9l/Zr3^q]Nw:K܋syu{4&_ [.7?Ӿw'ŃlmUhH`SB}܂ 3iw%s^cV[Q3}TxEހTy-Rbr;1[UCpZ]YHZr!Tt fE߰X8gr:\<El=>}iSM3d|]赑C9:iE/_'v1bB o##Fzq|`7A6ED _AD]vDd,lh1>#[D4[Q>=,K~@1B8yo}MF[?έ݀Al W@"O}A5ž|ۄ k>jxеaDg~4<~fS'oϛgtzT?uI1]~+k77}>菉h<qD-H-^+klN6Һ4g[}9b;}Zzܢ^Ӿv)alxK5: J+i=ں[5l3L^g>v|u9CIW/m4st . b%9O±?D:dґ;فcr?>LTTQO&2x\aU\ G3Gϱ=cK{<.޵U떶Gg<:AJ8aU\-^i~O2't/8~xKOW UC׃?Av^yݙ5 ?y\9pfbgk =pO==tȵfOЌR/x \ѳSpxLI~2`~@H$WW3*Q>}ɓgn}et><MW˖xfM7?nl:V,vW`eM [9 `{t=p?5w Lk!sߧtY0m?:H翋5[){yO}Yu>h]Mw+t<`3);p>;Bl6,ED<  L*:p@4}$wO!6W_Ŀ;< oߒ?M"oF2u&; ?-|4?}J(QbuDlmV.~ɏyḂ{Te$q؇z8:Gϖl18xLz2h@Il'p೎d A_2 p' סoǰC=1:Ia|[}&o 蟘Wjp0 s41}Ϣ/DoKv"_s{v~8Gs6m/X2#:i3;G߃t^5;Og}탾\V;-OXذtH yuF Mux@7ⷭ}~8h" !) onXƝRx {}Q".<6j`a߄oOa" 4j0FMM{jw= ^7_^_G^6x=@<r ~:💠^ڽxȏNc3 ;?{'dzNxe=XWlq:|brc8>sFO\NqC/~Ȉgd|ߠӳ9DB&c֮W {aGm-JQþ/cюsKA|Nl2kؓ[z*$@A}@^+_|-+/p]~}+ ^6 7߿t1_udthǎ_z 43Dxt5˖/#[\#w,.xl6yb-fFyLb}жu6rD.@ K^i ?e+Xݻd |B˂9i`B'ci%|H Y"N/i}EdR ==BKqngv˶-?p|w`WC[ $9'Wulr?6Z.&Ģi_dOcVrRAu4A\Ac?߽w0wNg%{׏^灞[yBeG >ӹѻy^gᏠP=;NDX5%_YN _Jߡ w'B _P+g}gzg=B yx&'?p*/ kq* ;N3)!t^ ya?3H_cy✠gsAv9'%J-ܼlEjHy:k֑:ujϿk[b{cvzj׫eyҭgT;iնTS^cAz5mhqבM u߸IC)lQN~&˖/7|sS:er&ߵW-9@,UVKGlxS:G1=WA*?䦘6X(V+yb'Nk|d]_aܣ8$̞[j>? aZgum=z䍄/bn|'Wz=zxb3j+tYbC&,U]?s; 7@_ѱS#!k/# -S8UuuV_Ev_4Ur@2r({?PN 8teJ-١s{zu:uhs $VȚ< -ǿS$w;w9.'z'yx M?rh<3Q_b>_-~l_^N2 tgh=E'_TÞ˾&w|ࡃ| " HIzUoG>^c'5Ĭ9, ;%|/˫Tt ĝ''"?TՒ?1¿w4~OOa,*)\cSJS;JB'F?dB7 ?? 8#ız U+?sg_y?=g ĕ"ù6xqs35 Q5=>#A 0x+lȧ͛57t|6_$bT*i%+|0\\Rz,7=}ɧB9>!kΨt< >ERrA܃mP3'%Ot>d̸g~~qmb='qInx#dy(q5y.1~~=OOd4)qyg_??|,?kňy|wx$'|z" |Q/m4ӽX$|4q=YA+4wSs'}di~=\ 7utG-(\,(`۔L0z_`_Ԏ':~lm! 2 ~>/⻦)_MT^F}w?x@O2o+S30ˌ;J&M4Y3L->Bh9`:;1%% >'<'#G4ZlF8d}Mao5UkrN.h}M46nM>)1Ɖn\9xpF|z߂x6x!9+zZC= hr%t9B3]y݈|h7f /gP[5_Q#Y?`|sB! rյ ׵j5R׏quOZ>u~n}QWw{}gvW۵񞩡}]ȵP;̱\֮=j=`Y͌0>Ag?6Vg*ҟBx'+}݌O#wP&$kA[:)ѧ ЂZhWo 5^KKW7lÍUXֽe¼U__@S=1z&ǯjEc'EqHu K B=k I#ݻ٫IUKʓ7"uyn=^t:YJ`6<Z׬0hnmdҨIҰ CibBȃm$x\b/ Gkhh.ӿEϟ/ӧObzKyӧQӧO͛~zʕ+ry\vM9"3fP(رcrIzYݓ˗/˙3gTߣaÆĉeΜ9}MM;V  ÇW?i$2d>s{ڦ TUUy|>9Ϲ7.?Ө쐺N/etنc.8[L6ds629KN7wѽ\UNl|FѼ\Uugs464JssjJeּTJf[*\m+ٟojlmmmmuCBVv5`:cd幂V͋wۑtyп y'*V=( nՅj :ݡks3}s<ykz@g{aͧFul~G-ROOn8O'ڏӷG}|c|=: l|ggXO5ҷo_Yb,X@kk׮M5S/ЛA k{\Ԣcvb;FLԩSr}y=zTYκu\88ƃ??˗/Ç2n8mO<:A,xަMX|sݻwԏ[j]9x{ ,Ƈs=H&9;w<0c;zh۬/8w8S 7'Olihn{-[9~ӗӾmoH|7EZ!Z6V0-ǵhϾw>_q_v;ZѕgPwGj?)>KmW4?}!%\/YDdOäd8ݚ5kt0GDžz"c]eNpȑm)H>$}lPubiZ,wO56ظaa+?ZjD6ojtkZZZ4ea @>U4;~kBU{ ..T}6ڳ-F`p]k߅~b  О$wݓٱ|sCoA+q3lOx@(0a+? T,_7s\Ϙ^Bl1)C+k(FyN"8dPC_9>O0&l4Im+nwGrŰ)/tihf ѸX>E)<,6s45zb?J\<OM%O#(76:= ӋYAƒH Ls6MXBcX&ǘJte. 3.je(??Lj=%wZizFTx$kP8Em jAOހ>~؆B9 ֤8UKCvjbL Cy ;mj P. DkwUE€3ܨ8xUJs\ɟ+;}sFQ(KIXݛƨ 1 +KdX];Jģcx$D׷X`i @l̏rnm$^9΄zBGϞQ=nfkDe; <a>,⢞jk0B[p($Ǡp4 nq`XƓ vϵ.xHnorJ5Hu뇗 f a[Z:>36[g RL؍?( &w.7C#~B{] UW 71jk~ecGrD.=K@WDZM0倐0\xvqNZ ># BE )&yA}t?B Ym(WIpɱ |2+\2 )l8tl@Z.Be񅋍RSƃm>dIl'N adĢG3%#)?$s _5=YBR#-k"qGP-e"f%֩-ϓ378M9ϊ,_*n;HEBƱcl~ ˝[/sagIE2,z1t:kLș壋G){7ond{@rP>kwk׽ #kXfyEAB9uM4P=_lgW؇N#_nGpp ,ZUu6ȓVӰ0EK7*|]{75F\ԶzQz! uH>upT٣o3P)[^6` -d&*=%fY<^ط`_6|h3ء>2 Pq7ώ ,NsjF=B` 큳CiU)R鐏@LҮǧmb<2FHRqùFXi䎲OmGA}:*u f:@ʫRH.66jcGOpO- 6HKJU:Jǃv,3DZEƮqq7p?ȌK%ȧ$;?Qr6pP7`a^=R_)m>D3#£ _' Iɭu͋C-Rne㯄ssL<ȭ/R)|Lt_1Lk=rr 4/gEr~PnB[\g[{gYvRW' {Fem1{ wL;7&$xc0 n&u@5sCCձm8Heft x{q(aтa?Q%l4ςxmWI׆GC1kQ3iJh,KRO`ʲ4)%b6B8\pe;u)ko)#WSncRx{[sXv195_0Kՙ7>Tp5ٴl3S"؝LX睫[5m Q="u}pϘ*xbՉ#iM+@Z! Ϯ~jYݬ$?5mtu] %@݅:4h8ۃtu3; ΑO1A/r R*5i&j#Y2:$Z(ad@>'z L뇶6Z8|`6"X1_z' F-я?X^ A:?1;h/KVB' vOnFS ƤQ{=kh7MwXQp\v͓O/. N3HKRlK"q^Wh1wt h@3e6N|I;y?8t[[! $,ήLe"z%IކAkRl!3u8ځy?_W)AbCO!rza5Sn֗#<43y6"R߃CQ&>[# BHǽ{vekOTlq(UH͵h ݔ8,@tՂL{p/*L"d_y k,4 G̖bD>,.ok"D;|7[.DCA#ilϟI֬Dq]+eE _-- ڰc^Lq1~CCC9gNH8BkhJ#Z-`VoMa 9r$պZ-hkh ?C$ ^tď9d(8P݅]ڶw[wl;dn׆oKd Hބ(DInI M_(5)6H/Y1 QRk,nXHʉ?>df&6^EJmt{CCc`0ʅv5x<\9Yc}106"״!֏9dl:' 1H"z'7QqɌ#KR./CVgQȬ\ `?d1yuM6Ƶ8ZX]8^pwQE &1frRKi$GݜЕh3'{;;~FK37ku<pdʎ+C RMzƏ7)nҀ lEGyl:̑IoBS%|ЕsTulebA}Aʹ10A{KʘӺtjdLI=r PRg_LbR Şl?␔)![Fo wi&k^CV(t@pW2{hxHGRn͉eCbxԉ6GQd27\ثdS=\Ff*0ۣOP5(rZߙxQZ>~GAeN-jY7Ҿn;n?ӹ"Px}/NW:݊&׾:x" ꭥу;R펔 c䛅љElmG§a= h¨BG_uYnZ쫭FYs U"zM&:Gnu.DX5Xn;}ԫ%XO?~2&Frjj8 yA*W I9/ub)Zl: s 85J>~iI3Yԕ;:#hELם[ROd^GA˩f~Y!En0~/A Km>^WYq"<цF*c:xw|͞w%ehRgd9̕v3v Dgh>>?3hYDkgC(ʹƒԕSԜ| 2Q94(?OGQ34 fccPopTYaW(>@tX4`LGٞpɄaŰl\[9c26U M6f,'C4i?W~psϠ?kAKrŵk@I|>^xs?\`,D̒5W^w DMXf_8<%|8_왉pP1Wlm߃f?4:́_Ԕv M;k:p_sj؎qw]$F}y ,b'N=o0, ~M YR46+!}@~ujctCP.Y(x׎z?70WXFܣo3z0c8RGg0 TU򄽻w"/4֏CQ`[{Ocn]+{{ N!33+5]qpj' r9FDȬ)~: 9Gmx2-?sraG"yvUpa;Ră A\& ?#n 0eed~oq嶭!!DzP^H)>oȑ.ļԶ=Hy7S-M ?8ycߧq|#5"2Б lm#UeΤVbM͘jAc7Z ]> 4gb s 2WRsKg6 's8qzTT[R[w)I95xWj #!nN+zPڔ KgTE,?{^RDݥ=Ru^zîc&D'i74SJߔ&HUG[crͦ<׿~4}څh;lpAZ%XZ;tQ?yk1+Ƴu6[ Dc4Ɯ*dB#!}e>samhG3c^8u9󼵕⸈߂UyB;f "Yi=D =4&|C3g]~WgjhSIXU"1A5Fr4{AljwTt6</N \Rta| i>T.Wo>>xϯY{緷m,J{gg}v~)]s!?wXGFl!7U|Cnfﳅ:.@mq%臔Ru?.:aBֺE#Gg'yXDuSWNJD)21ѵVagWPqȒ s?¶@g")s\T{f3go^w:^"{d#!φt},nyWFKv„X4|VB~,˘_&fjp/WԍwaO H 3I`u1ͤ+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_Wݚw)WmkBTxܹKy/Œ3; LlXZ Vv**ފ"x x²("vZXXh!l$K4Cf1^D 'Q1ߙn˯A\JL ܺy׫UEw?\rw*,+\_ǀ]w(IJJ+11Q"L?_um\\I>Yȿڳ3͍7}u1߬߬߬ߛ/q?Iee+)))~OOOVXX(Q&JL1;ZXX=||;mJ&guqq!WWWryy)2??/ ===r}}yxx cW Tdee+WT̐566fsbY\\ߥӣca)++d?gddx?77GGbbb$;;[ZJJJ^˾̴gY=6ˬ,,_˾liii(RTT$~399swwf$'69::{?22b]]]rrr"rxx(-;J__5O777_UU%G CCChzzڎz>٬4{_NOOe^裾/_ԔҒlyyNj4b???ߞkjNYL;}g@vnn]{=_] O|\ޞ]_ϋlښ7z`ggǮ F}ew6z{O~///>uww;NL ;ނ˒5|??[pc a2iTXtXML:com.adobe.xmp Adobe Fireworks CS4 2009-07-06T16:49:55Z 2009-07-06T17:03:11Z image/png  IDATxip$u˥2k/ hr_$Je-$,-Y dz-;^F)ٞ'yLMIDQ%q&w  }}ȪDPؚlD!w9{eY-,7[-[ x 7n*n1-Tb[ŀpSqoM-[ x 7n*n1-Tb[ŀpSqoM-[ x 72_Xwmyˍq#nL, ?(0 r6eYXXd>QɗAV[i (eˤo2S,B4͆t`Y_^0MDI2ͺ("ndԣ P]$ ]睲g̀eݽwS3WFzj(qY!y*˗ X$M==AK[|!]P$D,D41MBEZet]D,t>4ӴEi0A% LDRi.2L %k$ae!" E V īdz0 [X,]1d/|/~IbUNqoG;N{/ֿ5M/3yhްd_?IGJÓ;?ۣR,u~WzSOOpqdV2UĢX*!nȏW@7Mk_@ 2@P@R]^;ħ2i].Coɉ n/ 'Vez|}L^F4(Y.}"BQ1S@vI\[tww3::LY ݶ+>h}av4?=wM {^\.O_W'sWnfǦS32٣?OZaXBdb] Z[f1L  @xC$RyYz"D>̏~-b4EMj&0~.~K3u'NϥBoo ዌ(zx2e X,B'ᅨl=ͥ #ٽb`7iX*BZ 8>i5\"EeDW H'S@_[Z^Z;$$)JZe)Ʀ(JDg}YzP$N m\8G<.[;LMst |%EU(s%W/Nq};h.Hc3(hs3Q dYXR<M_">kr﹟man۱tl\aLYZCO%\L#M aN!~dö}793{y䙊i De`d:I2ALC9>F<6,{1[Be:M:iR t t^ ٍ*Gi8'0zO̽%y4M^[%;7Oqp&/7EL3%4)0;=A4[fKCӾ~#dd*AW{YqkMuN~1MD147 ]]g. Hx\ [,ô(S>su[ve FHB.M%$9JI\2 ctr7Pjtt2;=L&N2emtE9زaJ8D{H!( MyfA[g?#eY|ߴ,A@xX%]b@r# 2^Dt[%,-$T)j,W,rt).t@qEJrpIrUUELK@qɔcj9:zyܘNJ dt.[5bY&KR*D.ETҐ%]$V^^,rYCx( (JȒr躉ףR*jen\nXH"膅&ˢ;B _ee'no´nvib"bZ"`" #KX=Z( yϹf{iV2 %3lI߾X~Ւ#"v) 5uY,kC5egοZsi˔'fyO SL1UNݨEܵzT?P?R6k?'x' o6Y2 ((V֐eБE ò~0-Pk&dJ.UT*ZV)JJ\BQ4MG|#TfR& $YFt\.W%WUNRRVSiuCX)S].R UUnbe\.#I3B~}Y劜Y,iseʲigǒr;BЄήN$mmqB LOTA5 UQ ~R$twv3=5E{G;SSttt0d"? RL,TU% IRNtfNb-XHKM_(D>0}a4QUB#L,i:;;Fttt055E{{;sssA,^MEIRMMM$ ژ)#,Ht:T*!˲-Vr2 @D"AKK 333}UzO"xWUe!4]IN"?ƖڣaH XS*JEʑGG_˪LD5=a5-ע: bsr$I¨|6n(}fdDAT* bbbロItDQ"^p8L0DeG'2L^J$!}{YNkk+O<[nŶwBFByx/s=:nT2A{G;>t&[usnmٺm P*e6, j 2<2̾{i iem۶399A6%+DQn{;'O+CٹcMd2A<gNaÆ $?<Μ9ƍ9rdHh eĪ|ȏ5&8וk@]]d8Q,k͛esW b׮]:qRt]^vP(rRۉL(JeYD7t\ 0 26)&$"i!RT=(JEQvOmKqx1-!J麎$JHEL&0/|/ 6mS\| C7$ Yymn,nMא]2tRk~Z& `|t>111AXV>Hk3,3a4) ȊL _jExAS+ۿ}1<={~ a"buQ(ze|>9=,J ###N~~7r\/hx<^WFss3}$ ~?a`&8i,]]]l޼d*( y:::Ї>$d;vw^hjjb::(\#R@ (ٶշ ׁ80Ȁt\.{vٳg)Jlٲd۶c! $qy{3O?úuwy'X>B!N:0]]]ݻ{lܸ+W 2 ͩSعs'O>${/O?4eɓ'r  X~==_9x X|>xf:;;9q۷o祗^{LСCyraisR{)֯_W.^ȯ}vyf޽e{]F(B<QN:}<OFۈbb1N:ŹsPU-1`-|>8$3T*y/#I2q{$#^gݷ H%"U,tΑɦ8|o=N8%d29;:, ;`]\2L|>G.C]|>JOjxǏg>Jsss,ҥKr9FGGx<3==(nR 5tG200گ23==M0t ۙL7""J4uRu۔i$I;<#<2ڕ+W@$^/H7299^X,a<Pnrv4 ( T UU^+J9ST .0;;˶mۜt|vrvo e@I$Q:d2YSSabttխ2n˗/ىis  ň'U7}}$ {MllΎEr,01L r)HȕIR'chxrL$R\l۶~;v8CQ46mD2DUUga||.]D\UU| sNϲ,nv,"Dxavva.\ؽi_ /# bљ, E$q>.]ijjb׮]|>ϟ4Md2X4xYQ++! mvh&l+Nq`v|$Cd+ɶt w#,N\EMӜ|iWͪlFݼt5_\v昫v6W|G $EYlH3!PqCk`{jEib תP^lΕ{`GK`p2^X1C,g,jiPv-r*MA,hj媛\nhrϺL:{vu~V7b =WEmc/(J)Q˲Kc5ÀV!c *$ =i4`,unZay?3Rʒ S0-Qct" V4@uh F <_eyf^>RmZkaRak3鲝‚ ϫ*VFM "%bHQ+m!ro{;[6oG?z|. (B:2-7 == ]"a&\Ap3Rb1o7J  ~ƵjY"t[z_X$^J⡨sb=[p~nBOOO˗hnnfeؼy C×xfLOEeN< C--r_M7ZϪ/dG ذȥ+gt52oUfZw ,XdӢ 4: 5r/>R%I&mwzkEK DoO2Us\7]Rі2-[5*3Ą&HKva&ex[E,*k4MCgQ&lG:jj/Zq^*Eh0 Y[E2b UK.ga 0-6P)Q%"ꥳr4[ZSo*Ca-9Xxs VUBQ:cߴ5ˋ`'M]Vzn}'u#yu F ~ LL%Pezba`va-2` X.}vV".,w:*ޮk X]6w 5 j/Z5(\(ρ5ʇ%[uê XȅZ{ҘM1v_e--2'Xo97+a%J#fZ{I4|K(,}]p?Tȯ`ueU%(avj֊a/z"/(/Y Y+ eaU,"Bh5NTiw j @Na1Ky[7r$X^4\RsfcԚpw1q' ~zL&ѣGW,44Ć V,mu}\)Ts_ֲHv c ݮWb;mmmKuKo;|5?C;&ZVi(5 `77 Krk6A.gϞϟuQiYn]ݹuZZN['9rdM :a':ZĈFx[M_2^)c/Z%ԙ{*+ [vXX*ޒ K啃~.\{Nżt[Cu󕛮'IkCkk+>י%` ]._/Vπ22O=o&bt:'> |%HH"O !X.G(RG}t&v~_%Ni|s[Z9wy;%K*zˑK͉fyyy ] u?br9,<岆[X,.WʩmZidҰ#W5EMVFJ=h##ak[Hv EQjDBB|`3x<L\%L.Nn@5ZА0%X$=nKa'px܅WBZ^ldR7\jXwu5ziYL-3-k,ep)F, KM`+k)|{Gi tE3! .+[B˪v%X933D y6l@TQ{@Ӳ5Y_EVS  (K&}^-sElNwxLh4֕P.WݴPQ'Z:]s:vp˲ּELt/2쀆M\;‘9,VG8*rlVTPS݉z4TZB9QoKuk߫1Y(7\0 q).]`E`hh??gnn&fffP`0H<wAf||}LMM d2_[sBK60eݺuH=zY h՞$_%4Mc\rxphhq^/\nti8pQ:::x"CCC\zHi[ (pAΞ=Kss3\t T۰yuʘdjjiʕ+tvvR,Ql6atvvrU0lܸ{P(fUԇa6o(sssJ[lȑ#455qQxcI+.n\.]QUY<{X,*Dm۶fٷo/_0[W$!B!8?O  L&% QN`Cͯҥk:~L&"NbXE4rQ,IR$I"nh4F6EUU8v^zmbBUUIӄB!gk-Eջ PԊ4JIJ,Bb&(Qd2IGe{`0l^&/q t]G44ft]5Z/2ZVQizz*L4btΒfd2|>'O4B$I$Un`O{.4M&xhnnv6 ('H9Gj!%8/null,^a]#|f(i266Foo/lP(Ĥ]!`R p̖۷ogvvАSO(ٳkD$^MӰ,1d2tvv.چV<1ApdYn]J;!I`б 2G^?__9eHD8& 9{9#chhYv*b]v}Y:r94:Y;JvIR~G9==lyz->(x^ R)<rٺJ#;_H py<4MW:<^ -L&(P,zd2\-,pI.R 4zJW[ZjL;c0\'Nz)JyVIKkK+a8{iPǃ8aq)FUUx UUt:#9d&;[*RGe._])x:r9ZZZ]b:?7/Y$ZZZfN$vI&F{eyQfD|nڊH$hm-iZ((B$P(8LnurBQ۽Y&&ikk0 ڈFOu;45(v Ôe ȲL(rޣapx<<gUttt 2MMM:rdkk+R UR:#Ap0̡CLOOa.^lxWFGGikk#K/DWW rgS徾>N:É>|R\.s:::!jM;v@ @4e;Dgg''O8~g``W:y:::V|E0455q)xWx˖-\lt1ϙ3gFݢ(:;yVyWiiiavvvQp8ӧW|/xE^ۢ\zŠjaq/{kO` i&˽#k3Ǘ85 ޷=V 1cs7JKo4p5[be2K.WkYrܛƨ^0^sc Vy2ocOqHo$cBh9ci8|X{yxXQ4OXK~+6S)k876٭}1᚛FzpgTzDUmflw -E[גgE~6V/V%ύ[Zc fw |FF 8ba(#0;w׏cNt]?!y{eh4ʶm׿$IQ(|KP(x<RKvԍYBA$tMCv=r[P(pn"y,U)K0tI-r B(.bGuS,pbP.Pd#i9[e K2J2nMXvS(q+*r UQ%LӬs%Sב$!K2es st\'aeUޣ㪼GeT1BJEeʲȟ:u'ISVme֖Q{zTOMM9eBZo{KEpQfff긴{(ڢx^oho S՟FjYOTDʆ:}]Z^eAB mDLD\WȆFIѪHe˅(HW㷸0RǕHkZm\/8CNI@>oɩ)2 OΦb5553re ܊;w2<20۷%3| ;!`p`\>oOie::vAl6Ɔ g||u9rME)TWL]k_B%~W.qV_b**;ܼTMBza_5ZX, kC%p³">@0o|TE!6;KkkGv}v~s#Φ)BA‘0ws'|> 55iW^&Uvǹ;ijjF=L$) ~~^yDaBh }=P]՞N۴3}ߛ(! 2=5i㥗^Fe.\8ϋ/(n122:DI6oH>#IJ, mmmW^"WǯbMK!HnFUT‘Díd+O=fЇ?Ѝ!5zNk1#ל[YDKdh?p0gxGϡu&&qQ$сklټuxǑdw0<2B__/W^x"Φ JF$db!_Z5U2YSIGo||d:G'47p1 $V^"7Al?ja6_+X߿.k+KVCp (!XuV24i20 :::p{$)"T,qUW(1/Z؋=fZ&>@p 2`Qp\33 ],aQ0]M9Kc^Vh.ٍ,)P֞/ް%6JS-)z+!(9wu477Ÿ{Opd$MM|.lij a~[ U0 ^Ya=/t͸,T 0+<_Gc͵!y^fjM]˺!QZZ"Dgtvt1==E{{GW -$SI>?|^;bXA6nkÑH sHD2IS(TqwS,p) a`ڊO6&j"6;K[kMg[;3ZۉFiok'>7GRiȢ(J>tD֖6tut1,-D&,Qs9L?@" 0WbD"fggD"WUWUtCTDۙכq+%ɶxɤSf$!ЗH$hnn&Iӎs"P,#B|c#lٲCbm/ؾ}_?!"]ݶS1<{ q6_(q{(n\FmCX1cYHubDC5,/`cQ@@:RkYhn:b-=Yev"Iyh=~:zu9xœ$:k9BTfjjPs ikogn6ǎ 9s sp9BM!n7;v2-ׯȑLNE_~ ?/} vwM&aӦM\plP0KvN"2Z[ٽ{7_D1w)"$%X,A5|7fgvu 1-pcVMYX\3?pBAH&EgW7r9N8_yB$h]ѱ+syW9~(i%t]%˨n ~(5JMM!2fbsLLL.㙞;gRHT²,GFlE ٳg$Jpb,PJʼn6{VggFj *[w?%qU^xEr,1, GF6ݵ6:7@_n2L&i 51ôL\Hxb^i`VLDY.p).Zۈ7ۚV8L"Du$qDI x) $RƢd; UdDHV+0 PT(4 $I4L\-p%OI0J* "岁 txUexʃiϗ!uV2 %O)KtwwR\S)bȲ̦'LOMU]K?'x=v$۰%elL(ih3Dž( vځ똞­-|.$IwOΟG+ittax&l۱83͑&242aRDFunΞ=M:O2@Q, tEuit"#>N8κ~fs8p^~ !dl[??~w/7vLt;wp z{x[mh4Jt:Js >_r}]w7qY~o?Ξ>K0|'> "9}`v֎O'?I\.\6?N&gpȇ$xaH/_Aҙ uDgxȽwLOrϽp% =2HLbc=FQ#kn#\.&&cZ#&''9s m ]"#pE"$ 'v ۭR剄#U0l<Ε+Wx  E;:/g{e8s {y߻(@ϲαDٵZnؕǞ63qBz\3i{^鴪w\SQGDR$xO }zX$ۃDܿFŞ9y-bc'~ʱcO8 Y*`~z|amciٜKzAqmIDATwanv%2οy\aooLF# 3jgvW`9 u},['m[#:PNٸ;_oNVzB.MNkfiM&gŘ06:9`> Na ?/2++,-UxW)ﳱ8Td:2<2̏~7|M#9z(kiLy.oC&''Me랦f)`;6cTVV8y/~9c[6C!~Lgjjfk 29n)+g)ʙ+%N؁mBrNƎrJ@|r=6i8`ABX,rwV<9N8AP #FFݥRRi2Sqv,[[5rcN(0558OlRԷϲٳg_qME*KK>exd_NLgΠX;zr+"4Q C:U(_T̚eDOiaH$31O=AN<|=xȕi>uy(eaazCۯz{KeBm{ PخoUbzr8O_ryk~Cyv}z4ڞ2`>£E,1K:sl.G__=~o3VWy!33ewǿ?.NF'ahSF Ņ3 /ݧ63P-BBj.Ӊ>RtL^zy,1>=mbHZ6ci88 Z ) 4\@cp ϭp-{P/Jllnr؍svv|>>FL6d4&Rj.~=Gy'DGFs-t+KaZ˲X[[Cmos\z>951Er0yTL#Yn `RZ.Q>6V7(gAC%jLq%Te\B4UB:P{}ދ\:Oc$6wWr &'&ն>C2 aϔu ʶ{%.S'ՇM:h""BSO9vt6's'>sD2cQ MmI0Mc~1 /iq,./>GY0Ifd~~RiGLё1"0U"{wt'&#ZEJY\\Y"[qM6s=|_-\c0_HiG#FGG KKK \Pmv~Vk NssLM<##,Ut{Y񷾾AOONDZA0-l5c{<++ X^^eblJJtН+|hܟB2 >1hӊP(,J+#:긧˗/7 y9rwPTկ 0 }r9z{{^;:y2 űu ǹܸ0imG3DHMxyX絲pmsu+,,D|e`)K g[v@v鍀)p]2r2dK/A$be&d n:7abM@ZӸ1!v_=ͱ:?(١ MFcgiڎ^a(tnji7ϟ<ʲЙ2QZ$.>0>qJl{3zv=13mŶO~yeab~L#yNa|ippINM* >Z7">/ߖm}nJ#*hR?MD.1k/u0zl_&3@@|2,S!# a1#[zhzbM$6Oۯdh7tjU_>m, \$\{ݢ3b[^@5M:Bs&mwˤ⿶#KO.˒ɒzF*yO@<1a|o5\ю1㾠0xĄW·y;80ҟ=tfcV@_lO4aTt47 =s_T]p,8rT]m)Ӂ ©ԾMO@ u)CC`c< lk&:7^GL:B7C tCp82 ׷*w|\>A@eA>UuxPBÅg?BTQ>-<)\WUdlj5PbuE8z E iY!QQEE+#aFdA"'/ʈ/B#ߏhS2C=dia0BeuӜ9u9+$ɰLnPAX4@-f X`iYX;I θI W^czu?g$=`EhZTl>m,!d >=]'HE:vem~"l;m|x+I3ΤLm6=`(+++ȗGImi$e-tyΏ5V&3b:l5_Cb;m7oSOnoodplۦ8ZQ b!w\;9Jqz&cͼ 4v U_ ᭷ {,//sm67uGhF۩o[+D#G:<)*/K{ Z5J<0b(gdUVV\\.Dbhy`V!LFꡚ5_BsbB\T)knAck3oAE#Et<1џCIs0StPm)9w 5wc &Gu#.1KK],f~`!8F-F-964t$|խ'5۞KUH0EW `"]E*)TSt*RLUH0EW `"]E*)TSt*RLUtov;IENDB`jansi-1.4/docs/src/images/project-logo-full.png000066400000000000000000000033431142666640600215360ustar00rootroot00000000000000PNG  IHDR(NIDATx휁8C/MhH-ڔny2!&570000000000000000AklDΏzs~дMP:>`?'x/GdT\ 1'gNPZ xYdds"#Gd{ bLOD Gwk;@% /L>XOAO.K3'M/{JNէGV9 0Jѳ;7?>%͸j~4 xnm+(_&x'܉Cy*ܡ3hI6ϡjN&gwz2`$]O&|l[.K.W{VUؿϪn5Y}&_*Lԯ6޼!_뽃)ûи9v{C_{MNQނiI->%Wuw>W}>U:EqoF9۷93CW(&etf>=?Mկ}ΌmfJ ʪtf>=?Mկ}t4QO ʪtf>=?Mկ}ΌmfJ ʪtf>=?Mկ}t4QO ʪtf>=?Mկ}2K)2_TbjQf/._*qy+c4/^RjQK:VtM|-,jQFRa(P7E]RYd\iUT*v}Y}UtW/?:EuTu~JDѾY_nӿjnOÿ^D0/pQY~TG:lh}Gd7+ެuׇ "4yP̓t^uQtPpѾ.Ot+Z?6G<|U:>F^lPgٱ9Y}ԯU頜>ڗW:t/?Z߭"Ҭa@/ɣU4 =b`s5O?뛬vl))J ͣ}Y}UtW/6N]Tn؜>WtPNT~QE:gGY!PTgmY噥3qUA7}M?t!=ԅ~X’Hk8R3*h+䞟srVPr/;<5n_)=e\]oiq!rDS?Iת'5^(˪^nO'?UCokp[xPf}?qECog\MZO>}z܁qQS(0d.b1~?6^B& r,o~:d 6\ꗜҗf ^1?`G5WV7]I5?_s y*ma$_-._n> '_A<.qɛiig~>RPCT1'նX䈭_؍nO+2ǴMywS BP( BP( BP( BP( xuj8HmkBF)38mkTSx}wƒ>&7-Yޒ{2sf~t}ryIQRl/> Hؚ(GxxOUu7f .r04~mN_S7x?:Aߎm:>:akgmoAǟv=?Swn9>oi چ6<&%|;.#(لK(1@'q;'#1yjlMAslA}PCZ]:iХ>mZt+m]n}Y ZCV8dwC`ky҃Ήq>mtN,t m,w2ڶGo`v %Ubf3cY=iW'hLll$]%3 ,a3x\i0x F0轅o{'%/8m#(GT .~fL1i:Yh9Д4- MIZ'AX) ZdqHqH[d}>ևox*4|{vky%-jimq!^.n їͳl? )׏֌ٶϚmKPz@yjH>'r"`uI|8Y 'O1Z;c9 !!DY Bؿվ|}F`rL.Ik´hfPs%9[g A3ht~' z,8J;+[3"ҟF٠%#K d49L(kGCC?d2L͠T6f39æи3`ypְ 8C0\>  _8?p_*$0uQZ#&՜Ok=Q?J%>QT8jkĬ(F6{g%1Kte%2N5cQPqde wҳفSaD]\AH4bgEbYS Nkjg\>@#T æBz9$3l^Bo̩WirsQ+4ɁC6C"`zSu8mrzR2ĦY%^q۵y8[c{) ' %Ӆ,0 edhriLr*:~&cE ~wHZ[' vBzgN&pw# /%!yoEq L$~Cps=ٺ*}<]x\h#3.)KN)pm#}+{*xRxpf%3Erq"}W qqmG 'VYVpm\4A`aw}zlp=6[A!BƁW69)xc>fC9j 䡄)'R!Z1FP ,,S7cȧnI < $:Km#Wvfd].FI0&5aDPqSߩR'פנR#u K0P  Y"ĝjN)iI`̗!MCz@ 4&USf hPI?y:SY)v>E}{b~Y]BjlM2?ίaI>V?jKw_j>Nbc3 kI ֔* da2Sғ&7uZejWzh?]_e_lQަ@|.e w.;N݌H0ܘ7χ07g';\e; RdPؒY5>b U7hR7#*-F!G9LəMf#9z *MyjIXC^p9mģ-$$0sy?ɟ4>ݦBaFi!|atQs,$߫+&(M=\`Y%mȑyR~ !PNby纉 Si8+] s6F Kp W$4g(l~8yl!O ~'HOSK8]]A K;tJ 7A7>c ~1 U)^rZRJ&lx (UO:"y| {O +n~z .{ŊN"C`,~-D׍g'<bYUfUr+"\n}@ƃb$T8D]&Qhns8~l@f$gW+cL7xI>49wbWèDZDo۽e=)ˉar*iVH/|ABq4x9iՙꕴHKCVFmuHhfJDŅsU^vݎس{vbow = `Qg\M1#h'|j6uiX#ȣU-YpzZ$iM}kHW+_^)۵|$~wI Y8g\\:, ř?f7Sw;ƹDyW5W ]1Zڊ+:>mb芡е+@KAٛ+v^:;\Qs;go3tghb芡+Л GWt+863OϧETqg/͊+ή8;l&wF̻i]˼>0tyW1tEɼ>0tyW1tE"F]̻+v.?;wC2*:CwG2*8:GWwgή2*ή8;gTk:%Z-[oM͆X[gkYeŖ!~n3Z2ˑ D>m't9ޫ|sVOkºވkSm~GOq}C,%iL/*{L_'*cݞh55zdە'[CоC _e_b芡+be'jL~6rE"f0 SY;M M"xg.||Z1RdzӍ`Xk{mm3|cw+b?`&b>}&@s%ڞG8(fsYZ -J ]_L=O}4up- H!4 I g[LQpUS"URF6we;t6G:\U^x}5I^=2y;//WjIjX<Ԟ2L~x Ǡ#I 1U4B~A^CF? + -]RWWȀOVJ)RY썄Mc/s9 *dS W/C;y\.]ـ1`,mCO tjZUMz$+<kT'&y߈^iLuIOb#_FOR#Y'>)rOyJksiWT¼'>S"ih>GiAյqjNU' 4T'm&a v~d|H|&`{?)t~vy|N\qAIOmBڸmf;mS7]ws񮃽No&Î`\="^_} \]ץݏ3E>᝽_#~{++y(elx"E]uhJ1ljD>-Sfd%F+٪C'ƚ} ui6a#6ߎ~8 ?⪘IL]&ؼ,($wu}ftQ-^͢Cm!?C3=r#_Tg5L2V`@O}buѨ)e`EE6IGi~ġE8P֤1J'何%"vRFQ}OWl]"[}:>G6BIWˢvgcSw\ۃz}9͊/ q=[N [[|aÌE/JĻ(7qX R#6YOk:e8k/w_F8tMuzmz(sz&IF̈́G4LHtj ?RVZ |40v7%h-dz Y9Q7h*Q.EQe&&UD*j+Q>xl5o2{8X#4#[xfFphB87+d]cdc:ɽ&jVA1^b1 @[N[_{/By?ywѻ^ʟ;')w:n6 {t:gels`xֺ?/QN_p@+i>0<.FYv=bڇ}%"Io #Ӧmp zK_S{6=~{_x ];2h=B+78cStpcI=8½sfhox72*A[J7κtا9ͻgp-8>o|Z h㳍6mq=9;huJilw/iwvhst;= '=N}FG3ӐD@G$!1f UMJRL݁][jZ qppȄ$yL=1m6A9akhtBv=GjAwOf[{mU0d߁y엿FSՃ)ekjlMAsl!K!.4 *haɨ6c~Dҭ.1pdX?!G~ls␶n P1oE8jXXv48F42q@?P}9C0GFlh1ha:CG~l08 Nbpw MuhI HA&ѳ@AZ85*#=jbN#PohNTig#ɁL1SRPcn(\$%|<7J<{h,F[v@ w, [2~>GB&MbCFr_P?_=Ǒ)93l$#SA#O- k ?xf?1>Ƨ4@((4^ 7ޞ^4.j%{udE"ǝ l"ļ 92O fożȱPNby纉 Si8+]r6F Kp W$4g(l~F["Ny69v?Se~S[,&7[=rαKJi(#99)'QIԭ$ZD%\'ee$g3ٕآp$[Ts;aT"-"ȷr^QӔ0q9HGN[> 8~rLZJZe%D_MR/'VVi= Q?ŝ'\>3NQNM&f%"|e٢Yp\V'-''ɫTDNmJG%<*)'1ٸY^^-jӔ5aҚT*3ES?zӌrDŶB5WwHhfJDŅsU^vtĞس{CkQ>jiF;WUN3EGUwl9Ȫ$ -Vywu-yC3KlB.R֭#3^7-YT|HfpƷaɲ2/qRTG {ئ$mUmufH6i4nxRKk91SEwiWs(wyI8r_o֩FR }cD׀cum\8tfP{Aߎj_P 6vf״TFߤKWl^S[ZM yJouK:J\E/Ӻ&| :M&.eFҐ k;ߒZ H!yؙGy木A\eHWA Ȇ_POe9=p`KXS}?pc٪ǮТ1BuevE]rUf-}V#$F3+ۧ #Hj7d?ҼT|!֐3R5Vr#Rkn87H|v<{UCW tb芡+b>Cbe3tb芡+.RPb犝2WT\sY[*]1ڪb芡s0,CkfG/튣+8:Gir\qvKl슳+9[dQ=`*b:;Gyv2* ]eU ]1tv2* ]eU ]1tǷyW}`*b犝N]̻+b]̻+U]̻+Ύ8gqvwV.[S35Z,+qfyys{d#v%nsr8+=O ]){bN*ߜդZ7b~k[ߑG\#~/? gIX'Z}!v剦Vħ1}x9!fh׬b芡XbIħ8%Mbt H:T%~f8{>`$CisBk Vtc8?X@[[ j<ؿ 뇽Oz@mƿ>\񾃶'69{AVBKkCSrxOS=y>6/t˂o#Үq. |BSr\UŔfHѽDj$j͑!W!{׻<^_M|Lˤ)hZoV23g; ӽ3%1Gixyk r _אJdKgxU82zS~(##Tփ4{#aX>\(Cd C"i#ŕːkfNt0kVU{5I_8(Uk>pI^7b4Wf|ғWHV룫>Ii~ܴ1q=U0ϔHyϑ#:jDFuPud&S=Ub1I $g_h329,y {]GY.zbz{buWaq?P>i{;pO8TB&$qid֦OLOHb~W!YM&hPSc{'4j:0~J!#mQz(8nlM:oQmq@tQ:5i| yo%g|IGx=Qd_S[WHVߡфm"粨ݙT]>^)vN⋰h\Gֽwg5_X0GhK?5.MD\.q$ yMįea~3t"<ĮQ;λr6]Sbݿ^e7w}ZkP0liIr#Fw&\za.P^}3֮(2\fyZMLo+օz'gPKZJ,Ų,A{k'b(zMOe_Ÿĸ?g\vI\* ߡ^o;*)oruGgH,u=w_V$_k'cXx5dY9|Iygz&3? EԮUW0?7yyVVU,}vKP̝U+X} 5f+#bኅz,«X͖?Տ>Ū2o",c3 Vp]lĊ_#!&1W)2&͢Z9trE,ֶ}G)\IRѬn3!:4R><+e󅷕m. ̆ cr9!a-,?#٠^|BVb Ǩk c|eege}" yk[ͼl{L9o1f]i[ڽ Dk@ 7ѷKQudA"uʈSfQ_w ̶vyLO({=p+Vg!Mw{,ޢYd/xƧq=M !Y:٘`r %8EP{X̀+>wH-sUaޤ7fiN6{xS==a^=/<Dž.~!z)n:1`$n{9~3`e?<›wBP]-g]:?Jܜuv3ٷSs>`]8mvC^U:[};;9vTÓ?GZ'K>#cxqi\m ȃ#Hma(Բ.8 XЀ&O6]@ P p {>&_j+qQ6m}ocg']Z6Ed5MYi3i$8VOjE@KW+V HmC<<+Z #AegmsOɷg&gpy^>`q2 B<BJ=mkBSx]N0QʫajohlU&fnÃsfd,>Op3]E1T яjV2ڃ-p uyGpodl`d/e>v 9]Aݩ6ٞGÃT{1H QlH':iуŏpa'D:__CEymkBT8x횉m0]HI!)$FR?6c>>~sm+vuՑνYu8uN?WP>1JsWiV_uKEϸ/rˆ_gKW]ױEYcl,[TYHT}xL#}A GV7^}>iҞ-i;}LJX&TP3T#ߨgJl e'=?͘ona|7>?ǐU%;/mN/IfQփz{G}?v✽3X~j{zTAO^ʰ>?sy|G)PEݭuVZZcQSf1̐T}* gq KX0&6o#XSJ!~#X!:4x Dsdெ wJ5AWb.:Y_AA 6!aHbZ֧RpL 0/utq6ܿIIIYMc\r@תU˾}wHPx4ׯ_VWRd6رc^㬊MIc']ߕk?PoCbd"g[ _C|р ,%}?j|@o߾]:|&xf̀7^?W^Կik^iaȑ#msA~7I.b۶mb'湂C3d& |GPM}[׿@bmA;]ヤ?1`!7ef 8|p@ܳgOo?HoG-[曮׫W/ף*Ux||_|a7֭[6ُƽ[˛~>}<ֳN{Ϟ=&*U2nM6wuߊGJZǏ~A4aaaYj{L)Eߑx曎ʣ=F2޼nsx}W[(i7vT˗[IҢRށLHkaԩS Lvg 'O߾}{^bE۬_^K&KXQ:Ck(a!w]޾}L?e3g8j'*T!!!f-HA=C}6ym{̋p-fj(>c >m4[oy,4H+..EEEŋ999%??_׿m[f͒> Oyioܸq|ƍr?Se˼Dԩϟ:xbDw^!CHfEBo'Nnj'L१q8O2E ٳ͚7sܹ{?s0ޮM;VG{?{hxaÆK׿I}@ |S* '? ί__B8>bp.]WgΝ;gʟ8K{?cL>;ErssyiibN9_ȿw޲@X,[̑ 6sÂy`laNxh"yq?$ "A?=K'e esU>4uԑ?Qw `a{oJBW0O:t_mG~SVau~KJdd>PHO+[|F {].,}я Ν}C/ 0@'Nb-ĢݿNS_"jZn-x}WsŎPϜ9SO-AlyfATTJ|Vk0d<%bcc%xGh?+W/+Vm?>7o<_z|Μ9|͚5z |_z5_d oҤ ]NhH,{3ʯ]ܹStӜ?ܺu뤽_;YW^G}$r"a#xvl{n9v6m$G ucQJ#yS|2gϖySuUsX+ .\(a&)xѻ I)IRO WqF{o|oSaAE( O), qT}V{ns_GFzEGlRCa=}|֭1T}iߕȇ:wKn OKJ6le`aiQc}TwP i#(4`fj'N?ʡP߱]G*׿ornT~?}ǾoVCyhb4t}a5Pi'h~O5<F,$?bgI˚G 6 MOyB[ {|>yy]+@[sU~n]97ɖ܋XyIHHW1Wp6jK'ٯ/p~ӇsP{h+X9O>nH#^h;=ȃ#s6Vux^]z+478܁zឋXMhO玝9c+_6#?" žwhAP^9҈-κu jNTyJBܔ&h (8xbvE˼)))b}bbbxjjL5з998@f͚)>ߡ|5&"e\73BPQE>i/--Mﲩcb⤯DVZ5i5+>,l^XCyPFi?@i8Xj&@ }c返gA we,XSρ=<3mdzr/lQ3mcss_;浶Lgwo׻gI@XjjgiЃ`0 `0 ?ϟ|:seQ3|ӧO|:2|.};7eGFO6_Qv]T]^ˮg{>pjzkuo{yye?{-x/ D:3D&򈼹e^Hyi#/OGzϪ߯_~ :sMe#M3Y#=2 QЙ[\s=E8}E>GȩT ڲTg-}VfoSVwzV}./>~!?U1<#}=F[ ~QڋBN..+푹^edLo+[\-k dW(}6q$#?z6Bөi?L7!3O_Q}Пuo[=tkȋM!'}/Ƈdr2_Cﲨ: `0 :8o=+8-4}۞cĥXdq{bUq©ήm!ƶg*ΪU\z[GA=^+ru{LV U?)V>ғ)x|Yҁgi\yi^cUo*= !TY?rfgWsʽVn*VX#=Fϫ+[F~yH\L~[O҇h5ݵTow|Sfӟ+);F;:x )/OS yUo2e)Ve3'wgGg=J^`0  ľu kU,Ksؑ5nY,bXw{ w&3QהNQev ]ƷgcH˞i{A3I8hwduwUIWq8I>+@pQşGcZ\ƪUߝ]/:3d;ɫ:gB9R|GW~w2;fzt|+i5nΟgZY|<1NyŬ|E7k?z/k><=Α}N΅>uWydʬdz `0 *\?W8GY:Dgcg< 2+'W6qn؟{ru"wU쏘~c#T?+y{Q,,^qF/Xv8.֩g3}ȸOP ~n%hUG4(_sn|W}Tg&x^c,Fѭ+ <#+}/Uw8BRh_|33!mr\7U9m({ѝpvew[xG]߱?g;,nҽow8]וb?OV=Z_#ve?vN_WrYLo;1g9pV^G~>[_vNOS3 `0Q[ veO\k^8֔v<Zbz\Opbn$~}oz3ј mK vU]^iNWA#x딫jt q :E= z%օq)CcYEqyRG-+u (K\hP'*^ء^q=m=y|Kvūe\rȊ4={W1;=ݷxp;o@>ȘT\Ԏ+C=*ɫ|GJOCW]x1.ﵠ9_Eб Vq)v(ʑ}[GwǺ{-oSdו_˞׃2;iT&w*w:g׭SOsj%Z[~_˯d֮+w]7 `0]kIu+eL]ւoA^;=GR?v쯱;<y o$N1紈=:ߥPVu< <&3KyC/4r)i=*/|Ύ^]QNН1qGw>ù{ ?Kv:A}E:_n+{u=rq͓̳]>>d}+|L01`0 leg:׺񶊝`W,3O?]\9P~[kOWiGc~)-<w.3q}'vuw$Vnv(r52S;Wk_Kϔ8B/hEՠ'9w?K;x:x<|@cϽVyc@ۖSw8Bq]=2lBe6V}eR( VeZT4ade2ޒ+nYBTqSߔ<[&=f[|szP)G}{Zׅ3n7jpWwftEw[ǽ;`l? `0 `0 `{~i`oLy>uoi\qK|}7Svu9G쯿c¾#>,jow{ՆݲL=mW2u_8دjo?kD߱mw>#}E:OۡO;y`$j?tU mkBT~x흍8 FSHI!)$FRHnw HYx3ꇤsaaaaxIǏ'U{o_ھgW9 o'GW {>~Jlo߾)*/N\ϱov[iZ_ձaJΝ/:6O- 92b?Tlk%?_21B sY5>:>c=1Ow y^- ڶ,XzusM#גU]>H_yYv!ۉ_mi Rus]Xm_g)YY)m]y,m z1aaaxEߓGקo/Y\k6xjgH|yu.\aæM&wk#ϐ$?]Mo\Ⱦ,/ڥQ@~6s?)}, l gX #vQg Bٙ^uのuhm?}{].~}v_J;xogJY]޳@.)oqC?}>@Xߘ'-(W? źvƔOʙRv[K?[A}?-wmՑ}g\=c}M ggg DŽ-B^k_g?F? v0||؎=ǧHPgs/hؑI t~{n^}ZyD5XWvO)"c0vY Z|~_%/,p\ɹyΰZ/;/xs_9?Pܯ5ݻ\[y|č8gʱL{? 0 0 _k3>z_\S |<)b|7aaaxn.ta?l^Cvkؽ#~e)3<3^kdlc&jK+o"e<.ʞ`^(3zu l+6v<ï k7]/lc[`On}򚄫 G뎱zt^v2)?;Wmr5ocIz?Ozx{&!ez."ѯ 1Gg{+ҏlw<=}GݽFƨ^)zIpG K֜{{e G12ۭqiumf>.}~a? 0 0 [u+7Svq֭y΅ ?ނ}XwŶv?ߩDZۓ-q/?߳=<~#>Fk"qzrQo 9r,nY[;o:)@-`ק-7({߯S@µK9֠ɸ>:n3 _[_*mtcmC>qSL=<6;ǫsaaa{xˌ\ފpx?0׋#5zяc]x^l򼠕(f:~٣^lin59W~\;?vn6erUbS~v^U O7O(|;+SG4|?f*?rW~2oNٟS9~daևmH6mX[J~s.ym4ٶO|Bd/b5ɿyU? 0 0 0 0 0 0 0.P~*1@G\⟿KrKXs2(ߥ纎J8'>X@▼QQbqwx b)_K|v 1M6kee-2Ǜ59?K^E~9ϱQﱮYF8N?~;:=J<-tĒyNAgC \NXKs)'^Kg\~2}6}Գ)n]Or^j~"{p29w6/.z-v:+M{WJYZ굢`% Ҥl9ힶկ#OUz+U?;sd~vND7*.Y+v:ye;8}~|+ÑޅN9}{Bƞ#txխsXɿkSV/uJ=o G<ջL'L:D]6jfgLz/+ؽ[{rCMYq~[{yy czA;w9zszWHVax3 ף*mkBTx}+(H,"H$"#X$,QԈZs>U{ ..T}6ڳ-F`p]k߅~b  О$wݓٱ|sCoA+q3lOx@(0a+? T,_7s\Ϙ^Bl1)C+k(FyN"8dPC_9>O0&l4Im+nwGrŰ)/tihf ѸX>E)<,6s45zb?J\<OM%O#(76:= ӋYAƒH Ls6MXBcX&ǘJte. 3.je(??Lj=%wZizFTx$kP8Em jAOހ>~؆B9 ֤8UKCvjbL Cy ;mj P. DkwUE€3ܨ8xUJs\ɟ+;}sFQ(KIXݛƨ 1 +KdX];Jģcx$D׷X`i @l̏rnm$^9΄zBGϞQ=nfkDe; <a>,⢞jk0B[p($Ǡp4 nq`XƓ vϵ.xHnorJ5Hu뇗 f a[Z:>36[g RL؍?( &w.7C#~B{] UW 71jk~ecGrD.=K@WDZM0倐0\xvqNZ ># BE )&yA}t?B Ym(WIpɱ |2+\2 )l8tl@Z.Be񅋍RSƃm>dIl'N adĢG3%#)?$s _5=YBR#-k"qGP-e"f%֩-ϓ378M9ϊ,_*n;HEBƱcl~ ˝[/sagIE2,z1t:kLș壋G){7ond{@rP>kwk׽ #kXfyEAB9uM4P=_lgW؇N#_nGpp ,ZUu6ȓVӰ0EK7*|]{75F\ԶzQz! uH>upT٣o3P)[^6` -d&*=%fY<^ط`_6|h3ء>2 Pq7ώ ,NsjF=B` 큳CiU)R鐏@LҮǧmb<2FHRqùFXi䎲OmGA}:*u f:@ʫRH.66jcGOpO- 6HKJU:Jǃv,3DZEƮqq7p?ȌK%ȧ$;?Qr6pP7`a^=R_)m>D3#£ _' Iɭu͋C-Rne㯄ssL<ȭ/R)|Lt_1Lk=rr 4/gEr~PnB[\g[{gYvRW' {Fem1{ wL;7&$xc0 n&u@5sCCձm8Heft x{q(aтa?Q%l4ςxmWI׆GC1kQ3iJh,KRO`ʲ4)%b6B8\pe;u)ko)#WSncRx{[sXv195_0Kՙ7>Tp5ٴl3S"؝LX睫[5m Q="u}pϘ*xbՉ#iM+@Z! Ϯ~jYݬ$?5mtu] %@݅:4h8ۃtu3; ΑO1A/r R*5i&j#Y2:$Z(ad@>'z L뇶6Z8|`6"X1_z' F-я?X^ A:?1;h/KVB' vOnFS ƤQ{=kh7MwXQp\v͓O/. N3HKRlK"q^Wh1wt h@3e6N|I;y?8t[[! $,ήLe"z%IކAkRl!3u8ځy?_W)AbCO!rza5Sn֗#<43y6"R߃CQ&>[# BHǽ{vekOTlq(UH͵h ݔ8,@tՂL{p/*L"d_y k,4 G̖bD>,.ok"D;|7[.DCA#ilϟI֬Dq]+eE _-- ڰc^Lq1~CCC9gNH8BkhJ#Z-`VoMa 9r$պZ-hkh ?C$ ^tď9d(8P݅]ڶw[wl;dn׆oKd Hބ(DInI M_(5)6H/Y1 QRk,nXHʉ?>df&6^EJmt{CCc`0ʅv5x<\9Yc}106"״!֏9dl:' 1H"z'7QqɌ#KR./CVgQȬ\ `?d1yuM6Ƶ8ZX]8^pwQE &1frRKi$GݜЕh3'{;;~FK37ku<pdʎ+C RMzƏ7)nҀ lEGyl:̑IoBS%|ЕsTulebA}Aʹ10A{KʘӺtjdLI=r PRg_LbR Şl?␔)![Fo wi&k^CV(t@pW2{hxHGRn͉eCbxԉ6GQd27\ثdS=\Ff*0ۣOP5(rZߙxQZ>~GAeN-jY7Ҿn;n?ӹ"Px}/NW:݊&׾:x" ꭥу;R펔 c䛅љElmG§a= h¨BG_uYnZ쫭FYs U"zM&:Gnu.DX5Xn;}ԫ%XO?~2&Frjj8 yA*W I9/ub)Zl: s 85J>~iI3Yԕ;:#hELם[ROd^GA˩f~Y!En0~/A Km>^WYq"<цF*c:xw|͞w%ehRgd9̕v3v Dgh>>?3hYDkgC(ʹƒԕSԜ| 2Q94(?OGQ34 fccPopTYaW(>@tX4`LGٞpɄaŰl\[9c26U M6f,'C4i?W~psϠ?kAKrŵk@I|>^xs?\`,D̒5W^w DMXf_8<%|8_왉pP1Wlm߃f?4:́_Ԕv M;k:p_sj؎qw]$F}y ,b'N=o0, ~M YR46+!}@~ujctCP.Y(x׎z?70WXFܣo3z0c8RGg0 TU򄽻w"/4֏CQ`[{Ocn]+{{ N!33+5]qpj' r9FDȬ)~: 9Gmx2-?sraG"yvUpa;Ră A\& ?#n 0eed~oq嶭!!DzP^H)>oȑ.ļԶ=Hy7S-M ?8ycߧq|#5"2Б lm#UeΤVbM͘jAc7Z ]> 4gb s 2WRsKg6 's8qzTT[R[w)I95xWj #!nN+zPڔ KgTE,?{^RDݥ=Ru^zîc&D'i74SJߔ&HUG[crͦ<׿~4}څh;lpAZ%XZ;tQ?yk1+Ƴu6[ Dc4Ɯ*dB#!}e>samhG3c^8u9󼵕⸈߂UyB;f "Yi=D =4&|C3g]~WgjhSIXU"1A5Fr4{AljwTt6</N \Rta| i>T.Wo>>xϯY{緷m,J{gg}v~)]s!?wXGFl!7U|Cnfﳅ:.@mq%臔Ru?.:aBֺE#Gg'yXDuSWNJD)21ѵVagWPqȒ s?¶@g")s\T{f3go^w:^"{d#!φt},nyWFKv„X4|VB~,˘_&fjp/WԍwaO H 3I`u1ͤ+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_W|+_Wݚw)mkBTx?H$Wٹ[,DS!9upޡwpE@@BTS+F1%6Bo!,H,ABJ_KV'n 4fgv1FoLKhDsG{L&eD]h?`&=*'H23XTeALCv뇩JoooG?>ܸkkE-3r]www?^txx}=|}}jLJ pr'1V"|vٿPEEE9%I|Me}Ӝ=|&)=ޞ/d>TPP$L"ccC:;;s=?trr]sWRggsttDɌp3TWW65551z@Xp#vŝckonn'ᄍjmmUCCCw@{_@X߯5MNNjeeEzKύ?aI[Ԕ;='.M|IeO333u2_sJӪz7Qoo411klυ'=]{zz4??9?88mϋGeCCCns}iiIn Sn~/..VEEJJJ߇VBsYw{L+sž˧/=&aݗG4=k/_12iTXtXML:com.adobe.xmp Adobe Fireworks CS4 2009-07-06T15:13:32Z 2009-07-06T16:49:06Z image/png aJIDATx[WZut=_ $+J@q<%$+%Kv!JH˲"v_DnD] K,~XE!y"'gcLOwUwuWtk<"_*Ows9 ;X;0G`nOlֺc āN{%Q/%,~;$py@3FO XHF9_ZI l@ NF̋] ~""p??<Lˍ'A*#_4a/鷣 Ano`t @Ggzw⹋x뚿uVuk<+JL',L}۶z`qغf;oN,S+WݥM>FIr,zakrT>}t{RP@)K\)zK8s.AݼwMw´9-x>\t)R{i>5~!ޜuuBW@b"I/NwԤkkHu |D0M>BthP g? 4$o\WN_C <؀A}!z0s@7t)`@|7mvt,&2a5 |x #TmVgT7\(B/ܩnhV)vemw|46  zM\D"ijjJK+%-Lt:lۦ\.3(xd2_Y\lbF|!7n>7o~?Q_z5"P}ROOb&9#uϜ9#z ߿0Ms_}?O>-H"w#GKC?tP~O<)wg٩v3Ȧm yj5bB>1ǏqˏKV.}bW_}BNywd2޻f:XX̨EpQ&'{vG)$v YmRMz+ՀyضM^Vu5nAmj5:jrqbs`p]۶qrY|RT*u/B.J[YqcA?#[^uW?b8r<1٬*c`x 6i;z#/=qMW<.|X~HGځ?j;l4́laۂmgPAvS{ [8uұ.eDR>ް{?~K_D^8{lD l6ˡCH$%Qڥ04h&DT@oewV2 |إ]Yec]!^=caas.C9,4m9rUiH ^b1T3ST 44 Pu\׍,o`MӔ #&kP1 !i4F}Gu 񝰽^7oOwA8<*\xPV#gחs1UaÆ ;vbi[p-jy_N<<֯_ϵkהK{n._L:q{1nܸ^^Bԩo>2 Wɹs:ީ8|0i:rY ivv qe9B*RZt≮,..~ze,,,a%`]V <3T9ŃD"˗`ꝯݾk# o!x%M0hoQ0c op=#!Dtw {_ MC/ _c1[:m]m8f~D5j

{title:}

Posted by {author:} on {created_at:}
<% if node.node_info[:page].blocks.has_key?('full_story') %> <% end %> jansi-1.4/docs/src/styles/default/css/000077500000000000000000000000001142666640600177535ustar00rootroot00000000000000jansi-1.4/docs/src/styles/default/css/site.css000066400000000000000000000071551142666640600214410ustar00rootroot00000000000000/** * Copyright (C) 2009, Progress Software Corporation and/or its * subsidiaries or affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ body, html { font-family:georgia; color: #666666; } body, html, table, tr, td, tbody { padding:0; margin:0; vertical-align: top; } h1, h2, h3, h4, h5, h6 { overflow: visible; color: black; } p { margin-bottom:0px; } a { text-decoration: none; color:#00AA00; } a:hover { color: #820000; text-decoration: underline;} img {border: none;} a.main { font-size: 12pt; } .wrapper { min-width: 762px; width: 762px; margin: 0 auto; } #navigation { width: 100%; clear: both; font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,Verdana,sans-serif; background: #0F0F0F; text-align:center; padding: 8px; border-bottom:2px solid #00FF00; color: white; font-size: 10pt; font-weight: bold; } #navigation a { color: white; } #navigation ul { display: block; margin:0; padding:0; } #navigation li { list-style-type: none; display: inline; margin:0 5px 0 5px;} #overview { width: 100%; clear: both; padding: 0px 0px 20px 0px;} #overview div.logo {padding: 0px 20px 20px 0px; float: left;} #overview div.message { font-size: 14pt; } #overview div.message h1{ margin-bottom: 5px; } #spot { width: 100%; margin-top: 15px; background:transparent url(../images/spot-banner.gif) repeat-x scroll 0 0; height: 277px; } #spot div.title { text-align:center; height:25px; text-align:center; padding-top: 2px; color: white; font-size: 10pt; font-weight: bold; font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,Verdana,sans-serif; } #spot div.content table { width: 100%; text-align:center; color: black; font-size: 10pt; } #spot a:hover {text-decoration: none; } #spot div.spot-balloon { background:transparent url( ../../../images/spot-get-involved.gif ) no-repeat; background-position:center; height: 121px; text-align:left; padding-top: 25px; padding-left: 35px; } #spot div.spot-balloon li { list-style: none; } #content { width: 100%; clear: both; } #content .wrapper { min-width: 700px; width: 700px; margin: 0 auto; } #content div.left { float:left; width:200px; text-align:right; font-size: 18pt; clear:both; } #content h1 { font-size: 18pt; } #content div.right { float:right; width:450px; text-align:left; } #blog { width: 100%; } #blog .wrapper { min-width: 600px; width: 600px; margin: 0 auto; } #blog h1 { font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,Verdana,sans-serif; font-size: 18pt; color: #00AA00; } #blog h2 { border-bottom: thin dashed #DDD; font-size: 16pt; margin-bottom: 5px; } #blog div.post p { padding-left: 10px; } #blog div.post .details { padding-top: 5px; color: #ccc; font-size: 10pt; font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,Verdana,sans-serif; } #content .post h2 { margin-bottom:5px; } #content .post .details { color: #ccc; font-size: 10pt; font-family: HelveticaNeue,"Helvetica Neue",Helvetica,Arial,Verdana,sans-serif; margin-top:0px; } img.example { padding: 10px; }jansi-1.4/docs/src/styles/default/images/000077500000000000000000000000001142666640600204305ustar00rootroot00000000000000jansi-1.4/docs/src/styles/default/images/rss.gif000066400000000000000000000022161142666640600217270ustar00rootroot00000000000000GIF89a9ܵx]sX{8XQofb+Mó[Ii᮳㲹,H_~6T&D9tse~AŎRxAav=cQmEh4Tk/Lꖴraz-P떫Lq@[g|kPq\Fe)I=Jj[굺Xo䑬pZt}x[tCcik!:k茵2W0Pk:Zn0MX|Bb!BJkAb+P[z{JiSs骶Jc3Qd|Sq1RbjZ^u!,!t"t@Ə#Hq ?(!e AnA2g&YeŊQ8d +Kx` '#j‰;!K:M:B]6dSy0M><' =AʒL!𤧍< AxD4wxQA>9@えAX@ix 8I͙cE3x#HF5 A6+ &IށH@͗N A^\kP0`@A>hqC[AÎ"-@/d/4ET@!P1v衇#P0(āF 4`@;jansi-1.4/docs/src/styles/default/images/spot-banner.gif000066400000000000000000000002041142666640600233430ustar00rootroot00000000000000GIF89a!,1pI$s`(Fihjlp,jxKpH,Ȥr;jansi-1.4/docs/src/styles/default/main.template000066400000000000000000000043531142666640600216510ustar00rootroot00000000000000--- # Copyright (C) 2009, Progress Software Corporation and/or its # subsidiaries or affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. template: ~ --- {title:} <% if context.node.node_info[:page].blocks.has_key?('head') %> <% end %> <% if context.node.node_info[:page].blocks.has_key?('overview') %>
<% end %> <% if context.node.node_info[:page].blocks.has_key?('spot') %>
<% end %> <% if context.node.node_info[:page].blocks.has_key?('content') %>
<% end %> <% if context.node.node_info[:page].blocks.has_key?('blog') %>
<% end %> jansi-1.4/docs/src/todo.page000066400000000000000000000021511142666640600160160ustar00rootroot00000000000000--- # Copyright (C) 2009, Progress Software Corporation and/or its # subsidiaries or affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. title: TODO in_menu: false --- name:overview pipeline:haml,tags %h1 The TODO list Stuff that still needs to get done. Contributions Welcomed! --- name:content pipeline:textile * The default color table can be adjusted in Vista/2008 Server, via SetConsoleScreenBufferInfoEx. Consider adjusting some of the colors (especially the bold red color) so that they match the colors used at: http://sixteencolors.net/packs/2007/sense27/smi-ar.ans.html jansi-1.4/docs/src/virtual000066400000000000000000000017611142666640600156320ustar00rootroot00000000000000--- # Copyright (C) 2009, Progress Software Corporation and/or its # subsidiaries or affiliates. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. in_menu: false --- name:content pipeline:tags \--- !omap - /javadoc.html: title: Javadoc in_menu: true sort_info: 60 url: http://jansi.fusesource.org/maven/1.4/apidocs/index.html - /development.html: title: Development in_menu: true sort_info: 60 url: http://jansi.fusesource.org/maven/1.4/project-info.htmljansi-1.4/license.txt000066400000000000000000000261361142666640600146700ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. jansi-1.4/pom.xml000077500000000000000000000332771142666640600140310ustar00rootroot00000000000000 4.0.0 org.fusesource.jansi jansi 1.4 jar jansi jansi is a java library for generating and interpreting ANSI escape sequences. jansi JANSI UTF-8 scm:git:ssh://git@forge.fusesource.com/${forge-project-id}.git 1.0 http://${forge-project-id}.fusesource.org 2009 Progress Software Inc. http://fusesource.com/ jira http://fusesource.com/issues/browse/${forge-project-id-uc} ${forge-project-id} dev ${forge-project-id}-dev@fusesource.org ${forge-project-id}-dev-subscribe@fusesource.org ${forge-project-id} commits ${forge-project-id}-commits@fusesource.org ${forge-project-id}-commits-subscribe@fusesource.org The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo scm:git:git://forge.fusesource.com/${forge-project-id}.git ${release-altGitURL} http://fusesource.com/forge/gitweb?p=${forge-project-id}.git fusesource-nexus-staging Fusesource Release Repository http://repo.fusesource.com/nexus/service/local/staging/deploy/maven2 fusesource-nexus-snapshots Fusesource Nexus Snapshots http://repo.fusesource.com/nexus/content/repositories/snapshots website.fusesource.org website dav:http://fusesource.com/forge/dav/${forge-project-id}/maven/${project.version} chirino Hiram Chirino hiram@hiramchirino.com http://hiramchirino.com GMT-5 org.fusesource.hawtjni hawtjni-runtime 1.0 org.fusesource.jansi jansi-native ${jansi-native-version} org.fusesource.jansi jansi-native windows32 ${jansi-native-version} org.fusesource.jansi jansi-native windows64 ${jansi-native-version} org.fusesource.jansi jansi-native osx ${jansi-native-version} org.fusesource.jansi jansi-native linux32 ${jansi-native-version} org.fusesource.jansi jansi-native linux64 ${jansi-native-version} junit junit 4.7 test org.apache.maven.wagon wagon-webdav-jackrabbit 1.0-beta-6 org.apache.maven.plugins maven-clean-plugin 2.3 org.fusesource.mvnplugins maven-uberize-plugin 1.5 package uberize org.apache.maven.plugins maven-surefire-plugin 2.4.3 true once -ea false ${project.build.directory} **/Abstract*.java **/Test*.java **/*Test.java org.apache.maven.plugins maven-compiler-plugin 1.5 1.5 org.apache.felix maven-bundle-plugin 2.0.1 bundle-manifest process-classes manifest !org.fusesource.jansi*,!org.fusesource.hawtjni*,sun.reflect;resolution:=optional,* maven-jar-plugin ${project.build.outputDirectory}/META-INF/MANIFEST.MF org.apache.maven.plugins maven-release-plugin 2.0 true false clean install deploy -Prelease org.apache.maven.plugins maven-scm-plugin 1.3 org.apache.maven.scm maven-scm-provider-gitexe 1.3 org.codehaus.mojo jxr-maven-plugin 2.0-beta-1 true org.apache.maven.plugins maven-javadoc-plugin 2.6 *.internal true http://java.sun.com/j2se/1.5.0/docs/api org.apache.maven.plugins maven-project-info-reports-plugin 2.1.1 index sumary plugins dependencies mailing-list issue-tracking license scm org.codehaus.mojo surefire-report-maven-plugin 2.0-beta-1 org.apache.maven.plugins maven-plugin-plugin 2.5 graph org.fusesource.mvnplugins maven-graph-plugin 1.5 release org.apache.maven.plugins maven-gpg-plugin 1.0 ${gpg.passphrase} sign org.apache.maven.plugins maven-source-plugin 2.1.1 attach-sources jar-no-fork org.apache.maven.plugins maven-javadoc-plugin 2.6 ${project.build.sourceEncoding} attach-javadocs jar download jansi.release http://jansi.fusesource.org/repo/release false true jansi.snapshot http://jansi.fusesource.org/repo/snapshot false true jansi-1.4/readme.md000066400000000000000000000056471142666640600142700ustar00rootroot00000000000000# ![Jansi][logo] [logo]: http://jansi.fusesource.org/images/project-logo.png "Jansi" ## Description [Jansi][] is a small java library that allows you to use [ANSI escape codes][ansi] to format your console output which works even on windows. [Janis]: http://jansi.fusesource.org/ [ansi]: http://en.wikipedia.org/wiki/ANSI_escape_code "Wikipedia" ## Features * Implements ANSI escape colorization/handling that is missing on the Windows platform. * Strips ANSI escape codes if process output is is being redirected and not attached to a terminal. * Easy to use Ansi escape sequence builder API. ## Synopsis Most unix terminals support rendering ANSI escape codes when Java sends them via System.out, but when this is done on Windows, they don't get interpreted and you get garbage on the console. Furthermore, even when on Unix, when process output is being redirected to a file, you typically don't want to output escape codes to the file since most file viewers and editors will not properly display the escape codes. Jansi detects and abstracts the ANSI support provided by the attached terminal. When your Java application uses Jansi, it can always assume that standard out and error streams support ANSI sequences. Depending on the platform and if the application output is attached to a real terminal, Jansi will do one of the following with the ANSI escape codes that it receives: * Pass them through untouched * Filter them out * Use platform specific APIs to implement the terminal commands represented by the escape sequence ## Example Usage Enabling the Jansi ANSI support into your application is as simple as doing a simple static method call: import org.fusesource.jansi.AnsiConsole; ... AnsiConsole.systemInstall(); Disabling it is also done via a static method: AnsiConsole.systemUninstall(); It is safe to call those methods multiple times, they keep track of how many times `systemInstall()` has been called and only uninstalls when the `systemUninstall()` method is called a corresponding number of times. Using the Ansi escape sequence builder: import static org.fusesource.jansi.Ansi.*; import static org.fusesource.jansi.Ansi.Color.*; ... System.out.println( ansi().eraseScreen().fg(RED).a("Hello").fg.(GREEN).a(" World").reset() ) The above will clear the screen, write `Hello ` in red and ` World` in green, then reset the color attributes so that subsequent data printed to the stream used the default colors. But there is an even simpler way to accomplish the above using the render method: System.out.println( ansi().eraseScreen().render("@|red Hello|@ @|green World|@") ) ## Project Links * [Project Home](http://jansi.fusesource.org/) * [Release Downloads](http://jansi.fusesource.org/downloads/index.html) * [GitHub](http://github.com/chirino/jansi/tree/master) * [Issue Tracker](http://fusesource.com/issues/browse/JANSI) * [Mailing Lists](http://fusesource.com/forge/projects/JANSI/mailing-lists) jansi-1.4/src/000077500000000000000000000000001142666640600132645ustar00rootroot00000000000000jansi-1.4/src/main/000077500000000000000000000000001142666640600142105ustar00rootroot00000000000000jansi-1.4/src/main/java/000077500000000000000000000000001142666640600151315ustar00rootroot00000000000000jansi-1.4/src/main/java/org/000077500000000000000000000000001142666640600157205ustar00rootroot00000000000000jansi-1.4/src/main/java/org/fusesource/000077500000000000000000000000001142666640600201035ustar00rootroot00000000000000jansi-1.4/src/main/java/org/fusesource/jansi/000077500000000000000000000000001142666640600212075ustar00rootroot00000000000000jansi-1.4/src/main/java/org/fusesource/jansi/Ansi.java000066400000000000000000000266761142666640600227650ustar00rootroot00000000000000/** * Copyright (C) 2009, Progress Software Corporation and/or its * subsidiaries or affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import java.util.ArrayList; import java.util.concurrent.Callable; /** * Provides a fluent API for generating ANSI escape sequences. * * @author Hiram Chirino * @since 1.0 */ public class Ansi { private static final char FIRST_ESC_CHAR = 27; private static final char SECOND_ESC_CHAR = '['; public static enum Color { BLACK(0, "BLACK"), RED(1, "RED"), GREEN(2, "GREEN"), YELLOW(3, "YELLOW"), BLUE(4, "BLUE"), MAGENTA(5, "MAGENTA"), CYAN(6, "CYAN"), WHITE(7,"WHITE"), DEFAULT(9,"DEFAULT"); private final int value; private final String name; Color(int index, String name) { this.value = index; this.name = name; } @Override public String toString() { return name; } public int value() { return value; } public int fg() { return value + 30; } public int bg() { return value + 40; } public int fgBright() { return value + 90; } public int bgBright() { return value + 100; } }; public static enum Attribute { RESET ( 0, "RESET"), INTENSITY_BOLD ( 1, "INTENSITY_BOLD"), INTENSITY_FAINT ( 2, "INTENSITY_FAINT"), ITALIC ( 3, "ITALIC_ON"), UNDERLINE ( 4, "UNDERLINE_ON"), BLINK_SLOW ( 5, "BLINK_SLOW"), BLINK_FAST ( 6, "BLINK_FAST"), NEGATIVE_ON ( 7, "NEGATIVE_ON"), CONCEAL_ON ( 8, "CONCEAL_ON"), STRIKETHROUGH_ON ( 9, "STRIKETHROUGH_ON"), UNDERLINE_DOUBLE ( 21, "UNDERLINE_DOUBLE"), INTENSITY_BOLD_OFF ( 22, "INTENSITY_BOLD_OFF"), ITALIC_OFF ( 23, "ITALIC_OFF"), UNDERLINE_OFF ( 24, "UNDERLINE_OFF"), BLINK_OFF ( 25, "BLINK_OFF"), NEGATIVE_OFF ( 27, "NEGATIVE_OFF"), CONCEAL_OFF ( 28, "CONCEAL_OFF"), STRIKETHROUGH_OFF ( 29, "STRIKETHROUGH_OFF"); private final int value; private final String name; Attribute(int index, String name) { this.value = index; this.name = name; } @Override public String toString() { return name; } public int value() { return value; } }; public static enum Erase { FORWARD(0, "FORWARD"), BACKWARD(1, "BACKWARD"), ALL(2, "ALL"); private final int value; private final String name; Erase(int index, String name) { this.value = index; this.name = name; } @Override public String toString() { return name; } public int value() { return value; } }; public static final String DISABLE = Ansi.class.getName() + ".disable"; private static Callable detector = new Callable() { public Boolean call() throws Exception { return !Boolean.getBoolean(DISABLE); } }; public static void setDetector(final Callable detector) { if (detector == null) throw new IllegalArgumentException(); Ansi.detector = detector; } public static boolean isDetected() { try { return detector.call(); } catch (Exception e) { return true; } } private static final InheritableThreadLocal holder = new InheritableThreadLocal() { @Override protected Boolean initialValue() { return isDetected(); } }; public static void setEnabled(final boolean flag) { holder.set(flag); } public static boolean isEnabled() { return holder.get(); } public static Ansi ansi() { if (isEnabled()) { return new Ansi(); } else { return new NoAnsi(); } } private static class NoAnsi extends Ansi { @Override public Ansi fg(Color color) { return this; } @Override public Ansi bg(Color color) { return this; } @Override public Ansi a(Attribute attribute) { return this; } @Override public Ansi cursor(int x, int y) { return this; } @Override public Ansi cursorUp(int y) { return this; } @Override public Ansi cursorRight(int x) { return this; } @Override public Ansi cursorDown(int y) { return this; } @Override public Ansi cursorLeft(int x) { return this; } @Override public Ansi eraseScreen() { return this; } @Override public Ansi eraseScreen(Erase kind) { return this; } @Override public Ansi eraseLine() { return this; } @Override public Ansi eraseLine(Erase kind) { return this; } @Override public Ansi scrollUp(int rows) { return this; } @Override public Ansi scrollDown(int rows) { return this; } @Override public Ansi saveCursorPosition() { return this; } @Override public Ansi restorCursorPosition() { return this; } @Override public Ansi reset() { return this; } } private final StringBuilder builder; private final ArrayList attributeOptions = new ArrayList(5); public Ansi() { this(new StringBuilder()); } public Ansi(int size) { this(new StringBuilder(size)); } public Ansi(StringBuilder builder) { this.builder = builder; } public static Ansi ansi(StringBuilder builder) { return new Ansi(builder); } public static Ansi ansi(int size) { return new Ansi(size); } public Ansi fg(Color color) { attributeOptions.add(color.fg()); return this; } public Ansi bg(Color color) { attributeOptions.add(color.bg()); return this; } public Ansi a(Attribute attribute) { attributeOptions.add(attribute.value()); return this; } public Ansi cursor(final int x, final int y) { return appendEscapeSequence('H', x, y); } public Ansi cursorUp(final int y) { return appendEscapeSequence('A', y); } public Ansi cursorDown(final int y) { return appendEscapeSequence('B', y); } public Ansi cursorRight(final int x) { return appendEscapeSequence('C', x); } public Ansi cursorLeft(final int x) { return appendEscapeSequence('D', x); } public Ansi eraseScreen() { return appendEscapeSequence('J',Erase.ALL.value()); } public Ansi eraseScreen(final Erase kind) { return appendEscapeSequence('J', kind.value()); } public Ansi eraseLine() { return appendEscapeSequence('K'); } public Ansi eraseLine(final Erase kind) { return appendEscapeSequence('K', kind.value()); } public Ansi scrollUp(final int rows) { return appendEscapeSequence('S', rows); } public Ansi scrollDown(final int rows) { return appendEscapeSequence('T', rows); } public Ansi saveCursorPosition() { return appendEscapeSequence('s'); } public Ansi restorCursorPosition() { return appendEscapeSequence('u'); } public Ansi reset() { return a(Attribute.RESET); } public Ansi a(String value) { flushAtttributes(); builder.append(value); return this; } public Ansi a(boolean value) { flushAtttributes(); builder.append(value); return this; } public Ansi a(char value) { flushAtttributes(); builder.append(value); return this; } public Ansi a(char[] value, int offset, int len) { flushAtttributes(); builder.append(value, offset, len); return this; } public Ansi a(char[] value) { flushAtttributes(); builder.append(value); return this; } public Ansi a(CharSequence value, int start, int end) { flushAtttributes(); builder.append(value, start, end); return this; } public Ansi a(CharSequence value) { flushAtttributes(); builder.append(value); return this; } public Ansi a(double value) { flushAtttributes(); builder.append(value); return this; } public Ansi a(float value) { flushAtttributes(); builder.append(value); return this; } public Ansi a(int value) { flushAtttributes(); builder.append(value); return this; } public Ansi a(long value) { flushAtttributes(); builder.append(value); return this; } public Ansi a(Object value) { flushAtttributes(); builder.append(value); return this; } public Ansi a(StringBuffer value) { flushAtttributes(); builder.append(value); return this; } public Ansi newline() { flushAtttributes(); builder.append(System.getProperty("line.separator")); return this; } public Ansi format(String pattern, Object... args) { flushAtttributes(); builder.append(String.format(pattern, args)); return this; } /** * Uses the {@link AnsiRenderer} * to generate the ANSI escape sequences for the supplied text. * * @since 1.1 * @param text */ public Ansi render(final String text) { a(AnsiRenderer.render(text)); return this; } /** * String formats and renders the supplied arguments. Uses the {@link AnsiRenderer} * to generate the ANSI escape sequences. * * @since 1.1 * @param text * @param args */ public Ansi render(final String text, Object... args) { a(String.format(AnsiRenderer.render(text), args)); return this; } @Override public String toString() { flushAtttributes(); return builder.toString(); } /////////////////////////////////////////////////////////////////// // Private Helper Methods /////////////////////////////////////////////////////////////////// private Ansi appendEscapeSequence(char command) { flushAtttributes(); builder.append(FIRST_ESC_CHAR); builder.append(SECOND_ESC_CHAR); builder.append(command); return this; } private Ansi appendEscapeSequence(char command, int option) { flushAtttributes(); builder.append(FIRST_ESC_CHAR); builder.append(SECOND_ESC_CHAR); builder.append(option); builder.append(command); return this; } private Ansi appendEscapeSequence(char command, Object... options) { flushAtttributes(); return _appendEscapeSequence(command, options); } private void flushAtttributes() { if( attributeOptions.isEmpty() ) return; if (attributeOptions.size() == 1 && attributeOptions.get(0) == 0) { builder.append(FIRST_ESC_CHAR); builder.append(SECOND_ESC_CHAR); builder.append('m'); } else { _appendEscapeSequence('m', attributeOptions.toArray()); } attributeOptions.clear(); } private Ansi _appendEscapeSequence(char command, Object... options) { builder.append(FIRST_ESC_CHAR); builder.append(SECOND_ESC_CHAR); int size = options.length; for (int i = 0; i < size; i++) { if (i != 0) { builder.append(';'); } if (options[i] != null) { builder.append(options[i]); } } builder.append(command); return this; } } jansi-1.4/src/main/java/org/fusesource/jansi/AnsiConsole.java000066400000000000000000000100711142666640600242660ustar00rootroot00000000000000/** * Copyright (C) 2009, Progress Software Corporation and/or its * subsidiaries or affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import static org.fusesource.jansi.internal.CLibrary.STDOUT_FILENO; import static org.fusesource.jansi.internal.CLibrary.isatty; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; /** * Provides consistent access to an ANSI aware console PrintStream. * * @author Hiram Chirino * @since 1.0 */ public class AnsiConsole { public static final PrintStream system_out = System.out; public static final PrintStream out = new PrintStream(wrapOutputStream(system_out)); public static final PrintStream system_err = System.err; public static final PrintStream err = new PrintStream(wrapOutputStream(system_err)); private static int installed; public static OutputStream wrapOutputStream(final OutputStream stream) { String os = System.getProperty("os.name"); if( os.startsWith("Windows") ) { // On windows we know the console does not interpret ANSI codes.. try { return new WindowsAnsiOutputStream(stream); } catch (Throwable ignore) { // this happens when JNA is not in the path.. or // this happens when the stdout is being redirected to a file. } // Use the ANSIOutputStream to strip out the ANSI escape sequences. return new AnsiOutputStream(stream); } // We must be on some unix variant.. try { // If we can detect that stdout is not a tty.. then setup // to strip the ANSI sequences.. int rc = isatty(STDOUT_FILENO); if( rc==0 ) { return new AnsiOutputStream(stream); } // These erros happen if the JNI lib is not available for your platform. } catch (NoClassDefFoundError ignore) { } catch (UnsatisfiedLinkError ignore) { } // By default we assume your Unix tty can handle ANSI codes. // Just wrap it up so that when we get closed, we reset the // attributes. return new FilterOutputStream(stream) { @Override public void close() throws IOException { write(AnsiOutputStream.REST_CODE); flush(); super.close(); } }; } /** * If the standard out natively supports ANSI escape codes, then this just * returns System.out, otherwise it will provide an ANSI aware PrintStream * which strips out the ANSI escape sequences or which implement the escape * sequences. * * @return a PrintStream which is ANSI aware. */ public static PrintStream out() { return out; } /** * If the standard out natively supports ANSI escape codes, then this just * returns System.err, otherwise it will provide an ANSI aware PrintStream * which strips out the ANSI escape sequences or which implement the escape * sequences. * * @return a PrintStream which is ANSI aware. */ public static PrintStream err() { return err; } /** * Install Console.out to System.out. */ synchronized static public void systemInstall() { installed++; if( installed==1 ) { System.setOut(out); System.setErr(err); } } /** * undo a previous {@link #systemInstall()}. If {@link #systemInstall()} was called * multiple times, it {@link #systemUninstall()} must call the same number of times before * it is actually uninstalled. */ synchronized public static void systemUninstall() { installed--; if( installed==0 ) { System.setOut(system_out); System.setErr(system_err); } } } jansi-1.4/src/main/java/org/fusesource/jansi/AnsiOutputStream.java000066400000000000000000000261401142666640600253440ustar00rootroot00000000000000/** * Copyright (C) 2009, Progress Software Corporation and/or its * subsidiaries or affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import java.io.FilterOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; /** * A ANSI output stream extracts ANSI escape codes written to * an output stream. * * For more information about ANSI escape codes, see: * http://en.wikipedia.org/wiki/ANSI_escape_code * * This class just filters out the escape codes so that they are not * sent out to the underlying OutputStream. Subclasses should * actually perform the ANSI escape behaviors. * * @author Hiram Chirino * @since 1.0 */ public class AnsiOutputStream extends FilterOutputStream { public static final byte [] REST_CODE = resetCode(); public AnsiOutputStream(OutputStream os) { super(os); } private final static int MAX_ESCAPE_SEQUENCE_LENGTH=100; private byte buffer[] = new byte[MAX_ESCAPE_SEQUENCE_LENGTH]; private int pos=0; private int startOfValue; private final ArrayList options = new ArrayList(); private static final int LOOKING_FOR_FIRST_ESC_CHAR = 0; private static final int LOOKING_FOR_SECOND_ESC_CHAR = 1; private static final int LOOKING_FOR_NEXT_ARG = 2; private static final int LOOKING_FOR_STR_ARG_END = 3; private static final int LOOKING_FOR_INT_ARG_END = 4; int state = LOOKING_FOR_FIRST_ESC_CHAR; private static final int FIRST_ESC_CHAR = 27; private static final int SECOND_ESC_CHAR = '['; // TODO: implement to get perf boost: public void write(byte[] b, int off, int len) public void write(int data) throws IOException { switch( state ) { case LOOKING_FOR_FIRST_ESC_CHAR: if (data == FIRST_ESC_CHAR) { buffer[pos++] = (byte) data; state = LOOKING_FOR_SECOND_ESC_CHAR; } else { out.write(data); } break; case LOOKING_FOR_SECOND_ESC_CHAR: buffer[pos++] = (byte) data; if( data == SECOND_ESC_CHAR ) { state = LOOKING_FOR_NEXT_ARG; } else { buffer[pos++] = (byte) data; reset(); } break; case LOOKING_FOR_NEXT_ARG: buffer[pos++] = (byte)data; if( '"' == data ) { startOfValue=pos-1; state = LOOKING_FOR_STR_ARG_END; } else if( '0' <= data && data <= '9') { startOfValue=pos-1; state = LOOKING_FOR_INT_ARG_END; } else if( ';' == data ) { options.add(null); } else if( '?' == data ) { options.add(new Character('?')); } else if( '=' == data ) { options.add(new Character('=')); } else { if( processEscapeCommand(options, data) ) { pos=0; } reset(); } break; case LOOKING_FOR_INT_ARG_END: buffer[pos++] = (byte)data; if( !('0' <= data && data <= '9') ) { String strValue = new String(buffer, startOfValue, (pos-1)-startOfValue, "UTF-8"); Integer value = new Integer(strValue); options.add(value); if( data == ';' ) { state = LOOKING_FOR_NEXT_ARG; } else { if( processEscapeCommand(options, data) ) { pos=0; } reset(); } } break; case LOOKING_FOR_STR_ARG_END: buffer[pos++] = (byte)data; if( '"' != data ) { String value = new String(buffer, startOfValue, (pos-1)-startOfValue, "UTF-8"); options.add(value); if( data == ';' ) { state = LOOKING_FOR_NEXT_ARG; } else { if( processEscapeCommand(options, data) ) { pos=0; } reset(); } } break; } // Is it just too long? if( pos >= buffer.length ) { reset(); } } private void reset() throws IOException { if( pos > 0 ) { out.write(buffer, 0, pos); } pos=0; startOfValue=0; options.clear(); state = LOOKING_FOR_FIRST_ESC_CHAR; } /** * * @param options * @param command * @return true if the escape command was processed. */ private boolean processEscapeCommand(ArrayList options, int command) throws IOException { try { switch(command) { case 'A': processCursorUp(optionInt(options, 0, 1)); return true; case 'B': processCursorDown(optionInt(options, 0, 1)); return true; case 'C': processCursorRight(optionInt(options, 0, 1)); return true; case 'D': processCursorLeft(optionInt(options, 0, 1)); return true; case 'E': processCursorDownLine(optionInt(options, 0, 1)); return true; case 'F': processCursorUpLine(optionInt(options, 0, 1)); return true; case 'G': processCursorToColumn(optionInt(options, 0)); return true; case 'H': case 'f': processCursorTo(optionInt(options, 0, 1), optionInt(options, 1, 1)); return true; case 'J': processEraseScreen(optionInt(options, 0, 0)); return true; case 'K': processEraseLine(optionInt(options, 0, 0)); return true; case 'S': processScrollUp(optionInt(options, 0, 1)); return true; case 'T': processScrollDown(optionInt(options, 0, 1)); return true; case 'm': // Validate all options are ints... for (Object next : options) { if( next!=null && next.getClass()!=Integer.class) { throw new IllegalArgumentException(); } } int count=0; for (Object next : options) { if( next!=null ) { count++; int value = ((Integer)next).intValue(); if( 30 <= value && value <= 37 ) { processSetForegroundColor(value-30); } else if( 40 <= value && value <= 47 ) { processSetBackgroundColor(value-40); } else { switch ( value ) { case 39: case 49: case 0: processAttributeRest(); break; default: processSetAttribute(value); } } } } if( count == 0 ) { processAttributeRest(); } return true; case 's': processSaveCursorPosition(); return true; case 'u': processRestoreCursorPosition(); return true; default: if( 'a' <= command && 'z' <=command ) { processUnknownExtension(options, command); return true; } if( 'A' <= command && 'Z' <=command ) { processUnknownExtension(options, command); return true; } return false; } } catch (IllegalArgumentException ignore) { } return false; } protected void processRestoreCursorPosition() throws IOException { } protected void processSaveCursorPosition() throws IOException { } protected void processScrollDown(int optionInt) throws IOException { } protected void processScrollUp(int optionInt) throws IOException { } protected static final int ERASE_SCREEN_TO_END=0; protected static final int ERASE_SCREEN_TO_BEGINING=1; protected static final int ERASE_SCREEN=2; protected void processEraseScreen(int eraseOption) throws IOException { } protected static final int ERASE_LINE_TO_END=0; protected static final int ERASE_LINE_TO_BEGINING=1; protected static final int ERASE_LINE=2; protected void processEraseLine(int eraseOption) throws IOException { } protected static final int ATTRIBUTE_INTENSITY_BOLD = 1; // Intensity: Bold protected static final int ATTRIBUTE_INTENSITY_FAINT = 2; // Intensity; Faint not widely supported protected static final int ATTRIBUTE_ITALIC = 3; // Italic; on not widely supported. Sometimes treated as inverse. protected static final int ATTRIBUTE_UNDERLINE = 4; // Underline; Single protected static final int ATTRIBUTE_BLINK_SLOW = 5; // Blink; Slow less than 150 per minute protected static final int ATTRIBUTE_BLINK_FAST = 6; // Blink; Rapid MS-DOS ANSI.SYS; 150 per minute or more protected static final int ATTRIBUTE_NEGATIVE_ON = 7; // Image; Negative inverse or reverse; swap foreground and background protected static final int ATTRIBUTE_CONCEAL_ON = 8; // Conceal on protected static final int ATTRIBUTE_UNDERLINE_DOUBLE = 21; // Underline; Double not widely supported protected static final int ATTRIBUTE_INTENSITY_NORMAL = 22; // Intensity; Normal not bold and not faint protected static final int ATTRIBUTE_UNDERLINE_OFF = 24; // Underline; None protected static final int ATTRIBUTE_BLINK_OFF = 25; // Blink; off protected static final int ATTRIBUTE_NEGATIVE_Off = 27; // Image; Positive protected static final int ATTRIBUTE_CONCEAL_OFF = 28; // Reveal conceal off protected void processSetAttribute(int attribute) throws IOException { } protected static final int BLACK = 0; protected static final int RED = 1; protected static final int GREEN = 2; protected static final int YELLOW = 3; protected static final int BLUE = 4; protected static final int MAGENTA = 5; protected static final int CYAN = 6; protected static final int WHITE = 7; protected void processSetForegroundColor(int color) throws IOException { } protected void processSetBackgroundColor(int color) throws IOException { } protected void processAttributeRest() throws IOException { } protected void processCursorTo(int row, int col) throws IOException { } protected void processCursorToColumn(int x) throws IOException { } protected void processCursorUpLine(int count) throws IOException { } protected void processCursorDownLine(int count) throws IOException { // Poor mans impl.. for(int i=0; i < count; i++) { out.write('\n'); } } protected void processCursorLeft(int count) throws IOException { } protected void processCursorRight(int count) throws IOException { // Poor mans impl.. for(int i=0; i < count; i++) { out.write(' '); } } protected void processCursorDown(int count) throws IOException { } protected void processCursorUp(int count) throws IOException { } protected void processUnknownExtension(ArrayList options, int command) { } private int optionInt(ArrayList options, int index) { if( options.size() <= index ) throw new IllegalArgumentException(); Object value = options.get(index); if( value == null ) throw new IllegalArgumentException(); if( !value.getClass().equals(Integer.class) ) throw new IllegalArgumentException(); return ((Integer)value).intValue(); } private int optionInt(ArrayList options, int index, int defaultValue) { if( options.size() > index ) { Object value = options.get(index); if( value == null ) { return defaultValue; } return ((Integer)value).intValue(); } return defaultValue; } @Override public void close() throws IOException { write(REST_CODE); flush(); super.close(); } static private byte[] resetCode() { try { return new Ansi().reset().toString().getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } } jansi-1.4/src/main/java/org/fusesource/jansi/AnsiRenderWriter.java000066400000000000000000000041201142666640600252760ustar00rootroot00000000000000/* * Copyright (C) 2009 the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Writer; import java.util.Locale; import static org.fusesource.jansi.AnsiRenderer.*; /** * Print writer which supports automatic ANSI color rendering via {@link AnsiRenderer}. * * @author Jason Dillon * @author Hiram Chirino * @since 1.1 */ public class AnsiRenderWriter extends PrintWriter { public AnsiRenderWriter(final OutputStream out) { super(out); } public AnsiRenderWriter(final OutputStream out, final boolean autoFlush) { super(out, autoFlush); } public AnsiRenderWriter(final Writer out) { super(out); } public AnsiRenderWriter(final Writer out, final boolean autoFlush) { super(out, autoFlush); } @Override public void write(final String s) { if (test(s)) { super.write(render(s)); } else { super.write(s); } } // // Need to prevent partial output from being written while formatting or we will get rendering exceptions // @Override public PrintWriter format(final String format, final Object... args) { print(String.format(format, args)); return this; } @Override public PrintWriter format(final Locale l, final String format, final Object... args) { print(String.format(l, format, args)); return this; } } jansi-1.4/src/main/java/org/fusesource/jansi/AnsiRenderer.java000066400000000000000000000141701142666640600244360ustar00rootroot00000000000000/* * Copyright (C) 2009 the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import org.fusesource.jansi.Ansi.Attribute; import org.fusesource.jansi.Ansi.Color; /** * Renders ANSI color escape-codes in strings by parsing out some special syntax to pick up the correct fluff to use. * *

* The syntax for embedded ANSI codes is: * *

 *   @|code(,code)* text|@
 * 
* * Examples: * *
 *   @|bold Hello|@
 * 
* *
 *   @|bold,red Warning!|@
 * 
* * @author Jason Dillon * @author Hiram Chirino * @since 1.1 */ public class AnsiRenderer { public static final String BEGIN_TOKEN = "@|"; private static final int BEGIN_TOKEN_LEN = 2; public static final String END_TOKEN = "|@"; private static final int END_TOKEN_LEN = 2; public static final String CODE_TEXT_SEPARATOR = " "; public static final String CODE_LIST_SEPARATOR = ","; static public String render(final String input) throws IllegalArgumentException { StringBuffer buff = new StringBuffer(); int i = 0; int j, k; while (true) { j = input.indexOf(BEGIN_TOKEN, i); if (j == -1) { if (i == 0) { return input; } else { buff.append(input.substring(i, input.length())); return buff.toString(); } } else { buff.append(input.substring(i, j)); k = input.indexOf(END_TOKEN, j); if (k == -1) { return input; } else { j += BEGIN_TOKEN_LEN; String spec = input.substring(j, k); String[] items = spec.split(CODE_TEXT_SEPARATOR, 2); if (items.length == 1) { return input; } String replacement = render(items[1], items[0].split(CODE_LIST_SEPARATOR)); buff.append(replacement); i = k + END_TOKEN_LEN; } } } } static private String render(final String text, final String... codes) { Ansi ansi = Ansi.ansi(); for (String name : codes) { Code code = Code.valueOf(name.toUpperCase()); if (code.isColor()) { if (code.isBackground()) { ansi = ansi.bg(code.getColor()); } else { ansi = ansi.fg(code.getColor()); } } else if (code.isAttribute()) { ansi = ansi.a(code.getAttribute()); } } return ansi.a(text).reset().toString(); } public static boolean test(final String text) { return text != null && text.contains(BEGIN_TOKEN); } public static enum Code { // // TODO: Find a better way to keep Code in sync with Color/Attribute/Erase // // Colors BLACK(Color.BLACK), RED(Color.RED), GREEN(Color.GREEN), YELLOW(Color.YELLOW), BLUE(Color.BLUE), MAGENTA(Color.MAGENTA), CYAN(Color.CYAN), WHITE(Color.WHITE), // Foreground Colors FG_BLACK(Color.BLACK, false), FG_RED(Color.RED, false), FG_GREEN(Color.GREEN, false), FG_YELLOW(Color.YELLOW, false), FG_BLUE(Color.BLUE, false), FG_MAGENTA(Color.MAGENTA, false), FG_CYAN(Color.CYAN, false), FG_WHITE(Color.WHITE, false), // Background Colors BG_BLACK(Color.BLACK, true), BG_RED(Color.RED, true), BG_GREEN(Color.GREEN, true), BG_YELLOW(Color.YELLOW, true), BG_BLUE(Color.BLUE, true), BG_MAGENTA(Color.MAGENTA, true), BG_CYAN(Color.CYAN, true), BG_WHITE(Color.WHITE, true), // Attributes RESET(Attribute.RESET), INTENSITY_BOLD(Attribute.INTENSITY_BOLD), INTENSITY_FAINT(Attribute.INTENSITY_FAINT), ITALIC(Attribute.ITALIC), UNDERLINE(Attribute.UNDERLINE), BLINK_SLOW(Attribute.BLINK_SLOW), BLINK_FAST(Attribute.BLINK_FAST), BLINK_OFF(Attribute.BLINK_OFF), NEGATIVE_ON(Attribute.NEGATIVE_ON), NEGATIVE_OFF(Attribute.NEGATIVE_OFF), CONCEAL_ON(Attribute.CONCEAL_ON), CONCEAL_OFF(Attribute.CONCEAL_OFF), UNDERLINE_DOUBLE(Attribute.UNDERLINE_DOUBLE), UNDERLINE_OFF(Attribute.UNDERLINE_OFF), // Aliases BOLD(Attribute.INTENSITY_BOLD), FAINT(Attribute.INTENSITY_FAINT),; @SuppressWarnings("unchecked") private final Enum n; private final boolean background; @SuppressWarnings("unchecked") private Code(final Enum n, boolean background) { this.n = n; this.background = background; } @SuppressWarnings("unchecked") private Code(final Enum n) { this(n, false); } public boolean isColor() { return n instanceof Ansi.Color; } public Ansi.Color getColor() { return (Ansi.Color) n; } public boolean isAttribute() { return n instanceof Attribute; } public Attribute getAttribute() { return (Attribute) n; } public boolean isBackground() { return background; } } } jansi-1.4/src/main/java/org/fusesource/jansi/AnsiString.java000066400000000000000000000047361142666640600241450ustar00rootroot00000000000000/* * Copyright (C) 2009 the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import org.fusesource.jansi.AnsiOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * An ANSI string which reports the size of rendered text correctly (ignoring any ANSI escapes). * * @author Jason Dillon * @since 1.1 */ public class AnsiString implements CharSequence { private final CharSequence encoded; private final CharSequence plain; public AnsiString(final CharSequence str) { assert str != null; this.encoded = str; this.plain = chew(str); } private CharSequence chew(final CharSequence str) { assert str != null; ByteArrayOutputStream buff = new ByteArrayOutputStream(); AnsiOutputStream out = new AnsiOutputStream(buff); try { out.write(str.toString().getBytes()); out.flush(); out.close(); } catch (IOException e) { throw new RuntimeException(e); } return new String(buff.toByteArray()); } public CharSequence getEncoded() { return encoded; } public CharSequence getPlain() { return plain; } // FIXME: charAt() and subSequence() will make things barf, need to call toString() first to get expected results public char charAt(final int index) { return getEncoded().charAt(index); } public CharSequence subSequence(final int start, final int end) { return getEncoded().subSequence(start, end); } public int length() { return getPlain().length(); } @Override public boolean equals(final Object obj) { return getEncoded().equals(obj); } @Override public int hashCode() { return getEncoded().hashCode(); } @Override public String toString() { return getEncoded().toString(); } }jansi-1.4/src/main/java/org/fusesource/jansi/WindowsAnsiOutputStream.java000066400000000000000000000242671142666640600267270ustar00rootroot00000000000000/** * Copyright (C) 2009, Progress Software Corporation and/or its * subsidiaries or affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import static org.fusesource.jansi.internal.Kernel32.BACKGROUND_BLUE; import static org.fusesource.jansi.internal.Kernel32.BACKGROUND_GREEN; import static org.fusesource.jansi.internal.Kernel32.BACKGROUND_INTENSITY; import static org.fusesource.jansi.internal.Kernel32.BACKGROUND_RED; import static org.fusesource.jansi.internal.Kernel32.FOREGROUND_BLUE; import static org.fusesource.jansi.internal.Kernel32.FOREGROUND_GREEN; import static org.fusesource.jansi.internal.Kernel32.FOREGROUND_INTENSITY; import static org.fusesource.jansi.internal.Kernel32.FOREGROUND_RED; import static org.fusesource.jansi.internal.Kernel32.FillConsoleOutputCharacterW; import static org.fusesource.jansi.internal.Kernel32.GetConsoleScreenBufferInfo; import static org.fusesource.jansi.internal.Kernel32.GetStdHandle; import static org.fusesource.jansi.internal.Kernel32.STD_OUTPUT_HANDLE; import static org.fusesource.jansi.internal.Kernel32.SetConsoleCursorPosition; import static org.fusesource.jansi.internal.Kernel32.SetConsoleTextAttribute; import java.io.IOException; import java.io.OutputStream; import org.fusesource.jansi.internal.WindowsSupport; import org.fusesource.jansi.internal.Kernel32.CONSOLE_SCREEN_BUFFER_INFO; import org.fusesource.jansi.internal.Kernel32.COORD; /** * A Windows ANSI escape processor, uses JNA to access native platform * API's to change the console attributes. * * @since 1.0 * @author Hiram Chirino */ public final class WindowsAnsiOutputStream extends AnsiOutputStream { private static final long console = GetStdHandle(STD_OUTPUT_HANDLE); private static final short FOREGROUND_BLACK = 0; private static final short FOREGROUND_YELLOW = (short) (FOREGROUND_RED|FOREGROUND_GREEN); private static final short FOREGROUND_MAGENTA = (short) (FOREGROUND_BLUE|FOREGROUND_RED); private static final short FOREGROUND_CYAN = (short) (FOREGROUND_BLUE|FOREGROUND_GREEN); private static final short FOREGROUND_WHITE = (short) (FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE); private static final short BACKGROUND_BLACK = 0; private static final short BACKGROUND_YELLOW = (short) (BACKGROUND_RED|BACKGROUND_GREEN); private static final short BACKGROUND_MAGENTA = (short) (BACKGROUND_BLUE|BACKGROUND_RED); private static final short BACKGROUND_CYAN = (short) (BACKGROUND_BLUE|BACKGROUND_GREEN); private static final short BACKGROUND_WHITE = (short) (BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE); private static final short ANSI_FOREGROUND_COLOR_MAP[] = { FOREGROUND_BLACK, FOREGROUND_RED, FOREGROUND_GREEN, FOREGROUND_YELLOW, FOREGROUND_BLUE, FOREGROUND_MAGENTA, FOREGROUND_CYAN, FOREGROUND_WHITE, }; private static final short ANSI_BACKGROUND_COLOR_MAP[] = { BACKGROUND_BLACK, BACKGROUND_RED, BACKGROUND_GREEN, BACKGROUND_YELLOW, BACKGROUND_BLUE, BACKGROUND_MAGENTA, BACKGROUND_CYAN, BACKGROUND_WHITE, }; private final CONSOLE_SCREEN_BUFFER_INFO info = new CONSOLE_SCREEN_BUFFER_INFO(); private final short originalColors; private boolean negative; private short savedX = -1; private short savedY = -1; public WindowsAnsiOutputStream(OutputStream os) throws IOException { super(os); getConsoleInfo(); originalColors = info.attributes; } private void getConsoleInfo() throws IOException { out.flush(); if( GetConsoleScreenBufferInfo(console, info) == 0 ) { throw new IOException("Could not get the screen info: "+WindowsSupport.getLastErrorMessage()); } if( negative ) { info.attributes = invertAttributeColors(info.attributes); } } private void applyAttribute() throws IOException { out.flush(); short attributes = info.attributes; if( negative ) { attributes = invertAttributeColors(attributes); } if( SetConsoleTextAttribute(console, attributes) == 0 ) { throw new IOException(WindowsSupport.getLastErrorMessage()); } } private short invertAttributeColors(short attibutes) { // Swap the the Foreground and Background bits. int fg = 0x000F & attibutes; fg <<= 8; int bg = 0X00F0 * attibutes; bg >>=8; attibutes = (short) ((attibutes & 0xFF00) | fg | bg); return attibutes; } private void applyCursorPosition() throws IOException { if( SetConsoleCursorPosition(console, info.cursorPosition.copy()) == 0 ) { throw new IOException(WindowsSupport.getLastErrorMessage()); } } @Override protected void processEraseScreen(int eraseOption) throws IOException { getConsoleInfo(); int[] written = new int[1]; switch(eraseOption) { case ERASE_SCREEN: COORD topLeft = new COORD(); topLeft.x = 0; topLeft.y = info.window.top; int screenLength = info.window.height() * info.size.x; FillConsoleOutputCharacterW(console, ' ', screenLength, topLeft, written); break; case ERASE_SCREEN_TO_BEGINING: COORD topLeft2 = new COORD(); topLeft2.x = 0; topLeft2.y = info.window.top; int lengthToCursor = (info.cursorPosition.y - info.window.top) * info.size.x + info.cursorPosition.x; FillConsoleOutputCharacterW(console, ' ', lengthToCursor, topLeft2, written); break; case ERASE_SCREEN_TO_END: int lengthToEnd = (info.window.bottom - info.cursorPosition.y) * info.size.x + (info.size.x - info.cursorPosition.x); FillConsoleOutputCharacterW(console, ' ', lengthToEnd, info.cursorPosition.copy(), written); } } @Override protected void processEraseLine(int eraseOption) throws IOException { getConsoleInfo(); int[] written = new int[1]; switch(eraseOption) { case ERASE_LINE: COORD leftColCurrRow = info.cursorPosition.copy(); leftColCurrRow.x = 0; FillConsoleOutputCharacterW(console, ' ', info.size.x, leftColCurrRow, written); break; case ERASE_LINE_TO_BEGINING: COORD leftColCurrRow2 = info.cursorPosition.copy(); leftColCurrRow2.x = 0; FillConsoleOutputCharacterW(console, ' ', info.cursorPosition.x, leftColCurrRow2, written); break; case ERASE_LINE_TO_END: int lengthToLastCol = info.size.x - info.cursorPosition.x; FillConsoleOutputCharacterW(console, ' ', lengthToLastCol, info.cursorPosition.copy(), written); } } @Override protected void processCursorLeft(int count) throws IOException { getConsoleInfo(); info.cursorPosition.x = (short) Math.max(0, info.cursorPosition.x-count); applyCursorPosition(); } @Override protected void processCursorRight(int count) throws IOException { getConsoleInfo(); info.cursorPosition.x = (short)Math.min(info.window.width(), info.cursorPosition.x+count); applyCursorPosition(); } @Override protected void processCursorDown(int count) throws IOException { getConsoleInfo(); info.cursorPosition.y = (short) Math.min(info.size.y, info.cursorPosition.y+count); applyCursorPosition(); } @Override protected void processCursorUp(int count) throws IOException { getConsoleInfo(); info.cursorPosition.y = (short) Math.max(info.window.top, info.cursorPosition.y-count); applyCursorPosition(); } @Override protected void processCursorTo(int row, int col) throws IOException { getConsoleInfo(); info.cursorPosition.y = (short) Math.max(info.window.top, Math.min(info.size.y, info.window.top+row-1)); info.cursorPosition.x = (short) Math.max(0, Math.min(info.window.width(), col-1)); applyCursorPosition(); } @Override protected void processCursorToColumn(int x) throws IOException { getConsoleInfo(); info.cursorPosition.x = (short) Math.max(0, Math.min(info.window.width(), x-1)); applyCursorPosition(); } @Override protected void processSetForegroundColor(int color) throws IOException { info.attributes = (short)((info.attributes & ~0x0007 ) | ANSI_FOREGROUND_COLOR_MAP[color]); applyAttribute(); } @Override protected void processSetBackgroundColor(int color) throws IOException { info.attributes = (short)((info.attributes & ~0x0070 ) | ANSI_BACKGROUND_COLOR_MAP[color]); applyAttribute(); } @Override protected void processAttributeRest() throws IOException { info.attributes = (short)((info.attributes & ~0x00FF ) | originalColors); this.negative = false; applyAttribute(); } @Override protected void processSetAttribute(int attribute) throws IOException { switch(attribute) { case ATTRIBUTE_INTENSITY_BOLD: info.attributes = (short)(info.attributes | FOREGROUND_INTENSITY ); applyAttribute(); break; case ATTRIBUTE_INTENSITY_NORMAL: info.attributes = (short)(info.attributes & ~FOREGROUND_INTENSITY ); applyAttribute(); break; // Yeah, setting the background intensity is not underlining.. but it's best we can do // using the Windows console API case ATTRIBUTE_UNDERLINE: info.attributes = (short)(info.attributes | BACKGROUND_INTENSITY ); applyAttribute(); break; case ATTRIBUTE_UNDERLINE_OFF: info.attributes = (short)(info.attributes & ~BACKGROUND_INTENSITY ); applyAttribute(); break; case ATTRIBUTE_NEGATIVE_ON: negative = true; applyAttribute(); break; case ATTRIBUTE_NEGATIVE_Off: negative = false; applyAttribute(); break; } } @Override protected void processSaveCursorPosition() throws IOException { getConsoleInfo(); savedX = info.cursorPosition.x; savedY = info.cursorPosition.y; } @Override protected void processRestoreCursorPosition() throws IOException { // restore only if there was a save operation first if (savedX != -1 && savedY != -1) { out.flush(); info.cursorPosition.x = savedX; info.cursorPosition.y = savedY; applyCursorPosition(); } } }jansi-1.4/src/test/000077500000000000000000000000001142666640600142435ustar00rootroot00000000000000jansi-1.4/src/test/java/000077500000000000000000000000001142666640600151645ustar00rootroot00000000000000jansi-1.4/src/test/java/org/000077500000000000000000000000001142666640600157535ustar00rootroot00000000000000jansi-1.4/src/test/java/org/fusesource/000077500000000000000000000000001142666640600201365ustar00rootroot00000000000000jansi-1.4/src/test/java/org/fusesource/jansi/000077500000000000000000000000001142666640600212425ustar00rootroot00000000000000jansi-1.4/src/test/java/org/fusesource/jansi/AnsiConsoleExample.java000066400000000000000000000025631142666640600256440ustar00rootroot00000000000000/** * Copyright (C) 2009, Progress Software Corporation and/or its * subsidiaries or affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import java.io.FileInputStream; import java.io.IOException; /** * * @author Hiram Chirino */ public class AnsiConsoleExample { public static void main(String[] args) throws IOException { String file = "src/test/resources/jansi.ans"; if( args.length>0 ) file = args[0]; // Allows us to disable ANSI processing. if( "true".equals(System.getProperty("jansi", "true")) ) { AnsiConsole.systemInstall(); } FileInputStream f = new FileInputStream(file); int c; while( (c=f.read())>=0 ) { System.out.write(c); } f.close(); } } jansi-1.4/src/test/java/org/fusesource/jansi/AnsiConsoleExample2.java000077500000000000000000000032601142666640600257240ustar00rootroot00000000000000/** * Copyright (C) 2009, Progress Software Corporation and/or its * subsidiaries or affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import java.io.FileInputStream; import java.io.IOException; import static org.fusesource.jansi.Ansi.*; /** * * @author Hiram Chirino */ public class AnsiConsoleExample2 { public static void main(String[] args) throws IOException { String file = "src/test/resources/jansi.ans"; if( args.length>0 ) file = args[0]; // Allows us to disable ANSI processing. if( "true".equals(System.getProperty("jansi", "true")) ) { AnsiConsole.systemInstall(); } System.out.print(ansi().reset().eraseScreen().cursor(1, 1)); System.out.print("======================================================================="); FileInputStream f = new FileInputStream(file); int c; while( (c=f.read())>=0 ) { System.out.write(c); } f.close(); System.out.println("======================================================================="); } } jansi-1.4/src/test/java/org/fusesource/jansi/AnsiRenderWriterTest.java000066400000000000000000000026601142666640600262000ustar00rootroot00000000000000/* * Copyright (C) 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.ByteArrayOutputStream; import static org.junit.Assert.assertEquals; /** * Tests for the {@link AnsiRenderWriter} class. * * @author Jason Dillon */ public class AnsiRenderWriterTest { private ByteArrayOutputStream baos; private AnsiRenderWriter out; @Before public void setUp() { baos = new ByteArrayOutputStream(); out = new AnsiRenderWriter(baos); } @After public void tearDown() { out = null; baos = null; } @Test public void testRenderNothing() { out.print("foo"); out.flush(); String result = new String(baos.toByteArray()); assertEquals("foo", result); } }jansi-1.4/src/test/java/org/fusesource/jansi/AnsiRendererTest.java000066400000000000000000000057661142666640600253440ustar00rootroot00000000000000/* * Copyright (C) 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import org.junit.Before; import org.junit.Test; import static org.fusesource.jansi.Ansi.*; import static org.fusesource.jansi.Ansi.Attribute.*; import static org.fusesource.jansi.Ansi.Color.*; import static org.fusesource.jansi.AnsiRenderer.*; import static org.junit.Assert.*; /** * Tests for the {@link AnsiRenderer} class. * * @author Jason Dillon */ public class AnsiRendererTest { @Before public void setUp() { Ansi.setEnabled(true); } @Test public void testTest() throws Exception { assertFalse(test("foo")); assertTrue(test("@|foo|")); assertTrue(test("@|foo")); } @Test public void testRender() { String str = render("@|bold foo|@"); System.out.println(str); assertEquals(ansi().a(INTENSITY_BOLD).a("foo").reset().toString(), str); } @Test public void testRender2() { String str = render("@|bold,red foo|@"); System.out.println(str); assertEquals(Ansi.ansi().a(INTENSITY_BOLD).fg(RED).a("foo").reset().toString(), str); } @Test public void testRender3() { String str = render("@|bold,red foo bar baz|@"); System.out.println(str); assertEquals(ansi().a(INTENSITY_BOLD).fg(RED).a("foo bar baz").reset().toString(), str); } @Test public void testRender4() { String str = render("@|bold,red foo bar baz|@ ick @|bold,red foo bar baz|@"); System.out.println(str); assertEquals(ansi() .a(INTENSITY_BOLD).fg(RED).a("foo bar baz").reset() .a(" ick ") .a(INTENSITY_BOLD).fg(RED).a("foo bar baz").reset() .toString(), str); } @Test public void testRender5() { // Check the ansi() render method. String str = ansi().render("@|bold Hello|@").toString(); System.out.println(str); assertEquals(ansi().a(INTENSITY_BOLD).a("Hello").reset().toString(), str); } @Test public void testRenderNothing() { assertEquals("foo", render("foo")); } @Test public void testRenderInvalidMissingEnd() { String str = render("@|bold foo"); assertEquals("@|bold foo", str); } @Test public void testRenderInvalidMissingText() { String str = render("@|bold|@"); assertEquals("@|bold|@", str); } }jansi-1.4/src/test/java/org/fusesource/jansi/AnsiStringTest.java000066400000000000000000000025211142666640600250260ustar00rootroot00000000000000/* * Copyright (C) 2009 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Tests for {@link AnsiString}. * * @author Jason Dillon */ public class AnsiStringTest { @Test public void testNotEncoded() throws Exception { AnsiString as = new AnsiString("foo"); assertEquals("foo", as.getEncoded()); assertEquals("foo", as.getPlain()); assertEquals(3, as.length()); } @Test public void testEncoded() throws Exception { AnsiString as = new AnsiString(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a("foo").reset().toString()); assertEquals("foo", as.getPlain()); assertEquals(3, as.length()); } }jansi-1.4/src/test/java/org/fusesource/jansi/AnsiTest.java000066400000000000000000000024471142666640600236460ustar00rootroot00000000000000/* * Copyright (C) 2009 the original author(s). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fusesource.jansi; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * Tests for the {@link Ansi} class. * * @author Jason Dillon */ public class AnsiTest { @Test public void testSetEnabled() throws Exception { Ansi.setEnabled(false); new Thread() { @Override public void run() { assertEquals(false, Ansi.isEnabled()); } }.run(); Ansi.setEnabled(true); new Thread() { @Override public void run() { assertEquals(true, Ansi.isEnabled()); } }.run(); } }jansi-1.4/src/test/resources/000077500000000000000000000000001142666640600162555ustar00rootroot00000000000000jansi-1.4/src/test/resources/jansi.ans000077500000000000000000000010411142666640600200630ustar00rootroot00000000000000[?7h ĿĿ Ŀ Ŀ  Ŀ Ŀ  Ŀ  ߱ ڴ  ߲