pax_global_header00006660000000000000000000000064124533074530014520gustar00rootroot0000000000000052 comment=d32743abb36cd586952f170e94a254e730b1a775 PyScanFCS-0.2.3/000077500000000000000000000000001245330745300132535ustar00rootroot00000000000000PyScanFCS-0.2.3/.gitignore000066400000000000000000000007201245330745300152420ustar00rootroot00000000000000*.py[cod] # C extensions *.so # Packages *.egg *.egg-info dist build eggs parts bin var sdist develop-eggs .installed.cfg lib lib64 # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox nosetests.xml # Translations *.mo # Mr Developer .mr.developer.cfg .project .pydevproject #Latex *.aux *.glo *.idx *.log *.toc *.ist *.acn *.acr *.alg *.bbl *.blg *.dvi *.glg *.gls *.ilg *.ind *.lof *.lot *.maf *.mtc *.mtc1 *.out *.synctex.gz *.pdf PyScanFCS-0.2.3/.gitmodules000066400000000000000000000000001245330745300154160ustar00rootroot00000000000000PyScanFCS-0.2.3/ChangeLog.txt000066400000000000000000000016761245330745300156550ustar00rootroot000000000000000.2.3 - New tool to create artificial .dat files for testing - A couple of minor bug fixes - Exceptions are now handled by wxPython - Under the hood: - Updated repository structure - Relative imports - Build machine is now Windows 7 0.2.2 - Added button 'full time interval' - This is the first version that uses the external module `multipletau` - This is the first version that is available at PyPI - Added setup files with Cython support - MakeTestDat_FCS.py can be used to create test data - Tested with Mac OSx 0.2.1 - Updated help menu (documentation, wiki, update) - Performed some artwork around PyScanFCS - Output of bleaching correction data (#1) - Code cleanup 0.2.0 - Code cleanup - Considerable speed-up in binning of .dat files - Secured compatibility with PyCorrFit (.csv files) - Fixed small file-naming bug 0.1.9 - Code cleanup - Moved to Python 2.7 0.1.8 - Initital GitHub commit PyScanFCS-0.2.3/MANIFEST.in000066400000000000000000000002141245330745300150060ustar00rootroot00000000000000include doc/*.tex include doc/*.bib include doc/*.pdf include pyscanfcs/*.pyx include doc/Images/* include Readme.txt include ChangeLog.txt PyScanFCS-0.2.3/README.md000066400000000000000000000027731245330745300145430ustar00rootroot00000000000000![PyScanFCS](https://raw.github.com/paulmueller/PyScanFCS/master/doc-src/Images/PyScanFCS_logo_dark.png) ========= This repository contains the source code of PyScanFCS - a tool for data evaluation in perpendicular line scanning fluorescence correlation spectroscopy (FCS). When a membrane is scanned perpendicularly to its surface, the fluorescence signal originating from the membrane itself must be separated from the signal of the surrounding medium for an FCS analysis. PyScanFCS interactively extracts the fluctuating fluorescence signal from such measurements and applies a multiple-tau algorithm. The obtained correlation curves can be evaluated using [PyCorrFit](https://github.com/paulmueller/PyCorrFit). It is possible to create test-data containing exponentially correlated data with [MakeTestDat_SFCS.py](https://github.com/paulmueller/multipletau/blob/master/MakeTestDat_SFCS.py). The obtained correlation curves can be fitted with [PyCorrFit](https://github.com/paulmueller/PyCorrFit) using the [appropriate model function](https://github.com/paulmueller/multipletau/blob/master/ExampleFunc_Exp_correlated_noise.txt). For further information, please visit the PyScanFCS homepage at [http://pyscanfcs.craban.de](http://pyscanfcs.craban.de). - [Download the latest version](https://github.com/paulmueller/PyScanFCS/releases) - [Documentation](https://github.com/paulmueller/PyScanFCS/wiki/PyScanFCS_doc.pdf) - [Using Cython on Windows XP](https://github.com/paulmueller/PyScanFCS/wiki/Using-Cython-on-Windows-XP) PyScanFCS-0.2.3/Readme.txt000066400000000000000000000007021245330745300152100ustar00rootroot00000000000000PyCorrFit can be used for analyzing data from perpendicular line scanning FCS. For a full list of features and supported file formats visit http://pyscanfcs.craban.de. There are also precompiled binaries for various systems. This package provides the Python module `pyscanfcs` and its graphical user interface. The graphical user interface is written in wxPython. Installation and usage: pip install pyscanfcs python -m pyscanfcs PyScanFCS-0.2.3/bin/000077500000000000000000000000001245330745300140235ustar00rootroot00000000000000PyScanFCS-0.2.3/bin/pyscanfcs000077500000000000000000000001631245330745300157420ustar00rootroot00000000000000#!/bin/bash # go to this directory to prevent execution of a git checkout cd "$(dirname "$0")" python -m pyscanfcs PyScanFCS-0.2.3/doc/000077500000000000000000000000001245330745300140205ustar00rootroot00000000000000PyScanFCS-0.2.3/doc/Bibliography.bib000066400000000000000000000073541245330745300171220ustar00rootroot00000000000000% This file was created with JabRef 2.10. % Encoding: UTF-8 @InCollection{Mueller2014, Title = {Scanning Fluorescence Correlation Spectroscopy ({SFCS}) with a Scan Path Perpendicular to the Membrane Plane}, Author = {M{\"{u}}ller, Paul and Schwille, Petra and Weidemann, Thomas}, Booktitle = {Fluorescence Spectroscopy and Microscopy}, Publisher = {Humana Press}, Year = {2014}, Editor = {Engelborghs, Yves and Visser, Antonie J.W.G.}, Pages = {635-651}, Series = {Methods in Molecular Biology}, Volume = {1076}, __markedentry = {[paul:]}, Doi = {10.1007/978-1-62703-649-8_29}, ISBN = {978-1-62703-648-1}, Keywords = {Scanning fluorescence correlation spectroscopy (SFCS); Fluorescence correlation spectroscopy (FCS); Fluorescence cross-correlation spectroscopy (FCCS); Membrane diffusion; Giant unilamellar vesicles (GUV); Diffusion; Protein–protein interaction; Ligand binding}, Language = {English}, Owner = {paul}, Timestamp = {2013.10.21}, Url = {http://pyscanfcs.craban.de} } @Article{Mueller2014a, Title = {PyCorrFit – generic data evaluation for fluorescence correlation spectroscopy}, Author = {M{\"{u}}ller, Paul and Schwille, Petra and Weidemann, Thomas}, Journal = {Bioinformatics}, Year = {2014}, __markedentry = {[paul:6]}, Abstract = {Summary: We present a graphical user interface (PyCorrFit) for the fitting of theoretical model functions to experimental data obtained by fluorescence correlation spectroscopy (FCS). The program supports many data file formats and features a set of tools specialized in FCS data evaluation. Availability and Implementation: The Python source code is freely available for download from the PyCorrFit web page at http://pycorrfit.craban.de. We offer binaries for Ubuntu Linux, Mac OS X, and Microsoft Windows. Contact: paul.mueller@biotec.tu-dresden.de and weidemann@biochem.mpg.de Supplementary information: Supplementary information and a documentation are available at the PyCorrFit web page.}, Doi = {10.1093/bioinformatics/btu328}, Owner = {paul}, Timestamp = {2014.05.14}, Url = {http://pycorrfit.craban.de} } @Article{Ries2009, Title = {Accurate Determination of Membrane Dynamics with Line-Scan FCS}, Author = {Jonas Ries and Salvatore Chiantia and Petra Schwille}, Journal = {Biophysical Journal}, Year = {2009}, Number = {5}, Pages = {1999 - 2008}, Volume = {96}, Doi = {10.1016/j.bpj.2008.12.3888}, ISSN = {0006-3495}, Owner = {paul}, Timestamp = {2012.11.08} } @Article{Wohland2001, Title = {The Standard Deviation in Fluorescence Correlation Spectroscopy}, Author = {Wohland, Thorsten and Rigler, Rudolf and Vogel, Horst}, Journal = {Biophysical Journal}, Year = {2001}, Month = jun, Number = {6}, Pages = {2987--2999}, Volume = {80}, Doi = {10.1016/S0006-3495(01)76264-9}, ISSN = {0006-3495}, Owner = {paul}, Timestamp = {2012.09.08} } PyScanFCS-0.2.3/doc/Images/000077500000000000000000000000001245330745300152255ustar00rootroot00000000000000PyScanFCS-0.2.3/doc/Images/1color1focus.pdf000077500000000000000000000456661245330745300202640ustar00rootroot00000000000000%PDF-1.4 % 1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj 8 0 obj << /XObject 7 0 R /Pattern 5 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ExtGState 4 0 R /Shading 6 0 R /Font 3 0 R >> endobj 10 0 obj << /Contents 9 0 R /Type /Page /Resources 8 0 R /Parent 2 0 R /MediaBox [ 0 0 576 439.2 ] >> endobj 9 0 obj << /Filter /FlateDecode /Length 11 0 R >> stream x͝M-UE+!- ۶}ds2vľ}=]{Eedޛ^4~^u_K^۱?\k_K__ckنpa>ߥߦ?ee?~+?xtu^7_P?Ae/Nka?}m}uT,#=A(yJH>Q=N_׷M:˾Zac{}ƿ~}}nz3.8| 忼aNcy:X<5q@yx zn9˴K>&~ֈx֘/}i5.mݧyz4Vy,y}uۮujN,/3_ۑ^>~ڌ?Ϗ_?~|yOas7SwN~2[:a֞1߆9v#:<\\" K}_u}Wk>,o/scur[-d˛|z0n=眖q.{w4kz_8Y}}|}0Edog9vPGo#_7K,juw6G;,mcn>(cs_LE?:[_?|WHy^"f<'>]\YKϝ݇3O5? wm?'C}"ί0? $+{\wLms,z=gjA/lwݧѶ|&?K4!xz ̯)l.8b0@ÓkX RO|!c x OmlK0>_“y3 4\h: >R 2lsm|1Ys\Çi' YR]zy\xbtt>lc2XvK>ÇfӅÇi r-OW =_zgld3 x7,3\>LqCx! q_U6H>Řj 1<)7ݐ1||} \of$Q0;>@/ ɖ3 Z8O!aa3 œ W cxr f~0Lq!Q`2d =_z_@FPJDӰq}յ9TD2'i{ '?Q :,S-Ũ3wD۰vը1 ё]kggXK0J$θ=}*r"T-PKưj>mlNA^PAzPJDqLح +rFdoG'mOx}ֈ;ט2Z2|&2 "P팻IjQ`gbãA(&"12:8qFӓ`gbƣB(ǣY]tq\3 hHR|&<b"R) ` ''' aH$mν؍TR2Z |& "PGgٓԮPADGPLDlAcd3^!2 ('i{ }&=*r"qb\3 zkHRB> B1]AD{0J$p=Q92 R"R]c˸kq*vk@]6R=I:n**(hH6-z }&+Q(ù{8L|TDһq\031 :o`OR.A(ƣMw q2yFd=--B9eܵEBL5AD68ԮPA/DGPLDlAcd ^!1("i{ ~!>*r"R9^˸kq.{k`W7IjqSQ/DGPLDjlAdl,LFB}TDWH0L2 B~)?qk$C_TׂB%s8QVE8DBl~Txtc6ZJaJ4AD7ԮPA/L{PLDlAd8,[0F$k~퍤1, }ʉHy .ŹKDq{=I:n*|oH9-z >a>*Q""i{ JaJ+r<:՞W`w-E0_ "Po9ԮP/{PLD*lAS2AXg$-=A2B9=eܵ8ʼ~i@9n']ME2 B1:]AL[0'8("i{ VeV+r"R{^˸k1.zy zsHRB2 B1<]63l?q,XY}ʉHy .ŹWKDq{=I:njsiQߺ*p]AD{0J$pzhWbB('"5_׷!ԛzu*88hH9-z t-cDr֓DZ`WbB('"5_׷!ԛzu*88hhRu^=z R%R+Q"TՓ=FB9=eܵ8/hA"v7J~4Dt=N(q0XXʉ[S nh7bK>ՙI9B)5]o{0J$pz(7"B('"5߈ҷ!TzuT Zs[8|F|WDrwؓ 7"B(ǣEyqb\TQ JsHRB\>_($"怵1.|FdvUO8F~TDq\ zs<Ϟv7F~4Dt=Nۼ(=°=FB9=eܵ8F5AD68ԮP,B"RuX ߈ aHa?p{=i{ V#V?*r"R{^˸k1.zx}k@9n']G߈ӏT؂ 7"Bœ|I߈Տ Ԟ2Z ^#^ "PIjסrw/4"U瀱1JH}FDn'mGPNDjkpw-Eo B7$(Tp;q Ѯ{8NWD2H߉Տ Ԟ2Z ^'^ "PsIjqS6lB!:]sAD{0J$6q{=i{ V'V?*r"R{^˸k1.zx}kPoIjQwA(&"U12JI}Fd&U=3B9paQ`wfc7I)H;>](#"@q.|F̯긳=F3B98eܵ8Δ~iTeIjQwA(&"12|Fd&TU=K }ʉHy .ŸwKDq=I: tt7Dt=N3o(\ `Oڞ>PL{PGkYeŹKD{l"PeIjWQOA(&"q2|FD10 hUq^mܵ8I5AD68Ԯ㦢?Ώԛ؂OB%uXAV=I`P'QQ!\]qAj"PogٓԮ0GPLDlAcd'^!5\'n'mGPGz?׷!ԛGuTt'q s[8gvA[0J$۰10ZXʉHy .ŹOA"v N$N?b"Ru` BP_D{0'{_eG8E~TDq\ zsHRN"N?b"Ru` 'Կ aHaEYIc`Q!\]s_[Dq=I: E~4xt:t=FF1o(LÅ*pI+ R"R{^c˸k1*zy zsHRB1 B1:]A_L[0J$ǰ10ZY}ʉHy .Ź`/KzsHRNbNb"Ru` 'ԿԷ aHI`84{PJDP:0Uh/fcI1$|/JH9p-z>b>*Q"9U$mA_L{PND*kpw-1_ ~+o:}_Q7/}p~[=e/О_玿WR[~]~ī㲮Uw}hۏ>yyYxu=pUospWZZW[:)=؉ Ɠxk a^' n?޴Ȟsvo땟|a,LXW}v O|Ws> stream x5P C1g dVukm;aBXȔy)K>:L." u%ʚ +`p&^7`i5tႦ.B%|u{OxjrvC` jMX> stream x36P0C. endstream endobj 23 0 obj << /Filter /FlateDecode /Length 317 >> stream x5RKrC1ۿSpΘ}tj'+-@B./YK~%ۥW%B>R-G- Q=2'":xa>N)x_xN;2$KMH=I+4t~&+s{rj X+)$=Hr7VސWg%&&MܕBXtLX㰄*aՃM5fcdxLP} #GMv²[6!D3,($Nc$ Ұ9 9e, mh%zМaמE[{ endstream endobj 24 0 obj << /Filter /FlateDecode /Length 338 >> stream x5R9@ } ] v͜~߆_ CVie!U-.Im W%ڥ Pt,6˯JH+kLwIi"Eo7o}=@.^ AS(i|Ъc(ew 4<3}(~_K&(? _osџa`Ś}@*z`yT endstream endobj 25 0 obj << /Filter /FlateDecode /Length 163 >> stream xMK1 C=/yoIʀXT~rICpn4Ke>\1'X *b8j`Nhҡ+[a v悓 |:a̶ͮ]cwIi׾zx! [YSoM-<ʦ}>9o:k8. endstream endobj 26 0 obj << /Filter /FlateDecode /Length 392 >> stream x=RKn1)@Mr[T /1 %?ꒈ3L~r]Qljg!.6Xr_rњbO/ȴTXVݣC(-װr{d`Jn@CHYAaPl( WԬtb ) ٠[]aP[[xfޑ3qYk?=Q2QMg|2RCgB'`$Ip#A 1qOl)V;ޒ{,\L'ib?lK\+E(~Aq|XdDw#h% 0xyDhDԎ=(ͱ&{ǫvzcw. endstream endobj 27 0 obj << /Filter /FlateDecode /Length 67 >> stream x34P0P4W546T060Q073PH11s,lLeb ̀Ɓ% 9pr΃ endstream endobj 28 0 obj << /Filter /FlateDecode /Length 87 >> stream x=0C{` }rۀ?iC:N 6 ΁7AE/.o !$ŢVůE4I7QNJx>uz endstream endobj 29 0 obj << /Filter /FlateDecode /Length 59 >> stream x355W0PF F )\@>ehifY@Has`zrZ endstream endobj 30 0 obj << /Filter /FlateDecode /Length 165 >> stream xE;! C{N#y6;I,%?+:cck'R: g]a2So\\`nN|愯U—L 0;Q|$ ꔍ0G@LM/yjAPkGkS4g*[ :L?= endstream endobj 31 0 obj << /Filter /FlateDecode /Length 71 >> stream x34P0P0S546T04V073PH1 X\00247CbBeX r`J# endstream endobj 32 0 obj << /Filter /FlateDecode /Length 248 >> stream x-Q9AzBsˑ C :-qPO+Uwu9HTM]vf5,?c 7zqxLu5{kOfP2+qSușO \ ȹeƌ#M!RH&3AQ~#aU#j \Ks4;<9GW +ET<pC7ҹ^s0XM7/=[ endstream endobj 33 0 obj << /Filter /FlateDecode /Length 304 >> stream x=;0 C{Ȍd'>2VI(/u< i& b;w؞D/)ϡ+E:Ū0[M*K õ}74uK hY pu;Gw5<TQ!OJ|<(!\{0FS@\^BAjI'> stream xEPC1 =`,{wHۿ=JFp!Z?ZK oGFA= 3A΄@xFnvpμ39Zpә\'mBITqTqLύׁlӑ!KI%&~S*)[*EH䁓M4,?Cb̠Q0qGuٜ9-L|X&Q)2>'\N}䢥Uޑ"ۡW%Qէ<Y> endstream endobj 35 0 obj << /Filter /FlateDecode /Length 68 >> stream x32P0P4& f )\@B.H  %[B4AXf&fI8"ɴ endstream endobj 36 0 obj << /Filter /FlateDecode /Length 163 >> stream xEu1 CsUx:?G i@xx= r]Ņ ?޶42܍e@N"WI3Tb\/:"̒@#|:C[ۙ~:!**na.@RԏQꚡ*+kjڿ"}\Ne{g+W}: endstream endobj 37 0 obj << /Filter /FlateDecode /Length 255 >> stream xEK D#> stream x=PC1= |7˥m$B6BLɔ:ʒ)O>Kbnd6%*E/% }ՖC4h9~ 3*K6p*3 mtV[ Ф`׶ r " JMrR=ot-N=Dkq: DpFjtaŲC5=kz7hGt4CָR endstream endobj 39 0 obj << /Filter /FlateDecode /Length 161 >> stream xEK CBGG|tJ■!M@w'/mK >[ x6n5uVhR}ith6s+ fz:rGp_Gdf)|Q]dcnk]3s: endstream endobj 40 0 obj << /Filter /FlateDecode /Length 332 >> stream x-R9$1 ~`LtIUls#h/#xE=f۴[iGiK,W ;BjW0wy.2meDkag؏]e8*Jl !2J'Qw\I2[E™w2;yNE{ kF9+%|6vzrYɩHHӺ NKؖߗ3| endstream endobj 41 0 obj << /Filter /FlateDecode /Length 157 >> stream xEC1DsUA wJo-%S'"h0yM%V,&rAJ1xN1븨ufihW3=5'M<[ }@8IP1}bv">G)#qbn fW7y endstream endobj 42 0 obj << /Filter /FlateDecode /Length 320 >> stream x5Qq0 54sۿ @;a@dJ\UGM>`!S֖{&UF!}W2j]* UYFp&I8d Rӿccz endstream endobj 43 0 obj << /Filter /FlateDecode /Length 131 >> stream xE ! CT>՞0ABA";06Ѣ76իc,zRV鐇Pi0QąYLCaΘȖ2MlTv<e~ma, U^ ?KwUBS0 endstream endobj 44 0 obj << /Filter /FlateDecode /Length 72 >> stream x50{6X`KEoC|N/Z #pu#])Ec΂q_H1F=#O_p} endstream endobj 45 0 obj << /Filter /FlateDecode /Length 247 >> stream xMQmD1 \ky R]oC /)%K [UC?13,=?TPbht/"+ߏe s`&4`oI&ռ3d‰ATwM,3V7: lx%D`r Z`Q+ tĺv7C/਺x} K{,|BL;wI#fR:=b}@e+ (\* endstream endobj 15 0 obj << /FontDescriptor 14 0 R /Name /DejaVuSans /FontMatrix [ 0.001 0 0 0.001 0 0 ] /BaseFont /DejaVuSans /Widths 13 0 R /Subtype /Type3 /CharProcs 16 0 R /Type /Font /FirstChar 0 /FontBBox [ -1021 -351 1681 1167 ] /Encoding << /Differences [ 32 /space 46 /period 48 /zero /one /two /three /four /five /six /seven /eight /nine 76 /L /M 80 /P 91 /bracketleft 93 /bracketright 97 /a 101 /e 104 /h /i 109 /m /n /o 114 /r /s /t /u /v ] /Type /Encoding >> /LastChar 255 >> endobj 14 0 obj << /Descent -236 /FontBBox [ -1021 -351 1681 1167 ] /StemV 0 /Flags 32 /XHeight 0 /Type /FontDescriptor /FontName /DejaVuSans /MaxWidth 1342 /CapHeight 0 /ItalicAngle 0 /Ascent 929 >> endobj 13 0 obj [ 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 318 401 460 838 636 950 780 275 390 390 500 838 318 361 318 337 636 636 636 636 636 636 636 636 636 636 337 337 838 838 838 531 1000 684 686 698 770 632 575 775 752 295 295 656 557 863 748 787 603 787 695 635 611 732 684 989 685 611 685 390 337 390 838 500 500 613 635 550 635 615 352 635 634 278 278 579 278 974 634 612 635 635 411 521 392 634 592 818 592 592 525 636 337 636 838 600 636 600 318 352 518 1000 500 500 500 1342 635 400 1070 600 685 600 600 318 318 518 518 590 500 1000 500 1000 521 400 1023 600 525 611 318 401 636 636 636 636 337 500 500 1000 471 612 838 361 1000 500 500 838 401 401 500 636 636 318 500 401 471 612 969 969 969 531 684 684 684 684 684 684 974 698 632 632 632 632 295 295 295 295 775 748 787 787 787 787 787 838 787 732 732 732 732 611 605 630 613 613 613 613 613 613 982 550 615 615 615 615 278 278 278 278 612 634 612 612 612 612 612 838 612 634 634 634 634 592 635 592 ] endobj 16 0 obj << /seven 17 0 R /period 18 0 R /one 19 0 R /four 20 0 R /zero 21 0 R /space 22 0 R /six 23 0 R /two 32 0 R /nine 42 0 R /bracketright 27 0 R /t 43 0 R /M 28 0 R /L 29 0 R /five 45 0 R /P 30 0 R /bracketleft 31 0 R /a 33 0 R /e 34 0 R /i 35 0 R /h 36 0 R /m 37 0 R /o 38 0 R /n 39 0 R /s 40 0 R /r 41 0 R /u 25 0 R /three 24 0 R /v 44 0 R /eight 26 0 R >> endobj 3 0 obj << /F1 15 0 R >> endobj 4 0 obj << /A1 << /CA 0.1 /Type /ExtGState /ca 0.1 >> >> endobj 5 0 obj << >> endobj 6 0 obj << >> endobj 7 0 obj << /I1 12 0 R >> endobj 12 0 obj << /Width 489 /ColorSpace /DeviceGray /Height 489 /Filter /FlateDecode /Subtype /Image /Length 46 0 R /Type /XObject /BitsPerComponent 8 >> stream xܭEch$6-Xd$6DbHn[eg%a<+;Y }:C=C=C.]y싍; wB_9,rY}帳qg!t7n͍ϾJqrx^fYx3^}%_/yʸO˯ƱcZ;]Z}KZ9F%CZ_%^,?,-1%&+c?K*W q}+-qIb .]%2|ʸ]|1cXR>\D|hB -B -B }U.ÿ]dgWƛrʸ$i-1sۤ2^\^t9[{~<> endobj 47 0 obj << /CreationDate (D:20120719120514+02'00') /Producer (matplotlib pdf backend r8292) /Creator (matplotlib 1.0.1, http://matplotlib.sf.net) >> endobj xref 0 48 0000000000 65535 f 0000000016 00000 n 0000018125 00000 n 0000016431 00000 n 0000016463 00000 n 0000016527 00000 n 0000016548 00000 n 0000016569 00000 n 0000000065 00000 n 0000000317 00000 n 0000000208 00000 n 0000007109 00000 n 0000016601 00000 n 0000015006 00000 n 0000014806 00000 n 0000014326 00000 n 0000016059 00000 n 0000007130 00000 n 0000007270 00000 n 0000007391 00000 n 0000007543 00000 n 0000007705 00000 n 0000007988 00000 n 0000008077 00000 n 0000008467 00000 n 0000008878 00000 n 0000009114 00000 n 0000009579 00000 n 0000009718 00000 n 0000009877 00000 n 0000010008 00000 n 0000010246 00000 n 0000010389 00000 n 0000010710 00000 n 0000011087 00000 n 0000011405 00000 n 0000011545 00000 n 0000011781 00000 n 0000012109 00000 n 0000012396 00000 n 0000012630 00000 n 0000013035 00000 n 0000013265 00000 n 0000013658 00000 n 0000013862 00000 n 0000014006 00000 n 0000018104 00000 n 0000018185 00000 n trailer << /Info 47 0 R /Root 1 0 R /Size 48 >> startxref 18342 %%EOF PyScanFCS-0.2.3/doc/Images/GUV.pdf000077500000000000000000001775551245330745300164100ustar00rootroot00000000000000%PDF-1.4 % 3 0 obj << /Length 4 0 R /Filter /FlateDecode >> stream xm1 EwN/P pfEi:_Nf?FdeI8LjK[PܑTMDZy~{s ֽʦba9α5 ~AZD$LJ689\'LvSZ)2 endstream endobj 4 0 obj 148 endobj 2 0 obj << /ExtGState << /a0 << /CA 1 /ca 1 >> >> /Pattern << /p5 5 0 R >> >> endobj 6 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 819.200012 911.200012 ] /Contents 3 0 R /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 2 0 R >> endobj 7 0 obj << /Length 8 0 R /Filter /FlateDecode /Type /XObject /Subtype /Image /Width 1024 /Height 1139 /ColorSpace /DeviceGray /BitsPerComponent 8 >> stream x1 7݉h H:0G endstream endobj 8 0 obj 1157 endobj 9 0 obj << /Length 10 0 R /Filter /FlateDecode /Type /XObject /Subtype /Image /Width 1024 /Height 1139 /ColorSpace /DeviceRGB /BitsPerComponent 8 /SMask 7 0 R >> stream xw[y}M'pgpIQEDQ<$jؒiٖ%˪cC$۱!*imIx5mҸ}Ѭ6Zyw Jϋ@8s{c-L`ŊZ ^jb-{CM͚5a^˗ZJ,j0|oYG?HC jA K+Wr7Xfmh9 UUUZ`|Z,xE)|Ԙ@X|ի< .h9"7Ҵ D?0?8X" @x}QDDDrr3=,J`F#0KhWZŔR|oYG?+{5kPK`n,_|ժUZy!_㵜߭ZR 9ic Dw0VXM%eʕZ`)k9/`5BῪJ̵mW_nK0!=> 8O0{hDKn07}9$`'*0`10"C?Xb7\P_f %0^ddr7d& )_pAnQ0{X"8 XR0-,_|ժUZ`1c0|o98fjKNN!fxr+W`X``SINNx$̭ǣ|oYG?$ X"׬YC , ?zSXre\\! oa)655i9h~ i,;̥ldzjժCc>_ܵks-_|Zu iiiZuX%nV_4(YL?>>^sG?X|ի X Ҵ Hϧ?3; .h9@0{,,EFFfee+V@+fzj[[ۚ5k{[bu ,qtNxgw,M6+sXʘmX@VX$wWgL )YIJ ,V6 ,6,soWr7VX1ߛL|Z,Q iiiZ5k(  Yht=`imXR.*膁'|r}~8fJzWZ;KNN!Xx,\2...&&fȹyGz9~㵜' x<''""e97ɞ~էp8YV\э c .K{gl}"0z!+8te]l ̣82 |Xc(;%S:N6ˆE{Cvwvv666jlJː):h8ϧ,Z".$$$mm!<))Irɪhrrr8\, SӃz?|8^md?9\@%A'rBBBdd48N=V5++k}}t׷߾}^xwΝ;򢢢e~\ϧ+))}SSS-l)nҳ) q6^o׳3j:!?.{T=V.//W) i>[D5 asEIRB޺uu \rω]S\\@v[o]}Qx_TTT[[;220Aٳg߾}ҥKׯ_YYY.^y>}ZM\@=fGGǕ+WhKгhz{{[[[*&z. P5R);4a#_0DMe]=Bbb5>;'*+N&]P}@@!gs"КկnuzÇ?x7|zzرc'Nyʇ^_VVTWWgv6XO' ]zC9;NIH]K}l ,#t~[rRuR!Gee`Z=zmmmΝ|Ν;ϟ??22*h}ܬ`BСC?z'Oj{~_cǎM6)**9dxwN..NVk5G844Fuv>ѡtҽSkU#oZ^tcV(qINFp/&׮o&(]Zj8 ? Y\۩Ggz>W_}wϝ; ;-6 Un&PW=򡷷W1z69Mʬ\4uU Iо[Xt1*'ƕ^]?/]400j ɺW\ٱcǍ7fµBXP,mꊻJZG7)TٳGX#jmsjKAAAHy\csYkQYzA{IuY[ms~=>W.KSo|pu8z+JJJT 9t&Hw!_ڼy[._~߿w'Wj}eZk utNݚ& 8,MGYbڵk|ͫW*i[֭ MMM۶m.kהGFFN>qFZ^NVqTeª|FFoݐgkO.d?بNe,o&k1tHnݚ?C۝'fjz]ZGAQmmm|zL᪛GGGꫛ7oڹ *#Z*.RRRjjjl٢ "aoETT ]@{`2Kjx*2Ҧ;;;~T1FUΎKW*[*ovܩ~_~YVP`gl,J\ʟIxCOu, * C6M* XH{bџNɓ>B믿~9WU|uwwݻWEO~A=Ds=A0 y`?&cM3f&o7ʊ[n2A ׮];tB @)7!!𬫫SEr@)WlXk'ZWRTb;ZeO4<}7af|\wDׯMX(p:AUhǎM=m{GJ`N UqH!\7͡C~auu2b HNNްaû{~֬ijjum`jQ3˺+w; $66F }?KKPh&lapu֭[쳲aexm}?;::/axxK^~=Uy-leVѴ 'ry!hZ:A)-gJRRRZZ򛲽"e>7o=z늅.]RmooWsss kkkmR]㜫r3Bz l\Ň>fyI;xg}V\o;j5;b|VߴSϕNC'&&*y}>mmm$^ػw={l!mP+VUT.zvG@AD* m*;/s=ЎX`:(M8Z'En庫W^|ȑ#?uTssTWM۶mJZE֭Z꾩zE!YU9hY Z9cߌ?_ujS9BC8=U vPWWk׮>_vYYYJn߷Al*1}xt+ 0!'ZYņQlSW/((Vη;'|xÆ Z3==KK>zm"]i-0<1s1c|gG4gGLְ$&&nܸ1//Oi_t~Ƥ ?>ddd8p@k;w75xY8]r*h2(0EC-&dWSxS;sLyyY{{j`uuT:(544qtG5U z;wܸqC%ӵFGbQ6zOqwc?^.[6sӏHWTTi:w}jkkUܾ}Q'?dJ---O+lXܜ,ĮnZ[ouAE<Ǐ_vmdddhh8%3nu֫܉s4Έ9emg* ^wӦM?O\b}$ljjR!peNRYYU Pףl j?|țn9R\uuی NMIIR9y7>}UZOJJz@cAP#!Qtew v]g&z _ٞ={TT:uJѳgϪTy'$;8) j<,VN먍{N%+ku ;::󻺺:;;;::} ]aݺuTXx6S ];Hѫ599Yy^רR4H^6Ҕ8#9#Sxmvر_~?{{۷ogپ}>*<á C fۄg\<|럯_XX8::j]cbbg{*kkkKKKGFFvQ__Ԥ(+YC%"rb,dϳ*6O_YYYQQr1?+)D)+eddR uuu6C 4uD6'Szӕ"O>6ЇN O8qDWWWfff}鏃{ &>`M|na T*~uuŋ?رc:c;-DGGOۧ9DDe0:os¯.&}z+**gݺuҥKwe488aÆ-[XXN2 vرuuuϟxwkjj&륯5U6ӄq=BYPϖ6߸qcdd$1110Tz簩A9^z_}oy5LIHHGYb:0n-X@&.֞nG}ݺu Q *++o[Rj:A~F?/p႖!& i2))޽{J/CJKKUttt޿eee]]]Go]i)07,YL `$*Wgddlܸ&33S?++͛JUPPzWt ilW:;/[5GgOR>xΝ;_R>ٳe˖#G :uJ˽{$$$ їb}> 0&EXtrօReFE}e$\%rU(>L?LED@[g1z裏m }P=>/~_Fx竫m } 6XRRR\\4O韉mkY,g-z˥e^^ަM~AJwT4JHH͊9p[_Hl |,驯ojjRo=ڪV܆R٩:FNg$.GLjZSQQ(SBC{{{[ZZ_WW̯Pҽ,SMa0T־111%%%www'Nؾ}Ν;kjj***l;@? 6eE>N埨(U H@ os=gelPzՉR&}b> |cǎo߾pSO=*~zg_ԤC}6| ((+(OJJ. vnjէ(++mf%-k|}2UcϼB@E>xڵKuqKK˽{޽gK۷oONN{.oܸt|ULs|8;VW*(766_3gl٢oTֵk8v2|9˝/vvw:ӞO{M6K 7nҭ5557o^~ )xt k,|ULFwN:UXX$wU񾭭͛~* i"16Nqq 8<d0U[κcoJ`|`4V)]UUKooPU2 bţ.L@&`ޕ^rrrT`gFGGjjj/b֭>Z?ZAT>(L֞iO'i~a%x _lOv΋)wW^y6nܨBz Z W"Ç׮]🟟֦R__3<~z lcccy"(k9/m=I%+?R%uVGGM7l}Ν;wZD|~tzjǏ?sW\y ?_1IIIzzdֹr)c|߾}eeeStqqKUnϗ,xS-[rTT@4؞]"0W&%%EKV,TWW+?oiiїfrbO+,n ?.Ο!SYc۷_rmmm 7oNHHy?4[]0f3C1? P.>|Xut{{_|qΝǏ[*  %mޫRyꩧ;?::Z 333**j3Ͷ6?(h9r$''0#?VWlTWKOOMliiQ1nwa(`dxk;kWJkkkϞ=ӧU?ɓ6uC4Cf-ж08{?틙tV]T{:!V!â*766ZP(..)--mjj:vXKKKvv%%% o,D og{2~.sP_F}I.\2}ӓ ㇚WEEEo;QQQqΝݺuKK%a1O04x_뜜8}U}\.['//ﭷzWbbb=R7Gg;11QI>Z!++ݻ/Unll,//6'MJJzi"yfPV׷2..N_^]U8]DR>~R_F]r^Y>?zq ,8̓ '!!!66lϞ=;w... I0S 03l͚5yyy֡N?8;v&~jjVS!6::/`v _Xsrr^{;v:th``w]vJbO`MȝV}}l٢j]eUy)))c/,mxFƍ6lXn.ݻwކ#G޽[(T8 .< )WUn~U*ۼ۪2F"GEA ++KjgB^ n{߾}~3</_VE]SS3<<|bhuQ/++s\4^G7WV]_YYr'!!>?dzjaa.;֌{=;շR̨əɣDMe'?ϻuS^^^☈ o]+KKKm Bp'N|>`łjes >uSfkqݍEc}Rȑ# kOj'Ą 300T؟RUU lBEpn9Tp႖!# iY;;;Uj`ڵ6yuui<>3RP*(..>x͛~yD`<Ϭ=zT%{7BߦW-++5Ya]rt@Б&ݾ}޽{GFFO~|^xjjjt}0۬6#Grrr~lϦ&I0..N׫.Cvv-[xj9c?|v.[%|}8}JW:uʕ+*U1t`APPpNq?bcc3|>{ݻ~_ JAG~֎w1:S9f?+} ث QQQvgee)iiiZ%%%*ep(_t͛oԱ^΂ -;::gRP0KSۮ@7lg}333U_r7nBTOMMUOOO/**ڹsgyyyCCPcco:07ٸ@999Ψ-hU^XXޞgϞ?R?~`_ӧO~ر%Je?/??KY3!Ȝ8JGxmfOeFWWWWVV8t &&&nٲEGs`z@ncjai_!W>}:777;;;55rigbcO] ˚5kt\V `~Ϩؘ1%%%###퍍JGA8 x#[EyCiGꊋuY;GjjjR0ӯL&f---:^ggg={Vk|!bx`H36]nv۷OW55Gvڗ_~yС߯ MMM񱱱UGjuX3fOQ zPonnNNNo%,BWWW ޶mJ+7lag1V\`_QQnݺӧO5556RM]iҚAñK} I+|>}:%222׮][ZZx6m[oٳGeA}OG5EW耛yܹܽ{W%ѣGjB{,5_˪l+?5@o߾7닏W PPP݈s610?-}ƍ?_~nd&/`=^Jﱱګh3~]̟asZ*JJJv,FFF\=>O};-x }Qtt?%%%Byyy]oC L#h(+x=ͻlo:uɓyyy6mR B@Ga;;FXRw)4YV_>ZU۷oΝ;ǟZ*11q/aՁ%.cܬ=ݾ@ p2A0ӡ_QQ~>|UU@AAA^^v8nrZU ,̯* ##C,۝}8p`ǎבJGL700Ϝ97 N`QaA@ TSSSIIj;_Iii%0k޾{Hgk9Siwzꘘ~ww~~~iiiSZ,j-zzzlO!A7O 3==ҥK}4:+/ ;]6!!!--gΜ9r䈮_KJJ[1&8xPsP0 Al _m^`@qu9K8RC@ vcccXYYhJJ׭No3r,fPΰ~իZ r@v3IC9r%%%X}[ny<kgFxD@?Gb3(8p`ppp߾}ڹY_Gg^&爈0lI}>b|||aa]***RSSڬXq3^\befdjo@[iBk디k 6iٲeKMMM v{WZZjg0 tiΚ-GFFnJi?==}ݺuYYYoV}ѬYa|Ʈڼ͛7:u_VceBBBvv t+q/ &YzvbbbZ[[wرiӦ¸Dkb`dQ?d4liN L˒X: 4x$nYQʦt˕qƪb촦xn(oܸ[oμN[.@Z.x scbb322S otvv;ڛŅaM5yv޽iӦ׿7o>zĆr7e<dž5S}֬Yxюu555iZ+ ZJĞ>O?ꫯt@LOOONN)ISdd Ię@@BBBNNN~~~CCۇ322lpvkENݶm޽{@EE29"+ .\r7xg8PKiꫯ^++ , z=OjjjTTM=4O@///OKKNHHP9`?w:CpSmbzzGFF~[[ۆ ߟg%, u}TT5h8JׯOII^1cJkа b01~亐klhkuv777+o...ɿQ&d~I CwкGDDx_zf5Q)oVs\w}wcNA!@9wd`@p8"xؘڑ_W߯rtr wZM;jٹy漼<E?`28pG%;lv700BJh +j&eźƪ9#`j*m!_B猈HKK+--{=|7#~'D $W^z111 Z_SA3 _1e/\O_xnC^X\YS7(kݠvEEE1fggoܸv[??\Hի;;;{ڵҨng.";6piin3//ڤ`)))+= f򍉉.))o>ógϞL:TuhQl۶m/G}K/f+Ӻd-{CCv?00Ғz`@3ݢl[nݼy5;;[5ˬjUpfx Y hZEEšCJJJ ;`_\\lfk۶mҲe˖=st"C_lK.8p^wc63痮IMMMOO|mmm:%$$踦5`A-֮]k:&+VHNNq~Qܽ{wVV ۭ2) sFӖ0o&%%|g޴iSff&-𨜑B$l"Kt*((8zo~T9`2?<3e5k`߯)?„RSv].۰a޽{ʼn0 UUUZjY^^k}'v튋M鐴m۶SN䴶޽ƍ555 N7'jDHettt ڵFEEcikVZx zzz~޺u륗^? ^WUhefL=ۚ1n;++">>v: -)srrt\reRR҆ ysDEEMO#k-**S533g-,,L ֭T,DbI~IOO~|h]*222޽aÆ[677744466FHIIh)œ<^z۷={/>44rƷ;{K]Ю]]]XRRR~~.//Y0l.݄"""m_Kvڥ#Q hooH3sgF=tkƖ]vhhH{ZUK;w*rzz߸q~xر}߿?##cʕV&0~z{Su\Th79 XDgʒ̢Htlx{?~뭷:|Pg 8-֭[ɓ*WX Δ%!Eq*&&uϞ=MMM^75{N+LO%ZvݻwiH1f 0hǼp~t;ʸ-uذaC ۵kۃDp[Grr}MJJUWO(::ZپkLsssnnnZZZiiiVVׯuӧ QꑑQQQ{Ԍcǎ'&&*9rd``੧t_|q;vcPL1˵7vUS߷oߡC[TT 6Y؂[鵌Qc۶mikkS&g|k?Hx<>/'',###***)))..η'YYYJwܹv Lzٔ'OnwdddJJΝ;u&`O xBN+ @#4===:_'%%EEEٹLk?K,GDDdee555"vZ6>|o)`asP Ғ#@fVZZz֭‚/$|kkkk?.33466\0Fd+III999))) %$$477J&%eӁ_T;JKKAG <::z^43LbM?˪ jjjtL f %k6ĝimw={dffMgqK'tJ.+::FijOTOKKr60f#۱#""Bʂ+WI0 -˻wV!ky@ T <ɯRv.Z}阒🝝k&;`9byuԦM?UZZ%:vXMM3)0 olo+u떒QQ¿J3D||GGG}ݪ*}}`ۣJzuK ,:pruvv8qbdd駟Ƞ‡lF뒒n+K*_rrrׯ_o&%%1 kQ.:--߻woaa!vPNG_?C^o}}}KK힯9Y5kh]۰aÑ#GFFF###C &$99yΝ/RFFիudхRMZl+**R?|?Ǐkr~~~~NNNeergbb."`p9z۷o_}ճg>3F*cgHXRy]v̙TgXZFFF*3)$grzz|v ѶǶ[-l٢|ܱJyyy{{7xcӦM63Ą 6f[Șo~m ԭ[vttxފ m(:v>M"F?,):(DFFť߿֭[ovgg㱖;DJs&dίNM Yo>|a:gܚ=(q@8uPhll,++KMM-((ꪮB 65k9KtCnMHH~pJe$c¿vabg!@K.577gddܺukݺrY+h,e?*wwwWWWk^^^r`ppp˖-===:,=[0?11QÇoRRRlcG{̼3gir ;;jlKsӞC{0lƙoϼ 7l111D²;w0aSyjjbwLQQQiii~~nX9ؘ}}G^TYsJs@Y 4d;ڍNv=v,gxgz T%sqQI⦅}PSSX/+Wug7~MR>SmH/A-v\])ՙUH?~Ǐ@KӮ:zjC? J?::gө ~/ 6# l;Mccc:62bv]ʉ^aA >Z*L&vNEP(t?WR9rW_Wہv QT555U *uK K[2F.sԄ\% FIl^Wf6 'EM}zt:[!?lK8Ky"W)m6[0?/K>?533믇e3G@b~kxTOHZUlm%\.P(LNNvtt8qbjjpȟxϗN)m4~Dx`+$Nn#r={8p@>_w d0r?'"T ‘#GĢ#(2-j`߾}͑HDm~Bo^iO$[_|q]Zƫ!\)`kP W~_?BjhpEU<=qD.9K'~?X,>0S===DBtP:Sm/_Jx _)t:R|>?;;+#Ǯ2TvaXh4\f*>N r`[/^v}ioS}`R[Iolltɓ'_~zknn.3*xԩSXLv+VVk:r 24X—^l￿tR6t`%|UNC@u*)WuС#G466J"hooExNxA h4zܹӧOOt޽T*xo@`?Izg2Fn{dd믿~O?wRfJsG@ @ H$B*@MGnuvxxѣ]]]}}}sssTJ~@2?6^wtt^۷o_]]عsht\Re-r2޽;11!6\|]@ńuD;z$ԇB!Ϝ97߼KHD﫲1hH\c=%|o~{l6t:e@nz_Ç=w;vra<6bFb b^P X,+mE-NtSSDu BAYvJVj%jO)%#HjOFGG%kfl^jD"133Ң^ m`ZQV:S~ ՍHP="\6@EX,]]]nojjr8 `^T1w[Nʕ+8CѸhR(n&*G,KZZZ|86  c]yru8h)Kڧ<5)e-r?&mZ({zzd !}Bז0&mi_VuΝ;_xᅳg^x1ZB`]PkṒp  L'OI`zR dL FU#jn>ꫯƆ\.Z2V'f%Uz>XM,ØW----rtRWWׁ$qtCfo?Hڵk{r 8 =ٞjH d2333;77JTb35[Thii???{EQ%}I` z\Mϟ:vW_}u ϧsb5[Ɏ;fs]]/<<<,ydjjnkJ8ʡd^ԩS~;w>hTJ@5Ց3L F8N͖fU_xH$ܸn"6Te7_: F|r366z%H֐Q@S嵨/a`0H/Z2`&T5%Mf)Upݻw'Ij DS:V [[[sDr ,|Dfgg?ӁժU_[[+# w___sss.Kuoӓ:6!PҥK~x/=5P.x?7P;>[?E6h/Ξ=ߟH$VqTE:̷FJ.Z%~{{oyС{aX b8o){{{~|hXzΟn@ALbp8B2>$@>D.kii ~\[[+mڦM\קl&-^wRIL& -X4K_b6vg2P(t{-(#\%8Ndwww6- r-rUK.+ͮ]Wk_ B]|^B"d2ǎ `-[,̣2 X49sʩDRԫzG={6=ݶufvou:PHo:;;o߾}}I.{|Ov4`iUTcccjoccĄ2(P3b^B4`T~?b|>'YF*5b44406{D jZg'a0O:%H,r䤌f!NWjJ}zfIXjL&|Jϟed;66p8T+Irh$b/Z{St,~0???33377fSԲ; Ut:)}>TjӹP(nZr?&l뾻honnO~?:;;ܹke?nC䪒:ea P鞥6d+}&wމ'z{{[ZZ B*bOt/zj[n޼)Cx<.-cFU͖? l=?ӓf^}`&|>ƶn~~sNTlB}}}ߟ \>0`r`D"@ HͣG>á`0H @YTC񿈌,?99Y($ ocW6ghBRL&2 덍*Hrx_ {2@{dr2PIv]Mmmm/^5mn߾-r?Hh۲I/544 \Nfj#226z#ȉ'&''etX__/ټN˫bϞ=J$\\ A[u v,TOh4zƍX/Ng6wp8*VHd``@|GGG՞p KK8붅g4].ࠤ$uL6촩fY, ϟ?W_ۿŋc<ۥrNsهYSF2K2{ #HJRMP6$Ǝ.8p3g˯zR ՙ+U) ~Hb2Pm OsѸlT, x EzĉuuuVF*ǾxNjdR4$u"NСCbqKJn~Ið^7@YΏNSet:vfeg'WiCC[^_[[+N[ci2쟞sԔ2$h#ϝ!U* Dt}~reY.)2W͢8x<r/6˱4E%F"cccjR__oX x KRzFn2( [zj0$JhP9x^ FMO|`h{,wuuIϞ=;77wʕYϷ荭v2{5,brtX `0HSSS;::L&Ӣs,:QDz$H$|SX_{d2.\ؽ{pOOO8Vm2l6s<$˗/ȗ~:S}].իW~2 <88(AX2ϛv`ZP(b1'J>?fHDrNS|ƍ/xx8|N{zzFFF UXeҾNS}_[g)%ܹSx6[J)o߾}̙HJlFQG4X uײ)5: ?Hlmm_}w,*)VpXG~g*I/kd*|k޽nsniR'_l6922r^Rғ$,uX VL%Wi&>s BAKeTVfbX__חL&:f3?<;Xƍ|Mkkk4_#GA(aUpHr\.FS,#aVjggg\cz^H&ViaN$ IC?%=LH$r|>J(ӱX,mmmr300P(jjj-j  *'#ZdN^(`d< ꝯfhTnj~f0"䠥4].WMMle"sN8.VcIp87226xނ/<99iX}KPmmm*_n۷ːA`S(*UWl2z:U_5Ԓx< ':l%ݻ 2 HR`?Ţf%r_/^zR[i`!jl%\$2ض$6c|#˗3DO>ܹsayPK?&*Kgsssrpz VUno}3gΌ:ҘIFc*yd247UHʕVÂ肆ƾ>  \2z2Lmm-`$fz<\.gXo.~2t2 p:&h4ʸ@L(/X,@@2T<̥Vq<wܑ!zff6;H/@%| d ŴZ&r?T:vܫ$Q*~m?6V౤s\L5 *jUYV|}}=~*f`_K@]l6ES2|v]Km+m `sYLSX}.Ut:{zzCBQmmT}ݿ˿(rijl.R߾}[~-b2^-iX< . vUAT2NDΝ;711fhTMm^Ao(H$ԎZr\ ݪ .^R'6O"ߴ@ROLLdP(d6_4ph'K - rUl_=p`H RܹSF:nTtm{sM |,+VA~;w.^888xĉ醆іI[Yi_PJzX4}7⋿|IXT~d`ZlշP!VToCF`pddDjOmi ԮGMӃ_}թS|>b_2pei[GuW 0B%xH@STx<^ *vTdH$p8r2LPCEo+wK.y^9ο/U,2Tle6O&NS?$SX(JK^^%fUiXxN4Fc<?y:n˗j_Ա~K3 6UU$j}iIy%ԓJBd+հFoƾ}J'l U /MǏExz(B ,YݻwttO߼ys20 e|N،$: Fd2-[s"`,Zկܺu_a8.s&USS300;HS UtF\\ݽ:TF0=O___*ڵkN[g`,K"_MgX_^Wx\)X;N訄U~l# P崒~׮]/ݻxd2OLL8N*ز2]=@ \xqft:m0`0HԩS_uWWW8Vܜ\(ESzzu\n{||\VSSvN[z^`Y3kkk[[[/f2] b1R̙37nώ;dPʢNQ\iVdjnn9~Z 4  y2RLm J%mI/l6f˾ B=~߾}X`00;v쐜*{{ϟ??00xxO @p8zO:7oL&Hj.ZKa$gr9YwȷlD[[P6 =Kq Νvڙ3gBxbToXT!)O&7fY2 Rԁ$2>-TұHH$v{{{͛7J|UKJ{ؒp8{555566F"_6*1p20H].f Bj;e~U5,$Ax>$p@S..TMu:bZnԩSTEq^әf޽gI, BTJ*)WRkaZ KRR*Ug,ӧO.hooZOY& xvR~fs(Y`X$m9/}v&_XŲ3???K][۳`]n`P>r+()Nm#16 b(#mt:庖Ez?m6[GG?77'iS,^ U9rH$i)-/ƪW,:,K,DRpMMM OJN|[o/E-NX,q i +pB:vOa5T3ɴo߾^JRZ-q`nifd4|PQ /033ËxR,ׯr9m!lmѻ.K6Ke`ZΟ?dVMeرl67W^ ZϿtͯniC {)z/wͻH$e*%zde4nw"hkkf2:3<)Zʽ`P A ~:@r8ccc.\( 2Ogffܹe\m[km })ndRoQ&r:vܙx Ho\.nP(Lʠ`bb"sjmB*fslGGTAH|:IIh4Emڡh4ʍIdjϊ;v%Pvn/}KK\^{ۓ'O&I۽ԧ,W C}}Ço޼y96_J26 kѓIIjo 9vXCCl֎,k*!Ym&ſnOӵ++D/%[6b+7چ?kXɲqUh4Z,)P(L& ]*HjH$n{ddd||< $R 9rA`1%INݫtVk__DxӧOˇ??tNMMy<( ߵknIO}}}tzhh(!wttȏѳR(@T={={Ԛ_^K {PR{^ |>h4*_J2L8 YZK j;t:vQ`èοc_ՕfP($JARRq/զj'O˦&)e8P,$6rݶ0_|>?;;+WDc ?,RWj<~ X>d`#%rbrV܏ J>9 hܘL:'Q7Kezױ.iHM/ᘞ9~^i[ٶo1Rb1tuuiu *=,k3H|Wod2z~@eIxZ^W R;Ύ7|UjkkeDP__/C_SS~:`0HqgϞO OAC*!4xb zJt:%t;wK.xD"!r?#l)*׮]kmm@.;p:l}#h-f-Q֎@RG"FjfZ`0xxcǎЭ-`d2944-KcccgggwwO[fV"p]]l}}Ъ۷K2uk׮Ђt:foݺuݑp/<'RY@RE `P24p\2j vKpt X,xNԏ,ؽ{c8w^ݮx:*H988(Cd2dN>Ř} l6K\NnڇA f`+]$IRgΜ9|_QΠu'uux<ꫯNNN&I jkPf`Vm"5Tl,K$@@2Qz4`0$J(6Z?<-G߻wo[[ŋ!O 7 jktz}>:KdoV,4ω*z܁ƕNldhxvZ6tfYr &''[[[kjjtW~n7?^zT0wd2r9ApڵK%rF[{%JꚟtzxxXԲ^ ֮$ETe&RlN6Ag\28xx)o2^RP{d2w/ʷs"W3 l6Kv!:xq-;^6  I4*{<`0(iH%[VLb&X¯|̫,zB*8} cǎ>|XnFL&s D}HRАèSTyJOX;5eb444H??f2((m߾]jx:66vٖ ]]]j6l6m޽24SI Fᐛd2r` )sN?00077DH4aԑ+rݾ}t / gZ U p8, R$t:)҆Ţէz%c/Kީ $#\pAmؒ$߾}[>;߿_?i<dfh$:Ze7-& 166&IALXld_Jzkkk%H21::*7N3N3*%9F"|>oV8Ҧ!|T*U__- V+0u:ՁXƍ}}}uuu厃nnN^L&I..+$I\GNhO gͦ+*\Gɇbqpp… j*-{Xvl6#X X -ehm}>TY$H/H$HFG".px||E$K /*x\nADVk"?NˈM>)#@USR>|8Iܖ(=<<ޮ^e`0H*y뭷d K(; %J )^nU"۷˸JڵӧOaI7Y^*d2y͟'_~}(ѣkY z*}I.h>N_pÇ2ؘl$UI+,t:bٹsOVSS300_oݺd vZz5,ذ/~,|||ll^D" `ʕ+r-o^[[*Cm cB'Nx'OT"a_#h'tJl]]]ׯ_-&"r@kjj?x۷%PiV^"KXn[&&&d8nPF:6;vǏQJCCDub5`YRXV-̢e`6[[[_=zL&yS E"햚۷ottTFX+=շ_7Mww| 1 J#l6vǒLk.@ `듓; _gHpѨEiz7.+T"5ffBA~]F<#k^__^bt:Fk5@`8Ш`2?p3 JFٳge,H ubx 8rȡCW'I&OEQ%~8o'O>|NTN'E#NKbt\쪆>_rd+Wܽ{W_M&24 w@%(}{b2:;;ǻgff٬p^m!S)\OTI$oqF[[[KK{XO Ů^z޽wFQjJ-KV3El>w8jP&@X6 z گڃ%ȫ?nTI҄T*F~)U`d'|K/ `d29: ſhժFh-B^~_"ܨ]7!8l6R_S{GK1((Z"y:D"R@@>a0T4`PPGƨd, s~<|D>x<+!D{&Uj(T,m\Z7cbb… > ^%˵ x k_Dt:mZvc8e N3NNN^zG`Zf>I z^~3F#-At:)`WWW(Q\I=u/d2-F@~>Od3*jx\ rDsk׮r?&lzkn\.'uZ[:(u||\nUs7-}'OJokkx0xvi*S_:Tr$_$ ,iPTҖ! ogffdpT*[Y`6o]4n b1P@[fl H$x@CCCooDx5A^kP|kkkccjmPKwlo9 >O˕[J^bZ^C: X~>˷n^/cVe`nۓd__fSKTTWr=6`,򾷷X,Lҟ"CI'OG NRKR @M ]:Ee|H扊v^7557ob B:l6K m8X*ڋvŒL&[ZZ.]|rPH$n{Νk=*`-Gxx@B0 ~Od*Ӯ] Ƚ:#d29N_ <9sDP_z| <edRl޵\.7==-?l%ˆt^ %b|>:66vu:V/{|<`?Ndp8<>>.c"X+u:9‚>h``t6)ɛ{^&_&枞ZW_rw;{BAMUCl6޹s/loolwdoFj@ 0<<,ŋͪؒN4O?WpiOI1#*ʳl)`0t::::=*l6[SS 3`fS%KhjjD"=%)[ZZo#ցDp8|/׿_FM&S}}z+E~ؘf~li B`^hη~g?YWW(:R;/ݻVC J-6MH$FFFbh4 T,VyF~_}޽&**⿻t:#T T2x$K.hlllhhz555e-zŎ=d$򷴴ȠF5zƝl6K?w\Xtuuu&()tEet:)>55u 3T!۳gOWWW.3~(:0LRA !555~;3>>n٘] F~MM~JNcS،m$[V~"H6M$Nh4T!)%SdbH\ vXj ãѨp)Fc0ahgJ4144ѣ>e0 8X,HDnl6455yT*%3z}u'%zwuu]~}߾}pt6X(Ӓ`WB!i][[u'IA%kLd2  *XE8~@n$XCJsGu>T_mcXZ[[vZz]8T~J1O]ߪ_(վNxd 6]%l< lKZW:;;1JgV Rs$<))_~eϟz5mmxtZ,aFEg8UBBh4 z^j'O~oooWſ\^r=\.w%./"\}'l.$aP(|{q2.^>cjS*ar. Ο??<<\,SاUE-Zdۻwt\>/w~Xd`Bzm%8HpV lV6 Ш#lnjjjnn>vد~o/KI(A݄?R/m6 Buuummmt&o-Kܹӽh4Ju-hzz&lP9R_NfbSSS>OV?`Yo0ג|2??_(Ԡ`Ucn,վ\Kmmmnjjj BT5KՕN~PFs rVt<ORGI&zO k)%a+d||BHlnL&b"Ç%zOOO;r?&־d{zz?˗/߷o_ff #E?`XÞC):(wtt@` `¿.{zzKJJҜtW0 ;5{…]veffgNoڠ 'O MJJ8w=vLRp* ***'''11QG]Y&==}@QP. c2>ff,++;|cZZZCev1|tP(p\)))EEESV`D?[ӟz7|СCp`Z_+^w =fd~v"ڝjgx222+WjHe'YiLG찰0>8;FZbޠA.+>>~ӦMOnnnnllԥmNT{e3Eutt Ӊ>Wd $$$)))55G{sܹ }tL w}^[ +8qBw cbbUEfgg+FFFj.E5B~~>jٻj#p㑖tY+ ICf{](99Y۔v]FU6#MȢݯ+X27W*++mOzzz0t0ґXc 7eC}jgUPPp\\\mmǵz :- c0V{<| : d@uu͛鬬T˥tF Svڋ> igWE;a]Eu:+ɻʜlzzB%c=vq׫9T}PSLz-QTu&ogΜ TddbmmVNմ&'KT{ԁӧO~ LsWËunݺu)))YYYQQQ:P4i`Ziyyy[[vgZ*w&߹twNHH(;COk`wO˕a&Ƣt]7hʚ?HHPNڸqe?d+f^?~D~qqqJiii WBTbG%EŋGR!`8Ss0i8_7*kϙh"gddTWW4؅;6 :r8p@G1~ 5>޲0""vi/ٹft*#TeeeiiJ׫+vo?Gk* ;/nTlذ`~'] S/..V򯪪JLLԁlh,4awUGGGfgg?~ՎrtKOOzGkZ_FFF*'''j]x}©|/ASGĢx@Ǿ#G*'$$45vlLLxG{Bߓ!pkB~v3@ǻ'x^hhhx<:feegG#( BP,-ZHo)l1n.]etMOO i0ik:[nx<9 [3i 6e566ǎnhh8ydWWWoooqqA:P2((i+ڿiWRRRRXX;'ӋMk? o;vسgOyyyTT3%Dӑ~thuEČBu劏Womm.@: vuu)4бrᯭ=Lqډ544XþZ!!!^WWc{{9tPZZڼAt9+rškz< 6&%%EFFqS{F #и8~gz/z饗';JLM;!o:D&$$O᝝: . i0 M^u%66aΝ6… u|B`:b)/Y977WŬDvg6[Gk޷vqk֬ٶml31Df$TGÊ+W}ݩ6Jvi08~?i&׷~9מ,aGA;wܲe˗|uL2_|*N0ǂ5nٙM ڭ566ZSFQQFɳ+++oܸqwi7^766VT 0wbOKOO_zvY}j lc`mƍ7fddЩ_XXѡCnQE0oPLqu njjR c]MKKӑTw9Z帼mh<7^P6ObbbYYr~RRJrz6@:qLݭ*`͚5---:V&$$,[,>>^&kJJJ;iT[[[PP˥K*g z Hڕ۷oSIOOWץ`sOiiC_TCbb" *l0…YYYSܹsw.//w\X5ܹs#"" tU-kgff꺎ι}``СCZWoZO=w JJJ^,11QuL]κ.Zn˖-GaT\pm;~Czm3$y%lB222nwaa`N3 ȪdzdɒKؚ*@Yqđ8/k|@;<,BfmUT> S,333>g^)3_MYbt%99y޽>vM? 26]{Eǎ: ĚՃt#)avYsE۶m۳gObb"{$jmR%@JJѣG;::un: s]Pttt||E  r)K/mٲ>22L(yft%&&,--M{*Gkv|;JllMII9u@zzz UcC3i/ؿgϞ˗/_~]i_;%K%&&*wtteZpķ枚P^^f͚U h{h;LOЀB/|’W^]QQx2337nܨݑvP~f;e@]7* #GaM_ 63v߈fC.@t4%%źnJ;"gߢ🔔tgN3DhѢ{駟!x v`PLLx$ >.3j|+@nѥLMMվMNcdI?fhgZ{ \.sݢ6/Xtt:GEEKnד99ٯLkwtȮihh& ]p[t_ +~\9) CBBrss׭[}HddݿҥKV\4o~afgq`J֯_{n|gl1ȱ6.+c޽{=S[[חۻm рC91w&_瓒m0l4Q^sFN @p)<6ՈYYY\tIb: #õO|HO G``PKݵx℄T @N^=*11ўgoE04a$|`rj(_w2猡9_t; m=M٣ú*))a]ߩlU 6ϰ,'Xuuu ӄ4\4]] 7]KtK^^vCLpt4!^QRGy&Xxۭ@lϷ2AP\\wB(+3 'NnhhUߴiSOOv%%%۶mKMMCПo!B!z涷벪jҥ6/@AAl*}B+|0 o]m~p}n555/),,;[[[ngh0Ѵzaaami*dTF9sfʕ˖-O6@P1p(NmA}TXo͛ p^D~]G"AFFƹs֯_ѡ`9߆Tfp]._SxP1la$Gg~'KIIYn竒oqvvvCCî]ޒ^naE,=0==iɒ%555Q  ˺n׫y@o3O5zuQEJWW/**'?7n/׷ LG Taaa svvv8!AuuuK CBB1l6۴XUFaDxgrrɓ'Ϟ=/r|||CCÛoo_x155պ rikzdd} +WR!;wlooWHb7oꪬPT(&&F_cǎZ*??_p p2H!..nڵ z˕T#زe˺uJKKu6>Ehګ[\OF}[d^}srrnחN}~ssٳgWZo~… iii6ODFF bk3=:ㅅ~#""E77))v,]4>>^7zrrf߅r $V\~=55U’os]}Ol(r`؟\ _:?`LϘFD8[OW^^9H)oy:bhdB6# T֣?bY/>*t|~QQQnwxY*`L3lh,77woܸx RPbn[IC $44TïC ?v#Map *)WWW'%%ٗkǎ{o'''*F2S;T(iXW%C-YD1Ci?77W7Zzihhعswީ  a0/f|[mxOzk:Z멜[bN;?`EJ!H(~Px< 3..Nꌌ K#~Mu%v]U  7ȷ!o0 N "lD]WHJJ/**Ruj*k*WǪ@SR -t8H.^qƮ.G_\v~bbnS}}7r630Q(WYWi˖-===EU@EEEgg D=JQХ*wygNNuG[ 52պuf[1 x.K_I}zuք^WWzv"3lB6&KMMݿ+rر˗/MMM v~J =Kֶ9lcEǽ~JOjic'貥eӦM*))Q1x{ҥJ6d-i~gp 3rOk|t鷀b|WWWiiiss?aÆ:U޸qALz*esP,;=ٔj1u~ kS_T+oݺU;ݒ^XXڪZ@_:;1Go˗ky}㜗QdaönLKK-**ReyyʁݻwYF#66VAE $֥z4,?*:]xmn[_cc-YDJ얖۷{wԩӧOݻB/˥o=/^_y啧zJ>5 9hוd*++W^…˗9s[|p>|ɓ6IqqWV a,0['[nUWF_=*ׯ_o١Cկs=* ΎLth$sB%XROHHn[%MzzzJKK;::N:믯XB)%//*豺◇rʰߴPw>KӘ6ZEA /ECCC=RZ#}M bbbߞo3oг x1LyHiuiW\9t?H (sm |1iƺ!UJ+;vٳ>m-]233;;;UUC73}Tk  kW~|W(+(@zxddd]]ݒ%KN8KvtaFKg$Ϥt/ݾG}lk~ӟ[օ zzzQݽy쑾}+DZ6(f1GxxXRSS.+++WZu+Vx^]߽{wCCš(۝VZZ꼊3|DwJbi_H=rz8?44TeuGGǗ˗/_r壏>:uTqqhKo~*#IǙK٦^If߾}555=֪ 뮻LXX*˗qqq6i+ t8NOap~GeA;U5'''ZxALJJS_1}_Va 3 ׮];vغuN>}?Y%>Ғx<;v)v}Ңq0i?4`Blkg-`222 -HKKA_~?'ܼysNNrq\A_^TTzlٲzj]*))ks;Jku"}XX c8kg\otI!guelTT6ֺW(~EP?z믿%+'''WVV*kcniiQ]A +V۷o֭ڼU2F~>5d䰝s,Yаj*E"嫳gϞ:ujڵ*.\[++F:A81M*&$7*mCk.ڀa/^Q[ɓ'ݻfU ڽ^b۷SD547C1XNdddJJRFF¼ROLLT߲eիWޮ(G3(Az48 ;X%䑞f ziCuOq6*mM֯_o߾_|K_/_mxǎw}wZZ);@L))z45l-BqÇ~ W*ϿKZi1=F܂Q~VK[ f=~#GUnݺEm\\]zurruv5bU>^4öZF%gš%(]QL~>QUUUO7qy|5bhM;@Cž:nǴnŋ>9iPmxևL%̓vڥ]T*gggkaLa}5%*--+>Л2kk@PҋFG%,߆VEekΓZmmrԛouVe'\ٔz6e9ݥAvN;'X1J5/M]ʹ.^nꊶիWk+Lj=u ҒZLi977W XGyg뮓'O^re͚5ZƼz2K6tsBf׀iah l:ݪRSSUZXɿan#+v.(xᇻ ̔m) ~-/Me|?\_C?qmN4ӊ--VY)+8qBUŋϟ?rʴ;whUZ^^裏Qz6mɪGakl0g׀hhg0N ecǎ ====o֖e?P mjjPp9巜o۶M1LKk%FZ#M%0d mSч=mFU 8g( ЖlٲÇ߸q_w'|gkkkFFLsVxj{S=w&1F`&Q-mԺz%1e*ݨ 駟*KN:rŋuuVTYrʔ,qƭasd[⒒a(TڊhinnV׆ZRۛKmr"UT>Fk|W[W^t Omu̴DU'3Q2t`ǎo~]]]࣢֬Ys>{̙3ZJn6}ՍJnu¾4Iw):Иޖ[k ;cWW(.K\q]֭[ϟ?l-M/++{'O82Z;{QubxSuk ]77M:<s,tm?DDDhIۭxzo|{]n][[ѣG/__G)**JKK.zȡsҼ?tjaYԺt`q73¿v۟k6UH9D/뉉K.r|sNmKEEet]=_¿S_ eWtB?n'Xנ;vÇzW]׷|]v=3o]߰aYEE *뜃}oGy3C-bO^=>bm 6miiyw!6詧ڸq .477??pmmmYYњ=Moill?c]I f k P!WW??{*=s.]ڲe˺A*tH9%@HHr7k;̰gZboX^0:g6 +lYkFWZZcǎ'|?Gz{{~_|ٳ핕J\YYY*H8'r]7 *맽lٲUVUUU$ -^RRrAE8j-dɒիWI\r ?lW_96">_W?g'MbZ*p%s=lҥNΟ?K/ٳV! I^C6\=vɘ v/_<;;3119fkRUT௯ojjѣGO:uɆ,G 'N6GiEMHlG ((]ygWX1&kaÆ wP}~ϣ `ٲedKJJU!\R |G7GydE>իW~3]9ݭGN QXֆP6LM+`;.+$$&S&Otg˨PlT322tKGGݻUR-+V8}n1aLju2q婌UM801FE;gn؝VY[ۥ@;v?z#Gx?ުkllp*BhjsGl{?U1 E)7G1()'$$hR~S`S Į*)+իXd5pr'xb۶m /--z*bEE^Z+J]2v]\ _cNNŋU˗/bzs;w_ L}l<|hzLP-Ш[ZZN>}ȑ7nGGƍ ) J* vp\\|R ZFEl-V:63< =ʯö! *[lbQqNu`}AJwܞ9_[zBk-JhTҒJ>S饗|^xAo;sI}jvJ]ij~{hWy׮]W^kjj;.^WJ˼<H?uj͛7+[[6sRM2K[w@رc.]Ds_lߖsHL dH')os !벥`'ݔm6νz;_\\Bl֭ zg@~|ꪩ UiytMQZ[[x YCo`BGtB5_+p*[y5H9_1ҚEA]aBaԩSw/~??PmQ=UssR§u.rDDEqgy[%%Kl۶Mo %Z;I%LnnVE( %\hb[( {EΔc{U=&?c쇘⦦'O^v?DZiӦ2c֭Sw -vPش*"RSS} ӝCƯm?z뇣ةdJU,466?'?ɯ~ׯ3Ra^Q RϜgSc,{s²(kZQJ8EzܹSϬEz-%^e~]*Nv?U迳+dh#|k-ך>[֓NspkѠSa^U3Ʀ¹ÎsmܸQÇ߿e˖F<ڵk؍z {z T:nN3%|ay}+1*O;:iT_WWm۶W^yEaUT=sA_ z!ۚݻw+)*[~=HkIeuizbⷭݭ{^qŊͶV8(ۨDv#G†дSUۧ ԭ)V992%jPW\{<+^f2z!]c(M_t^ESJJJWX1MKn߾Ғzug'o:chNa|G_{Mc}…zH]A]TIʕ+ O>3߿_ׯojjR"UVꩧΞ=at3g(-[kmqq]222}ӧșL kZ[[UbU#*–UE谘3[ǡ2DiݢCOk6^PSQQln@ ۛl'VZJ+sСW_}Ur.(y] ׯ_xڵkB---ZyUFv^U6n'_T_6;W-F >呆N N0*nmQ_-<"ػwK/wT5(_tiٲeG|ѣGU466*׽r5kt_|Qw)+)V(ik1*"jjjzZ=P!_  Z=֭[{{{zn[͛VXͨ(%p/Jwqƍd-BGJzݮ'okk''GAoϟ?|ڵkS۽{Ϝ9'[ׯWo:PNKK3wc?׾vZ vkkkg۶m%%%z݂E;zi-\VVҋ@hhhPqUEz=\*ZJ劉ђ=ЗU lex=n*iʕ+|믿 * jђZg^TŋtQ|f[F?7lo+;;{Ϟ=sˆ>3֖2(55UqqqZT޵k>۷:ujΝ'O\zsuuBu{矿ǎ{y;SՄ\믽ڍ7Ν;OuBٳgwsnݺUQ\렕eeeY*%Z6x*^xAj=Pw+×{^;WןZF?q^B vj?LPUboG[9F|pS#r9b\.mw@(:RoDD xmL!JJK,PVVzE7666yӕ?S%M6ooVWە+++Uddd[[[UnNI|;s=VKZ-*7:::&WuVPW]PRRG)k BSiNuQ-999Emdozy7Ѱ G*w}c{&bë|^׫جAu³3lkk{;vPVU^^zꂂo׮]{w+VQ_׎;z ^BTW1vUqguuu5>JZ7UZFZRF~@Tتdř`e:3?l}9v%|xa'̵˫T\\0ԤzEq뫯pGiMt]qU)ۜe65JZgUzuvx<l ֱ_k.=_cgIOΛc 8^kו@=u&'( QQTVvVWQFԭNIݒ\__ڪT2رcGGGNOu4tr9_QW`Ѫѫ iii~'9c=!mllWK0(*`+5;uwQWhm;#;/aC*/ⅅvZ%Kl9_\`SY/z+> >> >> stream q 1024 0 0 1139 0 0 cm /x9 Do Q endstream endobj 11 0 obj 34 endobj 1 0 obj << /Type /Pages /Kids [ 6 0 R ] /Count 1 >> endobj 12 0 obj << /Creator (cairo 1.8.10 (http://cairographics.org)) /Producer (cairo 1.8.10 (http://cairographics.org)) >> endobj 13 0 obj << /Type /Catalog /Pages 1 0 R >> endobj xref 0 14 0000000000 65535 f 0000064776 00000 n 0000000261 00000 n 0000000015 00000 n 0000000239 00000 n 0000064465 00000 n 0000000361 00000 n 0000000575 00000 n 0000001926 00000 n 0000001949 00000 n 0000064440 00000 n 0000064754 00000 n 0000064841 00000 n 0000064969 00000 n trailer << /Size 14 /Root 13 0 R /Info 12 0 R >> startxref 65022 %%EOF PyScanFCS-0.2.3/doc/Images/GUV.svg000077500000000000000000003665511245330745300164320ustar00rootroot00000000000000 image/svg+xml PyScanFCS-0.2.3/doc/Images/GUV_1_5guvb.png000077500000000000000000001317171245330745300177410ustar00rootroot00000000000000PNG  IHDRsXgsRGBbKGD̿ pHYs  tIME  & IDATxYwy̘jꚺ#n6A$dRdRT8vYs|_h.ke2Ʌc;H$hʢER0gNPcWWPa u]Lq+*C[׉xx!8d W4""@QUS2Vwةt2#")x@DDD2 """bSȲ """Dms_\+QJ3'F6i7f{ f[4H}rTlWeE+ NAdv][}]W% ^TI3UDDD,nPDDv """^ ! iHܤwvpXنhFD܋elKT֗)A#"DDDĆ """"C=6v]]0 ̲ my=n0rDDl` +#^0-/b[깗#b BF,jF=1^1l& kqDj&<۾DD\n3.DDm-x"""D܋,u#"xp+ELjx=H1Y9`%{0""r0AfEDD$ """DDDDH """"@DDD$ """DDDD4iDDDzޠ4jDD$jm*""{|ݮMӤͯ2\Ռ-1.0"DDlH @DذP3"""DDDDH """"@2ܽB!""=v9@ mؕ:"HᏂNnLjq """DDDDL@HTUM3D].8~jf U2i$OJlГS2wR(NوE4DD$H ""@DDDsY """DDDDHyGxx^t\FDl DDDĶ #"""@1c#)巉Y[)&n4샆DĦ5dIM8f&"3fe39Z9i$_4DD2D$ """6݈H """"@îfi^*&U Pvv+Z#"oü #""LDDD$<w˶PPΪďhΥDɈR!6fΥ{2 J:iH[["""DDDDH "n""6""C]2FH._.U{)-H!drQ.oTQHLl0#"ĶUu)m~TrDD${f9 ix6#]T XՈd""S0+#"0DDĶSJ$،qR."bu 6+ԥb]DF"l.B]*EDDl """,HZʟGm:-hDDl@_ռSR<DDl o_T/(xMp[2xMh~j[ec:zI3 G-?k˫?ŀ:M:megGkbFD-qYw]l][lL-Ku4>C(^bHN UKTV &?uas{KØ=]Z@\ JjJ:׭ƹ:_5i:L#YDF,N;]U6kY{-y=.E +ڡeOke{[ձSSn-uU3`9==M]]=EFU<`∖3&Ed"=5ue7k8S&/v>bJє JT𼊃~Ѽ p۔>9~ˤ\Ƹa<+w 8h'iᢥkBߩiތu+V+rȈxׁ&sLSiQ -.j(ԲGKW˘yjv(Y0kGs8gYA E]K{Y4|Ae[-%ms9=e%uzzʆ,ZDpꈿ&*,hɤLAElY[ʵ3ᷚ(ѵlȧ} 'T|O]!1/89k̯kI3j:`);}̧ǝSr޿m9I=p7,اs3_55{sqS6kQIYWSτyɬIs׺ :*JvhYQk.&2l@ăV\cu7nq+z.9 ]qe'oJqwJ3 ;9؊2j̳tW~bшo9k%gT=Q-mm%2 /ia~EӌAcbҀ|\oZRhRJfs*w1)d"6Q߻]OxOo 'xN_S^+}Gz?1YqyE5oU k3  /팪ӦMÛ1 UeoyՊ7aiu]2aiٜQmMu]-ckژ_k[R6fɠQeW7N4n2 e඿6]J)_u޿vZ[ψgr{֗yU`ΐ_]6gȂaUK1'\pI3agP2/%tߵEjT֝PP.Q6^qZe@ᢲqO8ⴗ : ?QwZ+3O;ꬶvSΙ$W6Cx1).eOdf~>]c3^4 {Z4|wt xNu9mF݂VtbƴuuzfһIZnW Klvڐ[w=%#:.{):J0ŵ#&}A#~iXp7k)Mvy#Zkz:7 $Sc3uZTK]mvA;|EuTM- 5SΫ`YY9Uoyâ{ )43:v*0-^i^k)Zҭvѱvm -=%{t]Զل-']kUu\%o#?/hyEЦl^[Ds_ _Ѭ[~Rx#[\i66G7v*׎WfnM#^E x^Y4#7lEN獪dɬ% MM3V0g?pXEum+T=bԒ- q:7Kuxb[4Ek#+ޠCIwo4[cqmCAnj}w򸊿 錋FMlŨL[Yٯ`ںɁe}ڀږغ1_O`K~z b35/o7㌦G3eA#73nWCDlaW<m-:`ܗL.>jig<.XM jzk'Wn)xc,vPQP3^v^׀%G-[29e ?hegf#~˲=[d}Zge]~.u뾲mN˖jjs)ߜY*sEUϪ5Ńn:Y;)" F-hy԰]9MG_6_W ٫e-=ܘJn#ک~+V\,xĘK>o]xn?`٠=v{c{_`n!"Cpsݪ'W3ZF`'=e%w]*7mDJU׌3(|uiꪀeE Mf|@ݏTð:нzdD2 뜕xby=2ovF|E=?`T+[ۢK7TY3s'x E#ƴ|^4j >3䃍r5#Ħtp+87|KX䐢%ESN: muvwxZWo_vQ]{/vyտ}l ܘ,]DشFoꮩ)*vIӐQ_p_YÆ]R5 XQbtpjN -{.eSUh+VPQwI@  7XYAAհ1Þ3/ (k`POt}7]mge Zqim@QMa9^4RuZwͪ4_y3 qݿFw]>y8GF:z:kyƔiK*nj:ׯpSw˟m^-;{y};oFAOmk9eјwℎ[C#-tCO2E+0jA+uutU1mE{[FvupꁅW2;|W,XϠ_ZK~o:dNf^lg5IQJa uShEMQgٜ:wԕ?Iz[ytp2f[;j ~ӊQxne]sv岊m`H ƹv+ޕ1Ec̘Ӟr;:|Ĕ5Z]u FXV” T_1fKYʪt✆& @$Mjݸ+誘4`{-xŴy-=% 5\\w86/`м9O EQO*8ÎdެyXw]Gta= IDATnb{wT~c .[T25ME% uopD={51%[o "?j}<洆:Zp%qM yCƹӹM~vnthy3n&6X{}myUuQ>l̒s_7hhvgѺ8f_vmV7PӌA˾bN˄󚖕TR& #=/|_[PP4W!@2*b)6棞vn'\д_YwyQwQVVm/Z?e/C{gGeEMeĶT̺X QY0ea/Kj7yz*{}7HNag~%[Բ/YS6.`^"sʚ=a;3N!qru=]+vZԴkب[P;c"6 oog=sT hU;4viXxm5QͬveOeEgkX0 wt8SDS~ozv%~وoYrYACLjg\t>qQljU=W]PEݠ_NYQ^ ZAEJRіXiG_>nΐ̙qIZ1Wǜ;n>hK=WHw׾n,9iژ#fU1/W(evwF$-5wƐ^kFX{UḋmJ(nk{F}¬y#x;ΚV!~ikf|NxR`\kg` '|sg#.p9 /4llk 3g%;M1#ݿ`wpȒEߵhEɘ[9=6j@9 eAOdΟqшi~5aw&K"l;EZMvē-y/xw6 P]3:^0U3=弝^aՋw}o8H}]c)3=e\ے};~lܧȏtLVVP|5#e*5j꺞1g:Vnrw& ^Um%]]-%SN:xը-8hЂqKvx䎪ءgIňqs|kk9xiK kڐGL8je5cT4㜢 ?ۖ\A?M#=S1i٤s^U/[2SZqVØU C#yK:vv({ t̢%Þڮ 7Sd)elĊAKZJ&T{Ң6 F̟;_R @ܨcQ]S:*,!O{YcAzUӅ|b^Qz?7r 9'fu(*]NkΓx J`D$׍٫zygT7aJun:*;qF&#yCkRR#*3Q˚nxOBlU{M.)+k璕~_P1Ƌ{: *\gmZk%JF2h@s>KFߔ/{AU/wkD2qe~QIAY[K͔;7mEͨ)--SŽMojʢM5U]T1rAi;5[3露 Ef'-;kQMu5M[sy^v=^Oq^{MMX鄂Ow^lzҠlg`??S^tʠCP6j)cx껍 *β(:೾kE~-E-o4iDJDu0a3z~n^D*&q'u%Kjk;2mIѐ>,Zl)HF$JƌYP_2k]̑f˗л3rȉ}QUKOOϐ͚dgWDDme܋u};fjkZw?'ÖoQطhM~я͚VT^;+0wnD-}E>/=vި1E󆮶ҫUf2b~ȯi.I M>~⬶{oR`8"ϿFxmcE #'okhZ2o٬EM-u-=] E{osJĭi/8iw,X7l`h0sq\C'|H`Kg*SW3j*d6K`[и;h^֭ -QŸ3:jJ9:R!u+rܧ}ۥkhGTH7z-7imuAՍ;8ԧdPòo{Y]ۢi5Cq]lKz^u eU5=?w*#F<opnTTVȦdJ?YC^ }0^9r""޲M_V)({[KOAAO!\bL뭕 *P;*6Ixدru5USZJvPK>uw){]d !79-_1bf4u_Zdc;+_Եd@ј朂c޲vFDx<㾣g̗|SZ3\Uv}[~6g^Ӏqs.Aɻ!Q11{j}sOl[QYOE!G8JR B>ģ5U:b\ѷ]Z42w >!F\|Vi+kFDx^oCqUuiA!k W;]7^U*:=KVеhQC;jʹS.bgMv] jVC[N:hZ蓢=w7+9h)s>!i)uoZcA{G$P R':g-%+ 4q}ڵt눇Q$Lcx`WrTq<$Saͷy jiqeܿuRG=m=#^4B.J+5kuIW]}Mݢ]zJ֝ %+;|ޔ} MQ &u_h%؂!^dwtE׼yJu&LkAF*e;ו7N8eJ976].nu޺JF+YEC6Q!F|̐o8笶MFeqoup~9*j)7oܸ'bFݼ򆟝 @Xm€Vk)PT>dbe+bȢCN(zF%5 o8V8"@7;ʺ䂽h1b*EaGl(T6"b~W];V {Lc.j[vR]W3u#Zvɂ~G39KYFܟG4k֯ g֜xG4rѫF-qRl~I5A *[xyZ⊦Y{Ք說ygM:愢AsfwT+QBѠA;;S~ɄzR!0yD.WEhl}fÑC[i~eA1%oV^[[Uyffғeko6zt k%#ΟO̵5 NYSTA+OYl"ʕYM3_;Sd~ͯ)+zZ9'=X?f@QMEe aHIdbUMC^O,#mq%:$]kGXtIϘ,kzܬh@$d:)Oxۛ.86 yoDl{ßttb?VS7ɶd:TU5T9m'6w\迲zG܅5c:L8gYOהK:*&Rf+xH.&렪N?5׿`}QSevWB:6iϛm[X6kiPWOS3돜5~~ecA;ӧ}ۥ-q"h.+!PH +w}QuZ+D$|X9oN[Q&4VW9>D2q?.DYM5 EJ5% 2nO vY=!u]4F$ز&E=+N=K97=UM5zw{l =sPGOZkEWDzռ"#@eIWQ=S~n: Yq]9Uֈd}KuE%eEƒy}o&r!vOM'qNٗb_ihǸv}7@k.i @Ҿ !]%GMj ^򮚜s{ 2n9t-; 3 N%'|;R|ü5=v8*2%TP0\'awqdaZ1*'għ D-D=8 ;MohvEA¶ ]>'%j=@Xc5bDFO.ګ2*z 7a|2'|#./ѓ(W_0(R =OțI9} j @ @Qsd|H٬KYVP׿%ve]yGDV4O @XZ+6iɔԫzZ1cNе9-YvWh% (:i?50aiw@ז5$UB^7VæpSAFixSìTQyА=flk?XcOY𺶼*k"G<3BJ6'kdekACW>S쩾;WGqōfl*Kd$Gj *+9?ʶ6\E=Eg-W\2'- (3 :NI]S4ₚ~ 6îjhjQ@NV+vPGFְ!_UF NrC>j^fZ*ՉvϭW YT؅5kQc>]3rEak3 R-YK!-[?LgQUs+!)zZϰsGA ѓ*8uH4e_,ȩ{Qs^06^u5t"qȟ VCu+԰ǝ5571O1cِ.ģ?!"=59vL}o{W+r @X`Bg GXc!*Y{9%W.җsF }cehΤ%4cra!~ђ7-3ֵ$MԈ}l4Y`ɪ+:n![:*NxϢ4vD=Đkz*qP^C֨yM-Kk12@q p4EGW/I2.j=YUrHUƘs);kD;4gfn౼1iStTrr4w.pc|8xΏXM֬%An aNJJk|y_RTO]3v.E,KuҘ޳Z 'V3gLGF}۬wL׋{@yG==vPGW߼?oVNYWa[/ļy=%R+ rzfdUu0,媊 XgpE_uyerj@MQ5-W$+UE!-J8r; =/HSQ[m+gu9'{jzoS*J4\QQ1oi?kaΨ1mj`NObX'Cس}i|Ԩu{_ZvLBJ50v;Ҭ1i}cu-"xck"/#'㘜! 􌪘Ժ%Lx!w6J,.G"VN:M˪J!MeWe|S7Q('k莇dUO`e򆵜vʴG-% F#*ވDNށc. DT=%YK־ǐHb Idțh p IDAT33X$;J lCzgV%(n$PKxHwM_m}Co=?x pSI_+8m~L!PumdVo0՗h8i'd$Rm^isO=2a8oTS}{8_PZv@ @[䰟&W%s& MRTձ1.K"v5lDAb_Ae>3kRA6+=/j ]>`06srtbFEUA f,v?ԕFFU5MmƕST aȩj{=d;ƛ")y7]ԓHQ/}8 „-\h߰sd}%acI>)kI]jq9۶ 1s[56(QЏUW`6hUżӎ,R-,׎!!y(Kuޜ>R X#b#s^Rv_,i^Q-]8袜GMzCӢzLlQ:tV'}׻ZWCq9R_EM}?ZM۬b9pO8^-E 2E`5{w%*NzNXqywD+伇|XACUFQ?DnrlYÖcD۬e1e?aO^sŢt~B˘g䂌hIcvQ xzpu?䐢QicaouSTAmdU֠Bؗ^wCr U}ˊQ?}#վi@NtP3)J*o\>.UȦ'q&e~@UGt,֎!Ye =Y#3-1z} W,F$(h+8֐Uԗ5B'!ǼeIIQT߼MCXssx yN:(+'cUcs0ܣMYFF/Cޕj)9McaT=%RCGm&J &꭫Y2 'EcW 2Zo I%?koHUq=8lMv)1z*te5%rq'}kQGW*/  8!wRyiOjf%TW*Q=xŘ5ڱL*MVwĘ}ƸtMjc B-/Qҕ,x)$l8pߑSUMO޸YgBwj8q9',c!kj fueP2J<BdJ:EY#5##wd!Շ<媆\ !9^ԕU,cFog|k=%qh0[}}#Z~dںqa8D:szTo=l:SYvV98=7j(z³^Sa;>:sYoY}MKtMhEӖTt[apQrW{hYLzGŌV4Ofpr$o\1q,!Uۅ}9*#BM3;OeK2&#BXeu9˖-)gFv64^K :R5mAӾ!3QuAIk :#B Nv#UԐ$.kQ]u0xqYU,ktPpB1^۸k8c Ci(J}a?z?qć@AM5+B#PAިy/ދ !|`7!sQC!lup!S4۸1uϹOwitTǜsy bT عqRUMzUDAQf5ڈg!#/Yo Bdvfy'mK hJ%1Ň>p(* dt>Nmg!V8䊖7ͫ4" :J*Θ^< "ٲ +˪'w?Jn_wM9.UZЋCضemӳTcC>ϙ[])~!BTƈY]EeCd~EowS],)c!ܦ|üKʃwDp N$z(=_tˊ5tM^a]F- ڣRR<$\f<ȹ;ah^WA#Z6c!SnjQmWag\P!5Cgsٸ_WS}u#CywPw;\YyF%MCطvrA׈z߯l1]'2j.OzlOM]_ϲ!%E6b9G!yw/K-3ZqOۤc\!h]:ʸ/jz'mYn[p9c[vmwBU@0)Y5!$## Daְvm1lUKu4$Zz jojv&eL)*W`m&||l-kyzqvQk8M5mA/wK!Ӛ2 JFB]2~8z hOZq//.JutnV7n6JU䢞U2$fI&Æԍ',aKHu,f3KfmBEo :,9Ö-6PIv^O{jjhH9Ogp~U3}”W\U-x/Vj)Ѵw[6=gIc6"Q-Uvزw !u$8嬪e#5D`GO>Uu%ob>^ !Hs͡~Ì˞Qr@agf=k += Y9Ӗt-{Bиy؝{ဇ,k*8 @\)fWQMu%:ҘCҞE9^3B ;3Za?K7;t!3ݘUMXg>eB>ݺv^qPwgz dw+6nڤIs|KƔcxƍVV]ɛS#:!a2O:7|͏hDTvRczzh4QSH}iȜ]9kșF!2eTeLhqƷ\ !<V(ɫIK~hvM]NUk!@-]B(}9?0x'׵c Ia}]}5Cz1lW5=!MU}^^^7q 򴊗n>6p DQ4,F l(6uK|g"s2a:6\4`AM_Ϣ 1`CfUcR:B`7o4 7%V Đ"UpLٲS>䀿qqUehFHfSGn fY:``q`  `HΈIi[n`!<Oyղh[!5 ꊎ[TQӔH%16|0촷1%tDϾMie_tJN"aҼCIc!lEwմLj˪FÄlM+Ր\Ogщ?iq^W_" ѹ~I0lq_RrɲTJWaӤ 4'ebغhCVjA_I=6U uXws-PtBq7ۖקDU6$kP$MBkV'\Ӿ\P)+1=m)i5e6dAwhE"]= u4m߶(/ja3~nw{jiwv~D|CyE9ǵ[U.(7MՓ( LٱIk:}hʩ)z;(By W1a}TqzjR% yÊGaC]Ey~ց~sLmc(w~ˌmJBx@3j Y]=mx1̰ww_voZjv!l[%\<~!{Gڲ*ڒ |,4 ﻧko] L{͜YДQEQ?€}뭚{ꚃ%'5<[~qM8au9D 2EGe5%):jR3;! :]-eقva;U})_5- ZIutyB mDQW ުW*WbTټ}D**:n^K+ۍŊ#^Co*:`AkWT! cknXP0nv\X)7'eĜtڿ.rq&a4-j8} 67';d mr2&|֟zV^ HW7G?=5G@dg6{hDC>-G(KBcvcr9:2r4@`q =aJ[M;p!MjP4%qЂMC`e qJϛEf+qr%Es  $tdUdӈ۸!-p?4);_?w5&ۈʻj 9=fWr*:BE!~`Qey=t:D`z$GRH-* O5IM5-xo_dn83::^sU @!<%r1n ml~Qڷ-C{ UtKЏ]VC!`lJiL!ȬXv %>w1(l/c~6N`yUh5C[PqO"wvc 6hI]=V%VTOmp(#/'fҪ&Bhx*zן~t†Hu%J2rxԧL4oԯ8CdGYU8a5$$ٴDELl}Y.jܗH6+}M0/U׼~K hu}Re .GB@`Tk*;笟GC+Qdesؔq-)FBؔq(wͼEL&-wЂ-u]zUCAό]!<5~޸:mތq&l/kAQxy }zBxP%^{-篽kJ.kXi!91kYU: i_LSXX0'hm eYe mFllE$]Vi֟J͛ŀBV.͙x%ftёJ错Mca+yGtI]G]WAnoոtյĄI\2+飯etX;\aC4t LkJ5xV? U蠂etM _?cte4N`ACF) FG갎7?AB v']ѓuM~"e}SŰnM{v-KSSQ 0lSy߇ו,garm :iBd1鿟*aZE)iNω=E_A ɪ=,|ېk*Fs6X޸!1)EUcA6yJ4Jʯ.S~G̚^U)0Y3\ !kKzؗk^Oτ#̠h#nq-;fؐ״yU5;\\_QIBHё_c_w&skD>q^_7.BK: Xvٷ|r ,a"oKeeA)EfEWCk;y}54b l^Ǧ,(I rQ H=c^*!2ۡ{ZVGQRYC!_-m?0H53gZoC[>Ȫhzi"E65܌\5#5dy0ɯ!3Yoi[җ2lܒ+q ljh;Y5 9gVk{! Rq֘Yw *>=Lą,k8=hyܯX5$QTqҫ.H"":Cu;~-Z! WtD1oh):jJ!Img"Jtwdܪ!qqFYC  K㚲ռaYWeXNFrхˤׯ'rF$1^٧st ijrohBMVnq?3x]'uؤoWgYɔ4]Ou壀h`zM?%#/zEm/QmIa' IDATręh{IDz;~fEB;u)h=YrLiXxq;䐳%:ZxtwΏ5a-8 ;5S2"5LMo*sXۺ>ߑ?iC#꠽gVѴyW&z:Ɣ<鴣z2hBxpyސuP+jc!StA} G$fuq9fuo`6ZK^wUǔi}]!l!= R􎒦z(DGPtH]ƤڪX<6Jj5&k <LC[g}Ẅ́eBش @GYWɓu^*ph%+w2) Z8[T8ɓy]yYeMhkk"]^QGU}Yˎu(Gh. =k&դzc l8iz;e?ԗwL!֐VQ5+%b `!syڔ2C5+X2-4bD[o:+]RPAv a?!U5Fm 3gÖMuIs:JrHMQ3FmDN|pR B;ː[/WE B{׌WFWqRˬ$*l6J.q9/O`!ܛC(wQ;%D*g)mJ-nv@a?UEWrgI!Fe#r*rظ)-+5n~TH yX-uz՘!sz22:QCt5z\3%C64o3dT;K-{ѫ7-,Box,T%ԼTLjE;!M;3&'Uv%-([ 5㪬=iTCS_Q5 Ynٴt|sy}X4z`YIw-R1}[!^Y>.x̿'Z4z`'Jd='qDV5BBТeJA!Gpwj^ sJJ&+LL!{Rqm?w)Fe:~'~B Ysd\Вs/o%V:wOu\/KG%=_u9ZzR};uuUM–p}KgJN詺 ž2w32jؘaYb@4%NjW!5GA_N:~"iFKIW+Fbz (k^1cQ n :Kѵh԰Wյ5u/_/uf!uf|ڤWuo9 `e)i)jp!!QDCCEI^׌N<(I7za/xLɈǍ?!5 /:! 2[ !+Ma¸JWBaIrla}GNGiiJuela!38y ʼ^4JhmO0ᒿgLDRwXżf:X~/_umuԸcEL a_NkD 6\Ä_4msa)iSW6e) wT"w}?g\jAg56.fr/g&RwS6.U4WD]nQ"1;<>JZ]/, mJ b !ܢ ~h"gw5Da}SܒCY2uB7ix)Y%-]J$"m:fp74c$pgźzjz^g\򞶕gPz[P`oLei !`ܼk-91Þd#YԴ-kj[_1+gzd=kΤTcEث@opfoꙕxA-k;lFMnW!<,+JEI?06Q CrRʨѕ @ZeG0ira⦕EOz1bB^_͌ΠGa?[yˆ,Nidٔz!2Mnpa%0T~8BX#0)9~첎~f[m:k2ѥC7,!mW^_J=KpқlW݄]ńyE-YDVǴ^?""Q߲GՌ5Z! ټ:ZqL8-CclDFӢFt- aN5+gMxDY=K*`!2?Q1gޜ/B՝vW2=j$1&5/OgVWUj4Yfȼӎ~aex0D`w7.䌨z^%9EeFVh`UBb؄Z.j)ٓy;EQ6Ҋ$Kj34q2RSU*U T&s15sd{>AK+km(q!2D``w,b^UXVw/3&,"`np9"0o>u-`-vGtLCݢS1:+&u=%柮نOZi6XWWCQZTuiuIt dH8^=JA;|Lغޜaǜ7,6{WϫJT5mJhe 0,j@IcvFN/6*>bC<␶juLXÀV_W}}_@KWFZc0jzB,Up]ذL̍ˊFu [**`JK@- nyJ]4n.O%hB`A#)F5À@~-Ru}u>_0R ]ƕ@9e}ʖdU< q!v" wL:߻Vn%"I0vѺ01]e{Z]ɌxKWyCs2yq3uM:i@[v9C:o@ۂ,Z}h asʼTf?] (cEMNX )U2{57f$a-8oE vO7F,P2%sRJz4 Ӷy5s~aQG^z,Ljٿ>7yq\%M?o l> ʺv>X }T(uos`DYKrOoHt] B{TgY˺VÈW>?va7y/r̤%˚ew[3i[&VcVQP` ?%qC]rʓFcop<Rr1c1 U  _vԻbB[Hk^%1;v޾ώc ʇySEW!;v1yJ)E}!mn,*G tmD iTK)uBEYd۔.qo%1 <v]3}+Uնn8:!% 8p E 䔌zOͫx$Pm`Y=Mܥ`$-$oPƜ)HdV}[ԕ}sD@nK1:[HGuXR_9 t%Js.dRLݼQjF6iNI Պ#At-ZԐ+ʫiS?ѩȉDQ~ h H ;ߖ0hMIwsz? @ kzȜIMuGT4B=lY+7u,Pi,1kҚcJ$0aD"q)C Tg+Ē=aM6G=g=ԺW~T m 3RHԦ)A ?fo&UPOMC) Kju}_d`WwMi h8'~fY"n7N^U3]UE "QwE+J1U&嶤^a wiZ=撶!ͤD[JNH<9{[W[ẗ;UT ж"qN=\ XOeJ^RQ;gr9|k~"S}F@wL[[aʼ-+JѲ#v/+j[)Mf @UCY$oLwKAI0mY; QR6+{ePjQӎD%f02QЯ3q8"r_OUރYUq;jwr6oƠcG#Bn\ Y5 \A}bYEdBՌjT..7 >ނwuѰěVb`[s\AEo9.7MB;JfW[*YR6/A|owL U6aJ3* Z sLgU`L`X΂ԨD}SO=yʕkN5aQ2%Nl@QN՘quKR}6E<`5h287zBlqX\7bpH;( ggRڦ6EʱP2nAÀOjyr*‰0ApoyeME] 1'oypX]ѱ,o4bLAfi]81]'43&x/LDzaM q;*n,!YgWTrkf ecIjux'< ;Z6^ԜT ڃ`'W7L[1%Z [O)Gifr%Y: Ȅ-VЎ@%obY, EMFmVApI!-FSu_yOA3Zx~k^W {s*Q%SFj}]yoZפF,PCɴ4g:2 ︠0 8rr,釒Ju*;c%}$J1 @Q(xȯ 9po}gcQodNrQYˊ=H@ |}sU7kܴDlW4*PmJt![rĂyyEM]U-oa U?bڏV+xJɸnjZ- lZ.ADۍM8O˒S2&%18`J]c:Q\ J$nAY䜎> {Gw^ڒ ]b;CSUQ0'q@L\j!;Vk모)ߔ *k|>ZMNc̷oWTߒz 7D#m&uo8+6%aXmMҏh'%eऌ]V9WrReUuj8.7wl=wz;oѿVא`WUۀՆ@PwJSA :h:Krۓ1u?V 3n\/vYI>]ƀ.k[ "97c^3Y "lRwƼ3F}UCx\A*+Yqclݸy؆:Hy ]d \7z%7 isRȢnpw7]eRkßߨM ̺}Pg -)U7!;.?D`+~-kk׵?->+{ʸ.R6>2%#&)񊿑:_|4 9֊—=hވK^~7a{.u5{4cLM[g]pN[}oK[IMؓX'X5lFۘ9U+g^IW!9)VJΨ)95塀 ]MU7- 7n^)I4@ܿfvkQ^KaT}o9 ( v/qpGԝ'J3]f͚rIMǠ99Y [ѐmđIim(~1^PWxջˢ(0niVdRy S rʌ9\27Ұ?n!y$ ):> =.P IDATgٵ+1# v5~o;R 뽖8o91t7,%wsy,=55u<7T,[bӮǢ!Iw3yU+.:czYMV&j"Umucf ?sެL~yI--3j2sd ]ԔyMA-+O >3`LKkVjٿRsf%$k;!{!j_]Dɨ~+R9l5֪ۦyܰa. 51]e<Ҫ׳&K2{MJkXv@A!z]>JKf\+E`U;ԧI)~͂|˧8.$ѷn~F_{E=X /]+#sF['=LANT<瘂&uo_g/dQtj2Wo֒,Ҝ~ZѠTIՂZ @ޙz.QG> {JS/5mdeP;d j)+D?4H v:KNzNM ˖#w[IQ4)gf1uG╣qVi#Fsλ*=s׮49y8h+t֌uQ&I5_MucmTIK5&?/Nu5$Pm-E^1Ate}Yt)kj@eA҆9%ֆ0riPv4ysuQtX/ ji"X9Y/DzT׀M`X`p+'#1!I%5%sk26$ь %l>%3hRAESNØo# kSod&<.LA΀>λhܷT3A0#iG &r^^V(껅5ȱdRR3h޲~ -Ep vt"`ד*1oIޠgu|}uoYݣnW*Nssq[`KRc>hJW5}Œ%un/gΧ`^{]O۴Tk  zFҶ?3Je<s*WU{\eov?r`uo'|Ɵ{F^75F)pr6"}>cH+f;]N8cUM)t/(ߠ Z>pF%93Vy9e78cP{(m#pߩ MsƼ'gjӜG՛v;v|8Mj(0W Ԕs/{GAۉ$ԊY:*KuiJu5-_p,I:0n=]mIuo_qyqQƺyWZ]+=/%"߽'8AC^pXfa)Z]c@Fர1Hk+0C}~.oMzDk5q7 ZvaהA+>$۾(ҷn@N2Օiѵ399}:G NzǬ3o{3x_(o9t|ޛ~ 䒊*UG,knק+SRvxEzKY1e1| MxX\x pG^^m-%sJ4kģ^4놪ֿN:&Q4lAoqk&.n(܎twd7y% ~fPfEN Z: 1QKTp7 5waoh˻kgd""ZN^"o mF JioI=`K6Jnr>lYlÑT2fIE3 1}~9uTE\ſV iV&]p̊"MdgNͩyV6ћg甯;-(Hms j5 okxY "^7plhJ4͘Ґʛp«j XP~PÛlſ/vr`}kނ!-+RUQ}W1$-+ඉe㜪LÏ/sΪEZ↠ܺwwm>]_wyeHRM9i$.!0Lɘԃ~;zKkܔ95%kw#뼛BL"Q[|*oؘE,8sF$޿piaZy%;-k4cw7\9p/zdwDoeuͧs.i*K*:e%zPAΚL^GW]یO[5%d%&H \6xȝ]}L \N[ \;3޳i)I`; \%hJk㩺)8YSV{U._}OڻŸAE-9fDlGpjO1 {%:{mu<37ׯ̐XerjI+4 (P1&S>}K!*`{ {ld/鳞 jJrnnmד=Qbq{}sT&NF cA]K2wqSjb'[.ⶼ>OyϽ#3蒎#F<_5bќUW{`cw,g4u{Rmcr ʙưmW*ME ln⸒we;_fq}f,kh^/ڙxs*:(cY[Jšlwv l;OɒDIAa'\b΀'[HT #zkS;%!o."Pozɒu{EyMC3:kO;Li 0h0$4aC8GQuT_vɂL~1o0Yn>?•!u}swA氮'L鵜N{$T @pLZkۯs޵ӞfZWY[*nnNz7˝NNxӤQ5{|ʹ?8ۋ\y2uyAy@ܙnRREmugq9K~ٸL (U`-c;R[dxh/ҳW1RI6o;9fXdq:C̸DMvkY"h,xLߓ)~*>𺜼-R/ z5;9d+EIH3/ k>eY-9'Kl;l~;hI3M+*XYʙgԁa iAms} $(tLi*?%m3i[ɘA"ΡuzLQ_1%1iTE&33Ռ*3[2DM5jR9}RC,^~% ʷ8"͞ qoxv9 95F}Y/[PВ^˭nIo|psOj+W[~_}ZZZyi#&on?ۈ}j39+z^0m҂ļ? Z5y>?讵չ9ÞSh{K{oĘe'y_K>kQuA;Pp ^waMԜsJ4W cAIdSbO-_#ml,qo~J:4zt·uͨy'fI 7gz&FNZ[RO~Oԏz(:pu`DWbqi-?yd%/2j֠GC ,%Qv˲1lm~bӽPp#pfe:휺z@i-u͵0m_|ɢL 1uKrhHy*\Eʹ:U7y @p ZW"m75%+f9ouBUGZo0LKM*Sy1eʩ뎆ߐ 7huU~m,jo睵q v)  h %etV`wВK撆:=`&/oG$;qr*ug^^'4nM3{Aɾ( vؠ$خ\(_N5Z2mZˀԢL?QO=⬦W:1[כp/זބ龙F-~f]OWk5X?&=͙Y>̌80`^].Y W еˎKK5C9~);Am&ej5|Iwtߝъ~q!b֓%'u x@ -sܓ2_v@S3eUU3(}- 9uSWvHΥ߿:2g#{!zȫjY+sQqԘ=aRgGNkYus(i$w2{x t6ygɏ .{QUNѻʞwQ;뢣=%ˊ$j2~GٿbCy n'צgk_d:%Tz1ϏW-zƌzҷTxRοaސ>.iI{Cm ";ϛuQU[Nrͻ>+:rb(yŊQeuMc$;{fxS^ ڽ%Hhkl_K܁AwpmG6c!v0z-%2'TV3 ')g~E5!eYO;謺e]} JN8oQ'^a]rHĪ0k)S0`W7;,\nĘQ-k{AS(3agUqΘ6cFGˌZB!A #djNRvop!S(jkZja| /˰i-痔e]1r($ƍVyMQ+ꐢpڒ+_G<\ۨ_Qҋ3i*+()Ԕ((-2u 9Ni>Eߠe+%֌vr4& wm;-Ke~w]2]O_O46\uN*&0;a_o OI}BO^@"`̗Cb^Me]^nA`T5d: :kT$gR[[K2w;ל7oES[Gӊ} @l M噂u#,I,jV,w/& T]R%uM(k6! 1Jۆ]UռiNr$3XYёjq,Xe,S Q}nES WRWWjŠg1$UW6l)!EUwsΰ̨[hQW&S.˃W3n0B,YfȶemY`Є0_Ex΋.Zs=ۚ:;EsegIr9o>fuZ6q+tެ',Y7$g9 (rs^°#F-;O긢wLx[C3yLA'y˒.xë5y]#.hVraƹ 7}2#!j6z>j%Y#~hZjX6b9'Sҧ 5{>{Eg4k/;mҨAg,iXۻɮߚf3q'&!H EB "P@<@HH#/ &%b Ʊgl=Tg2K/XrtOݺws;V[Bkmp|ɕ ^hl7W.3ky4pb'{ i}t:u=C=[o읝=뛻3}}=}Uƞl_ꅎvۚƾm >ػ;z{k@zt>W7C=x{zcP3=z i:qD/ε,BU`W; ]yca3͵ڠBo:Twwfm%Xh={{7t鮞ց~'X?ޱ>N4c.v}绫=Y==@SM=޾o[ktTK-w[5N= C]_lR}E-lL[{"  슝xɲ m=G򭴿0lK ocjOVttw=ߙl>>ܷDdJ3~Slf;zzOz}=}XǺC}ǻ.6D7Rj;{lg;Zk m.f(_΁k;o: h.~ՁMXMҠ4;;dÖF+5נ#=hH;# 3ۣ=L }?t>sޱzDwvɞ.B^VlSu>4J35hKzx%Tߨ+Ӱ6۩+.hx=Chu}εգ-u{3|&bZlɦZif L4iVZnކ=؃uoAM6?q&}&7)CܘMtōkZhF׭rkts =} a;>\:ζbD =ζlKŇ5:fzOjرVZqXn3=%+#N6Wtjku ]s9xf_b0mMlMu{s [hDil =\hDK7u=۞.dkA-|;}1_]fؤѲm_>Rki_:BkM\@Π&ZnM/]m0e+뿲K(օWxxzϨ6A.]~#[o=Lln_u*=V_|XF<ՠK*\*oo\y/ =kvkT \u?|8g42vX$jQ{`fM_e_C^YD*+hj* cy2v𙲳d=vSv=T.uPH= P3 .a@@@@@@@@`l)uǖ5[W8٢ @@@@@@@@@bڂ~tǛkbU]n~ :i :W@@@@@@@@@@@@koW3 }]mvAkW\ ]lH5xUfkECd;ՒV\MvtX3c`а`-mQ 눁q7ّ&;fnk,_@`*mm&vpi7 cގwС`GzGSvm: s*wusj D;߲-weݦC+wk Tw!.+VhcGZrJc1n4(1ƑoB^7P`;Ӵnc}eqǑYsƛ,ŮY`lnm0cH@@@6|my,cGomϵDZT: tǛm7`7X{Iv'yŖg>}t[m0ݝh ko_uom;؉wB׏MhomooU5^ 0WƶF]Wo{f{?W:ՠSaZs*7êM}hpyM/M~ E74t_/7MkΖT>{znl{=Pڙ^ `\)O]W=w}u?`+l?m!@nm`UMm6j*/V{#U 0tl~8z-0z|ln`:3z|%OߐƖ6jk7!pE}׏{ٶc/9gսX16um˶67]`Fǟ2'zns/N]i R翿v Uf[mޛwMivf^엿u5UlQ[}w^پU 7f?~lRnr>Ѕ>ُ}jٮiCp^W&F!3l ;AV ` UttfMk]qEeaMm:birCw-mq,2  02poh@'{>Q a @'Zvev9#hwnj`Ėc nzAxt .;\,:m0ηlg`|W5]z؊@fx @`\ ;P3lV3#E]~>ۅVpnڙJgulK;1zT_H>}&557ݼ -GEc[G@Q K5`IENDB`PyScanFCS-0.2.3/doc/Images/PyScanFCS_Main.png000077500000000000000000003307271245330745300204470ustar00rootroot00000000000000PNG  IHDRljqsBIT|dtEXtSoftwaregnome-screenshot> IDATxw|E^ R "{ҋ^_QDAtiĮ"H#RH 3 "B!B %1c`B!BQy͵z@Y ͊M!B!7 {>v\ .< 0q0bR2E1 !B!jIW&FtCB!B!č&QR I!B!7=s1#vBLziuk]ˤ$ah2l6l6VսNNCբjoHyvVD`P gs!B!VW*ȼWW\Y`z@FF'N$# *( Uj3;& T$PT43 ~2CUU{Cf̙sDFFQ{W++&B!BܡYKAOԩ3z6;zcK)_UTn?)6JG\-|F7{VyŪ$%%bًAv;G_jiy &3%K\IFha6qevJrJ6T5sVvL[x;V-K6h4 Zo3Pv[2HM`j5}?{y;ũk0yB!B[YPg ZvZQЪh<<ѨvHxz ^id(:4Z ʕy7P + 70ibccAH˳m9-pU\|28]\g歘Lw`^k`Ax~LF#))D_קev+ȭMu3?_O쪊buxaJ*^#.>3g0^wR,4_[Q"81%&b΋ݮɐ^><=$DjjL!B!]ufh4(T)AkM%+o^B{kT$T4`e5t.eSEQttڕR!!../B]Yjut~gC b2,jj&kx{{ѿWG:wh!jCQӌ_h^4kUc-SBQ߫ ݎ(:  @ENѨwԛ d ݒݞ9o2i۟զ|l6쪆_@R,Y +}ڕjZ;r_~-+Wooώ5w&qIt|͎ yONI絗ro,XvB >%yixz_!B!nV|-:}RV4Z RbHOPlXl|m+G ZVo_$h4Nxիv.__~zS:́P@j&4KeIJJbǮo9|(qqqbO{t CGQHXY8=|

N{ Us9>Q+bYㆴn(CHLJb݆/~/t26|uEUU}߬@HI8:s毠sBd.YÉڦl6>:Q|YVG= :t:8~$Sdԑbq]9[m8[FQٺ{Z|vGPWsxzHN\w^l6;eCCvu zQ&6П !B!(nnW^=PۆѠ(`:6b ae(BڵiSN~Z +6@JPv:Q9v?ڌUC{tv;+Uh4YzQyѦ|O$&&Ѫ8Q22 pv;v]p_GҴq}~Px;ERr2~|8U7ϿNjdf ߍ?Uzvm7h@LFƿQ/zV' ÜbZϿ:Z5ڗ1wMrv&VF`4U܎ak3> jW^ϱҽCїbi*[.9yd~ZѦv<ڴ6 B!Bqpk^GӠ(jj)r*)5X3;!A,р.EhZAvՎNf`Z0 m݂m;;INJ~!d |1fV݂NÈgy DlBrr -oF`4=D|T*HMIޝh5 maiDSFYljzs1o)ʣMhFl6/ jUKV#55EQX|=z}h6lފzE QRthW%QU78v@r|W5'$`ޱ7K^UV+: +fԂ>&N')U$dؠw FmB!BQ ( z p2MCI ;[w~CGGUUڱ ]ikApnDɄFq2h;N5}߭Z>w{<Ҵf̎c yB@6mD22g￯F>FZZ fSy y\ϾfCW ZNw@rN>Gz5Y<ɨ<{Q//O7B`?c02;Yvʽ*лG;SxF^^tcb0.Wk IGZظ!%%\nGQ lWn))xzz\9QŠ<1%%5׺ ##Ƅ)_.3ƍa0ȠB!րLfPxTV̡FMѪjkGJ{nq"Ähr+ *ǏVL=7{/3Pn-z6k#ci(8 P:$!Y : {YQ@ՠ$^6v-7e߇0 |~eu@ՎN!11ocoa6]Yp9& 66EQu,6&/}0BհjGv]e6]j4_y1<\/Ġ0*Vс.]Q'OSFJp%2Cl8:Yr~Zni4 Μ& 6+B!wR- ixeeZ)͈EIH?h^ O㝚%) ;KKb Iŕ|E!== DbܫncOK8S9C9RLwrL,>H<<̎Y*fs>Eޝe;K>Ncװf;>X,6XF(3ziϼfjU*9^=Ga13.ӄY)p`0˴Pڔ're2>{N_7s0z˳l9}PsuzF5˯%55t~Wj5hȪ(Ήok4^Zm^%8 ?tEQd%B! ,Z*DFxFAѠjt( .NQb %%t zF "/ҥKᅫSot+s?z@`f̳B!BWdl8~QQ(/ڻB7yM9kvQgIMM#!!Q$&&.h7:FU͜7eB!B$&&d,B!B![B!Bqۑ!B!.$B!B!]HB!B !B!w! "B!B! YcW5!B!B$YcB@!B!X! B!B!y@XCB!B!͒5P$+V,tcY_níBB!nSC#U|zu^\ep>>˕IHH\ͱz#5{] !B!ĭʭ-!tMmZIIx{{gʕ*гk{)WpM]~>DG_ʻFS퀫SS8pKqJwݺ]=u|{=sb:kIHIMceF;WߡƒS_G_B!V[[g_p|s( fێ3fӬZddWcO 88Ȩn_Tet뉵TO3}(BU:Lp@8lgpPQ3:HO!q !B!Dqe IAh5ʖ).'bWk=0^t:*V9 z,V,8qؽWBftq=ܭzb-l{=zBKjPPh..w٧g'l̏~bB!BpV|ڶz/"/yn{fӭs[zvm`s|u#%ӣF "6./Qڎ϶ҫ{}E6}zEՎnkaۗ߳-?͸у)Q"ȋtv9v)^d2oaW7,6!B!(Yc 2/qx#*M!B!4[3W!B!Bܺ4N !B!vv%B!wEyB!B!n]9^;(B!B!y@XCB!B!͒5 +B!BlB!B!BYco`˦uBq ,#B! 1 B!rR~ Zܡ!BkV*!Պf+0B!L #h۱-YB!Bq;(p@γkb!Y Bφ(&BJNԱ[?:F!Bq3e Ϣ%˙=w>P@FZZ:Οgo39My%9:!B!V[ 2l<=dZێ2h6orL Gn",mwF;zf97Dl&b礦ѴÌ1^'նc7Fʺ \;{+w9ղ, -`Ϗ?c6ԡK]d2R T\łKl65kTqXek*{B!02p8rx#vF83'lBK,dY`qq\&ϼô):l5jȬJw5դӹ̙9.ֲEsڷwС]V-_e -ˀ[6sd!B!( C]OHKyVMC t3m.LP` fϿXO뛹a@<1L&#;Jw5?aȠA l~ԪO޽-zB!BW8!peߚaݖe/=Y˙=<ԮUgFw*, 11=. ,Yظ<h4^J]G{Kdgw:VNo(Pn~6rOCdJN/ii@ps7ĭns@!N-`f`IK䅢92_ߏN&00 ʋHR!\_bt4!%Kqe *^J%h:)n~6rsd͟SܡF! N *ݻ=F!vLxs{o[}h)IIƱprjؠCB!B!K ,Qa`dШA=Q! !B!%k q[vi߮uq!B!BZlB!B!"95!B!B$YcB@ᒶR!B!2 e<زi]B!E)k [ ۬Xv;j^FNg@QI'.BX~7.]l6@jkӊZ5kl\]9؍re0gtM2j̳9{qO~g,w,^CA=iX.c( jق}{j-!BqSdFJJgNs/TGJ`ۭEO:fP*$A$&%Y_?oA~7L&S1FuչTk/?OBB"a:n?1o &Om;vѲE [!B%2`Ͱ}%TNj(MTSG@Cy.v S8 iia^| ڴjIDG_b 0oG:|KWpyѽ -[4wDg g]ѰA=Ǝlv5b("6sr K♑8!7r1"ʕe1\ml,]]~fg.t|K?]=?дIcw'NtW{vԁ7; ߸;\Nf YϩUkݣ?`#njr-" ~}zFB!M֡NJR" @v2O;AU5g>b\ޣ[g׬CUn _ZfѧWw֭^ɓ8r(p#e:9~$xe 1 ,Yҩοg껓XG5I? M3j8 սrob0˔iIJJv>sʕ*:T^N>S:B!pU0 h4J54{5vdQ|}#nlE}s>L`yeXxGDlȜ~ї0SR/'w> }v2_nصN-Fc}y;u~%J1s';d%_b2g wڴ`0G|BA}fdm۾Clf`/NyƌNPP FڐC;~":v}#es6x ~2| lr+LmwnEs߸ u6ѥc\,nڷ/n ! DFF1gt.ȜO8SS0no0T!B4ne@չ\;y 2Y9OuegL==ʹs9SM睷^G,]fM&,|-]:wh4va!t9&;9;ގyfYGLl,!%KxBBJ:)Yxٴy ʕ+XW^?S okRvϜemd22h`<2hO:c6HMM#B)B! |w$YTWfLkֲ\WgMݍވDELP yt\oؠ:e+8|ZpU\7^}U1b f峔ߏe;-o"lw4S?Qmj#|`._&99O-5_&Yh qdz`b *'(0Nb[qvґVӵs.ӭK'U=EXt9II$%%p2s ?+‰%&&a4B@!Beu]z  N>M坮)J9ϚEUU?dzbIj?>:ʚ -]ꚴ rjLFt_vs# 1-zƖ/bμOڵx N4 Kc8]oԠ>LBdyٱ3~⋤9w҉6oChh(=w)639TTzvk}{1o"@ѿO/ wn˳>r38-x 5t f̨Z 2*cU:͝m|{T5m#Mqdw[R,;ߠ޽;߳7B!n7O?k *NCUNPUNˢҵsL&# .S-[жS|͢;cZЬe^3ΚOnu3fkTUe\I& A*ki~qu B!(k @e?O6=ᱤeb*ϐMP{H^%3g\ovF+iB?dB!Dɀq2Wof΀_0EAU\)`¿DYl\q#r!B!ĭ(k 5Z-{\2`Zoٔv;fr]9`Q!B!ݹ͊fB!Bq_QP;!B!č !f/+_!BqcȀ!Y:EYϭdSgV^wV>7{ty[@QUq&HA9;O,#Tz?# !t)ҳ$$$2v\t)ޤdfϛohmݳ-|!B!\!B\읯=#oݶbެLve.4ut5KO b >KY橖,[O`4Y>];揹ނB!rEb`֜O޻?{gX,Y߶9GFE1ݩtُNzw/[1xh:vŨ8x0;v}˰Qcإ'c}NvcY">ӹ{~0Te tғACG.z-" ]ߺs֥xzzҽkΜ=r:s_thO^^ 4vr/B!+d@&|+¹˂yX0wїXj5puw˦uNޙBvmX|+-$44 /+}$ք-fMxsd~O&Oz5ѤC̞;ߑ?qgOز ,[s,κ+:yGu4d[nw>sʕ*:T^N>rzNe$ԯWtEKӧwO }.5\O~-|!B! V$"w`n3w j|f}EӘQ h4ҡ]RSS=bӵcO8o۾Clf`/ni0#>! >3{زi+q*^~a"{gђ4f{iUCA9 4wG3;eA.k? <Ҵq׭SEKLRR2,'--TB!( }OOOj’e+9¦yv|m4sf_aqNeϫ/>G ^Æ AzFCqxfK&!8'ϗ*@dE|}}gʴ yzu>޼;vQ.( _}0{l&MG}kI&a0X`;B!n4BݺuW .tJZT^^xÇ3eJ,I:u(pkˀ(ҳ{WNgncQN#ݝvƆ0.=Ѭddd8 :mnll ]UoIDDD1D'$yMyOOO"6ά1= #Ѡ^] _.W g~G3rp>Ã.fɲ1qx>K_ղQQ,Z'w9=&c߸U \N/H*3INNZy(Z qY,N83<LR8t*UraBBB(QZZXd pbB!n5wlY&箛å3w^^?<1o//:wli66l^z c@`]Lk0_?ѩ;t< g7o:ڿ e/c@ :S^uթ &vfM8 1;W0^`00sݣ[gzttQ4jZ6W[yvoAE[Nt)z ҬicȯM?D噮( O]Wz˖ eo晷hg@T;]'>עWUU  !k'.."ʭ3p1NY`2w:0l͕S~\9.S~uڙWҬÄKѥˮ("/YtLek/w+n˘f{H!yV]jj*N50z[+Tӷ߁nokp}=l,m/FHчuҥ˯ rj#<;nKeWJܸ;;-B|||PXʖz>FLL ~~~'66ZLL tt>B!nk׮a, :tpzsat: 9wӵN~INIa -z]{ا@|B.Zʣ͚8ngO,$''颥Rݺ!3ztNs\yV2s+2?UT}9EGGsVzM*UŋOŊR~Bqwz̷-ȿ#222HKK̙33g`Z]^mPJ=Jzzs=fs HUygBw^ L 5-&O}YYt9c=J]i9.7#/]{ĭųBqԩͣjժ(QsRF *VȡCx>}:AAATX5k3ڵk9Tn%B!nZ9Gx{{]2r.HLL$**ʱh4BCCiР̘1smƔ)S GQPWohC%=5crj_4kژG6)8M}}nF! N *ݻ]zuhժUlܸd֭ĉ篿bĉZ%KKO]twהL۶movSBjժž}زe 7bccyW$$$֭[ý UUQӧSV-Ξ=ˇ~ _~j*jnɋ?C@\mN.\YNmdPN[޽s?ܹZ@@ M!xN1|{6ks>T`m۾I{͑o`<3~cF wC6,_Cu7 @ppc9!\2{'B|TU%>&R7+;;>2g6ɦ)JzV@:UDQxrp' һxNςQOP=@TzH%}gǖ&R6e_7ygg;fn ŸuuY"cɼ*{<0yxs9v!_Yȼ9B̈́x?8u499E$a }s z6lKl޺z챜+L2a_I|a:g3g:9i$%]a݆4mr-=w+Wt z--/7 AA\teo>Υ( 0hCzU^l/\DUU~;; i޲?QU]( +y B+ !k^=vP,CP2ٿ7x#[nT]JkȠ/_IVV6cb֖<<fN{ M:UkPFu}J^70 Ԯ]{rgY ߗ3Crr2ua%ڵ SâB!Bp$5 ]QP,޽XbɊd] 82k@DUѲ-lq<3cFIkwG[a_^;[by{6d ^?( x/x{MtĒG!BDٷ7׺|R=DŽm yJfڬ(gpYj~e|ɧ?.ױ.-}_uejB!(!#?|[_g٫WB.+DT gikN:jeg߁$1t+2@Q^da:!pE?ڽ 'Gll&Nf^ ]S- M5U`o+DY۬^oh\UB*KB!QGtz/YYYԪ]` ӧhڴ-o&M9utk4Ǒ Uɔj(`^3" 0@cEWE!G% X hƩSXURRRxldggjFVVt g8yS-MRJnnώo 66onϖwB!5LJ@ƍy~<h Mxx8YYYyJGII#ТH๠eE{ni ֵỊt\u<'wi*))|oբjPN]TS/L!B2y`@ : 6cis'NQF^ M;d痟K]i늮(殼n XmOA˳NEEG`+&&́/?eB!_JYԩٳ¼/һu{+tˬ\{x/tM+&]IKLLl)fMeaRM,jhEJ5]GS54U-\j}麥jSp MUMa$]dY!BZoWk@(; sӧOSzu>&LdKݧ/gϝeӗ={y/dN4U ( &MXfXXZ4ǽemʁe,*B!OL( ppLW)S2e ?3^9qEDgU'(芎+4EuŶ<58,3`ΣP-tsYQP!~D 8*5sP:q~;C̈́x.\D u'(,+항[(ة7聎.!B 8>֥s;SRIMO'9%.#(MTeU/H4frȫi&1J@@JH !(+2B  uڶ&",DF!!!xo'K/d׮yN_Xtdo( 9Kн3!A2&#B!xS~8omiNUU%33KRMh$/N]ÔGȑ#N?3p_}A:-.Ϝ#!"xdhΜXs]L88bc0q2wﴥؿiӦIdd$Ν:=?N(&)d~m 4ФQb"#ht]y@LdMhG5SB!'Fk7ECv$TANWy@Xx5ЂX}\;Qtz/YYYԪ]` cu~54o4_msؿ4q cMh4:-);v̦0p0[СS.S4mI:uʮT_ƧNxU(^.Vhڨ6'@XUaRM^K!D٩U!D)^4habz\v<{: Э[w1O7غe3>KzU?O顡dgg@VVaa/һWw!^?PX k۟0Gӆ./!B_xd…a}YVXrpE Q "J~Ox,xmܸO>]dɓcҤ:vhk){^B 9yJoذǏM8q85GEGK/-?3_|4@:׋'uy !Ÿ* pU[iܸ1ӧOgϞ|w~:T0?c'ңπbٳƩS'QUgys_oۺ_Odk |~BBBhѢeqجMt az^ 6_K9qW?Oݺ=IJLReVXN=l/4K.˗_aU=y(^Ib4UrB!,??] DQ~ {Ufu4~,wj[_zw9?ӧ^:ws&L'&.`Ёaz L~l޴[ni!Kݧ/gϝeӗ={қ7oz5-Z2+ԫWZw@pP wqA*+!B_,3_gomŜYðG|mUޙ3ghr9Wqʳ;K{{+}R7o7hЀĥT?w銢0eTL4G^i?SЊ1eZxpI<@!*<@5f͚wzE@@;wn7X!P-"]M>.XU_d@i%bH0@// /gժUHj߿?j*ǚW=K͹:NΝ:2ah S޺n隦qV>3srm<6e"&UeX,3^eҔy%:-k}Y>2qoԫWB \fFΝ=G4?WNmOg ܛb0!P%=B!(;3;0?^pݺu.?BKTբL4W'brꍛr%9Y,˗شeqW.;.;y%^fU]jtО}C?٥.;Q^?mӾ$.[n '2l@޶/ĉ_UҶga !*$ BRV#9s%< /@޽ᕅOh~ʹh~34}}3(0n4{"-'1abk 44#sѝ]PUcᱬQ:!!ӓSNh$%9tbyInV(N}~ Da}`ylB!NJJ /Æ cɒ%у{V2!<5c&iM͚:Qf}̈́xRSӼ>vi_INfi^w]׭ˁs?pfM뱬U`[p3bwؼm;aa;{ҶGq 4@_P[BG|_cbT^ZCZtt/^V\xH]11ѼEjԨ4wټu;;u4aeK3k t]CYt9z(n{Kpp0`m}|qNQǑt걕wk> L%xB!2`Uutz?oaNYz-iirtǺp3ޔw{I\.*XdKUKٹ_p}^$<$77+WYZQnExS~8o #B2!nEhdQl€֭3gt,3o< }ǰaxmn&rUQFX|o!,_q Ա=# -?_{|nԩS;A.[3]֝~}z3ɱ͵ov^ /\N<#=NkKm?Q:mSݐFIZJLF1D;5@T6ꐟs>b֭̚55ktRΝŋ?d$$$pQ^~eBBBٳg^!(ʗS"_zv4BXHi{Qu΄(LSU >ۯjB59ή==[{z\7_?Ν;pe̊+hܸK,̟?߶/33=zB!-[?sN=(~'UVceddp-v5%! 5EP5ya(~cyyy:/ V@# Q蚊)?WF#7~EyQӬY3e.^ܹ3cƌ) !ԩCRRRKTS>)I8vZ u1Hg+/=Fq48ЈhEBuȓiBkH߾}Y|9͚5#>>e˖Ѽysz;K/… L>ƍ3l0 $22D!θ Liվ+7m]^u(}`OQ֦iN< SB!*\׮]INNfdffҦMfϞ @nn.gϞ=\pzvVZp BQp6 :iɗU^+[s]zX23EѣvvEWQСCoժ~}׮]ڵkyVM!(ЗǞ2MtMl:nFZJ~huk-Dգπr?VYS!Bī u"[ v}C  TU-YYl_-IW ᖛoh٢yEW/}oeOF!UCZ8|EWCTB2e|HL5+(d>nFGnݨi/ֵ`+U3xg d, gq2>^>x3}Y :CGlyygkp;;>(R?OmgBV-YMT.%tֶ:˖%{xcQҦW&*sKQ IDATtDZJ 9gϞoٳ|疵L|fMI|}OB^Blٺ3k^aIJbK;o>{>Ȗ ٴ~uf՚tWcowVs Џooh[oӫgwNbɢټ~F#korF?ꕯƦ-ox'~%^ۋ{\INaDV.K$6mfKߴei^:Kʑ,vٳN۶V!0 U<nao?|[i6~PfUkhiDT gik,]j%FDpTMUg">>^G2j$V^ի<}[3Җ,q-[܂h$<,G1y8jԨNHH0ԩ.\omEHh({,wϝ;ϡ?nhO>c8sPF΁_mcFEtTnjdϗuqG{cGG1ah-8_+8tǎ.vymB!D"G>YCݻ0q2qL8Uoge^UQ̏ 4?{жW{젨Lyf&"瑇ugϱByj&;='X~N&''Dj};\Ǻ ҩn{,gJr2LsW%7!!bzNMMf LHIIu8k qնW.;oN`DB!$ p)6mf{ߤISN:UfUE5~Q|rEHHJMnv-(\w]ƏŠa#mp%.:_l+ ;ZnEXh(9 :tw;Ʀ-Xq3OiS*g/&&WHսŋU&.]&::Tdzp /U0 &&!K.m8mklT4(B!DyElBCCm,BT'n+.*LBã d'7; 9i$%]a݆4mr=w+Wt z]qs KH\F\0h@>D``Wuz?VpETU35IKO'-=7W.Ju<{]:ud굤Ukҹ-ΝlOMKc*Ns\{\ELE}!B!'Sd@hh(لEXXxWC"08m deeS=&[om3OO/3x km`괧t0K`IҷO/! O ''Ƕ n[WS~AhY^B!e' q1ڴ 'ӨQ2K*4] C@ ykZmƏ1-p|JbtNw9g_aؐx]|0ࡾ x:ֿoouy~ȴG'1INAL(ӧ=jW^Nm ЏAmeB!D9)|AVX /`ѫҫ ! *]O9]:u\@xMVҩ[,뛊J&>>K*B? Q畀:vh[1칳 jܧO_z,З65Deг@tO#m+DCVU~i !|GQ ,k!kEQ2e*SLIzUa?B U^XH3wxe4*ƾ-]$=!:N>Mnh֬kfrܹKn rMm f1WݪCdq%7mf/*R5 =9] 8s T@b(H}Ȫ$m(Bqm唁osݻQF:/ ݐFIZJLRM8c^UahxC cqDYL'Ao&`D4˅|KP'(`0`KKQ]];U](By͋'2k,` **_~KTY! ۋASbu M5I05~9J@ᐕ &yu)+"FE?x W!B*:dU̙3Y|9111:xՔju] ikj_¢@S |[VLw{xHNN^<5l@~~>/__B޽ŋ\#?h~3OL{訨".\Ok|VйSG&d?y8>W$Sv-4s/r%իǧҠ~=ꙗ+{v&v6*o/o^ǙnХsG۾˗xeڕn_!˟ !/4 W_W_濵 z*~!tM?O?zt/Di( \$H) 9x8cE@s^lN}䧣26};H\–i6Yu.~#?Xsͧwٲa5֯NڬZޫzX;؅5lܼ+)\e\Ħ-~06.=E!^;S,.OܸyYYYys?wY-[s?xm+Y:IIWJc[o;f[oӫgw (% !(_۷gL>)SIWU]1Z+LQ/VU̝+eHN$HBƅsr}T+ygף͙QFuBBק'N}>ƏEtTQ;%.e[0>CZ={1~H[&͞L<ӻdgg3e8}r~Ǝ~H"#7=L?5gܘjַ"$4={pyvфB!O걃QQQ4mڔe˖믿r6l3g;*JՔO|Xy/Xf+D(&d695i['%KFN.--0U!ZDupp0ZgJJókzx'X~N&''rmʐF͚ uHMMsj>TϔTl ^]JǺ ҩn޶BTNy}eBTU\C`Μ9$&&OGySpr3F?bp[U,~/*|( mR3h֐Lh掰h{#&&/QVM,dGhݺadg0p[z@@mFF:DGG9KDEEgtt._f9qeǪÅSVmocӖm߸'NĴɄKepW !* V.qqq̝;Q,^M pvV,[B˯nBT~@S#tM'.Ȑ 6Uū!tgNf=i餦r:r KH\Czyʕd.w\$/<Z,~ucygEl޵ur}}=tɏMO7i)$gimF׋%PQtXAYhi-=R׆LDD8NǞ-7?m$VYOAߞfMҧNaGxѲEs~}z3#!::q2nTWΈaCJu]0rD&O}Mn ? Hݺu:)LB\\q`0Pv-˝%H!‡)|*|@UUWi|#x<$.[W^*cԫW+Wx5thxgڴHakKmiG9mJjDLOڐַ)I1((Zs3426bؕMn*rS+w~i2}ڣ}~`;ûQC,|!{m ǠҍF#ĴG'yoygpp0O>>' u+0 cF1~̨"twg_aؐD!B+ 8U=^_|؈1'uZڊ: {b }gϴe2]=u*)HJr*iN=Y`(#W:R/%3$\9h=?lΒW.G\W3IIIe /Ա] tTB!7d#Fw\^]b^;i~wkxs5`<] ӦN.RN%5sSlm'<,cG2Qbk:/(!>񓧒O1|r9oϾIceH!BQ||@UT)<ԯ7onOB̈́?hZ9ԪY*e)//1lnh̬3ufl\+kJDٝ^=yeďB !R.gfe{Rv2@֭Xf= wٙ7VMVN{Z=je ;;L6n@V90?QU]ǫB!( Q:2eW#;!!Ԭ3~L*Vlܼ8.;zyW0j$BCۧ-ݺyNNN߱3T3MV.9Pt;1ﲤ(_$( [ ),沺9n9+K;t.bΈt+vy,i֋)%R7^E10_dAZĜzЭn˱[s`kIScn{ˁ?[ۏ"?99q2R@N( ZZVQyժUpMs8sGTRQQ007kn^nvO)ʆ'6 Ů_mPZ:[:>ca [o!,wK%̻ (hBf9yԂ(hhAuVtk5QPt}(-x`$ە3t4KqsDum{,q]t5s 9,51ilgkkA^%nۮRmK`Eu4NkA[Q h$.>D]$ κA?Ο?O|||OF88B ??\-LSA.(@PFx`!FTS>1ս.yˊMuS(tbկ[n^pY/m nۍ6`@~fw,́k6tWs(m 257 %[:)f7~Z44u`99dN(a8 0 F؏ mkBR̜ pN`@h~ !( kGK 8rPU|= qqq [i/_СChJ>Ac]=(MSI'GTUES5!v~Bp:{_p,H![-S lwsR5ߞwLwٵ˧E+xmW~D@dXw:N} w oOU(tv-a ꨪ!lŽ;z*['zu/2fؾ}{9T )|(}@@SC۹˫NUV5>:eNuP#.7ڙА(]5<_Qu sO;tݮS[8[K;v}izeԁüw:| w^0=๡.D)_ e9CG]ֺMw49`?*|2lS<46Ÿ"GuVf͚E͚5Yt)se.ʯ~:.Y_(!]'_5PFrN՗@Ii7m ?ֳ&`aԨb0`ƕnE&淶8~*vYc7wP)G8M -8@-;֚[/Rut Z8v܋pfDX'XGJؗ}>+vVb,9̕رco੧bqN˼DEEѾ}{V^];ǾoIʷWںI{oZ x`0X Y6&ڤ4kmk#RƟ!yyyj*Xa7.TSLvZdlOYT(`rl+y ӾLvקZN%';EMS5s5Z˵.Y?;͒fwc)=P% tt]'&&aLL iiiEL&^z%&OLTTTyU(%\k_\)Ԇ*gѢERU6uU[#J O%i&"s ( ߿nѭ[7EFb}ƙ?}b2P43땕E}z{l2e|H43͝ݻwKLT4Y޽Z#-&* /Ms>'8wqN/8+p;*.R]|=u7]Mup}1adGO?ອ@E!==?(={j~e6()8?w:f=>۳?q55̏RU~ϿD6? e ,ZǽnC?g& yCir}=z1t9m껣d\d

vJBBBd^+gYҜ,;%9fqW,n=|=m]ѼgqE\xJ\UgPVMΟPN52Jdy Oف︻ck}ss/3fȃox7t/1fHwBC7oLgId#}}|ӹq5+)ηusr cޯZofޒ|a[َ'{K믳8xP53Pc6s׆!#3i/ >{キXe۷i֬,[͛ss1^z%.\Hll,5kt({qhРsrt]xɫ?6})II/'tv}m9U@{b_vAԾx[Կ4+ JwʙeQvbDŽٽ{_5ղ5l-yEQdQAk6~&L 00ٳgٳgpgXbع9oh5w s-.UY0+YQuwlO;s;;7EWyJ~i-*Hp}`@VpYDU ^|agfegdfr"eRY9DG:~vvk˛] &>5of8=VDx(iDG:v\}6K$",e~ ڵkKT.""eСCoժ~f<<@NIi^Ҽrw'ٝPOǵ)|W͛Ӆ|ŹZVs߽rמּQY֑(4g≧|i#ŭkѢ˲]qj7Ww2eQF? ?|>͛7|%.gggj{FVVߦ[y~^{tQE(_&Z Y}a!eާZm{EXXߦ[VMTkE7~gy5k\&3+Zg4k\ϖߒjҸ>M˧i!]_ڿ|Y?{Eߤ RCM "($ *EDD#6,E ( *EEJ@| d;33;ٝپ~?ٝsw s=\:vF7ճS[:{ =d4o._un3Wh~_CTWW`[aa!>^.\pfHLL䍓Ԕ:g\kDdg7))tr;'G<LMMѕI1wT*PHOm2Nۤmk/S*HIIAjÕΛ7?5#,ȃK>WP_3B_F3VXӓ;לq)w X=߹s$Rsc|O4-n?` 0׍3\_Ǝ1 3'ŜDYY$U$%ܦ:]OuCW S ɲM6åKѹs@n%4k֬`X2__17epx]?qnx{kb\eZABݥ_[RX_|#+.q߶Ь1tiH_{d66}3Y\nI ,Ԫ5xQz]LG˦8YE`ڀc<܍)-G6wC @'K,Jš5khϚ5 DM=/_'u11Tdff"5u oP"##7:rrrLz :hW59#&&999a7U(ZAA/^'at@teysJptEQXx1ϟ8v)eU ::GNN8";;ד39e(?,bŊHOOOGjj*222tlNfRqA#++ HIIB螑C E XС_п ѪU+>|N2`xr D5CM]~瑽_:FBxx8&N}ݏ[Xb9"##ʂՍ_`oobAZ#|?**ׯGRp4oQ (Ѻc::M}CZ5v~NLOv`ǜCuZ7o-{l. 1|`O_ &:b6~/;Ш8zd L999`YAzz: ~Ӂ? M@yؾ};vލ@}$-믭?cǎ坷B^uϪɬ-xݍE{!ƫz*"""@*}9GD< 1b$҆=R/?ODrct/t%]˲8{ %h4^V{%⏵0Y6 ؏b4lؐoy0@~:tP~וP  ljJȕT)CH&+ /g`tnU*!g(ˮ+WlqYbS jpY ˲kǜE C++la;􆻩n tLL ?mU/gb.ܧ+zn/ź׃\=mR0ZE|?wgNd6[q}שᵕS>dgk)|y;1U~ 5~pۅ騽GE3rڣN ѴiN8Ν;#77֭#~|'֭%ELEߪny9YNمg#X|ԟNC_g~'jg]3yհ++7BHP>q<*Sӧz/;w4hfΜ41cЯ_?L>~,]- ]^sR/RŎ2F)92̵InRd[Ţǚ4-Cbm04bÔ֜;L6ڿuRe$pٓ.bwwj+ ؛FGZZ.\B$%%dBkd4ԨBY—lnIfE\ia].h1=lȿN>s%𕣷J,Zib:_IR1U֔L1۔Aȸn1>szoIm:7rK9NGv]9s˖-s*fji1} wJu C2uC>ڤ!@Æ ?~/2bbb  :J rc^ޅ _^)CԈ9B066xR)db'zIh]:Ph2L'.übATRlq8Cr Uڥ_ByϚgDKT[r 8pHNNvP,8?$wW =(<,Ey]1bf͚H K.6ݻwQRR;YKwJ_ z9z66MmE\dL;jilg*ZB9@L9;L!l0'p9xP?ܵdےkxd]I]ϦE[rQrGl~|lr{R٢i S׋kΔlοhEmr)#L@0 0 `Eo8iյ~b>,(0*P,?xx!"2L ؝Çcu?vFʐ [+'z \`%aROK%bLn,2gp:x[Sc:I,I.cro%Xz-ч+c-Xr-}~Xvoӧqi|bR?/(լtEۓAQQqT*|X04]gehṧ(P^Vap*BR^VfN>U5H !@ Y!F(/5bj붚 U!6+{oq-x HR,-xVc4k.JsHM9qT*TRm1ƒ 9uK#:u)S`ʔ)x'%߿ڵC||d &#<=<]hذ!<<,1͛7qQąR2"&*`˲PA"P|XĄ!wKpEdz o/oxxx8܅F5G;[ #Ə?~ 44uPn"T#˒22Lm-ǘĖ,9V K¿kk19'^i}H$%kcl}m>q14z٪첃F'ɖ- 4*--+>žj,Eҋ{@ 8O?7[oF9[br9ƍyR-k.gIۥFLlKqqd1hcpg\ݦCbrh GbU"_CWGA ,PCp K5jxzz;[ B=?9ƥmG,}ɕ!lƖ-d[3nl%r,u>X=RuPY#מQ#JqD\:*pGHB >~(/-CKg%BkjQSu~$&K pelbl`J.hfJ+ޣ,O&iMV!Lg kjRFsVH!'\SIڈQؽ+Yeyo>@7Q[S d<=߀hjM6a u:ǔJ_ ' IDATs}L{p5Ys:+` g#flTttܒ 0-]ClPba>ۂyݻuq#QאMHIIAee%&N>} **J܄ cQ2G3W @;\T􃣦yȹ> Wq08c-QUgAue;00ڷY#z]Ν; _ZZ2m@ W^Ŗ-[PZZ={Hƴ[A;h\r[Z*rҔR-U18l-Gi=ΰfYeexwr|]SBm^d@ 1w\kV"a[:w^ Gc4ޯD'[`g=UtrB˕ g9,UD6<$BEI)BXh(Ǝ~ׯ F¾`X0%\Obcc1yt:dߔ,^_#-7@0oƍ44mqqqW$&F?sLg3I;FS{ rPy[:n}Im|%S;CO}A*ee7HhRL?l"s3zkI]j5ҟ؂%.Bn_eq w} B u#((jX%/1/rB1_~Kp6`>:^8b bmiFKQ2'uOa~+^H+w8‘`}ӒOpUɲ>>>S\Ҳ2DGG石X`+!>#$`C Çh)Fk G4HGaQܩF.(c)r~Cd9#_d|ҰӍ#iL 翈ga~X@ œ9spA={ΝqW)5hIR^_ʭ9k8X;b/9gaT<~5,! W;-[k eYq p-l"K܋0}T-Ѱa<3y+ۿ4isg5TXg9ءzaukkk8~$0r0lڜ3 -p 0ѽ[0cdBO϶fMDDD`0(ubYjhmM3;1>NAjkX=~@xΘ6_؅b4i_fM̋/-CQ:$U0uK&woW1Z̑S";*T7kW5pElKT"UV(p%Idd5q Q\\~˗m6TWWcׯE;**+{ooQ,] cG? Y@`` ͻF  l,yg{w9#]:5ޒw^gN^Fm_Ӎ[2@ee%6~m\ _XFlڜӦbjxt%%WC@,senێko燭_szdnCQ_`_`'2\^@{^+W9"#/U 4FrKt7[bmxe`˥V5WRc~K3 l(r!ٖס#eEEEv/WXjb @yy9^|E'OĢEлwoŲ0y"4Gqeb.^ƌǦ3xcZfϛOy"**>l(0cTm7_~HJl`q8sFxz 4$S'!~ 0:QħSסDihbꔉ̔ EXX(:?=fPyEwg>3\ {"LeIL"sa%Zr>QҟvXc\1C}kM>[^蘳w2dq]^=W z3.,#VޔF=dw̨G1fԣt!ШkQ[SB nF\M3pUTWІrܹSh}=11ucڌYۄpض}2؎`YkQ^VO//Ppi~gn11o'N@bb"줝2bbpvAa֗^-Qd-\KbhϑlSX.{+Kabbpg x{{??@MME[` / 5UwQSuz57TXc}O7~(+O6n6Xfn@4vK[)YpƿiN%̕п>^PQQO6|r{HѷOo߰ %()-O7JFÝqOu9FPTS9&hy7$o\b,@"(wT^kKBm氻qb \9 ՖU2G[b;S9ľKi6mGeY.Guu?7`괙>{'d&<myiuS_p6o^]lXS l_RF5ѣGm-߿Uǿ{/iii- vW~yb0_Ve Z\\U7{C\Z7'0|Y=)) Νݻh>eRUUSU_cN<_~9r$hK.EJJ +_^F5(̿/CYIMGH3MZ*KQ BLl#DDD^8='>cFAVMgnV@ 8k( q"b/r_"p!cNk˺2~uĹwdbC%:: `\5ʁ`H=УG:ۃh"t5_-\O>MlƝ۷}Aa '6&LZ5zt8[%de A( 3v优)cf9 3@L#֞mʲQij5mlXZ-8{ZDFFL9q@`?r~m:tHlF.=yk+,tq1FQ"ub}W܏8G=G=l @ cLgR.mr Fw1س?M5`i(戳W΄G 9LwtÚ6\eeY"#tֆa+9ޖ##FEmy :kWغNGNWN[cK]a!\vLˑ#Gp;?)WQQ$%%YTYvЎ,@gwOX,\,@ @,җd[ / s{hgwd ["ΕtK3$pT9ioqdʀi]cǎsss[0{l!;0Pݲ2?~ -[0d#@ 3˩ךrg~ Vtp羐uGaH+>t~F2qDL8@&rhݻQQQ CTTݣ (Gp_5Օ@uUj+!u6bU .01RsmUYJeOL` r#p{#G>1аqqql |N=s[,xe>v=2ܦʹ; W a7DE]o}*2}MCx@Y@Ee%2}S~b}6t$FoCڈQؽ+mƿmbzɝ:~+[ /Oar ,zg >]lΚ5kc, жm[4hSNŘ1cH}m6kÇ~EaժU?s8pfBӦMQ\\,I*T3QTPi9#WH5ƉxSsS/-k;p& Y iW"ۑKJkiu7' H׎:6h@VéSgܸqroݺU\"݃gMGTT4ػw%54XFu#ܮ+Kp/Xyא} k~A( E/ q@4(3v,Yƻo_mź5_>j]XFz~:fNul߾]M30oLE99N,bK;w_cbʕ/ݻ7N:eѣGk׮hܸ1^|Euʖ"33*v튨(j 57*dol:pq1)"5 DI+ް%rdSz=GO]稶XUO\Tw_sbȐ!:t(^{5u޻w/^y:u >>>FLL EllE-z ZnNHh+WX@}8'"@pc45J Ѩy{H/FBw Ƅ';<̟LJ޽@^zimM3;1> Ra!;u QUy1͖m;0!жMkh.%9wv>X ۷K,z{1o@Onlp|?l"s3zkI#UטQbۗ_<}0L(dWʥ)|}|isb}`K6~jFnjG_+%IJ޽+IXrOll f\y^ۏj<6>F /")e,'//ɒPUUHfYYXExxpQC~~>jjjb…xב+W*PWz`JC5]Jop٦[\K:T]JTg;_ֲa'@ ^z? 6l͝JL˯0 Cp/X05?uPr "bbGc49߰ z#?a3S@L2߷fJ$%0a89sΠӦ"22~~xt0\rUR;u?~:yyN9aCQȁxv?&>5'NJ7cxfD",,N38~ 1͜Nr&垟gLª?ª?3OOƭ[v̝r$K ΌzPz5 ˳XR5eioٳ1|p x:Y Mhڴ.]Νrs/Yf6U>d^Sm9e1tLx2,"/&v~=/[|P|?"lKش9W^Eu-%>8( VM5Gۧ2mccڌYۤsrKJJ?̈pl3ܶYӵK226 @K?<1f6l7/f͜X|2wSgΞCeGqa>P`-n(˜Qa0fu5p+_ϱ+/ IDATXcSr6%XFr1)oMIٶQ?׮]a|$X~k(/@^Mnm>k0r`ڶm7|.]¢E|-(oȑX|9:t͛ŋxꩧќMsqU_XnRRRc` N8ҟPfs:`AƊU1x0gR\Nڶmme W^/xІw/FEE:w_PSS<,*VZ3f>*@ Nh۶-ڶm @;%4퍖-[C`nBTTU:XªMA``2<qPSuY]U6aXƅ󡑨.wQ^ZX纩okF]aQvaQ oolUv䣵ѸQ#<2augHhTc=zd 2***hт {@e$;ww6RV\iUUU3gN}:{ Zjo-[,>p,Nfm+n,B 5!xzzQ^J;^޾@J w>hZob[򠠩Geq nG>օ\3g1,Ͷ@ Gc6@II ֬Yb$$$`ҥ6u֢6Gvx*Bãpv>b6CMU.POШk@yx"4"Y C`\91ј\*Lk.۷ׯ_G` ?,(¡C!@PBll NO {:]Z.]?ϟ˲XlQZZ7|cƌA5$,Ye 08 wn#iӾY =t kqFddd &&ݻw@v{AAHnn.fϞ(q۷;o!"JZ:b&ۣjer@ݻѽ{w$I @0#MаaCY555HNNݻ-mr8 vƹq_`HR%E0 #ը(4(Pq`4jgN 7s[g ^ {g>-]vHΟ?CJi҆&#|Ӱ)|pn޹M$\|QVY@@`0LDhXԵUv֎@ 6m͛V"jjgkA gPSrmFcrej !@Q@\|S4lҒoWCP0Zò ZCn‰4MfheX?@EGNMĎ2.zs= SNԩQčր@ 8eQFp~X|ŧSNYfɖ@mM6ANp  9uj5*4~P! ۓAW-|@k } RMD04 ş(д%܍~ /ܽ{ju]Ye@ =ᷖ#F?ĢEXlJJJPSSb6i4; ghP( PX _hhQX,(bAXX X,Kg)N( Pʸ:r=Ma%r KdtYh]GZ~?9t{E(,jYx%vAxd40иD]ѪU+gDFF"44}!`{ 0m;=/Ѫ.ѤI[hԨ!q)xWѯ_?:ez3`aT%qHw l52%F# P`2#,xna' ·3F@,/`Aee8~ZjǏaȐ! 8uI Hq a„ ۷/DM0@pQ8qAAAׯ:X%۴C4gs҅# pܹHJ ulj v>%Z>X`)0I @kP\|q 'c :9xË^;2.F߻wʨ ݻG]igpyf={$@ !d̞=ǏGVVۇ={AHIIXs݅f6%7B+ۥK^%(̂%dps^^>6g? `:,XuKXu vIgS^^ K_%+"D؏_}A@`܄-# E /k`Yk~owE#FƚM_܅@kh 4Mki hZFFk544ۦו^Oˢu-#hy{^࣡icr84|]ICѨ ˵Aft5j]2VW7zwiZ`Ӧ#**QQxvtݻiu ZiG]W@ @.Bڏ(((֭[1i$L6 | Zj_|"yf"eD^Ƌaӗѯg'􆏏 qliyI)Zf4+4DF#iZ9j@ݟWш:& a)Ru 7YpCkQ| ]H+o5 (+hݺ ;!5\bqe M i,Y0oAһӯF>hAq>mYapȾ7AIE69tI/=ohJ[G~?7na8#C`XN?p_Uм I:NtjjŲxc&  ~JDaک{?s:h4Q(X3_NGmbh\SU@VM1ĢUXuDzu2TUUߟ ׷R4̙3os@  4 K裏aaa1bȖE^ޯ^Eql = #?aɳ) ԇ//gPp<1>^8z*@6/DMug? fɳw  _x |91~FSƥum֝0v9nQビg.c4acQ^QF,}q]_H-LM؝uOFuЉ?pMwYqЧ3$` 1BC:QUU@Zo^@@~ ÇM ׆8;F B׮] m'4TU[tP4i  @r&=>AĀޝDˉm~P4n W:5G=?m~>`$\|oѶ+ kW:@ӃB̽>񆿯7RtmP_z'|U{ze?s1ٗI*hM6åK߹ЬY3׷ K+@ 9^uLvھx|QQUyq䗳PݾZ?-}/BhpdmNXY7.r{yzaX^i@qe+*DTQYUe`YX!C~ZbukA޽_eOI`;  %%EtÇ;X@ ٳQRRѣGI&_M"$$DLS(!PX\| ;9PˮPh֤|}QSƪ Ni"‚PVK58V]IAh  bN]JQrh$N]H2`GD< 1b$҆=bq1BrD 47|ǎPI&[o!C`ʔ)e!0n{wnm'5 Jp%HPkhxzxrkV@}u4<>^8߫# &2 I g$嘫EņmCJN DQI~9}%2Kݶ6-3`Wc?6-׺yc:vC8x44ol:F( 3fČ3%prxgɪ:.?AAr |T*@ .;:222p ̙3]vŸq}ݻ7~w;LM ~8yx4ёa薔ܯ r@p?&&7D{%ŏ'+mm}}?DP?wl+1Wg|Mj(~ Dye5"‚ѳS]BmÁB\~ZABݥh}ti`=fѧK{7֑ + G]pkAA#Gȑ#;vS999HJJrzpOBV ؋,aذa(--iӦO DyxhIQg;W} :k71l xg"XGNTd9@Nbr٭cuL0ݒZ[v+j6 u~]][JRT?ٞMɢeAV 8k=sCL|r@׹v6ͭSIII={##{ p1Bmڴ燚d!@9%".:!@/#A~H'=ݒGL8'N`> @ = BII6=eK*H2;Ge?@Ð{C6 h!䯧ѷW:. $ٺu+œ@ ;ѩS'9rd}ػw/zel!̞4DoOEEE{5T*|X04-:NGHt@2 &Q1qqqV@ #&L{3gĀکΝßjǏHC+h 9<=<w|TUߝI&TP@J+EJ@C@ "*+ *UqAAjAE)b$@z1L2FI~62s|Ordd2εWpwӐUYa !B[PuLԭ[7x;pw+ASEQF6E%J@VA~V`v'@f"4/5il7MR͑B!z֮]uڕ9sK7fժU;w/IÆ 9hN Q"n}*7kʔ2ux{ihJN0O&=5 >63;"B!!ФIΝk}hnG4h@ ʭ"*Ee|/^ *ܲ&\>*ICQA!BQJPTݕ@Xx<Iq < 얣R cG:!B!VEܹs 8777ڵkĉwuhE*6!yG",a 2Y#1 ۷o&NHÆ ѣiӆW)BT (`fxի\g}wy O80&' !UPvv6O?4gϞח f;wɓ'8R!:eܹs9_PvԩÝwɐ!C8}4sO`քZNXD5cP]Fa40/EQPԨPԕKhvVi !\g͚5?^{ロXT*:wB﮻⮻ 77ǏY>$$]Vᕙ5!!#5O%I nc |e] @%;+NkNk<DPH8^>{8ABܡC}. IDAT_n]vȄB"u RSS *Z7w}ۗ;"V~ BPTjLE\/$<g6!!5Il޺*K61 DuObbϟ/󂂛6m> ##6m0c oYr%.\Ã:0mڴ*BKEx"w&--5jСCeA/P A֠/uEB܎z)I׈lмP2_0p<ލSyxzzG.֥hݍtsrC;M˫P}ŕ ]_`02dУ YNzhnjf燻Į+MV˒e+8z+<п/km[^k:\ֵ ǠѸ[Ne;IJJn:<1m  q+ر#}/?`޽ݻٳ͛70,Yœ9sx7 MMMe֬Yۗٳgo xt^B!DEٳo΢,Z4NJV_VrIېh ;+:Ŗ Ublڤ1^ϿVuX;y-|hXnCn^[ z\~O޹aή+QnBVVW.p槟HJfŲŬXk׮a2'OalٸNeE+ĭdԨQt:bccٰs3|&OÇ/u| }ԩS~SN*{Z-cƌ!<<&M#p…>?!vẁWaaaʢ$+C{EUd20h#L7GL%88OOFy鄈GHHo6 4`ǎ|Gݻ-Z[ozؾVܹslҮpΞ=[| f޽ RSS9|0:tVA!n 7U<<< o g¹( mGgL&\>ż HJ"ntO*lRr2anLPP`LNN!fNsh))ղJJJ5|}=<._s+muBu_.XTRRSYu)uLB*U~~~(Brr$ ߿?'Z4m4>#o|B"""*8el޼Zwn,4eUL~5!k9y44P!EvNݺvfJ\,+ۮP^Ԫ%_Һ[-]nxzx _`>>|./]xI]-`e%>QT* Ԍ/t%]%jEd2Ygi٢yeE!D?6~۟ʺL7 78z tqmzxx0㉩xɿ| ֩h$?x.K_TgF*1e#a,[&MҥK{hРgϞW_e…Ӿ}{VXuѣ,]FZ@!3s L 0oֻccxČ k4FFLR;aXkƍ_vk]hl`T_TKZБ 1:/Q{i)\9w|GLÛZw\G[u\tįYO{e5r!Jb̘1NϞ=IJJb޼ydffҶm[^z%rssrzxYv-7nDЦMNZ) !%UGT$^E13x]ٟaͺ ps ἶwj٬^V())N+nҬJ^T٢VKHuPDvCმաT.E?( JhA рäm eh::vhLja]aÆ1lذB[jUh B.]E%.OOBT8tG]6]v[neӚ0uhs2Emޕ]x1=oƏM6";;A{t6׶kqJ婨҃*dB!#j77u,5рE~}{ӯooW!Dm6;͛Whd_:t`Q$ %W_}`]̙3۷N:1gΜR=šd㏇zm.FmӃ,~Oj_po۴ZѸȺw7:ؕ1}yUkYVK6%ntGɔە?xʾBOhٲ}PN+ !9B`ƍ|WDGG3tPkB %%[uV6nXuk O_ƢW5DlTbdeerۡӧN"~:<͚M&Kl2)bb'SïÇ)um!xyy2f|>IF q+CfVTuZy !(.]AN׫W/VbDB!DU;~|A&Md߀&NHT*:'#J귣;ہ H/_qfqe[-]2 !(7* NtV[NBQ]znݚ[wBw%Zj-$'jB!*Uݺu//ĈB:իN'$$S%!P,N.PKv_E^oXt)YYY홙,]ǏӫW"jB!n1!жm[}N:UhO?Ď;h׮]v+(._`HWP&~`ܹڵ _z0`G)Bo'yԫW .pi7n\ꖄBQT*^z%8|2۷硇pqB!DQ2βeˈرc֑<?ZjnIQNLF#&_P*U]BB{ Tн{wwPD): !TDŽ@XXfh42>!P?<͈hhuzH./5=GyxeDϕp:v_޽{qu $ $֭[Dž  ɀ .nݺ2].#gM<4ZlQ!ͨס+ǭ]7TCSVIΣ1oͽ2ظy+_}7y}-[Sdl`9/xh) EQ&$&?;^zB*:&_N4ɃsYu|Yr5km`r\ln^[ ɦ-;x/ƢW6ݸ,V\ ˜HJfŲ`abƌ9y LJ>Y8b8I7De&::_~={sѣz"""ա !.U;k.u㉏wZ~„ ejԷ Rxoi[6S{YtӲhXnCtTvVdY{%nӢ`ESzŭdR0&@7q;q UN6ƤLΧ 0iBCk0dNbŪ5dddZ|cQ38///ƌvX_qe|~ >>>ĎS3ƚ (Ie|h#6|0a gbl +39. <==՗/(`<>ybNX*aÆtѺ7ؼy3F_N,Bn,SnlْQF1j(vj}o=z4qqq[ 2Lh@㾾>K __Fe{۝t̞E`ƌO̰YqY)ͲzEե(`21&1ULNyɄI:GgL&\>ż y$L/㊋+LX 1 ,U)X߇LJJ*aaU JJJ] C1:}ggQ;BT/_fϞ=|ܸq@ #}EQh߾=ӦMsvkL0___֮]뺀B Μ9.c}}}xl`\(MǦTT8ZJE;r9GP~MjQ#7cn6)1l_^3_xGzfARR2<=fL!4&._ay' W\wVbI5,||||/"#j}ݺz=Ӧr׵ +Va_}ݺ*[;?͇?s^N̥ߣ>JNN=^zPXXz#B!jܹ#GPvmvJTTE?ܙR'2^"jҥ8RͶy3b(*5JшO@N&0搓rǣPTE?bhv ++@Zng~t /LRR +;t V]OcĐAY 3#''T߷ŵ9r,[qx{yѯooúFʲ @.5|hc)(~90'oBT'ڵO>o߾D|A|JL!z,|I~7|||Sdsq)… ˴}i&1SOnvM+3תXIVkhwWRPMA(!'e媵 NcђeDFf|O{f>\k*?~nݚmVrdeffҧOW! iٲ%?#wǧBڰϸq>ֻ4Z-Vr={/8~x$ Bǎy'7ꫯزeKj߻ե2 (d2 #f*2>LFIP+4 ء# vuHBTK6l(r̀k׮q*B!\G\zuֱxb.ohԨw}7qꖄ7 ׷7vuBT{Ν+rM&MpJH!*2!`47ocǎ%$cKߟ .8_K3!BT9Zȕ5 Q^~ZB!oߎ=z(z;wΝ; /عs';w.S%!`00 CEqJek!'44gһ7gϞ-׻ #B^:BҥK\|B'۶mcvرcyW;? 11HbbbTw NύkWx2S͉!PTnF.3Ru֍N:;pQ>\BQ5!Idd$`O??{,III 4n3!Cy1"{lb}Ʊ Pl6o7o/L}&S~PS~yeL&0)0i[VQ́31嵍y9.,SQm/okLC-t^y15ɿ6e3g=@?E;=oGn2ᷟ~E;Cn2:FQE 6G2k,4iBÆ ÿ~ IDAT_矉dȑ.RQ݄H!Jk׮4nd21n8f̘An~___ƏBeUdBh0pӄFNN~^ۦ?vh!ika)90*yex#Fd(J^'/&y7Kْy$lN8wX%~X]Ě0v1sbާ`=D&!L&sYl:P-cɿFy%cyS xh4rӴp-Pd͠סV;.JF,^x>sΞ= pׯƍF.RQH2h0*jQA___|}} m f͚7^E*:!`2Dp` F|?vN3`˻ey >u@>;1' &ywQM%`}=%1 |Olk8`cޕSyx#F!/QwXksͭ#qۀ!la|},\V&U*R1՟ӇD;| BL-i֨~˜fu^OX&62 SڙL7-c64d`6K-_@c}YX,78&Ţm'}( QHBA!Du#!DYTDŽɓyXr%QQQ[Ō0_,G >HNcSk<ƍI;~& (qF>Z i`w:6wywYo ^}W' :}_8Hl8zc8fgasP^Ҧ\yZH4tK-{{%po̩Sgɡޝw(tМrdB!UÃ>h~J_^gfve-EantǾK{hnڡA<ɩ|rtH:a>ޞc zsYgGsFuhIZ^zr 5y05ɱEz=(6~]Q=ۓW0ɱ(M&~%WQgW4wsmF8Q= WC9I3 1? Jo0cw:mw-[p ukǗߝFӬQ=:3( >k~GM͜7ךUzI>7 Sn!7zq6CG3uD<==9v|*BzΟ?޽{&vdBdJSF<å>JD ;.E.mgzv`4rZr_ z2>ݍ_[i;]o4޴s_6~{ti#[2kHty$W^#fh<5|r>= =ym)=a08Տ=y]{bקG;7|GFfS@Ѽs9\}ؽ~σ]L&oQ]Zi#)4zn-(zmtwC {V8|ݺvakOT4cFHJb9f4ywf>wЎiS>rjB+ri -iƓ'ߟ>Qv!d<%.m$))uĴ)ԯwg9^]!DI;v^z ʔ!Ed@S3gάmyQ\<5E.8;kZ}`]>y<9. ˖~!D|2qqq/d@VVBQ=) x{0Bwe֭deeF.]xg.kW LBϿI{vpO@VԯƝ\7WNj4jGRtk4mZz{1bCOn8:ﲶawޞ$oPP|>^)Pwrj:N:Ss|S:-L(_j%5-@ǥV>V())ve _pۍ$Llٟaͺ p"˖5fK2E6VZ.z:Ν;_>CR9-[oÇQу'$a4={Xf ^^^4mڔЪi~qׇ)i|O{kR󲻖yۚUGO`ώ>GO䮺kܠ|O;ّiҠN\YI:9x鋒cp$$$ՄDUH``o AŖ7ǎMVx{yàaEOm( >r3isH Eq•y>3[dZ-m۶]v[7?୷"''sرc-&!vGQvm,YB@@W_}SO(2OaPp|ՏBв|/`ǨE%;i_dͶOԦu_ns8Ǿ?j//;6;l<3!ںlY9ԠS&N;9/[m]5hhߢ/]d':"&ۋNQ:tia{5糣'X#կCv͋<=[}ʀ6'/=dxsqw'!1un+Qa[7snvz)Ϭ'7;o@՚5kƗ_~ɓO>I߾}YQA-[tps=?Ceؿ? .~}sb0&&%K0f̘bQZHLHpuB!Q] 1j5Æ \xƍK;%{젓!gǫY7#wkլuGVN-SB cvhRa=ŵ١U#:jdW?~.yݦR)G;zu g߮ECխVx6<|_eYѹ­A6ǮCXv8K߰56Kzw؀2F eيUMkN>1D?:_&)) zaS'z10Տ'f~7EYfm-[$--+WYamW B꡺$YݶIJ˭bP傉W>FBsu?xu"#xa3Nh4L|pmPl=@{;H/=ńJUs(>C 99???) y$'' !g߰)EE/B'*^u L&ӭB*gϞM~t:Bq{yyʕJk8~8{[F>| .*裎GEFTO_>[mBIOOh4ZG $%%Y9U&dfVFB!E"""~z4[c߾}˗{B@^wBT7n믿=zTX 6h4rN}hݺ5ߟ;v( &L(uG_š( ,VZ\r\kӧh"N=z`ԨQvB!(E&TBv9^Tҿ0ss$! n߾}tڕzʺ]wE6mxd&b4]ZrqKAѴIcV3?7XmRRRٰiuߜ6_ņuDD&~:O>ysٲq:%~^OgҲErOFW_`0~8p 'NZȑ#;vB!DU?BOhsQ^j7իѼysLwЊ*‘/HIIh4r ֮HFwە[ziirZu6W;wwYJ=##+WqFŖu4 AQu=z6m8ܧ( ڵÕZCB2Bf SO=7ndx{{9*(4B 梺:8e+&(0֭[25kژ)S";']:1|S'z10}ӧOsYunݚx-Z]w̙3ɩڏ]/єGgоu(^} 6V8|<[.LFNe+8|K<п];Fw7n}6%//>Q!\A !*Z_ٶmBj4h?]B!Chh(ljt:Be<==]6kצI&ߟon}D .;~f M73ӹӽvݸIɬXL`6lb}نM[HMKcՊ Zbw{w,Z:>,_5609.NW0uԳHEQPqu(BTY&M\|0/&ؽ{w6mB,KD EQՏ;vϱ<EQ<|ys_&1֊$($r65kFf\BQUTB`͚5tܙ RRRغu+mT[.!ifb4X?ش=>ɋ?[T %%%>99ZBۺDܔv,Ik>9!BvCმ;W9{ZtxZuPdn3f^h r(^ ĠVxBTw/_&==:upB[ŋ裏HNNח-[oЊdM:9x鋢YF{IHH$<< YOHH;>007^{Bu ɢL9d]C憢8^wSOҪSO4nSAV&Pgɰ&E!fmʹм?$! oq zި;ds:t(cǎuUB!DS_zr2X{ڜL|CŨ.T8(uR}]bO ׭u?ueuL: ĊUka/]BCjrn{~=W!J۟ }7L&]#fx%Gvk0&0%@D֩kف%1P̌4 !n7>? s"##9y$6lAUzA#!TՅkA6d{ 5b(M%6n*AAA>Ժİ!0v$6{u~t͚4_AÙ":w`3}GQ&THφ.(-iNAP@C Ҏ^ P"]Ab($ E4xwDAMٙewe&53|g0wBHQhcix}yB 5}*RM᧡ЄDIO}bb`외w \4o CE@.GJ.\ȹe//`ΞÎ]{p=#1h3x~nhB"OϏ@C}8i 7oѺUKQǽz{[h֬\ۡpQ2%^JɊ^<'`ZlOEEHDSvpkظ~52R+bgZdE)[7#ef#=s #YL6J9]O2vŲ+be$3 }<lwVaC{;Ri6lq`Z/_yt._ׯCE3{#\+֬|2d\}1i8W:,qB!C(@,!Q_XxS{69MӦ $8!9m2fٱb֌i?&Og~2Z'1sdB1kT|}hyC͙paCPYY:qO1nټ;A*"0 &ùs5˥R) E(.)AddϝmQ3NFpƢq>/F$ õk-ڏ駟AL#|5xcBCC]9N())חy#Bq(!;.2Ҩص;F9EjdQ:i.P(@g{ bDG?EˢPTTlQ5.ĩ>i.~iv:,})2G`@fNO BXnR1>@ b ^P?zk7n"Z\nA:! 2R8U =#=sd˗dry.4!$$X,44kW@xxBBu@fֲWYS&k.GeeFY޶my?=lŞꄀ5R㱆#IX{ſ^߹R2l8gB5cM*!JK#ѣWxGKJP\RǴ ,6oن`Y7nª>HپE(*.FJ \j%||| <7|p, ΕV-[೬èFAhN`` ܽWyS$Ds#(]ƍ%A~uBH}nԝxW@}& eUH$igTe;CEB>Ob1e#YxBP 66cF4Z c5e;f$$&kmآqHݑGxxF$쓧5{x+Vr`5%'a[oAa:}ƦxHx /EUUUXP"'p?gѿu<*I!nQWٜqS \{]r4S;^ ﵩdGFu.U߯WyC#!<5 \٨Dǟ#0JhhG#:*UUU(*,@nO!!~?#8i;*//СCikYrH'!sAdy|}}uwG;t3_ޭ+਱` >"tfYȕEj\:!ā,iXP#~vG}rvw8 eqjdѐEEb;!Q1-ٓGP\ODm]MTY ZGpHjB^WUmنpnwka WCm5컔+kizm"e2䕕9b shi(mmi|8Kty*Jd?pTTTĉH ו"%%?3Aaʔ)y [waVsH}K%~Γ3qTȓC\2KTB@W;Nc7VϪ`UJ;GPBܞRDnн{w,R%KYfqVZ>}3uc h{^usfԚqVMgiZ{ gϸ999Xh5ui7"]!~"==]q]@.m kg\\rrr4e:GTT9qBs M'G"Ġ & ==]}͉]X6nx8qB>jB ^az_c͉:崏10t>3:}|ùZ׎YvyC.ϳM&F\|N;c]cLq;`f,c}k57dOߡڟgC_ViLxxeF=tLT5r`q:a)kRmgԦ8Em#SG0#wѳGwWbw 3ݻwYYYXx2M4AS|<:מ ** PnH ''\.F\Pv&B6րjF6µڍ;!2p@M\ 8q-Zu!**JӘhPk#6333cݺu: yask%qI^LswȀ\.Ih7vRE(3\΅ 0p&)PWttt~Bxd2rk !I?vaҥEVA7ymc&~ҎU-i'I몽o(L d0ԫxnDȢŋq\JBx? WsڍiuGFFdzC!xPL&3%c> }'lwD립=mx\u>sNNvվχ~JHlj'?%~c>^+^?1'I=ὢ$^r9ZDAy9bcb裏oS(!TujrlWUĿv㹗!,$ e 0hZ teu AHWl$/zʪ /xp=&$]VlȎ=0ЄDoH[>4!ӧNBGPPx #%u.\˲눗EHp0@Ųؕo=XØ#1aԽ,dűߢ ={t$ܧ={ KGbgNR1 A)--7bҥfGd kܕ]׺j-u-QL\G?x[1tzkm~s[{vl29KdƼ䒱 ֎nma.K^cSϙzۆXYnjEs1?hַ6~Pqm۶}۳ \zǏGQVVM67|`S]F7O'nap ˂eUXj<jg8N`YPVũj˱\6Yp@`` g 2rqO^( u3RlF^^>3B#H ZS/_ׯCY AHOKEll Rwigݏnc5ؑ! 4 WW##-R)vݧu6c8oVX˗=oM}4tz*޽ @}sUTVV"//'N@}W^7QTTB"P3.`-Y]197s'X{@k#OT+hQ2Y~"Gq$fDLCzUؓb3ڸzPqo/ ѦM$''ҥK(..vuh&}BOjΝ#2~bp'1sd#$$fL'Eo1u2f߲y=:wT*E`@&MskH9  Či5ˎfc 8}'uKR*P\R̟;lo>@H]N̙3vZ0 $̚5 W\˲{ְ._˗/cر5jF9s昬cNV&$j1 5nط$s,=wF hOgvPk% 2w\obqt2D?1۵1t\M{&,n#f{+2:z0F{̺ 2@~  }y[}zCTCC@}՝h&T7UL~`!d93 ؒ%K_ݺCv:ˊK1Z"B[7&,Lw`c>Xp[>֭yOgYHH0\4i x Ep{su}VYS&k.GeeFY\ԽHhh֮Z0Qumx})xga[g-[S!:V-]-m [%L8zc{\Uغ)oxnl!͛5sGy>HپE(*.FJG0!b7%00w3[NY>>bt?S(e; P^^,{~ؼe?eYܸy _ok7;`Y<Q3RLBڅܚ\ykntni\ 1c.:ݶ;s'DLyKuP1\ v@ƍѴiS4m111qVZ;w`sYΪ @hh(SJM6Šg޽ﻩT*rxv_`P*cۧ'̏1a<տ7Fx][Oo85y!VR.ֱmMeG3BֱzKjրUO.~#!Æk[:Kta+ÎY{t]Ű{^qz"[ipƱ2WGL339jǚ5k䂽]._?S\۷Į]ǎe)۶"?/ <㝷)!ynvK_s/-ѧO_( ؑa/h~::o85D À_9f]yHrJ+*#bU겔eFR)̝&&35MR8:z@aC兙Ӧ`)ue#qpcvlڿR!'u5c-4i]݉c{]߻S\V\]_?#{=<B Ds\ƍWXoBPP#_fǰ`"",, /Ǐmp;5fd ?Eɢoڎ4~Sǩ!2CnRo/DIYT, mث!ۈremY[W%9>c+ntwضf aG^w!bu}#GPRR9sh<x68wg?λYF#&62Zbbc5[svl1p"6:N 0ڮU nɅUJk#z}JB{tܱ Y!UW=-NWmb:jqqQ:꽳'g}ˀ5wqVq?UСɲweaaw{w"4LzyyJwq[oW_âKj -oK7u"uBzEl "6R/RBB܏gwg/ x;S8v2{a)ONַd˺ ćnM]f?[(++Ŧg~f@lܰ(,,Ć k1`@1WM۶؛*afc[7puT*<21۹miSC0 xXK-kĢMT5@Ue9=JexQBH)'Ξ7,i%q)ެe+\q\]Z:WkߝNY\ צSՕU8/FHkn Amހ,<)u 1qb(4ϕ!<5 \`U5ȗElpY3H$^Nӝ=u:Y|cQ/BǺQP.- ahl&z˔cС?ڴu;Q'd+xJbշ1/}vtiիΝ;8rROey;˲tCu3;sABe W.]GuuPTqX5P?0 "b./?)$!㈱)؞'&t3Wn؎:wΊǦ6qŒ;][okK;GM*S!9aiBy+A{_qgs,8ǫnqxϳh0 }eBOE W]5.>ְv=kX2x m"=i|T}㎓2j'YEήz8a0+=L;=p< ֲ7P\X7󜋣&8B'~:oaWT a1AcQϻ,섍33%z%wOEc-TP%۲<趃փx_|/P}^!~s=OT `nj]}rRm8MЧld2]7!^5s_?fh~-m}/{khHCF@ ]f͞N\ap<p jEE8u$>(N:B'Şݱ6F'n iЮKXy]=%jjw-Oغ“D< aΊ /)#K0Gz/ ADD Z!=N4ɸOyodKolH='&txk𹲅z37߆X> @=tˀ7 | D> ]I%N" ph^>Pt$8U]٧wNGgغ|F`VҜ7dz1 JJJw޽9h@4nܨ^}BʕˁF\YvpG3'r7cCΜzC=2dB[V#(.̧iIYMs!H( #Je]+$??_ΝCF>k.ő°^Kݞ=.'o^rߍM'6&OSXV|]}ߝ۸~: ĉQYpxBEE]k; B7[Nm5 c 9kX:T16U3+yQg 袄!NԪUko/_[vaDB1tI7Ǿ>vNCEyW%L}ozr\%XՕ,GGue9ՕX:y'Đm["Q r2<'Ja$jm:kx "|1a8޻cќSy̖q[;3ý^%pGwx]55-1isg GIuJjȻmеe0 xÝ+h۩'j d?_(N;`ؐ9>κCq$뀫 $4 a<ω+eexwՆ:e^_!L5<1jwsu8#k!MLLς?WHbn(!KԐPQVX`$4m`ӛ^f=XoC2m&<տ/~rв= xc5ѲHthY$z쎠rϚ[ *krwfWYw?'{_]ku:/$d2@H$H.\ĔI EA" qc+]Qcl(*.FiYM2۵a¤(++qHۓaXz MHDֿ`$ >d0#i.nݺYo֭ۘ4`Owk"uGMOơk=9!aL1_q!8y "@QXz)Ci,^2~C8!N~k̵941,9+GY2K/Q Dо6 _RiwVaC{;Rih>Wǎx_bpkظ~52R+bgZɘ._ׯCM]Գ࣏wh9^Bپ0THց:,2[iHe}݆?v4ۃU++& !}_K]ƍ%A~uBp"(7-k_BWY4 };J ! _l#0SfF:Wl^ JIܹ>/~ ,⫯!ǎY3!"<x;uB`d? |_= BDˢ nܾt #0 3OF'[oC0 "QaM\1t?0G`mmUUU jl'%!^۱h0D~G;vvM*KtBC1 Mc1s4~kaIڵ QYY&jdݏ~}{_GY5BCCv Y6S!Z&CӐJx{W_4BC@ؘQs޶my?=lŞ7 | D>I 7"t< v]j"!rrQ#l a)1-G7 ~ ?k&dIYg.ϊ3֯>5,!`!}%/sw;0jDꇏRcn300wC~Qv,7~~w@3lܾ^cFBLh<4.xRDŴBgOAqa> )cv7QeFFh6!QBؾsF$Ă=vhص,cFz<+9bcc0@tl+4oK-E)xǪ(@iO-m,سq=,}cX{OIo!Tuj2£[N!eu%*ʊ(4MyQV&-PSM's!<5 \3 ^@ ԓʎ1tz`i^䈓oO:'Oo!^OSq\ ܹ3Ο?#G 00!1 @"bqwN?pTTTĉ6Hg+v!-EH(ь0!4÷$B!qD6zbOxj!<͂B@Ͱp~2ZjY'g~chB"OϏ@CEGBe)~;w0m4uThBMuRrܽ{pUH$jgݑ/eŹt'*%+K3cY0(J B()g0WqΊKJgxѶ?y ׯFFZ*|RLK,_J8l2woGzZ*bcc#MLzBHSO:3gbڵ`III5k\LzC~F t ^^ h ߀P)̔b JWHKmˊU@^ǎoN8s.Ɯ-kJRL0Sg<8sCX M9?o 3zfy# +V0Hx'Ok3;vƼKǘѣ8.^*sAqS3%axЮ];DDD ""BnQQe˖O0H!8 E BlH0Qu*|1Jrk Q]QC0=o 0H5,۫gCaC兙Ӧ`)b12)q^JS~9.8uV^ u p]T ҡQq4i: BH=B BlH <AB`*;yy8NJ .wfno.]\N%tV &<0< B!ǹx}:!6RCr̭!B!Q(!@!B!Ah_B!B!iҤC vP%!B!X&(!@!dBHD=tBq:\!4@4.!@!B!4@CB!BH@=tQBlı*(+Q]Y*#r(+8/\ĄI14!2CB!b !zbcQQQDYIx3Xa$jm:rrkwz&,.G8*B!B<%F7!k][v#18ܹ+ݼz6s.vgENίB-0jDݨ^n{lQQB!CCtQBRĚH#iE0:ǫo/%bޜYõ7١9-!NJ%\!B(!؀ 0&F"D˜-o?FH<أmŚlx;OOTr&$"9i|B͛adnR3._(8|h?HI݅ 9,:slt;aO^;-*гGwONc }.CD!BHCA b#\AMٓBl݌-} Ś`_Fl1}$@+`՚wVaC{;Ri&g5l\iJ3-`06$B!_4.Jb#/ bʖ!qce>&#$8!!5c*>):4aňavufLۖ9R)0i8;w6fLCDx81y>E%.}"B!%tѐBldv1e5 BqI BC)**FtLw, EEŢFAA}}}%bXnL~;quTUUI t3ԥOB!4 F2%>'O>oLHH0\4i x Epë^^^/TtXfO] U=nuBCCv 9$&WE!BM* b#{7f4~@iYjjjp叫xoZM} eN);п_V-[೬èFAlMhq=J@yn.6ov,6oن`Y7nª[ؘU!B!  ooo/9 >؊}"<, F&3kD Xx)N F4X>0"d\!&\xcc8t4!B&<<۟$BqQYYpa||| J57n à͚5onݺp73uTn&bcc\C=o'//xvU8שL4I&֭[Aff&:?<\r|ҥq+Ws7_|3СW]uf+<'Wu8vh"BcmlظpTYGe+qff=4s_'y5s1ZlyvݡNu?Gd^ciCǃL,:C b /ّ x>pW_>sNb*_ ze/KMM%==-[4bdM֭[ܹ3={j߾}\Ϯ]:۶mkxS~~>NN˵;2ŋСIIIr͎,{1&MTaR[˾v۷oG4w>??={D4222 0aO<yyymj$! D-h{ ?A^=x+A=p\DGEqş/ iUWwTmn:RR sQRRS Y}GKk&%9H˟Y=){e6VCQ7QJU[h(V[!11\rrrex{aܹ;~\Zc2vX-[?ir͎#::ѣGWXWٵKHHYNNqqq!c`cQݹxg;رcӦMC)Ennn qȐ!j3Ͳowϴ# "PNhfi!s~@nٺW__v P!I:mKYLӴfʍHɒ){e6V!D8ekK):xi2}tt]gʔ)!UO>̙3l{=.^z%@YU~7}]^~WUX:UHxn mݺ5ڵK/eƍn/oGBRXX=gf?]j?%4MC)uz =9$!!^ؓ0yۛHJJJp_9~|:՟A&mM_\\C֭$$$4bdMSbbbrk|1-͗ ,zZ?ݻ9sfdrA-hѢ]vモkv[l!;; &,;1bdggζ)((,J }Sl.ρ!Bԁ/<]p~n`͛y#n7{瓗칾q0\aa?p_xI#;fϿ22c&ǟafGզ>Uk$8z.N:OeC<Ⱦ}ڵk#F4u҅m/[~=Vzz:!s˖-XEΝ<ކ⩧b֭<ĄkW=wUmС̝;9s0gfϞ mƵ^K.]X~}H?N8,bӦM!iٲeÝH#;tyyy[#B41WO ?5Vtօo?JJK:dxgμיS$''ql&m > ;;-[r .SoR\F5~x^|EvJZZ/'t;vlEAAر]iٲ%'113fm۶c:wͣe˖s1rc~3fj*}QRքt]kWW_}Dnn. ,rq'.׬ 111N͛7'55#G3{l9VZ_ FɬYN<;K͛ǠAHIIa⋴oߞ={b|5!*ƎE&0 ;.)hPlxDÈOiͲed:4|}8䓹ێ`/'B=3ՋݻwOyf9묳i/gaz*SN )?1¾^1|5k ׮<6l ''zɓi]f7bz) ͛ygٹs'-Z`ʔ) 8޾g}e˖t:=z4SL hXs~z󉍍L2y/oo7{HbJzcdY_'@chպM`@\B Eh̃*ueݺu&L`ʔ)ٵkW^y%G;lQxh۶-Ç;v`16mڄ4hp:+3h Y~= .l(DC!2e@ )(}jPj䨅rXt)Yq.O?7t7xر7xº3<ŋӳgϺ DDD0rH vm۴iȑ#֭[&$ N)3eh|˃BQ?Jvv6k֬ Yn&K,aСY1Mu0I q!BgY 4|VX 'Ȋ9묳%uBzԵkW222O8p|͚5dgg3fJ~w;Av0a#Fnҥ|رbcc۷/W_}5+}]v܉%!!Ν;3uTRSSKIOOgƌ!mcg̘A^_)oܹsYp!| 999+tؑz--[FVV 8${߁̛7?"zɴiHMM'++֭[s7WnY~!| wtңG&MDΝC:Nn7qe1vX233!U}p}njôi{kb̝;͛7STTDLL m۶eҤIӧVX% !DS44|(N)O1aTʟBQ_FūJ~~>qqqo@vҥKm>#}Y5\d;SO=Err2 !!{ӧӹsg.#^N;l.\E]ĉ'@-ضϿ:u*O"11|lΝ;%! D$! D2z*߱c;6'::k>!Cltij={؟Gy&qqR  `ԨQ̝;/ǓǪUaĉZX|ɐ琶5ݐC=sdee1{iƵ^{gOЦM& IDATi̟?RfϞmg۶m6m_oꫯ2}ܸqL<^z3gٳga6a-ZĀӧO'55#GZtЁnݺpBzŐ!C|맟~tԩFx$ !X }.qr+>$yy̝3KX FLl4*L BQׯ/f|XřgY| a0j(B 8/͛7ӯ_?0hٲ% lݺnOQQWfu:}!R|׏HJJm۶;Go"GB&[t) ӧuׯ .gv2|ר]vN+Pel2ڴiS}q< h\udN{$PDDs#:;;$uY<ܹŋ3`),,mwM7U/M͵o۶y~znwȶ?~<+V{%!!ݻs'3r Ge˖!sss)((`ٲe,[6Чt"##Bw׮]VHNhF^^^Ⱦ7ʾ. Ͽy7M׮]ի#GB СC=g,EE *8C;^aYmR4k֌;mwTοgXFuFuXn]W{qgv?~ˏ?U{@IѴ<ʾwHKK0LEQF*h@;PaY#$B@!VZqWqTNO?͵^ȑ#ILL͛7zj>S7aܹâEHHH 33;yd6nȴi5j]v|OYz5~zGu 6իW믳e)bڵ<3W!ݻw租~ߦYf1]tA4}]L$<OiϪ\8>ħfٲeD !hxSN%33_~8I=%%%|<̘1^zGB4iIu-_ɓek()B4 ۜxҠ !BhƁ?~<,Zv21&Vwu]')%%EDFPRO\b3'ӈQ ! 7eU 'Աc:M?"I!BO"7wi1Zv0B!OU4Ҏ I!\BNV&i-:.ɗB!B3JXi˲*|D&в}WJ B֙ɏ+!B!-D hF|R*9Y;?$e>tMM8 !BQWdȀ5p:93"bh޲#z &9^YVU{CT(/ <|<44hhXhῆ7 ُTB! ,$獤 G)lЬ@>O πxmi4,,',e+{—cPX8`w})7@:!0"$QW,ӬU~Pn_J}ok?M.0C W! UB!BTEBԈV吁/O'2Op9Զ%ڶ(rZ~ܸKm8g`\0xj:ɟ3%LbY%˲8m`/= a|j6m @8k@N<3ѧ`/,^3-?vx^:wl9g%<LJiz-`31-sSiٯ ӯ1؞11?85ƍ7PPXLZrJԤ _4YB!"IQ#Z褂Av.[`˿[Y\=q0>f Kay7`ZFzՏp9Ysdq|{8dse㈊#di<? `Z0 _.as*eu,7zh%Tv}XKV8chY;w㊋FbYt.[HB@!B;!?KJ w,{7uvp'ӡ3l`/f?c_}01 MvrƐDˆ wrГٴm'a`;g CDm? C 4Bf8ڤk9m@O~ٵ,40̿l;~DG5LJL*(B!I5ʯ*tFFSX\Blt& om y_ +:E%FW]Qq) qec)*) 6:*Bˎ&=Y|jrzn[پsDxp`YRR B!aHB@ ªakviMLT$`dH x}ו$'/ 뢣"+ 1>"#ˎ&?[&pWns߯1*f2yʀB!# !jH)*ޙzr LӢlj툍0Mdf֑_a>Ds(7Uk7sA8]yg?ljmYl-g ;Wobtؚ/aX|-];/;RmCqh:9|US`}] G1oFZviY²,5U 0L|N%?N) Mwq/ueo6؟W? L4Gi>k15M*1NI!$ O`ׇ_R\ZJ+i\<4M^Q;Maq)I 5d/5ڋ+cpn|z=?_W^@گGgp1UFGrJlT1IhlAbt(/?C_yeIk^$Uɴ,nC99z <&Љ >.HÜojuٹ?Xcmc׆g6 ~!OO;ë4 zK>SlظG1*6¥䗸9}ztF<﵅Rgݖ=VXNlR n>iB44 Pszc"DTwp˼/,GjATc%W *:>=KYfŠ W3M/J ޻ɯ I sA q88wJRX0 y3bB3z,Sޗ??lu>%;^5en >0JH;NTs8*ps$7|7n!>>+VT 7t7v4/> qqUWι3?cF k 7C)4f@'uS*KbSKzrFXڋ/$2/θϓ !jD .<4l'+\~5C&ZpCѭ09{R1]( x+'H-\8N {HHHyZ*S޾";o Yyf=Z&.%^]S[dEXU %d=i~*߸+Wj_rb<C39tޅn^qM`W(a_Ɯޥ[0&a5 {ް,,´L,3GNbK_"] #M$-0UÿDSJI>@4YE p 1(JKJM%%D('b3i fϪ9^~ߍ""#q8JReXp84\Rl WX݌ojTҗS0}?u]c\.~ag ]Y%NbvF8Y6V5Uxť ~TǵLMőAffxgp<ࠅقfz3‡w_r p0l0}`[{P':oIFf{r,LLP9,=yB +a-3v5J!IQR!Ih*oȜg9)Dj|s EFR`ѢE[n,^sS'L"''KdTNӉM2MP +(48\ERbvj8􆉧*5Oϖٴf.cgYȉ#ófNfH% %Ҡp囘h>x4gxnr3fM(o5frTc{^{YLL G;ĉ9p@b0.H Ja0-ol` 0os=!kC |P!4{̡T4UI6Ѹ"f=wG8.>m5=g"<<»N!xGCYDDFfw8|pxb={PGf_ bb ]HeY$'%`̬x$U{ I4{L4(.&ВqbO? xf}'SMܰq5ؠix^N`dgtr<]9u]aœTNRtIahI1x&ea:4-&10&D&eae`Z雜v(dZ!ıIBԀRK*,Mӥ@@4EzHmLۓzҬY3n7)Zq,u*=r AER,roף4 ӁԔdP`Yu%'7dmuXB@oޜ{K<^I˲ CIM%)BGt,BWn :$뤨P3_Ywq N"h3/P!aN0NV5tCuFC}08=-&i5L,2ĴL[6ю7Y6!vjBK$! DMhI)X4hzt'I)2d@4[ykiq1c}oBHJJ"&7!1- wn55<^/ΈH\l'܆AaP6 S,ES/ !|e/56vŋ _DB}9u|?0]t>#Hm㢋."''}r/vQrg`~Gk xM""7^4q:t _rL i5=d@RBc$-8d8~\Cvh< )9OyzGrI1`b£s5'LV]H/?NqAbZ><ӢQmv._YxHMN(_gG1jJAb|W]x4yZ*{33kϽ 娳 ^=*xQPxt݉e)UK]BvNC%q=ќQ(Oѱks%?|=_p%&q͜qѥ\,ZҧB:rrp\8wU'* ۯM׳xTeYۿNySYM{qa%%JC\ Ok6E3t.w;0"_^S5 so **P Oh2O!ʓG0'8LÃx#BT]~:rQR2Q XvסkDSvom:{EzR/,W!"2"^USXTDaQsU|ɀ'``t3FmZCniin×.|{^= p 7駟ӧ-ު ֭wޕYn[Ew\>&R]%,Q2R&4O 4}աa jB4һ0""c1dpGxTtB%e-7(7fʍNbB<{e!?)-*ͲNPB7/iT;ow˲ x)(*"\7&ֽx}3|I[:6=v>DFFr)sIC'^s#sJo޺->Cɭ]5* hVG^)-qcx<( œNe?|gdVqlՠ;D&tBzűOY&-Ƃ&*tRzފeY޽gZp^6ZADD815[{4&1 ş x ]Fra1|Nai薆hO"!:KP麆p*.ߌC|Ik(M?[V'iwt+qc`Z+&_J-0^ 0 ^/rr9X! 8HB@jLNBQLU X^thތ}U< ~߳pke*t ZlQ#?E%OUN{]rK)(}}H gս˱S"-L+ON.@)mVI,_^{ÉR֑7px-x/vL 2:y{Aa獨ϲ|4QVee'L\Yoa!D !x$(4f tH qSv:Cyž|~-Ӊp̂2}>ZmR~zMD46 K=nRJܘh0]*:ViF{@Ϳ' @ZZgEi̴h;;=hю V? H =$aއ$ B$! B|'`yQV1,A??oۊs:)u{fxJ[[6x*>.*aٶ=O/CѩYBuYO=)#|IQ"oZm+?gAAAh^fb=h'l{>CWtoT=P?_`]0LlA2LSVO(B!R(p&xKʪMڷax^", wPg\C C)HZ7#"Kқb<ѭ5_3S:gj`.2,7&F <p׫wO'^^{@=I':dPc0i! (_20M B@ I!D:I ^7?̫eC׏Kj*AYNf$'W@aQ.<aaaDGEKTTD nj+׼sZ7Z{ Q+]ӡ ݻewUѧذam~Ԕpn{ ~RAV1 MȨ_"T TCfL׿^bBƠ{[oXBcʴޤM]V^nm2sryu Ǽ>7mġkht+s7Q K=MC~R^sW4%FXMCK !^q?wO'B!D}ybǭ_Gi0IirB!BdIB@!B!8IB@!B!8IB@!B!8IB@!B!8IB@!B!8IB@!B!8IB@!B!8IB@!B!8IB@!B!8IB@!B!8IB@!B!89/x4FB!B!Gg#/w}{B!B!DÓ!B!B!qHB!B!qHB!B!qHB!B!qHB!B!qHB!B!qHB!B!qHB!B!qHB!B!10 aJIB@!B!8F%rB!B!DzJ\'B!B!1$x B!B!dȀB!Bq& CB!BcXUdȀB!Bq j B!B!aU !B!B!1:dȀB!Bq020}漺M!B!MD^!+$o B!Bcpw߷g5v,B!B!G}{w=2',hԀB!BѰt41nT !B!Ǩ=o~~jk_/~s'б !B!n$4͗8{[?bB!B!D= N G!B!XvuIENDB`PyScanFCS-0.2.3/doc/Images/PyScanFCS_icon.png000066400000000000000000000227411245330745300205020ustar00rootroot00000000000000PNG  IHDR\rfsBIT|d pHYs N tEXtSoftwarewww.inkscape.org< IDATx{|Tչ{.IBBBЂ/hk[۷ǣoxT=XOj^ZkZE;! !e?VF3̞=3Op0_YϲRPx  C @1A(c2F @1A(c2F @1A(c2F @1A(c2F @1A(cl5YB6, , V>\LF~Fڀf` XSSvbBQc5YA2|/yҧ"QG+3-.Rjq&71XMtMz`7tODؗ^;Uڒ ]J&,rm f9{oR<橞iUW^^$XpV5x`N0Ȳ9P=V[ Wћ:E~+9uwKoF<7 ٤~; ~Vn 4ZMP bkjNc^n fXUR?w8PĿM #=VVfLzfjj8O.\dՓb1`px^9\d 1-\ 65y9jkkTs\@UAs.Ĕ_zFy,.x 1vgfL )9u/B" ʙI[,쓏ε,w1 \lNb?53 8P6]<륲p:Dbm膙-[gd,ŝB[շ6^d>'PB @(4R&=A?BN(E 6Vתm'(bBnאa΂cE5n;SW)(c~b|9GF4-b4J oEq*\  M#;.562`72658Jjv+r˪Q /†1 j kyܚPFjf%6px"6;fs_OB}?{9v<h(*G֘yIxprr^h $f{Bp0$aq$ʲhc \R HSʸf, 誦$6q b5Y7 ,+k&FeV,Կq5)l8B*`6jzx*ȩ@}YqTcTsK)] VU}3|{t/`3 jnk<hR|;վ=a=^7% $9Zq8 C׀ƹ7{Zh;B6%Ux)%wÏ]SPDXMxtv`=S ;3k^ GQתQ]ثi7ƐMs,Tvrp!PNp T7Ƹ[fUMdR< Hrڂa)Ѓ!a`=XlD]d Hi}0;zSҥp?D؟~Dըj K)5-ᚇ !5T O?-C0l a?"+Pd#Lz8)^O^AwQG,Dٓƣ<ըe0@@X'6x Lv +ؗЄLbYLzh,x,X=J٥ͱ+F91|j6תCl-h3$ C/Gܶ"g\UI29il uŁB7Qkfw&I=Mɻ5ihR;1bvYazya^`zx h` B/jT%|YMG1;Q5y|OAq$R0C| sw(V~dwcd+>qx?u$R̠ͦ?c2j撥.\@FR?ՇY<()vHf0sQ*""d:_>E%%7T52 ]l2jF3|DW/:@6F0VBh#He,B%"~[\)~zmSdDV  |aT2+fFIe1`+&R!1\AFf]h#H|,>hpBob^B< Uل^-hpt9DoKQ& a^ROFћI&%Ƽ"ⷥhbN1mv$GwS S$"-E%~pÁI]:=+2m{sZfXM'Rt1B@0}~m+rZjDfA NFcN U܁1R1B2| c~T !WsI]sQ_ pnXA rVRoKыp?ezh`j"~[V'LI1A18Âznɰ =$Ȫڭߖ?*Āv DЩ"~[JJ P BJ+N7$Ývcߖ? `:IxH ⷥ$b`Y DA B=<=kk"~[JZ PX!A ځVu,"~%/~Ȭʭ>bЫgvowX+hXG LcWW! 1b*`Wc:i3Q|}Љ+g Pbߗ%ۖmco/g8"(!҉_t ZZ`s]4i.Dg(2?z1#EW6{=SMB 8Y?t]SF"݄Q9n(r 8-˘(&`..E'9?w196 4Z?ixB дD8 ='5 ("4.řg2rAF aJTqZvQ]r x /bҴiZ ?·d!^;+ #.ی 8 `\X$PSQCಂ*5B5х1-׵w(!~[:ZQ .XGVb*ƠAͳOQFu{ p8)cO%JLܻ#dےapppAoH< ڱN^zӏGUÖٺ/`CeCM'>SHRjZ(vw~o|aΕ_,+ub:F׌6 o~-uy((r)-{C{g~}G.|=LtfӵNp7zsŘK\ox<-+*o~hz 9<'o`%S.[ke38{0 y@ _?};ݯ۹ Zwcljs40pN;ZE ȸN~*j?AXʃgpޞzZn"Dm+vn%2A\LrZUO,@3$OW^QGA'ZŠcv*e Ұ"귟'j,o:ꖳsS67 >'r+]?@g 9B׾\L%>CWwrS'ABQ~CHilݽcQvT=+!ߔ_3pQc@ع޼,^_ ?p6-{b.y7|)Ufߠv|aӹeȶF촧 >ѳţzB0`"#=!w_mڵ:as 9gؖ/ڶ?yןţ[10RB?p)wvƢCLmp܆'j;-7^Bm w;+ܕ2ƠDLFA Ą1`lڮ}48Zu*ݑI>?dž LE@ pS1Aө9C:+c+mW>GŜk8 b.yJ)<'uCm=ўC~g&9B@"À)YG@ u<湡].'5nm]A1|> &28w5b.cFxv쟌ŠvӮ^ wN_qxL1N=ewz՞ܓOOq7b4MBJ\=+*jYם{Nmkj6ǛJW`N^@E.C[O'5 w4識 zc~#"^;Ԯۓq ].ۿO?p-hh?^ra=^tQ!C\DO6ߊ9)iHQ ^@ 1P`@PEؿx= }&&MTB2b.b|Vv#7! p}x"!b.@FdGTl>Ysvp%b.q`uWot8UmEYQc[m6\cpb]/tT;kJe|,0J11j"P6z;'-v>59~]XenxcZp1qڵu yPh{'ƶ!CF֐|Zp4R;0%b.wz)]^$u8K$;.3I e@rɓ|}Cۆ)ɸw~׭NTPIH\ fٙ!ǜp_V9QQ=;g'lʴ18:Zg HD&I@[^ Nm'js LWf"pJW_K_k^kʱ7`2^ 2`TEkV\uG s!dXGl y@gO/̞g E@Y i?_3a0yX`ᦅL}d5z dd!vUz=}pd/ .!!@X~.@}pl7`8~_o}P՘pt;pgOK+NSP$Kq5_a$n8nQś{&-T;BS@lxd!-dJwMx `re/vtoTBY#=^ fJ) >Pʚ51YٲB_([d@kWi--WA' KA M2,9^ ~0Ȼ[ߝQ4`Z(}c PvdZ 䇧7P$41epS@ ߄!",8Mn@( XXzRb Pv$L=#߸/pBNc$p۽N @p%sNIJ\Q󬽻]zTo[SC]_c_IENDB`PyScanFCS-0.2.3/doc/Images/PyScanFCS_icon.svg000066400000000000000000000121611245330745300205100ustar00rootroot00000000000000 image/svg+xml PyScanFCS-0.2.3/doc/Images/PyScanFCS_icon_dark.svg000066400000000000000000000126071245330745300215160ustar00rootroot00000000000000 image/svg+xml PyScanFCS-0.2.3/doc/Images/PyScanFCS_logo.svg000066400000000000000000000135501245330745300205230ustar00rootroot00000000000000 image/svg+xml PyScanFCS PyScanFCS-0.2.3/doc/Images/PyScanFCS_logo_dark.pdf000066400000000000000000000233251245330745300214770ustar00rootroot00000000000000%PDF-1.5 % 3 0 obj << /Length 4 0 R /Filter /FlateDecode >> stream xTMk1 WV(@irS6K=3nҒC-poœЏg< =TD- r{x73 Mm*D}-4/Jс,rHW.bBtj!ZpUfYiV/qo 5yɜr`88Kv*F){J;x”3p}  *K8d=EzfG UT9usSjт Bk4CkŦ"$z@PVlSYX#M5t(&A…yU`w1NV .w=uֺmn&fuO[4gf7Ʉv> 7#VZ,NJ}ܮ> /a1 << /CA 0.804734 /ca 0.804734 >> /a2 << /CA 0.445104 /ca 0.445104 >> /a3 << /CA 0.172107 /ca 0.172107 >> >> /Font << /f-0-0 5 0 R >> >> endobj 6 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 624.549377 180.208176 ] /Contents 3 0 R /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 2 0 R >> endobj 7 0 obj << /Length 8 0 R /Filter /FlateDecode /Length1 10120 >> stream xz xUhs^It[wtҐYX"4$#1(dP;H'AM+xg"8~}.3*ߝY3I:VUN(@/0p-Z| M֭qB:զ]VzPL^zW/ɝKX#N$$n?/Wc%\;.ajZcuǒKG>bɗ*nU0T HU@T`Uƨ-Aioo_ L ܮ!0M?hCqh ^1+Pb"鵗#~M1kXKPvfsՏw0}>'% j*cBAIbT!5hȰ}V keVgLKZեt[a>qւ 7uy<j[`:3*QWCGǣ/_:S\DZ+*tXjRzDlLik*,X2fLy#q9l6Gn^?lRIcӸѿ}7E?&k)FŘbfߘSR>8c–2{֝= @SJj X_+Ia6h7wbBJcTw'4ܙr{kV_SĝK~thVopk F mw{(r s0/II|lBl4w "31ͦ-$7SWeez2=\;q<ht11H 2j˜wnUZIPfVWhr.9EsʚzKѥ8P*G3|ڭa|uWm$rGbKŏkF]n-Ǿ*RjXU$1A߉y)qCJo1:lԴd?"Lٗt,]v/Z t:%E0[1ПFI8uY0w|m饭?O{ mAʧ'jj/z̗*`ḛ!0g|͢SM.)2!  ~?+2Szak0y>/X:gcΎ=9r9_!Ϋ:hݾ,VԜfNΊcH--7K.2=ʵ3ž/-@ͼW쾘N9ϾP_--dsq,h/Y4gd-y"Y-O>r2G3yv9vid _5RQ8OW,.,.[J|#nS w#&Gĸˏ@ݠG C4s%" F $YrIpkӓ!!)y}n71+vx FE򣣒D?\&biXÓH+%!:F4C0G" )E!J}u_I/|%Eل_=1W`f 'Y:O*J H 3.'nI.i7$%1XZ@ݸ^xNOI➚q58I0a&JOKBd^9CZ p;4A/r3l>;>?s N;`'OS0v0CjQӋ%jRFƑ yD llTdY. pN=a'sH l& %2*c~+|=#igq]; r2p|%y|H4!i4-&IOY(;Qa]Q-=#E#UTԓ.0=A/Yu Qv$g_ THYFw XxBKqB^ #GwBe! {/4e&DkiPr|TR&Ы4|, }:>@+:\ֱSt/mcG ؈kՒjGЍgjbJ[}qp<|r44V}<ד =̃ Fϐ%oJznEsM$oM&] Ep#- ~ydwMu4ϓ6*Lo60zCa7Sd> P{ڑ~!q!f+,n [$15Iw "-s\q?F\}ngԋ+HJm3xڙEl&;IJ٩2"X҈?9hXG6#7nߴ>|q>M@}} WC_}X;|}]# BxN2._V6໡;V~ڦ \V'cwF;ǯJNNM헿Hk+J:-}(\ӯS aq;V"A sU`>*uIo(Ϟ@*݁y'= Y8;>848h3Kz9Nx0.C!І8jN!A8>AATa 5`> XK϶{p16 7v]Bvvvv.`Mp]H߅]H%wsSuiq 6j4,bN <籹%c5a6>${lwu\O2w^-Wj]o):^lfN6Mq/v6E$߆t F3"!}':gQMې_Όpu:T@؋pVa=&KVK A# 0Re(; g TW 8s̓*vr(B"4!8O}aA91&Į8v~A`M= !ЅK*qBm BPCuLմMәޝ3ȸtL gpDWsA5[-Q]' !p+< f,YJ)]@:QBD(aNFJ6qL6f#,DM;ynٙݲsq.7j܃$t5cQI6޶s":.`%Ņ-hXv`yv,۰5L|u{+WX4@ZJAmL hACrmZ_hn>ݢ}EܢEТ-lٯ̯k~m_xh (%r 2oP  Ia/a :Ո6z b_u˜y1/2pC^TTAU@Ve<*ʤ6duZVjAMՠ6 K~Z?)^ r[Oc'?f)LH k&E03L4+<I'Z"c*ifIhZ<@C!EaI<B6oq(4dT'*~ kcwyqVsdF(RRF5ǓZA׍бG4~&kzB9ur^brYqxn@ʌe,fe̲ Ɉ7Ȩ΁(ˈsCOxRm.?2Sə #_Dz;\%gpǢNۗ 3%uZOk`ɏ쩞X_?y`}pIzO{]hhR{{r?1Y;,5Or$AA֤$y--01)h8lC]do-ڏ@~ 'עkk8 og%8roh?B~glLK:7ɿ5 {p,Y=гQ5Ihcs?69Fmڳlkxu}k83  ?YKP MA&N|ICn˃ endstream endobj 8 0 obj 6976 endobj 9 0 obj << /Length 10 0 R /Filter /FlateDecode >> stream x]Mk 9nn!C?h`t 1'l :3[{+; 0h> endobj 12 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /LRHCSR+CourierNewPSMT /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 11 0 R /W [0 [ 600 600 600 600 600 600 600 600 600 ]] >> endobj 5 0 obj << /Type /Font /Subtype /Type0 /BaseFont /LRHCSR+CourierNewPSMT /Encoding /Identity-H /DescendantFonts [ 12 0 R] /ToUnicode 9 0 R >> endobj 1 0 obj << /Type /Pages /Kids [ 6 0 R ] /Count 1 >> endobj 13 0 obj << /Creator (cairo 1.10.2 (http://cairographics.org)) /Producer (cairo 1.10.2 (http://cairographics.org)) >> endobj 14 0 obj << /Type /Catalog /Pages 1 0 R >> endobj xref 0 15 0000000000 65535 f 0000009309 00000 n 0000000703 00000 n 0000000015 00000 n 0000000681 00000 n 0000009146 00000 n 0000000938 00000 n 0000001152 00000 n 0000008223 00000 n 0000008246 00000 n 0000008585 00000 n 0000008608 00000 n 0000008879 00000 n 0000009374 00000 n 0000009502 00000 n trailer << /Size 15 /Root 14 0 R /Info 13 0 R >> startxref 9555 %%EOF PyScanFCS-0.2.3/doc/Images/PyScanFCS_logo_dark.png000066400000000000000000000104011245330745300215010ustar00rootroot00000000000000PNG  IHDR<"4sBIT|d pHYs'tEXtSoftwarewww.inkscape.org<~IDATxy՝?zYQTܗ$8G #Q@#'#m#!cCzdFLP"j}hY{}w]<[5m:4Uuo^}{KTI'`*pUHX jmk~$ )[S(. BGQ>DZ wjnm[mF@\I E1#|X 0jj4k%Pk2[%LA L`|v&dBW:7ڄ %2嬐$`v^-P^G?e^X2+\]avC_m h[Zչ#@۶HR&OSgEALhS$BYe~5-w-"-PJ7:@;*cLLTŌ|T."B ")3 q.‚ZSiWKE S ;pPRn:Un6S rBtzyBrv@@*P,yzn_5&*w`jKQňGKfIwj9,iZqRrrSHDc% 8ԙX3FD㧀GWcQpt| 'at؀k-pEA<:2L жh k1*rXįAdNj L Vut}*(!F^d3E0Ur!Q>&+ :p!Ds ,Ʈpd%J~xwZ^ld"ocǕ@XO.!e2 !-)ESĢ@yșaΞϰc"~!"]$9\mUU]A]lZbfO@sV`0],Ux?a/lm}Vw+M MbyCXzl0'*5 LR/uׄ P6v `>O0ed5?q*؋~ELgYpx^EdOQ`"+x&"[D90AU<.芹4A EDDqebK!0^Uzo`8CDJ3Ģl>h>PzR..wC(tP#9.3XOy㮿p6<3+USI\\.?6vE߃8hr4vrOnrp#%\NR* O xQ*|et`M(\Ɋ眎X UXYW..`.wqXba=ID8r|HDO0 )/=WO<~Mr 63 ^a:sa%oaӱG1<?P6jФ ^(>`20"IiuVe1asjWr灗&w݉XIN"ܐ6د^]D0G X!~ (e&y Ϫuyz˧*o =lBnb!~5ƥ9b"6gx("oB%h"Ǹd?,^HP]$< _YUáL@+oc+"Xm5 BUw췾 xDDʱU=蟀1<_I'Bs!P ]шf EB*69"SUf1;p_-B{Tui n ]ȴ86|IruHt\fkҕcsDcu'1MR[mi+~o8_DG@Q])8xp`].dy?C+0/P.pm`r?PeC8`.6^ $?yal>B5e;l>L.\‘.w ƋhP@AG1/N>VBTٳBUߏ@D E$YB 1Xc2DݪsTuVÍM֩jԄ}tpTs>@sR%%"YUyq~0q>uq1`ه ,YPn"f"22Չ")"o^Bib)3 1JU]KDJtǭwX rw2ܗ9~""&`-E$[Dq)=LvAqqs1R#. P1uGBuq\՘6]D`bj(Y"yĢNJz0RDt}o\7K=_{'M\];23vQǽϾ'~\'2<S< $N`LV("`M'%ĝÑNi~О^a7>˺7fn/\M ?qUMlCSJR)<3W=+ɧp?ވ=^.`^ЉuXPe 6 Utjֻ]|"r楊Rw;zPx!ֿH4df?.G0f50[UOzD$+$?Ět)Uta O컒M 'Hl+y\&A 8{*`W[f# \Atu6dqah,VMcX)u$8q 6pDxbϾ'VmPN'ԍey ͪ,t:*g Tf {`sdʱS+"Qm% D))ԛ *2Vh:Y cCOEDeEU}m h> A-B}\AJkG*}ʹ?˸kVdc.A#Kv{ad0^kƥOM8)QE79^+iꍭrxUU79푶4VĚqӖT5r8,ew@إlK@;$0ìa'kxu)&|pKyhX  ؄2(byH=y V!n<\OsBԱ Jb'B&}|#-F$(E+i5>,P$?sE "8Pw.HyN@Fjv+GbSIENDB`PyScanFCS-0.2.3/doc/Images/PyScanFCS_logo_dark.svg000066400000000000000000000136231245330745300215250ustar00rootroot00000000000000 image/svg+xml PyScanFCS PyScanFCS-0.2.3/doc/Images/SFCSmodi.pdf000077500000000000000000001140121245330745300173310ustar00rootroot00000000000000%PDF-1.4 % 3 0 obj << /Length 4 0 R /Filter /FlateDecode >> stream xˮ:S:(J0` Nƌs9ߥc. FkV "|,˶j{y_?_m;׹_g9^|%_QD; hsQy\U:W/1x/OUx^Kko>~WK{?wg_v_^wGsjo/~oW~ݽ~9^ >$SwR{A6>o1А*:5D_8ۯ8_߯ciQgxʯv7_Q}tZ wƯ=z"}]\^z)(9 E> ƍ{1^Y4[>{çם1^@_1MbU~]W'y絕_Hcu =w>xuH_+qC>~$5>w$5_Xszm ~w7 nAcReѦQ5Px[0$AAS! ?:FC:چTGUY5A;XªE0YM(G7&iZ$Qww xtu`Cxc`h]2|Pc@|%=jPTێ?Fsj;{pT7>F+S-+%#:$QUtk˃j ]U3 Iu1F['y}A=X?En+J cׇrA;%M+cz,3lDwCA ONrZeWm1LmljC waMf}5Mn5R7Jtm]҄a'c*j- 1ZجRVS( {"~O Ʋ?Ff~{\>Fcf厱W֨vg< F?:_swEciv.cq#{L21٩x O|Ϭ$=⏮CKػ&;ȧ50`hm9 3i6'FsjP}prj~?X(~s3!ј 'TO^@ICjZG9OHv.C?O z&.0C_K3ޮAbr`c{<|}lEQz<>3-+w@xQC6̓WT\,_)1J&c3&նtBa,qD5\;mceLܰF[5Zۑ!cBڄ~k~hڐנZ2Tf @9R7BT{?[S/#o *j :b󁢍(=՞$5)Z4x%chGs r&5Hu؋[5TȮ۠/Ke $CXɀ^)`oZH+sTFc>Ur0 ;LVR8 V=mAF̓X,VokAZHMk/* F͘'f5Ơ㧍~.$ Ʃ:G<,>4j׬57~ֲr/"yy?8G(+4+zH մzcZ{(, TPk_tFvE2̆5K%cxOvOhs?GNM,": ecҳwtò|p[(?2tR9l&9)pZs8p1BBmPZޠ'}e0ݶl + pyFA@ޛr'&8ypd-Ùu|F|FM!ȑ3)IzrʙΜɑ7gysXcpwV&Ekݳw!Py{e5{'';YCYNLN)E( 1;gwG5f5h-K{Pƶ5ڽ`1#c.mp ZrʷtcLkrúYQIQ=7:2v np.>N5[* !=Z܎'TaaH +ЀisNI\7T fǤ;<ƛmW652}zgsؼKHTY((+9O\i erFY;16tYyo'ƨT86M?쿺l}Sb@(:x>(i_`i5ӳp*L>I-ɨ+ȣr~b2졶 *ٟsԢ먅`nN߭7-g\9RBz۵0&oSNm0fXh PB ]-%68OpG.ɰhc- ŃĠWaK }2nVg>W4NQz:1=6ɧbxBWj|k* cPC#C Ƙ~.ҧC%FGkyQq~q^U~gGzue"M$|\ \ 0ZS>㾗W{hcw2ЃaOc>Uƛ!~KCf~6~gzrOT'' uw"jrs`)^ Vr*9a׃Qaq?Z)<ŨoT :![Qɺv"_Kv1C֢%&y.2o;K5Yd4&~䄰gASQ-MΟH%ސ #!xA%- ~/O?7aؔB;ȱUhL0Fz%yܕfQeQp4ynkyY :sP06&̉ނQ-HE%U\@ih6$7MoQ%YVțҩOC9ABV5qvmT:=8C7PCrK_ɟ.tPȅXnnh;l _f@1ؐcQ5"I%@Klf,@gQG<]6oQ|ĩ +W"}bՆn+W5Ԃ"=U|*@5@V1*7aUnϊ -1UyRa3U>L^H-x*҆SS`+;T@J&~T3N8N h4`Nn"P19j6<@L!K >0REDd]1H ସ W5𷗁on].\DdV.(7CFX ܅ڒn2ƺvs H6vww Cⴀm¸Zޭ5ۖ~#Ї^_^BWߣ(V ApOꫣcZw8] VqY7TvVAqROJQ;~ĸ[l[/FRpkP"5`XFs\9Ջ^VP;!~heC@k͍SII Ѭ`Qg&(5wxTMPbѫ)qG nT8[Q+<. NU[*.`&_ p:͜+#_Y;; :,MLB|VA) qnE#P4j08"5DY.Bݗj16@!9Ӥ"O-m:#O聃kNvm.@}8C]MecW:p"rmaa8ڧjH(6@wr[0e/RAUR.`$M&x=Q @jm=4'6/4%rGp3yKE2v6@Beu(']j O^Af6h!f l񸉗-X!\#;JKS^esqhŐtud k{BOruU@ w}c _(= 5<%p#\5 ;j WjcQr2.pK2 ouBؿ?Y"@{2kr>oQ|B-r I m=l4fo(>fyFWvƚϝ$+z:eԢ86BU@H;)u@X5Tka *-&ܪ [m-DSZ `Veڬ^a{zJP11HvdDmBU#U[QEFOYxb;}ϖͿvjrNݏe%SJGntչ籡s`1pJnmet4@^6-T_XV8%aw,s0 sÔJ2&,_^?˿׿n?^aNL0'V :wtrOۂG|Y!l";`ι"?a؏< L;淸?~9?p[4oj5䔬P'' Q'dk75nSi0Rׂ68x]qJu^u_*aȒ4tͬSc:8S/zOm (6:[yA$0v k>2eDHn#'= OzmmrԷ@r*M+9]j m?6ViO 3tLFՒ/n[->\~# G:{dcժ2>=A@?J_L;eA5Xr.˃EDj(-9s=Dx, FȖr)'rY8hǷ,A]=sꝇ^h<іG~e09"Ic% q) +04Bw*9[wxv Zt/>Gi74{|hMayt=P"'BnL>'+8=ҸzL^298x?*QU]\yS7I !Gʏ]K3pEs4sάpeg Mkuz9I홴5A xti\,]?,|0 4 N i< ;'[Bq:#~;)+ɈMNnŃ֑[\.<,~x4uq87;cQnzg#%ё6:X !rƹQb;;n]gfd9! 0,TJ XsdK s2~%,G}fbʝ0`^Ѣzȹe^%+}V]ٸZ8'Bcّn&}NtP[ܝ>!`NQ/uD~]őG\'i:5+Ιtzutsxr = 5a)NK!Lؓ V6DDۻ<:;a&C en'@,;ywg~|Tti, 2G*zs%(Žq3*a`fӊX6%Tm6 iT"˝")JSvJΌ``ֿuҡ *RT@ TԚJPqTtҀE9--pC؅ +ҀVO`8p[tbTG)08WQ^ʹhm_js.]OD0b4[xc!SHiPV3 Fߣr78yF ]9ɔ^r)Sy5ntcd-9t%2PeXSϞi AV&-y4z̆f߯9'(*xD%C=NJtGoMc Ԕa*lۑJ3`UMzl&xc)»\~gaE5=^ڱˌ~Zy9G!˨D?BLr63L iC !˨a袴pBFy.۴ԩ8k6.XPίג5 z'Ölaa^2kَ&Z1˂ՑHXp }#NzJoWv8h }5^rF"'o+Ct쏠ף?d}X D*=jmкz/9wo57-4[1>[ҁ IzA4$r{UZOXi\8oSG8L У'.gj='w`S)4;!1g ҹH[R1{V[AG5M{ 6&kHΏ1ܽYh I%8՟EZ]l~,c- vKz0m\M>=G7Q^ nBIbȷZn+qEA4>#cHSN5MVx/C<3y'5 |prnj:`;8ّȃCqkƙ!uZ9 0!hy:X V贰a. PD&"v9ىLUߜkui{hcX''l+.O8$jYMX´ Qv-v ՜vuP͸R)YKPg:]E/mZ j5p8 9iH]q gz&äda+;lT#LfG`KeluYAҮE-v窴lHpԥtZnݐ@kF2} s?9o8lp'r ~q;[2>|o{w579 >(ҩb}+'2 }9 tJxVS4ۑ-#m.Q].)Ž~vH8'!9Ub(HqtɃj֩Z"'ǴoYu컦FGL />|N|0.I.g}sQM'>?. wQ˾,38^Y!YҘaڨh6OYŵ?l*-4dJ800x81D!5U$BLztu2z 'gjI_oZZ;~p3v>ǏMoNpͳ=؝*v0Fkl XrduZ9$_\?Ma*x|gPy  ta+se{^}g# twm8y pG #yD@^y\7?NbS8ʢ|eyGwOĢ{ ?n>vgP!' oz u 7'{>P3ASC2rC&iwd2E/gEt<0_ a'Ŵ/Q]ΐ!mx|!jo!k9 WH2JDZ/U򅠷j|]Z#cZ d~`.<薵x _W>}!WȂ`7RE |phHloByF½ɨD6 ߅*}=9՘vfT='Z ~'/@kIENe!胑X5a=Arx%=ܻ?~MEI?9!ƪX^l"9DDQ[V0<Ȥ=WQB|XR r&)ߚ1J2g\o8 1]98'tJ+ȵc~yQ!p@Yݕ4gn}698+w gO(-Cx|,Bv#T..=HM>[6Ԝ@io>e|Pvى=#C _Ԟa9%q̐V'tc*" etQ> qCP%qw$!8s[!|ĉ kJuZdZ \U?9{dMN 4qrX}(ab7I@q`ukM69$^F}ecRjy{[KuqL!97ONJ{t@pm=, %aw$>NўIΓ*8-Etxi>NҍNG`I}I;rr8إ =4AZS}r'*},a$!nSɦirЧ] $Iyy o*a71>O.>O.ÎWQ'JPp"{(bh'J}(ͻOHsN>T5zC 0Tԗ'8uKIYL 1wMN{|iWz)'C;55E Ea,(b0o<Aq !$^sas}YF ցԝt1OH:`64whqDp)Hہ 砘yJ8-Fo:MsxCH_P^_ Kr^M Iźr`z7la6+8JYa YٝI2Ve7dk.))$xI{Tبp3'-M ZZ31əpXqiWjn=uɉJOܖV04j%4MHTiw\'6Y\AkvtGjrٖqQOaL:% Hd'`{ ~m)ݤV@hTO{){*<bdlX-ѲW"&'lmDےE6#^lIx?z?:eHO6d\"j4Mjۖr,x-QdZUgNrc-+O\)>WDg3VeZ6"619e9,ˏ(cbX\ҫ`Y޽@C5±i˲%,KѾlL5/rRE晒ۖ%-{HVbNm8EpHgLaW+`0*tDEq?NSED.S}uV\/kGƇ=y5$Ҳ`%[: rœrpH:"QYɱXZHL2ۚXaQXXqeR±/w4{UHMJrkLvufv[V*TiqyK K kN']U4y}ɹrC r(meaWhe>1}+.")񑐤ka9GAW8Tx>⛜c‚/lk0CsDzmdQ9^ ېq‚~޼g¢ivrbw B/,>߼Y sD 慅,ⅅ $Vϛxa/c{aoA^X j\]zaiϛm//, ;E2Ǜ1z&p\nW3T+ ֱxa-e޼ QUbL/,Ⱥxa9m޽MkU"%)ylN%p`/[`y3`ʀ;޺Âq֏0gֻ:u)s {d7{8%Zs{"b4j8 ﰵϽzx>IO1GAޣؘ_}6A^Y?eY6 iD75!!Rؘ2n 605 ctTeCzc"Y 5snYvts+bb^~#ww%G]a? 1](OWyۓ3WN4/tG y69<)TNٸɥ̼M]3 ,+G1oE(:`WQ vjzd1'MBr'drO;'''kZag)%?2ĀSvS=>@h -%L2)mGOβkK'2(h3&} ;&C1~@eH:c G1tS@\Ѣ"3&Н9'b&RS_x-4c^c+@;9xd\htH 99T.vO8$8=4 vqzM3@ C{oԕ!d9$H mOKԞȜ5LC&C) , $! >DFvNSnSҝKpOtI13hnD w*TT֌ qQ9S>o x*(Пd &Srg6E̜`殠DŽv[P2bvgYxm-(9ނC;c@ =Q؀&g.χ[Gbz\F!3'Y?'9SBF?,O6އmw?ԆC ^ z/O:[gbEDJЉYO{>{kñ@>XxBl^## Bƒ9ٸ3&h~ÚJ7ٰvL{\JrCs?r;)?9G^o' ZSYUuU![9ԱpQd~˚u.$x~Cg6,ʔu7{+t^s!,G$]Y/j|d Ab쓣M:UǃQN֡qIB+;q~ۨV?Їp6Yc`6.`&Pl0tg͘9YoWp@ &P] RM׈}w`78$N㌟)f~[f*O 9׎[wjs;K4>DRپ2_zG^3 u\E|y 7,O63ߓCr"`ləFH¶'[-qGZ7qq2tD[i몎jx9`eh\Q4z-zg>keСl%dqI 5 nm뇎}u0<3(u Jsu/n=$p!u63.\@c-`1y܈+a e;geq]>j;%uSł A`W]\O^TMA%Cp/t+ǡ]+]n_tƥ}P*FY+:3=y$0/]i3yW0dAl)+pi=#6n3BO 1V.9tƮ+30PWꪠpd5"3xF#Hiir"U5Udi~ᆮ#~QD_f.S<$*n+ՠ"^Qt%~1 g7B(XH`hE2GOcӂ=HC:5CuؼO^֩W$l<Nů}PA3[׹̎{E*w۩A䢯m|LZt/i XVT$x2Rxq6P]JbHtթ\6S0}C֩>v T0) p~ҶVu[JOV-ڸoPu;0_73+c%+QQwlZɷp)dᐋ;AP:BkA=9tlj /B5{>K:)\B9;.^_t~0'sM(8~@Ͷs h˞rMq:LԮ12(drx)L33@jI,!.sTs-ȐSҚky?9x15VC82txUI*L&r\>~bz2u'zE91٢j)7] '/~F`̴]x8a1lOC|ܳ%湔m~9UGgr&tsG"@j*sћE&EERo;v%en4 y].u7wP[|fO522)C YgBv0]GLv쁴 s{Qݧc YM"L>$B>G\qѵd BP?ixB͵O":E7^Y<פya0J=So=vu5HuD=4(|2r'o顃s6* :`ٵqnbRq2`0sajAbM{a{tAq@TmB@Dqp&ȁ 0xE@~yCsKVeS;76mp[8 G]@pwi yTt9eܫJN9TiXAz(:a7:< fi:J3;<|)Zq+ߞ @eAɟXub7Ψ%Lp^Q"23Ix&WZVHLǺp.LekrsB1/mECQ_@R$qӗz8 8|Gc 22VsM>i ]}>޿wrz7nX7nXczy{V^@߼`,?V~5DbWҘ?o?nAo޿dOgm[Ozt-m޿ ߼I%USPx@{Y jcyرY,޿Gq֗V2"b8d܊q8;[a1l^@1xG! g+H=2"4 QX^ 'gC!`Dw"HA‚耓%,!ΊZJ_嫮V%-e۱ˈyǴU7e ͤe$ e@maU|ʗdg:%VҶ2kt]t~;rﯧڥXW-ƲnSVtqڅq/y)<-me1="szhc.=U/&EܠR{nlu9ʱkefuT%\jVAkRYKj,#}b>$ь$崋e]m CyK3dezcA!T) 2ěN0?02f 3f`ŭJ~+Ŗ1pݨ\a1T lt#qSt-/r;a1l[ˆlӋ|}"E~BۂTQ~hloz ]V\`3%O?t;"N=,Fk'g%Pgn"eYaȡ)1L782 \_Nx"8r"" qZʻDzW5IoQ ]]PJSO2 ?HWF\.ߎ"Sa#d]ꂋ\}\X]Y6ޔ-FG@0\[DZBB~A(Ϧ v6 e:ϕ)؟s>4ƍ'%\;mvc."4pŞP%5g3W(e/Wdy"9?; %z!]{-t-E&guQdRr>U眿t.h+ ɤ}vV?.U%ֻB``uu3Ȣ~r0;O!CsDWy7^xP#Rxv $C3&vz .c Aslt4slv<6ZDpzehg/+ȔٽV+wL}]D#Smi;mt1+v͕2) - ~3}Ŗ-N}iaE7U"~zZEFQŇ`O3p%ßGFӖgw|e~pE΍x, FE8"D[&s&0q/Yy6!_+5~YELnP BeXQPӔ]TEAo(ē.bNrɖMeE ##~J~HzeeDj9R4H_= #$0@0P[͏P~GFo2() Fyk(rKV(*(iA? .ELJ[,P?0zCT]7P/bwl=xc@?b"HUqؖNxzU$kI.wZs21UmR$W3Ry)a#d BfnSpe1`K\ 4]T#Ve^TajcĬ&M'ke苪oFT ݍٙ+DpU%#lqU*F%ٞ|@kx*.9nYȆ]^|rAfot@c'DŽ9#}rH|>9017J |sۛOS >H|ZLlW'C1=c铃(!wO=|rD(O.#SbF#CgɱOWOgF{Ʌ,c牡S"Uc6'$OSr>90c̽Y}rL=}rh8:WɁьY?JP#<*((L(Ǯf ;=χ&qu/K@9. P:ҥDPdC9Ln I1q.:6+,]Г] B=FF" ÖU7k[`7V,b"7t4.;i^'7#m4t6e²'[;ۛvbqih#6.>lݟUQvc(ȥ m}ِ\ ]0V (k8_cg"WxzW%-Uˉ[nĵwΣ.ɵK ܌i,?{,ZmЌJGls%t98c.Ndfnڋ#8Gn?{++2Ww3< -^ݑi^qshxu7EgR[Vk/N5thpGo␥T> Q2/+sq9yw9X8Ƣ ‰ELY2 .( ʮj .=705X[vCGG&fƉ Mr!aJ񞄙}%]t!^-:%8.:R8E'ƕ-?ȴׂEdkϊa 2do" K޼LJpƱ[#r jETD4ژa"rh˝wCPTRV_>a "Y$C0 xs_Y0( PDY 퍲)yWieUΥLFZ4t8'H`d<>UX+"Z&quQʷ쏿6 ␴Hɨyv^>Ѥ[ s3K H@gj=>mhe5R/<ʌ<^dQ|ONW}8~3l6n2C@:dnxׇC.[F \NBQK ! !&>o )vPr EiDA0Y@eGy=91n*oQ*ߡ<7 =_!rPekX c~;>p{tЁu3Q\R(bQ*.?c/hYLp@q !-{AWA8~Xwڷʃ{vBr@#.:pfj"P0&gӺ s4IAPl%o6YQI'cX&87o2T)QћCnxR7!iv0D>r>1-\NMUHÂs33OLIl5Nfx9Q D˱ϝy5ۣSÿ {|Y6Yo"tZ~EY gWl//ƚ#Mˉ8!CMlzޚdD&{)a h2PQg{/k'B pܕ֜ɩ;1 p$b%&w0k#q8\pK~xp)5wFFg+VF_v+3\qNǚLbIo5{t?vX#Cs7cYW5?o~VË~TRKz6"l$S.)I)X/rON}y.>>[~@+z s6XՑ 末X}\4X˺uOpzu/v.=}tPuI%~SL1袹C^>CL Wǭԇt]t%-\ƫ\afS~ioNET_ ՠ"V5yrF+9q7ʢDk\ r$ꀔWl^lFpnc"䚞_EYfV~<~O12([2,Q/nZz3`af~+gȡg}f}=ڭbCg2;/AnF z#8(!߰)IW2%y::+n7RGr''7x)?ᖇ{܋P29\:7jǖs<<7N%GsSEļWg899os/fwkzvC _ət#9Y63əմ:k97(F A3s@:3!CLz6,8K8C̬b<7bwe1l29oysr&=ZpYEYF%Cq}zp 1ԩ.F]U`aT^C]0GpIݡ!Y݃lkymBta&pNb̯IWƼ =ݹZYzx=`QK*AkC -+$J32?̸.>ʸ3zR1V.u,cpUĕ{4-_j!bzY下~ K|sy1ON+$EqHJאEP*@r8nqZ^L}!,苜f; A_\%}hC0"b=‚pSvS5i,dUEt7vD%NZ44,^UI|R ˈf񦏨9Kc `=_oK<3d`ɮaݖ fK" B4HܵB?\]9O^]}YJ<UClOgmm #+CeK#saݯE)IhtfSb.A.D^Vl;"'͆EECNRumNO,&Y QӼ`,^f1̏Q~0 znًOcf ˌ-fȲp;u[bf%f3 :&#,BSbqJ}:){)5G^M!4H "#|NY37W)@K cfO~ n _K t]cfXOysK Ǩxw֘E̲wJq.13{}M;mGAs F ~+7u,86ə䞚-9? ssd*\NA3GVwa}sQsWoJ 1-!ENx~<g1!>HYgR?!MNFcGπ̊㔶IOə|m?9?B? p=vӣdA+ok"fC|,FP-Pe@*B tfŘbP.4@嶆8dN lآnQ5E ZMz<%9Zϔc0[O<{И߯d4 \pi\`M0WD'@Zīó YP.Ke6Fuw݂̎0c}^u9{@>j,-{ R̊U~;ꚽ]y[MFT!|7U^&\7t>C-6ɥOPSBU Dj-&5n4uŮgz% ̴{`,SdFȤY'IK[|HF%YgO f6;k8z_o'n{4 <GF@߾bZ ˉʅȓpsp/k=_*h+wUAyHet\`>{\ 9;C˻Po~> 4|= y2Imx]T]q{qϗH"+F=!W )Z|r$5cIcJ!tL<OM,9K=?UOqn뼹8|vqfi=9{?&$Й1s`ךF#ދp~-9CI7~CÌnn橺p皊J\)`sM5 \E32'`_g8Bx97,ea L&\cFFjv{3jGoU`veKܭHPḱi@> hpa pN0*`SnӅa I[oO^8{%8kg.ýMKZ :dSlsLҖ8*0cLNt\ZWXHU<@[ OKѾ^oqbĘ6 &b1k*[<̉vw8amLCBzL rviҘiww*m@i1($j9񄮪^#Y?O!YM䲥agQį`']+ M_K,"GlvH֪G4f,`k'sn'jlg>.'Y?!k|Bʺes&^yn]lp[zք]?;$Ib"2j{ ciji5&6>Q.AGзSE{E6MlݧS8molڈi#6¡Pg{FX1i(ϟB@Ҙ]ͩT_o\H8ۨ@].sP3Pqh ϫ@hSWVƙV^!戀7nC6*h('k{L_zЃRm(Ë%0#ayE5n8靸|!&@Aq4D O0ue.&\g@P@ ?wP0D#_RP)lp.s5I9_Uǻ4F\.J4}OM qrH@И^/; Z3bg¢VM̝; (1盽F bn֠*wm j;PNdԭe4ª d>41FPy}>TXMn1|j/sT&Ϣ*ˇ?O=,w{'L쩭Ԏ꼺IƒQeUfZ+ UMU=rvl[d h dY*&NHumӂ`Eg?СT-ЗHgsp| [@߃ {q| =qV>4@s?:H}\0EQ} l>v c}l>0g q2@x {/ -Ƿ큾"З4Çom>šT@>BWh} l>~ QĶ@E2}P dr$t}ZMx[Q_Ӑ PİW\6`!B`c^y,k<ȘG? ]AI l܎|R[?f[0W'8eg$+^@\N,HާI k*q&eľh^b žĶ8Z;J?_ lJOyS X+kd#+k.%jI Wb_8źS ):yek_'կTnk Q\u1&[6Q9fs}Jkc'ԯƶ!Ĕ!>(X(!_O`%2Y@Jd;<v'`Uo?u[lZ`UXꞍ~TeuWu"ޢN~hU攭R}=K;yO6xJ:I"M9Fb=8\hktoOLG .g%2OP<)B8FHAR ׉#G/ }~ǿ___<2"wMƓ>}2|/wƿhoˤ|ίn\sndz@e讓?:ˆJr{7q??qmje H:v\ J|'zG/nxJd>z:$,BۛF8A}<=^^2-w;-3͛/C f5::'5*FnUKG8 <^ eD]^lG>I?!8h9E@?_S@8У/yT@Moyѣ7w6f%?~?xĹXu,:aڪP7ڬ}c חjB$-_wĜ7* er2%irwdGIZӻSNf70|{|U DCUZ]x>Amz )k˖Jj ?V N5ajHfPH5uqG|w>b/4)Rԝ6#$R_L=MPqckWaPo=B ~D:-fG,ޞ|ɥcx_c<9'훌,z$<=/IK]*;hߡAbO3=#D ޫN.!1#QSo_ޔ e9."X 8ߺ[lYГ2dQA<(%᪒1'.Ѕ4(>-QTm9(4i?>|j)!啷qn#a'{ɉFR7r`{ԥ_?3(hrUb$E␡6a@p/|nTxGX0NdBoUTKkcumHb:BT7?CV̞$OG'**kUS1#utRV['{x6xt'ݨ&ܹ/A^n7~-%I1a `6W3|R_N\]TAwZykؗy|% &E0׽^E9̰!k9O5e"v-*~{j;mW"BdT Yk,Eg|ܰҺ}Zsnu)#n"ߢ ;B; Ó\w]F|,BRR&P)J ~ag/%ko5e1ëXksX ~ILkvNH\,Em\WN=t0 S܃aɗK !c U+-$zA!ux1:W P7~ULJ2 ;QBHuf5)f^F#L/u3$`BGﳎǥ} kJ@+YJR9UH6U2!﯏4 <[;}k\y[fk(L.s=};[uP\{q3v+| SHWiY1?#Xؽ멳]˻F>uR»67߼y{GuPR*? ˻f5eS}Vgiz׸XeFK72;].zqn˻F Pj Kү۷aԤQ ÞpQAr`g3,uwGun3z-Zׇ>9k[Y(VtQwxN޻s n̆2D]µ}-/ù{5D$S-[Cq~l_(qGDZѕ&4L k>a,i6d<^nBãn"#eRMoH7ɈW!IXF^+Ej#d+$,_֪?U3(IAZ*f 4%?}g7o]&;Jh,62|v hoL74LSuO9\\ÿE'\صvr7hJq[R(DȨ+eֹ=apW{}EP^WU5dv|F}FVT/bG8 k.~hgB]So>.(,4nw O_MQ,̬{[Bš;XwhXu($Av~FR|8ɪD2ӃLfOv-UJBZ|2_̎cV{hZ1_:z: ڜ2 ܬ0O`-7<֌;ǓpJ{8' 4f7RbB sκGu ljݛAmvuq @N1 ++%Ve s\^;ijI%QXUY ΚgX"U5^D Tv`fܺ-c!Z Ʋm &'`+ vm(5(Ц G@lÆH6!bIY7ޢ^>$g*)a,a+"jm`dw:!Y=u6f+Q`'cP`mJ׈CeM#NYxqtB.sO(,%Pה:tÁrX'3깎 T#tdڽRR|BdOpРx%6mU/ ҒΠO@PxU+ /Lc}a!@F̸%Y= ;f(CrU?mSakt8ks޺%Vc_a*34esmp!jbp]ډ]{uhS R<<T\n 7NvɇŋW $g(Iy+o\P0k*'6i#~N:~cQ] BнI].AlP"_!^ 0af^}RY Ǘ8@ 3ӹ4X[^S-I2yyw2IQܢp% ;w|NBhXtl6E~׃OP!P=+-Pye9TlFi#( ^ >hlr!ZƮ%P8fMAjnZ*sV0>-Ɣx5[eMuQ>'1K^+HpS:1R@ &E C*+RyQ"~mpyP*9ԉ8>h~F/Bgt41!|ecѬcӯi++|*V̹(0C~koXK"@F.h40"q7TWq7K)iҠ"Cgs9E#q HvjSNMDyxpˆci|kEɻ;z<5qz{Xg45q:Zlɑ8ή[ n.U|!55] p!VJ3 8"xR\*q4gENULTQ]8HQKF.Ymx}mR*#28z9T^"%Kg"obH=gC|z8Cdtz}SDܘPR\+"O>G0{RᨐՐ3m_ׯ?` endstream endobj 4 0 obj 36758 endobj 2 0 obj << /ExtGState << /a0 << /CA 0.292208 /ca 0.292208 >> /a1 << /CA 1 /ca 1 >> >> /Pattern << /p5 5 0 R /p6 6 0 R /p7 7 0 R >> >> endobj 8 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 635.710266 385.044617 ] /Contents 3 0 R /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 2 0 R >> endobj 9 0 obj << /FunctionType 2 /Domain [ 0 1 ] /C0 [ 0 0.729412 0 ] /C1 [ 0 0.00784314 0.729412 ] /N 1 >> endobj 5 0 obj << /Type /Pattern /PatternType 2 /Matrix [ 0.8 0 0 -0.8 -211.718064 181.499988 ] /Shading << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [ 368.191406 106.175781 367.976562 105.960938 ] /Domain [ 0 1 ] /Function 9 0 R /Extend [ true true ] >> >> endobj 6 0 obj << /Type /Pattern /PatternType 2 /Matrix [ 0.8 0 0 -0.8 12.752128 177.584958 ] /Shading << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [ 368.191406 106.175781 367.976562 105.960938 ] /Domain [ 0 1 ] /Function 9 0 R /Extend [ true true ] >> >> endobj 7 0 obj << /Type /Pattern /PatternType 2 /Matrix [ 0.8 0 0 -0.8 5.934624 184.480622 ] /Shading << /ShadingType 2 /ColorSpace /DeviceRGB /Coords [ 368.191406 106.175781 367.976562 105.960938 ] /Domain [ 0 1 ] /Function 9 0 R /Extend [ true true ] >> >> endobj 1 0 obj << /Type /Pages /Kids [ 8 0 R ] /Count 1 >> endobj 10 0 obj << /Creator (cairo 1.8.10 (http://cairographics.org)) /Producer (cairo 1.8.10 (http://cairographics.org)) >> endobj 11 0 obj << /Type /Catalog /Pages 1 0 R >> endobj xref 0 12 0000000000 65535 f 0000038349 00000 n 0000036873 00000 n 0000000015 00000 n 0000036849 00000 n 0000037370 00000 n 0000037698 00000 n 0000038024 00000 n 0000037035 00000 n 0000037249 00000 n 0000038414 00000 n 0000038542 00000 n trailer << /Size 12 /Root 11 0 R /Info 10 0 R >> startxref 38595 %%EOF PyScanFCS-0.2.3/doc/Images/SFCSmodi.svg000077500000000000000000000740701245330745300173700ustar00rootroot00000000000000 image/svg+xml a) 1 color - 1 focus 1t b) 2 colors - 1 focus 1t e) 2 colors - 1 focus alternated excitation 2t f) 2 colors - 2 foci alternated excitation 4t c) 1 color - 2 foci 2t d) 2 colors - 2 foci 2t calibration-free crosstalk-free PyScanFCS-0.2.3/doc/Images/alexA.pdf000077500000000000000000000540511245330745300167620ustar00rootroot00000000000000%PDF-1.4 % 3 0 obj << /Length 4 0 R /Filter /FlateDecode >> stream xXj9}B`a؇gIYہ-uM!rNtJRDy,nPcPRC(q]gsXwռ/CmA\/, (+-2̫C2,z<4Yy˓8x==e*F !x/^Q_복4<js̩a&|W8.q`:P9}9ԁ $ޯ>SMj8*4l~6+}Q[go8QUmj+&Y[co`0撴qZdžn14m+n6XarbHVO:e6{IbTݍOLnAGM2&XvU[)>E_uO%zD3'lFCZQFJK׭s z3oېQQh3ofFeK>?2eB[s};SQ O2#k<\R$t-eB$ooRv.*Q& J7nL(cm(3OI|Z;ݹ$a2eB$?d\.%7wZʄ\A}Pv{S걹xh6H/++rA;"|S7N)9O9|$_HFϟ@%@?Q.vpNc3)}> >> /Pattern << /p5 5 0 R /p7 7 0 R /p8 8 0 R >> /Font << /f-0-0 6 0 R >> >> endobj 9 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 576 451.799988 ] /Contents 3 0 R /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 2 0 R >> endobj 11 0 obj << /Length 12 0 R /Filter /FlateDecode /Type /XObject /Subtype /Form /BBox [ 0 0 576 452 ] /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 10 0 R >> stream x VpC 9y&fe a1:qpgS\l"fÁNj/fG]PqXCkFH>9 k/ endstream endobj 12 0 obj 92 endobj 10 0 obj << /ExtGState << /a0 << /CA 1 /ca 1 >> >> /Pattern << /p13 13 0 R >> >> endobj 5 0 obj << /Length 14 0 R /PatternType 1 /BBox [0 0 576 452] /XStep 2056 /YStep 2056 /TilingType 1 /PaintType 1 /Matrix [ 1 0 0 1 0 0 ] /Resources << /XObject << /x11 11 0 R >> >> >> stream /x11 Do endstream endobj 14 0 obj 11 endobj 16 0 obj << /Length 17 0 R /Filter /FlateDecode /Type /XObject /Subtype /Form /BBox [ 0 0 576 452 ] /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 15 0 R >> stream x+2TtDb(?]@PH ( QH24PU015311z 3=sKcPR!kͅ @l'@.l+@ endstream endobj 17 0 obj 125 endobj 15 0 obj << /ExtGState << /a0 << /CA 1 /ca 1 >> >> >> endobj 7 0 obj << /Length 18 0 R /PatternType 1 /BBox [0 0 576 452] /XStep 2056 /YStep 2056 /TilingType 1 /PaintType 1 /Matrix [ 1 0 0 1 0 0 ] /Resources << /XObject << /x16 16 0 R >> >> >> stream /x16 Do endstream endobj 18 0 obj 11 endobj 20 0 obj << /Length 21 0 R /Filter /FlateDecode /Type /XObject /Subtype /Form /BBox [ 0 0 576 452 ] /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 19 0 R >> stream x͎J)-$$E,@HOٕU1ܫ#ǜ|v38_y?~w?/oy%؆#pcUǿ~LK;|9V >i=/eٗ:{81\Pc$k:<% :,wBN=GW*/5Wa}zCB'.᪗[|]þB U8߲,w^CwWC ?G^v_ja3ѭ?Ra_ {}; В@B'.!➝qrxJ|}J}?/]PޫK |};NZx엚 ö@;aܬCG;Sa_mk@})Y/`ЬCo=<5Wa}?{Q8 \z//5a}ft><%+1oi0z輇dö@?a|!ꁣxXѩ=;Sp{\ԦBy 5gR?fd|P;@Ygd QL6sw=&Jʾ9p+\ڠ Cd+x Wccz;D3wG'~_w&cfx=j@1*[G awgP/FG[zhzcbryTX'CPDn~\N0 VKB5&\=kՎUvbk-O|&awp(&;ܸu.^ M\Î0Vovt| g_cxzb !lv&#-`2MPޞ;*1*k*\QL8s }hLB9hXkȈb™kWbI=P3 ~B&1Md3װi/>aװ; uR\T$/>awg_os| aװ1Ν4AkB^p~P^XkkؕL?젘lvN?(N\C^Nla6nY{%I &a' d̀PL8s t{;iB5 Sa) g~+\S &ad6$[{Nm:d5^N6q ;TXkb™ke/M6q X $k pMPL6s (g{pMPL6s gKB5caP^+\ \î0V8q *|N֗oʲ&A(&;>Gh kY \NI$k?'{}:kB5 3`I gp}C!l 3`Q gs Q aװ/[8q <^5 B15Lf@(kf:)reZF:t(k7tdɂP;h(zǁB5a[!{ʽ5B15 CaA ˘ ^.lv k=T7 -6qwv9a(5B158ڢۤ4B!l5d3װ3 uR4B!px ͻ|lk΄U@(&ǫoMP}h#柗ܿG1 ca_WPń3KkUc &a7[8q 1fa0V8qwx^l#`9 )pP]lvN@(N\Y.\2Uo0qwvϏ&KB5 *\c \O[c &a ṕPL8s >Vmf+`2`Kk7 u:4B1w|>1 aװ/ ṕPL8s <ƭ1 aװ pɁP^zi eSװ; n6q \r 'O_V4B15+k6q ;!fa pyx[!{14B!`vJń3$i B$Ci bkuR4B!pxkM9Ve*Ys \!Wq7P`(5B15{Lj B Ca+\r '_~?md3װSp> >> >> endobj 8 0 obj << /Length 22 0 R /PatternType 1 /BBox [0 0 576 452] /XStep 2056 /YStep 2056 /TilingType 1 /PaintType 1 /Matrix [ 1 0 0 1 0 0 ] /Resources << /XObject << /x20 20 0 R >> >> >> stream /x20 Do endstream endobj 22 0 obj 11 endobj 23 0 obj << /Length 24 0 R /Filter /FlateDecode /Type /XObject /Subtype /Image /Width 458 /Height 503 /ColorSpace /DeviceRGB /BitsPerComponent 8 >> stream xu8Pe,E1YtƄY,6}>t@ A/K" Xe>Yp3 W_ntWKz]x?dhЃ x Ѓ ܔog߯>0&w*u8w_=|2=*N.7c>w7 vy ES+Qf>Rv}7= r>d9kN'"lռs^ۊ}\ Bwؙۣ9 2ŁVT>z]?inEw7םٽS›q  nof.Ưy1wy15ϵ2B 9l턉SA?SaSYW2}'>Tku$au]*vkGXjvzȫT9 zږ8ym6λ}tꮺi#xk)'︲vnb#yek)udn' 網>W݌ڶ1jk:5{׏p׿KB@ņ6@k/=k>\diy_? ӯ~dZϕK&sq|9 ը8ʃ+#cOꮏWK">tW-XRe&ӫcz^$0lW`:1dϏ}p|KCAҼMs >L#%=M9 5 aydKTɩDv _,)ðaEI;|z3YY<v&6z>;Uw]uWݵiwM˝/eZ4aZp%_Y&w^|W`:;T^tpiR<Sw|{Pp~95K5͋℅vHZdWh~Q6m:kfןb+{J5L{/Oo-5sC!Is Yw h7n4f5bIϧ+%?8m䧄bNNof֚?9 _a3=N7 ~1pJ:&\M 3/W&mdH8ů/n4VcaxrϏy5ޟK:}wj~n!ןB>^fX^YL:u¹k5 a U)Ouv8fRztu[TjU^JSB)B}i# UMm٭uEmG;,Vr8燕oF/]:U~{3_;2󦽶Cpn2QvoU.1Vfj^f2?<]k'ug05)$t׍tɀ)]5CF9R-ǬfxLhqN9u*kqzǿVoZS҉;H]$SCww7%v<`FQʚkxYmVY; 6_ݴ);:Fϫp(5UpvG:C jsd):ms/=5nڄz6w:WpmE^J55][9#;EnHwAw79Ӛ'pwL]Ǫ$pj\jR'3)wp ݤ~d/Z/~m;gSb΢o&rf;jأLSwMuHwDwy*UO}wdWYZ9Tm¶FwՖ_G"uG]TCwmHwviҪ mzN393Wa[v})ґnK-4IÆv PnVT:^K\ z-Ӿoz9Hn~c<:zuM训];J~ȇjBop̬Z9aÄM$fA_Q 6TꮺkscfՊ]dJ:]fˋYX|W`]4wZ;zfNU68ίHGҾdCỳQ3X!rsv{܆z-xA"; uL"wjw,&,6NܖF[nm Vw9Dwm~z7`\M[͢yyŗvܝ w,"VKrʀqǜwdjnggCo[/qMwsm5]wzN;*N9a幷ۮK8?|>vKY!6yݵ%$ΎڔNwzl!~9rbd:it׆tLiU蛎0B}l>pQAA۬`wd'oh6;0#2y.Wtֆ{~WMVw}KkW޻$tiPgdQ4rnq&/߽?^kTOw]]]ۆ-<1ܽ6[?[gR[8}oRMq!ԑ7 u7PoDkv}e04){Hw-?9?&-pӖʄN,搾.4 ME[r!bʇPŀvpqM\KP}OB+^L{p[O];dqUaruvW1CpUw}p#0)ϐ2gii:ÐLsw}i8)rNI^y1† ӫiONc0a qʯL&l¹k<\!bY >]׮yy( kb>uץkYw]Zw}ZsT^P5,gZ58rxY}Y";w5Hl:k'zΑ TH2˄ jEeKɟ_zyˣ~ԧ]Yt<ྃÉ!ᵇ~Vmp5Rz Ӿ4vk5%b{۲~KP芅]Tpq6ud|6?|fZ܁]rkW莻Å})59:îoٽ=Hw=>tץ{Lg{4-VMWrps{\#[$YIw}y8]^}䀛c7ͫIH4WỬ]M,v3O~m~7=L;w qR1]o{ɀRMK?Z: oc6T2/ )U]fx#4 _>akwbm2HrVOFhYC)ȵYKJ.;s{|L:{ޫpUJwmHw?|ͫ]nj}[G^;]3iMLkSdۙ_zyuUȚMSW{̢ 2xG8u{̢!u2rn r'A*hq#'fv}{ j%t[gvq8da2PÕO1*ܷKInz#tԜūɭ:%f e3ŦodoLw;¾su23{l"ܴ :_?ڦqq堻6Lurn>VۀJ+dC-ّdT  S:sʣv{寻^K ,p;ޛ} n]}nǹoBԭwmķt 4a#ݔA%hmzp";}\LfAuںvٽ{v:î`91sfu{ZW+S56|~i ېOoV>^#!sas8"V_w9Ww}o8AwyFZWF|ym:~@a#õt׮w_yf΅, nzA޴ R,msN5yĀ'il:einrz>Aw}ZtW|:@ z]>㎬@+5} endstream endobj 24 0 obj 6376 endobj 13 0 obj << /Length 25 0 R /PatternType 1 /BBox [0 0 458 503] /XStep 2389 /YStep 2389 /TilingType 1 /PaintType 1 /Matrix [ 0.72 0 0 0.72 99.908376 45.38 ] /Resources << /XObject << /x23 23 0 R >> >> >> stream q 458 0 0 503 0 0 cm /x23 Do Q endstream endobj 25 0 obj 33 endobj 26 0 obj << /Length 27 0 R /Filter /FlateDecode /Length1 8104 >> stream xY|յ?wܙݐnMGL@P~F4 !"@@, 0 VD#Q"?_}jU5Z,mHnޙ Oޟfrwޙ9sϹ􇦕o  6&JhbpQϏnϧ3gL+˄Ɔ̤[22y6-zgOlF?CM{L~R~lt3ARQ'ĭJ6*(WWH2 j>~hgϴgFP,sw~.T߾sr-V(%ↈm{eLD7>Fljܮ]dIKsgg]. _i矧矿ի 3|"NQkatf1OTj1bأl>䭤p; #KTM~ŇgV̄zgAa6ԞuYo©IlT449lWlxxܺS7qlGN竣Ɠ>N\z!"fGC%AP-P]pׄzO] v6|˝{?ƿQ7>Y8y >*?WǪ2ȱr}e~ܼ}K*vi#UE!!g NMNRԜXv(Fzs")1{O_#)yF+.ܹs![3֍ Y_}!F@Gk5"7?=LITYlUvX+ЎtiMHL_IC.2y bFT@8+WLqgM}O5o;ZƸu_9;Q4-l>8?Ɨ_5Ї{ݮ=9k 4_NU'( Vq4|ə1ōI&ٳ:;)+ȑm@k R:%B)t33~tsW9}᥯j;v{܅75/zt<]wK^xhkWisoUM2c+\bmH8Vk1ƣ'k^{+JtnjJ[u6oYg\yhhaX79epjRvl,#T*77/gT2yxAhv\,07ZTWMڮHͤ ײz HmFء_g&Ƙhtg9l7̜mV#rՈJaN*$z*!)4H/ë&Jn!1(&z7QF>z>y2̨Wg;.]D̰/Ӈ[dEMz$ATgQ{/QQGlQx۟jh~H ^% 1֓f%?<}Z"WK~]g)PNR^eHEo"5![à?>Ddh6#6u#m {NI"`|Tԭ SOؒPx=г^)o]yrjktͫ/Sfί`FAYܕ()]&cH&1lKܚDA\3Ƃ[*ty{x:K39VڰaƎ_eLt_A]{>l׎ba z_WUCqϚqj_V+ӵI_i3Ƈ&74 6t{G~F89/ʕ TaTXm GBp#b]?|?]޽s  ?9/j8.7T,RMa H WiP Q›\ze'X[<~SsScYRT!UIid'2i/89tLaqic8'ci LaSqo*R> g*Ŧ0+ry>TYX 5J:^ڀRo:lmIl3f7a{;}5먻tW%+: X& V^27z7D$efs걌*pEudPz`:n<&T_,UCEX8-=^N.WƯ.C>[I&][_;z't[Qx*b-rs--22vP"`n6<وMgcX͔{B sY. -ˊ>hvŤ?9٤*2b@edۙvwuU?\z0Ӌ!*60dNɩo@!,2X f$ b)PʷfJc8W^>bf˥J3ҳX'эAL RH.ay׽[+td z"3W0:dBe:iR~[ko(0Ѹ ?ӿ`G*AL 'n B4Ŋ|ăVDS@ye;a#NR:F"R,4rd5N7$$C6|% `/ȥKyW]n-0T'<[Z.#)}`?~xPUv'؂;sE&'B9a\v9[`y Nw Ϡ,M: DZ@D+[*%~#ŵ2 )ƈ{>7V4slULΎve-D4ލsCLNwcGX D{RYSl'|%wthν$Q)PHlhQ˃{.&fc̢r 0렖(*C_ˍg$s-[%ZVHR *^ +V8>58?uz@cww~ϧs_=Lr('Fz[ilr!=ѷIy <=< m=&+^o25gzWʶ5A] +wf{mGZ@5ϨQHD9'v#r9fs7_= ~?&Pi om-|8AMvP[">}'N4Ez 4['if}HdO*t5ѸܗZ;ڧ=͚Im56]q9@#E p3GQS bdL$zt~Vצ앢*7JaJÃ߲JՁ ,/!΁^|f~Q:;㗣/:l&㹳<;?OO?k1~p(}zz'u1 CEX *+W +OO܌5˭ƃ˭XM%XE 2JK]qK]D` Xŋ,/>*pGІ ,8_8v,8[/>_gM\ST % OX܁ذH]8§v`SA31 8i|r G[g'TTÉ'Г Ǐ(`4kǟSVH-8<tG:n9G8Ž 6Çu!!9V>D+Nl;f`Yob +ϴ +`5`Y/3J_ axߛ1-!+OubȊ)&91Hr(A&%`Gi'0Fa,ubƔ`TQt,zzF t n.5 ,A@-m[4ZZ44 4k&L"Cd@Jbf<_^ endstream endobj 27 0 obj 6051 endobj 28 0 obj << /Length 29 0 R /Filter /FlateDecode >> stream x]j0>EŠeq }MSF·oB 9|ė*w7V8Z$:6JALvblJcm)*Keu8> endobj 31 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /DejaVuSans /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 30 0 R /W [0 [ 600 636 636 636 636 636 862 615 612 520 633 411 974 633 392 317 277 390 390 317 636 636 557 636 636 636 603 633 611 591 610 549 684 ]] >> endobj 6 0 obj << /Type /Font /Subtype /Type0 /BaseFont /DejaVuSans /Encoding /Identity-H /DescendantFonts [ 31 0 R] /ToUnicode 28 0 R >> endobj 1 0 obj << /Type /Pages /Kids [ 9 0 R ] /Count 1 >> endobj 32 0 obj << /Creator (cairo 1.8.10 (http://cairographics.org)) /Producer (cairo 1.8.10 (http://cairographics.org)) >> endobj 33 0 obj << /Type /Catalog /Pages 1 0 R >> endobj xref 0 34 0000000000 65535 f 0000021556 00000 n 0000001265 00000 n 0000000015 00000 n 0000001242 00000 n 0000002088 00000 n 0000021403 00000 n 0000002815 00000 n 0000007023 00000 n 0000001422 00000 n 0000001985 00000 n 0000001629 00000 n 0000001963 00000 n 0000013880 00000 n 0000002330 00000 n 0000002742 00000 n 0000002352 00000 n 0000002719 00000 n 0000003057 00000 n 0000006950 00000 n 0000003079 00000 n 0000006926 00000 n 0000007265 00000 n 0000007287 00000 n 0000013856 00000 n 0000014163 00000 n 0000014185 00000 n 0000020331 00000 n 0000020355 00000 n 0000020793 00000 n 0000020816 00000 n 0000021051 00000 n 0000021621 00000 n 0000021749 00000 n trailer << /Size 34 /Root 33 0 R /Info 32 0 R >> startxref 21802 %%EOF PyScanFCS-0.2.3/doc/Images/alexA_orig.pdf000077500000000000000000000537221245330745300200060ustar00rootroot00000000000000%PDF-1.4 % 1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj 8 0 obj << /XObject 7 0 R /Pattern 5 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ExtGState 4 0 R /Shading 6 0 R /Font 3 0 R >> endobj 10 0 obj << /Contents 9 0 R /Type /Page /Resources 8 0 R /Parent 2 0 R /MediaBox [ 0 0 576 451.8 ] >> endobj 9 0 obj << /Filter /FlateDecode /Length 11 0 R >> stream x]K$qׯuPd% X>>,&drF;X02"^_K~b>ۇ>u߿c_oSbyxmu^۹] /˟_aIxkJ|l#/vnxK?ɿW˯^m=:y~ͷ>s~{wߗ~w˗.Ϲwz}cX7?m?|g__aMma?P _lǐ!qcq1Ĵxc=ZU=z㖏uc<>ۺgJczoxb;;wsGgWK<>pϱdWOD0Ce Ou :ǹ۶񥙫ޫq _u5ni;+l|9|iV^` 8O_sc=sp=nܩ9׵2^:S8ǭ:+fS|HA⧶-F<7·JqT̜?U=}ݾnX;C:{sUq+:v}= ta㻯}PV7S! MFq{(\,,xQs?2M7smNv:>a/ϩU( B۱It>aت Zs?? `xʣ a[|>쿶lPO-)<De*UYXe0T:y99ytԕ|-x!_E\*^9ȓOa޸/$QeSW^*v vGΧv8nj… \|? 7)e^reU */dqy%ޖMҒ$׾%2 ywz%_bW`d|3o>E\M\8ȓH\7P$9:lATv.)yo+re*U\Ye0^\uԕ|]uYDIU}iE.eUv,Wru+-J ܚ+ T=ɉ-lKV"gx-wed*5wA=HݖMZ9ȗX~WEOOt%WBfl -ԁeSW^*ce=TTfDڲI r47n V]\m|ܞQ\ŵw_yl\ + T޿E]M]yתX Suą<ܜgiTreV*vq{.)}.|%WB77gl -PeSW^{5M[#KYea]paQwn t>h.2/T N,W>|[6JKRgl -!U|<+J;V#Hnn&.T-@=S#HI+RhEOmSu+-J3E-U߰DN`1@+}yE.4<EbZogx[q%uy5ă.JCbz?bw&j ^k~(,Wmi R ܸ/fJEtץWUp}Ai )U[6JCb;#fkłn[A[ JC=XY;LUxu]7sl[z7SܖFY9h"=BOŃ{.ЖC!_Mѝfk_ |+ 9!PX0N,JU(}>bT!NaXh" J >|4 ػ?bV,@DO^4`S&'(rpcŖP$8 !vJ A jk`lm͇yCB5nhCP! N2,JU(8x+1S*'1,4S0pkc0@PZ<`@ѐX #fk$I M<#YvD$%A'7n0һ)'$14Sޝ=J4{wbL{Ɇ&jL㝰GP!A N,J)wҢJp"B9SRAJpFCb7n 1[+ N Nbhh^4dSV1S NRYQ;X{[zC*b)p.s*| #fk+W M B@8%8I+PVߍ#fJ_QKtB9fBAx%:K!_M[}7 D'v144S^hau|K::I 9" ߩ=[z7EB.&b<7nxzz=`ѐXVߍ#fk0 a Mq/tHd( R O[vCҢLt"B9" (p8ͭ FD'144Sj/`Z)}hTVt*rm껑@7D'14QS0pǑ`x&z)ҐX\ϳkF#fk j Mq/tD/,J)? #fJE%5&r >E8@Pz(ҠXسqcEe5&z SF2ч&yYH -*!MBFL5vJ4Ki|5*^#fk5 j MӚ5\)eG̔>$5Kj M 3ܰ FJH ΍bd5&z 5l+kCRF8Q qcbKU땃&b }BO4 h j]؏0[[,`JDO;BqiMre!WB{qp0S*$'1,4Sp_" (-]4IHR,rbd5&z &nZYǬ&9YMe%OG3 [zC*!MrBCL5/$7=R4|5N88-0INPchhWCO#P(:pe!WJ=fJ>&5Ij M( j4KшZYMrCC=Z)4 t}q-" D3&Z 结Rd3|n1[[,`@s8;wz = j\)GBi`LiǐpBB9/J44;wZ14&z ^AL?6eEcÉi*+y:y@7px׀D) N44ͻlXp2CC=wz!P( 9FYȕR(`LiǐpBB9Q!(NJhWS?K4)xh"`K<͜^64)vpcοb h M<+^(,09+P@h7)}iN/i,4S> (-09FiWؽqcbbӋi M +lDbӋi<E"7nPl Uqx_tޖn4RVA8!_MH7-09DO=Z(Ԝ^PSYȕRF #fJEB i M*l( Ҝ^J4)`lXi M#XY;L!4n@`wS!9hqDLs_z* 9lFiWSVߍ#fk_ F44) ҚKk* R-$RчrB9CzJj.'i4)€ZYd5&z =j/}j.'(rOýaKoH!DMaAxrRFCb+5UpϯpB@8 *B _#ҢI$5&r Fnx JD54K  \NVchhๆӊ$\NR#(pqǑbK(CJp91᠉ϺC4|q ֊Hi.'144Spv{GPqpC WHn 1SZ1ưDNvЏj.'i4)vr- -0DO=iȦL!͍[zC*!4&jp  (-0ѐ@0bV,@Ps9A=Z(|d;O!X^#fJ&5)xrkyAxvFCb7n1[[,`Vs;YzXY;LUIj %5`wS!|pDL[;^N@hWS,rcbRIi MLq/tcH )tpc3I$5&r ^!jn'i4)vrf5Ux٨4`S&NVSYQd?j\7T1DMR)4|5Rh NPchh!PXλAB7n 1S*NRcXh"ͭ;=F54*v #fkd5)41Y;LUIj@`w*c>s;᠉[=K@iWSF #fkLin'144SZ3TҚIk\)B`LCRs;IaECPzx0yѐVkVߍ#fkd5)[lDj<E*844b)xp`T<@Jx)Ґع>:-0yDO=Z(<^ZSYȕRf #fJEKj M*xkNjj|57n(1[+rpFB5ӺE+UhcRxIM GD7F- 3&b  T<@@xҐͭ F <^JhhB@8ҚBT9n$1SZ1yDN<Ax!_M[ZgalXFB55 lʊ:f5+y:軁@7<^HӈiͭSKi|5Şax+1[+ yDO, Hk'Qr 7]?`cR8Ia1- zJD54;@`-};\ h¬๞ҖÔu~x&L.s= MWA&-{^ߣ_/ǚ>_pӼ#(_>?ǾvIW+-o~Ͼ,H'Ŀ)~gg˿~IF{;n%D2v$c%oKƇ~Qw=y,'Wr+|[2YkY2a{<发d؎7Ps}>K6JߖWg)o%ωV^u,yqK$dyἶ}')?b%kJwJ^g"׹o%oK2a|3o &{;[~6ݸg;7^>Ax ߻ro}Z? endstream endobj 11 0 obj 6780 endobj 17 0 obj << /Filter /FlateDecode /Length 68 >> stream x336S0P0 F )\@>,́,# .C c0mbl`fbdY 1 r endstream endobj 18 0 obj << /Filter /FlateDecode /Length 49 >> stream x36P0P040F@B!H Y@8&+ & endstream endobj 19 0 obj << /Filter /FlateDecode /Length 80 >> stream xE 0D{`~&f( JpO{:2Sa ,S`5FR죰n_uzS*Ovvq= endstream endobj 20 0 obj << /Filter /FlateDecode /Length 90 >> stream xMA "OPDtz_NE5jK02kP)U0\ 2IL{qIqzz"X endstream endobj 21 0 obj << /Filter /FlateDecode /Length 210 >> stream x5P C1g dVukm;aBXȔy)K>:L." u%ʚ +`p&^7`i5tႦ.B%|u{OxjrvC` jMX> stream x36P0C. endstream endobj 23 0 obj << /Filter /FlateDecode /Length 317 >> stream x5RKrC1ۿSpΘ}tj'+-@B./YK~%ۥW%B>R-G- Q=2'":xa>N)x_xN;2$KMH=I+4t~&+s{rj X+)$=Hr7VސWg%&&MܕBXtLX㰄*aՃM5fcdxLP} #GMv²[6!D3,($Nc$ Ұ9 9e, mh%zМaמE[{ endstream endobj 24 0 obj << /Filter /FlateDecode /Length 338 >> stream x5R9@ } ] v͜~߆_ CVie!U-.Im W%ڥ Pt,6˯JH+kLwIi"Eo7o}=@.^ AS(i|Ъc(ew 4<3}(~_K&(? _osџa`Ś}@*z`yT endstream endobj 25 0 obj << /Filter /FlateDecode /Length 163 >> stream xMK1 C=/yoIʀXT~rICpn4Ke>\1'X *b8j`Nhҡ+[a v悓 |:a̶ͮ]cwIi׾zx! [YSoM-<ʦ}>9o:k8. endstream endobj 26 0 obj << /Filter /FlateDecode /Length 392 >> stream x=RKn1)@Mr[T /1 %?ꒈ3L~r]Qljg!.6Xr_rњbO/ȴTXVݣC(-װr{d`Jn@CHYAaPl( WԬtb ) ٠[]aP[[xfޑ3qYk?=Q2QMg|2RCgB'`$Ip#A 1qOl)V;ޒ{,\L'ib?lK\+E(~Aq|XdDw#h% 0xyDhDԎ=(ͱ&{ǫvzcw. endstream endobj 27 0 obj << /Filter /FlateDecode /Length 67 >> stream x34P0P4W546T060Q073PH11s,lLeb ̀Ɓ% 9pr΃ endstream endobj 28 0 obj << /Filter /FlateDecode /Length 87 >> stream x=0C{` }rۀ?iC:N 6 ΁7AE/.o !$ŢVůE4I7QNJx>uz endstream endobj 29 0 obj << /Filter /FlateDecode /Length 59 >> stream x355W0PF F )\@>ehifY@Has`zrZ endstream endobj 30 0 obj << /Filter /FlateDecode /Length 165 >> stream xE;! C{N#y6;I,%?+:cck'R: g]a2So\\`nN|愯U—L 0;Q|$ ꔍ0G@LM/yjAPkGkS4g*[ :L?= endstream endobj 31 0 obj << /Filter /FlateDecode /Length 71 >> stream x34P0P0S546T04V073PH1 X\00247CbBeX r`J# endstream endobj 32 0 obj << /Filter /FlateDecode /Length 248 >> stream x-Q9AzBsˑ C :-qPO+Uwu9HTM]vf5,?c 7zqxLu5{kOfP2+qSușO \ ȹeƌ#M!RH&3AQ~#aU#j \Ks4;<9GW +ET<pC7ҹ^s0XM7/=[ endstream endobj 33 0 obj << /Filter /FlateDecode /Length 304 >> stream x=;0 C{Ȍd'>2VI(/u< i& b;w؞D/)ϡ+E:Ū0[M*K õ}74uK hY pu;Gw5<TQ!OJ|<(!\{0FS@\^BAjI'> stream xEPC1 =`,{wHۿ=JFp!Z?ZK oGFA= 3A΄@xFnvpμ39Zpә\'mBITqTqLύׁlӑ!KI%&~S*)[*EH䁓M4,?Cb̠Q0qGuٜ9-L|X&Q)2>'\N}䢥Uޑ"ۡW%Qէ<Y> endstream endobj 35 0 obj << /Filter /FlateDecode /Length 68 >> stream x32P0P4& f )\@B.H  %[B4AXf&fI8"ɴ endstream endobj 36 0 obj << /Filter /FlateDecode /Length 163 >> stream xEu1 CsUx:?G i@xx= r]Ņ ?޶42܍e@N"WI3Tb\/:"̒@#|:C[ۙ~:!**na.@RԏQꚡ*+kjڿ"}\Ne{g+W}: endstream endobj 37 0 obj << /Filter /FlateDecode /Length 255 >> stream xEK D#> stream x=PC1= |7˥m$B6BLɔ:ʒ)O>Kbnd6%*E/% }ՖC4h9~ 3*K6p*3 mtV[ Ф`׶ r " JMrR=ot-N=Dkq: DpFjtaŲC5=kz7hGt4CָR endstream endobj 39 0 obj << /Filter /FlateDecode /Length 161 >> stream xEK CBGG|tJ■!M@w'/mK >[ x6n5uVhR}ith6s+ fz:rGp_Gdf)|Q]dcnk]3s: endstream endobj 40 0 obj << /Filter /FlateDecode /Length 332 >> stream x-R9$1 ~`LtIUls#h/#xE=f۴[iGiK,W ;BjW0wy.2meDkag؏]e8*Jl !2J'Qw\I2[E™w2;yNE{ kF9+%|6vzrYɩHHӺ NKؖߗ3| endstream endobj 41 0 obj << /Filter /FlateDecode /Length 157 >> stream xEC1DsUA wJo-%S'"h0yM%V,&rAJ1xN1븨ufihW3=5'M<[ }@8IP1}bv">G)#qbn fW7y endstream endobj 42 0 obj << /Filter /FlateDecode /Length 320 >> stream x5Qq0 54sۿ @;a@dJ\UGM>`!S֖{&UF!}W2j]* UYFp&I8d Rӿccz endstream endobj 43 0 obj << /Filter /FlateDecode /Length 131 >> stream xE ! CT>՞0ABA";06Ѣ76իc,zRV鐇Pi0QąYLCaΘȖ2MlTv<e~ma, U^ ?KwUBS0 endstream endobj 44 0 obj << /Filter /FlateDecode /Length 72 >> stream x50{6X`KEoC|N/Z #pu#])Ec΂q_H1F=#O_p} endstream endobj 45 0 obj << /Filter /FlateDecode /Length 247 >> stream xMQmD1 \ky R]oC /)%K [UC?13,=?TPbht/"+ߏe s`&4`oI&ռ3d‰ATwM,3V7: lx%D`r Z`Q+ tĺv7C/਺x} K{,|BL;wI#fR:=b}@e+ (\* endstream endobj 15 0 obj << /FontDescriptor 14 0 R /Name /DejaVuSans /FontMatrix [ 0.001 0 0 0.001 0 0 ] /BaseFont /DejaVuSans /Widths 13 0 R /Subtype /Type3 /CharProcs 16 0 R /Type /Font /FirstChar 0 /FontBBox [ -1021 -351 1681 1167 ] /Encoding << /Differences [ 32 /space 46 /period 48 /zero /one /two /three /four /five /six /seven /eight /nine 76 /L /M 80 /P 91 /bracketleft 93 /bracketright 97 /a 101 /e 104 /h /i 109 /m /n /o 114 /r /s /t /u /v ] /Type /Encoding >> /LastChar 255 >> endobj 14 0 obj << /Descent -236 /FontBBox [ -1021 -351 1681 1167 ] /StemV 0 /Flags 32 /XHeight 0 /Type /FontDescriptor /FontName /DejaVuSans /MaxWidth 1342 /CapHeight 0 /ItalicAngle 0 /Ascent 929 >> endobj 13 0 obj [ 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 318 401 460 838 636 950 780 275 390 390 500 838 318 361 318 337 636 636 636 636 636 636 636 636 636 636 337 337 838 838 838 531 1000 684 686 698 770 632 575 775 752 295 295 656 557 863 748 787 603 787 695 635 611 732 684 989 685 611 685 390 337 390 838 500 500 613 635 550 635 615 352 635 634 278 278 579 278 974 634 612 635 635 411 521 392 634 592 818 592 592 525 636 337 636 838 600 636 600 318 352 518 1000 500 500 500 1342 635 400 1070 600 685 600 600 318 318 518 518 590 500 1000 500 1000 521 400 1023 600 525 611 318 401 636 636 636 636 337 500 500 1000 471 612 838 361 1000 500 500 838 401 401 500 636 636 318 500 401 471 612 969 969 969 531 684 684 684 684 684 684 974 698 632 632 632 632 295 295 295 295 775 748 787 787 787 787 787 838 787 732 732 732 732 611 605 630 613 613 613 613 613 613 982 550 615 615 615 615 278 278 278 278 612 634 612 612 612 612 612 838 612 634 634 634 634 592 635 592 ] endobj 16 0 obj << /seven 17 0 R /period 18 0 R /one 19 0 R /four 20 0 R /zero 21 0 R /space 22 0 R /six 23 0 R /two 32 0 R /nine 42 0 R /bracketright 27 0 R /t 43 0 R /M 28 0 R /L 29 0 R /five 45 0 R /P 30 0 R /bracketleft 31 0 R /a 33 0 R /e 34 0 R /i 35 0 R /h 36 0 R /m 37 0 R /o 38 0 R /n 39 0 R /s 40 0 R /r 41 0 R /u 25 0 R /three 24 0 R /v 44 0 R /eight 26 0 R >> endobj 3 0 obj << /F1 15 0 R >> endobj 4 0 obj << >> endobj 5 0 obj << >> endobj 6 0 obj << >> endobj 7 0 obj << /I1 12 0 R >> endobj 12 0 obj << /Width 458 /ColorSpace /DeviceGray /Height 503 /Filter /FlateDecode /Subtype /Image /Length 46 0 R /Type /XObject /BitsPerComponent 8 >> stream x휋*F]؅e؅U]0 /zΓ/QMyxv;s{C?{)$)$=x P#ρ)$Ia\W\%Wp<8fs|^Qz^דpi.0GN)$ ẽK=>{Q"7]dfZ1g;!ی?$ $+Edg^%Z u^ \zndA%<]R uPl>WEɮ{ZmyNi+ ֜z&:}ߘw}uJc5}tˮ͋ Ogߍig,v?@Po {#aƄpڠ.0N~ѡՇAJCj; ݄2;tgZt&YbZwHYgsi5w)֊$I%uRU3͸L`Q, ܵƒmӠSAtڠyI$Q`Dn Du=Ǹ6Ʀ1fdڜz(Q3L&[`$r`C|2HndLkn櫕r,utCsT[(ڛ1R?ooQ^vb7~2)!u"1;m3;^4";td F 3dpڐߺ M}'t#f`\$DqEm%tZ"_.Mfe5c^yjLUV5G2--]ŐČ]LJmGlhvX[a3tUs^覅͏;&*ig]o8 2I|^x|{wCFwn G[:tqڬي.xVL6-\.A*ϒ`5G8YDT_RH|/?cd|& :t'`zoAvݙt%G݀Rн}fؼ0ŭ9H恑/d$(7*["[7[{+ʀJuk %WPɰt%DQN&H<+Ƽ\+a1^~*2d(9'n>؇D&Gnnb?JP Ll%j O]/p̙;v`}VˎP28߱ᡠe̓vb><{é%Ood x[gm%{5Q=z⇔2ux^b'N"+rG ^edߕ<ۊ#wQ݋fHN/K%JLr ,oWoDV0wXxb:1R;I`SbR~:y!J)uUco"kbux-Y[&ӊ^q%F* %az ( up# W{*a!n{v m_q q\GO%. S@IsQxPP0^?;s->JI} ( x(P%S@I/TS@IS@I*PO%vO%o@? :U<$PpP0G[ϿG$\]DfjꖠQ&$\?Up9=(ɚ^>G Aü|AɏOyHB#:wI>{^Omr#&Xaj%c),6ӵ 34O:5e1F#A6bx%>m+GW$˞jYӡtNCpn@dTӀE(() su/~5Mou"ߦzݢ3m5R9ﶕ6Q`lIѧ5vcӘ^EwjxiϾ>1j8k%Xez}H}SUڸŌ9i漄)chՐ'$grVjql ֦w?&d^6G5D:ց.gqiNٱ9t!0>IWc$[">CcYI#EӘi9׿q7L2; Gcgi"r&ZG2m*PvPRag,HehutJZ"A^*j %ddg>Fi#rA^VqktuymZGГ[$cY4 t6w}]Hwgўu{=7y?.b<7m5]nE7%By8_t(KWrԣL.;܇8!ᩧ @r=~1bkW=Wc]q4JMc 5QjPŏҗX(vrJ.ZJm*ƇӇ-7YG|w8dyk+y$[&#n<{}&Nu{ç |~v?}*Pr/WQrCZ |TTEos@h&vM(948eL{%]_3ݧ@Q2%:ӹ<9UCh}u*0zOEGEQlv+y}j?gAqo+YF0w%;ˮ̩\ C~"Qo' ̶):%;L~Vɬͺ{R;[/ي(8Z>7qh9kQPW8ߗ1 JS@I87J~02GWmS@IA_/"J?"YS endstream endobj 46 0 obj 4409 endobj 2 0 obj << /Count 1 /Kids [ 10 0 R ] /Type /Pages >> endobj 47 0 obj << /CreationDate (D:20120719154523+02'00') /Producer (matplotlib pdf backend r8292) /Creator (matplotlib 1.0.1, http://matplotlib.sf.net) >> endobj xref 0 48 0000000000 65535 f 0000000016 00000 n 0000021225 00000 n 0000016494 00000 n 0000016526 00000 n 0000016547 00000 n 0000016568 00000 n 0000016589 00000 n 0000000065 00000 n 0000000317 00000 n 0000000208 00000 n 0000007172 00000 n 0000016621 00000 n 0000015069 00000 n 0000014869 00000 n 0000014389 00000 n 0000016122 00000 n 0000007193 00000 n 0000007333 00000 n 0000007454 00000 n 0000007606 00000 n 0000007768 00000 n 0000008051 00000 n 0000008140 00000 n 0000008530 00000 n 0000008941 00000 n 0000009177 00000 n 0000009642 00000 n 0000009781 00000 n 0000009940 00000 n 0000010071 00000 n 0000010309 00000 n 0000010452 00000 n 0000010773 00000 n 0000011150 00000 n 0000011468 00000 n 0000011608 00000 n 0000011844 00000 n 0000012172 00000 n 0000012459 00000 n 0000012693 00000 n 0000013098 00000 n 0000013328 00000 n 0000013721 00000 n 0000013925 00000 n 0000014069 00000 n 0000021204 00000 n 0000021285 00000 n trailer << /Info 47 0 R /Root 1 0 R /Size 48 >> startxref 21442 %%EOF PyScanFCS-0.2.3/doc/Images/alexB.pdf000077500000000000000000000516501245330745300167650ustar00rootroot00000000000000%PDF-1.4 % 3 0 obj << /Length 4 0 R /Filter /FlateDecode >> stream xX]k8}EW߂BY(,l7PL2- <|'Ʀ,3++hWquA%H߅_G/?{kԸW>6LO1L$IS~4$'u@j ޼&|>9%gqϟ/O*vTLySȍ/Y4?Uy(jt8&3fxۋG/*)z|2R{0$?Wǝ!@û܁~NK> o1} YՇRR+q};ҥH;*/cpE\ -=\g~o{v,$9;u9%5<ю#(,3d0X'EǖW&Yf. g[TȢ:^NI($jj)+%NQU"J [dQ;#p1ddI,M1]ybdqn;f*NQU!C!X,jLUq;EHI`ĂIlQM"J *9PR F섓p-c1bΠ29ʅqdž!J;L1ޡ Rk[l˵™)3ŃֽB܌݌v:rF7#3vZ6ؽyM6v7/J[`ާ @og=@ >;ސ֬fm橹aMxN;o[/E xaKb`|XłCAAf|XJFsXfer2i3"48l?.>VdjHfd6J8[ ,Je  l p3ظ:w109cA6P¬hQأ {FYuJ S\ls3($c9eA6PbWwާEFK ?@iG҆|'`)Gp-+c-Zmt*dH#|"UdC]W)N1 |2Ud?tisฒ'!-ZӘ~E2g:'`i^f) geepmVHS uLO;$(짣~Cч⭏'/Mg_z@M9iإJ&8@ݹϙᚬzw+OZ]iy? p endstream endobj 4 0 obj 1254 endobj 2 0 obj << /ExtGState << /a0 << /CA 1 /ca 1 >> >> /Pattern << /p5 5 0 R /p7 7 0 R /p8 8 0 R >> /Font << /f-0-0 6 0 R >> >> endobj 9 0 obj << /Type /Page /Parent 1 0 R /MediaBox [ 0 0 576 439.200012 ] /Contents 3 0 R /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 2 0 R >> endobj 11 0 obj << /Length 12 0 R /Filter /FlateDecode /Type /XObject /Subtype /Form /BBox [ 0 0 576 440 ] /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 10 0 R >> stream x9 |N/ B"cR3JKJ ;eCD &Ybl(T< }A tf\;3= endstream endobj 12 0 obj 95 endobj 10 0 obj << /ExtGState << /a0 << /CA 1 /ca 1 >> >> /Pattern << /p13 13 0 R >> >> endobj 5 0 obj << /Length 14 0 R /PatternType 1 /BBox [0 0 576 440] /XStep 2032 /YStep 2032 /TilingType 1 /PaintType 1 /Matrix [ 1 0 0 1 0 0 ] /Resources << /XObject << /x11 11 0 R >> >> >> stream /x11 Do endstream endobj 14 0 obj 11 endobj 16 0 obj << /Length 17 0 R /Filter /FlateDecode /Type /XObject /Subtype /Form /BBox [ 0 0 576 440 ] /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 15 0 R >> stream xUο @ =O=AhyK`WP(C)?"w%?nŏ ܃?M*haWe3;3T,0PwquʳH},Xyv\sfBCD+ endstream endobj 17 0 obj 126 endobj 15 0 obj << /ExtGState << /a0 << /CA 1 /ca 1 >> >> >> endobj 7 0 obj << /Length 18 0 R /PatternType 1 /BBox [0 0 576 440] /XStep 2032 /YStep 2032 /TilingType 1 /PaintType 1 /Matrix [ 1 0 0 1 0 0 ] /Resources << /XObject << /x16 16 0 R >> >> >> stream /x16 Do endstream endobj 18 0 obj 11 endobj 20 0 obj << /Length 21 0 R /Filter /FlateDecode /Type /XObject /Subtype /Form /BBox [ 0 0 576 440 ] /Group << /Type /Group /S /Transparency /CS /DeviceRGB >> /Resources 19 0 R >> stream x͎,9u[6HH,-bÂ'#Q )]iNgW+ݾu-}϶[ִ.ym<<ӽeӕ㾖9v=]g{3@9@w9\}=fNg⁶;)Q0QR9rmW.XC!5FE^C!t=b?_Se'?ӱxv{^_R>wfS!wZoo)qmxYӹ}I;·t7vi;K\V ~kg{I;¯Tj|Uޞ+x ~=m.MTrTؒ_7ؼ %vW٥oCv?BI;t_Uq ~k,vAWxNU#6rm{a#$k|P8iGxMy'+\n޳ k5doa}W J'-tnkr]tHAm' @]ΜRpAzNg!ܮ>4:k~rn7NZ״Nr{Nڑ)dE-ZojfG:x(?/'.?;\h8]f~I p\np }ht}[})sI;S.NZo nw:>4:k> >wkA-M$t]<?'w-pye2Fg-'y.] .(#u_ VuW,&-'[5"+nFg-swAM4:kGZ{üJ'-'4]J'-E?un^ɇFg-'n^袟bi%J>(@0wJ>(#1C[97|P:i>٧l^\_S|;M+pzl i^~s7C袟i^vWO4I I?WY =3^ѧt}O}|ht]Y|P:i~į%NZOĒZ"ĒJ'@WOӶfa?YXAѤ'WI pO4C~s7I "ݼZON'4䃢I tOdWY I?WAnZɇg->nZ}ZU~7_|x[˴J'-'4]J'->W˴Z_I/J>(@Sy%@ ]z󇏊*Niz%Mڑ~i]=e^ɇFg-/J>(@Sy%@DVL|P:i~=ug*N̒ Z/ї%NZ.3K>4:kG9 >w3K>(@AF2I I@YY tPdYAz~M2C蓁s7I t1PZjjv_[ejɇFg-'njbBAڟֿoo%@T%NZ}]|Af|htǛlfvI@ sWI tPf|ht}P}f|P:i.*XY pOdXA䟆XAzI'lbɇFg-k*wo%Nڑ~O]fa\O3EG{7f|P:i> >w3K>4:k.* ;NZO̒ZtndۉU#.dYAѤ$,(,tLu%+ԒZOԒJ'-@+%NZnSK>tڎ:U-t] YARzYY I@YAJon3K>4:k> >wGEGpE@{̒&@?VP6C蓀s7I tP1Ē Z" ĒJ'-'4̽LQQܜJ&o~K>44k^~7G%NZOĒڑ" ĒJ'-'4]ŒJ'-?yÅg-E?[ۼJ'-'n^ɇFg-TȯW}>>UQʘWA+'rr4I #S;ڟ׿gvĒ ZĒJ'-?[bbɇFg-'nbv)]L,t}O}&|ht]S%NZ Y,$,t]Yf|P:i.*p3K>4:k> >w3K>(#uoV %MZOi%NZ_i'N@S%NZ7BĒZ" N0kK>(@+'+t}O}|ht=?vKHϢ+i5I ĒJ'-'nC{jbs7CskBownI|Q5䃢I;?YXY 6ݘb{ɧ}>0·Fg-'nf" uխ >*:+*;f|hh}P}f|P:i^S&Z,eP}f|P:i.t3K>(@?M>ZY @ZA(r-5CbMc5I @ sWI;ҫnfɇg-E@[jf蓀ҹ?#.hLw953 endstream endobj 21 0 obj 3589 endobj 19 0 obj << /ExtGState << /a0 << /CA 1 /ca 1 >> >> >> endobj 8 0 obj << /Length 22 0 R /PatternType 1 /BBox [0 0 576 440] /XStep 2032 /YStep 2032 /TilingType 1 /PaintType 1 /Matrix [ 1 0 0 1 0 0 ] /Resources << /XObject << /x20 20 0 R >> >> >> stream /x20 Do endstream endobj 22 0 obj 11 endobj 23 0 obj << /Length 24 0 R /Filter /FlateDecode /Type /XObject /Subtype /Image /Width 449 /Height 489 /ColorSpace /DeviceRGB /BitsPerComponent 8 >> stream xm8 b B#` `,ݜ{T%K8+qquJWo7˹zu2'A N|U+ӤPo- 4)ӫxKR(gӤP{TiR(V3HiR([cI|W> 1LBB C+Z.9A` d/wX7wIkFM/O“hhWI^K fPގ/wcxخ]^9+Nao< :o/Yo{'91!g̫fiw1@&%)tOӁLf~~tzN 78u2߷Hz5^ hY i.Sgil? gzOtF&9cDUѥ pqJqy$#vZ1R|\OZxT2Fۣ`9ib{yxLTԊMR棯jT7((勹pqJws WcER)4?3iZVz{eQ8zr)[|#9-wرi>cƞ|xSu~ JG [ H8GW|vwld<1T_bi|+>6Ol)η}x*#5EG^bF/n;KqdE[|\1jΗyt%K`V<ؐb'ǾD$Ź1|n?I[4"yKy*z{tZ⾙@ca>:k#7"⬥J~uB>u1Ox,_Hk)n8a"iBP)T Bй??|-'\i_?6)mS+eRSXriF%|ǯOՏbe yܾjtZ N1\4o<>S*-C- jrZZխocXwH4K{~9rr٫):'bZjե3pk.MnnHč#djbkGc{7ƭˋ786k6OOTnzQjƻf#Y-*l<ѭMΘ}]sM`QQ1LHce:eN;Igt?v!;$=ߜa42s?k^&>o)tgu)&B=ol[Q7DC.:?I[ko gGL=aIh{ܞk6#g(?W?5ukO# ;c?~a{ <ម?3C/i)ZSpG7Pmn>X%m.?q+?6-|nO?읤1ZRP Rh6΍|oԔۿ=%7cp<ן^hQWr)v$W'ju62Z?)&"Nٸzjfx~wkzknϫ{ 9 S3E:W5SQutl?䬝Uڬj\Sި5 6f!kաsŦsch])b=Ƕ!K3ؽ?gB"))&Ul3.3j6{.IrSN'?-/C>Z\1TWmayk4=94>ji퐐vLכg&jmjdt_jϑB;[N=H˧W_26)8iq}GxᐝK<itr[mjs)7jwtFٷ:)tRh:*ujZx]0yM> >> >> stream q 449 0 0 489 0 0 cm /x23 Do Q endstream endobj 25 0 obj 33 endobj 26 0 obj << /Length 27 0 R /Filter /FlateDecode /Length1 8028 >> stream xY{\e=s?g 8"B *jrr)ՊD2o e^N25#r ̒lVk*nZ"<=< "7N}jͤa }rfߧft9zo_~u)p>mJh|Ms<[i09O4͏ONlz6@8/}rELhִA4:4(bAt,&K%) [tT=`fcLWZg$QqA A|)6W9G<6/z1J[uVJ*#=aW4+ o@6d~M~lOhb|6/|6[lKgH{(E!,-Aؠ3)r&͡[ڈxc'L& v)#n/i1m[wGՍj=i1$օc0cDK8TyžvU@1 馠q猭y`l+;Lz>|ȼu"}w$Bi驘(b-H9<7zvb(Z8fg숱BnDd]&]NV!6>W>ӓ.1׈;wcU\;z^a'Hۊb7޳IPn+;nKذJ-I'+ݯx3I "r7hғ[HN_iiܢ|}EѾT2{"2/s@\ /ҏJf'?9c[qˋ͚}b<} +>x+aJ , 2 Z2Ф K Y/ckL$E̬ vzpCK]j-i$fVjԞ& `2<9EdΒ~ie"+`s\,dL `=o2P̙I ԖYF'dnwC}Ѯ;FaQ' I2Q`QC-mU}Mn?Rҷj&Φ[pBw_7eubbJ!Bd&tg0QЗ ƉɆi \^F $3g7[JXxI#/iδɒ Dh(@֚I,1p3C~~Ifv Qg^q z 4TTCIYE؏cJYŲ,wVKO12B!+ ݅1ܙ,2,ޯ4a*:ŒZs3=2u~%g:auVwO^l32'ƿhXwFUb7d 3u3Xnr/ٗw3C7&]#X'O U;64_o|TL{*ۯScSTj 5.+1|!(ˎfفĢ%r_<$neb8ZѮy"o_(J\OvEd}n݋ _:twcM&6o_δC횐^PO&k_`{9(Y֧6*.[̂4qj4y}X*sWD )hUwō衴5Pvh&dfBpV5B묝qU_xc<>^^AAAAf,AaaLq{F% e2SPWdlB3ZЊ6T0 1=b!1%)+ᤒҤIkI"3[)֧EH90Uil+*YհƟ?D)O◿/+f#''4:`R}22&36;hKXxn/h8$r}tՙ .xA#ݪ_e19zC]UBart :gּ^W7͹g)6* .z w6c;\Iv[ uFYvھקO7۹I۲N]QHIwk`c|{~%>7jL$.Ce!rm.c](8r]oDGƓimmD>xpu-9SV&nلqrNn*&8CVn5o va3OpAa+mm/6n~-$ã<]2i:A#ƍ.mXK! H5w ]_?,lڨ@[O˿J'|/m}ކԗM"UwpiSWo32A̭ BKc|sfsy_nJ6eV&!M8(HL/H=mىԐI1 نXW^uo}[^iQ6eshtw $X$2QV-BmHeJT5<P3j`#%hCx1Zg/Sb:WXaXdYNVaFQJzWTPT+ WT,"7t:oV jԫ%CG?{^ɑ/l_?w[~_BwMĿ SC]@"_2SN6t?UZ 3rӁ09$0Li(@P7x)ӥ3[Iɝqf鲜0N *l&"V"uO酸8EsRSWWZWtzNDCчc{Ǿmv::.;|7S͔;f2 ƭK3/MgMոl-0 sL|پEh &WXSL*V~"9eɲ j UкpKje`@mdJ#l_n >?R?z>||E }|ҕj:sd+վQMW'cBN:}v:#}F(>+]Pb,1K,%[Rb/vE~cݻ֬ڽ{5W}ǯ2;xKǏ]^Ϗ-5  wnJn`,#!`זoUu.~udE$CB^9MJkZ*Ӵ\Tr`/$xqxX'^8[l,7K42AA; a?^t<(pp'|ED*a+/.V%1 ѷ7q= gEQ!GxsGP@#ZM:M;ÌdZ#iGX-Ѿנv΁r.ƶ#E^a8L-(A%^>#$-V <.yGD^^Ҙ'+$ +Sj,4ƈ)i') } p@2JTtӺЃF 1ƗÔJc%f-t z6 @! N 5N)f0v0"@Q%U[X'V#Ox߂kA]UWjlioZ/KC"ǯ WL76O S x>q4 9~?/O8~BϜtf!ctc?slƓ^$F/~'8]bzlxxq|A8c}YPXrۥ}ĽߪZor=w JqN+;1Z+*9p+-Җ4lW1LqǍ39JZ/Sp/Ek-Z\Cիʊ/bRǕT|>(UbeH|>+8._GZqY||.Xj*\ԄPe .o9>.=qq,X1 p\Ts|ڊrӊ[qV+l">q}4c>qB|&q8# ļV|Ȍx?ɓVd_EDIJÉ9niB${8{8f߭H9ޭ8cXcF+'He_pY#q8aBoiX+=w,CtHC\x`tHC6d39b~߅2LR?3L׋L$qÄ)&)Ղ)& Q{arϠ=R &9GbPq&{$uaЄ 90@rG_+zIo>ZCpiE(؍4Սc=n.NNڇmhh1GHf&F t΅r>tQ$VSP$72#cKVf7RP endstream endobj 27 0 obj 6004 endobj 28 0 obj << /Length 29 0 R /Filter /FlateDecode >> stream x]j0>EŠeq }MSF·oB 9|ė*w7V8Z$:6JALvblJcm)*Keu88! endstream endobj 29 0 obj 360 endobj 30 0 obj << /Type /FontDescriptor /FontName /DejaVuSans /Flags 4 /FontBBox [ -1020 -350 1680 1166 ] /ItalicAngle 0 /Ascent 928 /Descent -235 /CapHeight 1166 /StemV 80 /StemH 80 /FontFile2 26 0 R >> endobj 31 0 obj << /Type /Font /Subtype /CIDFontType2 /BaseFont /DejaVuSans /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor 30 0 R /W [0 [ 600 636 636 636 636 636 862 615 612 520 633 411 974 633 392 317 277 390 390 317 636 636 557 636 636 636 603 633 611 591 610 549 686 ]] >> endobj 6 0 obj << /Type /Font /Subtype /Type0 /BaseFont /DejaVuSans /Encoding /Identity-H /DescendantFonts [ 31 0 R] /ToUnicode 28 0 R >> endobj 1 0 obj << /Type /Pages /Kids [ 9 0 R ] /Count 1 >> endobj 32 0 obj << /Creator (cairo 1.8.10 (http://cairographics.org)) /Producer (cairo 1.8.10 (http://cairographics.org)) >> endobj 33 0 obj << /Type /Catalog /Pages 1 0 R >> endobj xref 0 34 0000000000 65535 f 0000020403 00000 n 0000001368 00000 n 0000000015 00000 n 0000001345 00000 n 0000002194 00000 n 0000020250 00000 n 0000002922 00000 n 0000007114 00000 n 0000001525 00000 n 0000002091 00000 n 0000001732 00000 n 0000002069 00000 n 0000012774 00000 n 0000002436 00000 n 0000002849 00000 n 0000002458 00000 n 0000002826 00000 n 0000003164 00000 n 0000007041 00000 n 0000003186 00000 n 0000007017 00000 n 0000007356 00000 n 0000007378 00000 n 0000012750 00000 n 0000013057 00000 n 0000013079 00000 n 0000019178 00000 n 0000019202 00000 n 0000019640 00000 n 0000019663 00000 n 0000019898 00000 n 0000020468 00000 n 0000020596 00000 n trailer << /Size 34 /Root 33 0 R /Info 32 0 R >> startxref 20649 %%EOF PyScanFCS-0.2.3/doc/Images/alexB_orig.pdf000077500000000000000000000524121245330745300200020ustar00rootroot00000000000000%PDF-1.4 % 1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj 8 0 obj << /XObject 7 0 R /Pattern 5 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /ExtGState 4 0 R /Shading 6 0 R /Font 3 0 R >> endobj 10 0 obj << /Contents 9 0 R /Type /Page /Resources 8 0 R /Parent 2 0 R /MediaBox [ 0 0 576 451.8 ] >> endobj 9 0 obj << /Filter /FlateDecode /Length 11 0 R >> stream x]ˮ,qWPdX[`,^^ #H{~" h +#}Ώ?o_mA߽ ׹'Cyg?]]~'#z(z-~Kgt>=OC׏md_M_o3C?7/ñ_|Jluy{9o;_>~w˗oOS O1on__~/ŗ5ۃw~OdOc?}x<p8< G7_lב{7{I{'ov]kjѿ}߾O?_LjS}=qx]9yu>8t~y9>\rG*G-O y>|ujӵb:Ճ~zTr{}yy)ShtkRU?q#Sr3FZc{n򜚻jy\zo?gn? t\;ޝ*_z@퀮jfoX};хLܚ Mޗ]]xj뙧I2#/t C-\Ah7Eޗ)Vj+v)+]ђԠpɐwUeW^Azf&^u╃,Dn42U:"W.-dK5"ȗC)UyYvFKR7glmrsUˮ.dkU9vv],M*gM\Aࣈ;IeAÉ֐tO.hTjPM\m2$pgyg%[a103U麛zued4-\A#Sn#yeM!ȷYe-J:3oJ~{Z}B 9OJzYկ˼/~a%KGGn;xlbK%.ĴP0p꡾ Ճ,FC`מh뛁juj{~_(,w}T2JܸoJ~U_J_Xh!3 <C$c{;'̘z+KeAhh'+kOU]J CD[ƶͫ(RZ xqO3pSP=.ЗC![M5k_ |/9< PX0pF!,dJ5}>cCCBN@.pxM|8#4d 渱tm3EC =wP{ՀUYՇ Hc%KG08& H@1-0APZ=@Ӑ&XCӵ7 -|ªɈ3a!SA[Ҫш3B 9v<$H: jn0cZ1~-VSUǤII CDȍ}n2$I-Lڇ3pSQ3NC`7a1][,n~/YBOV}HP R9n@0ccEBN?`z AJ![M0̘ NqFhh'`vj/*+8#Sid6^ѐE`$*j>`x\J![aqjg+z:nha@:I)%V?3J_}Q7B 9/fAi7NC`[0̘ vFhh'`O`7ޓd CQ6)x#tQk`<8Aы7NC`[0̘ Fhh'熏{a@:D)%P0̘*-x#Q,0pzl-a$1][ `jɪCF㍌ӐV?m! "=4Jil5ЌfLV x+4 5Jk REnH0cCR㭤BNpFJ81h$dk p7ӵf5j: -vJ IA0(lݼʘx+soS![M~fLV x+40){a@8[iMc!SJa 1UZ!VRYh!'೟^" l=7a1][1 VVih'߲PjP XU}jTVt؇@m41 VHӉi&`֎Ai)MR![M\KtmAMNC =onha@8&XiMc!SJ'F/SU`%5rt3$3FHIƎj`d5z= ! FRS9 pc@cU녃b`4l5nnpM-0 FJhh'`{a@:&i)ՠ3O8*#Q," (-]0IIs ӵd5j - A6YM0J 1 FC"!M0BEL 5o$ OR`4l5Ҟk j(Z5,Vxi)%ɍSE`$5rznx&Jjt ьj`d5z^ޥS/i.#)4+6? +Eˈf-L燓oRed3la1][,`@s'wz #5 R叄Ң!e4rxMV\FJiV>?3ki.#Q4nj/*+\FLX$qѐE`]BK 38 L\F@iV7jӵd4(Z ӣjL)B fL} i.#Q,>?Hi: jx+1][,`Ls1 -VSS2BAkNa(Þv0B\V^\F6iVqӵ4(Z q/ \FP#,dJ ?": 3J>4(Z wxFJHi.#4d ofL \FLhh'^@5dUV!Ӑx/@m4T/NC nv&J"4h: jp0cZ&7w0 PX`PFXȔ(rcSUBh4r}OVD#4d pcӵ4шi -xX]LMBh4 7aP6y! F>h!%`K<&D+ߌjh4zv  j42SUBh4r/'JLi j K7a1][-@LBO@>/jCL#> m&KGmNK -/n8LVD+G`tmM2NC =7{0 PX@P)%Í~fLV}itZ59Q (-0VJ#4d V0cZi: -#XYLUCh4 .n@mtS!V49h!&`Wf jꇑ`tkƈ"NC =m 0 PX@Zs[iMc!SB ţ``CRsIb.@ #F5t`atmYmd5z=j/)}jn#id'^бm4$FHi&>i8BPZ=@Js)M![Mgwbj -xW`aD: B?#ҢIm$5rznx &Jjn#4d էL FBO`FRS9V#ƶMQ6bA 1H8Bm4lq LV FJhh'ˆ@au8 L!GD`TiQǤ6B 9>C?CPZ=@TsQM![Mȍ~0aX6EC =on!Ymd5,A7a l 84(bZ5oC@0APZ<`Js)M![M뇁`tmAm5zznha@uPZsA1NCZ[0̘ yFBO@ _@dUV!y#HV?t_PǐBNL 5/nxLV9CPZ<`TXQА&f? 3kBM^KT1yp!"#¶MQ|A 1#7{<&=- FJj#4d vqǁt-[vЂYGi`:<k&˸_÷lӍ}Iްw74 Jy~y~c_~W+{:~!yy)o%d~}VW1IY2.$O1kI|sagg!yHP$%oOZ'|yfWn->[4w @~Xkkx_-({55gO߳•5XIik/=|#oj.nBv܆O{@K.꟞H';g _|GL}7qf endstream endobj 11 0 obj 6922 endobj 17 0 obj << /Filter /FlateDecode /Length 68 >> stream x336S0P0 F )\@>,́,# .C c0mbl`fbdY 1 r endstream endobj 18 0 obj << /Filter /FlateDecode /Length 49 >> stream x36P0P040F@B!H Y@8&+ & endstream endobj 19 0 obj << /Filter /FlateDecode /Length 80 >> stream xE 0D{`~&f( JpO{:2Sa ,S`5FR죰n_uzS*Ovvq= endstream endobj 20 0 obj << /Filter /FlateDecode /Length 90 >> stream xMA "OPDtz_NE5jK02kP)U0\ 2IL{qIqzz"X endstream endobj 21 0 obj << /Filter /FlateDecode /Length 210 >> stream x5P C1g dVukm;aBXȔy)K>:L." u%ʚ +`p&^7`i5tႦ.B%|u{OxjrvC` jMX> stream x36P0C. endstream endobj 23 0 obj << /Filter /FlateDecode /Length 317 >> stream x5RKrC1ۿSpΘ}tj'+-@B./YK~%ۥW%B>R-G- Q=2'":xa>N)x_xN;2$KMH=I+4t~&+s{rj X+)$=Hr7VސWg%&&MܕBXtLX㰄*aՃM5fcdxLP} #GMv²[6!D3,($Nc$ Ұ9 9e, mh%zМaמE[{ endstream endobj 24 0 obj << /Filter /FlateDecode /Length 338 >> stream x5R9@ } ] v͜~߆_ CVie!U-.Im W%ڥ Pt,6˯JH+kLwIi"Eo7o}=@.^ AS(i|Ъc(ew 4<3}(~_K&(? _osџa`Ś}@*z`yT endstream endobj 25 0 obj << /Filter /FlateDecode /Length 163 >> stream xMK1 C=/yoIʀXT~rICpn4Ke>\1'X *b8j`Nhҡ+[a v悓 |:a̶ͮ]cwIi׾zx! [YSoM-<ʦ}>9o:k8. endstream endobj 26 0 obj << /Filter /FlateDecode /Length 392 >> stream x=RKn1)@Mr[T /1 %?ꒈ3L~r]Qljg!.6Xr_rњbO/ȴTXVݣC(-װr{d`Jn@CHYAaPl( WԬtb ) ٠[]aP[[xfޑ3qYk?=Q2QMg|2RCgB'`$Ip#A 1qOl)V;ޒ{,\L'ib?lK\+E(~Aq|XdDw#h% 0xyDhDԎ=(ͱ&{ǫvzcw. endstream endobj 27 0 obj << /Filter /FlateDecode /Length 67 >> stream x34P0P4W546T060Q073PH11s,lLeb ̀Ɓ% 9pr΃ endstream endobj 28 0 obj << /Filter /FlateDecode /Length 87 >> stream x=0C{` }rۀ?iC:N 6 ΁7AE/.o !$ŢVůE4I7QNJx>uz endstream endobj 29 0 obj << /Filter /FlateDecode /Length 59 >> stream x355W0PF F )\@>ehifY@Has`zrZ endstream endobj 30 0 obj << /Filter /FlateDecode /Length 165 >> stream xE;! C{N#y6;I,%?+:cck'R: g]a2So\\`nN|愯U—L 0;Q|$ ꔍ0G@LM/yjAPkGkS4g*[ :L?= endstream endobj 31 0 obj << /Filter /FlateDecode /Length 71 >> stream x34P0P0S546T04V073PH1 X\00247CbBeX r`J# endstream endobj 32 0 obj << /Filter /FlateDecode /Length 248 >> stream x-Q9AzBsˑ C :-qPO+Uwu9HTM]vf5,?c 7zqxLu5{kOfP2+qSușO \ ȹeƌ#M!RH&3AQ~#aU#j \Ks4;<9GW +ET<pC7ҹ^s0XM7/=[ endstream endobj 33 0 obj << /Filter /FlateDecode /Length 304 >> stream x=;0 C{Ȍd'>2VI(/u< i& b;w؞D/)ϡ+E:Ū0[M*K õ}74uK hY pu;Gw5<TQ!OJ|<(!\{0FS@\^BAjI'> stream xEPC1 =`,{wHۿ=JFp!Z?ZK oGFA= 3A΄@xFnvpμ39Zpә\'mBITqTqLύׁlӑ!KI%&~S*)[*EH䁓M4,?Cb̠Q0qGuٜ9-L|X&Q)2>'\N}䢥Uޑ"ۡW%Qէ<Y> endstream endobj 35 0 obj << /Filter /FlateDecode /Length 68 >> stream x32P0P4& f )\@B.H  %[B4AXf&fI8"ɴ endstream endobj 36 0 obj << /Filter /FlateDecode /Length 163 >> stream xEu1 CsUx:?G i@xx= r]Ņ ?޶42܍e@N"WI3Tb\/:"̒@#|:C[ۙ~:!**na.@RԏQꚡ*+kjڿ"}\Ne{g+W}: endstream endobj 37 0 obj << /Filter /FlateDecode /Length 255 >> stream xEK D#> stream x=PC1= |7˥m$B6BLɔ:ʒ)O>Kbnd6%*E/% }ՖC4h9~ 3*K6p*3 mtV[ Ф`׶ r " JMrR=ot-N=Dkq: DpFjtaŲC5=kz7hGt4CָR endstream endobj 39 0 obj << /Filter /FlateDecode /Length 161 >> stream xEK CBGG|tJ■!M@w'/mK >[ x6n5uVhR}ith6s+ fz:rGp_Gdf)|Q]dcnk]3s: endstream endobj 40 0 obj << /Filter /FlateDecode /Length 332 >> stream x-R9$1 ~`LtIUls#h/#xE=f۴[iGiK,W ;BjW0wy.2meDkag؏]e8*Jl !2J'Qw\I2[E™w2;yNE{ kF9+%|6vzrYɩHHӺ NKؖߗ3| endstream endobj 41 0 obj << /Filter /FlateDecode /Length 157 >> stream xEC1DsUA wJo-%S'"h0yM%V,&rAJ1xN1븨ufihW3=5'M<[ }@8IP1}bv">G)#qbn fW7y endstream endobj 42 0 obj << /Filter /FlateDecode /Length 320 >> stream x5Qq0 54sۿ @;a@dJ\UGM>`!S֖{&UF!}W2j]* UYFp&I8d Rӿccz endstream endobj 43 0 obj << /Filter /FlateDecode /Length 131 >> stream xE ! CT>՞0ABA";06Ѣ76իc,zRV鐇Pi0QąYLCaΘȖ2MlTv<e~ma, U^ ?KwUBS0 endstream endobj 44 0 obj << /Filter /FlateDecode /Length 72 >> stream x50{6X`KEoC|N/Z #pu#])Ec΂q_H1F=#O_p} endstream endobj 45 0 obj << /Filter /FlateDecode /Length 247 >> stream xMQmD1 \ky R]oC /)%K [UC?13,=?TPbht/"+ߏe s`&4`oI&ռ3d‰ATwM,3V7: lx%D`r Z`Q+ tĺv7C/਺x} K{,|BL;wI#fR:=b}@e+ (\* endstream endobj 15 0 obj << /FontDescriptor 14 0 R /Name /DejaVuSans /FontMatrix [ 0.001 0 0 0.001 0 0 ] /BaseFont /DejaVuSans /Widths 13 0 R /Subtype /Type3 /CharProcs 16 0 R /Type /Font /FirstChar 0 /FontBBox [ -1021 -351 1681 1167 ] /Encoding << /Differences [ 32 /space 46 /period 48 /zero /one /two /three /four /five /six /seven /eight /nine 76 /L /M 80 /P 91 /bracketleft 93 /bracketright 97 /a 101 /e 104 /h /i 109 /m /n /o 114 /r /s /t /u /v ] /Type /Encoding >> /LastChar 255 >> endobj 14 0 obj << /Descent -236 /FontBBox [ -1021 -351 1681 1167 ] /StemV 0 /Flags 32 /XHeight 0 /Type /FontDescriptor /FontName /DejaVuSans /MaxWidth 1342 /CapHeight 0 /ItalicAngle 0 /Ascent 929 >> endobj 13 0 obj [ 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 318 401 460 838 636 950 780 275 390 390 500 838 318 361 318 337 636 636 636 636 636 636 636 636 636 636 337 337 838 838 838 531 1000 684 686 698 770 632 575 775 752 295 295 656 557 863 748 787 603 787 695 635 611 732 684 989 685 611 685 390 337 390 838 500 500 613 635 550 635 615 352 635 634 278 278 579 278 974 634 612 635 635 411 521 392 634 592 818 592 592 525 636 337 636 838 600 636 600 318 352 518 1000 500 500 500 1342 635 400 1070 600 685 600 600 318 318 518 518 590 500 1000 500 1000 521 400 1023 600 525 611 318 401 636 636 636 636 337 500 500 1000 471 612 838 361 1000 500 500 838 401 401 500 636 636 318 500 401 471 612 969 969 969 531 684 684 684 684 684 684 974 698 632 632 632 632 295 295 295 295 775 748 787 787 787 787 787 838 787 732 732 732 732 611 605 630 613 613 613 613 613 613 982 550 615 615 615 615 278 278 278 278 612 634 612 612 612 612 612 838 612 634 634 634 634 592 635 592 ] endobj 16 0 obj << /seven 17 0 R /period 18 0 R /one 19 0 R /four 20 0 R /zero 21 0 R /space 22 0 R /six 23 0 R /two 32 0 R /nine 42 0 R /bracketright 27 0 R /t 43 0 R /M 28 0 R /L 29 0 R /five 45 0 R /P 30 0 R /bracketleft 31 0 R /a 33 0 R /e 34 0 R /i 35 0 R /h 36 0 R /m 37 0 R /o 38 0 R /n 39 0 R /s 40 0 R /r 41 0 R /u 25 0 R /three 24 0 R /v 44 0 R /eight 26 0 R >> endobj 3 0 obj << /F1 15 0 R >> endobj 4 0 obj << >> endobj 5 0 obj << >> endobj 6 0 obj << >> endobj 7 0 obj << /I1 12 0 R >> endobj 12 0 obj << /Width 458 /ColorSpace /DeviceGray /Height 503 /Filter /FlateDecode /Subtype /Image /Length 46 0 R /Type /XObject /BitsPerComponent 8 >> stream x݋u:a*P**:*tRɽ`9mB߹gcav02#sI<>( 2 7MqVIdMVIg[A&]I5L~oC^; bY"[A&7d]2f. $^'2?|?'>"\P~oWaFgǚL>3>\H7˿V~v\O J7[2?cݭg_S?xd~%B&>oPd8,DYul|Y^B7V֎Y/Y%F\"ڞ`LeZ.("ioGs0r1EbzsBӵ\QZd^u3iLWdѾN#+c/8l'HT!S!/L2ybӏ1fMd3ůxrAtAvR5nږ,hW4}o\8<㜐G;{0GxB?w>fn<%p$1=>v7&vuCKtIt3Uw8?d? !?Ӝ6dk7=Guj'1~VI~QSsJ&3}wtp>_.p8y{i8;G ޞmfnc_.>;ǽ4? 0؎N':[pY\nIZwGޝjw' f{ظ$}̓&W>rاah?s8t?דOOF.|CR_QRW}u\wa˽GU~N]\9o3ʺun7[%ƝWjLqtL9^\RL^$͵c?KGH܅٫ sJq6O״=ov??ǯ}e:N7Wfub;>?%&̞sI^.n_pEϞwܨWU^{CIe[y1r w9v!FY]f%J wfcUqn=;8%dxqaJ[\gM]{88>0LGS{s>Ʊd܍׏J:wۗ @eܖe%=0ȬbLn$K] }?ׅ}$Ews`'fL\1xZc2H.̚rHG{̺4o+ {GO*OF6uڅ<5-FeiNA> 'J&ñM_T'zO Cx{4 IǺ4&YnMD6&IQ AE+"5piZ-?HÛ!$GmulP^}Z2Mzt4W$O^~M}w>6-p*s8xW/Q$Q8c]ŋ~g4P6I6,gȤ/ܩ/p3.7xal]g8-&?̺xB+Ph&;쒧[6kI~DMkAťdev*Jq+f7v:4mFOFA{̾/-O#)$sXwa$ߖԮ:S7Jz u^>q ˴kL 홐 Z|3-թ'ɘ}(⣡8' 7V厧qfmwE\妓ŧ+"1}@)N:lvw|?ߺֱ~/|uaI5WɤZg&} 4t7sHWZoɩKU.f“1UMߑadk~Xd_ŧɡg q j&c3=ګ=Z]}~O7]1bGsU_qE,L_,]JO2l]2~7HzC֒6ɏm:bv7ƬT]D᪙B&1E>UWG9fYB~[w*/ڹǍ}X;4l.)>;3Ǝ #>)qe{tmYIӾO#w̤DVmߥ,S"fOmk1>TR6[\3}ZZ_k\]{s>#>7 `}QNE3Zy(?U(˶M!Z,y=Qc/"6/#.!ˤj+~`R|VR\)_kuAvgV#T*.VmLVzzL. zzko滉ZX=OQ/7"}`vT_HͩϩoEor|g|˦~бuLMM&+$/e#|]s"NΖdr<}1aAʣ2h觅uAdV2mRiT,/M*hmTs;b[27I7Y+w|_{4Y.To= zVx4b!$w~|bf{P\jKCuV>|L.r2Z.LgZD1HNI}2iQgkַުe/aM>G__j<0w^~ٸ*<87A&gοM&u5>A\}IbU$_^/~j1}/ D=Wͤ{Vv,ko.'-Jw_bmٗ~]/t1K/m̛o0B<­&]x,̪fyȤb|>w+\KJp~w^sȎ߱Oc31=ɹ^0oOy쒽m|G,W-[A&~ۛA&॰,yVI2V{dY} 2 t;[VdZΘQLo麿A&VIV<66~[A&VI P endstream endobj 46 0 obj 3555 endobj 2 0 obj << /Count 1 /Kids [ 10 0 R ] /Type /Pages >> endobj 47 0 obj << /CreationDate (D:20120719154550+02'00') /Producer (matplotlib pdf backend r8292) /Creator (matplotlib 1.0.1, http://matplotlib.sf.net) >> endobj xref 0 48 0000000000 65535 f 0000000016 00000 n 0000020513 00000 n 0000016636 00000 n 0000016668 00000 n 0000016689 00000 n 0000016710 00000 n 0000016731 00000 n 0000000065 00000 n 0000000317 00000 n 0000000208 00000 n 0000007314 00000 n 0000016763 00000 n 0000015211 00000 n 0000015011 00000 n 0000014531 00000 n 0000016264 00000 n 0000007335 00000 n 0000007475 00000 n 0000007596 00000 n 0000007748 00000 n 0000007910 00000 n 0000008193 00000 n 0000008282 00000 n 0000008672 00000 n 0000009083 00000 n 0000009319 00000 n 0000009784 00000 n 0000009923 00000 n 0000010082 00000 n 0000010213 00000 n 0000010451 00000 n 0000010594 00000 n 0000010915 00000 n 0000011292 00000 n 0000011610 00000 n 0000011750 00000 n 0000011986 00000 n 0000012314 00000 n 0000012601 00000 n 0000012835 00000 n 0000013240 00000 n 0000013470 00000 n 0000013863 00000 n 0000014067 00000 n 0000014211 00000 n 0000020492 00000 n 0000020573 00000 n trailer << /Info 47 0 R /Root 1 0 R /Size 48 >> startxref 20730 %%EOF PyScanFCS-0.2.3/doc/PyScanFCS_doc.tex000077500000000000000000000126101245330745300171230ustar00rootroot00000000000000\documentclass[a4paper,12pt]{scrartcl} %Wir arbeiten mit PDF-Latex. %Bei Texmaker unter Werkzeuge > PDFLaTeX (F6) \usepackage[utf8x]{inputenc} %Für deutsche Schriften: %\usepackage[ngerman]{babel} %\usepackage{sistyle} %\SIstyle{German} %\usepackage{icomma} % Komma als Dezimaltrenner (im Mathe Modus) % Standardmäßig läßt LaTeX im Mathe Modus immer etwas % Platz nach einem Komma, für 3,45 etc. ist das falsch. % Mit icomma gilt: % Wenn auf das Komma ein Leerzeichen folgt, soll auch % eins kommen, wenn nicht, schreibe es als Operator: % z.B. $f(x, y) = 3,45$ %Für englische Schriften: \usepackage[english]{babel} \usepackage{sistyle} \usepackage[top = 2cm, left = 2.5cm, right = 2cm, bottom = 2.5cm]{geometry} \usepackage{amsmath} \usepackage{amssymb} \usepackage{array} \usepackage{cite} %Für Zitate und Quellen \usepackage{url} \urlstyle{tt} %\usepackage{longtable} % mehrseitige Tabellen %\usepackage{multirow} %Zusammenfassen von Spalten/Zeilen \usepackage{subfig} % Vereinen von Bildern in gesamte Figure %Schönere Unterschriften für Bilder und Tabellen %Setze captions mit Kommas und Beschriftungen \DeclareCaptionLabelFormat{mycaption}{#1 #2} \DeclareCaptionLabelSeparator{comma}{, } \captionsetup{font=small,labelfont=bf,labelformat=mycaption,labelsep=comma} \setcapindent{0pt} % Zeileneinzug ab zweiter Zeile \newcommand{\mycaption}[2]{\caption[~#1]{\textbf{#1:} #2}} \usepackage{tabularx} \usepackage{textcomp} % Sonderzeichen \usepackage{wrapfig} \usepackage[svgnames]{xcolor} %Farben wie DarkBlue %% %% %% Definitionen für schöne Links innerhalb des Dokuments %%% graphicx: support for graphics \usepackage[pdftex]{graphicx} \pdfcompresslevel=9 %%% hyperref (hyperlinks in PDF): for more options or more detailed %%% explanations, see the documentation of the hyperref-package \usepackage[% %%% general options pdftex=true, %% sets up hyperref for use with the pdftex program %plainpages=false, %% set it to false, if pdflatex complains: ``destination with same identifier already exists'' % pdfstartview={XYZ 0 0 1.0} , %% Startet das PDF mit 100% Zoom, also Originalgroesse %%% extension options backref, %% adds a backlink text to the end of each item in the bibliography pagebackref=false, %% if true, creates backward references as a list of page numbers in the bibliography colorlinks=true, %% turn on colored links (true is better for on-screen reading, false is better for printout versions) linkcolor=DarkBlue, %% Aendern der Linkfarbe urlcolor=DarkBlue, %% Aendern der Url-Linkfarbe und andere serioese Farben anchorcolor = black, citecolor = DarkGreen, filecolor = black, urlcolor = DarkBlue, breaklinks=false, % %%% PDF-specific display options bookmarks=true, %% if true, generate PDF bookmarks (requires two passes of pdflatex) bookmarksopen=true, %% if true, show all PDF bookmarks expanded bookmarksnumbered=false, %% if true, add the section numbers to the bookmarks %pdfstartpage={1}, %% determines, on which page the PDF file is opened %pdfpagemode=None %% None, UseOutlines (=show bookmarks), UseThumbs (show thumbnails), FullScreen ]{hyperref} %%% provide all graphics (also) in this format, so you don't have %%% to add the file extensions to the \includegraphics-command %%% and/or you don't have to distinguish between generating %%% dvi/ps (through latex) and pdf (through pdflatex) % \DeclareGraphicsExtensions{.pdf} %% %% %\newcommand{\kommentar}[1]{\marginpar{\textcolor{red}{#1}}} % Kommentarkommando %\newcommand{\fehler}[3]{\SI{(#1}{}\SI{\pm #2)}{#3}} % Fehlerkommando %Ort für mögliche Bilddateien (Unterordner) \graphicspath{{bilder/}{messwerte/}{auswertung/}} %Neue Befehle \newcommand{\hyref}[2]{\hyperref[#2]{#1~\ref{#2}}} %Schönerer link statt "link zu Bild \ref{im:bild}" -> "\hyref{link zu Bild}{im:bild}" \newcommand{\mytilde}{\raisebox{-0.9ex}{\~{ }}} % Tell latex how to break the program names \hyphenation{Py-Corr-Fit Py-Scan-FCS} \usepackage{doi} \begin{document} \noindent \begin{tabularx}{\linewidth}{Xr} \textbf{PyScanFCS \newline Data evaluation for perpendicular line scanning FCS} \newline \textit{Software Guide} & \raisebox{-2em}{\includegraphics[angle=0,width=40mm]{Images/PyScanFCS_logo_dark.pdf}} \\ \\ Paul Müller & \\ Biotechnology Center of the TU Dresden & \\ \today & \\ \end{tabularx} \vspace{2em} \tableofcontents \newpage \graphicspath{{Images/}} \include{PyScanFCS_doc_content} \section*{Acknowledgements} \addcontentsline{toc}{section}{Acknowledgements} I thank Eugene Petrov and Fabian Heinemann (MPI Biochem, Martinsried, Germany) for discussions on the implementation of the multiple-$\tau$ algorithm. I thank André Scholich (TU Dresden, Germany) for initial proof reading of the manuscript. The idea of a kymograph and the Fourier analysis method are adopted from a Matlab script written on the same issue by Jonas Ries. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Literaturverzeichnis \pagestyle{plain} % nur Nummerierung in der Fußzeile \bibliographystyle{plainurl} % Zitierstil: alphadin = [Nam88] apt-get install bibtex-extras \bibliography{Bibliography} % BibTeX-Datei name.bib ohne .bib hier einfgen %\nocite{*} % Listet alle Eintrge der Datei auf, wenn aktiv \end{document} PyScanFCS-0.2.3/doc/PyScanFCS_doc_content.tex000077500000000000000000000460401245330745300206610ustar00rootroot00000000000000 \section{Introduction} \subsection{Preface} PyScanFCS processes photon arrival times recorded in perpendicular scanning FCS setups using the Flex02-01D/C correlator from \url{http://correlator.com}. \\ \\ The PyScanFCS software provided is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. \\ \\ An exemplary usage of PyScanFCS - delivering a proof of principle from calibration to data fitting - was shown in \cite{Mueller2014} (Authors manuscript available at \url{pyscanfcs.craban.de}. \subsection{Prerequisites} In order to use the PyScanFCS software, the following equipment is needed: \subsubsection*{Hardware} \begin{itemize} \item A confocal laser scanning microscope (CLSM). For single-color one-focus SFCS, the CLSM should be capable of continuously scanning along a single line. For more sophisticated measurements, features like ``Multitrack mode'' for dual-color measurements and frame scanning for two-focus SFCS are required (LSM510, Zeiss, Germany). \item One or two avalanche photo diodes (APD) for single or dual color detection. In addition, matching filters and beam splitters. The detection channels are referred to as channels A and B throughout this documentation. \item A photon stream recording device connected to the APDs. In the tested setup a Flex02-12D/B correlator from correlator.com\footnote{Note that for some reason the photon history recording mode does not work with the Flex02-01D/C correlator. Keep that in mind while troubleshooting your setup. When using a different device, the data has to be converted accordingly. The data format is described in \hyref{section}{sec:datformat}.} was used in photon history recording mode. The device creates two binary files A and B that contain the photon arrival times detected by the corresponding APDs. \end{itemize} \subsubsection*{Software} PyScanFCS can be downloaded from \url{http://pyscanfcs.craban.de}. \begin{itemize} \item \textbf{Windows} For Windows, stand-alone binary executables are available from the download page. \item \textbf{Linux} There are executable binaries for widely used distributions (e.g. Ubuntu). \item \textbf{Sources} The program is written in python 2.7. On any operating system, PyScanFCS can be run from source. In general, the following packages need to be available: \texttt{\\ cython ($\geq$ 0.1.6)\\ python-matplotlib ($\geq$ 1.0.1) \\ python-multipletau ($\geq$ 0.1.4) \\ python-numpy ($\geq$ 1.6.2) \\ python-pyfits \\ python-scipy ($\geq$ 0.10.1) \\ python-wxgtk2.8 (2.8.12.1) \\ } \\ There are two ways to make PyScanFCS run from source.\\ \textbf{install from PyPI:} \texttt{pip install pyscanfcs} and run the package directly \texttt{python -m pyscanfcs}. \\ \textbf{clone from GitHub:} Obtain the source directly from GitHub (\url{https://github.com/paulmueller/PyScanFCS}). \paragraph*{Cython} PyScanFCS needs Cython to perform some CPU intensive operations. Before running PyScanFCS from source, a C compiler needs to be installed (\url{http://docs.cython.org/src/quickstart/install.html}). \begin{itemize} \item[ ] \textbf{Windows}. The common MinGW compiler can be used. Instructions on how to install MinGW can be found in the Cython documentation: \url{http://docs.cython.org/src/tutorial/appendix.html}. On machines running Windows 7 x64 with the x64 version of python, the Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1 must be used: \\ \url{http://wiki.cython.org/64BitCythonExtensionsOnWindows}. \item[ ] \textbf{Ubuntu}. The following packages need to be installed: \\ \texttt{build-essential\\ python-dev} \item[ ] \textbf{MacOS}. Use Apple's XCode, available from \url{http://developer.apple.com}. \end{itemize} Cython can be obtained from \url{http://www.cython.org/}. After unpacking of the archive, Cython is installed by executing \texttt{python setup.py install} within the unpacked directory\footnote{Cython can also be installed via PyPI with \texttt{pip install cython} (\url{http://pypi.python.org/pypi}).}. \end{itemize} Correlation curves created by PyScanFCS can be processed using \texttt{PyCorrFit}\footnote{\url{http://pycorrfit.craban.de}} \cite{Mueller2014a}. \newpage \section{Data acquisition modes} In order to achieve all possible measurement modes depicted in \hyref{figure}{fig:scanmodi}, the CLSM needs to be set up properly. The scan paths should be checked for straightness e.g. by bleaching a layer of eGFP\footnote{Often, hysteresis effects occur during high speed scanning and scan paths are not straight. Switching to slower bidirectional scanning or setting up a ``multitrack mode'' might solve these problems.}. In 2fSFCS, the distance between the lines can be determined in a similar fashion. For each measurement, it is vital to record approximate scanning time and channel assignment. PyScanFCS attempts to find the correct scanning cycle, but manual intervention will be necessary in case of a failure\footnote{In some cases, the microscope software (AIM, Zeiss) might also calculate a wrong scan cycle time.}. \begin{figure}[h] \centering \includegraphics[width=0.8\linewidth]{SFCSmodi.pdf} \mycaption{acquisition modes in PyScanFCS}{The six figures \textbf{a-f} show possible scenarios for scan path and excitation settings. The alignment of the scan paths (black) is shown for membrane of a giant unilamellar vesicle (red). The arrow tips define the different colors used for each scan (blue excitation, green excitation, or both at the same time). Multiple arrow tips indicate the sequential scanning of one line with two colors. The time necessary to perform a complete scan in each scanning mode is shown respective to ``one color – one focus'' on the top right corner of each figure.\label{fig:scanmodi}} \end{figure} \begin{figure}[] \centering % 2012-08-27-SFCS_DiO-DOPC-GUVs --> GUV5b \subfloat[SFCS: GUV scan path][GUV scan path in SFCS] {\includegraphics[width=0.34\linewidth]{GUV.pdf}} \qquad \subfloat[SFCS: Kymograph][Kymograph produced by PyScanFCS] {\includegraphics[width=0.55\linewidth]{1color1focus.pdf}} \mycaption{1 focus 1 color measurement with PyScanFCS}{ \label{fig:1c1f_example} Example of a GUV scanned using one focus and one laser line. \textbf{a)} The equator of a GUV with the scan path (yellow). \textbf{b)} A kymograph generated by PyScanFCS. The scan cycle time is \SI{1.527}{ms} (vertical) and the measurement time is \SI{500}{s} (horizontal). Each scan cycle is binned into 70 bins. Note that the resolution in direction of the measurement time is adapted to the scan cycle resolution. Also note the step at the end of the measurement. Such a step can be the result of a movement of the GUV during the measurement. This part needs to be excluded from the trace before calculating the correlation function.} \end{figure} This section describes the acquisition modes that PyScanFCS supports. Correlation functions are labeled according to \hyref{figure}{fig:example_kymograph}. \hyref{Figure}{fig:scanmodi} shows advantages and disadvantages in terms of time resolution, calibration and crosstalk. \paragraph{a) one color - one focus} One spot of the membrane is scanned continuously using one laser line. The signal is detected using one APD and PyCanFCS can be used to calculate one autocorrelation curve ($AC_{A1}$). \paragraph{b) two colors - one focus} The setup is the same as in (a), except that two laser lines are used and the signal is detected by two APDs. This mode can be applied for multiple dye studies. There are four possible correlations: $AC_{A1}$, $AC_{B1}$, $CC_{A1B1}$, $CC_{B1A1}$ \paragraph{c) one color - two foci} The CLSM is set up to perform a line scan along two lines with a distance $d$ apart. For detection, only one APD is required. The distance $d$ needs to be determined beforehand. In addition to two autocorrelations, two cross correlation curves are obtained. The cross correlation curves contain information about the shape and size of the focus traversing the membrane. Thus, no calibration measurement with a reference dye is necessary to determine extents of the scanning focus. Possible correlations: $AC_{A1}$, $AC_{A2}$, $CC_{A1A2}$, $CC_{A2A1}$ \paragraph{d) two colors - two foci} Like (b), this is a dual-color extension. Two laser lines are used for scanning and two APDs are used for detection.\\ Possible autocorrelations: 4\\ Possible cross-correlations: 12 \paragraph{e,f) dual color with alternating excitation} To avoid cross-talk between the two color channels, as it likely happens in the \textit{b) two colors - one focus} or \textit{d) two colors - two foci} modes, the CLSM can be setup to sequentially scan the membrane with two laser lines. This way, only one laser line is used to excite the sample at a time and the fluorescence of two dyes can be separated, effectively circumventing crosstalk. The scan cycle time doubles when using alternating excitation and hence the binning time is twice as long. This effectively results in ``loosing'' data points\footnote{For the multiple-$\tau$ algorithm used, exactly $m/2$ points are lost, where $m$ is the number of points of the correlation curve that are calculated by the multiple-$\tau$ algorithm before the intensity trace is binned for the first time.} at the beginning of the correlation curve, which decreases the time resolution.\\ Possible correlations (1 focus): $AC_{A1}$, $AC_{B2}$\\ Possible correlations (2 foci): $AC_{A1}$, $AC_{B2}$, $CC_{A1B2}$, $CC_{B2A1}$ \begin{figure}[h] \centering \subfloat[][A: Red channel] {\includegraphics[width=0.45\linewidth]{alexA.pdf}} \qquad \subfloat[][B: Green channel] {\includegraphics[width=0.45\linewidth]{alexB.pdf}} \mycaption{alternating excitation with PyScanFCS}{ \label{fig:example_kymograph} The kymograph yields a scanning time for one line of \SI{1.527}{ms}. One can clearly see the trace A2, which originates from crosstalk from the green dye to the red channel or from the red dye being excited by the green laser. There is no crosstalk from the red dye to the green channel, which in this case helps identify the traces.} \end{figure} \section{Working with PyScanFCS} \subsection{Data file formats} \begin{itemize} \item \textbf{\mytilde .csv files} each contain a correlation curve. Further information is available in the \texttt{PyCorrFit} documentation (\url{http://pycorrfit.craban.de}). \label{sec:datformat} \item \textbf{\mytilde .dat files} are created by the software \texttt{Photon.exe} that ships with the correlators from correlator.com. The format stores the photon arrival time differences between two photon events. Data format is as follows\footnote{Note, that Windows uses the little endian byte order. This might lead to problems when using PowerPC.}: \begin{itemize} \item The value of the first byte (uint8) identifies the format of the file: 8, 16, or 32 bit. \item The value of the second byte (uint8) identifies the system clock, usually \SI{60}{MHz}. \item The rest of the file contains the times between two photon arrivals. The time unit is 1/(system clock) (here \SI{16.\overline{66}}{ns}). \item 8 bit format is not supported. \item 16 bit format. Each word (2 bytes, uint16) represents a photon event. For low intensities, values of \texttt{0xFFFF} may occur. In this case, the following four bytes (uint32) represent a photon event. \item 32 bit format. Each dword (4 bytes, uint32) represents a photon event. 32 bit files can be created from 16 bit files using \texttt{Photon.exe}. PyScanFCS saves \mytilde .dat files in this format. \end{itemize} \item \textbf{\mytilde .fits files} - The \textbf{f}lexible \textbf{i}mage \textbf{t}ransport \textbf{s}ystem is used by PyScanFCS to save already binned \mytilde .dat files. Those files contain additional fits-keys: \begin{itemize} \item \texttt{SysClck} - system clock in MHz \item \texttt{Total} - total measurement time in system clock ticks \item \texttt{Tcycle} - acquired scan cycle time in system clock ticks \item \texttt{Tbin} - binning of the photon events in system clock ticks \item \texttt{Binshift} - bins added to beginning of the entire 2D data array before plotting \end{itemize} Because these files can become quite large, it is not recommended to store the data in this file format. Also, information is lost due to the binning. It is possible to save a \mytilde .fits file with only a few photon events binned (small file size), which contains the correct plotting parameters (cycle time, bin shift). This file can later be opened prior to opening the corresponding \mytilde .dat file. This way, e.g. the scan cycle time does not have to be found again. \item \textbf{\mytilde .int files} are created during binning. They are straight 16 bit files that contain binned events from a \mytilde .dat file. \item \textbf{\mytilde .txt files} are generated optionally, if the user wants to save the generated traces. The file contains photon numbers, separated by a new line. The binning time, as well as the corresponding intensities can be calculated from parameters given in the file. \item \textbf{\mytilde .zip files} are bundles of correlation curves ( - stored as \mytilde .csv files). They can be imported for fitting by \texttt{PyCorrFit}. \mytilde .zip files are automatically stored in the working directory (location of \mytilde .dat or \mytilde .fits files). \end{itemize} \subsection{The user interface} \begin{figure}[h] \centering \includegraphics[width=0.95\linewidth]{PyScanFCS_Main.png} \mycaption{user interface}{The left panel displays all parameters. The right panel shows the kymograph of the measurement. \label{fig:SFCSMain}} \end{figure} \hyref{Figure}{fig:SFCSMain} shows the main user interface with the following content: \begin{itemize} \item The \textbf{menu bar} with standard operations, such as loading or saving a file. The \textbf{cache menu} displays all previously binned \mytilde .dat files. The file menu contains a method to create artificial \mytilde .dat files for testing. \item \textbf{Pre-binning}: This sets up all parameters that are used to bin a \mytilde .dat file: \begin{itemize} \item[-] the binning resolution of the scan cycles \item[-] the number of events from a \mytilde .dat file to process \item[-] the bin width of a scan cycle (not used if the scan cylce time is known) \item[-] a bin shift can be used to help selecting traces \end{itemize} The bin shift parameter adds a number of empty bins to the beginning of the binned array. This will shift the vertical (scan cycle time) position of the visible trace. \item \textbf{Total-binning}: Bin the entire file using the scan cycle time found. \item \textbf{Mode}: Selects which mode to use. The modes are described above. Optionally save traces as \mytilde .txt files inside the working directory. \item \textbf{Data}: Displays current file information and found scan cycle time. The scan cycle time may be doubled, quadrupled, halved or quartered. This may help, if the automagic algorithm did not find the correct scan cycle time. \item \textbf{Find line scan time}: Performs a fourier transform of the binned data\footnote{The user is advised to not use too many events. This might result in a system lock-up.}. If the check box is activated, the program will automatically find the correct maximum in fourier space and write back the corresponding scan cycle time. If the check box is not activated, a window will pop up for the user to define an interval where to search for a maximum. When a scan cycle time has been found, then the check box in \textbf{Pre-binning} will become active. \item \textbf{Image selection}: Selects which tool to apply to the binned image in the \textbf{kymograph}. This does not work, if any other tool (e.g. magnifier) from the kymograph toolbar is active. \begin{itemize} \item[-] scan cycle correction: This is used, if the scan cycle time found is not exactly correct (tilted lines in the kymograph). To correct the scan cylce time, the user draws a line along the trace in the kymograph. Afterwards, the kymograph can be recalculated using \textbf{Pre-Binning} or \textbf{Total-binning}. \item[-] Select region 1: Lets the user draw a rectangle around a trace that should be used for correlation. Region 1 is always displayed in yellow. \item[-] Select region 2: Depending on the \texttt{mode}, the user may select a second region for additional auto- and cross-correlation. Region 2 is always displayed in cyan. \item[-] Full measurement time: Maximizes the measurement time selection (horizontal in the kymograph) for the regions. \end{itemize} \item \textbf{Correlation}: Calculates the traces and perform the multiple-$\tau$ algorithm according to the selected \textbf{mode}. \begin{itemize} \item[-] Span: The trace is calculated from the maximum of each scanned line. This corrects for spacial fluctuations perpendicular to the surface of the probed membrane. If the binning is too fine, or the scan cycle time is not exactly correct, this number can be increased to include more neighboring bins for the calculation of the trace. \item[-] No. of trace slices: Sometimes, dirt contaminates the trace. The trace can be split and the correlation curves can be calculated separately from each slice. \texttt{PyCorrFit} is able to average over user selected curves, yielding cleaner statistics. \item[-] Bleach filter: Fits an exponential function to the selected trace and performs a bleaching correction according to \cite{Ries2009}. Note that this bleaching correction is only valid for an approximately linear decay in the fluorescence signal. The bleaching data is exported to the zip file that also contains the correlation data. They are named \begin{center} \texttt{PyScanFCS\_bleach\_profile\_TYPE\_RANDOM.csv} \end{center} where \texttt{TYPE} is the type of the curve (e.g. \texttt{Region\_A1}) and \texttt{RANDOM} is just a random number. \item[-] Countrate filter: Approximates the count rate of the fluorescence signal from the membrane. Because the laser focus is \textit{scanned} through the membrane, the average signal from the measurement does not equal the actual count rate within the membrane. The algorithm fits a Gaussian to the average intensity profile and uses the standard deviation to calculate the residence time of the focus inside the membrane. This residence time is then used to calculate the approximate count rate. \item[-] M.-$\tau$ parameter m: This is a parameter of the multiple-$\tau$ algorithm. $m$ is the number of points of the correlation curve that are calculated by the multiple-$\tau$ algorithm in the first loop. Afterwards, the intensity trace is binned by combining two neighboring bins. Then, sequentially $m/2$ data points are calculated after each binning of the trace. A thorough description is given in \cite{Wohland2001}. $m=16$ is a good measure. \end{itemize} \item The \textbf{kymograph plot} shows the binned \mytilde .dat files. The Pixel resolution in the direction of measurement time is adjusted to match the resolution of the scan cycle time (bins per scan cycle). This is implemented by slicing the array and showing only a few slices in measurement time ``direction''. So far, no disadvantages compared to averaging have been observed. The plotting area contains a useful toolbar. \end{itemize} PyScanFCS-0.2.3/freeze_pyinstaller/000077500000000000000000000000001245330745300171615ustar00rootroot00000000000000PyScanFCS-0.2.3/freeze_pyinstaller/PyScanFCS.icns000066400000000000000000003402041245330745300215730ustar00rootroot00000000000000icnsis32S sy l dy ږ˂ ɿCDV =SR a b䏄 ̊  sRcNǘyr ! 5  ʂ ǽ ِǀ  bs8mk(.blWXVN3 \Y()/;O^<MdZ0.-+&#(WJNf]\++,/.1j"hY,,,)/!kqUlR ,,,,+0P`~--,+/%EDG))-*1 c/[ 32+,*/$bT1-,,,-!&(Z((&m_PQONז|\F~W2 TY_܀ On aҖK RZ_MZk ll8mk }NcH k@C9+Dsvz{fCY$$&+5G`yl4k[G-00/-*%!%9_x5pG+++,-/1/)",WmqD&,,,,++*+-0-#0g@p ?&,,,,,,,,+*+1+"Nun A%,,,,,,,,,,-'-1!ȸJ A%,,,,,,,,,-*/."тVA%,,,,,,,,,+-)$΃=&F<#,,,,,,,,,+.-ˈ'%)#,,,,,,,,+/&@lF~QY,,,,,,,,,,,*Y?eq,,,,,,,,,-*2,K)3,,,,,,,,,+.&>bq,,,,,,,,,+,+6o33,,,,,,,,,-)2/0!bh---,,,,,,,,+-'@%0&<))),,,,,,,,,,-/7(.*/&{>231*,,,,,,,,,+2-*2.++0!cb0,,,,,,,,,,),-)+-*0$Kxi#-+,,,,,,,,-,+-,,+.)9!0*-,,,,,,,,,,,,,,,.%c 1*-,,,,,,,,,,,,+.(|13)-,,,,,,,,,,,,+/&y;it32$(ߤf]0J^qT) l   #7 $BUN7 - Xϻ+ B 'ÿo 4˽ŀ ÿ֌ "ȿā Ǻwp ѽà Ƚ; 91† ͘ tԾÉ !j Ç ǾN: ň Ǿh+ ň Ǿq-  ň Ǿc+ ϿÇ ƿBH eӾÉ ſw MÆ ǿт pպ # 7Һŀ¾Qÿ` ?& yҰ@6'xŹT 7  "  $7ϩ T7 ;`&7 ؤvT7  7  7 h7  h7  g7  g7 g7 g7 g7 g7 g7 g8ghg mCghttUg~ngmTgl/Ogm9#;gl8!?gl8!@gl8!@gl8!@gl8!@gl8!@gl8!@g l8!@g l8!@g m8!@Q g m8!@uyAks:!@qvf<@Ռh ?G,S~&ڭ躝{0(/ag7+O0&7"f$+110012/#XSUT UP,0%M%,AXSUT US,1W$->XSUT UP,/& n/8XSUT SVL*.+1.T USX@+(C %0(IVSUT UTU10wM%-3VSUT VSWF'2! 4&AXSTUT UURVP,0#X T!2&EWTSST SSWQ2'2! 4*0&>TXVS TVWJ-'7%)3'-ANUVWVRH6'.5t:10**/351,).3'n%)120012.#CmHCA>;2*! 'jzxyyyzzwuskaTH:& 8oussrrqpppprtwyzythXG-@}zwsropsvyztdO4)|xsppsxzuaE&  LOQSUX_gms{ztpouzylM( %%$%%%%%%'),3;FP^o|yroryyjL"////////.--+(&%%'-7EYn|soryya9/| ++++++++++,,..//.,)&%'0?Tn{rnt{qOG~,,,,,,,,,,,,+++++,-./.,'%'3Ga|xopywY(6LbYB&!Q,,,,,,,,,,,,,,,,,,++++,./.+&%-Ca}~rnwzb-,1,,,,,,,,,,,,,,,,,,,,,,,+++,./,'%.Fjtmu{a*+0,,,,,,,,,,,,,,,,,,,,,,,,,,,++,./,&&6Vzumu{_%+t,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++,..*$+IrtlvyT+v,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++-/-&(AjsmytD +v,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*,/.'&>loo{j*+v,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++./'&@n{lszQ+v,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++./'&Fytlzp0+w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++..&+Tnq{O +w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++.-%2fulzj#+w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++/+%E}~msy?+w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+,/'-`rm{V +w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+.,%Dylyg +w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+,/'0kkyg+w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+.+&Ri+w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+,/$@+w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/'4g{P ,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,)3k~X ,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,*1쏈~j{^ ,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,*0 Ulyb ,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,*0 7 Flya ,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,*0 6'3$@ly^,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,*0 5(0'0&;lyZ,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,*0 5(/).*.&:~l{S,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,*0 5(/*-+-*/'<|k{F,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,*0 5(/*-,,,-*/&@zl{9,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,*0 5(/*-,,,,,-*/%Dvnx, ,w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,*0 5(/*-,,,,,,,-*0$Osrq/w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,++0 5(/*-,,,,,,,,,,*0$[mz\3w,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/ 5(/*-,,,,,,,,,,,,*/%fhw,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/"5(/*-,,,------,,,,,,-*sx,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*0"5(/*-,--+*)))))+,-,,+.'8},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*0#M5(/*-,-*)-133333/*),,.'4]T ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+-*87'/*--+)02+ &03++(2"HcG,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+.%?m.)/*--*-2"5b{qG$./2"Hkz,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/)--+--*0*Ù)#"Hvusj ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+-2,+,-*1"9dHOm{J,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+),,-*1#Q6"g|nx$,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,-*0!W2),1rud,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+.'@4),/&Ll{;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*0$Y!1++/&lxpo,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-)2k#0*,-)7nzJ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/&_!1*+/$[}nw,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*0#O3)-,+/~qxU,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-)3--,,+/%Nmx!,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-)2D&/+-+-*vrxW,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*0"S"0*-+.&Imy#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*/&a 1*-,+.)trwW,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*1"R"0*-,+/&Fmv,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-)2C'.+,,,+.(tqzL,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-)3,-+,,,,+/%L}ps,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*0$M3)-,,,,,,,{ozB,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/%^!0*-,,,,+/%Uyri ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*2g!1*,,,,,,,,*1nz+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*0#S#0*-,,,,,,+/%bswW,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+.(<2)-,,,,,,,+.'?ot,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*0"R1*-,,,,,,,,,+-)to{=,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*0#K"0*-,,,,,,,,,,+/$Rwu_,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-)0#5c0+,,,,,,,,,,,,,-*5nv,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*0+Py)!2*,,,,,,,,,,,,,,+.'npz?,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*,3#1\v|lB".1*,,,,,,,,,,,,,,,+/%Oxt`,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-,)/3,!'02+)-,,,,,,,,,,,,,,,,-*4ot,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-*),133332.*),-,,,,,,,,,,,,,,,,,+.'noz5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,--,*)))))+--,,,,,,,,,,,,,,,,,,,+/%UtwS,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,------,,,,,,,,,,,,,,,,,,,,,,+.(=|qk ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,yoy#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/%bqz>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/%LuwU,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+-):{rj ----,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,{ow)***+,--,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/&hpz32100-+)*--,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*/%TsyH "#)/31**-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+.'DwvYhaWM<'!01),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+-)7{si ЛY#!2,+-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-{ptX..+-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+.'moy%*(.+-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*/%apz49(/+-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/%UryC6(-+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/&KtxO'/+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+.(@xv\3)-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+-)7ztfF&/+-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+1|rj 2)-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-|~qp@'.+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+-*wptw3)-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+.(ppv3)-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/&jpx$%0+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/%hpy&.-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/%fpz)4+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/%dpz,;)-+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,+/%apz/ic08t jP ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cOQ2R \ PXX`XX`XX`XXXPPXdKakadu-v5.2.1 s#I<(GHw-N"$!0zr])=[}!^䉑(5@7XB i/\؉Qw o'qD E 9_!*H>:| t|SBej# |J'\5KcTc rЍ*J_7{mo7 qDx0 8>et_=R5%s#"{Fj(X)@Da+5 Wai0 &:U3p t|7la l^V= 5Q˼H/D`=_9)<qVbu vsZNc"EX%NdXNC_S^._ծUWڧ72.Xj\2ߤzV*fs$:-)gw`x]cvlQrcatTWd0Ćm&QT/[m6c ͼQ,JGgMj=TA0H˒C-WtL`?`V/Z[f+F`͈m8_Xm͎T)]YS4*NZre#QUHyb״龽 G})2\lm0z]݉PbG+֕9(عAُ"*ޛ\Q| ڣs$=GSF\ "CcEy)H6gR,!OSҥ"H!Xet{RSl~mWd1o>jTܗ XIknts$enSy4/B7H3;!-kw6Ζg'Jz/HB9mvI K`?0 FW%S{ &8yQVJb6 hS!tD欁*@JykDQr i:A=tǫmLm!Jy1Ph)KYRi6,q=m6*O 3{çMk۲?E .)&$#B P?h1> 8鰩n:qRNr*}#F _1 Q ;*c.?ѷ qsj8r7DnTw?1VVr=}^2nOZc %pJO"PlL %u>eCUsva]`<,_d kKQb3K)G H Grߘbu:C+ Q/yw,H>~֚Om9g%oaA깓 P^Pk 4jH_rx#Q]څ9T,eE~A¦$xXVvn5L$AH ?W&0)@g\=: ٠۴_SϑSnHʎzWB -oU=3 lGn؛.H ^f*L(k) oҨ$g<)-ˋ룂wwA'_b6ͽҼцL=8b7_B-is43YL՗̔'g2[ùڃ뎎Ie7~jKcl٥kWɴSeeb%aY U7>7 ie-Udž8 čۇMy=NyЪ&֦Q!ߒV}EKՊ VU{2= q1@( Bd߷`t2&&] }KRn@t /$IVa->H lh#ڐ]dgf˦ yNnף`bMM kbZ:܊?M7GW=TOuH(/GO"b6c-ߧ3%)YR^gm[d$ct;&gQPo܁I5*s'^_)Ϗ/̙>ǢMH20L>h(Li?bJ D;Vs"`M+f0G}Uzj©pL.Kp+JrD*$Bk l"pm;wm>& c*xE5 4S r_ ⸌?mKl@"zܧ-QԢ^Ɛ. 0aŬSmKzYKYte`>C@C'JqrZ%pui;nSŇ0B]V{=DI.;W浪s輔}S@uy<L|IJE9Xjo{ֳ ԯ'q2I$[:ZQcO<㸳\>w* e]qTLlw￴ql4SW%,~2dXT;m މ2Y 3\~m˼Bd Mǃ+tլ$ޟqR蕍lOiU!#KO6 @H$ۗHݱB&pb:6D+X{Uxm&_U*/PWYRQ` 4ܕkMmlet6nG8ru-,`BI-3znwfF')=8grČ>?۴r&7UCE/c!g}' D0u VOB@C~^^q]%f4([IҏD6D;Uxp.5 yMDLp|)1{^3BTs˱4Eo:!*ridɆ!o*Aƞ2tەCAj y,ά -G dp,ɓݘ>^s5Q2]/ ' -gٶ1Z8M^.ub%k)w[TPs1O;{MK'믭ro6Rf ӡqw\j3~ n4?& ]{,cUMA@A0,MMk"'ip׃oZ:&:d7ٝ-*eklx?*b W6mX~vHpoBtBb\4.{1l`nm?*>T,̳kg]w.! 3 V5Bac{BwA7= e&_'n Q.xydG|F*qOWdp!հ I 8 3 MᠸK>式K ;\*#~ GeϿcż+~9g-OU2/z8bãn񇹀 :]@pq]"`cS/""f"+ d|[Q, Pk0+*^I?0&{;J,J2 X<s(yiop9UrrFx<ݐ@+O'>%2+7Nf`#P.Jޠ$HwuǙ($FnWE-?ʰ,tIPeGu#}ĤFȻ4/e ۯN'S/&$);d(S͐OM69Sv1ͭoJnr4  I?T*qmv:E_bbE2܂$-PjSVf eAN19uABPcb4;N)>hb+/uԐ}yEj!n_qΗwBSQ5_m6o/%7L ʜ9! iZ"3P(c 4{딺|=.Z/I^9pĉC1^ݞ٘ ]+gkV\#d;Ɲ̂9lOɍ5u4Nda@).s|D@R99Tشg/i-7zx^MSoX|jm_Z=0A aF =yrkɌ|kj)> g·}O!%oȬjI#(ˎ e#-%u Vv\n4Ӏ~;41uf.Ě<[ATn8X)fO/+ŠfoO膝j~,ţ$?] x[wd:EGcW")4"8R4 1݌5öjňc=7€W02 C<ם>osɅD .p" %@sυ6&3GZἱo4~{aߤ"F OJΦ)8BxpX@Kn+4v%o>6B,/d-1.3djdSƅo٧9'ӝ'u9D.ʳHf YYYE-s{;MO}QO'nxDB8[,7yl N{riw>:^-/vlV)J܈bHpΕlƅz5`%w;pGC5_8TxCgYڭ9KDW_6RY+&̽-&G ǣ>gAe,t gK&#vUWk`u kg[zKrm+".8&֧bfs°n#(Ey@@(ݛϿHH"QFkVr_:ΪԠk%tvDM$JHFKpH__B^iw[G^^*,QQ9؃Jwy'25'qRLFŷ/b7c.m2Ŋ}Id zQ]s6%x5.sAo"JIP[3֌<_q=8]({r] fMR56ݦ̏6әIA tn?#!Ovd,997.ٝ+w(;=Yf0elY2oYU:<̟՚y O.rI2Kd>1NʴdqZ-n݅sbT`Xq gURUv jNGƆD]g&ī Q(Ā!C4ܽ L:ZL!zEzeyvp[ď$1xW3i66.EX//q&/BXc; +5f%]j䧜~mk-7zCvh0Ik1vO:ͪUyrs&19goghxh)Yvҋmd\mTZ?hjsB#6%*-vR96Pj)U*R SxIlGcŔ5J0(R @''|;Kޡ]_A>zǣ<4;饅HX Jed oD|8`ZSf2+jK@S BD="HJ~qjz锠Bxkq GWLxfW^z5<.x*Y'-K`t ќz;Qw ,-jZL@kG}/F$2# P:Z}GVzR[H?)pK %K<@rz'8"GijQk}#<.~Iِ.eA$ҩV9PS3Ԃ%I^aQxDj_50I~ :{Y -l3[mJ|$j胬=/$oY$Lf1BX^EV>UC"Cl%W BdYnI_3$wI!8c,aِB2"Y/>&hbݿiסH؊Cx< 1%<^f0)o(Fϝ=)K& >iUh 7xKTm0#NgWp`?dgI> h5+~պ}q0(: mex7g6F_֘)u7pW/\MǛtD%l ؁tSԸxڪ1KXc*]܎A~D:RK_ET-D$W4R-aj܃K@DS\LOtp`@|ePPm²K/*Yys :f3xAZ UӚ f.ɏ~A E7 Auʜ> ^KޫiQ4S)Q6gr'♕4h:>b;8fr2PѦRCIt C9_ZRLl8wK˜|TKj.]-yH2$/d|HG.& %V u +Mcd_6Nϣ~Qֽ6qnIXh諉k=c*:r_+٘]K ahhdw I~VFq.7x{;rV:w}7nJ@^$)u0LByGC+ACZtsT` n|v, } ScZhqd$G^U:*P;WϋN\F ԫY,$ta2~ ԅvDQ,@mQ -smB6;3oYcm̾txڞA9'T])Bl6{s 37y<,QZN$3_7Ţ]t DS2gvtHK ,{> nFTK-xc65Mxrne7#T߀PDL<~Gp;]B,PKCJ GkBD;!SI"?wer[g'ztF8ap2-85a|P` $)f1_>K"b"ZQQ0@A L$&A9 ʼc$})0To4K6Eu۸ r|•tQP6ԩȴfC:&nd_M'DCuy$+ÜL(4NNIi;<&txs'ߊPz;i|qkvQitOOY2vVGOn5~0ԑ*Mqb31mC˟%ÞgESAiS&f% D-ǹO&N 9ETB]b f9]U'##E%2Q04;c@H"*ԣO젞Aٷig4ӣP|P϶+C[ ӷF y)z 0˅(h{?rGU5  τFBD |9wOhQw'xPn]#J (II 8l$'p'/GeHȔ\ms&0s2ⓖuSDoemQ7cC@A7Ս(]J:X+B IJcmRvlfi_1c_0kmd/ag"If (^DXb|Ɉ?ye4c`6# XzP+w݉-OqCmѤ\-;FÁ s?ݍ3#FnͦWH4x-QQ TL &G`*1b4>w@Ѵ5HтQ4-<5/eJ'7=CӤXҶcyev9CMc >;5tL:N(I @-jpl]vac{Q﮼ Km1Wvu-&Od2W]H0"7ʚ`Wא)yn{Rj<7d#);L¤vZ!o1&гn "[ !omjJقq1 S=#K#ŕS{d^3T%4,5e,Om (,ej7)DypU%]C:`QꞶ F D1<̽uqjB2R@j杝NIɂ'G'#-"B~Ay| S)! 7qjV[Ȩ$,`,%w2<ݑ7[]C.ƗL_d[@g*ҵlk.Ed@%+be۬9PdwJs'k!E:RB'lx ȾDpE&f?>)KMT*lT5heTSÄ*N~lbz( {33g'奵f!\N(_Ni#+}@tg v^ڌ-!++yZ]8b+JX7z4lJ&GHP)5ɤ}U_G /OV+`Π4ri?> \ Լw9i,KOn>}С\D-%h<ӧ;[{/'|:1zuN̡g3.rw܃IM\M#5XQv~魍V׀:Ղ5M*|zigBQVA TU#jف0:PfҔF3őyaB>fwYs6w ffu}+O(y>q_( 5ia슪Hk NhKdz-{^C<7YiEPöRF3hV oR'x縉L9)=(ߙfYM),#Յ%?Aݳ&* 2<8ԑp!c$k)9Єb p\\@nGľwDhQCJKl'BA]tL@@=4  -,^Юvm3N_QI>DVCuQp8 ? SY#!Ařs[?bǻE eN, n/SG1TQa#Yp~~a{KOYu0Ӄ)\ֆ5MxR6%|A !"eE^g Nhx?SI2!(aēJ$;Z#I`V7$oVؑ:ʟ젫YSe2 )fuU:7l/X_3vx7ӽڵBp4s>69ݕ_&o&{mrBJ/PΉ~J bL5|"cd~u2e9A164~!]S_اRTc Jc+<95XՍ(9Ŷ7> +9栃1\W|K7u8ơ$M_^oJOph m՜F\SizIWas"JK*Uؿ连m, &cJh:9Njδ׽SʮU?x>+H0+8Ba#5|9JX-́R0&}b 3ꄆs^˩+PɊK? >ͫ!i_"rG}2tYL,n82\oAW @Ek2b48:)){jQD8|2vGp_SG .o~W Po>}wlĞ{=Z4o4D[s_Z} Ye4xys޺8::/Z9˷$05zWǖm-7T Vׅ! ׁQ>c$!_Co5ʰbXc`aӑB6:) ;׵LO׺X1 )t9J%Q&3~ctWUi?Le^lWpvwEQ<<h6|,oo3NTG﷧'Tg\* yT0LMǯ}*"]QAuc@lr{y!@"@Ϡ`k(/O҂YIU9qZ>nɇu4I@;.\<hIHws?qv?X;o1JSrw@FK #4pW9T_:K-*^6m|)*b"[+3 !yolj5tI~Ё֕;r,<l`= P"ʂ&C=6 tǵB)?A{l`fI3H  k %Pt+()<)7̯ y44,% BOFD 'z툄G%wǾҙY+ c"[Rw;#-Nɫ'[4<㯽G^R,᥹:T<ͯahb6_7q5'M\?P$$VRKڴԏ|)aꌅ Rkag7x9:3[Bs_K޻-nsIaW~L5^փRMrXy} z⩝y˜Іt5$ h_Bu2w/0/Բ{5MGjRܬ[ysAU G p2aAv?G &A%#8 ´s[?k͓_yd< >6 ` *o9]=u~HaO 0is_VŭGO[-^&{DaipzjX΢([D݌JS|ާn%.w;7}/;oIim > /J_4گiiewScL(lxj͗+/eOcQB4oK|s⼢(%ƛZ)?_1_h~?r(eZÈk" m0{c0: gu IQAQӝhQ@t2)P&f9~tDT0c/"OChd5 5B&:]%uxvIG.ot裇~v[@9b66FJW4XUyD=#+#oMA.NW^m1O֜q M<B%kvebsJ}:;7H=F~栴o5&⹨GV!|Z/m8P'HaO[.FzA do HಿBl%QݷOLJlp'"$t^:{xG5 Uj<9J <BယAppsVYU2{-ؒJ3{sRĄ$ר"~m*ꎷCl#4^Bh0z'k5dvj:i{'vu%e%_֛DC@r i_BHϼe#hXxܦ5^I {U>ޞht ,Us?k.aDܔs)\ Re?x^^`y~|M#UO5SrJ۵UՁg@`@ '`2pzɯ(|H=8{zr+R{"fT*;vS ɪouoEю‘.py5M'b:]fJb+5ƃ@u=UCQ! ?s^5y+KR=@ Ybc{У/b[BoE M\"O)Qۧ?Bq>zMt!u+v}]"V~޿@֌ =d{^Kq4)*-*ګAC63/~ ⺁˰ƐKPTBEm$amJ/g:J.%;i<.o( |e=Ӊq?˕E94N\ӎTu@g=NJU+6@Ih.C ^~/~ ی\y%A/"]4שm1Ӄh x'`[TY#1& V(߁DdVݰk%Õ9{IyA*~{6(ie\؀YΠ& "`X Lr;y$xrZ`ٰ}:ʼǒ1{\/!I2(3k*WLUBוYcA0?o:(_> oL%! P㴞UqX ج7> 6+寜`jFqSˤ N\azνt~e-FC-@`\a8o؃E0b%6X61[ h!?On5ZHY&XP)HfvC}k$Px3N ^C$e#qvy򏥵n`v;( HS"V 9T4CXʥ&х}ol}"dDUtYz)w:&%Ԧ: Dx1 J u8е&^|jW.Dfof7\btN:P/7SzG^BvW9C֩FrcTz^U6^ǵ?4N1 grtC/\e.dH3m@!Ҫ?uHN[3cCݩ7&LmS%>E4-q] m}"ſy0yp go9aEMx8׿BЦcF.#'CO n<PCz9lP }ff)K " O[5eM`L`epWycY D6*1 ^G AKEJ%͒T4,snpT=QgjuShK cS*ۥFP'&a6anxw^sd+gt;Y$M_^o{%o:puڼX$|ir[1rP]2DT/aS-  .º:D(DfؾVhߵۡ}듌}'(.͚E9jum/f=qLmyv׿uI1\*e % Fϫ$|%/"qꤣEd05b.ueֲ`KRYNX(~3:-ReQ%E};[8b~J%6o|;ŊwȐ(1Ⱥ<+x# tSE 9!/cAdW9J~ͬ%Y))FΆk;2 WKGdBzux5HE &1mH!EdKV,q5Ҍ%Z&c}@ 7ـJh/*Qfrـs\gu9*Ж#@ w)iJ]~dYxoH'j$M8j5 ;°|: p#-Z۟23% 0,^@- ʓm@^GW* g(uCJ<ԈǻclebMC? Wl1{:H£Vbr995U-C͆ bJ+!FRy?39]w甜6f޹w dPŮO$:ȝ$ Tx! vxh3a7շu|Uz瘖A5۱"̾MvK:fObB![6-Uzb]m hš0`Z8̓W7?jqs>*`-}Ǚ%U~<%p%8\͘͠&θNE ׏%f = vecbHD+8qcJ 0eAJW)<+mlV DBb 4dH9h('~+1ky+[XlZ=kal`ԿuqokaɝX.]y@8%pk&X0HWXbE\/}~j!o?tՉ*B E¡[14ahكLUZH#;-V'r5~+f@c9T d%Neҙ=w߼!6TipDӫt~}:soWZz?JQ@h9R?P])Q8fyeI<)[^0[D,Ŝ5%Za~3\MeP4TJ ǒ*Ũט "%IX\*Ot )qwcg40j:_ {k!տRݯ.*,v2L@1p3oϳ& *!5+:Ƚݸu*re/v]Eٿ6,9 6sqQry'۲Hѿ%Ae *>U\V j/)hZ^1Ik8?;-e-Z9>V^l¡=l)d޽" #Vz2D^P*Ifݸ=ҳހUA)'"50{f[p ˿#eA1oqv 6@5V5g5uI9jCB݂,CQzkl4SoPդw|b|Mi^_S ޿@֌ =d{^Kq4)*-*ګAC63/~ 씒B@FBh{.YsF%eְi(6VRY/߸JƬY/-)eƼ Uƪd5<򃢵⧚[4`-l$a EaP0VS %3X%;3g׾Hdkc" 2;-s@z~Fܰ ^~/~, 7#䟦 -A!Z6Éf]¦9՜*`pNEywH|u4KD[ rL#; #;rɯ)(+.^-Z6KoƵ'ٓucuDz2pˉqq0τP g*ij70֦B,i kB_휒6"VHUY [IbE^C3e\QF?l Do'pT_ yq#Yax͎wWh{ Hxa D)(rC\ p{a^C-Gq=oWDnp?Ւ\CSΎO3]JA2b(2h ,^iKUicXeංk*dž~ 0PExpM{vIOvjM)-`Hd4 _Ћ;BpQTBt 6c\K*M1$! _ۨq`z|p=Ƕ. p_3і8G'a=y.y+Jťy9F}~i7 6WmeǾlxZ%GbVab U1?%FT로j,<-BI-chYDu,ϛq,m54^^v]cŲ_[Q$<]5㑋۸ O@[x3,u*[:Xd6RLmc+\Щ 6O k}VzON@,#9<A1Lh{-uNӅB|aY^=HK_ЅH!JWSkgOƲd:DGZ%lt>|h*pNڭ9*݋ojsQT4,snpT=QgjuShK cS*ۥFP'&a6anxw^sd+gt;Y56?Eǝ3"'0T)!pf+ۊxz "p\$cD%t^ФR'yq/Sy9haD70Njk_W: D2aātxǠ6z|7C sP3KgMeKt>Z4w$,0Ri%?ZVޠ]k@DsY¢@g_b[Lœo6vYv G/y%T:Xp6͐ʖ0!^=@:wűVф< VDN0c oWⱻ_3QMP;脾_-r`4G^eci8vٮh A1=RI=}5#1MTpvMD.'^)6 r||J? ᡥcHgB@rOvk4zzEe/q;1z70]KT5 Gݻd(#ӄ:+_LƱKOkDm~>@ٿ-T>i#[@n7$HXCԝu.zRt~.6=K燧_h0%<ٺ;C74"V mzi7ii!x\6AۧXoҷ~t?Y*QvٯD?*5Ynh$5S{$^rq袝M.O0Q9j#絽y:OBF*#G}o9[i1kcSjC?cu@7 e})&MHIOI7%/':X.);Xix ިuqGW /[XYG:mECl U;J,39Ō{/+}徹;C ʑnl4oU;e&U6ᣉN⊽i'ϞF-˒fNKۜ:}^rE RVZ!+N*BQpP.|Y-VP{T+g5j^CcmRrSM5[0=<ڔ'VP DRYd%5c><z08FG=:>"_t |׻}vC kwrTA->7ZiPݿ5e%35b]jmTH.kؗ6VH,A>JW)<+mlV DBbBr wJeMWhd6HWH0YV=<0Q*#ǺB[ݻ\3AK~ʫXKȪKftN96z{ NtNh NuPsS=s(ĦJ{0hd{ȶȖڻ{G#8gmSvL;Krfcn7Sy,Jjo F6f};}8NJRBMn8bvvg'Np*WmOWLO|\qCDӔcsb'Hɞ«敜xyh4eߧo[bT{@nktaṖ1q\1~gb=?+k 5-,n{>lUWupcgW?z* !BNG@C"W1qNANE_vYѿqsq9,Oa. B<_C$/#5h-ӫͿrHSZLo?~z arwri[_'`$oK&cֳ4W6 HdP$7L+JUA&D;HL<,k 5jW務uYj$2~]X r >])Q8ń8*YSa'g_knG<m/EGiHՓ~lin/W`"z׬;2AIX]8 yfzj-} g_'~+~7k-MXb ydخt%O8PM/cݪ%3Γ yfԢ9G};,I l)[<~0b7DMT<xjv&ִ5{^_o?縗~D:FbT-$P_NRS+ s'z `V[@rn {xT,4Y y*TpMm ^+.u쐾sPĭiGKC+rk(}.R31lcȴ}X6it>_ߌF,ՄQzYDrp X,] mACX*oJ:ԟ$Xvc 꽚O'vpiNM@TaD@BQ~%#z?ZٌZ6 =m(${L[%hF"-au0TSh/*'tkݏG7?nީ7G?n@Ao*׈ kdCU8Ӥ+?j36WTP>ShRU*PY]xF˼(Sb)@y]i,3%¥d>q4=ūU.~5*؀R/aʹZOb״B7p;]PB *ۺ@SW5r 4 ]߲=s*ͱӈ-SrQGT<.oBŏp7NF|`)8yF|gWǮ|#e,bȗ*|$GYn4 K/Z] tfENa!EDȮ3rV+kBr;quvO~ݝYx1JsY ROA3xLYTToQW{tcyl$P|kዢG0,ņЄ;W$9T'Uĕԣ _'0|,8Ks|ȷ6csCs!%=U\' @oDrRӯ w2 %ToEV>HO2QOlv4E-\MH/du8ط GbA5}n_(eCRGP_xk\YNf$FJLS1),[\8!w肆_tLk('!!㨩닺ZnZ{I;zͣfb惛*5|O ӼrTqxPGq/YEx2f'PV8+֚s|2 ZM5P/:ijlt*޳+",t?r@SlqA^D,uKY>` Į!o3 x!q! O,))vq:\nZCl8涷rh ާNuO t>8E *3?ށLAsY}\Zی}F_ǿ@ɏ/"q\,'Z[2"(a Nyc(X7]y$ZɎHv%-cz]#>C>W#LNg ڞ A:r, ~cB\׏71@8X![4J,CBH3>b88`H.i?5$|Vx?+.v)ښCԌý2/7m[ju$*=MR:neHmzN:s 3]}w˘ր*f2Kb8x%,DΧ't ;?Zef2;/0C_r[7E0O^ew{=k>뚗Kn꟮4  *S/R.{Ӯߵ{UdV 2UC[cb/|;7!Aj6$aF~-ޏd^CVLleg铯Ґ;SrC(ݝlHH)?{PĵLHFeV4j \,{RxJ;!%"[7Y7dc;(t24>. I3xK%S9%M` 쭸GpaS2zW5lݝ6ۤ4G\(J.UR x5OeZOy2 oԷIȹٰ2Kg.QH_Nkg4Z?[~day1m'Myg^'.HnLfjQ %|l\(%G@X#1, iD<2 ˍ5#X^JN-C[A5UڜCd3o"k] 03QաϫRdr~wz3d1_"SqjNI4[;XE2aŐf]'.8dNT"cbX(`Pv,œke N ^1U}W.\*7a( sΆ?{'H+`( eLo\,:}M ]kd-FdSl;<5"|WfB'I@5 D.M "Pkb6T<ȱ$Zm0HI"B]`T;Կ 0BS` :|ZvR0>Ѩ*U@׊T]ԮS )vMӸ1A) (i!vB~Gǡe$GBLOeco[+kuT-K^[6qN'.ډre>=⣴~m *JSyf3k W BCjϨ腴j\)aM>FeVbܦr+")MC^ƿbD,RvBT6@I^QuϵU₉܊$s v֭~Lʎ(v*ۦ'@9zMͦ UdQ} 4:vWrIaōvu=78{uv,CgkH4粒4P-ޭ|T2?yp?wCi˧[AO*ތLK 9JBH/Zdz)ywٳ¤ddFm~*c𹒂AE̤:j;l)0Ri/y(M$wb#g $`5~źu6D%<?3(,ECSb/hA`Di}}OsI}siVQl*;!޸JL>4(G&͌^)Ѕxp_ŝ&'L#y`f Qa7('YFzb/XN#A!lUt9N󓖇Q6S#ŋw no&czձwFcX1P#͇GߘU24qr붯b:%*ʟ/녥̵kNjXdN`P_rTY.4Abw s~%iěb]b"5[ID9l~fvm  Ғ vCMrX`V#9h;rY<4'U;E)j~Kk[L*e7lRWg7LFj>~L HF8t|Zs;-Ʉz3 ݂{COXh;J#3cpPEcS3<0V] 1縼52_7\ &gA,BR`[+B j@}?ނAWX3ї(WMu<8!ډz&aV*3BE„k:qbARY;g[ +t m. AXT"eIB O-H1ioU{kC[ztN7BEvP狪\( IIF8uQیWYEρj3,*BZPtR7Q;&b8,bET UOahP:Wq3DRY%_ /\< .$4ⰿ*[Ysx_W1_tk1i4X]sc{kT_~4dw|4g!wq PݼZ^`:Qq۔Q[AٷC1k]xFveFdtL4tV%ꯖQJeŠ#]#w-P0< )wazسN $'讇4pJM5u}t \d>7>uM;E955)y6}U֐xG!ᦧC 0q0lfxaF`uƧ^@s-YNO D{<}l )klb|ƑҐWVW0"N~t @%̅d~]KʢzLWJqdJ=Aˣ_`Xryqdk)k /gXTYR&cv*Bsꈞ -U!a)vqeu>qsZ d|$iiuy+ p;nѮ*5Ÿ\2eCRQеvE{њC UW76T )FJ<`LN>~ڹl}t"EKdIҢ,"$uI& S5Q tJ%A3Ҡ>>kVB5*ZUQ0QubñÖ|o%V2«|uhZsԑvZJi+G<[:<B:w6N3X,.O`zǺe;Wރl3nŨ)Pxe%z7X(g~͖[Iic093 jP ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cOQ2R \ PXX`XX`XX`XXXPPXdKakadu-v5.2.1 F?p TӢ>a]tH*|ޅčM=ru%QNH5BVlqyD #p̍/$i#R|Ã&̎FLD"fŽ)0{u[.N K2WDn pz"ߟy3WX_TKzt<]nk:n2 `}ziZF5*qy; hM^H I HnER01KnɫՕ]w^&b6;RtM &E[C43 6g84>q+[*e= {7a458 ㄯ+PQgY|{&"q?}o 1 Z]օW{Z)Vw!+[FB ~Jq)Yu$2)kwڼIN\B7"PiЖ/y]W?K8>!RktI f;,M$\IdtצYlKc`NPGܴ 15[R+SY+t5x Z0ASjMS/Ҁ~4CTα"l~mWd1o>jTܗ XIknt1$R/a ؖ*)э1੦.)s1>7p l'{usz(A=h\sNk`nTL:)z藚Ŏܿ 8#3I-B~X%K`0:qZwBLI &iCn~ʊnM&҃d<SwN#>kgzu##a$rҋi;7ג;8Ṿn"+{9R#+C;6=+I]z|"  QT?p? 0+lI_T؇#Ge RwJÚK .\=uT)a mr 痔/(wvKIėl冭Ł鰩n:qRNr*}#Fùrbm)֭̊Ŧ+J,,wucp.cxwӲ,8P|m`'Kz&(;Sk9,1Ҍoe%,lbc9~wtC<,队'gKXQ} Gw8.͆[ClG2ay0`ޚaX&Q*^q]^پą(*>C󔋍^ha[̔m3Žx؉^UO5|O~JzKCLdd؞|8QG`N?v$d$$,;,< v1֮?!v~.2#9\a tqHkzi '||RjB.6ܹ}\f{`,|h.A.]f8oqNץ|љ66@~OMf#BB0G>ۗA/4jqmeѝŒ>?_vS :QV;JlF ]U m}yXU,'DIWX/3&ʤZw:hWmr .s`IL%taij,k"ؔPw+HTyq tZP_@qHJ5bL)jN#oܗ I&x)`M6*0 YM0V}NI&EN%{oGoC؛.HOcA(=%Vpn yܞ$"_p-čiZg ԎLZ&m{UK*'Ú3Dt6ḓɆVqnblCzj"{Hx ػ%CjRڳP}D.۬\JAD.h8A P..CBV?wq($Tx#quo?58t0# H )p5@ZYSZ&-î~5׶NZG9gi-|cFڮhnuq>0yfAYIU#RVRze};Ҹ9gۃ M|$B 8a!+%1':-4+ jQ>%BSs>İjõR v_w;ևS^63D?M8jܧVeaO ɰc?dN)(gmQY[+ h$uo kb fbRjyC>$EVR),6{}qIUmUrDi8 <![! j(LIlw ;e(]qIGosVh }@K+D㣥͍/&%&-s$srC@ Hch,N+J݈$CV.z+钌|D NAK$v^md?nN4%uЄA*?Qh-h`~ZjG]O(?W˘W\@C V\wR:1@2F /YLz_]<(IHT"t@h*~1!\G\y3kA@4P΢:O0GC3 B0̣?+"[@மrf WǫOPa4b@/ cϕUS 1?ClBQ5kb rG?P|XBTMUH -鿺m*#p< /0:كj #tĶfٯ3[[4ta ꝈpK6ԗ{]&PYo54ܖ:)Yӵ0It3(Vo2Hړ9Ӫ ]\@𤝲5op-~h]/J?2bj_3+`̖ :2 8C؝i= zWn*`ݍ!NyyhnxjtYtCYU@c ~H`:!a$#n\Aァ;WL y3Ɛ^+ŬGqj? [bV=֥V5`S] nFl1t1d̚Bϖ 0sY+c_Nf6&3.;Nؠ@yƵx t@ {y[Vǟ3(oEm܊bʅ&\ ohkE7d}I=ѽ áV/Ngms=/lA*m,oS<Y v.PkB30di>*٤OYuOb97*|P{hW%*۫ 6M jܟl@- 3#?Wrp>3`tbFEj"r4Tl<<:ƕNɶ8 )+U'e(,iTۚeR/OY-B  oȤ'.&f%"v(NPs(hCaDDC]7h0 d[ݺ(NlE)1;UXI)R?_tEb ~Hk~n' hoENu;Jom9n"Px~ohj]}}휻ZXa\8[Ѫ*>l2?B9l~'ا'x7Uwf".qeƕncfe .rzԕ|T]l348T[(nrF3wb5m[aDm@ R:N#(+|0#x7eA7u>(p/ZP, :mՅrCS/.`p ~Da|qE8K 0k?Ȁע&ҝ"EVx|Z+X\u*D%qI1i8dj Ttd\,M`{,jFk(0gE G%2Irp_ 8_W6vh@1GV E9Avy*gBgMW{eּ8Y\+Jӡ {X]PZw\ݷx$oȟv3a! 2mc 'vkU`K$̖DSθ0:JБ5;ō '(0,]ƐjԵ7ƙ;+ҡؘ-q+̣jYiGe5A*ב/t:CYcu_UrO|Ԋ3`L\kg1ah. qgXj}}payDj¡Tğj]4Q< ]޺vr"Va7aI $½(;K=mijGCcĨ4f"T̀#и{L^Muį!}!yGu̴^\K!4 Vp1VypRn>ڪ-ۋp$w W z|(1i(̨0kVi对0|@)dIK :˲.YOnqYr_` XAuv jD<aڿ 'OGKF\Cd}Oηn;s#cEJs[ĭ0G#lhp#ykv]J\b;?]Ì2%|ǝh˰}_AԮf)ҨW>b|NV‚]ZJO]V̜ N;ʋSx fgo<ZF>t[E\΅Z_+F8ܤ_[+(fya῱tá gBk5^W i=zl:#Y>իM߱s$eG*qK$xEtV-YߛtY%B {0jw٪@iaW3n8Pjd5*V0%J7YkasGGF :>D D!,~H4u}l@l?20}@1adSr54* XL$$1cQ,lg|&7?)<k$4;ZdQ] "GmSښtV*euGS+*j?x $ c i !aӗ;hؾ:r."GI/'*ג?b1n׼D(XE u-r:P Th> N?^ҭ$ [7XRFo-yO~ܤ; ~$K6н[0+PHt驌9@]K2BCK9⼹oȆ e|%x>̼+I;(Zt R»{ͭ؟mi?Ǵ_B܆#4>jpHsL5NPZ;!VCB)s]|v(ߏ[Ot<\:Z|ԁ[R{v@ey*2^FtͽpK'~V0vW%ETx_)4~plJY!i'…)qIHEj.Fl4.Ei/)KڇI*.@܉>a "mgT/s'fm-S1s~(c~h ܋dU9iPy<Q~/E|Xރ6ęcz-ghZlճ$,99y2>Hb,(ZU 2KkCp&/}e.wEuߝ qHÍì鴰@^>r<Ɲ̂s2CZ<q$05V&]x '3tomqmڽ̊gճB2ߟr 7go^' 1*|h I!.Q'PB'TP9$uű7ƥ> a…`㠩J,?R%zA/z W6{W%E qb84h~8`;Ybqttl ckr}p9ػXy Rꌏv[ՄFle0D 7d\jG~3 ͏FҾH{1c33UAL4Ѩ)4WKHDʦ\[)yƚRMIȜ+;Am-s]v{-/79Qa&ϊ`.4F^YG[hd|2h @_~a{"ثqPЧd8sIV A8[d0 O>\wƝHg'Mnv Ũ7oUQCZq"e~+B(,rBB5{*{ lZLN,TNL=MõQf)Py|ޞn5y)Ct\8"3 Ru: :xׄvQ!M <@N2S0؝r]Q 4d8ܜ{E3m1<6>L(WncP) (R KlI^m#LTVHG ͏)=ײSJlkϑ@;'y'Lԙa2fФM,d}]q B&K{P"GZğͰ&:#D}¸4LpF6bစZFkռOW#ĵ\:OP/eŜOFCQw|"Ea\^V=1#aDi:VQI}m#,~ey0P gWa"{L-d@AC+5hG|7iZWK~x;EY dhpx{تk3XrP+@. H]tC"08A}kS-X[m׭<cPjpV]6\7 W}Fj/nDvAS1V)9B/m&I@VĘ'r8!<ƔRG fAFoBW 5OL#b=DGO%&ut-p_/l^-40ؙÉΘa-ؔ A+G}n¶HhR+b2#|//iʋ퀍Y8U2&gb>:7ϒ-2[ M~o5 m4Łc֣_E?RY#\LL;~P#^jgJL`Yr{V0~%T82A7@hŸ09PYVz>v.:BU,ol"bhi7w1wZᘼȳ-pQR$e#A ^# ohXv"KkV|k[c7!~X/`$vl^ܜ:"? l'(f1K*_h&Qƙ7\ԡGVm! JZe4w~|_$nYa7L;:1Uaa_(:Lsqdy*ֈ (ONZ吆RQ9pB+ N1"Itljp:_ǂ'Ua][@f]`t(t"qWn3e_, [ن>D}ujPT%pðtō(7֟Ժ 4 K hgߧGD| `2tZRn4l%LSpq>`-J؞lk~P7@_/i~ w*GXxCl'T0 Įh"C2v؁V>;~;{ޝ"tԹk95l\<9[wmzyP׉]c8,3um4"+{%{OCHs1=)/+t+K]KxAdPc7I+􄸿3M#(>Lb3jPpg_O[ A:@-IqШ3)T޸7*;7hT=?&݋u3!<˦KFf{Ht=9n.V|ZDZ~V>4wEP9PE,T0ŤUi*IqQi="YrjDb20Pݘf/v~?'ҎWݴ"2+>]AjN%V/zȜk=)-hOt5Vm)f⤞9~8VÔ=wwAĖu?Qxth̜NYSSd,چ,8 = ̘ "w#V[ꐐh0E,~9\T\6wM:bR*Uoc hw9Ɔ+RpqFZ#M8038pU|]!ҵ΋T'G)ղ9ߴrssmL]#O ^W(!Ol__:yJRpyTŅ⡲t4|[I>h@h?n~jz} -A7Cl7*딗p:T@7V2oF.\P^1"x>O_gBA4HхLD*B={x;N =cкS#N)yj6伨6n6Nfq\mt7y8~8l!CCC[lb.I> ᱗amk!wg.Od6f &Y^ ƣ߫EB+-όYl ޟ3CeHnp~džd@X3O$U0 שQה⍨>GL` 0N$]X=ܹQ/͊ zʁ] _mޣ@h$u3Kw y ;]RlXi}Z9̡#!aGKc n+6EEH*.06`rt?-Q=SwXxe4}$gTM\?$?E8џv޿@֌ =OraMP,z5r7]}]x൩ <&AL,lo~*t8u6(NuhL+4x5}8L8ᚶn(2*Iф”BEM<NU<ieQYyMbAu*+?a&4m=]lm| 䦧(8/x5Ě-t 9MЯ'}ʆl R'h}nֱ),_W [i$*LOl 9؏\V B&…X.(xdZ7x1}1b£hUo}<>+6~p֣Q^(aYhD+3ɮP(+h>ٴ%o LFfɖuڸ2 j5 Ǒ5տ1oH>H5J]&`{ŊkD b1bFSCs7ވϙ}ջ݄3X-hK|%{Go&!ۃH{khdo!/!osZ=pS~R"] W7jhpT#QBͰpVIlvC#ڦ̔uR?Tf"0,:H- ֆ'8/<ܭS3f[9`]`ue?Xgdž} Z/B;ߣ 5ۑ\Π9 0KdM=DXB,@F2k&W7ݖ6r qZJtAdm jy߳O~u^/Xb*=H3r =s#(IHh5q2iRX=,zD)0< ꂒM"ɾOGRsg5 y 3s'ǥ 5֚T6MHQ,n!@JK)K&,cUXZ.7 @tfa.QNO)3' dD[]b$7vq(G9PLE:u^9 Ӫ&6:AH~:q_-˰/DaCiWvyERn "]ٜ<]3L9BG&[NM鹈x 59Cb]oQ&zs_ֈpEY6 1"uʱʯXǀ@}TȍE|jN= ˭(]Yb%nK HY<7u,s&~mZaj Ix"53a$y?#SbSK'|n Z,bXMZeR]5ebFf!T'9X1 u@efr6KOKDž |OKq pɻ'+pU->?PLjB&6jOWX%(yg;@5F*0mHEVV}d+v4#Qxxk1I+=P!J_b4=jXN)k¡b Tr~LKgVb*=k6ITRq\١S[|n" FXb7.VgSzM2@ŠnHFOЈ[wk +})"^SzICaA؁yVԋm7*ZM7/֓q=mLB_` /uCYXbyUf1 2l"]CSq 繁ZvQ@? Qt.݆Vjsmelc5UHk(ѹYazK|=O:!P=">$\US#C*Y,I8s2emC_Rq%/\:ϒ#3ݘ׉8m༶ u|K`[ErW@uGZTW#r 䊹wRz#cbZmY#fLBa!ogi_UcDZ״0Vڥ0V;~b{+Jp(foJDvaD:Cؤ}@X(Y|!E袝וf\Oos:Om_P 2?G^淶ft* }Ga,Zh/ v x$*Yg. ܓᠯ!g4 S@IȭsCBر`ewn;[˶znD) Ű K c~(C8v%f$*~]YZYG2ʜb7 5'-kYfAɃ mjmN[q(~n ӝ5>?o았 5"d}/yeOf{@#&{e`tI{wrl9,Ѕk3/^?PTar^xQe]6Yc??Aȑ寶SՎˇ~ڸ-w4ظl#Cps;""Q1й $[uKzxumo%ɼXʩL5$!˯ɯKSPo+H=@MU#49֛1#{+q&*]TVGE1:>Dس%w*5d*݀BZo^ (>K8Qx[sHf%IĿ4Y6*d_ۘҤCT[w{!G04Tс ({ mQ.494TIrX7 R \||KM8m<YɉO8(I/yaӦ. }ns ufNn[27.LºUåou_p$ލYOF!Np+MF鮠s=}Hwѧҟ~b}Hѝq} W㖣Ci(A*z^?*R+c9Ysgbp yQ;mSK՚0~,Rr+QtZ!_9֡=heJᗋw[WA&q㮸7*3CD:]Ld&Ŀ#BȘ|Ÿ~On(bE RRYFȈݑʄ<}咱'يB@J-:jsCBYZ{ZVvR3< ߱ ]KmI#3,$[.Dz <3Twh}`Td򮪪3n}6(˨G;uO<>x5f5Zv[OD eV{[>epQܣj0$8ZT+?Ez mS5aY?%LGK+Ga^.{ rb|e(:i1$ET-?̶?a^'\>!`>Rsmɯz QH-LU$뱯QHF3rz!z*UAV]TZ+3o9]a/6XifΑz9{gڎĉEe % E&ay?Rcgn FOV܋P&r-0hH^ź"0S,ߗ ݝS FM ~"\I=%iJL4GuQlݛV8Z956_\Pfݤ V^Vԑ{`Th6A/ӹL vϪNU )ue<:+m LP& oipnjѫ|F?ڦȗ%*a="hёG̯ڄAg%>HY(hz88W̜g|ڽEA30rЍQĻJ9p+X қ[9=^ gp 7(HÿJBUGIL(;F]U?QG;r3@PcKZ 1J |NHwP<0W⥊ˮN1k4Wu6Y_;Q~?עbqNo DL20AtX -y_\l (]TR .(Sq)dѴ%}C6=U1 tKSn踨WxrY (}H*\FM&tM4,FP(?EtGl˝%Kb4fH!&uHl䕀>vh,}nK/r6YoFv~ 0-mԚ g;od b& !⪦n/n!+$yǘBGQLVjƗrj(h\/7}fֈywOA 5.ɚ-gS pDs$ZBaaM8UeZ]Ūf8vw{7M~C`7>yYҗ/@R-]vi戅8>(ScGTofWRv~u)ZrxZGߩgC(HB6NF,|yȓ7B=,M0J%~UV7]%/("P%S>\ WQ[=hPpL1omZӱsFSA_n7$ioʴih4}<=LvB ^|IyKħ֎T0J bN uu ժX9cjqcLX6 S$0x=)L:|V2] 0%'MNi>`jlz&ċ}W$:!Wm*e7;D 1L-#d&ӽSC`Jk? 7ZU|vKAa)u[L2JHV5ĵ\1eK1i@ˈ;}Ɨ @m2:Ug;ӫl^Q5o%ͮ%2wZ?9@_p<\ǃ]o𸂕Zs[!I}2L>q. ]J*5и2޽2wg'#btטWkAdH T@On -- 9UF/y~)}vy >YQtտO ky%r()5xH !*@hʬ`*#=9XB)ꄏrc{C( oB_>z&e-\.B#IMxnF62>0uq3DZ+E{҆d?i Lv`qɭD7/Io}c:V@YqDTd郘eKo}qqlXwr's(SXޖB2=W’~xufLm#^Z߭_czuGd&>`jik>Vh1DmԂ&zahiBOWQtٞJaf9|]JpȻ ZnoA s`UF$l˕E,}Hoۣ_?oT_HoF㖣Ci(A*z^?*R+c9Ysgbp yQ;mSK՚0~,RXH9ׂ Q]߲%Mc_cZEv9P@]9I $MSY鵣tcu@vn;քG 2LCh.K9>q癷_/Nk&jd<R)3(M]ue`?~%i+z::+ 6ʮ}x4PfwSA+LXUB4  }'u0uT%04N[£G]qɝT0dt7+_u$LI`qJ=MX5|=|n9}ge822Q]]]&*?|.xo}d.||H^"U-r7v}Sv+>_neE~\ze+G? NX*PP9ʹx?oU zve mpU. Y"%C8MT4ЙݷUKNk`$ə22=#u:[5`DO.hMvhf7>,FhGCp*t9kߪܫ99dsZd&?04֌`{"v5G=6*M)BLm/ Jg_~oAm*w|?4ԋ'(rRIp; AzO[.*85?K! |Jp#)ub].r1@wVb I9gW/E!'^s^vbzA0 3ye~|:@3 8uH͍ؕAKjwP(8uNH)W+fIRNEk!"ɧZj.Q;zcQL/Nڇ3-= F'l](AU $$F}Y2'Sxr#hH*nuBilm$Aj"_8U0뷓PKM>eVO<][Ѣ!k|.jl t*dX~ HkϛSJC,χozu%˚mԠfrEܷGRh,o @7e;YsX6>r뫟I=(*{\v2TEZ8@=1J2y4 )JKDiAa g™;ǯ(-o +{D S>di}T8k`r(BKіK|u|i8 I֣J}J lSp}k._~q)KZax f5tssFpMWtFφhmJ6]9`5wX fܩ>YOD,cDq(EKZgU?9[7qΛ /Հ0>tPSFجO~ Ϫ(ġLiN\ WQ[=hPpL1omZӱsFSA_n7$io 2'}'"~@h]lCg+5sd;+N_꿗pp4KXPBHwPwJ;VJB.>:c:q!Qk{%` r;,/f^nS>]q[M Dݦ\D·&{3t]w`!3L{^^sIi{d+$ U˂hvnɻ#)ַ5V=LԷy0  K6~*F_ %ܵz,{%W=(gR~jCU)"@]k@y(Nwm8$%<}zt4 )2 +l"NsG<>9D* ?ka?a r]֏hASUלlU%J1Fzd)/'H}q)A=='nPr"w@uJMt.;/wLƉ% lC.k1dPw_ʜh*c<ϪmqsogO1' -Mf][3~7/nh P͊ I̦&B0UUcʊ{Yem ̈́ GxJSB<ytB\19`\{iNE^Flx%I^-T@s;{Bu%siUJCFCő22|7/AN bUEBVc|`K4k? G󅼅k;DA7KD’-LڬIGl_6"LѿG#{ >..*f&Ȧ&wYL$- #'6=l-'ç_2Q,%( <2dqs}>7ѼTN:I`r=4P?@LeC•ޥzD!C`nFiy3ї4]'l=J{b f(jI{ #kO?,]f:?&P6rad8T Kѡ3Bg W'c1I46*<3J+,7Z6S.3J>i=oKGv8Y?jXU},z uf>M:UWCڔ7#>DoE dbt0oNn[jϰ<1m}"N\%ʍB!1 b+jhn+8jlZq$-Č]1*b1U"yk|9DY/e.iٳf@cJI呧=tHnL3˂.sAѻ!;:`$@j)Pqh(PvRN„)H7P>閎M0[s1tET+%F $ Іd%݀5[T)y^:dɄ&UD ds}\ΔJ Oi5ݩJq&t5ikdhe$6i<7Hhp0P: A2G%Ҡ28{7>d& mm YbQ>r.$09^O'ϰN|R.^;3j[UH-xWFPjv8'͜K BR.6l4al*:۶p+^IOn O!OlYӗ1wYgRIj1?u8\Y'N#~4}@*-_'ʔh6L[S?cP`^WbhnZ5}b7ObxЃQ٣TҥśY̆%cIآEMt,Z u7^ !R`g1+.ϋ&oMNG! yZ<8=^[ (Ym7خx`nIqJ. iP{b̺/bC|&kMGF!BHſDܚ'>@I`9toڏمf4& WGgAopQ{jL,5h{PB|TOis%`HgUu|],6-֜Z8< †BQHnAf;$M:mP9k_MlQ:M}X)]'Gy!M(X-L@jmOлR9U800&(_b8(Utz4rJDMq=F- Ӳ7UO't-b}frx;sqnM&`·Nfq2:oS1`a DsZm e@ E1اŶ ]`p6-az" Th:Eb̀2.[z kc|Yf0uf}c}`Pz Nl,c+5.JMlؚح*s_vl/Tk;bƨ2*L0vlyrIo?X\(!tG^ ǜ=dS=ynp9k<@u)@ャ,xϳh:F7/=ujŀdc6z7z\ˆ/Z-2b'|~1}h莹T?[(GKM Gx/"$4p\t)_RyIbSOItu$nm*F"]X9FJi;I{G3ѢKr?>oKH[hL9|IA84x # _W㝀d>FPTIw62T%}xOe2{a!F_G'0s&1c}.+K%ZY7)$yZ}`r ]0[|otoGݝ3 tS)nx+ZrL |}WYa9:4 `G,Z89 OFN$磈hmWaQtʁr@c]Y8IкoL#lG`]4\\tcH`cf?Ew`r+FxAvPV= &z]3KTi$ r%Lg+awu$\x/phk(vM0TtKĺZ$bAڵ !qzD5߽p9@@ep>ݜbU|̛}Ea^e^e^e^e~ȹ:Rn]ra9L̼̓<6Dқ¬8{C9 w5@p=Ygh v07fZōi܀c5'OԾI_%g,QU[$@+*xZżHs%t\qJb%UfZIꍱ[C,@+*xZżEu;!vLZżJRbZ{:Wfz$UATD.+ w&%ԣ}R1ޟd[6 2Vנ+̶4͌6M_Y mBm0kvxɻ;$>vJ-I8baF4CbZ-Y=~N#41oycbJb݅|''}oy}m;_߿i/Xa@j!b93s[8) k߅D"=>]3 0Si$G"(iH)Ͼq2q0E3f^Mԍ٭-rxڳ-I &"VOe| 3ik[0: ac4*(Bkxu,/z+3u&VvMb"PmH@0@cEo2°~~ J"’uI^pc3n)XФұĪpVEcסs`<ϯ)]VKkŸ0݀:]RC8;Onj$,'',~p65ѯu AJPLMj-kW@]]P-j#m,FH;"8Gt9ܭ㑷d)akO#ݗ) [9]8sx|A-ً&ȼ0'{{JaX|u\v`NcUs C0+'PU7/Hn_*)Ʒf-2v짮*jsٞ3K~Qb:M6a Fl;q.SHH|_6p30em:5ul>dV X@WqY@,Lt cao/h{v0/4ypxQ1+M':Ȝ+9_!yd2]=OjyYkJEQ-nd{S?.,л|y  vY?d$r}Aqfk֔t(%NptXgqq:=i-'R Iu5=2 lg'cPF,@0 ƒˮ/6dYaF㵰)4E\ mALr @bm FnGoX|j\ҟ+/i{ԎО7_)ݠşsSo* j ] TUizZWr96m}vaN5˛$SP@+X_VՊ#br qpR$أxg:3bR̤,אDBٛQYY΢GGqŜ{Ixo!5V㺣=RM~~p@,aǁUja,S;ϿicxkAI 2@Q5 3)sA<q5D#*ͱy%ɞF%Q^}E KĪ-Ukµ+v/:*6" q@R3}E KĪ-Uk|,c׹!=U[Īɥc&uK'd@ib𪾒~=)͜Ml3]Jڬiw@ eqg#0.ၔsؙ P+Kk:kü=7%PJ 0%u_c8pL{ߍ'cgk΃%7Hk 3<]k#?җرXU2\ڊGM/@XOU[ĪGjܷ-fܦ q<̆yS+DT:}dR;t_N_a}gJ&ysw&{7".A3czQ" c*VGm#vjT7}P\9 T_}Nbζ`\e~sWSդ+F:V ·O6A5H421o/UԟRΰYLe`$L=ʟS<}6'%4[}ɑ3D2$4O+Ű7$:QLs@2MTo~Bt7p#.BΕdXØ}AJo\d(9o0n+T*BcMUL-16& JyD˥=#_3W`AtVC*7:S aЀGtuj(@lkb X[ 4&R@ff*ee¹'S@_ub;5u ta~Ǽ5Pb]S`=ׂYM{T)]b&[%MYQM5OÝ;pX*J~\ن\~;}v\0AbLYu׏yȭ.MWC.Ѡ|5# U9݁23xg=deUa|ՓԎbM4hHLHchc!Ӿ=j%o#+XMvH!,9~'\?oYTeP𮕯ɵֲCvS?`>v-G0ـ(/uߣ&9NAdl<`7S||\zvlhJt~A;b2.dDccocAHJ 8%KKư.}ؿ&Hw𚌲AUPsv0 081!ƫtZe1􈾼 b[seى8Igt&\zqUvaJ3 *mSRo3!2n lxEIRo\_E~Q[[d9bpag֐OyP.~79oA7X/1l|er=h䖑]yr&WU@|;axs[I 9 jWhe\;l~/hǻ?[~BVŧ_sۉ H77H&ck% Yʩ! `LԇͿ=~V)ʆ~{ެ"US>m~{.9[>?o{WVi/&9́3R6=W# n LZ-V&sjCߞ : Hs)o}M! |pM$B \B \B `]q.ouP8vu]Bb iE',SpeÃ$KļFzێz)ɸSȄNGk5d r3(KZdVHݯˇ$0cjpf fiǡ>Ւ7k2 <#ӏF asQmn@_[(/ɒf`2fᚌb1JYXqcyQ9TW2^m?KjF<yEY }~Vn3Wddbuqh.@}f˜8/,D0 1̃$Ȋ. >nք_/Wg;vg򳩚h#]h,:oAH!QEGApQkLд)u)t#63J&}ӋlX_m'N$|fUhcoq;2J ,zPU:nyh fw%nwm?54FUM xUhZ E2y&,WS?asi }HWf󇨑o5XTMC\3@}gOL#$qLD|)ЍrO䲜8LmZ浽BXrζ̞|hu-v\w+e@nĿfM;B043| Hƥ=eۨͅ\D ,7|\} TZQ"euf /|Wi|* 5Kp0WJQP<(j-# hUT h>P *0S')?s< _R&&0lLzv.KgO1;ОJUl-!۴$.$ɢ>Or aw%Ta EBCh?/@_V6݂7hߵ|΁Οt7vI\/aDT=W_VmKt.#Wo\fN<%]o 'lq ?=߻50:>X?68F0huu|?'q~2*@xh Z]?3 \(6ԝFDDW'Fwٓfiev 2 ;e2WjXI—EJ95d\ߠ{?c%/2*68PKF6`'^S~"5bE嵬Uj|n)#Tq~VȺ{TodSq@{SHJXl^?gSdCG7KmS1w4$8sАצ:?x%Sص4- Fyک7Nhwk XE %@|$B/ԒvشUϘJ^h ZuRV/?0H{?&c-+v5Fm=n&p@Fy˾ 4Ci!9a 7&^ 'hO^'Ўnx6lXh*; b} Iea#[!b{D8XtiG is (k%>K faS he\ClV^N鬩yw6ڣ[^a2 ǭDyU =j#`+a$g<4@:bTT*sf2֠W. ; 7RZ+%3I?4] c{c=eCG%oaN̠}Ÿ\2fa!eePpMn˵Cx6L(:#dhPԒ6`:yfٓ$O2O&AV~I&: {{M7Me7Nk CVK,2,ڤބLjC hlR( Eo&cD2en"jD%Su0Bo:| WJC|^߼{+F+l9'1Յޖ'3jo<𕄄BVl9F@GUYiT)++<%?7l%&.~V\8aHj)#<&/<ӊ i 75REAܛ禎[ OlP]PJPE@ZG(Qy>q [OD{h[k[lN}p%/+X~Dl!0N5ƌٛRm/ÿ"4dVqy !bs{wW |EmL[WrSgxws~?"} d;ki3 >. 9mOI Z(S]'!LW0͓ll>i_Ig-|n(ʡ"C{Ayp;#Ǻ.JIk mw?rixo+#x5w/K" l< ^XUX|0떬iJ؝E;bv={, rJn7kQSK TS_MzImby^Wy^Wy^W hVn-KRԵ'ԍP _:H2_UW]:+8G#p+@C`>v87;`$yjĶ;7ŢzXu!=j!&]&eW:T[i>&o^GD)2+֝ʻ4zq#=;V'9[ɮ\f!,0R)y3;+G V\)˽bD Vj7֤)9pEglڇ&kA'o1'KWb.U (𓤬V"ג1%Ӭܜ{SIs.ܫ/] 65L25wSc Pn9K'fY ؄1}dikز+ ?.gji C#/xJy]?ם\>J> g`4Kj'k3֨xsDEЖlTd!)MZn}oS?]ʨ>fwzyCRU--E^M@掗`C@*t/?^EyЋgQbM9^r7곝 s ۯ,3/p-J0C k.Di:R*TrnrE.`cas/[HoA yc}hK| ܥ%_0vبG8|߶(?.J55s,ϘF\tt-p'eO 3VAJ6ߧ:@"TG|,2}{ wHsP<]凭aYO K4:1*wb?Ƒ9[FG#`N tJH1;L Q:l97ҙu4uMΥeZx3 ԑ ?zTiW-kV[sM|mu7{~v~ (CWQ'ךF߷Z/x~nli҅R*f rd2G0;FvCBHnn(`<ƒt5i!(>a~Ľ 01-kxE\V7e^ ;%s0L |%;9P@n{wr N߲2zr<='E 6}d(a%OAչ}_@ۗz" LL[=b5t <-N2r|{@`4j}X3Z.r/km3)@b^i8姸P2ӕEJq-%F_ kVY$j̧ḯ]5&S'%J~CD6vBH1=Q /Ղ)&y`O_d+owzևX/7 lR1 ?_Bn/xP 514p QV>xh Z]?3 \(6ԝFDDW'Fwٓfiev 2 ;e2WjXI—EJ95d\ߠ{?c%/2*68PKF6`'^S~"5bS/`.Y 7.uzt̯Yx% uyjvTi$p{:%8mCI>%?Uc?Uy:P3PGXۯWqw0xpmI7ALy-i-[ZzhQkP5fEhBAɧ[M`>T4o +}'Z{f0Go#GN$yBPER^,b @dm'\eI2wOLH̝yq0ǓG&22B[s*{svzӉ_W@R 1o1W쵹P^ry(:#dhPԒu@(‰o/  < Pm];iV IwMe7Nk Cb e1mYm|~FZ!,R( Eo&cD2en"jD%Su0Bo:| WJC|^߼{+F+l9'1Յޖ'3jo<𕄄BVl9F@GUYiT)++<%?7l%&.~V\8aHj)#<&/<ӊ i[LYvm=Ú!S>bG:$Yy! iZ?id d}P!>~lݯrɪ>s洇֕カ߿PCt~yE 1V_hce[YUk0ߍ' ڎcbȍMJ($Hݝ,\@-ˍ1𥳐ESBjM}3Xv;!)P,\ e1wEٛR:#匿*>}Wj-G KfGwJ4DŽufSʿg<|X1D$U=gv"\sw-@HE31 Dyr/  EGyx9b4&I n=WPx,«D f(0= tQJ 4L`c^ qi3 >. 9mOI Z(S]'!LW0͓ll>i_Ig-|n(ʡ"C{Ayp;#Ǻ.JIk mwc y8[p|1ͰY'PRg CZmUY)$(<pI+aRvY6xVF諆̝_ڵW]1A[*?D|dr@[W߱,hy^Wy^Wy^WnBQe<#vO<(C> lpYՑye 2PC(ZdF2k+J!\\ ;L>NM+L<z1b|,FTNtHP h [sUEAQ p! ~ vP O]BE¹~] -~ ف2`e;gE?$[Ϙu a\q;^%n[kC2&PX_sgX * u&ز-HʩMjP}=U\Jʣm%/N Ⱦy8v \y3gqÆЉ*iE-n(MKA4jٍZv *'%#KF'WHF]?V#?޽afl$XN{T#SC<ֽ^YǶrO𺪲$>Q)>r0:,'0*, u~m`-5Hylʫ֑irΖ5m+-(A(Db\O[&lR弰˷6\wOZ/z,ŪZ <]խ$fTx/r$P ۵6~= !]N+\DFʉKawXҟH*NW,Vn-4}=ŋ6B_]qDAa+F!:X׺|udxG9?P3D 8uxBīC3.3g*Al%MiZJR MGj)6w McBdM 3Ƕ<ŴLQb[!qv \(~|ȱCQO^d0 'u-odV7'\8T$^]g>v7 ~.yZewIol_:o#"mD^})*0vبG8|߶(?.JWB\6q\#Dr\,ʄ H Ww~N-IKa'JMH[ F3V+eG|wӏQȎaXrPxe['8$C_f,`3sP~HW:C?mnJoPu [e=rӐڃpINs+"63d20yF!LT﵉Rf a;Tyɿb!w ohbc74W$c KS/O{xBhBg!oYJ604Eâ_?q)t]n&:э`<&XyBLfNsAb;CE'cRM+JGl1$3zmYM;CX菥2&2ll&ɲaqڀV};_68%D쟜0y4-o >Ƌ*t\۴PmlG̔ эK 84ImaM!i;L^ PRGOAq䥱/Us#AUp [yF `>{sVV?,$ePoė2,6]l2Ӯ*8w iQ]P;Zn嫽3-8eZb_X@9fR)7SYKf&4%K6J&TT!1_epkK:Sv3ZG(`:r2Y-ذ~0Ҡ(p`կU9W;Y*ق=vEŠ sT] iz uph!@xrW ?41>*O-rA$ŨǬʲ϶}b\G5zb$cG*dz]#8%,zP|%'4SGڡÁmw->5jn.l}0yDo9U-pUv iLB-/W;uk"U? WN.QC}ppQ]y\fr#V'^Mpn4m$*-9T@{`†rsW;7~okp$ۇ"Lq_iLt'"csH"}G1{nH"ܥt@1ь_~)|;*snB^LAmPe/~L|xA>2χ#/ G>9,UPX*( ܈OW"4dtURȾ0p*J2Tלc =}2Jɉᷧ{V}1s%2p?-8ׄb#[9#nI޽EC;gdyJ˘[|>`N tJH1;L Q:l97ҙu4uMΥeZx3 ԑ _=9WqsoL?A/F3O}VM;~-covt7v_>G\3?B~inމ6׿7dꡣ qY'{<ҭkD.ai>nN;,Wp[*kF `"V]>o6PsZVE6@s%~~-JAIP`V,@r- >-xp[>j}c[\%ؗ\LUWCʗhCi x[lE5L`䇙o *4Lc:]*ơ^# +{avbf<"D3  T/i6Z" \)R:hcMjs6 w'1qHԮY9ρ53FߐSI52[݆v̜#)>98.oznt ӹp$}smM.pܬ7R[ćCSgT};' yr2!$z=7;?(_,xxh&ɏ#` $EطIPM7@9#mykc:TXx8m[޺d43ş[n9@2 Xb/0tWz4Q0:}Cn.7q8,iSXSaw!_=$f EQ^- L~J< 8rNLL[*- k\0 g)AO_e8Dž!LLC E0_ X2ZHSW<;!{ j9Bym~{u 1,wMXy)Tv[n)z4+I8u&ba3HMjx\hzu򽼴qlڟ>37ۻ".k٤EH3FR}+Da3s]E GnTWX0{l_Qm"kƄ C(e 23|yMy0ӷ$zK E2[ OVnv_שu!U>Ȁ2Z|qVؼ:&y6 _bs@HW?2f\lL`c&PI`yi5)]X2Sg:Ffl%{óQxQ8AL 9U>0wkVOhOS+#DZ` huFRS=8[> I Zˑ07_Ah Q%c_Z]5yj# IDo68e7 qs:l> G\[5D?\"rAuYo˛n֐C(dg{Vu-RdninwT<7g'snoj7#oL<*ܪ_e L":cѤE@;:e(񙯛 C{( 7PJ1P$ hi/E8t0yu"MX~K5cp4=b_Xx#juK>qe_:p Ѽ>L ؊C~aZ).Fw'uڇjKle L9Y,}T["{l* @Ȣ8 1>;/8e&>dG~@SB7ZiS6kW :;v^A3z4XՖ$Zb4]` Kh8Q$/+IRt<[ܓyoG3{B<Ɵ@ޏPj//''#IqR n5 S/DiӪS8ѣ W/3g@y\(EѰ.;9}|wܙvY uZbe2< a׷u[.x-yEpDm@] 8vheTVҎ'ըCeEu{ 52Ԏ8 $פ%O:]״ EVeMՑ\ @]9Ad[72q ywn.$ *W9I QM]}:‘6 7 o|BР%GR3V(Yhl~amLQ[|eIJe?o6UN#qe֊uCL]GM 3e4mw[f1T`S$2{Z5:?E?JȖR#ЖI,| UWH%t\UUr22ة t2o{Ќ5(Ɯ]{yjܻy-ý?`qz*8?]R$@W+A^uSw4T\uww\[V8},uc,e?mǚICTda'XG7drD"{oi (#nWye/S_D 'P jxY^n98Ln턦ѩk 4 ^V鑘yHl<YQylP6<:_EsK_GbrMILl,u>^Zq(j6 ܠ@nTcn}1Q,v'TV6+Dثh֔{B@B\S2Xq|Zj$9%qUA.d[BA/!Kh[oD;xdE(JyY1C1OYEy{ekĂcSXE&7'6#R{C| (P*ɘBL G1Yz 1^?KX]b UD nCJԀxJYEOEž^o3~qS03w&wM^b>i^A.˒z0q"J q'+M}~8}6Wx*JW_'m/5/{IȆ=_ta-=M mY렀;`:J2-_E2$z!gFbEi;Q|a)jxqϲ:9PD T8t ؑ"!)h t0?=SryȓMLG Y?;'`4{ֲq(ܶ_ w{?~u$Xqb$0t#ጕ͉ڮj Ug8H`Sh4Q0ȌpC Q6ej+BQOe#VOx\]5Tc3(dOV_F^Ra A?Vd`ސRx8v_cIH"2£} ;3Ifdm M1f[^._4MB+ 1PVˆdA87x<nW5yU..]]WȺwȎ4ӇtW?wk6œQͱ"ф1-riۭ6XY:A V R]E_Fl}Ӆ1[r c/{{+yDI&-'FbuP+ҴO)\e4Dyi'MoPF=9i3Ae lB["Mj:ON?~RK|XYxi10gGI0bn &`K?sq:j!< S@. :=Sp^ 3@0R7eMe3Rdg-av˸M P n9D9:_?g y9)e}&r&I,R)qCX/U4N $W[͗\8LȎA$"F0" չn $$'ƨ$ޱR_H!]SN/E"U: U [ŪZj,Scu52د7-Ÿ:҅I=Nڒ0̗ N{h6b@iE#oa|k/¤h6 ghnSnFDF:ΐN>N?1^kJd}"g A%v'MF3:W>'hyoKtqv4 A9 ԓ 'c|_{hKeY/R?mɇ1LO%Zvp'@z2L_&Hڬu[jZ|1jhK)e񆓻W q6-$r7}ږեN&1>ho jUhc9~l9$[ Sd=C&:#⎎|;ڗ.OZE`m }ׇ쒟Knݥ*!DNAr%˶GߞMz5S5\Z$ڰW(?29̓ &eѿ?D ;,m*[ clfp#!J"ZӔ4>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33ggm,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,frrrrk,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,֭ACC--,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,66rrc,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,/yrrrrF,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,hhl..,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,AA0,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Lrrrrr,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,MM,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,77ʹڴ>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,orrrrd,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3==,,,,,,,,,,,,,,,,,,,,,,;/k;wBrFmIhLkKpGuCz{?M4-,,,,,,,,,,,,,,,,,,,,,11ÆT,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4wrrrr;,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,755,,,,,,,,,,,,,,,,,,6.z{?jK^T^T^T^T^T^T^T^T^T^T^TdPtDL3,,,,,,,,,,,,,,,,,,--ssb,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Urrrrr,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,-;;,,,,,,,,,,,,,,,,3.z{?bQ^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TqFF3,,,,,,,,,,,,,,,,//ΝG,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,x}rrrrZ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,JJ,,,,,,,,,,,,,,,,c9cP^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T_SuD1.,,,,,,,,,,,,,,446,,,,,,,,,,,,,,,,,,,,,,,,,,,,,^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^ThM,,,,,,,,,,,,``u,,,,,,,,,,,,,,,,,,,UtrrrrD,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,rF^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T/-,,,,,,,,,,RR,,,,,,,,,,,,,,,,,,.rrrrp,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ȒM,,,,,,,,,,,,mJ^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T=0,,,,,,,,,,HH,,,,,,,,,,,,,,,,,,QurrrrH,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,tta,,,,,,,,,,,,hM^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TL3,,,,,,,,,,@@,,,,,,,,,,,,,,,,,-}rrrrr,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,aat,,,,,,,,,,,,bQ^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TZ8,,,,,,,,,,99,,,,,,,,,,,,,,,,,NvrrrrM,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ggm,,,,,,,,,,,,dP^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TU6,,,,,,,,,,<<,,,,,,,,,,,,,,,,,{rrrrr,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Y,,,,,,,,,,,,iK^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TF3,,,,,,,,,,CC,,,,,,,,,,,,,,,,KvrrrrQ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ѣE,,,,,,,,,,,,oH^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T7.,,,,,,,,,,LL,,,,,,,,,,,,,,,,xrrrrr,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,vC^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TaR,,,,,,,,,,,,WW,,,,,,,,,,,,,,,GwrrrrV,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,//,,,,,,,,,,a8^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^ToH,,,,,,,,,,,,hhl,,,,,,,,,,,,,,,urrrrr,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,<<,,,,,,,,,,3.`S^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^Tm<,,,,,,,,,,,,߿;,,,,,,,,,,,,,,LxrrrrZ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ZZ},,,,,,,,,,,,nI^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T=0,,,,,,,,,,77,,,,,,,,,,,,,,1rrrrr#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ذ@,,,,,,,,,,,,c9^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TnH,,,,,,,,,,,,OO,,,,,,,,,,,,,,`xrrrr^,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,55,,,,,,,,,,-,iL^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TK3,,,,,,,,,,,,ƍP,,,,,,,,,,,,,=rrrrr(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,MM,,,,,,,,,,,,\8^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TqF,,,,,,,,,,,,22,,,,,,,,,,,,,,utrrrr],,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,߿;..,,,,,,,,,,,,mJ^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T`SE2,,,,,,,,,,,,^^w,,,,,,,,,,,,,P|rrrrr,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,MM,,,,,,,,,,,,<0dP^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^Th:,,,,,,,,,,,,44.,,,,,,,,,,,,3rrrrrG,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6//,,,,,,,,,,,,K3aR^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TyA,,,,,,,,,,,,,,hhl,,,,,,,,,,,,,dwrrrrj ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,SS,,,,,,,,,,,,,,`8_S^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TrF-,,,,,,,,,,,,,66,,,,,,,,,,,,,@rrrrr.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,077,,,,,,,,,,,,,,U6cP^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TxB.,,,,,,,,,,,,,--ÆT,,,,,,,,,,,,-xtrrrr[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,۷=11,,,,,,,,,,,,,,B2hM^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T`Sj;,,,,,,,,,,,,,,,,YY~,,,,,,,,,,,,,T{rrrrq,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,…U--,,,,,,,,,,,,,,4.zAaR^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^T^TnHK3,,,,,,,,,,,,,,,,,,33۷۷=,,,,,,,,,,,4rrrrrD,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,__v,,,,,,,,,,,,,,,,,,9/vB`S^T^T^T^T^T^T^T^T^T^T^T^T^T^TmJR5,,,,,,,,,,,,,,,,,,,,,,,,33۷۷=,,,,,,,,,,hvrrrri,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,TT,,,,,,,,,,,,,,,,,,,,6.e:rFbQ^T^T^T^T^T^T^T_SlKy|>H3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33۷۷=,,,,,,,,Crrrrr+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,rrc//,,,,,,,,,,,,,,,,,,,,,,.-@1P5a8o=g:W6F33.,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33۴ڴ>,,,,,,.{srrrrX,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ΝG44,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,--MM//,,,,,,,,,,,,,,33۴ڴ>,,,,,Zzrrrrq,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5@@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,33݁W,U//,,,,,,,,,,,,,,33۴ڴ>,,,Brrrrr@,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,ÇS::,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,11[[{.,,,U//,,,,,,,,,,,,,,33۴ڴ>,3vrrrrg,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,xx^77,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,00SS1,,,,,,U//,,,,,,,,,,,,,,33۶۶>o}rrrrr(,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,СFUU99--,,,,,,,,,,,,,,,,,,,,,,,,33HHxx^.,,,,,,,,,U//,,,,,,,,,,,,,,ccrrrrrU,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5hhlQQGG??884466<C M ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,0>M[jz}urrrrrrrrrrrmIC z,,,,,,,,,,,,,,,,,,,,,,,,,,-8FUcr}wrrrrrrrrrrrrqT*C ,,,,,,,,,,,,,,,,,,,,2AO]lz~xsrrrrrrrrrrrrr_5 C=Pbtn[H0,,,,.0358:AGOV]dkrzysrrrrrrrrrrrrrrh@C'b N1ysrrrrrrrrrrrrrrrnL"C& c |xtrrrrrrrrrrrrrrrq\?"C Q~zvsrrrrrrrrrrrrrrrrrr_A$' ~|xtrrrrrrrrrrrrrrrrrrrrraD' F m~|{ywurrrrrrrrrrrrrrrrrrrrrrrrdG* kN pssrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrfI, - jrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrpaP>- w yhrrrrrrrrrrrrrrrrrrrrrrrrrrhVE4" Cerrrrrrrrrrrrrrrrrrrn]L;*p9 anlifc`]ZXTLD;3*! Q[B W 5 q=3 s` u )  ;: M; M! ;v *a 4 t s?Y 7D  U]s<  G{ } 1 oR L s#, C W n, i -i T9`CViztbN6#: U&c2X5:g??????????????????????p?0???`????????????|???????????|0??????PyScanFCS-0.2.3/freeze_pyinstaller/PyScanFCS_linux.spec000066400000000000000000000010431245330745300230030ustar00rootroot00000000000000# -*- mode: python -*- a = Analysis(['pyscanfcs/PyScanFCS.py'], pathex=[], hiddenimports=[], hookspath=None) a.datas += [('doc/ChangeLog.txt', 'ChangeLog.txt', 'DATA'), ('doc/PyScanFCS_doc.pdf', 'doc/PyScanFCS_doc.pdf', 'DATA')] pyz = PYZ(a.pure) exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name=os.path.join('dist', 'PyScanFCS'), debug=False, strip=None, upx=True, console=False ) PyScanFCS-0.2.3/freeze_pyinstaller/PyScanFCS_mac.spec000066400000000000000000000013301245330745300224030ustar00rootroot00000000000000# -*- mode: python -*- a = Analysis(['pyscanfcs/PyScanFCS.py'], hookspath=None) a.datas += [('doc/ChangeLog.txt', 'ChangeLog.txt', 'DATA'), ('doc/PyScanFCS_doc.pdf', 'doc/PyScanFCS_doc.pdf', 'DATA')] pyz = PYZ(a.pure) exe = EXE(pyz, a.scripts, exclude_binaries=True, name='PyScanFCS', debug=False, strip=None, upx=True, console=False ) coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=None, upx=True, name='PyScanFCS') app = BUNDLE(coll, name='dist/PyScanFCS.app', icon='freeze_pyinstaller/PyScanFCS.icns') PyScanFCS-0.2.3/freeze_pyinstaller/PyScanFCS_win7.spec000066400000000000000000000033701245330745300225350ustar00rootroot00000000000000# -*- mode: python -*- import codecs import os import sys if not os.path.exists("freeze_pyinstaller"): raise Exception("Please go to `PyScanFCS` directory.") name = "PyScanFCS" DIR = os.path.realpath(".") PyInstDir = os.path.join(DIR, "freeze_pyinstaller") PCFDIR = os.path.join(DIR, "pyscanfcs") ProgPy = os.path.join(PCFDIR,"PyScanFCS.py") ChLog = os.path.join(DIR,"ChangeLog.txt") DocPDF = os.path.join(DIR,"doc/PyScanFCS_doc.pdf") ICO = os.path.join(PyInstDir,"PyScanFCS.ico") sys.path.append(DIR) ## Create inno setup .iss file import pyscanfcs version = pyscanfcs.__version__ issfile = codecs.open(os.path.join(PyInstDir,"win7_innosetup.iss.dummy"), 'r', "utf-8") iss = issfile.readlines() issfile.close() for i in range(len(iss)): if iss[i].strip().startswith("#define MyAppVersion"): iss[i] = '#define MyAppVersion "{:s}"\n'.format(version) nissfile = codecs.open("win7_innosetup.iss", 'wb', "utf-8") nissfile.write(u"\ufeff") nissfile.writelines(iss) nissfile.close() a = Analysis([ProgPy], pathex=[DIR], hiddenimports=["sympy.assumptions.handlers", # sympy "sympy.assumptions.handlers.common", "scipy.special._ufuncs_cxx"], hookspath=None) a.datas += [('doc\\ChangeLog.txt', ChLog, 'DATA'), ('doc\\PyScanFCS_doc.pdf', DocPDF, 'DATA')] pyz = PYZ(a.pure) exe = EXE(pyz, a.scripts, exclude_binaries=True, name=name+'.exe', debug=False, strip=None, upx=True, icon=ICO, console=False ) coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=None, upx=True, name=name) PyScanFCS-0.2.3/freeze_pyinstaller/README.md000066400000000000000000000015311245330745300204400ustar00rootroot00000000000000PyScanFCS - creating binaries with PyInstaller ========= Usage ------------------- All cython (~.pyx) files must be compiled before scripts in this directory can be run. In the PyScanFCS/ directory execute: python setup.py build_ext --inplace Download PyInstaller from http://www.pyinstaller.org/ ([Working revision](https://github.com/pyinstaller/pyinstaller/commit/779d07b236a943a4bf9d2b1a0ae3e0ebcc914798)). To create a single binary file, go to the unpacked pyinstaller directory and execute python pyinstaller.py /Path/To/PyScanFCS.py Alternatively, there are ~.spec files and scripts for Windows / Mac / Debian in this directory for bundling binary files. Note ------------------- For more details, consult [PyCorrFit/freeze_pyinstaller](https://github.com/paulmueller/PyCorrFit/tree/master/freeze_pyinstaller). PyScanFCS-0.2.3/freeze_pyinstaller/debian_ubuntu_bundle_script.sh000077500000000000000000000037461245330745300252730ustar00rootroot00000000000000#!/bin/bash Progname="PyScanFCS" # Go to base dir of repo BASEDIR=$(dirname $0) cd $BASEDIR BASEDIR=$(pwd) cd "../" StartDir=$(pwd)"/" Progdir=${StartDir}"/" # We require a Progname_doc.tex in the source-doc directory DocDir=${StartDir}"/doc/" Docname=${DocDir}${Progname}"_doc.pdf" Changelogname="ChangeLog.txt" Specfile=${BASEDIR}"/"${Progname}"_linux.spec" codename=$(lsb_release -c | awk 'BEGIN { FS = "\t" }; { print $2 }') distrib=$(lsb_release -i | awk 'BEGIN { FS = "\t" }; { print $2 }') version=$(head -n1 ./ChangeLog.txt | tr -d "\r\n") #Binname="dist/"${Progname}_${distrib}_${codename}_$(uname -r)".bin" Zipname="dist/"${Progname}_${version}_${distrib}_${codename}_$(uname -r)".zip" Env="env_${Progname}" echo $Specfile cd $StartDir echo "############" echo "Checking pip" echo "############" # Check if pip is installed if [ 1 -ne $(dpkg -s python-pip | grep -c "Status: install ok installed") ]; then echo "Please install package `python-pip`" exit fi if ! [ -e $Env ]; then virtualenv --system-site-packages $Env if [ $? -ne 0 ]; then echo "Error - Aborting" exit fi source $Env"/bin/activate" # Pyinstaller pip install git+git://github.com/pyinstaller/pyinstaller.git@779d07b236a943a4bf9d2b1a0ae3e0ebcc914798 # PyFITS pip install pyfits fi source $Env"/bin/activate" echo "###################" echo "Building Extensions" echo "###################" rm -f $Docname python setup.py build_ext --inplace if [ $? -ne 0 ]; then echo "Error - Aborting" exit fi echo "############################" echo "Removing old build directory" echo "############################" rm -rf build if [ $? -ne 0 ]; then echo "Error - Aborting" exit fi echo "###################" echo "Running Pyinstaller" echo "###################" pyinstaller -F $Specfile if [ $? -ne 0 ]; then echo "Error - Aborting" exit fi echo "############" echo "Creating Zip" echo "############" zip -j ${Zipname} "dist/"${Progname} ${Docname} ${Changelogname} PyScanFCS-0.2.3/freeze_pyinstaller/macOSx_script_starter.sh000066400000000000000000000004641245330745300240430ustar00rootroot00000000000000#!/bin/bash # # We need to run PyScanFCS in a separate Terminal to prevent this error # from occuring: # # UnicodeDecodeError: 'ascii' codec can't decode byte 0xcf # in position 0: ordinal not in range(128) # # tags: pyinstaller app bundling wxpython cd $(dirname "$0") open -a Terminal.app ./PyScanFCS.bin PyScanFCS-0.2.3/freeze_pyinstaller/win7_32bit_bundle_script.bat000066400000000000000000000001521245330745300244530ustar00rootroot00000000000000cd %~dp0 cd .. DEL /F /Q .\doc\PyScanFCS_doc.pdf pyinstaller -y .\freeze_pyinstaller\PyScanFCS_win7.spec PyScanFCS-0.2.3/freeze_pyinstaller/win7_innosetup.iss.dummy000066400000000000000000000072071245330745300240310ustar00rootroot00000000000000; Script generated by the Inno Setup Script Wizard. ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "PyScanFCS" #define MyAppVersion "0.2.2" #define MyAppPublisher "Paul Müller" #define MyAppURL "http://pyscanfcs.craban.de" #define MyAppExeName "PyScanFCS.exe" #define MyAppDir = "C:\Users\Paul\Desktop\PyScanFCS\dist\PyScanFCS\" [Setup] ; NOTE: The value of AppId uniquely identifies this application. ; Do not use the same AppId value in installers for other applications. ; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) AppId={{10078D61-1BFE-505A-C57D-57BCC20B8360} AppName={#MyAppName} AppVersion={#MyAppVersion} ;AppVerName={#MyAppName} {#MyAppVersion} AppPublisher={#MyAppPublisher} AppPublisherURL={#MyAppURL} AppSupportURL={#MyAppURL} AppUpdatesURL={#MyAppURL} DefaultDirName={pf}\{#MyAppName} DisableDirPage=yes DefaultGroupName={#MyAppName} AllowNoIcons=yes OutputBaseFilename={#MyAppName}_{#MyAppVersion}_setup Compression=lzma SolidCompression=yes ChangesAssociations=yes [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" [Tasks] Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked [Files] Source: "{#MyAppDir}{#MyAppName}.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#MyAppDir}*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs ; NOTE: Don't use "Flags: ignoreversion" on any shared system files [Icons] Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" Name: "{group}\Documentation"; Filename: "{app}\doc\{#MyAppName}_doc.pdf" Name: "{group}\Changelog"; Filename: "{app}\doc\Changelog.txt" Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon [Run] Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent [Code] ///////////////////////////////////////////////////////////////////// function GetUninstallString(): String; var sUnInstPath: String; sUnInstallString: String; begin sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1'); sUnInstallString := ''; if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); Result := sUnInstallString; end; ///////////////////////////////////////////////////////////////////// function IsUpgrade(): Boolean; begin Result := (GetUninstallString() <> ''); end; ///////////////////////////////////////////////////////////////////// function UnInstallOldVersion(): Integer; var sUnInstallString: String; iResultCode: Integer; begin // Return Values: // 1 - uninstall string is empty // 2 - error executing the UnInstallString // 3 - successfully executed the UnInstallString // default return value Result := 0; // get the uninstall string of the old app sUnInstallString := GetUninstallString(); if sUnInstallString <> '' then begin sUnInstallString := RemoveQuotes(sUnInstallString); if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then Result := 3 else Result := 2; end else Result := 1; end; ///////////////////////////////////////////////////////////////////// procedure CurStepChanged(CurStep: TSetupStep); begin if (CurStep=ssInstall) then begin if (IsUpgrade()) then begin UnInstallOldVersion(); end; end; end; PyScanFCS-0.2.3/misc/000077500000000000000000000000001245330745300142065ustar00rootroot00000000000000PyScanFCS-0.2.3/misc/ExampleFunc_Exp_correlated_noise.txt000077500000000000000000000013731245330745300234020ustar00rootroot00000000000000# Exponentially correlated noise # This is a test function used to check times of exponentially # correlated noise. # Fraction Purity = 0.5 # Exp time tauexp [ms] = 2.0 # You may choose to substitute certain parts of the correlation function # with other values for easy reading. This can be done by using the # prefix "g". You may use all common mathematical functions, # such as "sqrt()" or "exp()". For convenience, "pi" and "e" may also # be used. If you are paranoid, you always use float numbers with a dot "." # to be sure the program doesn't accidently do integer division. gTrip = Purity/(1-Purity)*exp(-tau/tauexp) # The final line with the correlation function should start with a "G" # before the "=" sign. G = gTrip PyScanFCS-0.2.3/misc/MakeTestDat_SFCS.py000077500000000000000000000135051245330745300175530ustar00rootroot00000000000000#!/usr/bin/python """ This program creates a .dat file with photon arrival times as it is produced by the FLEX correlators from correlator.com in photon history recorder mode by "Photon.exe". The generated files can be used to test multiple tau algorithm and workflow of SFCS analyzation programs. """ import numpy as np import multipletau import csv def MakeDat(linetime, noisearray, dtype, filename): """ Create a .dat file (like Photon.exe). System clock is fixed to 60MHz. linetime [s] noisearray integer array (uint16 or uint32) """ NewFile = open(filename, 'wb') if dtype == np.uint32: newformat = np.uint8(32) elif dtype == np.uint16: newformat = np.uint8(16) else: raise ValueError newclock = np.uint8(60) NewFile.write(newformat) NewFile.write(newclock) noisearray = dtype(noisearray) # Create matrix. Each line is a scan. data = list() timeticks = linetime*newclock*1e6 # 60MHz half1 = np.ceil(timeticks/2) half2 = np.floor(timeticks/2) for i in np.arange(len(noisearray)): # Create a line N = noisearray[i] if N == 0: line=np.zeros(1, dtype=dtype) # Only one event at the far corner line[0] = timeticks line.tofile(NewFile) else: line = np.ones(N+1, dtype=dtype) # events are included between two far events line[0] = half1-len(line) line[-1] = half2 line.tofile(NewFile) NewFile.close() def OnSaveDat(filename, data): # Save the Data """ Save experimental data as 32bit format. Raw data file format: 1. The file records the difference in system clock ticks (1/60 us) between photon events. 2. The first byte identifies the format of the file: 32 bit 3. The second byte identifies the system clock: usually 60MHz. 4. The time unit is 1/system clock. 5. 32 bit format. 4 bytes represent a photon event, time = 4 bytes/system clock """ # Make a reasonable 32bit filename NewFile = open(filename, 'wb') newformat = np.uint8(32) newclock = np.uint8(60) NewFile.write(newformat) NewFile.write(newclock) data = np.uint32(data) data.tofile(NewFile) NewFile.close() def GenerateExpNoise(N, taud=20., variance=1., deltat=1.): """ Generate exponentially correlated noise. """ # length of mean0 trace N_steps = N dt = deltat # time trace t = np.arange(N_steps) # AR-1 processes - what does that mean? # time constant (inverse of correlationtime taud) g = 1./taud # variance s0 = variance # normalization factor (memory of the trace) exp_g = np.exp(-g*dt) one_exp_g = 1-exp_g z_norm_factor = np.sqrt(1-np.exp(-2*g*dt))/one_exp_g # create random number array # generates random numbers in interval [0,1) randarray = np.random.random(N_steps) # make numbers random in interval [-1,1) randarray = 2*(randarray-0.5) # simulate exponential random behavior z = np.zeros(N_steps) z[0] = one_exp_g*randarray[0] for i in np.arange(N_steps-1)+1: z[i] = exp_g*z[i-1] + one_exp_g*randarray[i] z = z * z_norm_factor*s0 return z def ReduceTrace(trace, deltat, length): """ Given a `trace` of length `len(trace)`, compute a trace of length smaller than `length` by averaging. Parameters ---------- trace : ndarray, shape (N) Input trace that is to be averaged. deltat : float Time difference between bins in trace. length : int Maximum length of the new trace. Returns ------- newtrace : ndarray, shape (N,2) New trace (axis 1) with timepoints (axis 0). """ step = 0 while len(trace) > length: N = len(trace) if N % 2 != 0: N -= 1 trace = (trace[0:N:2] + trace[1:N:2]) / 2 step += 1 # Return 2d array with times T = np.zeros((len(trace), 2)) T[:,1] = trace/deltat/1e3 # in kHz T[:,0] = np.arange(len(trace))*deltat*2**step return T def SaveCSV(G, trace, filename): """ Save correlation and trace tuple array G and trace to a .csv file that can be opened with FCSfit. """ # Save Correlation function csvfile = filename openedfile = open(csvfile, 'wb') openedfile.write('# This file was created using testmultipletau.py\r\n') openedfile.write('# Channel (tau [s])'+" \t," 'Correlation function'+" \r\n") dataWriter = csv.writer(openedfile, delimiter=',') for i in np.arange(len(G)): dataWriter.writerow([str(G[i,0])+" \t", str(G[i,1])]) openedfile.write('# BEGIN TRACE \r\n') openedfile.write('# Time ([s])'+" \t," 'Intensity Trace [kHz]'+" \r\n") for i in np.arange(len(trace)): dataWriter.writerow([str(trace[i,0])+" \t", str(trace[i,1])]) openedfile.close() # Line time to be found by SFCS analyzation software linetime = 0.714 # in ms # Time of exponentially correlated noise taudiff = 7. # in ms noisearray = GenerateExpNoise(200000, taud=taudiff/linetime) noisearray += np.abs(np.min(noisearray)) noisearray *= 30./np.max(noisearray) noisearray = np.uint32(noisearray) # Create 32bit and 16bit binary .dat files data = MakeDat(linetime/1000, noisearray, np.uint16, "test_"+str(taudiff)+"ms_16bit.dat") data = MakeDat(linetime/1000, noisearray, np.uint32, "test_"+str(taudiff)+"ms_32bit.dat") # Create reference .csv file to check results G = multipletau.autocorrelate(noisearray, deltat=linetime/1000, normalize=True) newtrace = ReduceTrace(noisearray, deltat=linetime, length=500) SaveCSV(G, newtrace, "test_"+str(taudiff)+"ms_reference.csv") PyScanFCS-0.2.3/misc/README.md000066400000000000000000000017311245330745300154670ustar00rootroot00000000000000PyScanFCS - misc =========== These are functions that are either implemented somehow in PyScanFCS or that can be used to test PyScanFCS. - **binningc.pyx**: converts 16 bit ~.dat file format to 32 bit ~.dat file format (For further information, see the documentation of PyScanFCS at http://fcstools.dyndns.org/pyscanfcs) - **dat2csv.py**: using a photon stream from a ~.dat file, it calculates the correlation curve and saves it as a ~.csv file for PyCorrFit http://fcstools.dyndns.org/pycorrfit - **setup.py**: compiles binningc.pyx using Cython Testing the PyScanFCS: - **MakeTestDat_SFCS.py**: create a exponentially correlated noise in a ~.dat file that can be loaded with [PyScanFCS](https://github.com/paulmueller/PyScanFCS) (http://fcstools.dyndns.org/pyscanfcs) - **ExampleFunc_Exp_correlated_noise.txt**: external model function for fitting of exponentially correlated noise using [PyCorrFit]https://github.com/paulmueller/PyCorrFit) (http://fcstools.dyndns.org/pycorrfit) PyScanFCS-0.2.3/misc/binningc.pyx000077500000000000000000000154261245330745300165520ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Binning Data for Multiple Tau Algorithm Paul Müller, Biotec - TU Dresden As fast as you can get with python, binning the photon arrival times created by Photon.exe from correlator.com. See at the end of the file, which .dat file will be opened. In console, we ask for binning time in µs and an .int file is created. """ #import codecs, sys, win32console import sys import numpy as np # NumPy # See cython documentation for following stuff # "cimport" is used to import special compile-time information # about the numpy module (this is stored in a file numpy.pxd which is # currently part of the Cython distribution). cimport numpy as np # We now need to fix a datatype for our arrays. I've used the variable # DTYPE for this, which is assigned to the usual NumPy runtime # type info object. DTYPEuint32 = np.uint32 DTYPEuint16 = np.uint16 # "ctypedef" assigns a corresponding compile-time type to DTYPE_t. For # every type in the numpy module there's a corresponding compile-time # type with a _t-suffix. ctypedef np.uint32_t DTYPEuint32_t ctypedef np.uint16_t DTYPEuint16_t # Negative indices are checked for and handled correctly. The code is # explicitly coded so that it doesn’t use negative indices, and it (hopefully) # always access within bounds. We can add a decorator to disable bounds checking: cimport cython #@cython.boundscheck(False) # turn of bounds-checking for entire function #def function(): # Vector to use as a list #from libcpp.vector cimport vector #Current @cython.boundscheck(False) # turn of bounds-checking for entire function def OpenDat(filename): # Open a data file """ We open a .dat file as produced by the "Flex02-12D" correlator in photon history recorder mode. The file contains the time differences between single photon events. Returns: This function makes the filename publicly available, bins a couple of events to get 1e+6 points and plots them into the plotting area (plotarea), using the Bin_Photon_Events() function. Raw data file format (taken from manual): 1. The file records the difference in system clock ticks (1/60 us) between photon event. 2. The first byte identifies the format of the file 8 : 8 bit, 16: 16 bit 3. The second byte identifies the system clock. 60MHz. 4. The time unit is 1/system clock. 5. 16 bit format. Each WORD (2 bytes) represents a photon event, time = WORD/system clock, unless the value is 0xFFFF, in which case, the following four bytes represent a photon event. 6. 8 bit format: Each BYTE represents a photon event unless the value is 0xFF, in which case, the BYTE means 255 clock ticks passed without a photon event. For example 0A 0B FF 08 means there are three photon events. The time series are 0x0A+1, 0x0B+1, 0xFF+8+1. """ cdef np.ndarray[DTYPEuint16_t] Data cdef np.ndarray[DTYPEuint32_t] datData cdef int i, N # open file File = open(filename, 'rb') # 1st byte: get file format # should be 16 - for 16 bit format = int(np.fromfile(File, dtype="uint8", count=1)) if format == 8: # No 8 bit format supported print 'Error 8 bit format not supported.' return None # 2nd byte: read system clock system_clock = int(np.fromfile(File, dtype="uint8", count=1)) # There is an utility to convert data to 32bit. This makes life easier: if format == 32: datData = np.fromfile(File, dtype="uint32", count=-1) return system_clock, datData # In case of 16 bit file format (assumed), read the rest of the file in # 16 bit format. # Load bunch of Data Data = np.fromfile(File, dtype="uint16", count=-1) File.close() # Now we need to check if there are any 0xFFFF values which would # mean, that we do not yet have the true data in our array. # There is 32 bit data after a 0xFFFF = 65535 print "Searching for 32bit events." occurences = np.where(Data == 65535)[0] N = len(occurences) print "Found "+str(N)+" 32bit events." # Make a 32 bit array datData = np.uint32(Data) for i in occurences: # The following two events represent the actual event # Convert 2*16bit uint to 1*32bit uint: datData[i] = np.uint32(Data[i+1]) + np.uint32(Data[i+2])*65536 print "Added new 32 bit array. Finishing..." # Now delete the zeros zeroids = np.zeros(N*2) for i in range(N): zeroids[i*2] = occurences[i]+1 zeroids[i*2+1] = occurences[i]+2 datData = np.delete(datData, zeroids) del Data return system_clock, datData @cython.boundscheck(False) # turn of bounds-checking for entire function def BinData(np.ndarray[DTYPEuint32_t] data, double t_bin, filename): cdef int N = len(data) BinData = [] time_c = 0.0 # time counter cdef int phot_c = 0 # photon counter cdef int maxphot = 0 cdef int j, i, emptybins, bin dtype=np.uint16 newfilename = filename[:-4]+".int" print "Creating file "+newfilename NewFile = open(newfilename, 'wb') TempTrace = list() for j in range(100): percent = str(j) sys.stdout.write("\r Counting photons: "+percent+"%") sys.stdout.flush() for i in range(N/100): i = i+N/100*j time_c += data[i] if time_c >= t_bin: # Append counted photons and # reset counters #NewFile.write(dtype(phot_c)) TempTrace.append(phot_c) time_c -= t_bin phot_c = 0 # Empty bins between this and next event: emptybins = int(time_c/t_bin) TempTrace += emptybins*[0] time_c -= emptybins*t_bin # Equivalent to: # time_c = int(time_c)%int(t_bin) phot_c += 1 NewFile.write(dtype(TempTrace)) TempTrace = list() # Now write the rest: for i in range(N/100*100,N-1): time_c += data[i] if time_c >= t_bin: # Append counted photons and # reset counters #NewFile.write(dtype(phot_c)) TempTrace.append(phot_c) time_c -= t_bin phot_c = 0 # Empty bins between this and next event: emptybins = int(time_c/t_bin) TempTrace += emptybins*[0] time_c -= emptybins*t_bin # Equivalent to: # time_c = int(time_c)%int(t_bin) phot_c += 1 NewFile.write(dtype(TempTrace)) TempTrace = list() sys.stdout.write("\r Counting photons: 100%") sys.stdout.flush() sys.stdout.write("\r \r\n") # clean up stdout NewFile.write(dtype(TempTrace)) NewFile.close() return True PyScanFCS-0.2.3/misc/dat2csv.py000077500000000000000000000073761245330745300161460ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Binning Data and performing Multiple Tau Algorithm Paul Müller, Biotec - TU Dresden As fast as you can get with python, binning the photon arrival times created by Photon.exe from correlator.com. See at the end of the file, which .dat file will be opened. In console, we ask for binning time in µs and an .int file is created. """ #import codecs, sys, win32console import argparse import csv import sys import numpy as np # NumPy import os import struct import tempfile import time import zipfile # c compiled modules import binningc import multipletauc parser = argparse.ArgumentParser() parser.add_argument('-w', '--tbin', type=float, help='Width of bins in us') parser.add_argument('input', metavar='INPUT', nargs='?', type=str, help='Input .dat file') parser.add_argument('output', metavar='OUTPUT', nargs='?', type=str, help='Output .csv file') args = parser.parse_args() p_tbin = args.tbin p_infile = args.input p_outfile = args.output if p_infile is None: # Use a standard file filename = "./A488_50nMA.dat" #filename = "./w01-11A.dat" #filename = "./03_100s_pos4.dat" else: filename = p_infile #system_clock = None # Also resets system_clock: a=time.time() system_clock, event_data = binningc.OpenDat(filename) print "Finding Events: "+str(time.time()-a)+"s" print "System clock: "+str(system_clock)+" MHz" if event_data is None: print "Problem acquiring data." exit() if p_tbin is None: t_bin = float(raw_input("Enter binning time in us:")) else: t_bin = p_tbin bintime = 1.*t_bin*system_clock # Creates binned file a=time.time() binningc.BinData(event_data, bintime, filename) print "binning time: "+str(time.time()-a)+"s" ## Perform multiple tau algorithm # bintime from µs to s deltat = t_bin/1e6 # File created by BinData: newfilename = filename[:-4]+".int" #trace = np.array(np.fromfile(newfilename, dtype="uint16", count=-1), dtype="float64") # Calculate autocorrelation a=time.time() G_list = multipletauc.ACFromFile(newfilename, deltat, m=128) print "multiple-tau time: "+str(time.time()-a)+"s" Trace_list = multipletauc.BinTracesFromFile(newfilename, deltat, length=700) print "Got traces." if p_outfile is None: zipfilename = filename[:-4]+".zip" else: zipfilename = p_outfile.strip(".zip")+".zip" Arc = zipfile.ZipFile(zipfilename, mode='w') returnWD = os.getcwd() tempdir = tempfile.mkdtemp() os.chdir(tempdir) for j in np.arange(len(G_list)): # Write G to file G = G_list[j] if p_outfile is None: csvfile = filename[:-4]+"_"+str(j)+".csv" else: csvfile = p_outfile.strip(".csv")+"_"+str(j)+".csv" openedfile = open(csvfile, 'wb') openedfile.write('# Created with dat2csv\r\n') openedfile.write('# Paul Mueller - BIOTEC, TU Dresden\r\n') openedfile.write('# Info:\r\n') openedfile.write('# Binning Time: '+str(deltat)+'s \r\n') openedfile.write('# Source file: '+filename+'\r\n') openedfile.write('# Source segment: '+str(j+1)+' of '+str(len(G_list))+'\r\n') openedfile.write('# Channel (tau [s])'+" \t," 'Correlation function'+" \r\n") dataWriter = csv.writer(openedfile, delimiter=',') for i in np.arange(len(G)): dataWriter.writerow([str(G[i,0])+" \t", str(G[i,1])]) # Write Trace T = Trace_list[j] openedfile.write('#\r\n# BEGIN TRACE\r\n#\r\n') openedfile.write('# Trace time [s]'+" \t," 'Intensity trace [kHz]'+" \r\n") for i in np.arange(len(T)): dataWriter.writerow([str(T[i,0])+" \t", str(T[i,1])]) openedfile.close() Arc.write(csvfile) os.remove(csvfile) os.chdir(returnWD) os.removedirs(tempdir) PyScanFCS-0.2.3/misc/setup.py000077500000000000000000000007211245330745300157230ustar00rootroot00000000000000# This file is used to compile libraries from cython code. # Run "python setup.py build_ext --inplace" to create those # libraries. # For more information visit cython.org. from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_modules = [Extension("binningc", ["binningc.pyx"]), ] setup( name = 'Binning Stuff', cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules ) PyScanFCS-0.2.3/pyscanfcs/000077500000000000000000000000001245330745300152445ustar00rootroot00000000000000PyScanFCS-0.2.3/pyscanfcs/PyScanFCS.py000066400000000000000000000003171245330745300173500ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ PyScanFCS loader """ from os.path import dirname, join, abspath, split import sys sys.path = [split(abspath(dirname(__file__)))[0]] + sys.path import pyscanfcs pyscanfcs.Main() PyScanFCS-0.2.3/pyscanfcs/SFCSnumeric.pyx000077500000000000000000000301151245330745300201320ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Numerical algorithms for perpendicular line scanning FCS (C) 2012 Paul Müller This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ from __future__ import division import sys import numpy as np # NumPy from scipy import optimize as spopt # For least squares fit import tempfile import warnings # See cython documentation for following stuff # "cimport" is used to import special compile-time information # about the numpy module (this is stored in a file numpy.pxd which is # currently part of the Cython distribution). cimport numpy as np # We now need to fix a datatype for our arrays. I've used the variable # DTYPE for this, which is assigned to the usual NumPy runtime # type info object. DTYPEuint32 = np.uint32 DTYPEuint16 = np.uint16 DTYPEfloat32 = np.float32 # "ctypedef" assigns a corresponding compile-time type to DTYPE_t. For # every type in the numpy module there's a corresponding compile-time # type with a _t-suffix. ctypedef np.uint32_t DTYPEuint32_t ctypedef np.uint16_t DTYPEuint16_t ctypedef np.float32_t DTYPEfloat32_t # Negative indices are checked for and handled correctly. The code is # explicitly coded so that it doesn’t use negative indices, and it (hopefully) # always access within bounds. We can add a decorator to disable bounds checking: cimport cython #@cython.boundscheck(False) # turn of bounds-checking for entire function #def function(): # Vector to use as a list #from libcpp.vector cimport vector __all__ = ["BinPhotonEvents", "FitExp", "FitGaussian", "OpenDat", "ReduceTrace"] @cython.cdivision(True) @cython.boundscheck(False) # turn of bounds-checking for entire function def BinPhotonEvents(np.ndarray[DTYPEuint32_t] data, double t_bin, binshift=None, outfile=None, outdtype=DTYPEuint16, callback=None, cb_kwargs={}): """ Convert photon arrival times to a binned trace Parameters ---------- data : ndarray (uint32) photon events to be binned t_bin : (double) binning time binshift : int adding a number of zeros at the beginning of the binned data outfile : str path to store output outdtype : dtype numpy dtype of the output file callback : callable or None Callback function to be called throughout the algorithm. If the return value of `callback` is not None, the function will abort. Number of function calls: 100 cb_kwargs : dict, optional Keyword arguments for `callback` (e.g. "pid" of process). Returns ------- filename : str The filename of the binned data. Bin all photon arrival times in a numpy.uint32 array *data*, using the binning time float *t_bin* and saving the intensity trace as the file *filename*. *dlg* is a python object that suports dlg.Update, like a progress dialog. Notes ----- The photon stram `data` is created by a program called `Photon.exe` from correlator.com. """ cdef int N = len(data) BinData = [] cdef double time_c = 0 # time counter cdef int phot_c = 0 # photon counter cdef int maxphot = 0 cdef int j, i, emptybins, bin dtype=np.dtype(outdtype) if outfile is None: outfile = tempfile.mktemp(suffix=".bin") #print("Creating file {} ({})".format(outfile, outdtype.__name__)) NewFile = open(outfile, 'wb') # Add number of empty bins to beginning of file if binshift is not None: NewFile.write(outdtype(np.zeros(binshift))) TempTrace = list() Nperc = int(np.floor(N/100)) for j in range(100): percent = str(j) for i in range(Nperc): i = i+Nperc*j time_c += data[i] if time_c >= t_bin: # Append counted photons and # reset counters #NewFile.write(outdtype(phot_c)) TempTrace.append(phot_c) time_c -= t_bin phot_c = 0 # Empty bins between this and next event: emptybins = int(time_c/t_bin) TempTrace += emptybins*[0] time_c -= emptybins*t_bin # Equivalent to: # time_c = int(time_c)%int(t_bin) phot_c += 1 NewFile.write(outdtype(TempTrace)) TempTrace = list() if callback is not None: ret = callback(**cb_kwargs) if ret is not None: warnings.warn("Aborted by user.") return outfile # Now write the rest: for i in range(Nperc*100,N-1): time_c += data[i] if time_c >= t_bin: # Append counted photons and # reset counters #NewFile.write(outdtype(phot_c)) TempTrace.append(phot_c) time_c -= t_bin phot_c = 0 # Empty bins between this and next event: emptybins = int(time_c/t_bin) TempTrace += emptybins*[0] time_c -= emptybins*t_bin # Equivalent to: # time_c = int(time_c)%int(t_bin) phot_c += 1 NewFile.write(outdtype(TempTrace)) del TempTrace NewFile.close() return outfile def FitExp(times, trace): """ Fit an exponential function to the given trace. Parameters ---------- times : ndarray of length N x-values trace : ndarray of length N y-values Returns ------- parameters, function """ # Set starting parameters for exponential fit expfunc = lambda p, x: p[0]*np.exp(-x/p[1]) # parms = [ampl, decaytime] parms = np.zeros(2, dtype=np.float32) ltr = len(trace) border = np.int(np.ceil(ltr/50.)) parms[0] = 1.*trace[:border].mean() parms[1] = times[-1]/np.log(parms[0]) # Fit function is an exponential # Function to minimize via least squares # f_min = lambda p, x: expfunc(np.abs(p), x) - trace def f_min(p,x): p = np.abs(p) return expfunc(np.abs(p), x) - trace # Least squares popt, chi = spopt.leastsq(f_min, parms[:], args=(times)) return np.abs(popt), expfunc def FitGaussian(amplitudes, frequencies, argmax): # Set starting parameters for gaussian fit # parms = [freq, ampl, sigma] parms = np.zeros(3, dtype=np.float32) parms[0] = frequencies[argmax] parms[1] = amplitudes[argmax] parms[2] = abs(frequencies[1]-frequencies[2])*2 # Fit function is a gaussian gauss = lambda p, x: np.exp(-((x-p[0])/p[2])**2 / 2) * p[1]/(p[2]*np.sqrt(2*np.pi)) # Function to minimize via least squares f_min = lambda p, x: gauss(p, x) - amplitudes # Least squares popt, chi = spopt.leastsq(f_min, parms[:], args=(frequencies)) return np.abs(popt), gauss @cython.cdivision(True) @cython.boundscheck(False) # turn of bounds-checking for entire function def OpenDat(filename, callback=None, cb_kwargs={}): """ Load "Flex02-12D" correlator.com files We open a .dat file as produced by the "Flex02-12D" correlator in photon history recorder mode. The file contains the time differences between single photon events. Parameters ---------- filename : str Path to file callback : callable or None Callback function to be called throughout the algorithm. If the return value of `callback` is not None, the function will abort. Number of function calls: 3 cb_kwargs : dict, optional Keyword arguments for `callback` (e.g. "pid" of process). Returns ------- system_clock, datData The system clock in MHz and the photon time event stream. Returns (None, None) if the progress was aborted through the callback function. Notes ----- Raw data file format (taken from manual): 1. The file records the difference in system clock ticks (1/60 us) between photon event. 2. The first byte identifies the format of the file 8 : 8 bit, 16: 16 bit 3. The second byte identifies the system clock. 60MHz. 4. The time unit is 1/system clock. 5. 16 bit format. Each WORD (2 bytes) represents a photon event, time = WORD/system clock, unless the value is 0xFFFF, in which case, the following four bytes represent a photon event. 6. 8 bit format: Each BYTE represents a photon event unless the value is 0xFF, in which case, the BYTE means 255 clock ticks passed without a photon event. For example 0A 0B FF 08 means there are three photon events. The time series are 0x0A+1, 0x0B+1, 0xFF+8+1. """ cdef np.ndarray[DTYPEuint16_t] Data cdef np.ndarray[DTYPEuint32_t] datData cdef int i, N # open file File = open(filename, 'rb') # 1st byte: get file format # should be 16 - for 16 bit fformat = int(np.fromfile(File, dtype="uint8", count=1)) # 2nd byte: read system clock system_clock = int(np.fromfile(File, dtype="uint8", count=1)) if fformat == 8: # No 8 bit format supported warnings.warn('8 bit format not supported.') File.close() return system_clock, None elif fformat == 32: # (There is an utility to convert data to 32bit) datData = np.fromfile(File, dtype="uint32", count=-1) File.close() return system_clock, datData elif fformat == 16: pass else: warnings.warn("Unknown format: {} bit".format(fformat)) File.close() return system_clock, None # In case of 16 bit file format (assumed), read the rest of the file in # 16 bit format. # Load bunch of Data Data = np.fromfile(File, dtype="uint16", count=-1) File.close() # Now we need to check if there are any 0xFFFF values which would # mean, that we do not yet have the true data in our array. # There is 32 bit data after a 0xFFFF = 65535 if callback is not None: ret = callback(**cb_kwargs) if ret is not None: return None, None occurences = np.where(Data == 65535)[0] N = len(occurences) if callback is not None: ret = callback(**cb_kwargs) if ret is not None: return None, None # Make a 32 bit array datData = np.uint32(Data) datData[occurences] = np.uint32(Data[occurences+1]) + np.uint32(Data[occurences+2])*65536 if callback is not None: ret = callback(**cb_kwargs) if ret is not None: return None, None # Now delete the zeros zeroids = np.zeros(N*2) zeroids[::2] = occurences + 1 zeroids[1::2] = occurences + 2 datData = np.delete(datData, zeroids) del Data return system_clock, datData def ReduceTrace(trace, deltat, length): """ Shorten an array by averaging. Given a `trace` of length `len(trace)`, compute a trace of length smaller than `length` by averaging. Parameters ---------- trace : ndarray, shape (N) Input trace that is to be averaged. deltat : float Time difference between bins in trace. length : int Maximum length of the new trace. Returns ------- newtrace : ndarray, shape (N,2) New trace (axis 1) with timepoints (axis 0). """ step = 0 while len(trace) > length: N = len(trace) if N % 2 != 0: N -= 1 trace = (trace[0:N:2] + trace[1:N:2]) / 2 step += 1 # Return 2d array with times T = np.zeros((len(trace), 2)) T[:,1] = trace/deltat/1e3 # in kHz T[:,0] = np.arange(len(trace))*deltat*2**step return T PyScanFCS-0.2.3/pyscanfcs/__init__.py000066400000000000000000000030611245330745300173550ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ When a membrane is scanned perpendicularly to its surface, the fluorescence signal originating from the membrane itself must be separated from the signal of the surrounding medium for an FCS analysis. PyScanFCS interactively extracts the fluctuating fluorescence signal from such measurements and applies a multiple-tau algorithm. The obtained correlation curves can be evaluated using PyCorrFit. Copyright (C) 2011-2012 Paul Müller This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ import multipletau import sys import warnings from . import doc from .SFCSnumeric import * try: from .main import Main except ImportError: print(sys.exc_info()) warnings.warn("Frontend of `pyscanfcs` will not be available."+\ " Reason: {}.".format(sys.exc_info()[1])) __version__ = doc.__version__ __author__ = "Paul Mueller" __email__ = "paul.mueller@biotec.tu-dresden.de" __license__ = "GPL v2" PyScanFCS-0.2.3/pyscanfcs/__main__.py000066400000000000000000000024401245330745300173360ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ When a membrane is scanned perpendicularly to its surface, the fluorescence signal originating from the membrane itself must be separated from the signal of the surrounding medium for an FCS analysis. PyScanFCS interactively extracts the fluctuating fluorescence signal from such measurements and applies a multiple-tau algorithm. The obtained correlation curves can be evaluated using PyCorrFit. Copyright (C) 2011-2012 Paul Müller This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ from . import doc from . import main from . import uilayer from . import SFCSnumeric ## VERSION version = doc.__version__ __version__ = version main.Main() PyScanFCS-0.2.3/pyscanfcs/doc.py000077500000000000000000000117251245330745300163740ustar00rootroot00000000000000# -*- coding: utf-8 -*- u""" PyScanFCS Module doc (C) 2012 Paul Müller This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ import csv import matplotlib import multipletau import numpy import os import platform import pyfits import scipy import sys try: import wx except: pass # The icon file was created with # img2py -i -n Main PyScanFCS_icon.png icon.py try: from . import icon except: pass from . import uilayer def GetLocationOfFile(filename): dirname = os.path.dirname(os.path.abspath(__file__)) locations = [ dirname+"/../", dirname+"/../pyscanfcs_doc/", dirname+"/../doc/", ] ## freezed binaries: if hasattr(sys, 'frozen'): try: adir = sys._MEIPASS + "/doc/" except: adir = "./" locations.append(os.path.realpath(adir)) for loc in locations: thechl = os.path.join(loc,filename) if os.path.exists(thechl): return thechl break # if this does not work: return None def GetLocationOfChangeLog(filename = "ChangeLog.txt"): return GetLocationOfFile(filename) def GetLocationOfDocumentation(filename = "PyScanFCS_doc.pdf"): """ Returns the location of the documentation if there is any.""" return GetLocationOfFile(filename) def description(): return u"""PyScanFCS is a data displaying and processing tool for perpendicular line scanning FCS utilizing correlator.com correlators. PyScanFCS is written in Python.""" def info(version): """ Returns a little info about our program and what it can do. """ textwin = u""" Copyright 2011-2012 Paul Müller, Biotec - TU Dresden Data processing for perpendicular line scanning FCS. """ textlin = u""" © 2011-2012 Paul Müller, Biotec - TU Dresden Data processing for perpendicular line scanning FCS. """ if (platform.system() != 'Linux'): texta = textwin else: texta = textlin one = " PyScanFCS version "+version+"\n\n" lizenz = "" for line in licence().splitlines(): lizenz += " "+line+"\n" ret = one + lizenz + texta return ret def getMainIcon(pxlength=32): """ *pxlength* is the side length in pixels of the icon """ # Set window icon iconBMP = icon.getMainBitmap() # scale image = wx.ImageFromBitmap(iconBMP) image = image.Scale(pxlength, pxlength, wx.IMAGE_QUALITY_HIGH) iconBMP = wx.BitmapFromImage(image) iconICO = wx.IconFromBitmap(iconBMP) return iconICO def licence(): return u"""PyScanFCS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. PyScanFCS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ def SoftwareUsed(): """ Return some Information about the software used for this program """ text= "Python "+sys.version+\ "\n\nModules:"+\ "\n - matplotlib "+matplotlib.__version__+\ "\n - multipletau "+multipletau.__version__+\ "\n - NumPy "+numpy.__version__+\ "\n - PyFITS "+pyfits.__version__+\ "\n - SciPy "+scipy.__version__+\ "\n - uilayer "+uilayer.__version__+\ "\n - wxPython "+wx.__version__ if hasattr(sys, 'frozen'): pyinst = "\n\nThis executable has been created using PyInstaller." text = text+pyinst return text # Standard homepage HomePage = "http://pyscanfcs.craban.de/" # Changelog filename ChangeLog = "ChangeLog.txt" StaticChangeLog = GetLocationOfChangeLog(ChangeLog) # Check if we can extract the version try: clfile = open(StaticChangeLog, 'r') __version__ = clfile.readline().strip() clfile.close() except: __version__ = "0.0.0-unknown" # Github homepage GitChLog = "https://raw.github.com/paulmueller/PyScanFCS/master/ChangeLog.txt" GitHome = "https://github.com/paulmueller/PyScanFCS" GitWiki = "https://github.com/paulmueller/PyScanFCS/wiki" PyScanFCS-0.2.3/pyscanfcs/edclasses.py000077500000000000000000000062511245330745300175730ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ PyScanFCS Module edclasses Contains classes that we edited. Makes these classes more useful for us. (C) 2012 Paul Müller This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ import numpy as np from wx.lib.agw import floatspin # Float numbers in spin fields import wx class FloatSpin(floatspin.FloatSpin): def __init__(self, parent, digits=10, increment=.01, value=1.0): floatspin.FloatSpin.__init__(self, parent, digits=digits, increment = increment, value = value) self.Bind(wx.EVT_SPINCTRL, self.increment) #self.Bind(wx.EVT_SPIN, self.increment) #self.increment() def increment(self, event=None): # Find significant digit # and use it as the new increment x = self.GetValue() if x == 0: incre = 0.1 else: digit = int(np.ceil(np.log10(abs(x)))) - 2 incre = 10**digit self.SetIncrement(incre) class ChoicesDialog(wx.Dialog): def __init__(self, parent, dropdownlist, title, text): # parent is main frame self.parent = parent super(ChoicesDialog, self).__init__(parent=parent, title=title) # Get the window positioning correctly #pos = self.parent.GetPosition() #pos = (pos[0]+100, pos[1]+100) #wx.Frame.__init__(self, parent=parent, title=title, # pos=pos, style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT) #self.Filename = None ## Controls panel = wx.Panel(self) # text1 textopen = wx.StaticText(panel, label=text) btnok = wx.Button(panel, wx.ID_OK) btnabort = wx.Button(panel, wx.ID_CANCEL) # Dropdown self.dropdown = wx.ComboBox(panel, -1, "", (15, 30), wx.DefaultSize, dropdownlist, wx.CB_DROPDOWN|wx.CB_READONLY) self.dropdown.SetSelection(0) # Bindings self.Bind(wx.EVT_BUTTON, self.OnOK, btnok) self.Bind(wx.EVT_BUTTON, self.OnAbort, btnabort) # Sizers topSizer = wx.BoxSizer(wx.VERTICAL) topSizer.Add(textopen) topSizer.Add(self.dropdown) btnSizer = wx.BoxSizer(wx.HORIZONTAL) btnSizer.Add(btnok) btnSizer.Add(btnabort) topSizer.Add(btnSizer) panel.SetSizer(topSizer) topSizer.Fit(self) self.Show(True) def OnOK(self, event=None): self.SelcetedID = self.dropdown.GetSelection() self.EndModal(wx.ID_OK) def OnAbort(self, event=None): self.EndModal(wx.ID_CANCEL) PyScanFCS-0.2.3/pyscanfcs/icon.py000066400000000000000000000342451245330745300165560ustar00rootroot00000000000000#---------------------------------------------------------------------- # This file was generated by /usr/bin/img2py # from wx.lib.embeddedimage import PyEmbeddedImage Main = PyEmbeddedImage( "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABHNCSVQICAgIfAhkiAAAAAlw" "SFlzAAAMqAAADKgBt04g1gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoA" "ACAASURBVHic7Z17fFTVufe/ey6ZSUJCQrjfFBHQgor3HgUvaL3fz2tbz9u3x6PtEW94/Nj3" "VD3HxlhPtfb2aq2t1dZe31prraKotaKAWo6igMpFlDsCIQQSICGZzGWdP1ZGwszaM5PJzJ49" "M8/385lPcK+dvR8wv1/W5VnPspRSCIJQnngKHYAgCIVDDEAQyhgxAEEoY8QABKGMEQMQhDJG" "DEAQyhgxAEEoY8QABKGMEQMQhDJGDEAQyhgxAEEoY8QABKGMEQMQhDJGDEAQyhgxAEEoY8QA" "BKGMEQMQhDJGDEAQyhgxAEEoY8QABKGMEQMQygKryRpsNVmBQsfhNiypCiyUClaT5QE+D1wI" "TAVG9n5GAMHe29qAZmAHsA1YBMxTjepTxwN2AWIAQlFjNVlB4DK06M8HGrJ81PvAPOBZ1aiW" "5Cg81yMGIBQlVpPlBa4GGoFxOX78y8B/qEa1NMfPdR1iAEJRYTVZFvC/gG8DU/L4KgX8CbhL" "NaqP8/iegiIGIBQNVpM1Di3Kkx18bQS4D2hUjaUnFjEAoSiwmqxTgGfQE3qFYC7wFdWo9hXo" "/XlBDEBwPVaTdTXwKFCR6feM9FhM9Xho8Fg0WBb1lkUPsDumaFWKZqV4PxIl1L9QVgKXqka1" "rn/f5l7EAARXYzVZDwD/N5N7j/J6mOHz8g8+L4d50qe49ADLIlEWR6O8Ho6yKzMt7AYuUo1q" "cSY3ux0xAMG1WE3WHODBdPdN83qYHahgujf7vLYQ8HRPmN/1RNiXXhM7gBNVo9qS9QtdghiA" "4EqsJuss9HKcz+6eoZbFbcEKZvq8OXtvh1I80RPmqZ4IaZSxFJihGlVXzl5eACQVWHAdVpM1" "EXiKFOKf5vXwi+pgTsUPMMiyuDlQwT2VAYJWyluPA57I6csLgPQABFfRm6//HjqV18hFfh+3" "BSvw5zmWdbEYt3eF2B5LqZFvqEb1gzyHkjekByC4jdmkEP8Vfh+3OyB+gIkeD49WBRlupewK" "NFpN1lAHwskLYgCCa7CarGrgTrv2Y71ebglmvBKYE4ZYFvdVBlKtP9YAdzgWUI4RAxDcxL8B" "w00NIz0W91ZWkNsRf2ZM8Xr4ZmrjucFqssY4FU8uEQMQXIHVZNWTYr2/MRhgcOqueF451+/j" "XL/tnGQQ+JaD4eQMMQDBLVwDDDY1zPB5OWoAa/y54msV/lRzD9cW41xA4f9VBUFzkemiB7gu" "4MSUX3pGeSwuq7DtBXjR9QiKCjEAoeD0dv9nmNpm+b1MyCCt1yn+OXUv4ELnIskN7vmXFcqZ" "87BJ+pnls/2NWxDqLIvj7JOPzrWaLHcFnAYxAMENXGy66AdO9BZi3j81M+wNoA441cFQBowY" "gOAGjjZdPMbrpbJwE/+2nJo6/fhEp+LIBWIAghsYbbrohpl/E8MtixEeW2ca6WQsA8Wd/8JC" "2dBb1bfe1DbMXmQFp8E+J6FQFYuyQgxAKDSj7BpSiKzg1NvHJj0AQegHxu4/uNsAhogBCEJO" "KLX96EX19xEDEArNNruGVhfXqthtH9sOJ+MYKGIAQqHZbteQYZHOgpDCAJqdjGOgiAEIBUU1" "qhC60m4SO1NX4ikou+xjEwMQhH5iHAZ8GI05HUdGNMcULdIDEISc8b7xYjRKpwuHAW9Foqma" "33EqjlwgBiC4gedNFyPAOy7sBbwZtTWANuDvDoYyYMQABDfwMhA2NbwejjgcSmp2K8Vy+x7A" "y6pRpeweuA0f8C/owoYxIGrziaENubv309Xna+Kf+3ncmlDuqEa1x2qy3gBmJba9HomyNhbj" "cJfUBHgiFDY7lWaec5HkBl+fT66IoLtCfT+7e7+KOQh2PI/BABTwaCjM9yoDzkeUwNaY4nn7" "HkkYeMnBcHKCD3JeaNUHDOv9JLKfA2bQ1xj2oHsZQvnyBHAXMCSxYXEkyrJolGMLXBvg56Ee" "UgxIHlONyric6WYspdQN6KqmhSSGNoG+phD/ur+AcQkOYjVZ3wTuN7UNtywerw6mysHPK/PC" "Ee7r7rFr7gImqkZlm9TkViyl1L9xoBfgvjUX6AC29PnsKWw4Qr6wmqwqYB02G2qO8np4qCro" "yKlAfVkZjXHT/u5UY/8HVKP6pnMR5Q5LKfVdINFWVZ+vff8cM3wSr+d7FnQvB8xgM9oghBLB" "arJuBB62a7/E7+PfHTwdaKdSfL2zO9W+hD3AYcXY/Qc9Xjf1qayEr/0lip4MjCT8ORfj/Fr0" "2XHx8+PaOLiHIEOG4ubnwNeA6abGueEI3cA3gxXke1rwo2iMO7tC6TYl3VWs4gfdA3jAwfcp" "zMYQJXfDj13onsEW4FP0EqVQRFhN1nh0dmCd3T1TvB7uqwykO7gza14JR7i/uwfbUb/m16pR" "XZ2XABzC6RLGFrrYq2kYFzeEvsaQTa+hofdzLNpUdnJwDyHFUE5wCZOAylQ3rInGuLazm1uC" "FZzl82bdVU1kj1I8Hgrzl/QJSIuB63L02oJhKaW+jc4I9OLOzMAI0IPOIehhYD2FCLAeWAVs" "RJYeXYfVZJ2FzglIaQB9mezxMDvg56TU1XpT0qXgyXCYP/RE2J9+/8EW4ETVqIpq778JSyk1" "LeGah4MNIf41AFSglwwDhk8Q/T8t30OzMNoI4p9sDWE/8BGwmiIr4lCqZCP+vkzxejjV5+UU" "r5cpXk/aXkGXgnejURZHoiyMRNmT2cajFuA81aiWZROj2zAZwECpQB/yWNv7if+5htwnHYE2" "hHjvIEx2hrAL3Sv4CNiXu9CETBmo+BMZYllM9XposCyGeCyGWBY9ShcZ2aUUzbEYK6Ox/o4H" "lwOXqka1ORcxuoF8GIDtu4BqDjaF+NeqHL1DkWwI/f3+LWgz+CSL7xeyIEPxL0eX3LatIpxn" "/gRcrRpVSa0yOWkAqfCRbAx1pJgFzhDFgaFCN/3LUQgDa9FmsBl3JkkVPRmK/030ybs1wJPA" "aQ6EFqcHaFKN6jsOvtMx3GIAdgTQWWGjer/WDvB5YQ7sXuzPBGAHeniwCmgdYAxCL/0Rv2pU" "nyV8WU3WxcB/AUflMbwY8DugUTWqjXl8T0FxuwEkUs3BhjCQoUN8C3N/dyjuBFb2fmR3Y5Zk" "K/4+3+8BrgLuAQ7LcXjPAv+pGtXKHD/XdRSbASRSw8GGkM2mphgHzKA/Y/4e9Lj0vd7vFTLE" "arLOBuaSpfgTnuUHLuz9XECKg0ZSEAOWoPfzP6sa1YdZPKMoKXYDSKSOA2YwEnPCUSoiHBgi" "ZDpfEAE+AN5F9iWkJZfiNzzbQieAnQ9MRpvBqN6v9ej/VzvQRUjjn7eBF1Wj2tm/v0lpUGoG" "0BcLvbd8JHAIMLSf39/DATPIZAIwih4WLEF2LBrJp/gzeHcACKtG5Wjyl9VkjQGuAf43+pfE" "/1ON6l0nY0hFKRtAIrXARPR4sbof36fQY/1M5wti6AnDd7Cpd1+OFFL8hcJqso4DXiX59ONp" "bplfKCcD6MsItBkcQv+GCTF0BmEn6XsFCp1L8A46e6xsEfEn8WPVqOY4HJIRpzcDuYUdvZ+3" "gXFoMxhN+u3PHmAQugcRNwK7LqWFHodOBjb0vsv2HLxSRcRvxDW/dMvVAOJE0ZuCNqJXECag" "zSCpLl0C8azGKtIbAb3PnYDOMnwbnVhU8oj4bXncoXDSUq5DgHTUowV7GJnnGsSNIJPVg+1o" "I1ifVXRFgIjfltXAdNWo0pQacAYxgNRY6GWkw4BDyWy7dBfaCDI50aIZeI0iO08uHSJ+Wz4C" "zlSNyjX/v8UAMqcKXYZsMpntauxG5wWkMwIFfIgWRNFXLxLx2+I68YMYQDYE0EYwhcxWEEJo" "I0iXZdgFLELnEhQlIn5bXCl+EAMYCBXAEcDnev+cjh60EaQb+20F5lNkm45E/La4VvwgBpAL" "fOhhwVQyK2YRRhcdSWUEMWAZuu6cKyaLUiHit8XV4gcxgFziQReznEZmmYZdaCNItXzYASwA" "Ph5ocPlCxG+L68UPYgD5wINeQjyK9PULFNoE0lWZ2YReLWgbcHQ5RMRvS1GIH8QA8okFjAeO" "JvUPC+hhwV5STxRG0ZtJ3iazJca8IuK3pWjED2IATjEWbQTpdiTuR3f7Uw0L9gCvU8AkIhG/" "LUUlfhADcJrDgeNJXTo9hh4WpCsysg5tBHtzE1pmWE3WF4DnEPEnUnTiBzGAQhBAF62YnOa+" "MPq3farufhhtAityE1pqRPy2rAZmFZv4QQygkAwFTkYfY5aKTvSwINX241Xo3IG8lTEX8dtS" "tOIHMYBCE98yfBypswpj6K5+qlTh3cAL5CGBqFf8c0ldc1HEX4SIAbiDIHAC6avb9qCNwG5Y" "EEEPCXJW1FLEb0vRix/EANzGcODzpD8QZR96aGDHavQP8ICGBCJ+W1ajJ/yK/kxJMQD34UHv" "MTiG1MOCEHqS0G7JsA09JMiq2q2I35aSET+IAbiZKvSw4NAU98SAduz3C0TQqcQf9OfFIn5b" "Skr8IAZQDIxCrxakSitONyT4CP3DnXZjkYjflpITP4gBFAseYDqpi0kOeEgg4relJMUPYgDF" "xhhgBvaZhFkPCUT8tpSs+EEMoBipQh+PPTzFPemGBGuAv9FrFCJ+W0pa/CAGUKxY6CFBquOx" "0w0J2oG5VpN1LCJ+EyUvfsisyq3gPhS6YtCr2GcHBtDpxnblyur+tv5vd48bPO55RPyJlIX4" "QQyg2NkGPI99WXEP+pCTpApFCzYumPzKuleuu+KIKwKThkyye76Iv8SRIUBpYKHrDRyT4p7P" "hgQLNi6YPO+TedfGVMwHoJRi/ob5fLDjoLlBEX8ZIAZQWoxCrxLY7diLvbn5zaHPrXnun+Pi" "78viLYtZ/OliEPGXDWIApUcQvUowMrFhefPyCa+uf/Xy3V27vaGo+aTzDW0bVizctPCUXf++" "a1+e43QEEX9qxABKEwu9QjA9fmF58/IJ8zfMvzymYl6A9u52uiMHzx/WB+s3zDl5zmO1gdoV" "wItkds6haxHxp0cMoLQZAcxc3rx8al/xx9kb2sv+sC5I3Ef88a7BFnQBENefS2BCxJ8ZYgAl" "zl2v3XVGVEV/VF9ZbzwKvrOnE5/Hlyj+ODuBZ0idVOQ6RPyZIwZQwtzy8i2nvL7h9Ye8Hm/g" "zEPPZFTNqKR76oP1W6+adtVvqyuq7fYI7AH+jE4ccj0i/v4heQAlSlz8ChWIxCLM3zCfDe0b" "DrqnPli/9Z+O+qenqyuqvWjBWIZHDQa+TOrUY1eQofhXIeL/DDGAEqSv+OPXYirGG5veYPXO" "1cAB8Vf5q+Jj/AA6acj0M1EFfBF90Ikr6Yf4Z4n4DyAGUGKYxN+XJduWsL5t/ZoE8cfxY28C" "FcDlpC9n7jgi/uwRAygh0okfoNpfvXT2CbO/WuWvWmBziw9dqtw0aegFLkRnHboCEf/AEAMo" "ETIV/6MXP3r9MSOO2Q+sRVcQNq31e9E9AVNNQgs4G5iSg7AHhIh/4IgBlABZiD/OFnRdAFP1" "4PhGIrvdhOdRwDkBEX9uEAMocgYg/jgtwMuYjyi30CZg2i7sBS5FJxs5iog/d4gBFDE5EH+c" "NrQJ2B00WofZBPzAFaQ//jxniPhzixhAkZJD8cfpAF7C/mixOszDgUq0CSTVHMg1Iv7cIwZQ" "hORB/HFCwCvAdpv2eswTg4PRJpDq2PMBIeLPD2IARUYexR8ngj5peJOhzUIL0LREOAw9J+A1" "tA0IEX/+EAMoIua8NOfUPIs/Tgx4A9hqaPOghWj62RkLXIA5pTgrJL03v4gBFAlzXppz6oKN" "Cx50QPxxYugzBExzAvE8AdPPzyTgrBy8v7/ib8nFO8sNMYAioADijxNFDwf2GNp82G8gOho4" "ZSAvFvE7gxiAyymg+OOE0EI0PduP/VHmnyd1kVJbRPzOIQbgYlwg/jid9DlJKIEAehXAxCz6" "uXlIxO8sYgAuxUXij7MHLcyIoa0SqDFct4DzgXGZvEDE7zxiAC7EheKP04qeGFSmkNB1AxKJ" "pwynLCgi4i8MYgAuw8Xij7MNfW6AiVrMKcMVaBMwHkEm4i8cYgAuogjEH2cDsMSmrQ5zRmAN" "egfhQYj4C4sYgEsoIvHHWQ18aNNWhzll+DDg+Ph/iPgLjxiACyhC8cdZBnxsuB5PGTb9fM0E" "Ron43YEYQIEpYvHHeRvYbLjuwbw86Hlr81s3BH3B+aQW/0pE/HlHDKCAlID4Qa8ILMJ8RHmA" "hG3CS7cvHTv347m3nTvxXLsEItDinyXizz9iAAWiRMQfJwYsxJwtWENvHYGl25eO/ePKP86O" "xCKVE4dM5LhRx5meJeJ3EDGAAlBi4o8TQvcETNQta142Pi7++MWZ42cyctBBhxiL+B1GDMBh" "SlT8cVrQE4MHsXb32lF/XffX6/qKH8Dr8XLhpAsJeAMg4i8IYgAO0rSwaVoJiz/Oh+hkIQDW" "7l474vmPn/+S1/IGqyuSq4YNDg7msiMu24yIvyCIATjI/PXz/6XExR/nDWB/XPyRWCQAUFNR" "Q4X34LKCgyoGNf/ovB/9QjWq0YUItNwxHhkt5J75G+bXtXe32xbKKCHxA4R+/+Hvm1s6Wr4Z" "UZGDDK8uWEfr/lZiKsagikHNs0+Y/dNRg0Z1AKejew7SC3AQ6QE4xCljT9nr8/iMJatKTPzc" "u+jeI7/31ve+u2TbkqTcf4/lYXBwcKL4QW8augj7g0iEPCAG4BCV/srY2Nqxf068Xorif3rV" "049HVbT2w5YP2bovuaxgQ2VD600n3fTrPuKPUwec40igAgCWUmpaoYMoF3Z37fZ+45VvfGHl" "zpVfsSwrPGnIpL/cc8Y9f51QPyFU6NhyQV/xx68FvAEunnIxVX69U3hQxaDWL0370h+HBIfs" "B3ZjLjLyKvCBI0GXOWIAJcyKlhWVP1nyk5N3dOw4ZH94/9DuSPfQUDQ0NBKL1Hssz/4Kb0Vr" "wBdorfJV7aoN1DafM/GcJV895qvb0j85GZP44wyvHs65E8+lJlDTV/ygE4hae7/2JQL8Dm0Q" "Qh4RAygxfvP+b0a/8PELp3+679PTOkIdJylUv8bUAV9g7bCqYQunj5y+6I4ZdyyvDdQmijOJ" "VOKPc/LYkz994AsPPNdH/HFC6KPJEtkC/Kk/sQv9RwygRLhj/h3Hvb7h9Tmd4c7j09+dGT6P" "r3Vi/cTHHzr/oadG14w2nSCckfgD3sDab8/69rXnH37+scAYwy370HUHE3kR+Cir4IWMEAMo" "cu5/8/4pz3/8/C17Q3tn5usdfo9/2+eGfe6RRy585Pm+PYJMxd90ZtO1F066cDd6c9DFmEuH" "tZJcb7ATeALzPIGQA8QAipQVLSsqb37p5v9o3d96CTk8iScVAW9g/SVTLrnzW6d/a2UW4o8z" "HDiX5Jh7MI/5l6LrEAp5QAygCPnlsl+O+em7P32oO9Ldr5LbucDCCh1ad+hjm/ds/moW4o9z" "NDDdcL0d6E64ptATgjuzDlqwRQygyLjtldtOnr9+/vejKppqP/1BWMqDr2cIvnAd3p56/JFa" "op5uIhXtRP1thCt2EfPmbiUyjfhB559cTHLBkBha6IlVh7cBT+YsQOEzJBW4iLjyT1de9VHr" "R7eTQQKXJ1rFoPZjGNR2PNXtR+ONJG/EiaOsGN01n7Cvbhmd9csIVX6adYwBb2DtvbPuvea8" "w88zzezHiQH/jR4KHBQ2MAg9KdiX0cBU9I5BIYdID6BIuPrZqy94b/t73013nzdcQ8PWy6hv" "ORsrlp2/7x+8mp1jn6KrxlTuz54Mxd+XGehCoYmYJgS70BOCiUMEYQCIARQB33njO0c+ufLJ" "3yplv5PQEw3SsP0i6refjydqLL/fbzrqlrNz/FOEqjalvTcL8YM+J+BykisIh4Fdhvs/QGcJ" "CjlC9gK4nJfXvlz/9KqnH0wl/oru4Ryy8h4aPr08Z+IHGNQ+nUNX3MPgnaelvXdyw+Tf9lP8" "oH+bJxUQQRtCpeH6UcCIfr5DSIEYgItp6Wzx3b3g7h+FY+FRdvdU7T2S8SvvIbDflF8zcKyY" "j1HrrmP45qtA2f+4rNi54o773rzviCxesQbz8l8NyT+fFnA2Di17lgNiAC7mhnk3fClVZt+g" "thMYt/p2fGHTuZy5Zci2ixi97kbstKeUCj770bP/mcWjFXpCMJH4hGAiI9A9ASEHiAG4lPd3" "vF+1tm3tv9q1BzoPYfTaG7CUcws5ta2fZ9iWL9q27w/vP+b6edefkcWjWzEfMFKF+YShGZiH" "CEI/EQNwKXe9dtf/icaiQ0xtvnAd49bchidqOy2QNxq2XkJt6wzb9ne3vTunK9yVzc/VMvTG" "oERMyUZBIP3EhJAWMQAXsmDjgsGb9my62q599Nob8fU0OBjRwYxa/3Uqus3TEt2R7kmz580+" "P4vHhoD3DNf9mPcOTEXnBwgDQAzAhfxw8Q+/FFMx0/iXQe3TqdrzOadDOggr5mPolitt21e0" "rLg+y0evxZzya5oQBDgLmRAcEGIALqS5o3mWucVKKTwnqd11EoHOQ4xtPdGeQ364+IeHZ/no" "/yY5FdhCm0Aiw4ApWb5HQAzAdTy35rmhXZEu46/4mt0nEew81OGI7LBSTggu2rQo2zF6G/ro" "8UQqMRcMPSnL9wiIAbiOp1Y+NRObbm1dyxnOBpOGQe3H4OsxH/Db3NF8+gAe/T725wwmMhSY" "OIB3lTViAC5j857NRuF4ogGq9hZ27J+MxaB2065e6Ax3Tl+wcYHpePBMCAPvGq77MfcCTs7y" "PWWPGIDL2Bfad4LpetWeo7Pe3JNPBrUZT/gF8Pxx5R+PHcCjN2KeEDRNjo4EzBMSQkrEAFzE" "5j2bK6IqavytWb3XnXu2qvZOtW1r62obNsDHm0qDV2BODpJeQBaIAbiIRZsW2S7u+0OFW/dP" "hScawBM11xroDHcONOitmPcJmHoBY5G8gH4jBuAi1u5eO9SuzduTcQEgx/H3mIf6XeEu279P" "P/jQcC2AuZiN9AL6iRiAi2juaLYVjD/sXgPwhs0GEIqGcmEAm4A9huumXsAEdNFRIUPEAFxE" "T7THNrnfijmf958pnphpSA5RlbPNCqZeQBDpBQwYMQAX0VDVYKqCA0Ckot3JUPpF2L/XeD3g" "Ddj+ffrJBpLrBAKYJh8mAcZNVEIyYgAuYnzt+Fa7tqi/v8V2nCPqN/XQIegL5soAFLDCcL0S" "fax4IpIdmCFiAC7iuNHH2RpAxEZkhUcRtekBVPmrbP8+WbAOc3agqRdwBMklxwUDYgAu4tRx" "p+6zsIzHYHVXb3Q4mswIVW1FWVFjW22gNpcGEMNcFryK5J9jD3BiDt9dsogBuIyAL7DedL2z" "zlQ7s/CkimtKwxTj32UAfIy5LLipFzAV80qB0AcxAJcxrGrYItP1UOU2eoI7nA4nLfvqzQbg" "8/h23D7j9jU5fl0UWGW4buoFeAFjWrVwADEAl3H86OMX2rV1DHnHyVDSEqloo3vQJ8a2IZVD" "jEaWA9aQfFqwhbkXcDRSOzAlYgAu484Zd67werzGKf9do14k5nXPwTi7xjyHsmLGtikNU2yN" "bICEMdcLqCJ5G7UPOCZPcZQEYgAuo9JfGasP1ht/e0b9e2kb+bLTIRkJB1toH/6asc2yrNCt" "/3CrqdR3rvgIbQQHvRb7uQDBBjEAF3LymJOfsWvbNXoeUV+nk+EYaR3zjO3s//Cq4c9OGjIp" "d8cNJxNCDwUSMRUPHYxsErJFDMCF3H/2/UtrAjVvmtpi3v3smPCE0yEdREfdcvYMfcvYZllW" "6IYTb3jUgTBWoScF++JBbxRKxG2VVFyDGIBLuWjSRQ+RXBwTgL0Ni9k19i8OR6QJVX3KtkkP" "g83Yf0zNmN9fceQVpkIeuaYbvVEoEdOk32TMGYNljxiAS7lz5p2r64P1r9i17xz7Z/Y1LHEy" "JCL+fXw6+QfEvF3Gdo/l2XfHjDt+4WBI6wzXAiRPBgYxH0Ne9ogBuJirjrrqxx7LY1Ybiu0T" "H2Hv0HzOtR0gEtjFliPuIxxssb3nsPrDHjvtkNPMecH5oZnk9GALLfhEZBhgQAzAxVx/wvWb" "Thpz0p3YDAVinh62Hf4wreP+bHdLTuiq+YSN075FqNrU49bUBevmP3XlU7/KWxBmFGDKNjQN" "AyZgNoayRgzA5Tx28WOvjh88/uf2dyhaxzzD1sk/zvmGIWXFaB8xny1H/hcRv/125KAv+MnD" "Fzx8p9/jz58L2WMygAqSx/we9CYhoQ+WUsqd1SaFzwjHwtaZvzrzwT2hPWemus8TDVDffC5D" "tl+EN2Ku05cZir0N77Br7NOEKrelvNNredvnnDzny9cce83WAbxwoFxEcg2AfUDiemkz8P8d" "iahIEAMoEpZuX1o9+4XZT3RFuo5Md68nWkV989kMajuByo7DyPT4vEhFGx11y2kb8SqhDHYf" "WpbVfc5h59z4/XO+X+gc5SNJ3v0XQR87nsgT6NOHBMQAiopPdn8SuHbutfe2dbWdl+n3eMOD" "GdQ2nUDXOHzhwXjDg/GGa1DebiL+vUT8e4hUtNJZ92HvluPMevF+j3/7lVOvnHPHjDs+yvKv" "k0uCwJUkO90ukjMG3wbMSQxliBhAEXLJk5d8fUPbhpsp0Mm41f7qpXedftetF0660FSyu1Cc" "BYxJuLYfSFyV2As87khERYBMAhYhc78897EZ42fM8Vgex3OCh1UPe3ruVXOvdZn4wZwTYJr1" "r0WfISAgPYCi5pnVzwx7ZMkj17V0tvyjQuX13LAqf9UHM8bPeOgH5/zg7Xy+ZwB4gS+SfGpQ" "G3rvQF9WALZJVuWEGEAJ8Iulvxj7mw9+c9Purt3nk+NeXcAbWHvC6BMe+tlFP3s9l8/NE6cA" "hydc6wYS1zBDwKPoicKyRgyghPje37836W/r/nb5rq5dp/dEe8Zn+xyP5emsDdT+fdKQSa/8" "5IKfvFLprzQn/ruPEcC5hust6JqCfXkBXWKsrBEDKFEefufhQ1/b8Nrp2zu21+4qzQAABVJJ" "REFUz+yOdB8ajUUbbIYJymt59/i9/h31wfp3pg2ftvD2Gbe/N7x6eLH+dvxHkusC7CU5ZXg9" "8KwjEbkYMYAyIRwLW4s2LRr8fvP7Q7d3bK+vqajZP7lhcuusCbN2FbHYTRwLHJVwLYxeEuxL" "DPgZ5iKjZYMYgFBq1AKXGa7vJLl+wDzMhUXKBlkGFEqNvZgzAE1LguPyHIvrEQMQShG7DUKJ" "iAEUOgBByANbDNdMBlAP1OQ5FlcjBiCUIp1AR8I1i+QkISjzXoAYgFCqbDdcM/UCss6XKAXE" "AIRSpdlwzVQxWHoAglCCmAzAT/IOyhqgLv/huBMxAKFU6QISa6TJPEACYgBCKWPqBcg8QB/E" "AIRSRuYB0iAGIJQymc4DVAEN+Q/HfYgBCKVMCHMBUBkG9CIGIJQ6mc4DlOUwQAxAKHUyTQga" "S4GKrBYSMQCh1DEdZmiaBwgCw/IfjrsQAxBKnR7M24NlHgAxAKE8kOVAG8QAhHIg04nAspsH" "EAMQyoEWks8885H88+8HBjsSkUsQAxDKAbuDQk1VkhNPGS5pxACEcsF0lJnJAOrzHYibEAMQ" "yoXEnYEgPQAxAKFsSDwlGPR5golID0AQShDpARjwHfmTI/+1LljXMqJ6xM6JQya2nH7I6S2X" "TLnE9I8lCMVMJ/pgkL6/9b3oZb++KwRV6ByBxBOFSxKLu5OWR7Asq8fv8e8MeAMtAV9gZ01F" "zdYTxpzw5sPnP/ze8OrhiaerCEKxcDHJXfxWkk8J/gPmPQQlh9EA7PB6vHuHVg5dNHX41Nfv" "PuPut2aOn9mZz+AEIcecDhyScK2d5PMBXwZWORJRgemXARz0jZYVHlE94sU7Z9758M0n3WzK" "tBIEtzEdODrhWgfJZwi8DbzlSEQFJutJQKWUv7mj+dJbXr7lhQkPTrht3ifzanMZmCDkgUxX" "AspmInDAqwBKqcDG9o1XX/qHS1+e+sjUa9buXmvKsRYEN2AygLJeCcjZMmBURWtW7Vx16/RH" "p//6saWPDc/VcwUhh2S6FFhHmWwKynkeQGdP57Qb5934h9kvzJ6a62cLwgAJo88L6ItFsg68" "QFkMafOSCBSOhYc/tvSxX5/xqzPOz8fzBWEAyDCgD3nLBIypWGDhpoUPTH1k6jX5eocgZIFk" "BPYh76nAq3auulV6AoKLkD0BfXBkL8Abm9/4tswJCC4h0yGAGECuiKlY4JfLfvmQrA4ILkCG" "AH1wbDdgOBYefutfb31Q8gSEAtMBxBKumYYA1ZiNoaRwdDtwZ0/ntEufvPQrTr5TEBJQJKf+" "gtkEqvIcS8FxvB7AmtY1X5O0YaHAJG7+AbMWgvkOpNA4bgBRFa256cWbvu70ewWhD6a9/iYt" "VOY7kEJTkIpAm/ZsuurH7/x4ZCHeLQhk3gMQA8gHSqnAd974zk2FeLcgYO4BmHL/ZQiQL3Z0" "7rjgjc1vVBfq/UJZIz2AXgpmAEop/90L7j61UO8XypoewzUxAKdZ2bLyzEK+XyhbZBWgl4Ia" "QGtX62ktnS2m9VdByCeyCtBLQQ0gGovW3vTSTccXMgahLJE5gF4KfjDIu1vfnVHoGISywzQH" "YFoFKPm09YIbwL6efWMKHYNQdmRaCbvkh6cFN4BQJDSs0DEIZYfpcBtTD0AMIN+EoiHZIiw4" "TeJuQBADKAzhWFh6AILTyBCgl4IbgFKqYu6auYMLHYdQdiQOA0w9gILrI9+44i+4cNNCGQYI" "TmMaBiTiocTPB3CFAazbvU4MQHAamQjEJQawo3OHzAMITpNJDwBK3ABcUfOsvbtdegCC09j1" "AFRvW/xT0kOA/wFd9Rqp2V9jXwAAAABJRU5ErkJggg==") getMainData = Main.GetData getMainImage = Main.GetImage getMainBitmap = Main.GetBitmap getMainIcon = Main.GetIcon PyScanFCS-0.2.3/pyscanfcs/main.py000077500000000000000000002551731245330745300165620ustar00rootroot00000000000000#!/usr/bin/python # -*- coding: utf-8 -*- u""" PyScanFCS Data processing for perpendicular line scanning FCS. (C) 2012 Paul Müller This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ from __future__ import print_function # TODO (Python3): # from __future__ import division # -> There is an integer division somewhere import csv import sys ## On Windows XP I had problems with the unicode Characters. # I found this at # http://stackoverflow.com/questions/5419/python-unicode-and-the-windows-console # and it helped (needs to be done before import of matplotlib): import platform if sys.version_info[0] == 2: reload(sys) sys.setdefaultencoding('utf-8') import os #import wx.lib.agw.pyprogress as PBusy # Busy Dialog import matplotlib matplotlib.use('WXAgg') import matplotlib.cm as cm # Color maps for plotting from matplotlib.figure import Figure from matplotlib.backends.backend_wxagg import \ FigureCanvasWxAgg as FigureCanvas, \ NavigationToolbar2WxAgg as NavigationToolbar from matplotlib.widgets import RectangleSelector, Button from matplotlib.patches import Rectangle import matplotlib.pyplot as plt import multipletau import numpy as np # NumPy import pyfits from scipy.fftpack import fft from scipy.fftpack import fftfreq # SFCSnumeric needs scipy.optimize # We import it here, so that pyinstaller packs it into the executable. # Pyinstaller does not neccessarily know that SFCSnumeric needs it. from scipy import optimize import tempfile import traceback import webbrowser import wx # GUI interface wxPython from wx.lib.agw import floatspin # Float numbers in spin fields from wx.lib.scrolledpanel import ScrolledPanel import zipfile # module import from . import edclasses from . import misc from . import doc # Documentation/some texts from . import SFCSnumeric from . import uilayer ######################################################################## class ExceptionDialog(wx.MessageDialog): """""" def __init__(self, msg): """Constructor""" wx.MessageDialog.__init__(self, None, msg, "Error", wx.OK|wx.ICON_ERROR) ######################################################################## class plotarea(wx.Panel): def __init__(self, parent, grandparent): wx.Panel.__init__(self, parent, -1, size=(500,500)) # plotting area self.grandparent = grandparent self.figure = Figure() self.canvas = FigureCanvas(self, -1, self.figure) self.axes = self.figure.add_subplot(111) #self.canvas.mpl_connect('button_press_event', self.on_pick) self.pdata = np.linspace(0,100,100) self.pdata.shape = (10,10) self.image = self.axes.imshow(self.pdata, interpolation='nearest', cmap=cm.gray, vmin=0, vmax=100) self.colorbar = self.figure.colorbar(self.image) #self.colorbar.set_ticks(np.arange(np.max(self.pdata)+1)) self.colorbar.set_label("Photon events", size=16) self.toolbar = NavigationToolbar(self.canvas) # Set selector: self.rs = None self.UseLineSelector() # Layout: self.vbox = wx.BoxSizer(wx.VERTICAL) self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.vbox.Add(self.toolbar, 0, wx.EXPAND) self.SetSizer(self.vbox) self.vbox.Fit(self) # Labels self.axes.set_ylabel("Scan cycle time [ms]",size=16) self.axes.set_xlabel("Measurement time [s]",size=16) def OnSelectPlot(self, eclick, erelease): self.grandparent.OnSelectPlot(eclick, erelease) def UseLineSelector(self): lineprops = dict(color='red', linestyle='-', linewidth = 2, alpha=0.5) del self.rs self.rs = RectangleSelector(self.axes, self.OnSelectPlot, drawtype='line', lineprops=lineprops) def UseRectangleSelector(self): del self.rs rectprops = dict(facecolor='white', edgecolor = 'red', alpha=0.2, fill=True) self.rs = RectangleSelector(self.axes, self.OnSelectPlot, drawtype='box', rectprops=rectprops) ######################################################################## class FFTmaxDialog(wx.Dialog): def __init__( self, parent, frequency, amplitude, size=wx.DefaultSize, pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE, useMetal=False, ): title="Find maximum of Fourier Transform" wx.Dialog.__init__(self, parent, -1, title, pos, size, style) # Dialog conent # Text result self.pnt = parent self.ampl = amplitude/np.max(amplitude) self.freq = frequency*self.pnt.system_clock*1e3 self.label = wx.StaticText(self, label=" Click into the plot twice to define the interval where to search for the \ maximum. \n The data achieved will automatically be updated within the main program.\ \n You may close this window, when you are finished.") # plotting area self.figure = Figure() self.canvas = FigureCanvas(self, -1, self.figure) self.axes = self.figure.add_subplot(111) self.axes.set_xlabel('Scan cycle [ms]') self.axes.set_ylabel('FFT signal') # We need x to be like that, because it represents the index of self.ampl #x = np.arange(len(self.ampl)) self.freq[0]=1 x = 1/self.freq self.image = self.axes.plot(x, self.ampl, '.', color="black") self.axes.set_xscale('log') self.axes.grid(True, which="major") self.axes.grid(True, which="minor") self.axes.yaxis.grid(False) self.toolbar = NavigationToolbar(self.canvas) self.canvas.mpl_connect('button_press_event', self.on_pick) #ipshell() #self.image.set_extent((self.freq[0], self.freq[1], np.min(self.ampl), np.max(self.ampl))) # Make the square or else we would not see much #self.plotarea.axes.set_aspect(1.*Tx/Ty) # Layout: self.vbox = wx.BoxSizer(wx.VERTICAL) self.vbox.Add(self.label, 0, wx.EXPAND) self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW) self.vbox.Add(self.toolbar, 0, wx.EXPAND) self.SetSizer(self.vbox) self.vbox.Fit(self) self.counter = 0 self.ymax = np.max(self.ampl) self.ymin = np.min(self.ampl) self.interval = [0, 0] self.red = False # Set window icon try: self.MainIcon = doc.getMainIcon() wx.Frame.SetIcon(self, self.MainIcon) except: self.MainIcon = None def on_pick(self, event): if ( event.inaxes == self.axes and self.toolbar.mode == "" ): # Let us draw some lines if self.counter == 0: self.line1 = self.axes.vlines(event.xdata, self.ymin, self.ymax, color='black') self.canvas.draw() self.counter = 1 elif self.counter == 1: self.line2 = self.axes.vlines(event.xdata, self.ymin, self.ymax, color='black') self.canvas.draw() self.counter = 2 elif self.counter == 2: self.line1._visible = False self.line1 = self.axes.vlines(event.xdata, self.ymin, self.ymax, color='black') self.canvas.draw() self.counter = 3 elif self.counter == 3: self.line2._visible = False self.line2 = self.axes.vlines(event.xdata, self.ymin, self.ymax, color='black') self.canvas.draw() self.counter = 2 # Transform time domain xdata to index for self.ampl newborder = 1/event.xdata # The time domain should have large enough discretization. self.interval[0] = np.argwhere( (self.freq >= newborder)*(newborder > np.roll(self.freq,1)))[0][0] self.interval[0], self.interval[1] = self.interval[1], self.interval[0] if self.counter >= 2: # Calculate maximum interval if self.red == True: self.redline._visible = False self.canvas.draw() self.red = True [start, stop] = [int(np.min(self.interval))-1, int(np.max(self.interval))+1] idx = np.argmax(self.ampl[start:stop])+start # We now have the maximum, but we actually want to have some # kind of a weighted maximum. For that we take k data points next # to the maximum and weigth them with their relative amplitude. k = 10 timeweights = list() timeweights.append(1/self.freq[idx]) Pie = 1 for i in np.arange(k): weighta = 1.*self.ampl[idx+i+1]/self.ampl[idx] weightb = 1.*self.ampl[idx-i-1]/self.ampl[idx] timeweights.append(weighta/self.freq[idx+i+1]) timeweights.append(weightb/self.freq[idx-i-1]) Pie = Pie + weighta + weightb print(sum(np.array(timeweights))/Pie, weighta, weightb) timeweights = np.array(timeweights) #print timeweights ltime = sum(timeweights)/Pie self.pnt.t_linescan = ltime*self.pnt.system_clock*1e3 #amplitudes = self.ampl[idx-k:idx+k] #frequencies = self.freq[idx-k:idx+k] self.redline = self.axes.vlines(ltime, self.ymin, self.ymax, color='red') ### Tried with gaussian fit #amplitudes = self.ampl[start:stop] #frequencies = self.freq[start:stop] #argmax = np.argmax(amplitudes) ## Get gaussian function and optimal parameters ## popt = [freq, ampl, sigma] ## gauss(popt, frequencies) #popt, gauss = SFCSnumeric.FitGaussian(amplitudes, frequencies, argmax) #self.pnt.t_linescan = 1./popt[0] #lenplot = 1000 #ids_plot = np.linspace(start,stop,lenplot, endpoint=False) #freq_plot = np.linspace(frequencies[0],frequencies[-1],lenplot, endpoint=False) #a = np.argmax(gauss(popt, freq_plot)) #self.pnt.t_linescan = 1./freq_plot[a] #self.redline = self.axes.plot(ids_plot, gauss(popt, freq_plot), '-', color='red') self.canvas.draw() # Plot the results # Set check box to True: "use cycle time" self.pnt.BoxPrebin[6].SetValue(True) self.pnt.Update() self.pnt.OnBinning_Prebin() ######################################################################## class MyFrame(wx.Frame): def __init__(self, parent, id, version): # GUI exceptions sys.excepthook = MyExceptionHook self.version = version wx.Frame.__init__(self, parent, id, "PyScanFCS " + self.version) self.CreateStatusBar() # A Statusbar in the bottom of the window ## Properties of the Frame if sys.platform == "darwin": initial_size = (1036,622) else: initial_size = (1024,595) #initial_size = (1024,768) self.SetSize(initial_size) self.SetMinSize(initial_size) # Set this, so we know in which directory we are working in. # This will change, when we load a data file. self.dirname = os.curdir self.filename = '' self.MakeMenu() ## Create the initial windows # When the user opens a file via file menu, the first 1e+6 datapoints # will be generated (binned) and plotted. We do not need to do this, # but it makes the program more transparent. Then we will need to find # the repetition time (time needed to scan one line) and bin the whole # thing accordingly and plot again. self.sp = wx.SplitterWindow(self, style=wx.SP_3DSASH) self.buttonarea = ScrolledPanel(self.sp) self.buttonarea.SetupScrolling(scroll_y=True) self.plotarea = plotarea(self.sp, self) self.pdata = np.linspace(0,1,100) self.pdata.shape = (10,10) #self.plotarea = wxmplot.ImagePanel(self.sp) #self.plotarea.display(self.pdata) self.MakeButtons() self.Layout() split = max(400, self.firhorz.GetMinSize()[0]+5) self.sp.SplitVertically(self.buttonarea, self.plotarea, split) self.Show() # Initial data values: # Time values are system clock ticks # System clock in MHz self.system_clock = None self.T_total = None self.t_linescan = None self.t_bin = None self.datData = None self.intData = None self.bins_per_line = None self.percent = 0. # correction factor for cycle time # A square displayed upon selection: self.square = None self.squareB = None # Coordinates of the square [(x1, x2), (y1,y2)] self.XY_Trace_square = [ (None, None), (None, None) ] self.XY_Trace_squareB = [ (None, None), (None, None) ] # List of absolute filenames that contain bleaching info self.file_bleach_profile = list() # Temporary filenames for binned intensity self.tempbintot = tempfile.mktemp("_binned_total.int") self.tempbinpar = tempfile.mktemp("_binned_partial.int") # We try to work with a cache to save time. self.cache = dict() # Each element of the cache is a filename connected to some data # cachetest = self.cache["testA.dat"] = dict() # cachetest["bins_per_line"] = self.bins_per_line # cachetest["linetime"] = self.t_linescan # cachetest["data"] = self.intData self.Update() # Set window icon try: self.MainIcon = doc.getMainIcon() wx.Frame.SetIcon(self, self.MainIcon) except: self.MainIcon = None def AddToCache(self, Data, cachename, background=False): if self.cache.keys().count(cachename) == 0: # Add the menu entry menu = self.cachemenu.Append(wx.ID_ANY, cachename, kind=wx.ITEM_RADIO) if background == False: # If True, do not activate new menu. menu.Check(True) # OnSelectCache plots the selected Cache element self.Bind(wx.EVT_MENU, self.OnSelectCache, menu) acache = dict() acache["data"] = 1*Data acache["bins_per_line"] = self.bins_per_line acache["linetime"] = self.t_linescan acache["dirname"] = self.dirname self.cache[cachename] = acache def Bin_All_Photon_Events(self, Data): """ Bin all photon events according to a binsize t_bin. """ eb = self.BoxPrebin[10].GetValue() # 10 spin: bin shift # The box contains bins per line self.bins_per_line = int(self.BoxPrebin[8].GetValue()) # t_bin in clock ticks t_bin = self.t_linescan/self.bins_per_line outdtype = np.uint16 outfile = self.tempbintot wxdlg = uilayer.wxdlg(parent=self, steps=100, title="Binning photon events...") print("Creating file {} ({})".format(outfile, outdtype.__name__)) SFCSnumeric.BinPhotonEvents(Data, t_bin, binshift=eb, outfile=outfile, outdtype=outdtype, callback=wxdlg.Iterate) wxdlg.Finalize() binneddata = np.fromfile(outfile, dtype=outdtype) if np.max(binneddata) < 256: #save memory binneddata = np.uint8(binneddata) return binneddata def Bin_Photon_Events(self, n_events=None, t_bin=None): """ Given an array of time differences *Data* [µs] between photon events, calculate the photon events that take place every *t_bin* in system clocks, where n_events is the number of events to use. """ # The box contains bins per line self.bins_per_line = int(self.BoxPrebin[8].GetValue()) # t_bin in clock ticks self.t_bin = t_bin outdtype = np.uint16 outfile = self.tempbinpar eb = self.BoxPrebin[10].GetValue() # 10 spin: bin shift Data = self.datData[:n_events] wxdlg = uilayer.wxdlg(parent=self, steps=100, title="Binning photon events...") print("Creating file {} ({})".format(outfile, outdtype.__name__)) SFCSnumeric.BinPhotonEvents(Data, t_bin, binshift=eb, outfile=outfile, outdtype=outdtype, callback=wxdlg.Iterate) wxdlg.Finalize() binneddata = np.fromfile(outfile, dtype=outdtype) if np.max(binneddata) < 256: # save memory binneddata = np.uint8(binneddata) return binneddata def CorrectLineTime(self, event): percent = np.float(self.linespin.GetValue()) if self.t_linescan is not None: # Set the new linetime self.t_linescan = np.float(self.t_linescan)*(1.+percent/100.) self.percent = percent self.UpdateInfo() def GetTotalTime(self): """ Sums over self.datData to find out the total time of the measurement. Sets variable self.T_total """ # Need to set float variable here, because uint32 are not # large enough. T_total in system clocks. self.T_total = np.sum(self.datData, dtype="float") self.Update() def GetTraceFromIntData(self, intData, coords, title="Trace"): """ region is a number describing the region the trace comes from (1 or 2) """ ## Get the data # Make sure we have the corners of the square for atuple in coords: if atuple[0] is None or atuple[1] is None: return [(x1,x2), (y1,y2)] = coords # Convert times to positions in 2D array x1 = np.floor(x1/self.t_linescan) x2 = np.ceil(x2/self.t_linescan) y1 = np.floor(y1/self.t_bin) y2 = np.ceil(y2/self.t_bin) bins_in_col = y2-y1 bins_in_row = x2-x1 ## Get some needed data # bin time for on line in s (used for multiple tau algorithm) bintime = self.t_linescan/self.system_clock/1e6 # Number of bins next to the maximum to use for the trace num_next_max = self.Spinnumax.GetValue() # We have to swap x and y, because we want to access # the array linewise later. traceData = np.zeros((bins_in_row, bins_in_col)) # We start from x1 (lowest time available) and # successively fill the traceData array: pos = x1*self.bins_per_line for i in np.arange(len(traceData)): traceData[i] = intData[pos+y1:pos+y2] pos = pos + self.bins_per_line ## Get the actual trace # Calculate trace from maximum traceDataMaxids = np.argmax(traceData, axis=1) newtraceData = np.zeros((len(traceDataMaxids), num_next_max*2+1)) for i in np.arange(len(traceData)): # We add to the new trace data array, such that the maximum of # each line is at the center of the array. maid = traceDataMaxids[i] # The array to be written to newtraceData nsli = np.zeros(num_next_max*2+1) nsli[num_next_max] = traceData[i][maid] for k in np.arange(num_next_max)+1: if maid+1-k >= 0: nsli[num_next_max-k] = traceData[i][maid-k] if maid+1+k <= len(traceData[i]): nsli[num_next_max+k] = traceData[i][maid+k] newtraceData[i] = nsli del traceDataMaxids if self.CheckBoxCountrateFilter.GetValue() is True: # "temporal detection profile" # We use this to find out how much time we spent in the membrane detprof = np.sum(newtraceData, axis=0) # Countrate correction: x = np.linspace(-num_next_max, +num_next_max, len(detprof)) popt, gauss = SFCSnumeric.FitGaussian(detprof, x, np.argmax(detprof)) # Time in bins, that the focus effectively was inside the membrane: # Go two sigmas in each direction. This way we have an averaged # cpp in the end. MembraneBins = 4*popt[2] LinetimeBins = self.bins_per_line #tracemean = np.mean(newtraceData) self.TraceCorrectionFactor=LinetimeBins/MembraneBins if self.MenuVerbose.IsChecked(): x2 = np.linspace(popt[0]-4*popt[2], popt[0]+4*popt[2], 100) plt.figure() plt.subplot(111) plt.plot(x, detprof, "-", label="Measured profile") plt.plot(x2, gauss(popt,x2), "-", label="Gaussian fit") plt.legend() text = "sigma = "+str(popt[2])+ " bins\n" +\ "residence time in bins: "+str(MembraneBins)+"\n" +\ u"residence time [µs]: "+str(MembraneBins*bintime*1e6/ self.bins_per_line) coords = (MembraneBins, np.max(detprof)/2.) plt.text(coords[0],coords[1],text) plt.xlabel("Bin position relative to maximum in cycle time") plt.ylabel("Sum of counted photons (whole trace)") plt.title(title + " - Determination of residence time in membrane") plt.show() else: self.TraceCorrectionFactor=1. # We could multiply newtraceData with self.TraceCorrectionFactor right # here, but we are not doing it, because it might introduce numerical # errors. This does not change statistics. In order to get the correct # countrate, we correct the traces, when they are binned for saving # in .csv files. newtraceData = np.sum(newtraceData, axis=1) traceData = newtraceData # Bleach filter? if self.CheckBoxBleachFilter.GetValue() is True: ltrb = len(traceData) ## Perform bleaching correction # fitted function: # f_i = f_0 * exp(-t_i/t_0) + offset # parms = [f_0, t_0, offset] # Corrected function: # F_c = F_i/(f_0*exp(-ti/(2*t_0))) + f_0*(1-f_0*exp(-t_i/(2*t_0))) # We don't want to subtract an offset from the trace? # The offset is actually background signal. popt, expfunc = SFCSnumeric.FitExp(np.arange(len(traceData)), traceData) [f_0, t_0] = popt newtrace = SFCSnumeric.ReduceTrace(traceData, bintime, length=500) # Full trace: ti = np.arange(ltrb) expfull = np.exp(-ti/(2*t_0)) # see formula above: traceData = traceData/expfull + f_0*(1-expfull) #### TODO: # Does this do anything? newtracecorr = SFCSnumeric.ReduceTrace(traceData, bintime, length=500) fitfuncdata = expfunc(popt, np.arange(ltrb)) newtracefit = SFCSnumeric.ReduceTrace(fitfuncdata, bintime, length=500) # Bleaching profile to temporary file # Create a temporary file and open it filename = tempfile.mktemp(".csv", "PyScanFCS_bleach_profile_{}_".format( title.replace(" ", "_"))) outfile = open(filename, 'wb') outfile.write("# This is not correlation data.\r\n") outfile.write("# {} - bleaching correction\r\n".format(title)) outfile.write("# I = ({:.2e})*exp[-t / (2*({:.2e})) ]\r\n".format(f_0,t_0)) outfile.write("# {}\t{}\t{}\t{}\r\n".format(u"Time t [s]", u"Measured trace [kHz]", u"Exponential fit I [kHz]", u"Corrected trace [kHz]")) dataWriter = csv.writer(outfile, delimiter='\t') # we will write xexp = newtrace[:,0] yexp = newtrace[:,1]*self.TraceCorrectionFactor yfit = newtracefit[:,1]*self.TraceCorrectionFactor ycorr = newtracecorr[:,1]*self.TraceCorrectionFactor data = [xexp, yexp, yfit, ycorr] for i in np.arange(len(data[0])): # row-wise, data may have more than two elements per row datarow = list() for j in np.arange(len(data)): rowcoli = str("%.10e") % data[j][i] datarow.append(rowcoli) dataWriter.writerow(datarow) outfile.close() self.file_bleach_profile.append(filename) if self.MenuVerbose.IsChecked(): def view_bleach_profile(e=None): ## Open the file if platform.system().lower() == 'windows': os.system("start /b "+filename) elif platform.system().lower() == 'linux': os.system("xdg-open "+filename+" &") elif platform.system().lower() == 'darwin': os.system("open "+filename+" &") else: # defaults to linux style: os.system("xdg-open "+filename+" &") # Show a plot #fig, ax = plt.figure() #ax = plt.subplot(111) fig, ax = plt.subplots() plt.subplots_adjust(bottom=0.2) plt.title(title + " - bleaching correction") plt.xlabel("Measurement time t [s]") plt.ylabel("approx. Intensity I [kHz]") plt.plot(xexp, yexp, '-', label = "Measured trace", color="gray") plt.plot(xexp, yfit, '-', label = "Exponential fit", color="red") plt.plot(xexp, ycorr, '-', label = "Corrected trace", color="blue") xt = np.min(xexp) yt = np.min(yexp) text = "I = ({:.2e})*exp[-t / (2*({:.2e})) ]".format(f_0,t_0) plt.text(xt,yt,text, size=12) plt.legend() plt.show() # We would like to have a button for the view_bleach_profile # function. Unfortunately, this does not work: #axgb = plt.axes([0.75, 0.05, 0.15, 0.05]) #buttonbleach = Button(axgb, 'view data') #buttonbleach.on_clicked(view_bleach_data) view_bleach_profile() return traceData def MakeButtons(self): minsize = (150,-1) dropminsize = (175,-1) ## Pre-binning prebox = wx.StaticBox(self.buttonarea, label="Pre-binning") presizer = wx.StaticBoxSizer(prebox, wx.VERTICAL) # Checkbox for later using the cycle time precheck = wx.CheckBox(self.buttonarea, label="Use cycle time") precheck.Bind(wx.EVT_CHECKBOX, self.Update) precheck.IsChecked = False presizer.Add(precheck) # Text bins per line prebplt = wx.StaticText(self.buttonarea, -1, "Bins per scan cycle:") presizer.Add(prebplt) # Bins per line self.prebpl = wx.SpinCtrl(self.buttonarea, -1, min=1, max=50000, value="70") self.prebpl.SetMinSize(minsize) presizer.Add(self.prebpl) # Text bins pretext = wx.StaticText(self.buttonarea, -1, "No. of events to use:") presizer.Add(pretext) # Spin bins prespin = wx.SpinCtrl(self.buttonarea, -1, min=100, max=500000000, value="1000") prespin.SetMinSize(minsize) presizer.Add(prespin) # Text tbin pretextt = wx.StaticText(self.buttonarea, -1, u"Bin width [µs]:") presizer.Add(pretextt) # Spin tbin prespint = edclasses.FloatSpin(self.buttonarea, value="5.0") prespint.SetMinSize(minsize) presizer.Add(prespint) # Text binfshift preshifttextt = wx.StaticText(self.buttonarea, -1, "Bin shift:") presizer.Add(preshifttextt) # Spin shift bins prespinshift = wx.SpinCtrl(self.buttonarea, -1, min=0, max=500000000, value="0") prespinshift.SetMinSize(minsize) presizer.Add(prespinshift) # Button prebutt = wx.Button(self.buttonarea, label="Calculate and plot") self.Bind(wx.EVT_BUTTON, self.OnBinning_Prebin, prebutt) presizer.Add(prebutt) self.BoxPrebin = list() self.BoxPrebin.append(prebox) # 0 box self.BoxPrebin.append(pretext) # 1 text: enter # events to use self.BoxPrebin.append(prespin) # 2 spin: how many bins to bin self.BoxPrebin.append(pretextt) # 3 text: enter bind width self.BoxPrebin.append(prespint) # 4 spin: bin time self.BoxPrebin.append(prebutt) # 5 button self.BoxPrebin.append(precheck) # 6 checkbox: use linetime self.BoxPrebin.append(prebplt) # 7 text: bins per line self.BoxPrebin.append(self.prebpl) # 8 spin: bins per line self.BoxPrebin.append(preshifttextt) # 9 text: bin shift self.BoxPrebin.append(prespinshift) # 10 spin: bin shift ## Total-binning binbox = wx.StaticBox(self.buttonarea, label="Total-binning") binsizer = wx.StaticBoxSizer(binbox, wx.VERTICAL) # Some informative text bintext = wx.StaticText(self.buttonarea, -1, "Bin entire file.") binsizer.Add(bintext) # OK button binbutt = wx.Button(self.buttonarea, label="Calculate and plot all") self.Bind(wx.EVT_BUTTON, self.OnBinning_Total, binbutt) binsizer.Add(binbutt) self.BoxBinTotal = [binbox, bintext, binbutt] ## Mode modebox = wx.StaticBox(self.buttonarea, label="Mode") modesizer = wx.StaticBoxSizer(modebox, wx.VERTICAL) # Some informative text bintext = wx.StaticText(self.buttonarea, -1, "Type of measurement.") modesizer.Add(bintext) # Dropdown mode selection Modelist = ["1 colour 1 focus", "2 colours 1 focus", "1 colour 2 foci", "2 colours 2 foci", "Alternating excitation"] self.ModeDropDown = wx.ComboBox(self.buttonarea, -1, "", (15, 30), wx.DefaultSize, Modelist, wx.CB_DROPDOWN) self.ModeDropDown.SetMinSize(dropminsize) self.ModeDropDown.SetSelection(0) self.Bind(wx.EVT_COMBOBOX, self.Update, self.ModeDropDown) modesizer.Add(self.ModeDropDown) # Save trace checkbox self.CheckBoxSaveTrace = wx.CheckBox(self.buttonarea, -1, label="Save raw traces") self.CheckBoxSaveTrace.SetValue(False) modesizer.Add(self.CheckBoxSaveTrace) ## Data infobox = wx.StaticBox(self.buttonarea, label="Data") insizer = wx.StaticBoxSizer(infobox, wx.VERTICAL) sclock = wx.StaticText(self.buttonarea, -1, "System clock [MHz]: \t \t") insizer.Add(sclock) totalt = wx.StaticText(self.buttonarea, -1, "Total time [s]: \t \t") insizer.Add(totalt) linet = wx.StaticText(self.buttonarea, -1, "Scan cycle [ms]:") insizer.Add(linet) linetdropdown = wx.ComboBox(self.buttonarea, -1, "", (15, 30), wx.DefaultSize, [], wx.CB_DROPDOWN) linetdropdown.SetMinSize(dropminsize) insizer.Add(linetdropdown) self.Bind(wx.EVT_COMBOBOX, self.OnLinetimeSelected, linetdropdown) self.Bind(wx.EVT_TEXT, self.OnLinetimeSelected, linetdropdown) # Do not change order of BoxInfo!! self.BoxInfo = [sclock, totalt, linetdropdown, infobox, linet] ## Scan cycle periodicity lscanbox = wx.StaticBox(self.buttonarea, label="Scan cycle periodicity") lscansizer = wx.StaticBoxSizer(lscanbox, wx.VERTICAL) # Magic checkbox lscanmagic = wx.CheckBox(self.buttonarea, label="Find automagically") lscanmagic.SetValue(True) lscansizer.Add(lscanmagic) # OK button lscanbutt = wx.Button(self.buttonarea, label="Find periodicity (FFT)") self.Bind(wx.EVT_BUTTON, self.OnFindLineScanTime, lscanbutt) lscansizer.Add(lscanbutt) self.BoxLineScan = [lscanbox, lscanmagic, lscanbutt] ## Image selection # Add radio buttons that change behavior of mouse in Plot userbox = wx.StaticBox(self.buttonarea, label="Image selection") usizer = wx.StaticBoxSizer(userbox, wx.VERTICAL) self.RbtnLinet = wx.RadioButton (self.buttonarea, -1, 'Scan cycle correction % +/-: ', style = wx.RB_GROUP) self.linespin = floatspin.FloatSpin(self.buttonarea, digits=10, increment=.001) self.linespin.SetMinSize(minsize) self.linespin.Bind(wx.EVT_SPINCTRL, self.CorrectLineTime) self.RbtnSelect = wx.RadioButton (self.buttonarea, -1, 'Select region 1') self.RbtnSelectB = wx.RadioButton (self.buttonarea, -1, 'Select region 2') self.RbtnLinet.SetValue(True) self.Bind(wx.EVT_RADIOBUTTON, self.OnRadioSelector, self.RbtnSelect) self.Bind(wx.EVT_RADIOBUTTON, self.OnRadioSelector, self.RbtnSelectB) self.Bind(wx.EVT_RADIOBUTTON, self.OnRadioSelector, self.RbtnLinet) # version 0.2.2: Add button "full measurement time" fullmeasbutt = wx.Button(self.buttonarea, label="Full measurement time") self.Bind(wx.EVT_BUTTON, self.OnSetFullMeasTime, fullmeasbutt) usizer.Add(self.RbtnLinet) usizer.Add(self.linespin) usizer.Add(self.RbtnSelect) usizer.Add(self.RbtnSelectB) usizer.Add(fullmeasbutt) self.BoxImageSelection = [userbox, self.RbtnLinet, self.linespin, self.RbtnSelect, self.RbtnSelectB, fullmeasbutt] ## Correlation corrbox = wx.StaticBox(self.buttonarea, label="Correlation") corrsizer = wx.StaticBoxSizer(corrbox, wx.VERTICAL) # Add switch for # how many bins next to a maximum should be used for the trace corrsizerText1 = wx.StaticText(self.buttonarea, label="Span +/-:") corrsizer.Add(corrsizerText1) self.Spinnumax = wx.SpinCtrl(self.buttonarea, -1, min=0, max=50000, value="3") self.Spinnumax.SetMinSize(minsize) corrsizer.Add(self.Spinnumax) # Add switch for slicing of trace corrsizerText3 = wx.StaticText(self.buttonarea, label="No. of trace slices:") corrsizer.Add(corrsizerText3) self.Spinslice = wx.SpinCtrl(self.buttonarea, -1, min=1, max=50000, value="10") self.Spinslice.SetMinSize(minsize) corrsizer.Add(self.Spinslice) # Trace # Switch for bleaching correction self.CheckBoxBleachFilter = wx.CheckBox(self.buttonarea, -1, label="Bleach filter") self.CheckBoxBleachFilter.SetValue(True) corrsizer.Add(self.CheckBoxBleachFilter) # Switch for countrate correction self.CheckBoxCountrateFilter = wx.CheckBox(self.buttonarea, -1, label="Countrate filter") self.CheckBoxCountrateFilter.SetValue(False) corrsizer.Add(self.CheckBoxCountrateFilter) # Add switch for m # m is the parameter that defines the number of channels # after which the the intensity trace is binned (neighboring # pixels are combined) for calculation of the # correlation function on a semi-logarithmic scale. corrsizerText2 = wx.StaticText(self.buttonarea, label=u"M.-τ parameter m:") corrsizer.Add(corrsizerText2) self.Spinm = wx.SpinCtrl(self.buttonarea, -1, min=16, max=50000, value="16") self.Spinm.SetMinSize(minsize) corrsizer.Add(self.Spinm) ## Multiple Tau # Get Autocorrelation function taubutt = wx.Button(self.buttonarea, label="Get correlation") self.Bind(wx.EVT_BUTTON, self.OnMultipleTau, taubutt) corrsizer.Add(taubutt) self.BoxMultipleTau = [self.CheckBoxBleachFilter, corrbox, corrsizerText3, corrsizerText1, self.Spinnumax, corrsizerText2, self.Spinm, self.Spinslice, taubutt, self.CheckBoxCountrateFilter] ## Set sizes firlist = [presizer, binsizer, modesizer] firmin = 100 for abox in firlist: firmin = max(abox.GetMinSize()[0], firmin) for abox in firlist: abox.SetMinSize((firmin, -1)) seclist = [corrsizer, usizer, lscansizer, insizer] secmin = 100 for abox in seclist: secmin = max(abox.GetMinSize()[0], secmin) for abox in seclist: abox.SetMinSize((secmin, -1)) ## Put everything together self.firvert = wx.BoxSizer(wx.VERTICAL) self.firvert.Add(presizer) self.firvert.AddSpacer(5) self.firvert.Add(binsizer) self.firvert.AddSpacer(5) self.firvert.Add(modesizer) self.secvert = wx.BoxSizer(wx.VERTICAL) self.secvert.Add(insizer) self.secvert.AddSpacer(5) self.secvert.Add(lscansizer) self.secvert.AddSpacer(5) self.secvert.Add(usizer) self.secvert.AddSpacer(5) self.secvert.Add(corrsizer) self.firhorz = wx.BoxSizer(wx.HORIZONTAL) self.firhorz.AddSpacer(5) self.firhorz.Add(self.firvert) self.firhorz.AddSpacer(5) self.firhorz.Add(self.secvert) self.buttonarea.SetSizer(self.firhorz) def MakeMenu(self): ## Setting up the menus. filemenu = wx.Menu() self.cachemenu = wx.Menu() prefmenu = wx.Menu() helpmenu = wx.Menu() # wx.ID_ABOUT and wx.ID_EXIT are standard IDs provided by wxWidgets. # filemenu menuOpenDat = filemenu.Append(wx.ID_OPEN, "&Open photon events .dat file", "Opens a correlator file (.dat) that contains photon arrival time differences") menuOpenFits = filemenu.Append(wx.ID_ANY, "Open .&fits file", "Opens a previously binned intensity file (.fits)") self.menuSaveDat = filemenu.Append(wx.ID_ANY, "Save 32 bit .&dat file", "Saves photon arrival time difference data in 32 bit file format") self.menuSaveFits = filemenu.Append(wx.ID_SAVE, "&Save .fits file", "Saves binned intensity data into a .fits file") filemenu.AppendSeparator() menuTest = filemenu.Append(wx.ID_ANY,"Create &artificial .dat file", "Create an artificial data set") filemenu.AppendSeparator() menuExit = filemenu.Append(wx.ID_EXIT,"E&xit", "Terminate the program") # prefmenu self.MenuVerbose = prefmenu.Append(wx.ID_ANY, "Verbose mode", "Enables/Disables output of additional information.", kind=wx.ITEM_CHECK) # Check by default self.MenuVerbose.Check() menuDocu = helpmenu.Append(wx.ID_ANY, "&Documentation", "PyCorrFit documentation") menuWiki = helpmenu.Append(wx.ID_ANY, "&Wiki", "PyCorrFit wiki pages by users for users (online)") menuUpdate = helpmenu.Append(wx.ID_ANY, "&Update", "Check for new version"+ " (Web access required)") helpmenu.AppendSeparator() menuSoftw = helpmenu.Append(wx.ID_ANY, "&Software used", "Information about software used by this program") menuAbout = helpmenu.Append(wx.ID_ABOUT, "&About", "Information about this program") # Creating the menubar. self.menuBar = wx.MenuBar() self.menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar self.menuBar.Append(self.cachemenu,"&Cache") self.menuBar.Append(prefmenu,"&Preferences") self.menuBar.Append(helpmenu,"&Help") self.SetMenuBar(self.menuBar) # Adding the MenuBar to the Frame content. ## Set events #File self.Bind(wx.EVT_MENU, self.OnMenuExit, menuExit) self.Bind(wx.EVT_MENU, self.OnOpenDat, menuOpenDat) self.Bind(wx.EVT_MENU, self.OnOpenFits, menuOpenFits) self.Bind(wx.EVT_MENU, self.OnSaveDat, self.menuSaveDat) self.Bind(wx.EVT_MENU, self.OnSaveFits, self.menuSaveFits) self.Bind(wx.EVT_MENU, self.OnMenuTest, menuTest) # Help self.Bind(wx.EVT_MENU, self.OnMenuAbout, menuAbout) self.Bind(wx.EVT_MENU, self.OnMenuUpdate, menuUpdate) self.Bind(wx.EVT_MENU, self.OnMenuSoftware, menuSoftw) self.Bind(wx.EVT_MENU, self.OnMenuDocumentation, menuDocu) self.Bind(wx.EVT_MENU, self.OnMenuWiki, menuWiki) def OnBinning_Prebin(self, event=None): """ Do prebinngin using *Bin_Photon_Events()* """ n_events = self.BoxPrebin[2].GetValue() if self.BoxPrebin[6].GetValue() == False: # from µs tp system clock ticks t_bin = self.BoxPrebin[4].GetValue() * self.system_clock ## If, reset previously achieved things. # - Why? # self.t_linescan = None self.Update() else: # Calculate t_bin through number of bins per line and cycle time self.bins_per_line = self.BoxPrebin[8].GetValue() t_bin = 1.0 * self.t_linescan / self.bins_per_line # First we need to reset the linetime correction to zero self.linespin.SetValue(0) # Calculate binned data self.intData = self.Bin_Photon_Events(n_events=n_events, t_bin=t_bin) # Add to cache self.AddToCache(self.intData, self.filename) # Then Plot the data somehow self.Update() self.PlotImage() def OnBinning_Total(self, event=None): if self.BoxPrebin[6].GetValue() == False: # from µs to system clock ticks t_bin = self.BoxPrebin[4].GetValue() * self.system_clock # If, reset previously achieved things self.t_linescan = None self.Update() else: # Calculate t_bin through number of bins per line and cycle time self.bins_per_line = self.BoxPrebin[8].GetValue() t_bin = 1.0 * self.t_linescan / self.bins_per_line self.t_bin = t_bin # First we need to reset the linetime correction to zero self.linespin.SetValue(0) # Calculate binned data self.intData = self.Bin_All_Photon_Events(self.datData) # Add to cache self.AddToCache(self.intData, self.filename) # Then Plot the data somehow self.PlotImage() def OnFindLineScanTime(self, event): """ Find the time that the confocal microscope uses to capture a line of data. This is done via FFT. """ # Fourier Transform cnData = fft(self.intData) N = len(cnData) # We only need positive/negative frequencies amplitude = np.abs(cnData[0:N/2]*np.conjugate(cnData[0:N/2])) #n_bins = len(self.intData) # Calculate the correct frequencies rate = 1./self.t_bin frequency = fftfreq(N)[0:N/2] * rate if self.BoxLineScan[1].GetValue() == True: # Find it automagically # The first big maximum is usually the second maximum idx = np.argmax(amplitude[10:])+10 # The first maximum is what we want ERROR idx2 = np.argmax(amplitude[10:idx-30])+10 # Sometimes the first one was ok. if 0.1*amplitude[idx] > amplitude[idx2]: idx2 = idx # We now have the maximum, but we actually want to have some # kind of a weighted maximum. For that we take k data points next # to the maximum and weigth them with their relative amplitude. k = 10 timeweights = list() timeweights.append(1/frequency[idx2]) Pie = 1 for i in np.arange(k): weighta = amplitude[idx2+i+1]/amplitude[idx2] weightb = amplitude[idx2-i-1]/amplitude[idx2] timeweights.append(weighta/frequency[idx2+i+1]) timeweights.append(weightb/frequency[idx2-i-1]) Pie = Pie + weighta + weightb timeweights = np.array(timeweights) ltime = np.sum(timeweights, dtype="float")/Pie self.t_linescan = ltime # Plot the results (not anymore, we do a low_prebin) #self.PlotImage() # Set Checkbox value to True: "use cycle time" self.BoxPrebin[6].SetValue(True) self.Update() self.OnBinning_Prebin() else: # Pop up a dialog with the fourier transform of the function # (log -plot) and let user decide which maximum to use. dlg = FFTmaxDialog(self, frequency, amplitude) dlg.Show() def OnLinetimeSelected(self, e=None): Dropdown = self.BoxInfo[2] Text = Dropdown.GetValue() test = Text.split(".", 1) for item in test: if not item.isdigit(): return Value = np.float(Text) #sel = Dropdown.GetSelection() elements = list() for factor in [0.25, 0.5, 1.0, 2.0, 4]: elements.append(str(np.float(Value*factor))) Dropdown.SetItems(elements) Dropdown.SetSelection(2) #self.dropdown.SetSelection(0) # Translate selected time to clockticks # Value = self.t_linescan*1e-3/self.system_clock if self.system_clock is None: sysclck = 60 else: sysclck = self.system_clock # Avoid making str to float conversion errors? # Use the second element, which is in the middle. (!!) self.t_linescan = np.float(elements[2])*1e3*sysclck self.BoxPrebin[6].Enable() #self.Update() def OnMenuAbout(self, event): # Show About Information description = doc.description() licence = doc.licence() info = wx.AboutDialogInfo() #info.SetIcon(wx.Icon('hunter.png', wx.BITMAP_TYPE_PNG)) info.SetName('PyScanFCS') info.SetVersion(self.version) info.SetDescription(description) info.SetCopyright(u'(C) 2012 Paul Müller') info.SetWebSite('http://pyscanfcs.craban.de') info.SetLicence(licence) info.AddDeveloper(u'Paul Müller') info.AddDocWriter(u'Paul Müller') wx.AboutBox(info) def OnMenuDocumentation(self, e=None): """ Get the documentation and view it with browser""" filename = doc.GetLocationOfDocumentation() if filename is None: # Now we have to tell the user that there is no documentation self.StatusBar.SetStatusText("...documentation not found.") else: self.StatusBar.SetStatusText("...documentation: "+filename) if platform.system().lower() == 'windows': os.system("start /b "+filename) elif platform.system().lower() == 'linux': os.system("xdg-open "+filename+" &") elif platform.system().lower() == 'darwin': os.system("open "+filename+" &") else: # defaults to linux style: os.system("xdg-open "+filename+" &") def OnMenuExit(self,e): # Exit the Program self.Close(True) # Close the frame. def OnMenuSoftware(self, event): # Show About Information text = doc.SoftwareUsed() wx.MessageBox(text, 'Software', wx.OK | wx.ICON_INFORMATION) def OnMenuTest(self, e=None): misc.ArtificialDataDlg(self) def OnMenuUpdate(self, event): misc.Update(self) def OnMenuWiki(self, e=None): """ Go to the GitHub Wiki page""" webbrowser.open(doc.GitWiki) def OnMultipleTau(self, e=None): """ Perform a multiple tau algorithm. We sneak in a plt.plot here and there so the user can take a look at the results. """ # Reset the bleaching profile self.file_bleach_profile = list() wx.BeginBusyCursor() ## Dirty, but makes it shorter. We need the namespace: def SaveAC(Gtype, traceData): for i in np.arange(num_traces): usedTrace = traceData[i*NM:(i+1)*NM] # Get the tail for the last trace if i == num_traces -1: usedTrace = traceData[i*NM:] # Calculate AC function and trace with human readable length G = multipletau.autocorrelate(usedTrace, m=m, deltat=bintime, normalize=True) if self.MenuVerbose.IsChecked(): plt.figure(0) plt.plot(G[:,0], G[:,1], "-") ## Correction that finds the correct countrate # self.TraceCorrectionFactor is 1.0, if the user # did not check the "countrate filter" usedTrace = usedTrace*self.TraceCorrectionFactor trace = SFCSnumeric.ReduceTrace(usedTrace, bintime, length=700) # Save Correlation function csvfile = filenamedummy+"_"+Gtype+"_"+str(i+1)+".csv" self.SaveCSVFile(G, trace, csvfile, i+1, num_traces, Type=Gtype) Arc.write(csvfile) os.remove(csvfile) def SaveCC(Gtype, tracea, traceb, swaptraces): for i in np.arange(num_traces): usedTa = tracea[i*NM:(i+1)*NM] usedTb = traceb[i*NM:(i+1)*NM] # Get the tail for the last trace if i == num_traces -1: usedTa = tracea[i*NM:] usedTb = traceb[i*NM:] G = multipletau.correlate(usedTa, usedTb, m=m, deltat=bintime, normalize=True) if self.MenuVerbose.IsChecked(): plt.figure(0) plt.plot(G[:,0], G[:,1], "--") ## Correction that finds the correct countrate # self.TraceCorrectionFactor is 1.0, if the user # did not check the "countrate filter" usedTa = usedTa*self.TraceCorrectionFactor usedTb = usedTb*self.TraceCorrectionFactor tra = SFCSnumeric.ReduceTrace(usedTa, bintime, length=700) trb = SFCSnumeric.ReduceTrace(usedTb, bintime, length=700) # In order to keep trace1 trace1 and trace2 trace2, we # need to swap here: if swaptraces == True: tra, trb = trb, tra # Save Correlation function csvfile = filenamedummy+"_"+Gtype+"_"+str(i+1)+".csv" self.SaveCSVFile(G, tra, csvfile, i+1, num_traces, Type=Gtype, secondtrace=trb) Arc.write(csvfile) os.remove(csvfile) ## Get some needed data # bin time in s (for the correlation function) bintime = self.t_linescan/self.system_clock/1e6 # m value for multiple tau algorithm m = self.Spinm.GetValue() # Number of traces to slice the big trace into num_traces = self.Spinslice.GetValue() # Number of bins next to the maximum to use for the trace num_next_max = self.Spinnumax.GetValue() # Whether full traces should be saved in separate files save_trace = self.CheckBoxSaveTrace.GetValue() # Define zip file name # filenamedummy is a non-wildcard filename wildcards = ["A.dat", ".dat", "A.fits", ".fits"] filenamedummy = self.filename for card in wildcards: lwc = len(card) if self.filename[-lwc:] == card: filenamedummy = self.filename[:-lwc] zipfilename = os.path.join(self.dirname, filenamedummy)+".zip" OURMODE = self.ModeDropDown.GetSelection() # 0: 1 colour 1 focus A # 1: 2 colours 1 focus A+B # 2: 1 colour 1 foci A # 3: Quad A+B # 4: Pie A+B if OURMODE != 0 and OURMODE != 2: # Bin the second file or check for a .fits file if self.filename[-6:] == "A.fits": # Open fits file and load second intData filename = self.filename[:-6]+"B.fits" fits = pyfits.open(os.path.join(self.dirname, filename)) series = fits[0] intData2 = series.data # Set proper 1D shape for intdata length = self.intData2.shape[0] * self.intData2.shape[1] intData2.shape = length elif self.filename[-5:] == "A.dat": # Check if we have B.dat in the cache # # Open B.dat file filename = self.filename[:-5]+"B.dat" try: bcache = self.cache[filename] if (bcache["dirname"] != self.dirname or bcache["bins_per_line"] != self.bins_per_line or bcache["linetime"] != self.t_linescan): # We are in the wrong directory raise KeyError except KeyError: # Open B.dat and add to cache filenames = os.path.join(self.dirname, filename) wxdlg = uilayer.wxdlg(parent=self, steps=3, title="Importing dat file...") self.system_clock, self.datData = SFCSnumeric.OpenDat( filename, callback=wxdlg.Iterate) wxdlg.Finalize() # Bin to obtain intData2 intData2 = self.Bin_All_Photon_Events(datData2) # Add to cache self.AddToCache(intData2, filename, background=True) else: intData2 = 1*bcache["data"] else: # We should not be here. print("No A.dat or A.fits file opened. Aborting.") return # Start plotting? if self.MenuVerbose.IsChecked(): plt.figure(0) axc = plt.subplot(111) # Create .zip archive Arc = zipfile.ZipFile(zipfilename, mode='w') returnWD = os.getcwd() tempdir = tempfile.mkdtemp() os.chdir(tempdir) ### 1 color 1 focus if self.ModeDropDown.GetSelection() == 0: traceData = self.GetTraceFromIntData(self.intData, self.XY_Trace_square) # Variable *SaveAC* will need. NM = int(np.floor(len(traceData)/num_traces)) traces = [traceData] ## Get autocorrelation functions of splitted trace Gtype = "AC_A1" SaveAC(Gtype, traceData) ### 2 colour 1 focus elif self.ModeDropDown.GetSelection() == 1: traceData1 = self.GetTraceFromIntData(self.intData, self.XY_Trace_square, title="Region A1") NM = int(np.floor(len(traceData1)/num_traces)) traceData2 = self.GetTraceFromIntData(intData2, self.XY_Trace_square, title="Region B1") ## Get autocorrelation functions of splitted trace traces = [traceData1, traceData2] # Save Autocorrelation for j in np.arange(len(traces)): traceData = traces[j] if j == 0: Gtype = "AC_A1" else: # j==1 Gtype = "AC_B1" SaveAC(Gtype, traceData) # Save Cross correlation for j in np.arange(len(traces)): if j == 0: Gtype = "CC_A1B1" tracea = traces[0] traceb = traces[1] swaptraces = False else: # j==1 Gtype = "CC_B1A1" tracea = traces[1] traceb = traces[0] swaptraces = True SaveCC(Gtype, tracea, traceb, swaptraces) ## 1 Colour 2 Foci elif self.ModeDropDown.GetSelection() == 2: traceData1 = self.GetTraceFromIntData(self.intData, self.XY_Trace_square, title="Region A1") NM = int(np.floor(len(traceData1)/num_traces)) traceData2 = self.GetTraceFromIntData(self.intData, self.XY_Trace_squareB, title="Region A2") ## Get autocorrelation functions of splitted trace traces = [traceData1, traceData2] # Save Autocorrelation for j in np.arange(len(traces)): traceData = traces[j] if j == 0: Gtype = "AC_A1" else: # j==1 Gtype = "AC_A2" SaveAC(Gtype, traceData) # Save Cross correlation for j in np.arange(len(traces)): if j == 0: Gtype = "CC_A1A2" tracea = traces[0] traceb = traces[1] swaptraces = False else: # j==1 Gtype = "CC_A2A1" tracea = traces[1] traceb = traces[0] swaptraces = True SaveCC(Gtype, tracea, traceb, swaptraces) ## Quad elif self.ModeDropDown.GetSelection() == 3: traceData1 = self.GetTraceFromIntData(self.intData, self.XY_Trace_square, title="Region A1") NM = int(np.floor(len(traceData1)/num_traces)) traceData2 = self.GetTraceFromIntData(self.intData, self.XY_Trace_squareB, title="Region A2") traceData3 = self.GetTraceFromIntData(intData2, self.XY_Trace_square, title="Region B1") traceData4 = self.GetTraceFromIntData(intData2, self.XY_Trace_squareB, title="Region B2") ## Get autocorrelation functions of splitted trace traces = [traceData1, traceData2, traceData3, traceData4] Gtypes = ["AC_A1", "AC_A2", "AC_B1", "AC_B2"] # Save Autocorrelation for j in np.arange(len(traces)): traceData = traces[j] Gtype = Gtypes[j] SaveAC(Gtype, traceData) # Save Cross correlation Gtypes = ["A1", "A2", "B1", "B2"] for j in np.arange(4): for k in np.arange(4): if j != k: Gtype = "CC_"+Gtypes[j]+Gtypes[k] tracea = traces[j] traceb = traces[k] if j < k: swaptraces = False else: swaptraces = True SaveCC(Gtype, tracea, traceb, swaptraces) ## PIE elif self.ModeDropDown.GetSelection() == 4: traceData1 = self.GetTraceFromIntData(self.intData, self.XY_Trace_square, title="Region A1") NM = int(np.floor(len(traceData1)/num_traces)) traceData2 = self.GetTraceFromIntData(intData2, self.XY_Trace_squareB, title="Region B2") ## Get autocorrelation functions of splitted trace traces = [traceData1, traceData2] # Save Autocorrelation for j in np.arange(len(traces)): traceData = traces[j] if j == 0: Gtype = "AC_A1" else: # j==1 Gtype = "AC_B2" SaveAC(Gtype, traceData) # Save Cross correlation for j in np.arange(len(traces)): if j == 0: Gtype = "CC_A1B2" tracea = traces[0] traceb = traces[1] swaptraces = False else: # j==1 Gtype = "CC_B2A1" tracea = traces[1] traceb = traces[0] swaptraces = True SaveCC(Gtype, tracea, traceb, swaptraces) # Add bleaching profile files for bleach_file in self.file_bleach_profile: olddir = os.getcwd() os.chdir(os.path.dirname(bleach_file)) try: Arc.write(os.path.basename(bleach_file)) except: pass os.chdir(olddir) Arc.close() os.chdir(returnWD) try: os.removedirs(tempdir) except: pass if self.MenuVerbose.IsChecked(): plt.figure(0) plt.semilogx() plt.ylabel('Correlation') plt.xlabel('Lag time [s]') plt.show() ## Save all the traces if save_trace == True: for i in np.arange(len(traces)): filename = filenamedummy + "_"+str(i)+".txt" filename = os.path.join(self.dirname, filename) openedfile = open(filename, 'wb') openedfile.write('# This file was created using PyScanFCS v.'+\ self.version+"\r\n") openedfile.write("# Source file: "+filenamedummy+"\r\n") openedfile.write("# linetime [s]: "+str(bintime)+"\r\n") openedfile.write("# bins per line: "+ str(self.bins_per_line)+"\r\n") openedfile.write("# bins used per line: "+ str(2*num_next_max+1)+"\r\n") for j in np.arange(len(traces[i])): openedfile.write(str(traces[i][j])+"\r\n") wx.EndBusyCursor() def OnOpenFits(self,e): # Open a data file """Import experimental data from a file.""" dlg = wx.FileDialog(self, "Choose a fits file", self.dirname, "", "FITS files (*.fits)|*.Fits;*.FITS;*.fits", wx.OPEN) # user cannot do anything until he clicks "OK" if dlg.ShowModal() == wx.ID_OK: # Workaround for Ubuntu 12.10 since 0.2.0 (self.dirname, self.filename) = os.path.split(dlg.GetPath()) #self.filename = dlg.GetFilename() #self.dirname = dlg.GetDirectory() fits = pyfits.open(os.path.join(self.dirname, self.filename)) series = fits[0] self.imgData = None self.intData = series.data self.datData = None # Set all variables head = series.header self.system_clock = head['SysClck'] try: self.T_total = head['Total'] except KeyError: self.T_total = None try: self.t_linescan = head['Tline'] except KeyError: # Old "line scanning time" has new name: "scan cycle time" self.t_linescan = head['Tcycle'] self.t_bin = head['Tbin'] try: eb = head['Binshift'] except KeyError: pass else: self.BoxPrebin[10].SetValue(eb) self.bins_per_line = len(self.intData[0]) self.prebpl.SetValue(self.bins_per_line) # Plot # Set proper 1D shape for intdata length = self.intData.shape[0] * self.intData.shape[1] self.intData.shape = length self.Update() self.PlotImage() #Current def OnOpenDat(self,e): # Open a data file """ We open a .dat file as produced by the "Flex02-12D" correlator in photon history recorder mode. The file contains the time differences between single photon events. Returns: This function makes the filename publicly available, bins a couple of events to get 1e+6 points and plots them into the plotting area (self.plotarea), using the Bin_Photon_Events() function. Raw data file format (taken from manual): 1. The file records the difference in system clock ticks (1/60 us) between photon event. 2. The first byte identifies the format of the file 8 : 8 bit, 16: 16 bit 3. The second byte identifies the system clock. 60MHz. 4. The time unit is 1/system clock. 5. 16 bit format. Each WORD (2 bytes) represents a photon event, time = WORD/system clock, unless the value is 0xFFFF, in which case, the following four bytes represent a photon event. 6. 8 bit format: Each BYTE represents a photon event unless the value is 0xFF, in which case, the BYTE means 255 clock ticks passed without a photon event. For example 0A 0B FF 08 means there are three photon events. The time series are 0x0A+1, 0x0B+1, 0xFF+8+1. """ # File Dialog dlg = wx.FileDialog(self, "Choose a data file", self.dirname, "", "DAT files (*.dat)|*.dat;*.daT;*.dAt;*.dAT;*.Dat;*.DaT;*.DAt;*.DAT", wx.OPEN) # user cannot do anything until he clicks "OK" if dlg.ShowModal() == wx.ID_OK: # Workaround for Ubuntu 12.10 since 0.2.0 (self.dirname, self.filename) = os.path.split(dlg.GetPath()) #self.filename = dlg.GetFilename() #self.dirname = dlg.GetDirectory() filename = os.path.join(self.dirname, self.filename) wxdlg = uilayer.wxdlg(parent=self, steps=3, title="Importing dat file...") self.system_clock, self.datData = SFCSnumeric.OpenDat( filename, callback=wxdlg.Iterate) wxdlg.Finalize() self.GetTotalTime() self.Update() def OnRadioSelector(self, e=None): # Define what style of selector will be used in plot. if self.RbtnLinet.Value == True: self.plotarea.UseLineSelector() else: self.plotarea.UseRectangleSelector() self.Update() def OnSaveFits(self,e): # Save the Data """ Save binned data as a 2d array (image) """ if self.filename[-4:] == ".dat": newfilename = self.filename[:-4]+".fits" else: newfilename = "" dlg = wx.FileDialog(self, "Choose a data file", self.dirname, newfilename, "FITS files (*.fits)|*.Fits;*.FITS;*.fits", wx.SAVE|wx.FD_OVERWRITE_PROMPT) # user cannot do anything until he clicks "OK" if dlg.ShowModal() == wx.ID_OK: # Workaround for Ubuntu 12.10 since 0.2.0 (self.dirname, newfilename) = os.path.split(dlg.GetPath()) #newfilename = dlg.GetFilename() #self.dirname = dlg.GetDirectory() # Creating image array M = len(self.intData) Ny = self.bins_per_line Nx = int(M/Ny)+1 # Plotting data will have some zeros at the end plotdata = np.zeros(Nx*Ny) # Check for maximum in self.intData maxint = np.max(self.intData) if maxint < 256: plotdata = np.uint8(plotdata) plotdata[0:M] = np.uint8(self.intData) else: plotdata[0:M] = self.intData plotdata.shape = (Nx,Ny) hdu = pyfits.PrimaryHDU(plotdata) hdulist = pyfits.HDUList([hdu]) header = hdulist[0].header # Add some constants: cards = [] cards.append(pyfits.Card('SysClck', self.system_clock, "System clock [MHz]")) if self.T_total is not None: cards.append(pyfits.Card('Total', self.T_total, "Total time in system clock ticks")) if self.t_linescan is not None: t_linescan = self.t_linescan else: t_linescan = self.t_bin*len(self.imgData) cards.append(pyfits.Card('Tcycle', t_linescan, "Time for each linescan in system clock ticks")) cards.append(pyfits.Card('Tbin', self.t_bin, "Time for each bin in system clock ticks")) eb = self.BoxPrebin[10].GetValue() cards.append(pyfits.Card('Binshift', eb, "Empty bins before actual binning of data")) for c in cards: c.verify() header.update(c.key, c.value, c.comment) # clobber=True: Overwrites file. hdulist.writeto(os.path.join(self.dirname, newfilename), clobber=True) def OnSaveDat(self,e): # Save the Data """ Save experimental data as 32bit format. Raw data file format: 1. The file records the difference in system clock ticks (1/60 us) between photon events. 2. The first byte identifies the format of the file: 32 bit 3. The second byte identifies the system clock: usually 60MHz. 4. The time unit is 1/system clock. 5. 32 bit format. 4 bytes represent a photon event, time = 4 bytes/system clock """ # Make a reasonable 32bit filename if self.filename[-5:] == "A.dat": newfilename = self.filename[:-5]+"_32bit_A.dat" elif self.filename[-5:] == "B.dat": newfilename = self.filename[:-5]+"_32bit_B.dat" else: newfilename = self.filename[:-4]+"_32bit.dat" dlg = wx.FileDialog(self, "Choose a data file", self.dirname, newfilename, "DAT files (*.dat)|*.dat;*.daT;*.dAt;*.dAT;*.Dat;*.DaT;*.DAt;*.DAT", wx.SAVE|wx.FD_OVERWRITE_PROMPT) # user cannot do anything until he clicks "OK" if dlg.ShowModal() == wx.ID_OK: # Workaround for Ubuntu 12.10 since 0.2.0 (self.dirname, newfilename) = os.path.split(dlg.GetPath()) #newfilename = dlg.GetFilename() #self.dirname = dlg.GetDirectory() NewFile = open(os.path.join(self.dirname, newfilename), 'wb') newformat = np.uint8(32) newclock = np.uint8(self.system_clock) NewFile.write(newformat) NewFile.write(newclock) self.datData.tofile(NewFile) NewFile.close() def OnSelectPlot(self, eclick, erelease): # Define what will happen upon clicking on the plot. if self.RbtnLinet.Value == True: self.OnSelectLineTime(eclick, erelease) else: self.OnSelectRegion(eclick, erelease) self.Update() def OnSelectCache(self, e=None): for item in self.cachemenu.GetMenuItems(): if item.IsChecked(): cachename = item.GetLabel() cache=self.cache[cachename] self.BoxPrebin[8].SetValue(cache["bins_per_line"]) self.bins_per_line = cache["bins_per_line"] linetime = cache["linetime"] if linetime is not None: self.BoxInfo[2].SetValue(str(linetime/self.system_clock/1e3)) self.t_linescan = linetime self.intData = 1*cache["data"] self.filename = cachename self.dirname = cache["dirname"] filename = os.path.join(self.dirname, self.filename) wxdlg = uilayer.wxdlg(parent=self, steps=3, title="Importing dat file...") self.system_clock, self.datData = SFCSnumeric.OpenDat( filename, callback=wxdlg.Iterate) wxdlg.Finalize() self.GetTotalTime() self.Update() self.PlotImage() def OnSelectLineTime(self, eclick, erelease): y1 = eclick.ydata y2 = erelease.ydata Tx1 = eclick.xdata Tx2 = erelease.xdata if Tx1 == Tx2: return # Since x and y ahve different scales, we need to # multiply the y-part with 1e3 to get ms instead of s. # # See in PlotImage below: #Tx = self.t_bin*Nx/self.system_clock/1e3 #Ty = Tx*Ny/1e3 # x1 = 1e3*Tx1 x2 = 1e3*Tx2 if x1 > x2: y2, y1 = y1, y2 x1, x2 = x2, x1 # Calculate correction factor delta = (y2-y1)/(x2-x1) # Calculate how much percent that is percent = delta*100. self.linespin.SetValue(np.float(percent)) self.percent = percent self.CorrectLineTime(event=None) def OnSelectRegion(self, eclick=None, erelease=None, fullMT=False): """ Internally sets the region in the kymograph `eclick` and `erelease` are matplotlib events on a plot if `fulMT` is True and `eclick` and `erelease` are None, then the x-values are overridden and old y-values are used. """ if eclick is None and erelease is None and fullMT is True: # try to get data from two sources: if self.RbtnSelect.Value == True: try: (y1,y2) = self.XY_Trace_square[1] # Line_time [ms] - convert to ms from (us and clock ticks) y1 /= 1e3 * self.system_clock y2 /= 1e3 * self.system_clock except: pass else: try: (y1,y2) = self.XY_Trace_squareB[1] # Line_time [ms] - convert to ms from (us and clock ticks) y1 /= 1e3 * self.system_clock y2 /= 1e3 * self.system_clock except: pass if (y1, y2) == (None, None): (y1, y2) = self.plotarea.axes.get_ylim() # Get absolute x values (x1, x2) = self.plotarea.axes.get_xlim() else: x1 = eclick.xdata x2 = erelease.xdata y1 = eclick.ydata y2 = erelease.ydata # Sort values if x1 > x2: x1, x2 = x2, x1 elif x1 == x2: x2 = x1+1 if y1 > y2: y1, y2 = y2, y1 elif y1 == y2: y2 = y1+1 # Set the values of the corresponding spin controls # To Do # We have to distinguish between yellow and cyan square. # self.square: yellow square # self.square2: cyan square if self.RbtnSelect.Value == True: square = self.square oldsquare = self.squareB square_color = "yellow" oldsquare_color = "cyan" oldcoords = self.XY_Trace_squareB else: square = self.squareB oldsquare = self.square square_color = "cyan" oldsquare_color = "yellow" oldcoords = self.XY_Trace_square # We should also plot it if square is not None: # Remove the old same coloured square square.remove() square = Rectangle( (x1,y1), abs(x2-x1), abs(y2-y1), alpha = 0.1, color=square_color) self.plotarea.axes.add_patch(square) # Adjust the old square: if oldsquare is not None: oldsquare.remove() oldsquare = None if oldcoords[1] == (None,None): (yn1, yn2) = (y1, y2) else: (yn1, yn2) = oldcoords[1] yn1 *= 1e-3/self.system_clock yn2 *= 1e-3/self.system_clock if self.ModeDropDown.GetSelection() > 1: oldsquare = Rectangle( (x1,yn1), abs(x2-x1), abs(yn2-yn1), alpha = 0.1, color=oldsquare_color) self.plotarea.axes.add_patch(oldsquare) self.plotarea.canvas.draw() # Convert values to array indices and make public. # Total_time [s] (convert to us and then to clock ticks) x1 = (x1*1e6 * self.system_clock) x2 = (x2*1e6 * self.system_clock) # Line_time [ms] (convert to us and then to clock ticks) y1 = (y1*1e3 * self.system_clock) y2 = (y2*1e3 * self.system_clock) if self.RbtnSelect.Value == True: self.square = square self.XY_Trace_square = [ (x1, x2), (y1,y2) ] self.squareB = oldsquare if oldsquare is not None: self.XY_Trace_squareB[0] = (x1, x2) else: self.squareB = square self.XY_Trace_squareB = [ (x1, x2), (y1,y2) ] self.square = oldsquare if oldsquare is not None: self.XY_Trace_square[0] = (x1, x2) def OnSetFullMeasTime(self, e=None): """ Sets the full range of the measurement time """ self.OnSelectRegion(fullMT=True) def PlotImage(self): """ Plot self.intData. If not enough information about e.g. cycle time is given we have to guess the dimensions of the plot. """ M = len(self.intData) self.bins_per_line = Ny = self.BoxPrebin[8].GetValue() Nx = int(np.floor(M/Ny)) # This checkbox is False, if we do not want to use t_linescan # to set the length of a line. if self.BoxPrebin[6].GetValue() == False: # from µs to system clock ticks t_bin = self.BoxPrebin[4].GetValue() * self.system_clock else: t_bin = self.t_linescan / self.bins_per_line # This is a fast way of slicing our 1D intData array to a shorter # plottable 2D array. if Nx > Ny: # Number of lines we have to jump over P = Nx/Ny Nx = P * Ny plotdata = np.zeros((Ny,Ny)) MAX = Nx*Ny for bin in np.arange(Ny): # Take every P'th element in Nx direction plotdata[bin] = self.intData[bin:MAX+bin:Ny*P] else: # We are lucky plotdata = self.intData[:Nx*Ny] plotdata.shape = (Nx,Ny) plotdata = plotdata.transpose() self.plotarea.image.set_data(plotdata) # Set labels x [ms] and y[s] Ty = self.t_bin*Ny/1e3/self.system_clock Tx = Ty*Nx/1e3 self.plotarea.image.set_extent((0, Tx, Ty, 0)) # Make the square or else we would not see much self.plotarea.axes.set_aspect(1.*Tx/Ty) vmin = np.min(plotdata) vmax = np.max(plotdata) self.plotarea.colorbar.set_clim(vmin, vmax) self.plotarea.colorbar.vmin = vmin self.plotarea.colorbar.vmax = vmax self.plotarea.colorbar.update_normal(self.plotarea.image) self.plotarea.colorbar.set_ticks(np.arange(vmax+1), update_ticks=True) self.plotarea.canvas.draw() self.imgData = plotdata def SaveCSVFile(self, G, trace, csvfile, num=1, num_traces=1, Type="AC", secondtrace=None): openedfile = open(csvfile, 'wb') openedfile.write('# This file was created using PyScanFCS v.'+\ self.version+"\r\n") openedfile.write("# Source file \t"+self.filename+"\r\n") openedfile.write("# Source slice \t"+str(num)+" of "+str(num_traces)+"\r\n") openedfile.write('# Channel (tau [s]) \t Correlation function \r\n') if Type[:2] == "CC": openedfile.write("# Type AC/CC \t Cross-Correlation "+Type[2:]+"\r\n") else: openedfile.write("# Type AC/CC \t Autocorrelation "+Type[2:]+"\r\n") dataWriter = csv.writer(openedfile, delimiter='\t') for i in np.arange(len(G)): dataWriter.writerow([str(G[i,0])+" \t", str(G[i,1])]) openedfile.write('# BEGIN TRACE \r\n') openedfile.write('# Time ([s]) \t Intensity Trace [kHz] \r\n') for i in np.arange(len(trace)): dataWriter.writerow([ str("%.10e")%trace[i,0], str("%.10e")%trace[i,1] ]) if secondtrace is not None: openedfile.write('#\r\n# BEGIN SECOND TRACE \r\n') openedfile.write('# Time ([s]) \t Intensity Trace [kHz] \r\n') for i in np.arange(len(trace)): dataWriter.writerow([ str("%.10e")%secondtrace[i,0], str("%.10e")%secondtrace[i,1] ]) openedfile.close() def Update(self, e=None): self.UpdateInfo() ### Box Prebin #self.BoxPrebin.append(prebox) # 0 box #self.BoxPrebin.append(pretext) # 1 text: enter # events to use #self.BoxPrebin.append(prespin) # 2 spin: how many bins to bin #self.BoxPrebin.append(pretextt) # 3 text: enter bin width #self.BoxPrebin.append(prespint) # 4 spin: bin time #self.BoxPrebin.append(prebutt) # 5 button #self.BoxPrebin.append(precheck) # 6 checkbox: use linetime #self.BoxPrebin.append(prebplt) # 7 text: bins per line #self.BoxPrebin.append(self.prebpl) # 8 spin: bins per line if self.datData is not None: self.menuSaveDat.Enable(True) for item in self.BoxPrebin: item.Enable() for item in self.BoxInfo: item.Enable() if self.t_linescan is not None: for item in self.BoxBinTotal: item.Enable() else: for item in self.BoxBinTotal: item.Disable() if self.t_linescan is not None: # This means a linetime has been found self.BoxPrebin[6].Enable() #self.BoxPrebin[6].SetValue(True) else: self.BoxPrebin[6].Disable() self.BoxPrebin[6].SetValue(False) checked = self.BoxPrebin[6].GetValue() if checked == True: self.BoxPrebin[3].Disable() self.BoxPrebin[4].Disable() else: self.BoxPrebin[3].Enable() self.BoxPrebin[4].Enable() # If no data is present, do not enable anything if self.datData is None: self.menuSaveDat.Enable(False) for item in self.BoxPrebin: item.Disable() for item in self.BoxBinTotal: item.Disable() for item in self.BoxInfo: item.Disable() ### Box scan cycle time / Image Selection / Save Fits if self.intData is None: self.menuSaveFits.Enable(False) for item in self.BoxLineScan: item.Disable() for item in self.BoxImageSelection: item.Disable() else: self.menuSaveFits.Enable(True) for item in self.BoxLineScan: item.Enable() for item in self.BoxImageSelection: item.Enable() ### Modes if self.ModeDropDown.GetSelection() > 1 and self.intData is not None: self.RbtnSelectB.Enable() else: self.RbtnSelectB.Disable() ### MultipleTau Box if self.square is None: for item in self.BoxMultipleTau: item.Disable() else: for item in self.BoxMultipleTau: item.Enable() def UpdateInfo(self): # Initial data values: if self.system_clock is not None: self.BoxInfo[0].SetLabel("System clock [MHz]: "+str(self.system_clock)) if self.T_total is not None: # This means a file has been opened self.BoxInfo[1].SetLabel("Total time [s]: "+ str(self.T_total*1e-6/self.system_clock)[0:10]) if self.t_linescan is not None: # This means a linetime has been found self.BoxInfo[2].SetValue(str(self.t_linescan*1e-3/self.system_clock)) self.OnLinetimeSelected() def MyExceptionHook(etype, value, trace): """ Handler for all unhandled exceptions. :param `etype`: the exception type (`SyntaxError`, `ZeroDivisionError`, etc...); :type `etype`: `Exception` :param string `value`: the exception error message; :param string `trace`: the traceback header, if any (otherwise, it prints the standard Python header: ``Traceback (most recent call last)``. """ frame = wx.GetApp().GetTopWindow() tmp = traceback.format_exception(etype, value, trace) exception = "".join(tmp) dlg = ExceptionDialog(exception) dlg.ShowModal() dlg.Destroy() wx.EndBusyCursor() ## VERSION version = doc.__version__ __version__ = version print(doc.info(version)) ## Start gui def Main(): app = wx.App(False) frame = MyFrame(None, -1, version) app.MainLoop() if __name__ == "__main__": Main() PyScanFCS-0.2.3/pyscanfcs/misc.py000066400000000000000000000331201245330745300165500ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ PyScanFCS Module misc (C) 2012 Paul Müller This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ from __future__ import print_function, division import codecs from distutils.version import LooseVersion # For version checking import numpy as np import os import platform import sys import tempfile import urllib2 import webbrowser import wx # GUI interface wxPython import wx.html import wx.lib.delayedresult as delayedresult from . import doc # Documentation/some texts # The icon file was created with # img2py -i -n Main PyScanFCS_icon.png icon.py from . import icon # Contains the program icon from . import edclasses class UpdateDlg(wx.Frame): def __init__(self, parent, valuedict): description = valuedict["Description"] homepage = valuedict["Homepage"] githome = valuedict["Homepage_GIT"] changelog = valuedict["Changelog"] pos = parent.GetPosition() pos = (pos[0]+100, pos[1]+100) wx.Frame.__init__(self, parent, wx.ID_ANY, title="Update", size=(250,180), pos=pos) self.changelog = changelog # Fill html content html = wxHTML(self) string = '' +\ " PyScanFCS
" +\ "Your version: " + description[0]+"
" +\ "Latest version: " + description[1]+"
" +\ "(" + description[2]+")

" if len(homepage) != 0: string = string + 'Homepage
' if len(githome) != 0: string = string + 'Repository
' if len(changelog) != 0: string = string + \ 'Change Log' string = string+'

' html.SetPage(string) self.Bind(wx.EVT_CLOSE, self.Close) # Set window icon ico = getMainIcon() wx.Frame.SetIcon(self, ico) def Close(self, event): if len(self.changelog) != 0: # Cleanup downloaded file, if it was downloaded if self.changelog != doc.StaticChangeLog: os.remove(self.changelog) self.Destroy() class wxHTML(wx.html.HtmlWindow): def OnLinkClicked(parent, link): webbrowser.open(link.GetHref()) class ArtificialDataDlg(wx.Frame): # This tool is derived from a wx.frame. def __init__(self, parent): self.parent = parent # Get the window positioning correctly pos = self.parent.GetPosition() pos = (pos[0]+100, pos[1]+100) wx.Frame.__init__(self, parent=self.parent, title="Create artificial test data", pos=pos, style=wx.DEFAULT_FRAME_STYLE|wx.FRAME_FLOAT_ON_PARENT) ## Content self.panel = wx.Panel(self) topSizer = wx.BoxSizer(wx.VERTICAL) topSizer.Add(wx.StaticText(self.panel, label="Create artificial test data\n"+ "with exponentially correlated noise.\n")) colsizer = wx.FlexGridSizer(4, 2) # decay time colsizer.Add( wx.StaticText(self.panel, label=u"Correlation time [ms]: ")) self.WXDecay = edclasses.FloatSpin(self.panel, value="100") colsizer.Add(self.WXDecay) # line scanning time colsizer.Add( wx.StaticText(self.panel, label=u"Scan cycle time [ms]: ")) self.WXLine = edclasses.FloatSpin(self.panel, value="0.714") colsizer.Add(self.WXLine) # number of samples colsizer.Add( wx.StaticText(self.panel, label=u"Number of samples: ")) self.WXNumber = wx.SpinCtrl(self.panel, -1, min=10000, max=500000000, value="500000") colsizer.Add(self.WXNumber) # data format colsizer.Add(wx.StaticText(self.panel, label="Data format: ")) self.WXDropInt = wx.ComboBox(self.panel, -1, "uint16", (15,30), wx.DefaultSize, ["uint16", "uint32"], wx.CB_DROPDOWN|wx.CB_READONLY) colsizer.Add(self.WXDropInt) topSizer.Add(colsizer) btndo = wx.Button(self.panel, wx.ID_CLOSE, 'Create .dat file') # Binds the button to the function - close the tool self.Bind(wx.EVT_BUTTON, self.OnCreateFile, btndo) topSizer.Add(btndo) self.panel.SetSizer(topSizer) topSizer.Layout() topSizer.Fit(self) #self.SetMinSize(colsizer.GetMinSizeTuple()) #Icon if parent.MainIcon is not None: wx.Frame.SetIcon(self, parent.MainIcon) self.Show(True) def OnClose(self, event=None): # This is a necessary function for PyCorrFit. # Do not change it. self.parent.toolmenu.Check(self.MyID, False) self.parent.ToolsOpen.__delitem__(self.MyID) self.Destroy() def OnCreateFile(self, e=None): linetime = self.WXLine.GetValue() taudiff = self.WXDecay.GetValue() N = self.WXNumber.GetValue() inttype = self.WXDropInt.GetValue() if inttype == "uint16": dtype = np.uint16 else: dtype = np.uint32 # file dialog filename = "test_tau{}ms_line{}ms_N{}_{}.dat".format( taudiff, linetime, N, inttype) dlg = wx.FileDialog(self, "Save as .dat file", "./", filename, "DAT files (*.dat)|*.dat;*.daT;*.dAt;*.dAT;*.Dat;*.DaT;*.DAt;*.DAT", wx.SAVE|wx.FD_OVERWRITE_PROMPT) # user cannot do anything until he clicks "OK" if dlg.ShowModal() == wx.ID_OK: # Workaround for Ubuntu 12.10 since 0.2.0 path = dlg.GetPath() else: return wx.BeginBusyCursor() # start new thread args = N, taudiff, linetime, dtype, path delayedresult.startWorker(_CreateConsumer, _CreateWorker, wargs=(args,),) def GenerateExpNoise(N, taud=20., variance=1., deltat=1.): """ Generate exponentially correlated noise. """ # length of mean0 trace N_steps = N dt = deltat # time trace t = np.arange(N_steps) # AR-1 processes - what does that mean? # time constant (inverse of correlationtime taud) g = 1./taud # variance s0 = variance # normalization factor (memory of the trace) exp_g = np.exp(-g*dt) one_exp_g = 1-exp_g z_norm_factor = np.sqrt(1-np.exp(-2*g*dt))/one_exp_g # create random number array # generates random numbers in interval [0,1) randarray = np.random.random(N_steps) # make numbers random in interval [-1,1) randarray = 2*(randarray-0.5) # simulate exponential random behavior z = np.zeros(N_steps) z[0] = one_exp_g*randarray[0] for i in np.arange(N_steps-1)+1: z[i] = exp_g*z[i-1] + one_exp_g*randarray[i] z = z * z_norm_factor*s0 return z def MakeDat(linetime, noisearray, dtype, filename): """ Create a .dat file (like Photon.exe). System clock is fixed to 60MHz. linetime [s] noisearray integer array (uint16 or uint32) """ NewFile = open(filename, 'wb') if dtype == np.uint32: newformat = np.uint8(32) elif dtype == np.uint16: newformat = np.uint8(16) else: raise ValueError newclock = np.uint8(60) NewFile.write(newformat) NewFile.write(newclock) noisearray = dtype(noisearray) # Create matrix. Each line is a scan. data = list() timeticks = linetime*newclock*1e6 # 60MHz half1 = np.ceil(timeticks/2) half2 = np.floor(timeticks/2) for i in np.arange(len(noisearray)): # Create a line N = noisearray[i] if N == 0: line=np.zeros(1, dtype=dtype) # Only one event at the far corner line[0] = timeticks line.tofile(NewFile) else: line = np.ones(N+1, dtype=dtype) # events are included between two far events line[0] = half1-len(line) line[-1] = half2 line.tofile(NewFile) NewFile.close() def removewrongUTF8(name): newname = u"" for char in name: try: uchar = codecs.decode(char, "UTF-8") except: pass else: newname += char return newname def getMainIcon(pxlength=32): """ *pxlength* is the side length in pixels of the icon """ # Set window icon iconBMP = icon.getMainBitmap() # scale image = wx.ImageFromBitmap(iconBMP) image = image.Scale(pxlength, pxlength, wx.IMAGE_QUALITY_HIGH) iconBMP = wx.BitmapFromImage(image) iconICO = wx.IconFromBitmap(iconBMP) return iconICO def findprogram(program): """ Uses the systems PATH variable find executables""" path = os.environ['PATH'] paths = path.split(os.pathsep) for d in paths: if os.path.isdir(d): fullpath = os.path.join(d, program) if sys.platform[:3] == 'win': for ext in '.exe', '.bat': program_path = fullpath + ext if os.path.isfile(fullpath + ext): return (1, program_path) else: if os.path.isfile(fullpath): return (1, fullpath) return (0, None) def _CreateConsumer(e=None): wx.EndBusyCursor() def _CreateWorker(args): N, taudiff, linetime, dtype, path = args # deltat is linetime noisearray = GenerateExpNoise(N, taud=taudiff, deltat=linetime) noisearray -= np.min(noisearray) noisearray *= 30./np.max(noisearray) #noisearray += 5 noisearray = np.uint32(noisearray) # Create 32bit and 16bit binary .dat files # translate linetime in bins of taud ltbin = linetime / 1000 data = MakeDat(ltbin, noisearray, dtype, path) def Update(parent): """ This is a thread for _Update """ parent.StatusBar.SetStatusText("Connecting to server...") delayedresult.startWorker(_UpdateConsumer, _UpdateWorker, wargs=(parent,), cargs=(parent,)) def _UpdateConsumer(delayedresult, parent): results = delayedresult.get() dlg = UpdateDlg(parent, results) dlg.Show() parent.StatusBar.SetStatusText("...update status: "+results["Description"][2]) def _UpdateWorker(parent): changelog = "" hpversion = None # I created this TXT record to keep track of the current web presence. try: urlopener = urllib2.urlopen(doc.HomePage, timeout=2) homepage = urlopener.geturl() except: homepage = doc.HomePage try: urlopener2 = urllib2.urlopen(doc.GitHome, timeout=2) githome = urlopener2.geturl() except: githome = "" # Find the changelog file try: responseCL = urllib2.urlopen(homepage+doc.ChangeLog, timeout=2) except: CLfile = doc.GitChLog else: fileresponse = responseCL.read() CLlines = fileresponse.splitlines() # We have a transition between ChangeLog.txt on the homepage # containing the actual changelog or containing a link to # the ChangeLog file. if len(CLlines) == 1: CLfile = CLlines[0] else: hpversion = CLlines[0] CLfile = doc.GitChLog # Continue version comparison if True continuecomp = False try: responseVer = urllib2.urlopen(CLfile, timeout=2) except: if hpversion == None: newversion = "unknown" action = "cannot connect to server" else: newversion = hpversion continuecomp = True else: continuecomp = True changelog = responseVer.read() newversion = changelog.splitlines()[0] if continuecomp: new = LooseVersion(newversion) old = LooseVersion(parent.version) if new > old: action = "update available" elif new < old: action = "whoop you rock!" else: action = "state of the art" description = [parent.version, newversion, action] if len(changelog) != 0: changelogfile = tempfile.mktemp()+"_PyScanFCS_ChangeLog"+".txt" clfile = open(changelogfile, 'wb') clfile.write(changelog) clfile.close() else: changelogfile=doc.StaticChangeLog results = dict() results["Description"] = description results["Homepage"] = homepage results["Homepage_GIT"] = githome results["Changelog"] = changelogfile return results PyScanFCS-0.2.3/pyscanfcs/uilayer.py000066400000000000000000000413711245330745300172760ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """ uilayer python user interface layer to monitor progress of long-running algorithms """ from __future__ import division import os import sys import warnings __all__=["dummy", "ui", "stdout"] try: import wx except: pass else: __all__ += ["wxdlg"] if sys.version < '3': integer_types = (int, long,) else: integer_types = (int,) class base_ui(): """ This is the main class from which all interfaces are derived. It is quiet, meaning it does not output any progress data, but it will display warings and errors in the console. """ def __init__(self, steps=None, pids=None, progress=None, subpids=None, show_warnings=True, totalsteps=None, dirname=None, **kwargs): """ Creates an instance and sets initial parameters for progress dialogs (optional). Parameters: ----------- pids, steps, progress, subpids : optional See documentation of self.SetProgress show_warnings : bool Display warnings of/in the interface. totalsteps : int or None Known number of total steps of all progresses. This number can be larger than the sum of all steps, inferring knowledge on the progresses to come. See Also -------- SetProgress : Sets initial parameters manually """ if dirname is None: self._dirname = os.path.expanduser("~") self._abortlist = list() self._totalsteps = totalsteps self._currentstep = 0 self._single_progress = False self.ShowWarnings(show_warnings) self.SetProgress(steps=steps, pids=pids, progress=progress, subpids=subpids) def GetDir(self): """ Returns the current working directory. """ return self._dirname def Iterate(self, pid=None, subpid=0, **kwargs): """ Iterate progress. Increments the "current step" of a progress by one. Warns the user if the step is above "total steps". Also looks for the pid in self._abortlist and returns it to the process to stop it. """ if self._totalsteps is not None: self._currentstep += 1 if pid is None: if self._single_progress == False: self.warn("I do not know which progress to iterate."+ " Please specify the kwarg pid.") pid=0 pid = int(pid) subpid = int(subpid) for i in range(len(self._pids)): if self._pids[i] == pid and self._subpids[i] == subpid: self._progress[i] += 1 self.Update() if pid in self._abortlist: # Try to stop the process if it supports that. # Returning anything else but None will stop the process. return pid def Finalize(self, pid=None, subpid=0, **kwargs): """ Triggers output that a process is finished """ pass def SelectPath(self, **kwargs): """ Select a file or folder from the file system. This does not do anything here. """ pass def GetDir(self, dirname): """ Sets the current working directory. """ self._dirname = dirname def SetProgress(self, steps=None, pids=None, progress=None, subpids=None, **kwargs): """ Set the initial parameters of the processes that are to be monitored by this class. Parameters ---------- pids : Array-like dtype(int) or int, length N Process identifiers steps : Array-like dtype(int) or int, length N Maximum number of steps for each process progress : Array-like dtype(int) or int, length N Current step in the progress counting up until `steps` subpids : Array-like dtype(int) or int, length N Sub-process identifiers - useful for multithreading The following kwargs combinations are possible: 1. pids, steps, progress, subpids all `None` Nothing will happen 2. pids, steps, progress, subpids all some int Only one process of unknown length 3. pids, steps, progress, subpids all integer `list`s Multiple processes are assumed 4. pids, progress, subpids all `None` and steps int Only one process of known length 5. pids, progress, subpids all `None` and steps `list` Multiple processes of known length - internally the processes get `pids` that are enumerated from zero onwards and `progress` is set no zeros. Returns ------- success : bool True if data was set and False if nothing was set. """ self._single_progress = False self._no_data = False self._known_length = False if (pids is None and steps is None and progress is None): # 1. Nothing will happen self._no_data = True return False elif (pids is not None and steps is not None and progress is not None): # 2. Only one process # or # 3. Multiple processes are assumed self._known_length = False elif (pids is None and steps is not None and progress is None): self._known_length = True if isinstance(steps, integer_types+(float, complex)): # 4. Only one process of known length self._single_progress = True pids = 0 progress = 0 else: # 5. Multiple processes of known length - internally # the processes get `pids` that are enumerated from # zero onwards and `progress` is set no zeros. pids = range(len(steps)) progress = [0]*len(steps) else: raise NameError("Your set of parameters is invalid.") # Convert input to list if isinstance(pids, integer_types+(float, complex)): # Only one progress self._single_progress = True pids = [pids] if isinstance(steps, integer_types+(float, complex)): steps = [steps] if isinstance(progress, integer_types+(float, complex)): progress = [progress] if isinstance(subpids, integer_types+(float, complex)): subpids = [subpids] self._pids = pids # Defines how many steps should be used to split the total # computation. The function self.progress will be used to # follow the steps of the algorithm. self._steps = steps self._progress = progress if subpids is None: self._subpids = [0]*len(self._pids) else: self._subpids = subpids return True def ShowWarnings(self, show_warnings): """ show_warnings : bool enable or disable warning """ self._show_warnings = show_warnings def Update(self, **kwargs): """ Read and write from and to the user interface This does not do anything here. """ pass def warn(self, msg): """ Warns the user when there is a problem. """ if self._show_warnings: warnings.warn(msg) class dummy(object): """ This is a dummy class that can be used to improve speed. There will be no output. """ def __init__(self, *args, **kwargs): pass def Finalize(self, *args, **kwargs): pass def Iterate(self, *args, **kwargs): pass def SelectPath(self, *args, **kwargs): pass def SetDir(self, *args, **kwargs): pass def SetProgress(self, *args, **kwargs): pass def ShowWarnings(self, *args, **kwargs): pass def Update(self, *args, **kwargs): pass def warn(self, *args, **kwargs): pass class stdout(base_ui): """ Writes progress into standard output. """ def __init__(self, **kwargs): """ Stuff that needs to be done in the beginning. """ base_ui.__init__(self, **kwargs) self._maxlength = get_terminal_width() def Finalize(self, pid=None, subpid=0, name=None, **kwargs): """ Triggers output when a process is finished. """ if pid is None: self.warn("I do not know which progress to finalize."+ " Please specify the kwarg pid.") pid = int(pid) subpid = int(subpid) msg = "Progress finished: {}-{}".format(pid,subpid) if name is not None: msg += " ({})".format(name) dn = max(self._maxlength-len(msg),0) sys.stdout.write("\r{}{}\n".format(msg,dn*" ")) sys.stdout.flush() def Update(self, **kwargs): """ Read and write from and to the user interface. The algorithm wants to tell the user something. We use the last line of the standard output to write the progress of all algorithms. """ startline = u"Progress: " msg = startline if self._single_progress: if self._steps[0] == 0: perc = int(self._progress[0]) msg += u"{}".format(perc) else: perc = self._progress[0]/self._steps[0]*100. msg += u"{:0.2f}%".format(perc) else: for i in range(len(self._pids)): # compute percentage if self._pids[i] != -1: if self._steps[i] == 0: perc = int(self._progress[i]) msg += u"{}-{}@{}|".format( self._pids[i], self._subpids[i], perc) else: perc = self._progress[i]/self._steps[i]*100. msg += u"{}-{}@{:0.2f}%|".format( self._pids[i], self._subpids[i], perc) msg = msg.strip(" |") dn = max(self._maxlength-len(msg),0) newline = "\r{}{}".format(msg,dn*" ") if len(newline) > self._maxlength+1: warnings.warn("Terminal width too small. Output cropped.") newline = newline[:self._maxlength-1] if newline.strip() == startline.strip(): newline = self._maxlength*" "+"\r" sys.stdout.write(newline) sys.stdout.flush() class wxdlg(base_ui): """ Displays propgress in a wx dialog window. Can be used from within a wx.App. """ def __init__(self, parent=None, title="Progress", **kwargs): """ Stuff that needs to be done in the beginning. """ self.parent = parent self.title = title base_ui.__init__(self, **kwargs) def Destroy(self): """ Destroys the wxdlg class. """ try: self.Finalize() except: pass def Finalize(self, pid=None, subpid=0, name=None, **kwargs): """ Triggers output when a process is finished. """ if self._single_progress: self.dlg.Destroy() elif (self._totalsteps is not None and self._totalsteps <= self._currentstep): self.dlg.Destroy() else: self.Update() def SelectPath(self, dirname=None, title="Open file", wildcards=["*"], fname="All files", mode="r", **kwargs): """ Select a file or folder from the file system. Opens a wx.FileDialog for selecting files. Parameters ---------- mode : str File mode operations read "r" or write "w" or read multiple files "mr". Returns the files in a list. """ if dirname is None: dirname = self._dirname front = " (" rear = ")|" for wc in wildcards: front += "*.{}, ".format(wc) rear += ";*{}".format(wc) front.strip(", ") wcstring = fname+front+rear if mode == "r": wxmode = wx.OPEN else: raise NotImplementedError( "Mode '{}' not supported".format(mode)) dlg = wx.FileDialog(self.parent, title, dirname, "", wcstring, wxmode) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() self._dirname = os.path.split(path)[0] dlg.Destroy() return path else: return def SetProgress(self, **kwargs): """ Sets progress data from base_ui and dialog parameters """ if base_ui.SetProgress(self, **kwargs): style = wx.PD_SMOOTH|wx.PD_AUTO_HIDE|wx.PD_CAN_ABORT if self._known_length: style |= wx.PD_REMAINING_TIME if self._totalsteps is not None: maxsteps = self._totalsteps else: maxsteps = 0 for i in self._steps: maxsteps += i self._total_counter = 0 # known length? title = self.title if not self._single_progress: title += " ({} processes)".format(len(self._steps)) self.dlg = wx.ProgressDialog( title = title, message = "Running : ", maximum = maxsteps, parent = self.parent, style = style) self.dlg.SetMinSize((300+20*len(self._steps),80)) def Update(self, **kwargs): """ Read and write from and to the user interface. Checks if the user has pressed 'Cancel' and updates the Progress bar. """ self._total_counter += 1 msg = "Running : " if self._single_progress: if self._known_length: msg += "PID {}-{}".format(self._pids[0], self._subpids[0]) else: msg += "PID {}-{}@{}".format(self._pids[0], self._subpids[0], self._progress[0]) else: for i in range(len(self._pids)): if self._pids[i] != -1: if self._known_length: msg += u"PID {}-{}@{}, ".format( self._pids[i], self._subpids[i],self._progress[i]) else: msg += u"PID {}-{}, ".format( self._pids[i], self._subpids[i]) msg = msg.strip(" ,") if self._known_length: (cont,skip) = self.dlg.Update(self._total_counter, msg) else: (cont,skip) = self.dlg.UpdatePulse(newmsg=msg) if cont is False: # On next iteration, algorithms can abort if they # support it. self._abortlist += self._pids def get_terminal_size(fd=1): """ Returns height and width of current terminal. First tries to get size via termios.TIOCGWINSZ, then from environment. Defaults to 25 lines x 80 columns if both methods fail. :param fd: file descriptor (default: 1=stdout) Author: cas (http://blog.taz.net.au/author/cas/) """ try: import fcntl, termios, struct hw = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) except: try: hw = (os.environ['LINES'], os.environ['COLUMNS']) except: hw = (25, 80) return hw def get_terminal_height(fd=1): """ Returns height of terminal if it is a tty, 999 otherwise :param fd: file descriptor (default: 1=stdout) """ if os.isatty(fd): height = get_terminal_size(fd)[0] else: height = 999 return height def get_terminal_width(fd=1): """ Returns width of terminal if it is a tty, 999 otherwise :param fd: file descriptor (default: 1=stdout) """ if os.isatty(fd): width = get_terminal_size(fd)[1] else: width = 999 return width __version__ = "0.1.4" __author__ = "Paul Mueller" __email__ = "paul.mueller@biotec.tu-dresden.de" __license__ = "BSD (3-Clause)" PyScanFCS-0.2.3/setup.cfg000066400000000000000000000000731245330745300150740ustar00rootroot00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 PyScanFCS-0.2.3/setup.py000066400000000000000000000053151245330745300147710ustar00rootroot00000000000000#!/usr/bin/env python # To create a distribution package for pip or easy-install: # python setup.py sdist from setuptools import setup, find_packages, Extension from Cython.Distutils import build_ext import numpy as np from os.path import join, dirname, realpath, exists from warnings import warn # The next three lines are necessary for setup.py install to include # ChangeLog and Documentation of PyCorrFit from distutils.command.install import INSTALL_SCHEMES for scheme in INSTALL_SCHEMES.values(): scheme['data'] = scheme['purelib'] # Download documentation if it was not compiled Documentation = join(dirname(realpath(__file__)), "doc/PyScanFCS_doc.pdf") webdoc = "https://github.com/paulmueller/PyScanFCS/wiki/PyScanFCS_doc.pdf" if not exists(Documentation): print "Downloading {} from {}".format(Documentation, webdoc) import urllib #testfile = urllib.URLopener() urllib.urlretrieve(webdoc, Documentation) # Get the version of PyCorrFit from the Changelog.txt StaticChangeLog = join(dirname(realpath(__file__)), "ChangeLog.txt") try: clfile = open(StaticChangeLog, 'r') version = clfile.readline().strip() clfile.close() except: warn("Could not find 'ChangeLog.txt'. PyScanFCS version is unknown.") version = "0.0.0-unknown" EXTENSIONS = [Extension("pyscanfcs.SFCSnumeric", ["pyscanfcs/SFCSnumeric.pyx"], libraries=[], include_dirs=[np.get_include()] ) ] name='pyscanfcs' setup( name=name, author='Paul Mueller', author_email='paul.mueller@biotec.tu-dresden.de', url='https://github.com/paulmueller/PyScanFCS', version=version, packages=[name], package_dir={name: name}, data_files=[('pyscanfcs_doc', ['ChangeLog.txt', 'doc/PyScanFCS_doc.pdf'])], license="GPL v2", description='Scientific tool for perpendicular line scanning FCS.', long_description=open(join(dirname(__file__), 'Readme.txt')).read(), scripts=['bin/pyscanfcs'], cmdclass={"build_ext": build_ext}, include_package_data=True, ext_modules=EXTENSIONS, install_requires=[ "cython", "matplotlib >= 1.1.0", "multipletau >= 0.1.4", "NumPy >= 1.5.1", "pyfits", "SciPy >= 0.8.0", "wxPython >= 2.8.10.1" ], keywords=["fcs", "fluorescence", "correlation", "spectroscopy", "perpendicular", "scanning", "multiple", "tau"], classifiers= [ 'Operating System :: OS Independent', 'Programming Language :: Python :: 2.7', 'Topic :: Scientific/Engineering :: Visualization', 'Intended Audience :: Science/Research' ], platforms=['ALL'] )