pax_global_header00006660000000000000000000000064137304620770014523gustar00rootroot0000000000000052 comment=760a8e52dd989dfd47c72e82776657c530c8c1b0 pastel-0.2.1/000077500000000000000000000000001373046207700130135ustar00rootroot00000000000000pastel-0.2.1/.coveragerc000066400000000000000000000000371373046207700151340ustar00rootroot00000000000000[run] omit = pastel/version.py pastel-0.2.1/.gitignore000066400000000000000000000003671373046207700150110ustar00rootroot00000000000000*.pyc # Packages *.egg *.egg-info dist build _build .cache *.so # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox nosetests.xml .DS_Store .idea/* /test.py /test_*.py profile.html /wheelhouse .python-version setup.py pastel-0.2.1/.travis.yml000066400000000000000000000016621373046207700151310ustar00rootroot00000000000000language: python python: - "2.7" - "3.5" - "3.6" - "3.7" - "pypy" install: - | if [ "$TRAVIS_PYTHON_VERSION" = "pypy" ]; then export PYENV_ROOT="$HOME/.pyenv" if [ -f "$PYENV_ROOT/bin/pyenv" ]; then pushd "$PYENV_ROOT" && git pull && popd else rm -rf "$PYENV_ROOT" && git clone --depth 1 https://github.com/yyuu/pyenv.git "$PYENV_ROOT" fi export PYPY_VERSION="5.6.0" "$PYENV_ROOT/bin/pyenv" install --skip-existing "pypy-$PYPY_VERSION" virtualenv --python="$PYENV_ROOT/versions/pypy-$PYPY_VERSION/bin/python" "$HOME/virtualenvs/pypy-$PYPY_VERSION" source "$HOME/virtualenvs/pypy-$PYPY_VERSION/bin/activate" fi - curl -fsS -o get-poetry.py https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py - python get-poetry.py --preview -y - source $HOME/.poetry/env - poetry install script: poetry run pytest -q tests/ pastel-0.2.1/LICENSE000066400000000000000000000020461373046207700140220ustar00rootroot00000000000000Copyright (c) 2018 Sébastien Eustace Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pastel-0.2.1/README.rst000066400000000000000000000017561373046207700145130ustar00rootroot00000000000000Pastel: Bring colors to your terminal ##################################### Pastel is a simple library to help you colorize strings in your terminal. It comes bundled with predefined styles: * ``info``: green * ``comment``: yellow * ``question``: black on cyan * ``error``: white on red .. image:: https://raw.githubusercontent.com/sdispater/pastel/master/assets/screenshot.png Features ======== * Use predefined styles or add you own. * Disable colors all together by calling ``with_colors(False)``. * Automatically disables colors if the output is not a TTY. * Used in `cleo `_. * Supports Python **2.7+**, **3.5+** and **PyPy**. Usage ===== .. code-block:: python >>> import pastel >>> print(pastel.colorize('Information')) 'Information' # Green string by default >>> print(pastel.colorize('This is bold red')) 'This is bold red' Installation ============ .. code-block:: pip install pastel pastel-0.2.1/assets/000077500000000000000000000000001373046207700143155ustar00rootroot00000000000000pastel-0.2.1/assets/screenshot.png000066400000000000000000003256421373046207700172140ustar00rootroot00000000000000PNG  IHDRſmsRGBiTXtXML:com.adobe.xmp 724 468 '6@IDATx]E>J ;;RDED@ERDQTĮO&H.^$!oflw}$曲Νmz7{CO&BN<45gٸhK?,'ȇaKkl<cM h^Y>`8I0 Dx W&jVݢ tǴ|9)>u#:J:/S FJ)>կs ta ˳ͮ|'$㥩)i'դح bi7d6 F6Q}t"Г޼4ˀ:ug"SdB5G%]1\٢[>Mʤ6MM޼ ׯظMWJYʫ}b+ Jq@J>}L]f^8.u }`K:b헱""Mb!4BY'0ҁ^[-yt}c2?N:f{H2u֒22V$C#c[l&W@Wf+e ";+jo7e](T=66jFū@ ?vUW ]̨*<\M Ǧ?Jٰjx3pѷr/r޳Rj1,0!RPyT  "U\TD\9-*(L)= Z%6\)l}ǖgVsrM2X¹pIz>'tEB+eovKK\iPw<;F!Tkk 7mu;v;|R* t>ka,Ed9u,SW4{Fyy$4\_lPأnǔfvQtn%B*b{MTvFJZ(:Ig] Y<K}YDQg@L+ZڥKk<&*e~WJt--<2ImBj&Zjl,1iGWguEĄ ?:%bmyZ7ɴVyd;YfThEgϬm|H(LE`_!Njl6om8D&RM _zOYt߲gB:tC"^O@A*) A%b4hJ` eKG eHT-Uz:~s+NUWYP!Tݢ9"M˦z4VQXaI4?֮q)̜ Lia4psMfR`$]ڣ/~߉]ARgbKV "!V aSTP Ln΁>1IC@ >&3 O̸P ij TbV:(MjA)HŠܩ.D@c(+Oj*:wU 0GUp &"\,9,i1V}2If )wdW+ՃŁZgѻVt5U; Da6R`hjj1G$&B`xQg}7:"eAVn kb▣Bu@F'et΂Eq 4囄5 atk1EwWSBTTvh(kcUIZҳkR3)M6T%\cVa 9 ۦnF}x3v Te䪄ht&ĥrWዯdP:%jDŽ)jYbqEza:jS\X~[\bl?9%^=l٘u>1sh}<3ʯ%BE@ DOidz#*|%Vng=9IbFyiD ɝ!9&]NBlltf^lMȗ 6:s5e ȖtkFؘ[FOu r/>`!2H6 ]hdn &z)&sp#ѲI/C2  ,jDX#,_ǮO+OdfN3O R6D`KɧrO sKoxq$:po)T~1'2j0eM4/&&Y,]Ҧ-(FT4$PTw"7D4ZTۆi~ۤ/'"d(52fAR(4Ɲ@-A3 b H-boDX3Ke, q.QM򻵅E\U"155a [iQ=0欁7WoVc5/K̝1>6jc$Sy2#ɶDMu #uycnqޛP ZDFeR9*VӐ$NM4OUbqMQ1ek}YiBOW5L̄4JE}^_PARZq"δYb_L~Yy+[EJi (tRML2[^exWmKXD y i˽CѠXW뗰%T+!~2*djzt,1;A Q<:M^>x|ZOGc]LHFMoϒ Ѩ!3bJ")IGL 8K >fq<&*6ZԍaOP XQ܉ 75INJ QyAӇ֏a.F*?\hgLxJc}3A˃cU{gIX^5:IGE-Ok(H=$ &iff ;%~劽BSkP":i7kvr!U]3|isM$nsSV, ? b:C"%:S3,r"EkN+=QJxWGy. 0P"\p1<բ/:+OVw{T%6v5qafV.".h0gb2_h2K ]Tk ]}]z$Ոvq"HE0icÝm]6C^рzvǘb$u䓝\4~EV+S H4L]LbQԩ][܂u)(=lbsmџ'KU褑Gp)4 yBCVGOe:cYRb ʥ )dkq>hsNcJ|>A%`p'V]1(/GK%ՓԼn_X1ayb 7"tDRSۏ:b΍)ͤ$$ހ"9V o KNk1xmÐ=XB8e6{Q>B@vg|qTf偦*h>[WᖷהaMWLȃ,UoIuH6eF ÆѠ׿h+ΰryEǫ88p 3ʘ5J8Rdmδj/y\Ls̥ 6DDz,Q9 P=F-6u6%ټ&ϱw2c)L Hyzy9}^MTU:}*-o)\Yޒ8M bB Rw6qb"K*TLv8JC ҠtN>'jSoy#+lpRw;ͱiiEp525;FPYLN掙Λ^r6;ǃwipueAj&^hBŽ~5#FV>)~ rOWpUL'N/tCveT7 %2b| B5]H*X|V԰;Fnh7el=eF^yE0&g-/ԥ/އDQ^s8D~*\j[9Çb Š z|Zf9f9Aqe+ҋtwu8j jx@!P齫jRE@[`Vt* )^2QPUȵ }*#)*Dc-εG  }`MPGjT[.Gve'ۊ>|Wb!CރYzAR$s, <% !ٽ+h )5;`[Vo$aAg<^Rh@HgTf :`"zԑ$p xiKkK aסf߱8@3lLѠ)W^~㈿M‰(@z+ci.MPutfWҌwR˶i *(U@|WӆKM'z(~. ;Ԓ]Ed+SMaF\xi +ހ8_}…ʱF@ޞvC-Y@O^{nym9FR_%ŝ.K+#_P~2D@ȨV5!ʜ6<_1EqG5~(VχE\Qtp>_M$_=4Ħ R{`!ޔ[ƶ Hyy_с7* i{Wf*+e:RaI漂KzhIrj$/=%QN%'!ИKUC?w7?\U~ES_URl ڗ=ƤAL& z&,)OfNxϋ)xxx{{YV˱/_=n4SRNV|DRޝ\),2Sxl"51 `Uz<+ # A6f[R|1q.E7{*ļJ?U"LːQe54ķ@r 8G&szn[57c}+Io&,4@y AV |~x!N+AA{h%Uq< ȼ"7+*L=l}LD9L ++2Weg2$YT&S~+Vr9Ί֗T>p,i@ l~@D#uT*8ZC /tnʋ%ukALc dȂ\ MֵV@a2{Raf>Cp7kgCNn!Yn֩[3Ia-i0Ω "u4s4ߢsl+&a^i) 7pWC# JC :nLƠU9\:֕A0QQ_Yqд":}`PGA 5*0t/%1sU#2ҫ8D&|*dO6[֎sFK\/rTG}+̵_P)0JjXćjZԫf>D7tOx:c<:gv ⰭIA\Ab^ֹ-C;a>#Ju34Uz"rtWJq!Npϖ 04FP!p6>,{>"A%O‘já)=nCjiǤ;LEm,w8@W*\J#0%?DbCW-zEr0R{AM YJ(֕.~,+gmWO\m!hZ6V _O@.~y-1SmZc7D6A 3!p8.W};fA{Rp}TPYC\'bEߞ ]맷MKiNk:6SU2 Hͪu3kտM |1_(>BTg+s\j1D'oOd$>@$.LL9nZ VfRnNTn4C!P]:vli[\^ S\ 5 E,N^ZR&qܸ5Z:{Jx07n+WRmC}l/9P m`k8JY{!-g I>*tAFR13H @#^!k,]ۻ( GolGuX*MEùFMo6>rKǜn@ĕߡfʁ(rnLD+w "8|Q-%:C!([9& $i*nWcV'sk86RhXGV! žBY,Or!IPU%yyQ7Ҿ:?byTպRdو;s˜QFt 1+7ϾSCET׈40m9O-Yʳ0)z(E]u]d+uWWd$|詧52Jw:c ?.Pذ.<- ;.. y)iJej~gw%#`LY6~p8Jqߢ w]UM=NvSV\-$EngC^~5I?= >iOmGטD<W_SVvB 4ؓtmw3L믷vآPBY[hvKZhU+KfӳKfA#&zc6m2x9zk=Y18ҒYfjxgtӼ7Tb0Zuj[Eϲ3n|tr4i24mMl_沃 ӘohAw8=h -:Ċ4MsԶaEe5w>C.m/sG=mSx;:B濄wa_r#tòRKL5w41߆6_Y=x_9yE׳ùv8m }YZLC!C@&Xғ jW< 6}Vjhþ ʱ@!O%XXh:Z^tK3Hb22&N\.gt'̢i~D+ϵV%8xzgh;U9V?{ghرt!RKsS4^UE$ ǎِ.A"}ui(|8A>;hbxE^. on3ݔW 6|c(LϡLآi*m#X?*B}+_Gm@e8ڏ?4a?{&mŦ>?T8˼sY+ xBH.ቶ9X'sͫXpv_%#Σ2\$-YǼǼvޚkjYr/./69z {u+j%cy.]x?m@:=`nK! Z§*;`>~1 ﹟&MZSiƇ;;:^v݉QjϴI0klLwѴ޻6oJAy֋t5y/ zcZm{7<ݻ=tLjtשùy~#&']Kht g=R g|:.Ci߂~nҋc _8tej#x{ƃ1t~pMeC![j>EM]c7vǰX*@j[[oFؼk/;21~R%@VOʲ~c.˒/ojbbQu*?-2NuԱ+QAS]h_ëiT{`N| +b L:eoKT%>O6ߢHqVeN>NV>s\jۜڗ姨zWVb?x{Чx߬*{.AcC_ {vRӶ>B.?@CÎMp]od̆:^@?G`Kg]WnU_%ymmzNJ4,γ"7x4=|zt9^ާˉn,Yf̘I{oHkj3DXY|v apl^4:Wti9|sx?D"!];byg>&F&7{~Q%_M]/^#!ހ8cvop.kkxeM|"HO!浹!^gw0]! 2AUI_uR,wvz7VZmmˀRWkiܲhAjN}XE\_9SUR~riT=OʐF|Z#Mp}')M*/#澲feq >v/)hbJ@G6$|VS;V'$zA̤YIAm$v_3mY3uNC!gw(YS8łtD4ĥ̸Vj6qEeY6+X;ǒ aņlXS&T^j[j+T,8?#Biͯ"J^ 6ޖ+b3UC-q9"ڲZ#p PR:3ڪgJP#Mh r5X#%:B BWI"V&MwZGi6 g6Hu=Z%X@P'µg4ȷrj8U >l@#)ٕ\mP#[^t 3ZOQ<|7C#iMUT?9J'I׈]L?|v2;E :ujRp;}v̾[j% ߰@xANRL-@s!8Aδx ɴ=I#I0>k53"0/O'! n NCVE6D#zjkd~pˉ',:Un(W+XV1n>^oE4erN)/@_h 6͉A?y59"H}좟V^i%=Zvt7(ϫMX~;=c޺$ϪF… 3Jl%5/Ee|?ZGO[Esh+y#s,,\G>/HӔmQ#ْm ze~CGQx<sbwAbMp꜐ceikO?7EN)28@.Zҁ7EC/uCtC󳣥H4zlEu{g/|BzQ>I*e#|뭴V[U_.ȁmff~2^ZslM{%Ͳais=}tZ`s___x!]X GoD&Lɟd{7 ϞF]|μ|6/Ͳ8zǯ'5g:ƴ598=H%Ktm?7m(mI6܏v%}n;<3M")%OޱYLXs3ޭضkI×i'Ӯg [CkL=tBOZd>ЍoB37Jw[1ƍ tiѢűrQ,8:?Vl[H<#J 6Ù뉊+̤wwѯ/=]si)>4QzLY:;& GgÓ~tԗ^=C=v߭.#DcFʫE| JT/ bՏ4|bFpO7rX~Bn[}ޫr.Tu6 /)7\4s't76>zUDI:Ao4`v!IԔf{EշO ΟAWx4a}:p{)M]imUv^oصjDPmWN91ghIVAGM_8V9 OD3ϧme~k_=K;^LC53w>ry:lbr2Շ6ڋV6J_X[nI~d17ߨVDG~ct)<.M> h+:'_#]I9ƅ[ɵNu':"DֿU1\Fl/<$D;bJ".gدCg Ft[+yWT6L}\]L{oW:R$?+з:ֱ4|?G=e&?8TZa|ӑ%(.Z&lL?:<;V|^z%{]w)Sq 8*owsт p?دӞ,t!϶Cz~{8l5kM<~Ѥ&6"^+ syko;l@׿UZfO=M9{asmekۯo]B+ȏ?;XxSOzv*+}~Z5O}2ߌ[[(\gHU.Uuw鿿 ϫҭY{:bP{kG g GA`h [Fnxt[tfaKg}li5/*[0vv WMUl[,=ĶͩضB϶iuœ7VOm0syS Ս]>v^0xZ~~4i6;d^6֎ ϳL{\Nca\hFjJ]礍[|zYW;m)ڋp ֝pG*?:-95F!vö4~^xwjS[zBatF{*~x˼%Sq}So:dT~u=<+?n2 wR{[}~ GVï/0(a!HW3}dcC]q/yߣ?-D hf]'lGח(_7ձ9[/o` GGD+#xo xXQ=/񒌜c8O/h+_Ï>VB[yuoΟ3곿CZҩ'iXyuzbɝteyOfҕ >꯴SOT-s5]Gu7Rvb>[4djmiUI'@ =!/[oN;[to~Mgu&]? ϿL5pqʉ?rN/c x츮_SSg?^Nor[gM5S:&N\~W>ӊ7N=T~G~Kϧ\;o.ygΜICݗ.ʡJ#ùDH =#>"cƌQ'yɧ]TmG7м;dbZqH(^a6!}xUsʈ;E.7_Kܝl}m4:lOфw͹vriR5ǬD; N6,^Sp{?nU7c'G?0>}jļa;wm;Xl[#ն_l{6d۬ ϼuB,.;Q93&NR:cVQNmo?8{ );`q[Dƭ__}n qGvw5GH:bG0|qԪ^[p=qn?%t>WZΟz8;Ug:YvQyuaWMggַWߊXaߏկpA i2˪+^[mيl|I[o]|_9gh;عAJg>~KC>W }aFs|۴۞{ѫV(&Iԩ*}ULjLCQ,bN+FnW-6ی6mi`_4̙3~mJr}Ҝsye]^ݝ={$²2;tO&obuyȐ.;te6hC߶ٶ 7XWN/!{ﵧr4aa_c GiZẀXJɛk}q) 眭>Na3:b;]1Vv=mn 6۟e,V t;Оn6>zkx׾B5n۲W_l;ui??vmv[ةYs.鯮+^}aվٞsN9Gy~:vc5wI[3R '25}f?9 A;Wx~osvZ~'V.,wL˞:~-, '>xA}IXwlЧڛ(n[X0/2mC~'?zC} %_$/)8o1d՗7O'n>xQ}Z1Gjco|GSl,/58qc>E:g6|~+\CMo3s\ǭy2@WS#OѪ=( _V3mr5+HY@ /AʫgLNVKm?_ڂ.ſ~Hjm >AJA>E ?Mf̊I`E{^I-%р.-KKoȐ>;~3TT^q~A˳W\~t)j+ ꈕwexeJs$WϛoQ3_tyE؂2eJ7Uxu4t Qh۫_֢'ae~ 0ލDsKoh5Vfnu#8рџYc~rXOl03yt4pL#`G.ڞ\gFm r0FCh;:Nq!#nېmlCm83ɼtA/f>pο /Ly4F=&AqA/H[pDycf-$fm/t !o9#GN ʱ$Z&vtxƒk JM3/_]|'ɬ+1 =+̙Wct _kt p}k~hP^leFKOG~ZeXP?.*񵣿Dizq9>ՖLrM4#  a+{&2ae;:-D E,'td8&-ަu qZ ~`kM4^,+JFaPׇ ?Enhͣi_Db' O w/۽ȸI'0n!om @(_OZZNib.؉WU9qSފ񢬛)Tm LʊbG

}WmX>L%_z}Nz-6W6cI_wQf t(NGv啼cQ ~nU3f p̀nI6_? {{O!vSagC=09}t{oBs~_y5{qΟT× G|V#>vƙ\j=b ǘ0tQ-a+iJ7m߽{7ʈs UxǙlV._2޼)Sÿs};}vۼzr;L1g/}>YP9T/^P/dAl6jCWwZJx/J7ohlԥs'΢3+Qv~- _ɼOK=(ڦ3>t"눶!z9>̤>s+Kjm T[!jw4/~G|y魷"+:W"@c _̲ ;ʉ43{8ίusFVZS'x!*MҔ-໴:k~|9>K~[Dp)8G}yև?\rEV} ['|GλH~CŹX {T=i׾+Z p8*p<{djt>VC$ s4{mGm{(9qߤH"[JP>{RCNR[Cj7ߤޣ0W9Seұ̷^(lO/P-7ߜ)<Ɵ ~CZkp]e/=m|zƅ!؃ 夎AJ"o`qj NO{!#D8M'̛yފ2z+#F V.$Gmoldzp~4ˮSTV!=c d?zp%DxpXE\ၽ ;ol)5˶s6mi*ħ( i% $9.փQE8Q.N&K3`Zh/́/!?0= `/+辞tXAWBtEBcn;J~M匓`Tf?x7^r+g{.X(ta "ي3 CuyMq+q"z'N* TUL{'C%9WJbD((5,P[rQZꍊF;tJo3;X N믷q>;^{m>du[N@m,c5Vm۰ 3e8cA(?‚-"Xët#Vʣ["oM'픨;Vzu$&QtT5n^`+ڻ}ߡ],+QFI[[atmܟʶ ƉcˋggAt6Yd[}_y_Dma V/Kqyqzq^zg#GI{[SO= 5V[ub((_hE5΂Zh`T [shOb^3/R4as!|5ıP3r&uqSH,Cev&wX J|âgu(?}Q%88 ":CnXIFXį|plGGT(QriB3 )#pp؅ gU#6pZȥK ԛ+5ld g7\`07omr|D^VnbŧΆd1c$vrԮv_>w߾Ǯƌpv48Tm!2"ɜYzKRj8Q>Il-љ^z]mj{DcH2x5 5qze i(2*SֺMw6BoF,t jهxtLQƯV5_/р-d=*~&wV7q3jYF5ji_meK!j[Q'C Yg?.}F D3]@@&zzd6&NAٸJu`@({KDh~#-vӄ)ÉςE@v l(3,_[ʼnVnP/b1G{*\!B"PrAeXXNwkp8(ed'I e$ `iJݷ-̦ *)x.Pf #W|0fԓƈay*ǃ7DEI]naƭ(j LkRKT7.ōUd֪Qp9@C-juj\muJw=lk };t8'*NU49!4" ;==Y (up~YNx?^{~V-7l9:s3h~+| d6c8 @Up9"\U-?Cb4\Ǒ^Y=Aޓ4f)c~J?7ysWєi[3OO!jGWk SiՑX00-ZL,IM~MU@e4弥 C!p4,5;gʋ5 jE;6OVWwC]=]G/ґ}ߨ8#ԷoTkoM=]lw_%24}4rD/8PWo;25vq9Ӎh[eF_2gBAc΍Fo.IA=iF3U:633$, ӋJ YD%І=v-6 zˮ1κlmҮtӒ%4z(:}i+Г>E>voT28ǍߐNx%EIGlp8M*[N :uSNO҆ Ö_?zrpov$pom&P|ߌ~O }ݹ突k^nx&ö 5X9m1tgW-C0Ó}<7>1ZAf }޾v:akeK=Xi=+Щk0Pfd(M2檔 C'Rk<`&\6ԄGa ל%smWٖ>4_ȰWz5U^?F*GL2+W7>T/C?{zi+| xΒ9t]g3_ 2ig2f2-`'zaB@| 5yw^UpwѦ+lulgѯ3`ez:e#۪#W{h5vU[DmU>n8بwA2V$:Udcr@__KPcL Y1np7V<6ŜD`OG{8OC.ڨex'>ӈ>hcj;pc8{L#LKykSzNuV«߷QGm%m-m_%%-_6fhئG엯̊!GtJ8Du2,IwbK[7hUp,6qzLqz3>DIFY K18N3: "C\NN9*^:S##bή.Toɯ%2֍YC!pTo+ͱ x 6ug]m%m`jRW3TNzD 8J7h}#8~f{{1혧o:Tn Vjw}}.O-d]!Oٳ]fp"U__6SN+?xwGzfexOc&o%Oy~j+m^ZyeB[PVM]Wtb@"~ʇ؆Gsl_GMؑFC?x?8L4ݲ-Mqh_s?~C뭻WN lI Aģkv G$FN?N?v?d~[Aґn} stɓ*y1-/ן .Ff7:@:KK_F=ުKK(/-0Ύ!W^x^#sY9|ZiRpu9X^>븇Oq9K,3g>Ӝ#M /|en7$ i/S>5p؁oaVe])_UTb_t~ad ;HgV6 bdkbpD9( 9D:kiܸ4hp;Pss3/6=!6fs ^p:KM\ǹđ_4jl j-W9~ Cbh됚>fHKhpH[l^!_El&+QTuԀ;kD6|[6ujNఴu΂: V/rotQ?{ EDr;$JDT"|DA& dP%)9̑lK0{3ӡuMuצ1\ }h;2E$爴$!A5phLԽ!GrIȡbZgutQq6P+h[*5 !WZdtCY*lr [w Bv4fԝ'7+-˚;ׯLI)Ɂ"=Իz{EF+&Щ*vaRiL޻MkW:+)\oK326s=qS KJUFD+"|NL%V <<Bm)ZnarOkg-D:,zfw%of#y rEKyJ^рPgם~ƪ̨ɔNה*2XH[_8ȭDHosZрa-cMWa loi;h db$k4@mO[bv 1HjЅԄݣZEseyIdMnЀqrC+&7]n4nҀMaO.T o(qT6< d M A^=}&~1Zƫ|,RRSO'&&'_/ pEQIUk~9"<7[qntiHM HHIqH1ӝKs长[lr9f:{%\?k7ݒR kUvҸ/;"{ { 4N(qY6LC d|Plj!b˽ٚ?Q#GmjB>7|]f }aAу\j֨6Ù O:aLf*͛; (6d?ZڹoۆXђ4ΰuN{mC (M4Et%X!jڃNdCm[6]8bc!z+9lGSk.ݤG3gz$f: /*U8.0C^Tk۟ߏ02uM^#ЀC9>ҵC+x`Ҭi#ڳ ~m8=٫=ݧFM`@5hPlF>O#Njis@p`Zb5}XRC!/|ھ}%$Ӽ xb^ݺDž  '~J5XXXs +shX(ƘAhf4ء }MJNNN~\t/z8/N/mGB СkS>DE ٴ'-SlJ"@kG-瞈z.~;Ȗ?צ\}Rc[`/%:EvO ./;R޸w'n[,RgԪTu׬7}k o!=\6=^H?YvmT ޟ묦uަ zW$ Mo N=^gPp"J7e,C,$dW`Eg)IW9o>}i_3hihб'h ybu<X=]մ-_~A~4_O6'Fw.]hƷ n|4"H#}4j/WgbՇ"jWr!Ĥ$HA TQOҏg x׻WIBrmybJl_"VjzX!O8et2.SR%5?T.+\^gC [IKCmA+Ⱥn\VmYoO`D|{A *D%K 3  ӂ$*t(KrȎҴɟS^/QbEE7k֘'Q]{ݳcB4/鏵Wn w(3h@X_8Pč5uHG3GD 8.]Zܺu|_EI|D/۷o Eu>p@95hPƍBm<"~wz̲5a:u(IHcp ѣlL̙8ٴy3]q"*~KGbb|<u?|._N/  sY?i3zj"ٗ}*&TLc q X!.%/Ҏ] Tm|*% _8Ios1@Og|Fo.RBʖ|j,2VaX@UXM͞`@d,ot\= /Lv,@@Z$,h4wgQJVY0/&jLlYQ @IDAT^=%=Z\"l`7s%HBӖA+Wx+[."mAK *]E^7E+Nn~j|`à;&۟!,$r<1ɉl!{KV`uԜf;儛? TXż`OJMgTҘi//2Ą% #Ȑom~zC&vDMƙO$ޮ{K0&f Y@<#ЀCj_&}e5FeəuE6n%;vxCCClgƭ ?a͛5[ŹyU3' s?sf G:$k~:_h 2 B9 ,(|ss!'!8{2 w䀌m쾀(C)×XIIs<]PBɖ-=J`Z].A(3-PIɚD[y7I#Gp5z,MUGJH }:ӛlG{^'M4\g6HCt!)‹ WO!  }rR)Y[aitHĖTXc符BJ@ 0 Vbm_J6YhۥcT`Ij T'X lA5&AL#=@?ŐH+IE &`~'I=:v-I>NF*' k?~ ?x J+Ln$Z:} }{zz4# 0cmI@5%Ͷю<ڋ]leoĠ<7/5`=^,4Qh\}w aP Oʚ%eЍԉյHof.$&%޾o ۋ6 04#}ZC4e,Maxx8m:H(?j?TB9.f0^^ض̓`,+0 _8~n0<9tA8)Sb0^bÝg0, *L!w ,i& @ȟ ϵkɪϦ`@Efb"*5eyBѼ]:qsłH+WׅTaRW%˖S<` 7[ ;G_?@l4 7h7fi}GOҾTV-{˃-3~X܁Am=IMص6nv0Gn"۷ 7>ׅb"-񇂾rOъMOtdf+q⡊~Pv1/}hCg_mS ư8K|ZalئjmZ{gck7ڵx m~whvJ>>+ ""H=c9[/1D+ 뭨 .ٱk7?q[ v]f$14`h@i=b,԰!҇-Blse-WGX ő6GyVc_"'XB̸pwԃH^&ӓO=Mkդ!셁/8jT.i2xr#҆c`XBS- mpO[ ,.(⋮pPvz2:-pEZXѯ}_^yu|lצO?[C͟Uhol$[Ԗv]h/|ᇵљF7@fMKعqi2s}-GmW)84@+\٥ 0/j/1-G8֍)ˎ yVg,,Į'h;W{Ow=W s5 vy;dŻ yPSVج:K0EE|F6LUKX$?'FAȯ €M9ZHpAObTzHqa]$9*WK_- AҼM պ8' @M3ѓ-%/12i؎(luNaYȦ'F:Y|YНvu[#+֎B6sQenwo,`Ga: ^ZO‹>_ӼSʻG߂z(yJ}>aYUSi|L?MuqzD-=`F#Ѐ~`I\*.`Z8#c,;\-9P,l,g,wlyi:?XpXXD 1(i 585s\Z%0i+ 5 w 2aa6&o~ܼB$t^O Q @ͫх|?y_$p?e-wL`=LpXVO|)^\k<*}+VЀC B Q0G__$ +,8s#2?X{1qbuA/ʹvf|~z ֫mS dlhЀC daypY`2?v#sߤ+{7+.G1sW"Oye NQ : /u<r}IsKWϦtᢒAC"f-lQ e8c/v!CҀ`Kuϲ@k@Xk< mU&9}2 7+p@8")1p̕ؤNKb _Ms֕e"*˻ [ndQ ҕӘoO/)z8(ߎ*uYHEIIN )W/( (y`yy'S-X)P _AkT xC{h8/6Lc}0$24`hF|40O&,&qm ׿8mz)e.ŠrKOj=RbǹV>]9E*`dwU0A`Γ&)Q WWLB SSD#<Ԝ?TߨHg0dedDlIF!5(0C/^˾yvN)jT9Bz )X edyֿ縰3K]TQkCr^x69/Q.xʵ9f7Ȣ|aL˻ILVUePlX>Y e7 ×wM`ؒAu7PE*#~ps-oחJWr MFƀ5UjIìV3ƵC 04 wg "| H`Nk>;<|8=WG|sܗ⢷xc7%ƑT ,{ %_mk(b{=x).:~i w?:z]<6p1~q|f'.6emg3rI SԾQܪZ>ށ26t+ix0HvÆW+ ctΘ͘Jl$еsŢJ6tRMʵF>Z2@>O%k>9%䅎Sy VE G.My|%XGIe9x?n~#05YJTڣ%6Ƹ64`h 7k@h˹ H ֶI~啁|../P#`Y{^U.ɕswAZN#",Mf#,]ZqNiJ:yZz%%%ӵkǺg&eCmHhIѾs[Lp;,ՕEFWR{FW4Y+u7fiH7` 31S!Q̏ w>cu-0݆5i4`چ;E!OCh4/(.>>KǴj,M)))ѧh ɓdrJ^<=> G_Xw:yȶa:pU?zzmU/*toI;*R]iHQ+OG7zThbj MضWqS>S;M㤚\|u"{:WΓKZm+v._x|3?^OI хVe^rvD/] e:=˻a*ob2v8fclf㋮+(D#|gg.ۉt*ۢ=^:.5ݼ@5@lU:@f +H ZBH虀t9H{Nܺ[֋G长 k` rUkݲ2hnMGn^X8kP%s)q{4O6n$ {8u$%&$JRNdȵPAHϵuuB0eˇ3q@ynR>x/_H?3M MiE_}}G)S%@Z,CS!@];w-ϰg9N@t}-E)tLnaMfcXXʚDKg%r]~FN~|U:r8NXi܍JYWbTVVyrEh@GĤ$P|^w#tºQ8 M~º"E?=]wwiKݫ? :{tEE*5aOeZP_9DZEtPe !ɉYT:!*Ö̝ MMBCƙaA%xa}+9>۹'ФVl¶KĤ~n#޲'U=8 04K[l}oNj!+`Zr5}2q,U|j]q#m߾_@ŋG.\H/"}n NP+.!=/@Uhh(cPA=MLF۷oI)s< "8eTڸi3>rFɓH>O'z:h[oR%UAo +۩A4qGO?uDJ ТZOGqqqTH@j߶-mMS6"[^DOEmE7n`WR EY,PLL/Ud',_x]q3`>'H>ZOƒo=IkS~@zo5HW^ep=߰4ײ%Mx"e3L2CE=q$[`ð7Gjm;m$Iocb"23?}W#L'!װ"~g[3`zMAc[@CEX܂ZRd@D`(o-G'D!!TpK TY u:xmK# bvYe'&+ bpOD z}T4$7Ήt`Tp91b XqMI(GI~p+m: OɉLX~]u xvz`\D0<;!λ38NWo#ߣ4ūtV7e0'9o#~y ҦpJ ASf"7)[Z+Q{yozهTB}{{;r=lh'VQ7!5`0@zʞ/Od?T W8 Ώ>FyAFgj^?$AyKSJ5laҶdmt:N3XOʔ.Esї.|9ƎN4h Ġϳ}@0ggϙC_Ρ*U+ .ZZiGl5n4zwB~ ҐPG;wpKj6W441hтzYݺ >o20H1U 2OH]wr 6[l[NÙ YK5s0` ,IiN-KT+4}YA a/8h&*F*d|jVMxȧ+};I?mMȲLwXğbyfO`!3j\Ԧ֥kSIx0J4c׃eKn[(<nUɴp*RLVl"N.|WdS-qƟX)a $#?"(v&أXIC,2h|>ԍw>-9)!g0[ϰq>œ2"/U@4{.-JTؔD$2Jo*,ݒ%KvR%fr9P,\m(+0[pv6 v\)U#~FUBbpRNA@ٽI/1QHجi#6y{~0@7 ޞ=…O?m`+*[b]EJJ*ݛ^zEk4[uDGlSOK^ 0kV.ae׭+ڭtԸqC[[HXyK* QNoݺE_~6ZdG/۷`"͛{*xviQqBdkҸթ][F gϙK:t`w$_3qia]h!a /hM|иѡÇisE:{0X?i3Z"ٗ>7--x!iڔGK`V:~1j8֞@t37m[CD*V"Y*R qXa!ڠ:JaX/b DڲXMgc pT+ԕAkj'x^#Kkgb~XXZw]9%,L߈rGY|:*m`b@\X3;hقF2xClH(P>Y0G:lxX'A, ZP*?2}*[[7euWn3 nOXy'8IjQ*)=e]e,[)RG=̲9?yjU):_DP(ҷ6ΦgR u-<8O#諣 O@h>_khZiixXdѶZB&R=_Yz]x+O ^lxj)~˸*Plx˃7>L1Y}rKlsˁf8!lbŇJ*Nj>B^),؍c1:xS W R-XrC(}WƜAFP!d* L ,ʣAX.a²40޼A7郱ͺ|ކˈ=B}u&CNd~gGXW#W[6?[ ܌ZHqȟc!'>#@tȯAԨx;yxm)Wi͖d_Um*H i2D&+d Gmx%ߢ4$ w,~V /n2?xW*`z˖ؓM|vЛ"K/qȻrov ፺YY霝Mha;Fu%LbeL7brRfLQ_X"`-6H^Dx_JtۮʆodcrRUgj6_]$`,~9lpTik.ץpT Yv}Av_QfGwXH _+ڃ#F^d}`{a>smB>,M1ݫ[KNS25 m?i`FS!(OKx˛@mBFފЫoa6tSs*# `+(-Vl.!{u ⵸Je GSo:E Ec_k`m:Gp‹y" 3C֯KVS<^8mGԣ{7λ4ր v^pQGIQxx Jto漛ǷԆ?Dt]-djk w1*n1j^z_' `7LX٧ tN,ܴ[g6 Nv/ ƘW` qmlI;Zi Մ[6U0؂|k FDW; )Ƞ"iY k;t|¯A;}}-VlEWhy">myFdE,xAHNџyGOv,0$h|"o á)^Lx(HlU dO6/{O{OFl#ݬ'jlf1=3m| U`m vPJK{Ĥ56MEt$Z>ޢ4zSִغ} 4|◟s~,To?i9 Th{G~?Z ܟ>ESY asuuC ;Uh@%X gQM{|[EѩDq˛uBK|quqnh3 h Ϙٻs;lL V1 @X8Ct\VCq"mx[+:&Oϱ-^M=78(e73\_ wh'>Cjդ!셗8jT.:VFN 7=(WWk%Vhj:85ؗ|~ϰku{+-"X2c=1Qtʋ;ї}XeCO1 Ckŋ}e8{dYgН}b#?54gU H PON%[{/c7,= v-@6-_2-vVNWиf0K>m=0p-9[(r"^<,+l.‹Mʖ;d: !̋af1_+KN^p[Ƥ+z3{SqTv≿I -9צw~mGp5)ܭ&,z0Vfχ1~Kó NÁJ97qnj?3rZ !%gK/1`&5;*:8VTU/VFR ti{d'w976OnΈk̕RȒB\n+Peg_crdѯC Wvz'svX7ސBS3E)CZ+\'u;.zT(7I=~d^r?h`\{>[VF6gNiǕzelyB.'VE٩ oi>{K].k%pGF>!\?64?G+i8NFL87;fβ? yJ0@hΒ%0nO{-(s %xlDЎ;HmS)wH{i@wew6̦,iViO--'01ػY][wT+{yp gnjwݙȹesB˜)(gzO,']cR*5 K41 (/۬ogNk@% ˲$nRnyZ1XE ]g j @Vme\Z%Nm*ZFy(i^ch0r_7fYQ;g*;B09RzGs"Le)yo^p@IDATi~N) } ]?SoSӱ~@iGoGZc'n`un毚%:|x='k{QB6%$QL^р ȅ$V3n) R9Sis\O5ym/tq [n&Q|5GȄ)̔W}@Z.3JݵM攼oVpulk\sߺ ̸zYHg+Ǡ2I_LްNXuΣ:;{;5- Џ\H9[>1\]rH騮87j z sP%zdoR6^a qmmE3/Z>ā.NK hK8R+!bȒDvLOolOp+ &4׬m WPʑC_?AA%3|/G)K5Q<2C`4]- XzV;(zu_īg,U^Vm*E/u6?dP ~ܣ2uOӑˇdOy2;?c0lX-RzR!/&R}ě1 _&%].!K?|3|oK> +F'^J_24B`(踒 ;HL׬KA=4a [ϦkW/*)^ +9ͱ?v8)OϚF_zca. 'B9e'8<"Ԯ+x;Cq_~LnO,9нENE̦9;gS%bENhODbHB ;svL+OӪͤ8 v״bN*9W%J* 7e$\0+;qLu%ʈ͋Qqj` d~q\lR햬3/@ /] є~9} ?sƷdxSW8թ/[5;QJ52>Y =`X3ua!&/ vSHj"_J>)o)߉̢?REL P2cɿR5tv/ep[ Γ *~I)z[wP{9J=zHE>~߾Mk5[ah 7h@;^ &Yb=8һ4w{@S"u潢sS޺\m%sLF׀=43—>2sqxN8JoRd n ȗ-VdK ・3(~jQ~˲țV_g0 I.'0q2Js/JpGq}YؐȷxiSnLLbC k9,>; v`#aNj!5b R$MoHeԉދ9W.]VJ|n"V%\3넲C;mV VN(#ܬ5\92f9< <EPʶ-8YՇ׈vc)yϦ2j*eK5KuzBeܾEUQҶ yv;K$3ʞ9Z+-^ h،}xѤÞrj5(}~_3NcIP@Ȗ v v52yjWOe5e^yk[fudhK{IΦtUI,3b:՞J^xlf{FYaveQn ]>pgʵ4"(=,@.UD} ($LD/ލï{o^:/,L_K6P"; >yf:;d ?)gv=ֽ'uXH3wA vɌ4I B%f`F1_?4t#Xe~>9.S<:7+ 8y&(g*z^_5(G&Tm6Ǚ%&s,W B{qUvm>{µ\-LDdQ gGN^l%Tp$ڗ~l#~c >89Vݣ ᇍPỳٕ. YFw&YD>Avr?v.Wzhh`5=TFtU&\!kkJe[ofz)͂s:][V[ 1h &W^/%Jtښ vA\:qeh 4 ;1e h(-ȶɦ,XIe22=j[l-xƕЀ1e~3K'Zz&%}ˊڰvL4ed^PS[͎do'P$OWۊ1ˇTD$5  !O9W-.jt9ԋ)B!;[E[uj쬘eɚQXwlF/Z᪢Y(2tkcbsuusp]cޫnUX nj4V+jK5QGEZf/9㡗'W+Cbk_OVN}8o@2 = 0j *,c _"5 {7;<wIĎ /v%3rCnK0"bNmz 7>+L&j/fe ,J[BlHiaL III_Qu(ѐxMrKik4etڼe+?q֩mG`AqԼYS*KbHEB,;M?$]9SiCC sXv?sՌ,@zm=5)٬fXe*:BoPLjg52coyQ}Cԏ-E_}4a URJx>p;Æ2@rֈ<uͿ9*b*ϴ^<2Νs5Gt-Ӓ]r-=9ٳ.^DիUu+{*Uӧ%KʫNd2#- ,V!$p:?Ze#$)i o;Jq’VrWȱl\vcƵ])ђF>zaT\&2 5WZP6zB;4J&0l6 s `eU*SL[Q9[tlu˖-#w= >\ݧJ?n6!ˣUJ4U3Z Fkx3v>Gi4!VƅCӀP%@bkņ+48AMҞ}ׇӓS>=WqPf4hPlF>O#zo\g[h -[>8Td;vv!HfKļ xb؍v'qݵK2~0)c'{(YC/ʟ/SitzgH DRll,=ٻ7|'/)^ ~pԽӁgE%R9ܹZO[/xpp8T- a2У[qtA/{c@*V>ʞm1[WHZptהG-h ב Y^K*z_%\#aK R@r80 k ٫7,14"-|>+Q Er֜%eMڥ/w"DbQ dj׏v}bl3jywBg*8 qšw)-V(4GZ{q--kqw+N@blnnrI.!!಻o~Z6C3(6 z0dsӏov?.L:N+0/ؿ*XC\4YcƏ^h>Sֶ~5xG.ԵsG~GDVOJ,I}{ҥKyzŜڥ.@\eF\a֥ɍi4<".^qѧQS4$8j7kcÊpl5I^%%`%aN j~(d'4X)Uk6PS 9FƀӅON#GO`D hW/O];`0=D||JJxͪT?&}4y)͟;o~x/S ٔÏjEҦ-7h__12 a؈LJ6[@՗&OFϜ6iL˖,VTnMYr]zlXL`XNOp>0IK"<2"^LaԓCNh Tf Щ ~e4^fɢLj/aek pzI`׽B#ӕ2*ː4&֎j4fAoG ,MUB!/0,4DyfgIRԫXa4VȔ䱰QG_d'u&l@iB0Se_Mؾ>˄7W!Al,' fY(`oϝlsO/i.F2*p5]z=Yl)ɝ͔r(j1_rkrSEPۮMk~:'ux&0}. M 2pH;vw -[p/4l8`%(`J2t4{Ə< [`ʅG-XH˗,~`-URP@…A<2p[@^J冀.Sޅe&it#1{ߴ8c24 Yf7o+CyNzL]K$t mRljō+7\9h |z2 }A>N?!J˱Veu֟N: '=rzf-[4%o>}Ҕg_Ԫ%kbG CeMr kl[[p/|(PCҏE`A%YٳSre Zo9O4l`re KlD{:f2My[7/^y>Du&>Bc] ϋ~/~ 2[WwwEY# :wfgTByu0{|jaزE3۷mC6nL"fȐ<<=4a)u*R#P>4P֎Vr8qlJpdˀ󆸶+XSi'A^aeW-4W5h_0{vdT>c>rHF"%j$JzZ˼ k.'a /t|b@msr3TId)rH/4j7<`ঁO&Y,y2#+)#k.;_eN>Es*3Y^Jm[Ing啫@ Qtv[bWn"]ߑ#N]k390ת)S4A6, 34?N,E!uy S6𠒜֒e ag_N"LJwLUٱ(Tl#9`a4g vmZ i`ky Xw%~pK,|ֺrnƔ4pK $uO!nц"96S;]2rb[tӒ"JЁO˼%sIo_Sy9RgΚkIr-ʥW4_39D0_9̙03<\w˒/K([F!LF`^&ot,nxЧH3CɳnSŸ_+7: z6XWKPt)ޘxZy(NJxR,SyGZS yf2rBBxQLI%I W?%ySN?&m{7 ,Z.w9!44Ph?qZ|;<(Z(Dx97^x)4N9y萫ʆZ h] 06nfڷ=Ә 2ctޥ$XQ9J]X(>ViӦ;W‹ <٢n'o+S+qll#\\96 qIX&K#XQӾ>l/ٳ{7q&MGaj˃46O3fZ}IKe5( A+ S & k5AC 7l5/4_SOQP$;96c & K '<xS+Ŕ>EQ2Ѽ)0sW!!|P㋙,nX<[A& S.o<%KfܞsHWZM{'hᷞ eΜ !]f[Cx%xGt\)3ҟlO}ef)8Q yT))llw.=l_3*3&Sc/=ڵneGk98s0zX&~O87Nڦok*`Ń]x{G .!D.NӌTIw<״xOyOy{ S-{[oQFG_u _xw2'E5Qc_vÌkH!E8wGu(k'-A˘>=-k[ĘWLmvahh}}yf ~45cƍݺүq5M *D#( ݳ'Tn=ܢy36xsy!ci//B13|R>sJ*[M @ڹpfMBrzu,L:D/"1 hٛ 4+/Tk>^>kZ%~e8Z4E+Ů)ZZdfjN"׼T6xׁ T7l@y!5ըu|d cQ N<*{N8WSNl7.5ә(Ӊ)ecfI7p-W!9 ;FI=\seo-dD?QL=Q"R<[P~j;-$E(CrS-d*=񭅁S8FJ7 $|?\wpuq {ClʲA% e?چwI dm&[9zB8?h!hq00=G J#Fo88'TpCHo?|;ФqcG{祥sVTPΝx!̳$g:@0~i!lB.Y*v/;ވ PK^P#==] #tuB>E+K}@\뀝N;!V>2p>sr܄+qHg^Q"n~͚ei}b";,:N#[=uEt$+ Ld 1ℑfa` mYK`ϋǵuqZjz6R%s5bGVN܂ NC;f-fS^!5["NC\ݲ:mkĒeyA_I 6X@Qen&=m:S呂e媽P5M? /Jx>.ftfic5!:yAkAG?+o/hSmo|p`l*9ej#!juփw8Y¨Kd#֒ |\Ŝɹ>66ʎ"Fa W51=N<i4 w`/Ѓybk%@8tvΔE*^%~%l~ڢFbR*V<|CI:`V2 0Y{dؘaE#3˴s Uk_ ){2&W&Z<dvI3l[ig5aKDiD>>>jyoG=&Lut 0Ȏ 5`뷤>rVUR%Zm+t+Ac˵]bk$kQ 0er,XplbHƬkgٰfuZq=s0N9h8| vlxȬU=:2zeZ|2&`z52',(n5a[Ѯv{2vHޓrI1$,#IO !sZd+ $<?rhMx{'~TA#zy| ֳ7ΤRHw%`Sf3d%`P'F;bj?xHb|@9Kþ+W[LOTl~8-^3ܵ*Wh+C}7˓ʨ`TlY±Uzǩ8'$0cGĢ!vi~i蘵*EwIʑ=I8ohc&Z_>}?zJɌ1!l+K e6[i]/6q_ٓaɐ7 `=ZA#⽉'ڌ=qb>Rmo?o`F"7{u6;=h5-䴎W[b|uo7qPR@bU@e/1=ENt5 q?РaS LC҂EypВO}.*ZH\`歛VsU+1˘[Ѯ+u|,N+&8TZ5WRL%͟=~ Je@_hޟxr}]t>ld_,]N"G=  qP41"q դV>ϖd`98ٷm-ސV5](m6$P±NGk%u_SZ9TCV6k[Cɛ%plh_-0\)3oEnۭMQLb?h㻀AZN`4{puÚf0:,~h7Иs4qp9qzD R6GD`t+3.ԡ]K+ULI:rЍH5kT1x&Mji}n2{>:e4oT_m'v]hOpx(;z4\#Gw:oq oՂ%^26d0\><wtq*S4M7Ӊ/]qػO<m@3d օ#DZO==v3)N*?8;wncB8r@-^=8u4}7f,|Ooyz kyJէWC{87'OC|nEgʙ#h(W_77o睻 >=e0:z8}Rn:fq7'qtp"SZ|w\#gw1 6ӽ iފ|rQ4jj%+bԫD]3.-aȧzs!o  P61o,xQC40wl *ݘUF?$rA/&( AޣDŽ#+f/x}tjO92z_qL2M mdj5$#HSnYn4.e@D||yEiߝ|}[8eJq\|\ʓ* ,Ht+{ ϟ,Eryob!77{bS+{1jưL( 8Kj,yg2%ٸ oW85q]\d^)!pZ|ք}yj;ۤn-:УG]=r5\h4r ctA|kGLS/48|+Y˘֬ZITo􊏬u-TN]rPrOOvz3Я/}qm:q$![Lcy44rp>ap!*|C>oѬHg02eJ` <X7oӨQlbI0Ǒ06b$",LS@,6oD7S'fުVoT %o$Þ}VԡSւ f&88Z̜e[D}N2]~EԨG/XZjȅK. wRlr [^M fUo=43fH۶+WZ]ÇVm^Vm3LT9 ׇ Q⃼m/Qfߝ=3HGLԬI?Nš wh׆J(.c,kʗ+K4'̖2c??noh[|eXȭ"VYyu*R*f6öMh*PTu\hsL/fCJ5`^3;2 O\ *3R1ZDhu؆1pUxkDe3%EwTn PADչla*wj4|3JN=+ް6y:7/lhX䖌Μ7L%r3ƀËlʶYBr`P |Y!O$ 00Rk!0peЧ!ZًS}~ d 8ǀ f,UnA;'l=-7R|'gnd{&'$^@N)s-G)ֹ]eH|jI<MpmD>j^"A7)hApĜCL>`)A .p+ >~^z0otpdžtN5'hv%~j?-t<~Ԝ9s'dlO)v2e4$k~/O.*]! hch.k`FL`3GE0 0)3f0zhF&S(ۅ]欫OXB{+ }+KT#0w9~MT0"c&uHBFG S 0M,T@@IDAT*44S\T)e M5v96-^2$WlQQ2 !xC]hlM"x%ZA0E?~Y2hZquD,qIҋ͋a/>:PvOJ&N ɝgR `b`kUKM4x!t]D|,vztW ` L  i|WrZ|XNj%#޽wO:pbI3iFT, L"+L A~U*U,hų? ޞ6t~ty x`8lB euv`z@Mx>NcժVfCh1b;_H,EmZd{-}6 Zd-[yoشC>–byEn1uڍMrD5~aZ]q0{̘@wZl+H-\c[C vv2)17k6=$!#a'`sF5 >$ɝyr5o)L#_- & `F2C&";kyctc^\X =]ŌQ^T϶k 2,&;VȠٖ`fC|j@gh S-eSJ7Oaa쑃y} _M3ީ ?Gt-l? I:їL k\0j ˦<ʘkLf6CPP tL̚/NO\ ) QKȼ^FY8}2M>vdbjŎdz|pNe m)d4ޗ6] #˕1}zmHh_i݅L v6F7M:Z8ɻLtBɷ`a{wE[lO3ZM boV3D` 0Ň ; GAXxWxq0oO慛7l@hK+xoݪ0s[PIL<)nK=w_R݆Ex P7P1W<&BMHUD82/VLѧ@C0BB0ȲP> 8taю:yK]Enߌ0An>TL׭K~Əi/JK=@ V3Pۆ@uhʉm6P'V[+nDx/OC+Eߊ-yw†0|Gr)N8:d[UV4IǷa m> `;_V!߆ lx0SNmPlK *l,M5&UM)r(J Śn?f0k?I0K3Tfxb҆Y4IY,Dֱ23BkD1+y*$xyX~kk!U@qCˏib؂x@t#v(R؍isSRL^fAĮ!@F":2&a%5$gm UX܉ļl#DٱgrO0Dy߭uReh=P}Ү]é׸ nCWQ"?PgLG(9k5- `;WH쮦9kX N5J\e4^%a`nyK\q!vӰ:=sqani_Gnѽ=ia;Clmk(UleRGԹ{Oڸv5!cl1o%׋Q7>cbIǏEDIX1cl->e I1rb'"3w{qtc^E 1Q@+qzFlXϙ nykAA*HvY L#njZj{K2)6JN! ZFxƃY@4J_)rI~[Ȣsi38"\FȋtT3 IՆ-Dn'e3sjZhLD#Ѻm푛y<۞t0kج|mN>QM MffSLOO~42?,"9'\t +ȑ#|[y@\|4LY5CQ>Aی,WDSz5aceX7w[nhSJ)F㱖.hJ ్`\ȃ<0/ : xH(D<)2 Ɵ,<'k]>f*|Q2Jc#Y2D5 u#ljp2Zw؉pz0 剠6=0!wWm~NE'۳v3Ϥor> YZ ,:oixR%ITC;wjCΊaK-{eЉBIϡM/3~n9Ѱ9ѺClgLԪj=g0_`Q*6M8֣JϜ>e=yD78na#^=A0(7FO_+ᠩWKk.qSL7x#>7N96$Ew}+KlyEƁ\N*͟%6 1f{kqZ{B_l nE@2yBan4M8J!/^}N z(ZgyFK+}زayp-qK']? ȯWS"]ƖurKbr,(@wS (?Py/ ?As1tzKO QXIo׫7Gf }Dq93s5Y# ʓIOxJ))[ܠݧQ.t"{ύbFlD)=IW#mgjn<:I.&&cE/,R&KҒp0o?21p ILV̩aC~ydB =eF`y^CWE{n><T 4۵]v0yprgK01Q l@ hJThƎEwi,գH $)]/c%f7/D4jis uTBIҴՠ7l"bY'v̉5.01BFzy7|lOD.W1w)X]"[:~#m]F` 3{ψVP6aPJ6SqㅒHȀ?hDsٽgAX֫ѯt $T X.RuQtb j<|Fk((Fe#lŌs >V{1MœVVC3>[ZP[-1s0;ya~N֔P9JOB!?]r9N90${.M1l+@hmE&e|f pg`z)5m"5aĤi}x@eǏ4M=a' @fڽc+OXi dsbi2HSݡd&9"‹_$0  m(L;p "t@ 6bO:&[yݴ w kľSc}9wx,S͂IJ?N[m'OOOʚ5 }ѡ=o#xp/vӱ'hԈobP섇Eжy(<;Q({ ؙ-YH2 D:%K@oYcKT-ɇLJ;ޮ{($7֠p:x'[$@w>SΙ:&'?5leaXlY{.\v+VfϦ@H[Eۻo?'՘7f2eJPUm$փ3 TUp뮝: ~gϛB:=d'- m"Z=G]t Hݓ~D.PY# JX@[^p/>gMXK:rdFlѣǂgg=r5\i<>BBCwZZ|ui`0=c֗\)kV PU$Zb4y)͟;oZAa˯lҴsV3k&&τ M3e͚Ӏ~}i @ SZQh 4ח|"@ {oݺ-@o=ߐɯ{~9Sԩi<Ot U\y޼އ)]J`9y@rR.g NׯPjHA\E)hhİan ÆM[D .=z5j*N;OE&U;w8>t-Y0Μ9Ku ѡ]޸y+}T>)7Z4ofd'auZvnLsgΠg* 9cjjxHYS䍉ܡT㳼Ԩ{QrvIF[瞧f((lYx2dOAmm /9 ţ 679E^/I墿7ߤ瞙.]Z=Ϫ9`P%%(t`I/aH/`S$ֵ&;ۋ Y!ޥO4oTjߩ'쾠E̔ɸpRr?:uG'On A|nx˖wt4i ڳ/j3r2P344ڵiCzeMr kTT)"x0o,Â}!ZJ,%ٳgdK\6t0RlYE{p&aNŊҋ.^?IW媭J'Ƌܾ/t)'k%S~N+U*{p_v#k j S4<`hmi~ɓ JLʰFh|?q"5lpӫ'K<Js;eTYīG&}@[P]|Rx -U64)%oל"L>r4bp`gYT %3W̙Ð6j#uX{'K,/VAJM467.hQO >zP  sSYYvر L`iYzD CC,ek-gW'j>$d35SP2F<•…{#&Ii,ޕ_%@g5NU./(s. W_j\녗e_7g%Cⵁ/Z.sI#rfMvO lpe<}z$apa``Ǎ++I YtLal￳M\D̘>C34|(5jP 6mZڽc=G..Ά E;_"d.T+!X1XxvE?v4kO bG '9 +7a,--?\$LU()r4$i3.+3O;ϜB)Kdtjfѓ.4d< c*1v'Y^E,^aD9 +'Mz L s+?b;jְCK.]IA蕬*I(.Cm)&v%LMQ% mģ+iBA+?m|uN:<>]tn={T[-EywF6%?EO 9~Oxgf~J#^l[mWpa;(uږƼ$lSPa U)Wzu1JÖ[Xh8w/v-<3ߧ0_h>ko_|Qr(EwzZpPb/=RP@p5w/j|t% DIz]c{nG,TwLDWpr$bпOwʗ/ 86ux_*ZXۦ8#/eS1,@{̅LJKbkcC¹6;Hv8 E:zI_tL-x߰(o<428WxjV k'% P⊹D:g^nR95RiҲY iJlNw6ws]GVxZ:>'c`,=Nxq1" шo8d0 4m0 ɻl-]:Em?(q̲ liSNkV7goݪn T6}$mGD)^%3ͳ8\hk6wyrS2'k5-HCG{^ci?AռL)s& xFaՖXEgKqPxտ#3lv:sRNXE#%_1ӽ5#xZa)K}/[Y= !h>])#uA$ v:_SWTSHhC8`1 ҠVLJ;a1vNiցEnzZi_rj Tn R;dj5E5f%,תU*!8Le` k.w };xi"{iekW)8Y^2>g ăm&f1U5|E6i yKo;iubG`vDL@O9#ܸfa nXq~RIմJ*,g,$f]Ѫ=Mqi:F+ل8am-$v?VaPXG|ٛ?" HUd8ԃJyUcM( I<T\@ p.!Z&@:HHQdHZԑy[Gc&tx7O 7Uؗ`QtI@-tep[Ŕ0xe> 8hqx+7h"hSh ́yZ)R[s=uDG{qIc)]HuLϞXaRPCMo= d34M4(5 ًECx9sRs/v3g/kI nk{>)` -ߵC,M%,ji^cEG%J#K(Aqt c d qHJ bGö¨dxCY0ӱ!O®2qG]I;e)ߤ>de+tp]ByZjUL,<ʆ6t3[F+`F,D eƣV&zD_*^wtng:2P_%YJ҅O .,) Z(U 3GenȾLn8ew^>>=]t @Oj7J#%rט4cm-~ݚ>v0]JZCxq"VĞZw>Siyū)w'*&8ط={n3?]r6XM+ς d'dB+,Y…ǘdbjiˇ1w.ƒOT״ߴ1)}~.*G敎L^ l5)n:k/#kE[T"=ItyEd"KSMݿ&eV>Ѕ:w.'8ÝƎ-A>ƼAzh|t9>"ط WЈ;7~ڶiM[cO6d0eQ |yZIǎCSJqcț5?.'|k>3c) 2f@}zzu0oN|o 1oZ*h=vcٟ?!9?{ʝG%Θ+>rnF%ޫ{7u'O&1c{"G}kQCq"ryJǫog*ᯇ~Cnߦ|;DA~:v5Q积3ąy睻 $>{ bE1"rc*rGBn>>`2ϛ5TLE('3"hg"s)+kAx 6=.2i"VTV2p=<*^WI ?ݣ%Q`X0ys!o,6ѷzf)2BZNcܱ u!kG?$PD}Hs0>a*fOP}tjd(3dQJNC|*#|po3i\z~ƙVyâ-߂=GGXޯCߐT{yRe:\_C'9KQDޛg f8fy+s~oh 脲68ydj'y44rp@PE~ٺjV.^zGLN|%ʬwZ`(_-8m [mM}gKP) fD`R/V"?نKΣMr!7Ȑ!="}8MXU`ͪYt# `(g¯,%s̎2`֯T} ah .ӄ5ޅ[VށT 0cECXfTV^*fNj:P(f")[rQ3J?~o] O%\_sA5~,W /%㾹3ks 'w2e̸rcyJI\e?ѧ|YK$C%mHA+<PZhh? t~e 9݊f]H5`*ofdU * ȾNDd͠upE@ AD6ŝMEld9էz}O'tuY:U}E|p%Z="׸!zߕ}H}O}ɥE;rD}8@D `QI-uvU0ݬ8Q[L8!Ǭ;y=wQ]h{__gnwmS}G<կ$7$.o+0 bWw$*q>|}ke~ٯ>ϟ}vvޥgUl?7nv?lj[P[`|ǥvi5jGo Hf@7/v[F:m췞<&t 7wϴ[ᓳPbmOg?}K<ʁWY qƦ*Ar1|rJOWgCގ/ 8w~U+sVUlUEn`s'_캣CLj~Tj P8N9$8D^ͧ3 ^%? )~/f[ n}W[mBq9RE`<zj]Gqz{ Y0LV\[z5ԠH}X̏>{b5;?8M.T^p'⵮uY<ؿZ?UeJS$=$]Nfrfbn6qRcKߢUV~~i}F h_gfxCƭni\K/UilZˈ{q %og79|_B zU~9Hҍi㫴7>hCjղfyo[G>1Ypdx;H7{ck[>V!.& nūB#5A"-rR:_J+B$!lF+i_5&OVY~C?}{ > ȁ;?{7=|F2 yu#fMHIp>0Ag<(t_*O̞[cOeȮa=@0fCwgl*3 Ŕtr{R:E@c9W̪67+S'tbRûY ˁץg8D+h!>Oy~p#ďwV< 5%O4 'ᇎA=؆6+l<ć9Iĝ6?M}7|;/Lvޗ>]w)"{=0/~輗doSGg>ߖ}V_7dj}w-h Q~YvސW#_OnS @!)|~я@-mW>ǘ!NK^v%QZW |9~t$I.Wwt ]B+o%m{٭hV6%or|Jr?z}!aV lx'?<,hK>R_ l8aCu~G*З>MW'x8t7|bK""ƶ'uB@IDAT^M[80k!w}ϳS;!C{>1~յ~#E"҃7uߕ;a}p%V?BJb}܍s6Wd/ۋ&xCPML^%dq6&ӗҗO~ꓼJdgQGoWV]R'X]UVxztv߃Lk'r{açgoL rd&-9 jހDxc  B.nL8nt=!zPv[E>  ۰6cO}dA:R6?zdogOɳx7 ō=~I2w{q6[md>Wjx_urO{9|~=+Ko=տM{oA_ ~}njle_-wǽG=7ܞO+ڀ>k_"It]߆J@[chu?z>3?ȁ [k`#ߣh߱i73qoD@>8מF{x1kJ6$orm3NDwCv'asCM)"1}x[|_C[W#}#ߔqk(&ڟ :~pz5(ίoﻞ+O9OHާdq4.e>t_, ~GgC8z~{/#&2e cO1vquZZ E-|=S5 ҇ޮk_5lg<3{ ;[W+bLc)Vmvcc<~";eniv~<^%6LVTƟ/ sxhX+R EVFyԣx%Ɍ{ڕۦ:['?GdJ?tpSq+bxKMo-6z+fXv2mc%B*4hK'th>!;!ߟ-mr+ /-">lU$_W')qrs8 v%83ҋd9οdmcK{>Ċ=syzvSRsh'^;Muk8NW$о[C.km;mMםKjrgNӊWkz^&]J4 K_KB+8P#- Xހ*ל]Ve?q֖Ef?gX dz׾#|URzm:ct uS* nGZ_נx/нHq8jr b V9,Jta/L%[ j:T㟹UYF3 ]LpIHS)n C |A`e*")%ӐmMVi:lC^%WY] =4ؔLCI &.BIm+r--Iz~2ҟߤwZ?&{}K-xMJCIH ?}m!4}oPIm僔!qaE`?u8V);$W}R匿t9C=݅?>yN~w<xy/xa:z'(s#ɭ-F,ͿBMބ@IrM٬XA}1qY- +H.YW/MS&tv24ĝ 0+M+x}'7ls'y\ai)R/zVjq wa8`uL2!$j%+c_v߲#lQ]h t vnidpز=jc +wYj4 ]V͆k,9>?H)(Ÿi!Ic|`ZؙN?N)WTW?@~t>5k'LñP2C0FKhCPv7!En["/&+7xcDN vJZR y-IhE@L΍ ua rF]1XEBDzViZE@X$.apH;ÜlL ̺ U>u%uf {8&sA.Ȕt  P -- k@ȗi2s7:*ٟ91Ӭ ' Ll%R*gU{jh.ԊIаo[2y&x7Ƀ1<w;33G^@Lg~n?Ohh Կ~-ٿ܂Gٙ~ B>&(|c'Џhm}U$&^̦X 4iU]vC@íS+@CKD=xK/G>ӯ|Wy5hIyGϒR ҟLpٿ'}gϐ]$~q L]=u,ΪJ>A)$F n PT'&($Bf0NiK8[(+}/~˲=W]te_Яv^7IOSnDt^? Ɏ=AϠD:?IGxlJՂ])[]' L=`e"}$[IFFPA=.0.2\p' \rivfw3|5'Ex/e|e_?9?_GCy}2ެh%]Ξ|9e/ymqS'/a̞_痲S_xog(iewf;6я^w LG*1.O7nP1Fmv{rGU*輖 }ТQ0X>jԑLOsv_>_oŧ,7Ӎ xa[/[?~zrZQom)>̾ s?o-?lg7fwfS6doon~d_Ϝr'Gp._zA}.nm7D,v.!H LP3&TU ĥN =5S64L|Bkߘ> @'_WZ[B6ÈVb'yt)'sŒO)_#G\唢OGO7U^yԜ'P~C]>!/D usk~KT%o&@|$L"8҈'ev\hcӔ3 jRӑИV . kYC{U?HI$МlϔAa?~a|`O2Q$Ŀ/|U^+Xvy}#|uv[Ɔʳc<)ûX$2,U\j"f0l.]E#XZG!"8TX%Ǐ}óW?_|q/Tqk{o5s7S~/ݾ/׽){Ɏ^yevҖ+1(Oo"yÛޒ}ӟ;teGBգ׊"(-ȄB͊n"`g,c$j,but 䬽43[A%'>}\s=z胲N;Wkʞr9mǝnJ<:h9rĨwg_W_x1=]wʎ;t Ȗ;썔P?G/?7;t\{W(b*FrN}FID`A SյR$^GxW [=k2e{du[[P>Ɖ51? }.Aeyo+*^Lfp l䒯d_;JQD54[㒯@p>)@B1~=~[n@WJ0fΤm6LP56M*օ>ƃ'o|}v zrƒ(ĂpqMI!lqs3s_,{v~s{TQ Ef!WQf%VE0cu8nc8$hL[8HTCE=x~G Q&%L#X4 xd^@Dl!xqGiP7A)z;l:"17nDLl5vyD*ZĹNN(+D^Y{'?^WVcbJnD}?@E@P# P'0( *ޣm|=BCZ_+sE@PR!O3B-~47i-go[8 @Ws9 iO F:C|۬4倄k+"(!7o+,^XV"!Nyj/AB-@nT'7hZC#6X~K~h./H)d2U"Cy;paYVւg^YLsQ_ Oqn_1/z,Ҧ/ NT hH,"@]1@dr#EZfdZsZW_~ѣ7?z[܊ X!+4]MV # s47&mXٕbh$pB<3%nϊKRt]g歔P?衏>яT|~Aɞԧg\Z唈?~E<;JjV㓆]pzs^b?[8 q ?ņHgW~+ǚZoe]YO~eĘ~1?_L-?=akiήzի5~xՓ8y#XZtaivXȪܵ!0 Y7͜.A] IcA-3fQ <(c?-_{!KDʑr. )ѕצt~~K/;&7u$wyӛ~K]g.{>Wuo=ߕ|Iy;~o֏wG??=;D?EyGiʿgȾ[oB;Hcqɑ(-d)E3̘ 1P0LT^W [{!h}#kNKv҉'f2/Ԡy|`>]rȲцJ9s(uyNXB +r'y ox^𿳫]Z|EE/x׽.䒢?{Ȏϗ° cz<0Lh ۣ-"(s!#k#\5ޘld`B-Ɋb9[;=쑏."Zu>1[}{}OsN ^\|/+dk{ew TH@8ҳVaml1݈{Cz/,^7d/~˹qyxv';xBos?/;ym|)xbvE]Z̞̳Ӯ] Љd~ʭ(E٘NOXn\?Flom=TB ӟH|C]r ?ȑ*_"Nse$Zh͋y T=@{)j &7ylk|6{ƕ|oŃ00M%VOx\vY8@d77KK|k\={ˮwݯ0Lð9n힙|9S/a"~ GF\yjlW/Rtr#7KǁLt)͡@ *c8-1T Fcd39: Xv䵔s ;tK= 5!4< C#WG:esLkLv-:.{,;ʆ\55*˫j.ph4v ;|KbH$bUH*8erM( 13 ] ulr3gՕSmիsyXvO9vwI=ihROO7SFE@Pv }v`Y;ASKG2dnlUE@!iƂ'uzMhpy]3v$]nU`B{ucQ@dD-V5BP !&:hbzm =B ʦi$P}/f{ݎXgKi쳵2JRGR,t,e'N}\ ƨwo$G˹v jFݺ=ۧ?V3~g4!n;RV'J(@J|O~'[V{郚c毈|9Fݏ_-.ށؑru3Ku|ۚ445cZoFP֏F:d W01sL|UMItQIu% uE;i mգ(d[*օZ48nϙ}[&,ʑ*5?HD- ޷|ɵEXIFFBXF(bµVP"`O|iX$|iz?N ,[+8bti`׊"*BP&C@ɠMQlʌ/ Z`$HZnjMyjb' X~VI "O/E`ttnbGArHfF/i1\ʺxjQց~:S+E@Ң.n)mGp_\M,Rzޛ:y+Ըg7˽K;d ރ+8*HpPWP`vYʹ9W bcI9HyqX+vy+^c^TJ$-)i#xuKIS!P$өHxHCv X>p_([AxJV&ntAr1CiKAc4;x Ĺ0NsQE@09N xR@KZ̋V- P>$[%SMX(-\mh$^%*(#"@~z^$shuP#oT24iKE D1]5ĭ3 D  f+:s@lpRB@Nuv> <`>%*L Ca+z5='9@@$">d'd E@C $Nz#ܻ'QX$o]șdfCUωsƂ#iGXLe  E@PE`]y/s@ IuvbkW.{3L3uvANj82ŖA fxL,Ab;?3M>jSyTX@ &x`#H K7?rXP_ uJ89`zrŸ~ˇF:m{a8R]RfbfUF 1GN&F4q``Pm@o&^X  jԧ Ѷmm_q ~nXR+ DoB̏}bt3ِ~ݐ~%4Rl#[T×jW'"R[}y;q5lͰtl[7]֎ս'!8L۹Ɔdsd[ywI"pq;/v9Ȁy?;4xsg}ʠN's17Dt>8sd8T=4qG?4Cfpz_dTiSݟPT&\ b~{E5UNmS6tBl1U g JGꃭGe8TZBa)6r$+U7*St:CniZBmeFe ]YhY֮e4#0QO׼aދb6MXT%Ɲ!Rnid0w|`5X5 P;I.-7Д.jo8#fJUtcr.&MU( B`WFǮ9]hR01,lI;z@oۃIj[]n3ئ*(%;N_ DXVO&)耊Nm# s^ΤsF91tiw4(YU\ 〢RgC`;`RKC &bhڣ(;lSϦw´#oSgGPc!$% p6/)"("@;6`fI jsҾ\L[A=}$wGڲchtX"0**<> l0Tѵ՘dFhuLQ"R~d9D䱢Mz("(!ͻuNc^)n~_]EBLN\ bXBQ2ؖV=m@@~q+{ 7JܛfPdf 5::I։mE1)6W(@1sa%Q:PGHCǩfY}zp<*Q55Jv_E@P"иBWh_>/li,=;hR#JwǘLcKf@`*>/,>ށf=_ۋ4TbnQÿNFCc!0N!d=ApTjBR(@ 2-9f/-2-ѝ‘HLEfD?F6N'B`M=&[uϤbtO *[>v33q'}ިjj˻]iqitbbui=㝬ѤTXBjk'{5[Pۋ?*18S#-PTd@Lÿ1Իz(Gd4V_r`$m@=zE꤉;#M_Z\Uڲ8_UiYFWЛtcbvCRbs,Jal/o- zE`)`۟5-TfǤM 'ېE 7aFDPFgE:SU0IOo!D %Ҟeo/Ϻkh:bΚekJ+דũLХPLYp Sy:m7,#"&sZsZʞ+._`ZQegTvLfF u{Mvkl/vS" Ӻq-.a 0D4Av/=@L 0JʚTqB&x[3VFWӮgӎJLP% % M5܁i՝0 A+24z3q((ղPM?kb|MO|w>Y)U,hwJ.>АW"DO@wz4`vza1١VW'G@iM&7pS ̯ KB`:SB< eOx|ASU@|E;}`R&EC0U3+rf*+|8xԶECb'RλBexF[Mj2he v":E@@i\mݭ+q̾^ؽvkO;+p0e?\%Z>]҂<{ǂ:EMY+Ko#9`!ubP?< 4D%נ)i1}ermQd> h{Vm3ںbV7l:b=(MmTrE 9}t$w ]&ԣ m팄Y}Jݝp ļB]w]&+@ ܚ|Pv4,$^$ԛ&b: >("f6dЬÚXj" Q(BG$ uۤ49Phe+JU҅][KSmK@ʞ11ewò)fRZI6ˡ69}cf+x<X|h 1k;Vy 0x/JP7gGD2:ulծMf@7ֶhW 23V5+@AhAH=%q% 5YgclPp _~h"P{ 6 Eb]A 1{l@O@V+;f u[<^::$bڍtj.WGGsMGY(zcgJe*?v[׼[UŮ*\b6v.1G˘<;6n&0i*\sN:~ߛbGѸmٝN(!hm@{^ѿ[9F!s U+~˛H'RdU !?7t+2l_414EW@pc.unŢB'7tͱҥl{v ~-1åivA?EXf>>aҥ=X.v*{K>曉L^kf vag%58ݍ:7)1MBβsP,,P̸.DhԸ#0ߴZyxݠʖ ILOPcu$w5"#` 0X"݌M u>ttDȢت@3+ m!]!@1A0DڟŃvU_f.Af Ʌ/1a.8˜ &P‰P.]K*D]e wLXJ'oDX'~X Ӵ]ݵHm6Ϥ'~ks^M'DFD >4uqIn*)7 ޚjMb'Ҭm7Z0튀CWi˧oF,d(Od#n4"tCg W3&d" \i .L,aJk զ "A)VdiQTŻtֵ^o0N\-uq> }p'2-~bG?h6a k3="KcB{Úۓ0oKwve6I({6M~O(:h6ڱ t+E5@[SD%Uy#%bc&Fv!8aȨ>hAMyE@P։wjl06'< ۲D_l>OHU],7R'F .K뉿@_ PE@F@ jlaYr핛(,ŕ9]Ӯmh-)!{X4vOeΎsNw.)gJQ?/wly}5L#_dȩP mVÇ&oRP<@MeUT}K34B~ѵLV,FSuXE$(Z)BiDx(-{t+]i,Ja| AIgON:' t\ّ mKvE@Pz"P1V* i##,[=TC4 "zK׌aS׶|aaфin 4JV.%Vn߹+茟2!T tyuw4ŠPë><HՑBr$k%J@߸V$iϝ>nGc]{UMx)d߱<3IubZV66v{IfGh3^W@(>G Y`#`֭aTx+Ã=ixU)AwDM4d?$Ry"%QɤtLhDT(6Jq?QݥD"pV2 -ŝ6/Yy4O\Xc۳||6E8K9 ɐ8/1 n3zĀPVE`  #xbMPF//-Wۯ ZлӑAqʦeZÝ[Q^VVIM;Oy-J-.vP-̔=Tu5 Eqgyi -h[[da=oz=~A@mgYof#>2k0^2}PV .&uc@gڔi"@/Zhe<[w y*CPvYen>\R rKIJt!tqeDlM]tuy'ԫ®Yv"kt`j HjʴG*}}[1՗WWHu!z:VbE@P.Mv2\665 1βdڪUV-ѴBmcZEY i=b;[cZmnklӄʝj$<Rkrlk{=$(g& {VH#Q*Xw$$ @jShvlIr,ϝja2wsGY6u XdsLA磟5g_U+@'>܉iK];rFMs.$UvrUgYEe@7s}S,>KZKEfr6oҙq 6˵r)56}b?6%vtSK#"14"ES_hwt,< 8br&qk_JAgo^goP#˕̺V:Pw NG¶.E7g6Uq֮PKBKk(q_ookCe]Bgjz+>>"@.sJ=^;c9=x7|,e>a%%z6)='p=vy׉1PN;9ͭF@S\gWgv%8d.Y Xu6ɒRlfA,(L*Diqȅv0~G#RdWve PYA@j ^@6Pb\KwV"tKk(~u7ÞJ.* >ʂƓ`7؉UUnоUI&%y Z=y5'=vU-\Yt *Kz (";šX)ƕnԣId˥.SeIMj yy-g-`CMIq- /@ 6LmTW5\u`(͔]O;Vtz[jTWʥ"*2ڥ1Ff1l-ps?.Dhj $7-Nb]P(6*6' >,N2Yʰ69%0PJ*Kå.O¶[jr`Ւ`>n!v̻kӁ쑬@0D1lVfT]KZk ByW7vk13^YZGpWK R".Sb(R7G׀3~`mБnZqHK5Fe\zuוt"DE\Nc$rL>krY24aB/yP#+7H dg> (S>%w\U"M1sb =2aXnF_ɂ:mLv1!ܶl;@tv_whGHlENۋAsZs45Rttx ;_G",b)WO"rU"ElFb}z WF5 UY $^ZaAe hUB=k(#@^Yb|.ꍯ]v M2meΒJ[JnYy(QձDbZ`(1Ws\V· HrJ+ xYE720CCN̲}Y&h! b=$\JsK=`!Z\ 1NdJO1uBOh)|\:0ssBRR9g"e83i΂Tq4Tf5b㤂 #*SE I_L R4Zyj.q(`=pꣁM)^ad(fX[Y3jnjY7]| il [O(f+;v`Л'j#Z*pe3ǶzY}^¹4e>4?@QB< r!Cpp9@nL Xj9DPC9#yũ0zs>- jƢOeΈ*#weUQ).n%e|7ܗa~5 WVQx7UY%ﶔdOG0SH).݁B=yI+eQWZf%>N&e< v8vb-Q>ÓًDn"Q6l#h9b9\ɹ2-sjҌ8Jqj^\ڻkƂ/>Ec\Qm_beޚd&6c9\W9c\/O74NtQ܏* ^M>nR5\J[M|?m8c w0KKիkFD Xpq 950Q>:%tP CFA--d5ۭC\%4oTOzC+z mv  ud="fhA8HMxR&VBYA cu:;қ>#ODIc`"v\PkLR 'o*zG;k1'E!9W&'bexjqjUBTAVۀ*dM G̑D~ h!Sr,P" Y&V_]hbDdQŴi }̵ /uk"VAdzV]lb@y;Bpe:Ɇ~9r)7)t$u%MXx[_Y2yssсk"4"YQE{8[-|@W@YImXA2WZ!?o }bdk|cHOpbcFO8ޑaPq$O! _6~ M.u8emDc0> ZC(ET 9ےrLZ$t0FVlKEQT"?>FNrR :|K4 r䊰28ĪigK&QkR#:5\rjNiՌz}V yF3.eb *DWHp1#O1~Fxsm%(5bTڵdW= u)L]{a0{f;GHRN?!k,~ؙKؔIZyNWq|<5t ~꜈Nw׆PB_; .:4Fv;xk\Ɔu4sP[L1PO0Q;ߐ3WM,ly, |Tj@زzM#6 N>k :uh' \7FC%F^Ε]▜kznm + ^'H4uX_" .&``b$#c } >'_X[v!ahgP.X%`-:Ch\Zx=.&Rd+vYJ A+7ea$?/Ã8h.^QN,g&רnbw|M.syZ2Q9*j~"WWykgo }j]ӗэ uiҔ2R6MFyAp.BW[퐋QS=(*$?Ϧ `|Gppg0s4GbL<F9]Uf"fb`^k?"dk, IL=MW> _ewn@'զl$> hַuISV lX?(eԚp7 HG Bsl㐝Ͼᚫ&}Ğ0o+<8I[\^v iyӔ0+%PVT9{ֽ%"|Ju++~ZD=f "cGzi9A]/8H9o:yx{=LLk >K53p2qC $e. ʤ63[7D(pz:? 6vE>J]eeg ׅ YQW5-dO9dW=n 6aIF=;e2Zc&98Ѯ6LnHugM/D"]geǑc;cʛl8m2^9@seE!m.g+fFK)˦l[wCͧ‰|Z.B%bΟ!)lGO*x3QVmMۮ2Ϙۻ+ \fHҖ_Qp>Nh+e~H_ 7xL\S>_ѧ_PrltYRJCE,ccuG0!MЂwoT}R%/Ζ,%bb\h-x^6:%$ʖ(䝰NάB4&"Mu_ 2e˦"Nbk*up̱͊8Z+qhD{=2'F̑I 6UzZƛ@L?X '֐YFAb'k%6SkH3U-WW,4{Sꂬ*b}WXG=G-A!jVkCzd ڻCͦ1jNLHgshry]C(VR^+X!AHB}%j/%13xR;DΏR_k)Rv*Jsfrql!~W_f3ob6ჱ"CMU68%W.t\uR6 l:ۤP=qJT|a' .'MRUu"  RaȌN18$h+E-[җxJN x;L'Ӓ٪e{LF`P~~U}:&2*"!=#emh (ފ/ʩP!)hWpb]ؘVGps6l%^r?B!IΥHt!}{03'8]A` X}X-z" eVx#1GUmWU*aiKv9*)ٮC>@˒CڶU-3x4Iy$2(3YXl0+}0 :Ie59wa>8Ki0TѠcG%tky-gH_ֽL<}qv 90&bD L'!e3 cvPҎm:umtf~^aR\K ,vb,"b0 SIdH̏U k./=~\B |I\go {>XT;. IUvJ^P?*~]YW$vV XR*׈vFMΖADl_[I+"$RDiL |eM&>}rȹK 8e>ӈ"Q&Ա]L@w"iaFad*啥 QD ]Ѕťca]cY(:;GLJi$}c4cʘdƝZk<(2jdڮVfOK&ʔ>_Q򄧋(Y.M :oACXkSn']&ᰏO!( k+ exɠ6Lvttݖcӣ1T\k7(7bdIK$ۨg/x9Pڸucg.~&3(0ukE$A~]thoj SCtH} AѷhM9w1ƴ2#*8LGZ)⛇JyOA> uZsCmajS-֘Z'|1ZR8' ze\2cfV2 GX+|&n˶U`b(ȇՕ"h04xv䫈 tKDoopfW4:!11ƒ?q+1ز8<+ȡM'F+-*zG;^v`6J0W} D&fZv =v/cچcA'i1l++ vώ4H&fsxI5 w<>` 'čIhs2$ayf,d3'Ѳ7@6[GӵWGDxJЅLn^.^D,.Tm)3le_,Rjf32ŶZd٥G' W &"v'=8WW+9ӟCiLv;sh4qcWKq]ԎuN_,Z|Qs>|#

?ʒx΍Dwt}Z sMv< #?VB "ds~$O}]܊E&9<]t6x-~f".format(TAG_REGEX, TAG_REGEX)) def __init__(self, colorized=False): self._colorized = colorized self._style_stack = StyleStack() self._styles = {} self.add_style("error", "white", "red") self.add_style("info", "green") self.add_style("comment", "yellow") self.add_style("question", "black", "cyan") @classmethod def escape(cls, text): return re.sub("(?is)([^\\\\]?)<", "\\1\\<", text) @contextmanager def colorized(self, colorized=None): is_colorized = self.is_colorized() if colorized is None: colorized = sys.stdout.isatty() and is_colorized self.with_colors(colorized) yield self.with_colors(is_colorized) def with_colors(self, colorized): self._colorized = colorized def is_colorized(self): return self._colorized def add_style(self, name, fg=None, bg=None, options=None): style = Style(fg, bg, options) self._styles[name] = style def has_style(self, name): return name in self._styles def style(self, name): if self.has_style(name): return self._styles[name] def remove_style(self, name): if not self.has_style(name): raise ValueError("Invalid style {}".format(name)) del self._styles[name] def colorize(self, message): output = "" tags = [] i = 0 for m in self.FULL_TAG_REGEX.finditer(message): if i > 0: p = tags[i - 1] tags[i - 1] = (p[0], p[1], p[2], p[3], m.start(0)) tags.append((m.group(0), m.end(0), m.group(1), m.group(3), None)) i += 1 if not tags: return message.replace("\\<", "<") offset = 0 for t in tags: prev_offset = offset offset = t[1] endpos = t[4] if t[4] else -1 text = t[0] if prev_offset < offset - len(text): output += self._apply_current_style( message[prev_offset : offset - len(text)] ) if offset != 0 and "\\" == message[offset - len(text) - 1]: output += self._apply_current_style(text) continue # opening tag? open = "/" != text[1] if open: tag = t[2] else: tag = t[3] if t[3] else "" style = self._create_style_from_string(tag.lower()) if not open and not tag: # self._style_stack.pop() elif style is False: output += self._apply_current_style(text) elif open: self._style_stack.push(style) else: self._style_stack.pop(style) # add the text up to the next tag output += self._apply_current_style(message[offset:endpos]) offset += len(message[offset:endpos]) output += self._apply_current_style(message[offset:]) return output.replace("\\<", "<") def _create_style_from_string(self, string): if string in self._styles: return self._styles[string] matches = re.findall("([^=]+)=([^;]+)(;|$)", string.lower()) if not len(matches): return False style = Style() for match in matches: if match[0] == "fg": style.set_foreground(match[1]) elif match[0] == "bg": style.set_background(match[1]) else: try: for option in match[1].split(","): style.set_option(option.strip()) except ValueError: return False return style def _apply_current_style(self, text): if self.is_colorized() and len(text): return self._style_stack.get_current().apply(text) else: return text pastel-0.2.1/pastel/stack.py000066400000000000000000000015511373046207700157640ustar00rootroot00000000000000# -*- coding: utf-8 -*- from .style import Style class StyleStack(object): def __init__(self, empty_style=None): self.empty_style = empty_style or Style() self.reset() def reset(self): self.styles = list() def push(self, style): self.styles.append(style) def pop(self, style=None): if not len(self.styles): return self.empty_style if not style: return self.styles.pop() for i, stacked_style in enumerate(reversed(self.styles)): if style == stacked_style: self.styles = self.styles[: len(self.styles) - 1 - i] return stacked_style raise ValueError("Incorrectly nested style tag found.") def get_current(self): if not len(self.styles): return self.empty_style return self.styles[-1] pastel-0.2.1/pastel/style.py000066400000000000000000000076631373046207700160310ustar00rootroot00000000000000# -*- coding: utf-8 -*- from collections import OrderedDict class Style(object): FOREGROUND_COLORS = { "black": 30, "red": 31, "green": 32, "yellow": 33, "blue": 34, "magenta": 35, "cyan": 36, "light_gray": 37, "default": 39, "dark_gray": 90, "light_red": 91, "light_green": 92, "light_yellow": 93, "light_blue": 94, "light_magenta": 95, "light_cyan": 96, "white": 97, } BACKGROUND_COLORS = { "black": 40, "red": 41, "green": 42, "yellow": 43, "blue": 44, "magenta": 45, "cyan": 46, "light_gray": 47, "default": 49, "dark_gray": 100, "light_red": 101, "light_green": 102, "light_yellow": 103, "light_blue": 104, "light_magenta": 105, "light_cyan": 106, "white": 107, } OPTIONS = { "bold": 1, "dark": 2, "italic": 3, "underline": 4, "blink": 5, "reverse": 7, "conceal": 8, } def __init__(self, foreground=None, background=None, options=None): self._fg = foreground self._bg = background self._foreground = None self._background = None if foreground: self.set_foreground(foreground) if background: self.set_background(background) options = options or [] if not isinstance(options, list): options = [options] self.set_options(options) @property def foreground(self): return self._fg @property def background(self): return self._bg @property def options(self): return list(self._options.values()) def set_foreground(self, foreground): if foreground not in self.FOREGROUND_COLORS: raise ValueError( 'Invalid foreground specified: "{}". Expected one of ({})'.format( foreground, ", ".join(self.FOREGROUND_COLORS.keys()) ) ) self._foreground = self.FOREGROUND_COLORS[foreground] def set_background(self, background): if background not in self.FOREGROUND_COLORS: raise ValueError( 'Invalid background specified: "{}". Expected one of ({})'.format( background, ", ".join(self.BACKGROUND_COLORS.keys()) ) ) self._background = self.BACKGROUND_COLORS[background] def set_option(self, option): if option not in self.OPTIONS: raise ValueError( 'Invalid option specified: "{}". Expected one of ({})'.format( option, ", ".join(self.OPTIONS.keys()) ) ) if option not in self._options: self._options[self.OPTIONS[option]] = option def unset_option(self, option): if not option in self.OPTIONS: raise ValueError( 'Invalid option specified: "{}". Expected one of ({})'.format( option, ", ".join(self.OPTIONS.keys()) ) ) del self._options[self.OPTIONS[option]] def set_options(self, options): self._options = OrderedDict() for option in options: self.set_option(option) def apply(self, text): codes = [] if self._foreground: codes.append(self._foreground) if self._background: codes.append(self._background) if len(self._options): codes += list(self._options.keys()) if not len(codes): return text return "\033[%sm%s\033[0m" % (";".join(map(str, codes)), text) def __eq__(self, other): return ( other._foreground == self._foreground and other._background == self._background and other._options == self._options ) pastel-0.2.1/poetry.lock000066400000000000000000000624171373046207700152210ustar00rootroot00000000000000[[package]] name = "appdirs" version = "1.4.4" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = "*" [[package]] name = "atomicwrites" version = "1.4.0" description = "Atomic file writes." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" version = "20.1.0" description = "Classes Without Boilerplate" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] dev = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "sphinx", "sphinx-rtd-theme", "pre-commit"] docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] tests = ["coverage (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] [[package]] name = "backports.functools-lru-cache" version = "1.6.1" description = "Backport of functools.lru_cache" category = "dev" optional = false python-versions = ">=2.6" [package.extras] docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-black-multipy", "pytest-cov"] [[package]] name = "colorama" version = "0.4.1" description = "Cross-platform colored terminal text." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "colorama" version = "0.4.3" description = "Cross-platform colored terminal text." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "configparser" version = "4.0.2" description = "Updated configparser from Python 3.7 for Python 2.6+." category = "dev" optional = false python-versions = ">=2.6" [package.extras] docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["pytest (>=3.5,<3.7.3 || >3.7.3)", "pytest-checkdocs (>=1.2)", "pytest-flake8", "pytest-black-multipy"] [[package]] name = "contextlib2" version = "0.6.0.post1" description = "Backports and enhancements for the contextlib module" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "coverage" version = "4.5.4" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, <4" [[package]] name = "distlib" version = "0.3.1" description = "Distribution utilities" category = "dev" optional = false python-versions = "*" [[package]] name = "filelock" version = "3.0.12" description = "A platform independent file lock." category = "dev" optional = false python-versions = "*" [[package]] name = "funcsigs" version = "1.0.2" description = "Python function signatures from PEP362 for Python 2.6, 2.7 and 3.2+" category = "dev" optional = false python-versions = "*" [[package]] name = "importlib-metadata" version = "0.23" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=2.7,!=3.0,!=3.1,!=3.2,!=3.3" [package.extras] docs = ["sphinx", "rst.linker"] testing = ["packaging", "importlib-resources"] [package.dependencies] zipp = ">=0.5" configparser = {version = ">=3.5", markers = "python_version < \"3\""} contextlib2 = {version = "*", markers = "python_version < \"3\""} [[package]] name = "importlib-resources" version = "1.0.2" description = "Read resources from Python packages" category = "dev" optional = false python-versions = ">=2.7,!=3.0,!=3.1,!=3.2,!=3.3" [package.dependencies] pathlib2 = {version = "*", markers = "python_version < \"3\""} typing = {version = "*", markers = "python_version < \"3.5\""} [[package]] name = "mock" version = "3.0.5" description = "Rolling backport of unittest.mock for all Pythons" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] build = ["twine", "wheel", "blurb"] docs = ["sphinx"] test = ["pytest", "pytest-cov"] [package.dependencies] six = "*" funcsigs = {version = ">=1", markers = "python_version < \"3.3\""} [[package]] name = "more-itertools" version = "5.0.0" description = "More routines for operating on iterables, beyond itertools" category = "dev" optional = false python-versions = "*" [package.dependencies] six = ">=1.0.0,<2.0.0" [[package]] name = "more-itertools" version = "7.2.0" description = "More routines for operating on iterables, beyond itertools" category = "dev" optional = false python-versions = ">=3.4" [[package]] name = "packaging" version = "20.4" description = "Core utilities for Python packages" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] pyparsing = ">=2.0.2" six = "*" [[package]] name = "pathlib2" version = "2.3.5" description = "Object-oriented filesystem paths" category = "dev" optional = false python-versions = "*" [package.dependencies] six = "*" scandir = {version = "*", markers = "python_version < \"3.5\""} [[package]] name = "pluggy" version = "0.13.1" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] dev = ["pre-commit", "tox"] [package.dependencies] importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [[package]] name = "py" version = "1.9.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyparsing" version = "2.4.7" description = "Python parsing module" category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" version = "4.6.11" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "nose", "requests", "mock"] [package.dependencies] atomicwrites = ">=1.0" attrs = ">=17.4.0" packaging = "*" pluggy = ">=0.12,<1.0" py = ">=1.5.0" six = ">=1.10.0" wcwidth = "*" funcsigs = {version = ">=1.0", markers = "python_version < \"3.0\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} pathlib2 = {version = ">=2.2.0", markers = "python_version < \"3.6\""} [[package.dependencies.colorama]] version = "*" markers = "sys_platform == \"win32\" and python_version != \"3.4\"" [[package.dependencies.colorama]] version = "<=0.4.1" markers = "sys_platform == \"win32\" and python_version == \"3.4\"" [[package.dependencies.more-itertools]] version = ">=4.0.0,<6.0.0" markers = "python_version <= \"2.7\"" [[package.dependencies.more-itertools]] version = ">=4.0.0" markers = "python_version > \"2.7\"" [[package]] name = "pytest-cov" version = "2.8.1" description = "Pytest plugin for measuring coverage." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] testing = ["fields", "hunter", "process-tests (2.0.2)", "six", "virtualenv"] [package.dependencies] coverage = ">=4.4" pytest = ">=3.6" [[package]] name = "pytest-mock" version = "1.13.0" description = "Thin-wrapper around the mock package for easier use with py.test" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] dev = ["pre-commit", "tox"] [package.dependencies] pytest = ">=2.7" mock = {version = "*", markers = "python_version < \"3.0\""} [[package]] name = "scandir" version = "1.10.0" description = "scandir, a better directory iterator and faster os.walk()" category = "dev" optional = false python-versions = "*" [[package]] name = "six" version = "1.15.0" description = "Python 2 and 3 compatibility utilities" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "toml" version = "0.10.1" description = "Python Library for Tom's Obvious, Minimal Language" category = "dev" optional = false python-versions = "*" [[package]] name = "tox" version = "3.14.0" description = "tox is a generic virtualenv management and test command line tool" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] docs = ["sphinx (>=2.0.0,<3)", "towncrier (>=18.5.0)", "pygments-github-lexers (>=0.0.5)", "sphinxcontrib-autoprogram (>=0.1.5)"] testing = ["freezegun (>=0.3.11,<1)", "pathlib2 (>=2.3.3,<3)", "pytest (>=4.0.0,<6)", "pytest-cov (>=2.5.1,<3)", "pytest-mock (>=1.10.0,<2)", "pytest-xdist (>=1.22.2,<2)", "pytest-randomly (>=1.2.3,<2)", "flaky (>=3.4.0,<4)", "psutil (>=5.6.1,<6)"] [package.dependencies] filelock = ">=3.0.0,<4" packaging = ">=14" pluggy = ">=0.12.0,<1" py = ">=1.4.17,<2" six = ">=1.0.0,<2" toml = ">=0.9.4" virtualenv = ">=14.0.0" importlib-metadata = {version = ">=0.12,<1", markers = "python_version < \"3.8\""} [[package]] name = "typing" version = "3.7.4.3" description = "Type Hints for Python" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "virtualenv" version = "20.0.31" description = "Virtual Python Environment builder" category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" [package.extras] docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=19.9.0rc1)"] testing = ["coverage (>=5)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "pytest-xdist (>=1.31.0)", "packaging (>=20.0)", "xonsh (>=0.9.16)"] [package.dependencies] appdirs = ">=1.4.3,<2" distlib = ">=0.3.1,<1" filelock = ">=3.0.0,<4" six = ">=1.9.0,<2" importlib-metadata = {version = ">=0.12,<2", markers = "python_version < \"3.8\""} importlib-resources = {version = ">=1.0", markers = "python_version < \"3.7\""} pathlib2 = {version = ">=2.3.3,<3", markers = "python_version < \"3.4\" and sys_platform != \"win32\""} [[package]] name = "wcwidth" version = "0.2.5" description = "Measures the displayed width of unicode strings in a terminal" category = "dev" optional = false python-versions = "*" [package.dependencies] "backports.functools-lru-cache" = {version = ">=1.2.1", markers = "python_version < \"3.2\""} [[package]] name = "zipp" version = "1.2.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false python-versions = ">=2.7" [package.extras] docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"] testing = ["pathlib2", "unittest2", "jaraco.itertools", "func-timeout"] [package.dependencies] contextlib2 = {version = "*", markers = "python_version < \"3.4\""} [metadata] lock-version = "1.1" python-versions = "~2.7 || ^3.4" content-hash = "569e785f5e774e4b45a66c713dbcc990048f57afce8c24a7a5a46760d225c8db" [metadata.files] appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ {file = "attrs-20.1.0-py2.py3-none-any.whl", hash = "sha256:2867b7b9f8326499ab5b0e2d12801fa5c98842d2cbd22b35112ae04bf85b4dff"}, {file = "attrs-20.1.0.tar.gz", hash = "sha256:0ef97238856430dcf9228e07f316aefc17e8939fc8507e18c6501b761ef1a42a"}, ] "backports.functools-lru-cache" = [ {file = "backports.functools_lru_cache-1.6.1-py2.py3-none-any.whl", hash = "sha256:0bada4c2f8a43d533e4ecb7a12214d9420e66eb206d54bf2d682581ca4b80848"}, {file = "backports.functools_lru_cache-1.6.1.tar.gz", hash = "sha256:8fde5f188da2d593bd5bc0be98d9abc46c95bb8a9dde93429570192ee6cc2d4a"}, ] colorama = [ {file = "colorama-0.4.1-py2.py3-none-any.whl", hash = "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"}, {file = "colorama-0.4.1.tar.gz", hash = "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d"}, {file = "colorama-0.4.3-py2.py3-none-any.whl", hash = "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff"}, {file = "colorama-0.4.3.tar.gz", hash = "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1"}, ] configparser = [ {file = "configparser-4.0.2-py2.py3-none-any.whl", hash = "sha256:254c1d9c79f60c45dfde850850883d5aaa7f19a23f13561243a050d5a7c3fe4c"}, {file = "configparser-4.0.2.tar.gz", hash = "sha256:c7d282687a5308319bf3d2e7706e575c635b0a470342641c93bea0ea3b5331df"}, ] contextlib2 = [ {file = "contextlib2-0.6.0.post1-py2.py3-none-any.whl", hash = "sha256:3355078a159fbb44ee60ea80abd0d87b80b78c248643b49aa6d94673b413609b"}, {file = "contextlib2-0.6.0.post1.tar.gz", hash = "sha256:01f490098c18b19d2bd5bb5dc445b2054d2fa97f09a4280ba2c5f3c394c8162e"}, ] coverage = [ {file = "coverage-4.5.4-cp26-cp26m-macosx_10_12_x86_64.whl", hash = "sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28"}, {file = "coverage-4.5.4-cp27-cp27m-macosx_10_12_x86_64.whl", hash = "sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c"}, {file = "coverage-4.5.4-cp27-cp27m-macosx_10_13_intel.whl", hash = "sha256:9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce"}, {file = "coverage-4.5.4-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe"}, {file = "coverage-4.5.4-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888"}, {file = "coverage-4.5.4-cp27-cp27m-win32.whl", hash = "sha256:63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc"}, {file = "coverage-4.5.4-cp27-cp27m-win_amd64.whl", hash = "sha256:e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24"}, {file = "coverage-4.5.4-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437"}, {file = "coverage-4.5.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6"}, {file = "coverage-4.5.4-cp33-cp33m-macosx_10_10_x86_64.whl", hash = "sha256:6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5"}, {file = "coverage-4.5.4-cp34-cp34m-macosx_10_12_x86_64.whl", hash = "sha256:331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef"}, {file = "coverage-4.5.4-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e"}, {file = "coverage-4.5.4-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca"}, {file = "coverage-4.5.4-cp34-cp34m-win32.whl", hash = "sha256:fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0"}, {file = "coverage-4.5.4-cp34-cp34m-win_amd64.whl", hash = "sha256:df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1"}, {file = "coverage-4.5.4-cp35-cp35m-macosx_10_12_x86_64.whl", hash = "sha256:efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7"}, {file = "coverage-4.5.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47"}, {file = "coverage-4.5.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025"}, {file = "coverage-4.5.4-cp35-cp35m-win32.whl", hash = "sha256:bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e"}, {file = "coverage-4.5.4-cp35-cp35m-win_amd64.whl", hash = "sha256:19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d"}, {file = "coverage-4.5.4-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9"}, {file = "coverage-4.5.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755"}, {file = "coverage-4.5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9"}, {file = "coverage-4.5.4-cp36-cp36m-win32.whl", hash = "sha256:6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f"}, {file = "coverage-4.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5"}, {file = "coverage-4.5.4-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca"}, {file = "coverage-4.5.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650"}, {file = "coverage-4.5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2"}, {file = "coverage-4.5.4-cp37-cp37m-win32.whl", hash = "sha256:93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5"}, {file = "coverage-4.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351"}, {file = "coverage-4.5.4-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5"}, {file = "coverage-4.5.4.tar.gz", hash = "sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c"}, ] distlib = [ {file = "distlib-0.3.1-py2.py3-none-any.whl", hash = "sha256:8c09de2c67b3e7deef7184574fc060ab8a793e7adbb183d942c389c8b13c52fb"}, {file = "distlib-0.3.1.zip", hash = "sha256:edf6116872c863e1aa9d5bb7cb5e05a022c519a4594dc703843343a9ddd9bff1"}, ] filelock = [ {file = "filelock-3.0.12-py3-none-any.whl", hash = "sha256:929b7d63ec5b7d6b71b0fa5ac14e030b3f70b75747cef1b10da9b879fef15836"}, {file = "filelock-3.0.12.tar.gz", hash = "sha256:18d82244ee114f543149c66a6e0c14e9c4f8a1044b5cdaadd0f82159d6a6ff59"}, ] funcsigs = [ {file = "funcsigs-1.0.2-py2.py3-none-any.whl", hash = "sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca"}, {file = "funcsigs-1.0.2.tar.gz", hash = "sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50"}, ] importlib-metadata = [ {file = "importlib_metadata-0.23-py2.py3-none-any.whl", hash = "sha256:d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af"}, {file = "importlib_metadata-0.23.tar.gz", hash = "sha256:aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26"}, ] importlib-resources = [ {file = "importlib_resources-1.0.2-py2.py3-none-any.whl", hash = "sha256:6e2783b2538bd5a14678284a3962b0660c715e5a0f10243fd5e00a4b5974f50b"}, {file = "importlib_resources-1.0.2.tar.gz", hash = "sha256:d3279fd0f6f847cced9f7acc19bd3e5df54d34f93a2e7bb5f238f81545787078"}, ] mock = [ {file = "mock-3.0.5-py2.py3-none-any.whl", hash = "sha256:d157e52d4e5b938c550f39eb2fd15610db062441a9c2747d3dbfa9298211d0f8"}, {file = "mock-3.0.5.tar.gz", hash = "sha256:83657d894c90d5681d62155c82bda9c1187827525880eda8ff5df4ec813437c3"}, ] more-itertools = [ {file = "more-itertools-5.0.0.tar.gz", hash = "sha256:38a936c0a6d98a38bcc2d03fdaaedaba9f412879461dd2ceff8d37564d6522e4"}, {file = "more_itertools-5.0.0-py2-none-any.whl", hash = "sha256:c0a5785b1109a6bd7fac76d6837fd1feca158e54e521ccd2ae8bfe393cc9d4fc"}, {file = "more_itertools-5.0.0-py3-none-any.whl", hash = "sha256:fe7a7cae1ccb57d33952113ff4fa1bc5f879963600ed74918f1236e212ee50b9"}, {file = "more-itertools-7.2.0.tar.gz", hash = "sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832"}, {file = "more_itertools-7.2.0-py3-none-any.whl", hash = "sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"}, ] packaging = [ {file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"}, {file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"}, ] pathlib2 = [ {file = "pathlib2-2.3.5-py2.py3-none-any.whl", hash = "sha256:0ec8205a157c80d7acc301c0b18fbd5d44fe655968f5d947b6ecef5290fc35db"}, {file = "pathlib2-2.3.5.tar.gz", hash = "sha256:6cd9a47b597b37cc57de1c05e56fb1a1c9cc9fab04fe78c29acd090418529868"}, ] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] py = [ {file = "py-1.9.0-py2.py3-none-any.whl", hash = "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2"}, {file = "py-1.9.0.tar.gz", hash = "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342"}, ] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ {file = "pytest-4.6.11-py2.py3-none-any.whl", hash = "sha256:a00a7d79cbbdfa9d21e7d0298392a8dd4123316bfac545075e6f8f24c94d8c97"}, {file = "pytest-4.6.11.tar.gz", hash = "sha256:50fa82392f2120cc3ec2ca0a75ee615be4c479e66669789771f1758332be4353"}, ] pytest-cov = [ {file = "pytest-cov-2.8.1.tar.gz", hash = "sha256:cc6742d8bac45070217169f5f72ceee1e0e55b0221f54bcf24845972d3a47f2b"}, {file = "pytest_cov-2.8.1-py2.py3-none-any.whl", hash = "sha256:cdbdef4f870408ebdbfeb44e63e07eb18bb4619fae852f6e760645fa36172626"}, ] pytest-mock = [ {file = "pytest-mock-1.13.0.tar.gz", hash = "sha256:e24a911ec96773022ebcc7030059b57cd3480b56d4f5d19b7c370ec635e6aed5"}, {file = "pytest_mock-1.13.0-py2.py3-none-any.whl", hash = "sha256:67e414b3caef7bff6fc6bd83b22b5bc39147e4493f483c2679bc9d4dc485a94d"}, ] scandir = [ {file = "scandir-1.10.0-cp27-cp27m-win32.whl", hash = "sha256:92c85ac42f41ffdc35b6da57ed991575bdbe69db895507af88b9f499b701c188"}, {file = "scandir-1.10.0-cp27-cp27m-win_amd64.whl", hash = "sha256:cb925555f43060a1745d0a321cca94bcea927c50114b623d73179189a4e100ac"}, {file = "scandir-1.10.0-cp34-cp34m-win32.whl", hash = "sha256:2c712840c2e2ee8dfaf36034080108d30060d759c7b73a01a52251cc8989f11f"}, {file = "scandir-1.10.0-cp34-cp34m-win_amd64.whl", hash = "sha256:2586c94e907d99617887daed6c1d102b5ca28f1085f90446554abf1faf73123e"}, {file = "scandir-1.10.0-cp35-cp35m-win32.whl", hash = "sha256:2b8e3888b11abb2217a32af0766bc06b65cc4a928d8727828ee68af5a967fa6f"}, {file = "scandir-1.10.0-cp35-cp35m-win_amd64.whl", hash = "sha256:8c5922863e44ffc00c5c693190648daa6d15e7c1207ed02d6f46a8dcc2869d32"}, {file = "scandir-1.10.0-cp36-cp36m-win32.whl", hash = "sha256:2ae41f43797ca0c11591c0c35f2f5875fa99f8797cb1a1fd440497ec0ae4b022"}, {file = "scandir-1.10.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7d2d7a06a252764061a020407b997dd036f7bd6a175a5ba2b345f0a357f0b3f4"}, {file = "scandir-1.10.0-cp37-cp37m-win32.whl", hash = "sha256:67f15b6f83e6507fdc6fca22fedf6ef8b334b399ca27c6b568cbfaa82a364173"}, {file = "scandir-1.10.0-cp37-cp37m-win_amd64.whl", hash = "sha256:b24086f2375c4a094a6b51e78b4cf7ca16c721dcee2eddd7aa6494b42d6d519d"}, {file = "scandir-1.10.0.tar.gz", hash = "sha256:4d4631f6062e658e9007ab3149a9b914f3548cb38bfb021c64f39a025ce578ae"}, ] six = [ {file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, {file = "six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, ] toml = [ {file = "toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, {file = "toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, ] tox = [ {file = "tox-3.14.0-py2.py3-none-any.whl", hash = "sha256:0bc216b6a2e6afe764476b4a07edf2c1dab99ed82bb146a1130b2e828f5bff5e"}, {file = "tox-3.14.0.tar.gz", hash = "sha256:c4f6b319c20ba4913dbfe71ebfd14ff95d1853c4231493608182f66e566ecfe1"}, ] typing = [ {file = "typing-3.7.4.3-py2-none-any.whl", hash = "sha256:283d868f5071ab9ad873e5e52268d611e851c870a2ba354193026f2dfb29d8b5"}, {file = "typing-3.7.4.3.tar.gz", hash = "sha256:1187fb9c82fd670d10aa07bbb6cfcfe4bdda42d6fab8d5134f04e8c4d0b71cc9"}, ] virtualenv = [ {file = "virtualenv-20.0.31-py2.py3-none-any.whl", hash = "sha256:e0305af10299a7fb0d69393d8f04cb2965dda9351140d11ac8db4e5e3970451b"}, {file = "virtualenv-20.0.31.tar.gz", hash = "sha256:43add625c53c596d38f971a465553f6318decc39d98512bc100fa1b1e839c8dc"}, ] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] zipp = [ {file = "zipp-1.2.0-py2.py3-none-any.whl", hash = "sha256:e0d9e63797e483a30d27e09fffd308c59a700d365ec34e93cc100844168bf921"}, {file = "zipp-1.2.0.tar.gz", hash = "sha256:c70410551488251b0fee67b460fb9a536af8d6f9f008ad10ac51f615b6a521b1"}, ] pastel-0.2.1/pyproject.toml000066400000000000000000000011701373046207700157260ustar00rootroot00000000000000[tool.poetry] name = "pastel" version = "0.2.1" description = "Bring colors to your terminal." authors = ["Sébastien Eustace "] license = "MIT" readme = "README.rst" homepage = "https://github.com/sdispater/pastel" repository = "https://github.com/sdispater/pastel" packages = [ {include = "pastel"}, {include = "tests", format = "sdist"}, ] [tool.poetry.dependencies] python = "~2.7 || ^3.4" [tool.poetry.dev-dependencies] pytest = "^4.6.4" pytest-cov = "^2.7.1" pytest-mock = "^1.10.4" tox = "^3.13.2" [build-system] requires = ["poetry-core>=1.0.0a9"] build-backend = "poetry.core.masonry.api" pastel-0.2.1/tests/000077500000000000000000000000001373046207700141555ustar00rootroot00000000000000pastel-0.2.1/tests/__init__.py000066400000000000000000000000301373046207700162570ustar00rootroot00000000000000# -*- coding: utf-8 -*- pastel-0.2.1/tests/conftest.py000066400000000000000000000005551373046207700163610ustar00rootroot00000000000000# -*- coding: utf-8 -*- import pytest from pastel import Pastel from pastel.style import Style from pastel.stack import StyleStack @pytest.fixture def pastel(): return Pastel(True) @pytest.fixture def non_decorated_pastel(): return Pastel(False) @pytest.fixture def style(): return Style() @pytest.fixture def stack(): return StyleStack() pastel-0.2.1/tests/test_api.py000066400000000000000000000024471373046207700163460ustar00rootroot00000000000000# -*- coding: utf-8 -*- import sys import pastel from contextlib import contextmanager class PseudoTTY(object): def __init__(self, underlying): self._underlying = underlying def __getattr__(self, name): return getattr(self._underlying, name) def isatty(self): return True @contextmanager def mock_stdout(): original = sys.stdout sys.stdout = PseudoTTY(sys.stdout) yield sys.stdout = original def test_text(): with mock_stdout(): assert "\033[32msome info\033[0m" == pastel.colorize("some info") def test_colorize(): with mock_stdout(): pastel.with_colors(False) assert "some info" == pastel.colorize("some info") pastel.with_colors(True) assert "\033[32msome info\033[0m" == pastel.colorize("some info") def test_add_remove_style(): with mock_stdout(): pastel.add_style("success", "green") assert "\033[32msome info\033[0m" == pastel.colorize( "some info" ) pastel.remove_style("success") assert "some info" == pastel.colorize( "some info" ) def test_pastel(): p = pastel.pastel() assert isinstance(p, pastel.Pastel) pastel-0.2.1/tests/test_pastel.py000066400000000000000000000120571373046207700170630ustar00rootroot00000000000000# -*- coding: utf-8 -*- import pytest from pastel import Pastel def test_empty_tag(pastel): assert "foo<>bar" == pastel.colorize("foo<>bar") def test_lg_char_escaping(pastel): assert "foosome info" == pastel.colorize("\\some info\\") assert "\\some info\\" == pastel.escape("some info") def test_bundled_styles(pastel): assert pastel.has_style("error") assert pastel.has_style("info") assert pastel.has_style("comment") assert pastel.has_style("question") assert "\033[97;41msome error\033[0m" == pastel.colorize( "some error" ) assert "\033[32msome info\033[0m" == pastel.colorize("some info") assert "\033[33msome comment\033[0m" == pastel.colorize( "some comment" ) assert "\033[30;46msome question\033[0m" == pastel.colorize( "some question" ) def test_nested_styles(pastel): assert ( "\033[97;41msome \033[0m\033[32msome info\033[0m\033[97;41m error\033[0m" == pastel.colorize("some some info error") ) def test_adjacent_style(pastel): assert "\033[97;41msome error\033[0m\033[32msome info\033[0m" == pastel.colorize( "some errorsome info" ) def test_style_matching_non_greedy(pastel): assert "(\033[32m>=2.0,<2.3\033[0m)" == pastel.colorize("(>=2.0,<2.3)") def test_style_escaping(pastel): assert "(\033[32mz>=2.0,%s)" % pastel.escape("z>=2.0,errorinfocommenterror" ) ) def test_new_style(pastel): pastel.add_style("test", "blue", "white") assert pastel.style("test") != pastel.style("info") pastel.add_style("b", "blue", "white") assert ( "\033[34;107msome \033[0m\033[34;107mcustom\033[0m\033[34;107m msg\033[0m" == pastel.colorize("some custom msg") ) pastel.remove_style("test") pastel.remove_style("b") assert "some custom msg" == pastel.colorize( "some custom msg" ) with pytest.raises(ValueError): pastel.remove_style("b") def test_redefined_style(pastel): pastel.add_style("info", "blue", "white") assert "\033[34;107msome custom msg\033[0m" == pastel.colorize( "some custom msg" ) def test_inline_style(pastel): assert "\033[34;41msome text\033[0m" == pastel.colorize( "some text" ) assert "\033[34;41msome text\033[0m" == pastel.colorize( "some text" ) assert "\033[34;41;1msome text\033[0m" == pastel.colorize( "some text" ) def test_non_style_tag(pastel): expected = ( "\033[32msome \033[0m\033[32m\033[0m\033[32m \033[0m\033[32m\033[0m\033[32m" " styled \033[0m\033[32m

\033[0m\033[32msingle-char tag\033[0m\033[32m

\033[0m" ) assert expected == pastel.colorize( "some styled

single-char tag

" ) def test_non_decorated_pastel(non_decorated_pastel): pastel = non_decorated_pastel assert pastel.has_style("error") assert pastel.has_style("info") assert pastel.has_style("comment") assert pastel.has_style("question") assert "some error" == pastel.colorize("some error") assert "some info" == pastel.colorize("some info") assert "some comment" == pastel.colorize("some comment") assert "some question" == pastel.colorize("some question") pastel.with_colors(True) assert "\033[97;41msome error\033[0m" == pastel.colorize( "some error" ) assert "\033[32msome info\033[0m" == pastel.colorize("some info") assert "\033[33msome comment\033[0m" == pastel.colorize( "some comment" ) assert "\033[30;46msome question\033[0m" == pastel.colorize( "some question" ) @pytest.mark.parametrize( "expected, message", [ ( """\033[32m some text\033[0m""", """ some text""", ), ( """\033[32msome text \033[0m""", """some text """, ), ( """\033[32m some text \033[0m""", """ some text """, ), ( """\033[32m some text more text \033[0m""", """ some text more text """, ), ], ) def test_content_with_line_breaks(pastel, expected, message): assert expected == pastel.colorize(message) pastel-0.2.1/tests/test_stack.py000066400000000000000000000017551373046207700167030ustar00rootroot00000000000000# -*- coding: utf-8 -*- import pytest from pastel.style import Style def test_push(stack): s1 = Style("white", "black") s2 = Style("yellow", "blue") stack.push(s1) stack.push(s2) assert s2 == stack.get_current() s3 = Style("green", "red") stack.push(s3) assert s3 == stack.get_current() def test_pop(stack): s1 = Style("white", "black") s2 = Style("yellow", "blue") stack.push(s1) stack.push(s2) assert s2 == stack.pop() assert s1 == stack.pop() def test_pop_empty(stack): assert isinstance(stack.pop(), Style) def test_pop_not_last(stack): s1 = Style("white", "black") s2 = Style("yellow", "blue") s3 = Style("green", "red") stack.push(s1) stack.push(s2) stack.push(s3) assert s2 == stack.pop(s2) assert s1 == stack.pop() def test_invalid_pop(stack): s1 = Style("white", "black") s2 = Style("yellow", "blue") stack.push(s1) with pytest.raises(ValueError): stack.pop(s2) pastel-0.2.1/tests/test_style.py000066400000000000000000000036451373046207700167360ustar00rootroot00000000000000# -*- coding: utf-8 -*- import pytest from pastel.style import Style def test_init(): style = Style("green", "black", ["bold", "underline"]) assert "\033[32;40;1;4mfoo\033[0m" == style.apply("foo") assert "green" == style.foreground assert "black" == style.background assert ["bold", "underline"] == style.options style = Style("red", None, ["blink"]) assert "\033[31;5mfoo\033[0m" == style.apply("foo") style = Style(None, "white") assert "\033[107mfoo\033[0m" == style.apply("foo") style = Style("red", None, "blink") assert "\033[31;5mfoo\033[0m" == style.apply("foo") def test_foreground(style): style.set_foreground("black") assert "\033[30mfoo\033[0m" == style.apply("foo") style.set_foreground("blue") assert "\033[34mfoo\033[0m" == style.apply("foo") with pytest.raises(ValueError): style.set_foreground("undefined-color") def test_background(style): style.set_background("black") assert "\033[40mfoo\033[0m" == style.apply("foo") style.set_background("yellow") assert "\033[43mfoo\033[0m" == style.apply("foo") with pytest.raises(ValueError): style.set_background("undefined-color") def test_options(style): style.set_options(["reverse", "conceal"]) assert "\033[7;8mfoo\033[0m" == style.apply("foo") style.set_option("bold") assert "\033[7;8;1mfoo\033[0m" == style.apply("foo") style.unset_option("reverse") assert "\033[8;1mfoo\033[0m" == style.apply("foo") style.set_option("bold") assert "\033[8;1mfoo\033[0m" == style.apply("foo") style.set_options(["bold"]) assert "\033[1mfoo\033[0m" == style.apply("foo") with pytest.raises(ValueError) as e: style.set_option("foo") assert 'Invalid option specified: "foo"' in str(e.value) with pytest.raises(ValueError) as e: style.unset_option("foo") assert 'Invalid option specified: "foo"' in str(e.value) pastel-0.2.1/tox.ini000066400000000000000000000002511373046207700143240ustar00rootroot00000000000000[tox] envlist = py27, py35, py36, pypy skipsdist=True [testenv] whitelist_externals = poetry commands = poetry install -v poetry run pytest --cov pastel tests/