xlwt-0.7.5/0000755000175000017500000000000012127663310010624 5ustar janjanxlwt-0.7.5/xlwt/0000755000175000017500000000000012273261172011624 5ustar janjanxlwt-0.7.5/xlwt/UnicodeUtils.py0000644000175000017500000001156012127401563014606 0ustar janjan# -*- coding: windows-1252 -*- ''' From BIFF8 on, strings are always stored using UTF-16LE text encoding. The character array is a sequence of 16-bit values4. Additionally it is possible to use a compressed format, which omits the high bytes of all characters, if they are all zero. The following tables describe the standard format of the entire string, but in many records the strings differ from this format. This will be mentioned separately. It is possible (but not required) to store Rich-Text formatting information and Asian phonetic information inside a Unicode string. This results in four different ways to store a string. The character array is not zero-terminated. The string consists of the character count (as usual an 8-bit value or a 16-bit value), option flags, the character array and optional formatting information. If the string is empty, sometimes the option flags field will not occur. This is mentioned at the respective place. Offset Size Contents 0 1 or 2 Length of the string (character count, ln) 1 or 2 1 Option flags: Bit Mask Contents 0 01H Character compression (ccompr): 0 = Compressed (8-bit characters) 1 = Uncompressed (16-bit characters) 2 04H Asian phonetic settings (phonetic): 0 = Does not contain Asian phonetic settings 1 = Contains Asian phonetic settings 3 08H Rich-Text settings (richtext): 0 = Does not contain Rich-Text settings 1 = Contains Rich-Text settings [2 or 3] 2 (optional, only if richtext=1) Number of Rich-Text formatting runs (rt) [var.] 4 (optional, only if phonetic=1) Size of Asian phonetic settings block (in bytes, sz) var. ln or 2ln Character array (8-bit characters or 16-bit characters, dependent on ccompr) [var.] 4rt (optional, only if richtext=1) List of rt formatting runs [var.] sz (optional, only if phonetic=1) Asian Phonetic Settings Block ''' from struct import pack def upack2(s, encoding='ascii'): # If not unicode, make it so. if isinstance(s, unicode): us = s else: us = unicode(s, encoding) # Limit is based on number of content characters # (not on number of bytes in packed result) len_us = len(us) if len_us > 32767: raise Exception('String longer than 32767 characters') try: encs = us.encode('latin1') # Success here means all chars are in U+0000 to U+00FF # inclusive, meaning that we can use "compressed format". flag = 0 n_items = len_us except UnicodeEncodeError: encs = us.encode('utf_16_le') flag = 1 n_items = len(encs) // 2 # n_items is the number of "double byte characters" i.e. MS C wchars # Can't use len(us). # len(u"\U0001D400") -> 1 on a wide-unicode build # and 2 on a narrow-unicode build. # We need n_items == 2 in this case. return pack(' 32767: raise Exception('String longer than 32767 characters') try: encs = us.encode('latin1') # Success here means all chars are in U+0000 to U+00FF # inclusive, meaning that we can use "compressed format". flag = 0 | 8 n_items = len(encs) except UnicodeEncodeError: encs = us.encode('utf_16_le') flag = 1 | 8 n_items = len(encs) // 2 # see comments in upack2 function above return pack(' 255: raise Exception('String longer than 255 characters') try: encs = us.encode('latin1') flag = 0 n_items = len_us except UnicodeEncodeError: encs = us.encode('utf_16_le') flag = 1 n_items = len(encs) // 2 return pack('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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>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>T>T>U@WAXBZBZBZBZBZBZBZBZBZAX?V>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>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T@VBYD\=S+;$2*4GD\>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>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T?UAXC[BX0A%            D[?V>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>T>T>T>T>T>T>T>T>T>T>T@WBYE]9M#0               ;P@W>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>T>T>T>T>T>T@VAXC[BY+;&           y N '    ;P?V>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>U@WAXC[BX0A +       u o LF*    D\>U>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?V@WAXBZE]=S+; +      y M-B66||쾾O@@    D[>U>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?V@WAXBZC[F^3F(6 +      n B$6,,w__⵵ح՜_MM    D\?V>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T@WBZD\AX4F'5%2         b 76,,tt̤ʢggkVV!Φkcs]]*     ;P@V>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T?VBX,<          o CaNN~~湹䷷ggQAAI::u^^Ƞӫ=q^PoYY*    ?V?U>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T?U9M      v e +kVVԪ^JJ3))qZZȠJ>1լ[JJ*    D[>U>T>T>T>T>T>T>T>T>T>T>T>T>T>TAX*    y N",$$iTTM?:O@@*    D[>U>T>T>T>T>T>T>T>T>T>T>T>T>T>TG_ x N!1))WFF{bbҨ⾙O@@*    BY>T>T>T>T>T>T>T>T>T>T>T>T>TE]F#,$$ffΥڭ|``nTTm\\NGGkUUO@@6    $F^>T>T>T>T>T>T>T>T>T>T>T@Wn(5 kVVЧϗvvWKK'++BHHvyy688qqePPG>>$$oo_KK]   $F^>T>T>T>T>T>T>T>T>T>TBZ2꼼iQQahhZ]]c__ 777accvyy\bbC44ʊx{WDDP   $F^>T>T>T>T>T>T>T>T>TAX_".zaa깹ʠR>> 622<==bccAKKiiШ}~zx|zijv[Vifڨ4Hdb_MM*   $F^>T>T>T>T>T>T>T>T>TC[v^^䱎v QWWLPPdffY\\%**?;;SHHt\\rs纻črszxqkG62bWnbmbnceZshqf`USCC*   $D\>T>T>T>T>T>T>T>TC[% 69..}ehhBEF456[OOqWXP>?xz~xlglRKT?7`Uk`mbaI@f[nclbodsiwlsipfsivkz]UndgNGD2,|b^K;;*   .=AX>T>T>T>T>T>T>T>TD\ٮcPWYyaN]MMGNN!''|oooov^_WB@fbsnZC;eMEwlodmbmbodpfrhsipfsitjvkujsisiqgyn8*'dMFlbbJCcLEi_eMFe\tK71ⲱ5=uy_KK*   U>T>T>T>T>T>T>T?V:O{ca˲kTRYEB`WujqfpftjsipfqgrhsitjujqgsivkaJCWBT>T>T>T>T>T>T>T@W@V  ䷸ͣkhx^YkRIT?7rfqfvjznvksisisipfqgvkz]UpUNdMF[F?M;6d[cLEsWOynynndwmtjwmpUNpUNQ>9kRJiPIgNGh_<.)~rwlxni`sWNxpy  2E?V>T>T>T>T>T>T>T>T>T?UC\'ffݱ|v|_V|]Rj_odrgtivkxmaXbKDhOH@1,^GAgNGiPIcLEmcbYS?9{psixme\[F?mcc[jQJjQJ_HAN<7vZRka{^U|qYD>VA;oTMiPIhOHrWOvkVA;lSKdMFwmmcO;5~zȡA !,0@AX>T>T>T>T>T>T>T>T>T>T>T>TG`V* fLDoctivkoTMdLEhOH]F@hOHqVOynwmw[Sw[RoecLEd\oTMf]}_WI83qgaJCd[qVO|qoeeMFjQJ]F@oTMpUNf]w[ScLE}qjPIrWO|qwlkacLEi`R?9oTMtXPpefNGoSJr[[ЧW!-E^@V>T>T>T>T>T>T>T>T>T>T>T>T>T>TC[:O |||zJ96eMEndync[_HBy\TqgcLEc[d[tXPvktjrhzoT@:iPIqVNiPIcZ{^Vt!^GAzovkwmf]#iPIlSKmTLd\tXPt<.*vZRynpUNd\Q=7oUMhOHgNGla~`WeX}{ۯS(AY>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T?UHaV*%_JDpTKgNGrhYD=iPIhOHqVNhOHx[SjQJuYQndmcaJCzozoZE?ZE?zoxmeMFtYQoTNvZRqVObYvkw bZU@;lSKz\TVA:O<5eLD^G?shmbkSN`IAnaS>6d^y_\꼽ҩl'5@W>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>TC[:O ll褃?/(gNF{pxne\?0,g^tXPiPI\F@M:5oTMpUNvZRtXPg^f]T@:rWOaJCbKD]GAeMFaWVA:rVM\F>ui{]R3% aI@sXP}Ц೴ժᵵrrBZ>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T?UHaV* ]JHfMEfNFpfx[SvkynwmxnshQ>8K93iPGfMEaIBeZ|o kQHcJBtk~w̡xx뽾ۯ޲ijuu2))<00K%BZ>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>TC[5Hr[[u[UXD>dLDYD=e\,!]F?nSKoTLbX9-,š躹뽽㶷Шmmkljj]JJ*"#0''# ;1G4GC[>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T?VHbV*ėpk|yTCC3*+~fgJ;<*"#)!!/gJJnnooffffffffffw__֬ΥΥΥΥΥΥʢŠѪq^]gZXU*AY>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>TC[:O %;01>236+,eQQyaayaaff{bbҨ֬ܧooܨ3pp/ssyooF99E^>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?UG`e$1;00ⶶ毯&&CCpp%mm7tt1uu\TUۀeeAY>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>TAYE^&޳ۿǐ͕頥ekbhSZU[NVy9KA?OF>NED]QabIS: U<O6aY|Y|Z}Tq=JBAUJœ2B?V>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>TD\ Ę̐k@Gmk@ZN4z`P7cG&v,x,x+u9ēKFLNNNKMTVVSQWYYYQQQQQSSAUJЧ/?@W>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>TC[ aHJLNMKSUYXVWYYZY[[[[^^_YBA_UTެTެTެTެTެTެTެTެTެTެS=IAƟQ(AY>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>TC[ EUKSTެTެTެTެTެTެTެ[YBF'hP+tZ7+! (UUTެTެTެTެTެTެTެTެTެQ\W*AY>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>TC[ ?PFSTެTެTެTެTެTެZE6402,(*$ "{}| \T߭TެTެTެTެTެTެTެTެQZ|K%BY>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>TC[ ?PFSTެTެTެTެTެTެ^_`_ aTެTެTެTެTެTެTެTެQZ| C[>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>TC[ ?PFSTެTެTެTެTެTެ^\Эۢ[Fr+]|hLnk;^N|"ZF]TެTެTެTެTެTެTެQZ| C[>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>TBYK%?PFSTެTެTެTެTެTެ^ZyLڽrS}V:wYTެTެTެTެTެTެQZ| C[>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>TAYW*?PFSTެTެTެTެTެTެ^d|Pټ̿8eTNa(_OOOQեUTެTެTެTެTެQZ|$ C[>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>TAYV*Ƞ?PFSTެTެTެTެTެTެ^‡aʢ_TެTެTެTެTެQ`E]>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>TAYS(Υ?PFSTެTެTެV[]iOҢUTެTެTެTެWbI$ C[>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@Wp)7Υ?PFSTެTެVE}}}eeeXT߭TެTެTެTެYL5 C[>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?V4EҨ?PFSTެTެ]<:;zzzqqq_TެTެTެTެTެV'w C[>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?V3D9KASTެTެ]534ﲲ]TެTެTެTެTެV$r C[>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?V3D|bbyMTެTެW@uuuwww}~[TެTެTެTެTެV$r%C[>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?V2BffKTެTެTެ]#\G^^^%!"[TެTެTެTެTެV$rE^>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>UT>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>TF_ffKTެTެTެTެVTެ```NNNFFFgggmmm CCC@@@MMMmmmmmmjjjlll0(+"gNYTެTެTެTެTެV$rE^>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>TE^ffKTެTެTެTެ[4jIIIrrrttttttrrrlll@@@zzzuuutttrrrrrriii///&iQYTެTެTެTެTެV$rE^>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>TE^ffKTެTެTެXIOOO888mmmwwwrrr}}}<<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>TE]~eeKTެTެUOС! 666555<<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>TC[~gfgpfOTެTެ_---PPPIII{{{uuuqqqssstttWWW@;= 1$[TެTެTެTެTެTެIĊE^>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>TC[RDC;MCSTެV?$$$\\\---GGGqqq[[[UUUZT߭TެTެTެTެTެFĊE^>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>TC[&! 9KASTެTެ_jjj5nWTެTެTެTެTެFĊ8,,E^>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>TC[# /('yMTެTެT߭]QQQiiiTOQ /"[TެTެTެTެTެFĊ0&&E^>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>TAYX*둑KTެTެTެU]ZZZźZT߭TެTެTެTެF̐0&&E^>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>TAYV*쏐KTެTެTެTެU]#\GA=?Ⱥppp5lWTެTެTެTެNmCJ(E^>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>TAYQ(񑕊KTެTެTެTެTެT߭cE6E6f ZEKKK "bKYTެTެTެTެNuJPllE^>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@W/?]`MTެTެTެTެTެTެTެ`"ZFE6aW=}% !     #H78sWTެTެTެTެNtFMffF_>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?V3DܰyKRNTެTެTެTެTެTެTެTެ[I–@]TެTެ[6o." " # # #[E$jQ*oV*oV*oV&dMSܪ[WTެTެTެTެTެM鲂mkffU>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?V1A⵵pvJTެTެTެTެTެTެTެTެTެUVTެTެTެTެW[[[[[[YYYYYYUTެTެTެTެTެTެTެK毑ff2B?V>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>TGaffؙFTެ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ެK毑|bb3D?V>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>TE^mmԖITެTެTެTެTެTެTެTެTެTެTެTެTެTެTެTެTެTެTެTެTެTެTެTެTެUVVVVWYYYYYU㧅3D?V>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>TD]u_^ݤ"ma][[[[[[[[[[Y[[[[[[[[[[VXA;<<:/t]EbI]D]D M8 ಳح4E?V>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>TC[ 0)($ L6    ) % &''%7#~W[zX[tSV˙ʙңffҩحl'5@W>T>T>T>TT>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>TBZ+ 0)(ܫʝ̞̞ƚ糏z,<@W>T>T>T>TGY;R>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>U?UܱȠЧyaaooBZ>T>T>T>T>TAU;R>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>TF_ⶶƟΥΥΥΥҨ{bbffffffffffffffffffffffffffkk"*$#*$#*$#0)( .@@W>T>T>T>T>T|AU;R>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T?U;P    I#W*V*V*T)a#/3F2D2D1B;OAX>T>T>T>T>T>T~||AU9Q>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T@W;P2D_"._".3F2D2D2D1BU>T>T>T>T>T>T>T~|~||R`7O>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>U?VAXAX?V?V?V?V?V>U>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>T~|~|~|~|^h5N=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>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~|~|~|~|~|io8PT>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>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~|~|~|~|~|~|~zyBV9Q>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>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~|~|~|~|~|~|~|}R`5N=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>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~|~|~|~|~|~|~|~|~|or7O;R>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>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~|~|~|~|~|~|~|~|~|~|}L]6O=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>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~|~|~|~|~|~|~|~|~|~|~|~|or7O:Q>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>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|}Xd3MT>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>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}GY6OT>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>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~||tuHZ6OT>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>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}tuHZ6OT>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>T>T>T>T>T>T>T>T>T>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}tuHZ5N;R>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>T>T>T>T>T>T>T>T>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}yxSa3M:Q=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>T>T>T>T>T>T>T>T>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~||]g>T7O;R>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>T>T>T>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~mqTb3M9P;R>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>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}hnO^4M9P;R>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>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}hnO^4M8P;R=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~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}~mqSa?T6O9P;R=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~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}}{hnN^?T6O9P:QT>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~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~||}}{gmYdJ[4M7O9P:QT>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~||}~wwhnYdJ[:Q6O8P9P:Q;RT>T>T>T>T>T>T>T>T>T>T>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~||}~~qthn^hN^K\:Q5N7O8P8P:Q:Q:QT>T>T>T~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}}~|zqstu\f^h`iHZJ[FY4N6O6O8P~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~||}}~~~ps~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~||{{zyyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxyxy{z~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|zzrv}~}{z~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|svXרHKMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNKgɡuw~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|svu^JީPݪ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ެTެTެTެTެTެTެTެTެTެTެTެQc̣uw~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|zz?鮞XޮQݪGۦ>١EۤRݫFۥPݪTެTެTެDڤNݩJܧHۦTެPݪDڤKܨIۦTެDڤRݫEۤEۤEۤRݫDڤ?ڢJܧTެEۤKܨHۦIۦTެBڣ?ڢGۦTެTެTެTެTެTެTެTެTެTެTެQḍuw~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|puQR߬:ٟ?ڢ=٠mPݪTެDڤmⷣBڣqʼ9؟>١=٠8؞7؞GۦTެTެTެTެTެTެTެTެTެTެQḍuw~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|{zJTެFۥ3לdJܧTެ;٠CڣYޮ~.֙phOܩ3לrq>١TެTެTެTެTެTެTެTެTެTެQc̣uw~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|xy}NTެIۦ/ךHۦخGۦQݪYޮ3ל)՗Ӓ,֘y侃BڣTެTެTެTެTެTެTެTެTެTެPiƠuw~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|xyNTެMܨ|!ԓp=٠Jܧw1כi9؟~Gۦ+֘#ԔMܨTެTެTެTެTެTެTެTެTެTެM寅xy~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|xyNTެFۥhiXޮq5לZ߯}l[߯MܨTެTެTެTެTެTެTެTެSެK簲vx}{~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|xy~NTެRݫAڢ^߱Uެ}Aڣ[߯]߰Z߯Y߮x@٢czqWޭJܧ]߰MܨEۤRݫݶ6؝~XޮSޫ}Bڣ~Dۤ@ڢi~HۦTެTެTެTެTެTެTެTެSެFxy~|~|~|~|~|~|~|~|~|~|~|~|~|~|}}}}zyMTެTެHۦAڢNݩTެRݫQݪQݪRݫNݩ>١Qݪ>١NݩAڢ?ڢAڣRݫQݪTެTެIۦѡKܨNݩQݪRݫNݩTެNݩTެNݩTެPݪNݩTެTެTެTެTެTެSެQMK簏uw~|~|~|~|~|~|~|~|~|~|~|~|}~psrtrtpsvy9IIIIII@@IIIIIIIIIIIIIIIIIHNcͣ|xy~|~|~|~|~|~|~|~|~|~|~|~|tuHZ4N8P8P8P2JcwRm$C?ꡲ;(G*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I*I&FO`vxrvrvrvrvuwxy|{~|~|~|~|~|~|~|~|~|~|~|~|Xd4NT>T>T>T;QCYat9%>ף!:>T4L%>%>1I+D+D>T1I%>>T0G%>%>0G>T+D-E>T1I%>>T>T>T-O)N2Q>T>T>T>T>T>T>T;RN^~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|}or5N>T>T>T>T>T>T>T";޲3-E2˅+C}Ә9۫/ݰݰ/!:۫%>>T-O~Fm2Q>T>T>T>T>T>TT>T>T>T>T>T>T(A՞֡6ݯ5ѕاߵ7إ'@ݰϏo9أ";>T+N)N>T>T>T>T>T>TT>T>T>T>T>T>T>T+Dߗ*.Fu4џ!:%>֠6]pWk3͋6m~CY;Q7Rg_zaf5Q>T>T>T>T>T>TT>T>T>T>T>T>T>T0Gܮ6ϏLaOdک3+D6Mm~?URfdvj|*Bәhy*Bcucu8N>T3QK#M;S>T>T>T>T>T>T;RSa~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~^h:Q>T>T>T>T>T>T>T>T1Iأ7NcK`RfԜ/є3+Cfx[o &{Ě/җK`iz3s6M:SPX適@T;S>T>T>T>T>T8Pgm}~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~^h:Q>T>T>T>T>T>T>T>T8N]p=Szfx@Vҗݰ.ݰzҖ՞6dw8N5QViGm3Q>T>T>T>T=S7O~~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~^h:Q>T>T>T>T>T>T>T>T9P[nȀ8՝Oc.ݨ6M";޲Ȁ!:٩ݩ9OT>T>T>T4Mio~~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~|~\g:Q>T>T>T>T>T>T>T>T>T9P+D.F+D4L>T+D3J9P+D5L/ɂ";+Dҝ5-ET0G'?(A4L>T+D0H+D-ET>TT>TA2;3;"hkjhjkhk")')) w.save('formulas.xls') xlwt-0.7.5/xlwt/examples/panes.py0000644000175000017500000000216011650243431015115 0ustar janjan#!/usr/bin/env python # -*- coding: windows-1251 -*- # Copyright (C) 2005 Kiseliov Roman from xlwt import * w = Workbook() ws1 = w.add_sheet('sheet 1') ws2 = w.add_sheet('sheet 2') ws3 = w.add_sheet('sheet 3') ws4 = w.add_sheet('sheet 4') ws5 = w.add_sheet('sheet 5') ws6 = w.add_sheet('sheet 6') for i in range(0x100): ws1.write(i/0x10, i%0x10, i) for i in range(0x100): ws2.write(i/0x10, i%0x10, i) for i in range(0x100): ws3.write(i/0x10, i%0x10, i) for i in range(0x100): ws4.write(i/0x10, i%0x10, i) for i in range(0x100): ws5.write(i/0x10, i%0x10, i) for i in range(0x100): ws6.write(i/0x10, i%0x10, i) ws1.panes_frozen = True ws1.horz_split_pos = 2 ws2.panes_frozen = True ws2.vert_split_pos = 2 ws3.panes_frozen = True ws3.horz_split_pos = 1 ws3.vert_split_pos = 1 ws4.panes_frozen = False ws4.horz_split_pos = 12 ws4.horz_split_first_visible = 2 ws5.panes_frozen = False ws5.vert_split_pos = 40 ws4.vert_split_first_visible = 2 ws6.panes_frozen = False ws6.horz_split_pos = 12 ws4.horz_split_first_visible = 2 ws6.vert_split_pos = 40 ws4.vert_split_first_visible = 2 w.save('panes.xls') xlwt-0.7.5/xlwt/examples/image.py0000644000175000017500000000036711650243431015100 0ustar janjan#!/usr/bin/env python # -*- coding: windows-1251 -*- # Copyright (C) 2005 Kiseliov Roman from xlwt import * w = Workbook() ws = w.add_sheet('Image') ws.insert_bitmap('python.bmp', 2, 2) ws.insert_bitmap('python.bmp', 10, 2) w.save('image.xls') xlwt-0.7.5/xlwt/examples/unicode2.py0000644000175000017500000000065411650243431015525 0ustar janjan#!/usr/bin/env python # -*- coding: windows-1251 -*- # Copyright (C) 2005 Kiseliov Roman from xlwt import * w = Workbook() ws1 = w.add_sheet(u'\N{GREEK SMALL LETTER ALPHA}\N{GREEK SMALL LETTER BETA}\N{GREEK SMALL LETTER GAMMA}\u2665\u041e\u041b\u042f\u2665') fnt = Font() fnt.height = 26*20 style = XFStyle() style.font = fnt for i in range(0x10000): ws1.write(i/0x10, i%0x10, unichr(i), style) w.save('unicode2.xls') xlwt-0.7.5/xlwt/examples/merged1.py0000644000175000017500000000344411650243431015341 0ustar janjan#!/usr/bin/env python # -*- coding: windows-1251 -*- # Copyright (C) 2005 Kiseliov Roman from xlwt import * wb = Workbook() ws0 = wb.add_sheet('sheet0') fnt1 = Font() fnt1.name = 'Verdana' fnt1.bold = True fnt1.height = 18*0x14 pat1 = Pattern() pat1.pattern = Pattern.SOLID_PATTERN pat1.pattern_fore_colour = 0x16 brd1 = Borders() brd1.left = 0x06 brd1.right = 0x06 brd1.top = 0x06 brd1.bottom = 0x06 fnt2 = Font() fnt2.name = 'Verdana' fnt2.bold = True fnt2.height = 14*0x14 brd2 = Borders() brd2.left = 0x01 brd2.right = 0x01 brd2.top = 0x01 brd2.bottom = 0x01 pat2 = Pattern() pat2.pattern = Pattern.SOLID_PATTERN pat2.pattern_fore_colour = 0x01F fnt3 = Font() fnt3.name = 'Verdana' fnt3.bold = True fnt3.italic = True fnt3.height = 12*0x14 brd3 = Borders() brd3.left = 0x07 brd3.right = 0x07 brd3.top = 0x07 brd3.bottom = 0x07 fnt4 = Font() al1 = Alignment() al1.horz = Alignment.HORZ_CENTER al1.vert = Alignment.VERT_CENTER al2 = Alignment() al2.horz = Alignment.HORZ_RIGHT al2.vert = Alignment.VERT_CENTER al3 = Alignment() al3.horz = Alignment.HORZ_LEFT al3.vert = Alignment.VERT_CENTER style1 = XFStyle() style1.font = fnt1 style1.alignment = al1 style1.pattern = pat1 style1.borders = brd1 style2 = XFStyle() style2.font = fnt2 style2.alignment = al1 style2.pattern = pat2 style2.borders = brd2 style3 = XFStyle() style3.font = fnt3 style3.alignment = al1 style3.pattern = pat2 style3.borders = brd3 price_style = XFStyle() price_style.font = fnt4 price_style.alignment = al2 price_style.borders = brd3 price_style.num_format_str = '_(#,##0.00_) "money"' ware_style = XFStyle() ware_style.font = fnt4 ware_style.alignment = al3 ware_style.borders = brd3 ws0.merge(3, 3, 1, 5, style1) ws0.merge(4, 10, 1, 6, style2) ws0.merge(14, 16, 1, 7, style3) ws0.col(1).width = 0x0d00 wb.save('merged1.xls') xlwt-0.7.5/xlwt/examples/row_styles_empty.py0000644000175000017500000000054511650243431017444 0ustar janjan#!/usr/bin/env python # -*- coding: windows-1251 -*- # Copyright (C) 2005 Kiseliov Roman __rev_id__ = """$Id$""" from pyExcelerator import * w = Workbook() ws = w.add_sheet('Hey, Dude') for i in range(6, 80): fnt = Font() fnt.height = i*20 style = XFStyle() style.font = fnt ws.row(i).set_style(style) w.save('row_styles_empty.xls') xlwt-0.7.5/xlwt/examples/country.py0000644000175000017500000000027311650243431015515 0ustar janjan#!/usr/bin/env python # -*- coding: windows-1252 -*- # Copyright (C) 2007 John Machin from xlwt import * w = Workbook() w.country_code = 61 ws = w.add_sheet('AU') w.save('country.xls') xlwt-0.7.5/xlwt/examples/merged.py0000644000175000017500000000137711650243431015263 0ustar janjan#!/usr/bin/env python # -*- coding: windows-1251 -*- # Copyright (C) 2005 Kiseliov Roman from xlwt import * fnt = Font() fnt.name = 'Arial' fnt.colour_index = 4 fnt.bold = True borders = Borders() borders.left = 6 borders.right = 6 borders.top = 6 borders.bottom = 6 al = Alignment() al.horz = Alignment.HORZ_CENTER al.vert = Alignment.VERT_CENTER style = XFStyle() style.font = fnt style.borders = borders style.alignment = al wb = Workbook() ws0 = wb.add_sheet('sheet0') ws1 = wb.add_sheet('sheet1') ws2 = wb.add_sheet('sheet2') for i in range(0, 0x200, 2): ws0.write_merge(i, i+1, 1, 5, 'test %d' % i, style) ws1.write_merge(i, i, 1, 7, 'test %d' % i, style) ws2.write_merge(i, i+1, 1, 7 + (i%10), 'test %d' % i, style) wb.save('merged.xls') xlwt-0.7.5/xlwt/examples/row_styles.py0000644000175000017500000000053011650243431016220 0ustar janjan#!/usr/bin/env python # -*- coding: windows-1251 -*- # Copyright (C) 2005 Kiseliov Roman from xlwt import * w = Workbook() ws = w.add_sheet('Hey, Dude') for i in range(6, 80): fnt = Font() fnt.height = i*20 style = XFStyle() style.font = fnt ws.write(i, 1, 'Test') ws.row(i).set_style(style) w.save('row_styles.xls') xlwt-0.7.5/xlwt/Row.py0000644000175000017500000002700311741774020012747 0ustar janjan# -*- coding: windows-1252 -*- import BIFFRecords import Style from Cell import StrCell, BlankCell, NumberCell, FormulaCell, MulBlankCell, BooleanCell, ErrorCell, \ _get_cells_biff_data_mul import ExcelFormula import datetime as dt from Formatting import Font try: from decimal import Decimal except ImportError: # Python 2.3: decimal not supported; create dummy Decimal class class Decimal(object): pass class Row(object): __slots__ = [# private variables "__idx", "__parent", "__parent_wb", "__cells", "__min_col_idx", "__max_col_idx", "__xf_index", "__has_default_xf_index", "__height_in_pixels", # public variables "height", "has_default_height", "height_mismatch", "level", "collapse", "hidden", "space_above", "space_below"] def __init__(self, rowx, parent_sheet): if not (isinstance(rowx, int) and 0 <= rowx <= 65535): raise ValueError("row index (%r) not an int in range(65536)" % rowx) self.__idx = rowx self.__parent = parent_sheet self.__parent_wb = parent_sheet.get_parent() self.__cells = {} self.__min_col_idx = 0 self.__max_col_idx = 0 self.__xf_index = 0x0F self.__has_default_xf_index = 0 self.__height_in_pixels = 0x11 self.height = 0x00FF self.has_default_height = 0x00 self.height_mismatch = 0 self.level = 0 self.collapse = 0 self.hidden = 0 self.space_above = 0 self.space_below = 0 def __adjust_height(self, style): twips = style.font.height points = float(twips)/20.0 # Cell height in pixels can be calcuted by following approx. formula: # cell height in pixels = font height in points * 83/50 + 2/5 # It works when screen resolution is 96 dpi pix = int(round(points*83.0/50.0 + 2.0/5.0)) if pix > self.__height_in_pixels: self.__height_in_pixels = pix def __adjust_bound_col_idx(self, *args): for arg in args: iarg = int(arg) if not ((0 <= iarg <= 255) and arg == iarg): raise ValueError("column index (%r) not an int in range(256)" % arg) sheet = self.__parent if iarg < self.__min_col_idx: self.__min_col_idx = iarg if iarg > self.__max_col_idx: self.__max_col_idx = iarg if iarg < sheet.first_used_col: sheet.first_used_col = iarg if iarg > sheet.last_used_col: sheet.last_used_col = iarg def __excel_date_dt(self, date): adj = False if isinstance(date, dt.date): if self.__parent_wb.dates_1904: epoch_tuple = (1904, 1, 1) else: epoch_tuple = (1899, 12, 31) adj = True if isinstance(date, dt.datetime): epoch = dt.datetime(*epoch_tuple) else: epoch = dt.date(*epoch_tuple) else: # it's a datetime.time instance date = dt.datetime.combine(dt.datetime(1900, 1, 1), date) epoch = dt.datetime(1900, 1, 1) delta = date - epoch xldate = delta.days + delta.seconds / 86400.0 # Add a day for Excel's missing leap day in 1900 if adj and xldate > 59: xldate += 1 return xldate def get_height_in_pixels(self): return self.__height_in_pixels def set_style(self, style): self.__adjust_height(style) self.__xf_index = self.__parent_wb.add_style(style) self.__has_default_xf_index = 1 def get_xf_index(self): return self.__xf_index def get_cells_count(self): return len(self.__cells) def get_min_col(self): return self.__min_col_idx def get_max_col(self): return self.__max_col_idx def get_row_biff_data(self): height_options = (self.height & 0x07FFF) height_options |= (self.has_default_height & 0x01) << 15 options = (self.level & 0x07) << 0 options |= (self.collapse & 0x01) << 4 options |= (self.hidden & 0x01) << 5 options |= (self.height_mismatch & 0x01) << 6 options |= (self.__has_default_xf_index & 0x01) << 7 options |= (0x01 & 0x01) << 8 options |= (self.__xf_index & 0x0FFF) << 16 options |= (self.space_above & 1) << 28 options |= (self.space_below & 1) << 29 return BIFFRecords.RowRecord(self.__idx, self.__min_col_idx, self.__max_col_idx, height_options, options).get() def insert_cell(self, col_index, cell_obj): if col_index in self.__cells: if not self.__parent._cell_overwrite_ok: msg = "Attempt to overwrite cell: sheetname=%r rowx=%d colx=%d" \ % (self.__parent.name, self.__idx, col_index) raise Exception(msg) prev_cell_obj = self.__cells[col_index] sst_idx = getattr(prev_cell_obj, 'sst_idx', None) if sst_idx is not None: self.__parent_wb.del_str(sst_idx) self.__cells[col_index] = cell_obj def insert_mulcells(self, colx1, colx2, cell_obj): self.insert_cell(colx1, cell_obj) for col_index in xrange(colx1+1, colx2+1): self.insert_cell(col_index, None) def get_cells_biff_data(self): cell_items = [item for item in self.__cells.iteritems() if item[1] is not None] cell_items.sort() # in column order return _get_cells_biff_data_mul(self.__idx, cell_items) # previously: # return ''.join([cell.get_biff_data() for colx, cell in cell_items]) def get_index(self): return self.__idx def set_cell_text(self, colx, value, style=Style.default_style): self.__adjust_height(style) self.__adjust_bound_col_idx(colx) xf_index = self.__parent_wb.add_style(style) self.insert_cell(colx, StrCell(self.__idx, colx, xf_index, self.__parent_wb.add_str(value))) def set_cell_blank(self, colx, style=Style.default_style): self.__adjust_height(style) self.__adjust_bound_col_idx(colx) xf_index = self.__parent_wb.add_style(style) self.insert_cell(colx, BlankCell(self.__idx, colx, xf_index)) def set_cell_mulblanks(self, first_colx, last_colx, style=Style.default_style): assert 0 <= first_colx <= last_colx <= 255 self.__adjust_height(style) self.__adjust_bound_col_idx(first_colx, last_colx) xf_index = self.__parent_wb.add_style(style) # ncols = last_colx - first_colx + 1 self.insert_mulcells(first_colx, last_colx, MulBlankCell(self.__idx, first_colx, last_colx, xf_index)) def set_cell_number(self, colx, number, style=Style.default_style): self.__adjust_height(style) self.__adjust_bound_col_idx(colx) xf_index = self.__parent_wb.add_style(style) self.insert_cell(colx, NumberCell(self.__idx, colx, xf_index, number)) def set_cell_date(self, colx, datetime_obj, style=Style.default_style): self.__adjust_height(style) self.__adjust_bound_col_idx(colx) xf_index = self.__parent_wb.add_style(style) self.insert_cell(colx, NumberCell(self.__idx, colx, xf_index, self.__excel_date_dt(datetime_obj))) def set_cell_formula(self, colx, formula, style=Style.default_style, calc_flags=0): self.__adjust_height(style) self.__adjust_bound_col_idx(colx) xf_index = self.__parent_wb.add_style(style) self.__parent_wb.add_sheet_reference(formula) self.insert_cell(colx, FormulaCell(self.__idx, colx, xf_index, formula, calc_flags=0)) def set_cell_boolean(self, colx, value, style=Style.default_style): self.__adjust_height(style) self.__adjust_bound_col_idx(colx) xf_index = self.__parent_wb.add_style(style) self.insert_cell(colx, BooleanCell(self.__idx, colx, xf_index, bool(value))) def set_cell_error(self, colx, error_string_or_code, style=Style.default_style): self.__adjust_height(style) self.__adjust_bound_col_idx(colx) xf_index = self.__parent_wb.add_style(style) self.insert_cell(colx, ErrorCell(self.__idx, colx, xf_index, error_string_or_code)) def write(self, col, label, style=Style.default_style): self.__adjust_height(style) self.__adjust_bound_col_idx(col) style_index = self.__parent_wb.add_style(style) if isinstance(label, basestring): if len(label) > 0: self.insert_cell(col, StrCell(self.__idx, col, style_index, self.__parent_wb.add_str(label)) ) else: self.insert_cell(col, BlankCell(self.__idx, col, style_index)) elif isinstance(label, bool): # bool is subclass of int; test bool first self.insert_cell(col, BooleanCell(self.__idx, col, style_index, label)) elif isinstance(label, (float, int, long, Decimal)): self.insert_cell(col, NumberCell(self.__idx, col, style_index, label)) elif isinstance(label, (dt.datetime, dt.date, dt.time)): date_number = self.__excel_date_dt(label) self.insert_cell(col, NumberCell(self.__idx, col, style_index, date_number)) elif label is None: self.insert_cell(col, BlankCell(self.__idx, col, style_index)) elif isinstance(label, ExcelFormula.Formula): self.__parent_wb.add_sheet_reference(label) self.insert_cell(col, FormulaCell(self.__idx, col, style_index, label)) elif isinstance(label, (list, tuple)): self.__rich_text_helper(col, label, style, style_index) else: raise Exception("Unexpected data type %r" % type(label)) def set_cell_rich_text(self, col, rich_text_list, style=Style.default_style): self.__adjust_height(style) self.__adjust_bound_col_idx(col) if not isinstance(rich_text_list, (list, tuple)): raise Exception("Unexpected data type %r" % type(rich_text_list)) self.__rich_text_helper(col, rich_text_list, style) def __rich_text_helper(self, col, rich_text_list, style, style_index=None): if style_index is None: style_index = self.__parent_wb.add_style(style) default_font = None rt = [] for data in rich_text_list: if isinstance(data, basestring): s = data font = default_font elif isinstance(data, (list, tuple)): if not isinstance(data[0], basestring) or not isinstance(data[1], Font): raise Exception ("Unexpected data type %r, %r" % (type(data[0]), type(data[1]))) s = data[0] font = self.__parent_wb.add_font(data[1]) else: raise Exception ("Unexpected data type %r" % type(data)) if s: rt.append((s, font)) if default_font is None: default_font = self.__parent_wb.add_font(style.font) if rt: self.insert_cell(col, StrCell(self.__idx, col, style_index, self.__parent_wb.add_rt(rt))) else: self.insert_cell(col, BlankCell(self.__idx, col, style_index)) write_blanks = set_cell_mulblanks write_rich_text = set_cell_rich_text xlwt-0.7.5/xlwt/CompoundDoc.py0000644000175000017500000002326012127661601014412 0ustar janjan# -*- coding: windows-1252 -*- import struct # This implementation writes only 'Root Entry', 'Workbook' streams # and 2 empty streams for aligning directory stream on sector boundary # # LAYOUT: # 0 header # 76 MSAT (1st part: 109 SID) # 512 workbook stream # ... additional MSAT sectors if streams' size > about 7 Mb == (109*512 * 128) # ... SAT # ... directory stream # # NOTE: this layout is "ad hoc". It can be more general. RTFM class XlsDoc: SECTOR_SIZE = 0x0200 MIN_LIMIT = 0x1000 SID_FREE_SECTOR = -1 SID_END_OF_CHAIN = -2 SID_USED_BY_SAT = -3 SID_USED_BY_MSAT = -4 def __init__(self): #self.book_stream = '' # padded self.book_stream_sect = [] self.dir_stream = '' self.dir_stream_sect = [] self.packed_SAT = '' self.SAT_sect = [] self.packed_MSAT_1st = '' self.packed_MSAT_2nd = '' self.MSAT_sect_2nd = [] self.header = '' def __build_directory(self): # align on sector boundary self.dir_stream = '' dentry_name = '\x00'.join('Root Entry\x00') + '\x00' dentry_name_sz = len(dentry_name) dentry_name_pad = '\x00'*(64 - dentry_name_sz) dentry_type = 0x05 # root storage dentry_colour = 0x01 # black dentry_did_left = -1 dentry_did_right = -1 dentry_did_root = 1 dentry_start_sid = -2 dentry_stream_sz = 0 self.dir_stream += struct.pack('<64s H 2B 3l 9L l L L', dentry_name + dentry_name_pad, dentry_name_sz, dentry_type, dentry_colour, dentry_did_left, dentry_did_right, dentry_did_root, 0, 0, 0, 0, 0, 0, 0, 0, 0, dentry_start_sid, dentry_stream_sz, 0 ) dentry_name = '\x00'.join('Workbook\x00') + '\x00' dentry_name_sz = len(dentry_name) dentry_name_pad = '\x00'*(64 - dentry_name_sz) dentry_type = 0x02 # user stream dentry_colour = 0x01 # black dentry_did_left = -1 dentry_did_right = -1 dentry_did_root = -1 dentry_start_sid = 0 dentry_stream_sz = self.book_stream_len self.dir_stream += struct.pack('<64s H 2B 3l 9L l L L', dentry_name + dentry_name_pad, dentry_name_sz, dentry_type, dentry_colour, dentry_did_left, dentry_did_right, dentry_did_root, 0, 0, 0, 0, 0, 0, 0, 0, 0, dentry_start_sid, dentry_stream_sz, 0 ) # padding dentry_name = '' dentry_name_sz = len(dentry_name) dentry_name_pad = '\x00'*(64 - dentry_name_sz) dentry_type = 0x00 # empty dentry_colour = 0x01 # black dentry_did_left = -1 dentry_did_right = -1 dentry_did_root = -1 dentry_start_sid = -2 dentry_stream_sz = 0 self.dir_stream += struct.pack('<64s H 2B 3l 9L l L L', dentry_name + dentry_name_pad, dentry_name_sz, dentry_type, dentry_colour, dentry_did_left, dentry_did_right, dentry_did_root, 0, 0, 0, 0, 0, 0, 0, 0, 0, dentry_start_sid, dentry_stream_sz, 0 ) * 2 def __build_sat(self): # Build SAT book_sect_count = self.book_stream_len >> 9 dir_sect_count = len(self.dir_stream) >> 9 total_sect_count = book_sect_count + dir_sect_count SAT_sect_count = 0 MSAT_sect_count = 0 SAT_sect_count_limit = 109 while total_sect_count > 128*SAT_sect_count or SAT_sect_count > SAT_sect_count_limit: SAT_sect_count += 1 total_sect_count += 1 if SAT_sect_count > SAT_sect_count_limit: MSAT_sect_count += 1 total_sect_count += 1 SAT_sect_count_limit += 127 SAT = [self.SID_FREE_SECTOR]*128*SAT_sect_count sect = 0 while sect < book_sect_count - 1: self.book_stream_sect.append(sect) SAT[sect] = sect + 1 sect += 1 self.book_stream_sect.append(sect) SAT[sect] = self.SID_END_OF_CHAIN sect += 1 while sect < book_sect_count + MSAT_sect_count: self.MSAT_sect_2nd.append(sect) SAT[sect] = self.SID_USED_BY_MSAT sect += 1 while sect < book_sect_count + MSAT_sect_count + SAT_sect_count: self.SAT_sect.append(sect) SAT[sect] = self.SID_USED_BY_SAT sect += 1 while sect < book_sect_count + MSAT_sect_count + SAT_sect_count + dir_sect_count - 1: self.dir_stream_sect.append(sect) SAT[sect] = sect + 1 sect += 1 self.dir_stream_sect.append(sect) SAT[sect] = self.SID_END_OF_CHAIN sect += 1 self.packed_SAT = struct.pack('<%dl' % (SAT_sect_count*128), *SAT) MSAT_1st = [self.SID_FREE_SECTOR]*109 for i, SAT_sect_num in zip(range(0, 109), self.SAT_sect): MSAT_1st[i] = SAT_sect_num self.packed_MSAT_1st = struct.pack('<109l', *MSAT_1st) MSAT_2nd = [self.SID_FREE_SECTOR]*128*MSAT_sect_count if MSAT_sect_count > 0: MSAT_2nd[- 1] = self.SID_END_OF_CHAIN i = 109 msat_sect = 0 sid_num = 0 while i < SAT_sect_count: if (sid_num + 1) % 128 == 0: #print 'link: ', msat_sect += 1 if msat_sect < len(self.MSAT_sect_2nd): MSAT_2nd[sid_num] = self.MSAT_sect_2nd[msat_sect] else: #print 'sid: ', MSAT_2nd[sid_num] = self.SAT_sect[i] i += 1 #print sid_num, MSAT_2nd[sid_num] sid_num += 1 self.packed_MSAT_2nd = struct.pack('<%dl' % (MSAT_sect_count*128), *MSAT_2nd) #print vars() #print zip(range(0, sect), SAT) #print self.book_stream_sect #print self.MSAT_sect_2nd #print MSAT_2nd #print self.SAT_sect #print self.dir_stream_sect def __build_header(self): doc_magic = '\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1' file_uid = '\x00'*16 rev_num = '\x3E\x00' ver_num = '\x03\x00' byte_order = '\xFE\xFF' log_sect_size = struct.pack('" ge_pattern = r">=" le_pattern = r"<=" pattern_type_tuples = ( (flt_const_pattern, ExcelFormulaParser.NUM_CONST), (int_const_pattern, ExcelFormulaParser.INT_CONST), (str_const_pattern, ExcelFormulaParser.STR_CONST), # (range2d_pattern , ExcelFormulaParser.RANGE2D), (ref2d_r1c1_pattern, ExcelFormulaParser.REF2D_R1C1), (ref2d_pattern , ExcelFormulaParser.REF2D), (true_pattern , ExcelFormulaParser.TRUE_CONST), (false_pattern , ExcelFormulaParser.FALSE_CONST), (if_pattern , ExcelFormulaParser.FUNC_IF), (choose_pattern , ExcelFormulaParser.FUNC_CHOOSE), (name_pattern , ExcelFormulaParser.NAME), (quotename_pattern, ExcelFormulaParser.QUOTENAME), (ne_pattern, ExcelFormulaParser.NE), (ge_pattern, ExcelFormulaParser.GE), (le_pattern, ExcelFormulaParser.LE), ) _re = recompile( '(' + ')|('.join([i[0] for i in pattern_type_tuples]) + ')', VERBOSE+LOCALE+IGNORECASE) _toktype = [None] + [i[1] for i in pattern_type_tuples] # need dummy at start because re.MatchObject.lastindex counts from 1 single_char_lookup = { '=': ExcelFormulaParser.EQ, '<': ExcelFormulaParser.LT, '>': ExcelFormulaParser.GT, '+': ExcelFormulaParser.ADD, '-': ExcelFormulaParser.SUB, '*': ExcelFormulaParser.MUL, '/': ExcelFormulaParser.DIV, ':': ExcelFormulaParser.COLON, ';': ExcelFormulaParser.SEMICOLON, ',': ExcelFormulaParser.COMMA, '(': ExcelFormulaParser.LP, ')': ExcelFormulaParser.RP, '&': ExcelFormulaParser.CONCAT, '%': ExcelFormulaParser.PERCENT, '^': ExcelFormulaParser.POWER, '!': ExcelFormulaParser.BANG, } class Lexer(TokenStream): def __init__(self, text): self._text = text[:] self._pos = 0 self._line = 0 def isEOF(self): return len(self._text) <= self._pos def curr_ch(self): return self._text[self._pos] def next_ch(self, n = 1): self._pos += n def is_whitespace(self): return self.curr_ch() in " \t\n\r\f\v" def match_pattern(self): m = _re.match(self._text, self._pos) if not m: return None self._pos = m.end(0) return Tok(type = _toktype[m.lastindex], text = m.group(0), col = m.start(0) + 1) def nextToken(self): # skip whitespace while not self.isEOF() and self.is_whitespace(): self.next_ch() if self.isEOF(): return Tok(type = EOF) # first, try to match token with 2 or more chars t = self.match_pattern() if t: return t # second, we want 1-char tokens te = self.curr_ch() try: ty = single_char_lookup[te] except KeyError: raise TokenStreamException( "Unexpected char %r in column %u." % (self.curr_ch(), self._pos)) self.next_ch() return Tok(type=ty, text=te, col=self._pos) if __name__ == '__main__': try: for t in Lexer(""" 1.23 456 "abcd" R2C2 a1 iv65536 true false if choose a_name 'qname' <> >= <= """): print t except TokenStreamException, e: print "error:", e xlwt-0.7.5/xlwt/__init__.py0000644000175000017500000000044312127663114013736 0ustar janjan__VERSION__ = '0.7.5' from Workbook import Workbook from Worksheet import Worksheet from Row import Row from Column import Column from Formatting import Font, Alignment, Borders, Pattern, Protection from Style import XFStyle, easyxf, easyfont, add_palette_colour from ExcelFormula import * xlwt-0.7.5/xlwt/ExcelFormula.py0000644000175000017500000000255111723765645014604 0ustar janjan# -*- coding: windows-1252 -*- import ExcelFormulaParser, ExcelFormulaLexer import struct from antlr import ANTLRException class Formula(object): __slots__ = ["__init__", "__s", "__parser", "__sheet_refs", "__xcall_refs"] def __init__(self, s): try: self.__s = s lexer = ExcelFormulaLexer.Lexer(s) self.__parser = ExcelFormulaParser.Parser(lexer) self.__parser.formula() self.__sheet_refs = self.__parser.sheet_references self.__xcall_refs = self.__parser.xcall_references except ANTLRException, e: # print e raise ExcelFormulaParser.FormulaParseException, "can't parse formula " + s def get_references(self): return self.__sheet_refs, self.__xcall_refs def patch_references(self, patches): for offset, idx in patches: self.__parser.rpn = self.__parser.rpn[:offset] + struct.pack(' 255: raise Exception("set_colour_RGB: colour values (%d,%d,%d) must be in range(0, 256)" % (red, green, blue)) if self.__custom_palette_b8 is None: self.__custom_palette_b8 = list(Style.excel_default_palette_b8) # User-defined Palette starts at colour index 8, # so subtract 8 from colour_index when placing in palette palette_index = colour_index - 8 self.__custom_palette_b8[palette_index] = red << 24 | green << 16 | blue << 8 ################################################################## ## Methods ################################################################## def add_style(self, style): return self.__styles.add(style) def add_font(self, font): return self.__styles.add_font(font) def add_str(self, s): return self.__sst.add_str(s) def del_str(self, sst_idx): self.__sst.del_str(sst_idx) def str_index(self, s): return self.__sst.str_index(s) def add_rt(self, rt): return self.__sst.add_rt(rt) def rt_index(self, rt): return self.__sst.rt_index(rt) def add_sheet(self, sheetname, cell_overwrite_ok=False): import Worksheet, Utils if not isinstance(sheetname, unicode): sheetname = sheetname.decode(self.encoding) if not Utils.valid_sheet_name(sheetname): raise Exception("invalid worksheet name %r" % sheetname) lower_name = sheetname.lower() if lower_name in self.__worksheet_idx_from_name: raise Exception("duplicate worksheet name %r" % sheetname) self.__worksheet_idx_from_name[lower_name] = len(self.__worksheets) self.__worksheets.append(Worksheet.Worksheet(sheetname, self, cell_overwrite_ok)) return self.__worksheets[-1] def get_sheet(self, sheetnum): return self.__worksheets[sheetnum] def raise_bad_sheetname(self, sheetname): raise Exception("Formula: unknown sheet name %s" % sheetname) def convert_sheetindex(self, strg_ref, n_sheets): idx = int(strg_ref) if 0 <= idx < n_sheets: return idx msg = "Formula: sheet index (%s) >= number of sheets (%d)" % (strg_ref, n_sheets) raise Exception(msg) def _get_supbook_index(self, tag): if tag in self._supbook_xref: return self._supbook_xref[tag] self._supbook_xref[tag] = idx = len(self._supbook_xref) return idx def setup_ownbook(self): self._ownbook_supbookx = self._get_supbook_index(('ownbook', 0)) self._ownbook_supbook_ref = None reference = (self._ownbook_supbookx, 0xFFFE, 0xFFFE) if reference in self.__sheet_refs: raise Exception("can't happen") self.__sheet_refs[reference] = self._ownbook_supbook_ref = len(self.__sheet_refs) def setup_xcall(self): self._xcall_supbookx = self._get_supbook_index(('xcall', 0)) self._xcall_supbook_ref = None reference = (self._xcall_supbookx, 0xFFFE, 0xFFFE) if reference in self.__sheet_refs: raise Exception("can't happen") self.__sheet_refs[reference] = self._xcall_supbook_ref = len(self.__sheet_refs) def add_sheet_reference(self, formula): patches = [] n_sheets = len(self.__worksheets) sheet_refs, xcall_refs = formula.get_references() for ref0, ref1, offset in sheet_refs: if not ref0.isdigit(): try: ref0n = self.__worksheet_idx_from_name[ref0.lower()] except KeyError: self.raise_bad_sheetname(ref0) else: ref0n = self.convert_sheetindex(ref0, n_sheets) if ref1 == ref0: ref1n = ref0n elif not ref1.isdigit(): try: ref1n = self.__worksheet_idx_from_name[ref1.lower()] except KeyError: self.raise_bad_sheetname(ref1) else: ref1n = self.convert_sheetindex(ref1, n_sheets) if ref1n < ref0n: msg = "Formula: sheets out of order; %r:%r -> (%d, %d)" \ % (ref0, ref1, ref0n, ref1n) raise Exception(msg) if self._ownbook_supbookx is None: self.setup_ownbook() reference = (self._ownbook_supbookx, ref0n, ref1n) if reference in self.__sheet_refs: patches.append((offset, self.__sheet_refs[reference])) else: nrefs = len(self.__sheet_refs) if nrefs > 65535: raise Exception('More than 65536 inter-sheet references') self.__sheet_refs[reference] = nrefs patches.append((offset, nrefs)) for funcname, offset in xcall_refs: if self._ownbook_supbookx is None: self.setup_ownbook() if self._xcall_supbookx is None: self.setup_xcall() # print funcname, self._supbook_xref patches.append((offset, self._xcall_supbook_ref)) if not isinstance(funcname, unicode): funcname = funcname.decode(self.encoding) if funcname in self._xcall_xref: idx = self._xcall_xref[funcname] else: self._xcall_xref[funcname] = idx = len(self._xcall_xref) patches.append((offset + 2, idx + 1)) formula.patch_references(patches) ################################################################## ## BIFF records generation ################################################################## def __bof_rec(self): return BIFFRecords.Biff8BOFRecord(BIFFRecords.Biff8BOFRecord.BOOK_GLOBAL).get() def __eof_rec(self): return BIFFRecords.EOFRecord().get() def __intf_hdr_rec(self): return BIFFRecords.InteraceHdrRecord().get() def __intf_end_rec(self): return BIFFRecords.InteraceEndRecord().get() def __intf_mms_rec(self): return BIFFRecords.MMSRecord().get() def __write_access_rec(self): return BIFFRecords.WriteAccessRecord(self.__owner).get() def __wnd_protect_rec(self): return BIFFRecords.WindowProtectRecord(self.__wnd_protect).get() def __obj_protect_rec(self): return BIFFRecords.ObjectProtectRecord(self.__obj_protect).get() def __protect_rec(self): return BIFFRecords.ProtectRecord(self.__protect).get() def __password_rec(self): return BIFFRecords.PasswordRecord().get() def __prot4rev_rec(self): return BIFFRecords.Prot4RevRecord().get() def __prot4rev_pass_rec(self): return BIFFRecords.Prot4RevPassRecord().get() def __backup_rec(self): return BIFFRecords.BackupRecord(self.__backup_on_save).get() def __hide_obj_rec(self): return BIFFRecords.HideObjRecord().get() def __window1_rec(self): flags = 0 flags |= (self.__wnd_hidden) << 0 flags |= (self.__wnd_mini) << 1 flags |= (self.__hscroll_visible) << 3 flags |= (self.__vscroll_visible) << 4 flags |= (self.__tabs_visible) << 5 return BIFFRecords.Window1Record(self.__hpos_twips, self.__vpos_twips, self.__width_twips, self.__height_twips, flags, self.__active_sheet, self.__first_tab_index, self.__selected_tabs, self.__tab_width_twips).get() def __codepage_rec(self): return BIFFRecords.CodepageBiff8Record().get() def __country_rec(self): if not self.__country_code: return '' return BIFFRecords.CountryRecord(self.__country_code, self.__country_code).get() def __dsf_rec(self): return BIFFRecords.DSFRecord().get() def __tabid_rec(self): return BIFFRecords.TabIDRecord(len(self.__worksheets)).get() def __fngroupcount_rec(self): return BIFFRecords.FnGroupCountRecord().get() def __datemode_rec(self): return BIFFRecords.DateModeRecord(self.__dates_1904).get() def __precision_rec(self): return BIFFRecords.PrecisionRecord(self.__use_cell_values).get() def __refresh_all_rec(self): return BIFFRecords.RefreshAllRecord().get() def __bookbool_rec(self): return BIFFRecords.BookBoolRecord().get() def __all_fonts_num_formats_xf_styles_rec(self): return self.__styles.get_biff_data() def __palette_rec(self): if self.__custom_palette_b8 is None: return '' info = BIFFRecords.PaletteRecord(self.__custom_palette_b8).get() return info def __useselfs_rec(self): return BIFFRecords.UseSelfsRecord().get() def __boundsheets_rec(self, data_len_before, data_len_after, sheet_biff_lens): # ................................. # BOUNDSEHEET0 # BOUNDSEHEET1 # BOUNDSEHEET2 # .................................. # WORKSHEET0 # WORKSHEET1 # WORKSHEET2 boundsheets_len = 0 for sheet in self.__worksheets: boundsheets_len += len(BIFFRecords.BoundSheetRecord( 0x00L, sheet.visibility, sheet.name, self.encoding ).get()) start = data_len_before + boundsheets_len + data_len_after result = '' for sheet_biff_len, sheet in zip(sheet_biff_lens, self.__worksheets): result += BIFFRecords.BoundSheetRecord( start, sheet.visibility, sheet.name, self.encoding ).get() start += sheet_biff_len return result def __all_links_rec(self): pieces = [] temp = [(idx, tag) for tag, idx in self._supbook_xref.items()] temp.sort() for idx, tag in temp: stype, snum = tag if stype == 'ownbook': rec = BIFFRecords.InternalReferenceSupBookRecord(len(self.__worksheets)).get() pieces.append(rec) elif stype == 'xcall': rec = BIFFRecords.XcallSupBookRecord().get() pieces.append(rec) temp = [(idx, name) for name, idx in self._xcall_xref.items()] temp.sort() for idx, name in temp: rec = BIFFRecords.ExternnameRecord( options=0, index=0, name=name, fmla='\x02\x00\x1c\x17').get() pieces.append(rec) else: raise Exception('unknown supbook stype %r' % stype) if len(self.__sheet_refs) > 0: # get references in index order temp = [(idx, ref) for ref, idx in self.__sheet_refs.items()] temp.sort() temp = [ref for idx, ref in temp] externsheet_record = BIFFRecords.ExternSheetRecord(temp).get() pieces.append(externsheet_record) return ''.join(pieces) def __sst_rec(self): return self.__sst.get_biff_record() def __ext_sst_rec(self, abs_stream_pos): return '' #return BIFFRecords.ExtSSTRecord(abs_stream_pos, self.sst_record.str_placement, #self.sst_record.portions_len).get() def get_biff_data(self): before = '' before += self.__bof_rec() before += self.__intf_hdr_rec() before += self.__intf_mms_rec() before += self.__intf_end_rec() before += self.__write_access_rec() before += self.__codepage_rec() before += self.__dsf_rec() before += self.__tabid_rec() before += self.__fngroupcount_rec() before += self.__wnd_protect_rec() before += self.__protect_rec() before += self.__obj_protect_rec() before += self.__password_rec() before += self.__prot4rev_rec() before += self.__prot4rev_pass_rec() before += self.__backup_rec() before += self.__hide_obj_rec() before += self.__window1_rec() before += self.__datemode_rec() before += self.__precision_rec() before += self.__refresh_all_rec() before += self.__bookbool_rec() before += self.__all_fonts_num_formats_xf_styles_rec() before += self.__palette_rec() before += self.__useselfs_rec() country = self.__country_rec() all_links = self.__all_links_rec() shared_str_table = self.__sst_rec() after = country + all_links + shared_str_table ext_sst = self.__ext_sst_rec(0) # need fake cause we need calc stream pos eof = self.__eof_rec() self.__worksheets[self.__active_sheet].selected = True sheets = '' sheet_biff_lens = [] for sheet in self.__worksheets: data = sheet.get_biff_data() sheets += data sheet_biff_lens.append(len(data)) bundlesheets = self.__boundsheets_rec(len(before), len(after)+len(ext_sst)+len(eof), sheet_biff_lens) sst_stream_pos = len(before) + len(bundlesheets) + len(country) + len(all_links) ext_sst = self.__ext_sst_rec(sst_stream_pos) return before + bundlesheets + after + ext_sst + eof + sheets def save(self, filename): import CompoundDoc doc = CompoundDoc.XlsDoc() doc.save(filename, self.get_biff_data()) xlwt-0.7.5/xlwt/BIFFRecords.py0000644000175000017500000027600512127661475014250 0ustar janjan# -*- coding: cp1252 -*- from struct import pack from UnicodeUtils import upack1, upack2, upack2rt class SharedStringTable(object): _SST_ID = 0x00FC _CONTINUE_ID = 0x003C def __init__(self, encoding): self.encoding = encoding self._str_indexes = {} self._rt_indexes = {} self._tally = [] self._add_calls = 0 # Following 3 attrs are used for temporary storage in the # get_biff_record() method and methods called by it. The pseudo- # initialisation here is for documentation purposes only. self._sst_record = None self._continues = None self._current_piece = None def add_str(self, s): if self.encoding != 'ascii' and not isinstance(s, unicode): s = unicode(s, self.encoding) self._add_calls += 1 if s not in self._str_indexes: idx = len(self._str_indexes) + len(self._rt_indexes) self._str_indexes[s] = idx self._tally.append(1) else: idx = self._str_indexes[s] self._tally[idx] += 1 return idx def add_rt(self, rt): rtList = [] for s, xf in rt: if self.encoding != 'ascii' and not isinstance(s, unicode): s = unicode(s, self.encoding) rtList.append((s, xf)) rt = tuple(rtList) self._add_calls += 1 if rt not in self._rt_indexes: idx = len(self._str_indexes) + len(self._rt_indexes) self._rt_indexes[rt] = idx self._tally.append(1) else: idx = self._rt_indexes[rt] self._tally[idx] += 1 return idx def del_str(self, idx): # This is called when we are replacing the contents of a string cell. # handles both regular and rt strings assert self._tally[idx] > 0 self._tally[idx] -= 1 self._add_calls -= 1 def str_index(self, s): return self._str_indexes[s] def rt_index(self, rt): return self._rt_indexes[rt] def get_biff_record(self): self._sst_record = '' self._continues = [None, None] self._current_piece = pack(' 0x2020: # limit for BIFF7/8 chunks = [] pos = 0 while pos < len(data): chunk_pos = pos + 0x2020 chunk = data[pos:chunk_pos] chunks.append(chunk) pos = chunk_pos continues = pack('<2H', self._REC_ID, len(chunks[0])) + chunks[0] for chunk in chunks[1:]: continues += pack('<2H%ds'%len(chunk), 0x003C, len(chunk), chunk) # 0x003C -- CONTINUE record id return continues else: return self.get_rec_header() + data class Biff8BOFRecord(BiffRecord): """ Offset Size Contents 0 2 Version, contains 0600H for BIFF8 and BIFF8X 2 2 Type of the following data: 0005H = Workbook globals 0006H = Visual Basic module 0010H = Worksheet 0020H = Chart 0040H = Macro sheet 0100H = Workspace file 4 2 Build identifier 6 2 Build year 8 4 File history flags 12 4 Lowest Excel version that can read all records in this file """ _REC_ID = 0x0809 # stream types BOOK_GLOBAL = 0x0005 VB_MODULE = 0x0006 WORKSHEET = 0x0010 CHART = 0x0020 MACROSHEET = 0x0040 WORKSPACE = 0x0100 def __init__(self, rec_type): version = 0x0600 build = 0x0DBB year = 0x07CC file_hist_flags = 0x00L ver_can_read = 0x06L self._rec_data = pack('<4H2I', version, rec_type, build, year, file_hist_flags, ver_can_read) class InteraceHdrRecord(BiffRecord): _REC_ID = 0x00E1 def __init__(self): self._rec_data = pack('BB', 0xB0, 0x04) class InteraceEndRecord(BiffRecord): _REC_ID = 0x00E2 def __init__(self): self._rec_data = '' class MMSRecord(BiffRecord): _REC_ID = 0x00C1 def __init__(self): self._rec_data = pack('> 15 c = low_15 | high_15 passwd_hash ^= c passwd_hash ^= len(plaintext) passwd_hash ^= 0xCE4B return passwd_hash def __init__(self, passwd = ""): self._rec_data = pack('