'#174
- +#230#163#254'i'#159#202#185#25'+/'#127'T}'#246#27#127'G]'#255#220'W'#223#215
- +#251#151#206'>g5'#254#188'P'#251#179'\l~'#29#235#207#165#188'W'#199#251#181
- +#218#159#10#248#19'&'#130#153#26'o'#223'S'#253#135'?`'#211' [,'#172#215#191
- +#17#206#251'/'#147#221'/'#223#4#213#31'&'#192#152#22#132#130#224#12#180#170
- +'?-'#152#231#15#14#193#145#211#236#243#185'I'#127#251#155#143'iX'#135' &'#20
- +'%'#192'cZ'#241'Mt'#14#130'/'#0#166#0#189#230#10'-k'#15'G'#189#183'v'''#205
- +#151#141'w_;'#250'b'#213'\'#135'?'#224'u'#21#213'$1'#168#17'["'#240'M[q'#19
- +#30#180'='#5'i'#9#138#217#134'r'#201#21'8'#15'n'#129'{'#255#231#191#169#255
- +#250';'#191'z'#218#167'q'#166'Gs'#253#138'z'#233#203'_S?'#243'+'#191#165#234
- +#171#155#207#245#179'M#'#15'//'#8#0#21'}'#153#16#0#219#253#146#230#11#149#30
- +'E> '#0#150#254#0#255'Tk'#1#179#193#158#218#187#253#135#244#191#194#238'W'
- +#176#251#189'd'#241#234#202#246#247'B'#178#255#149#168#254#180'L'#137#4'0'
- +#203'/:'#253#222#147'f'#159'w$'#1'h'#219'8'#254#158'W'#216#175':'#142#149#0
- +#224#16#252#214#183#190#197'MC'#136#201'Z'#244#195'`'#152']'#22'-'#0'$pM!J'
- +#160#188#149'w'#247#214#190'0Kk=eH'#0#210#157'H'#160's'#249'5'#186#233'/IRP'
- +#205'j'#1#8#13#194#28#240'b'#157'#'#160#195#131#18'"4'#25#131#158''''#10#192
- +#249#9#19#254#254#223#254'e'#245#240'";'#176'4'#26'kW'#212#205#159#255#154'z'
- +#235#24'@_'#26#206#196#157'6'#209'G&'#241#204#165#161'g.'#177'~V'#253#167#218
- +#238'O'#5#252')'#183#249#30#178#211'o1'#30'j'#233#159'&'#186'4'#152#237#254
- +#189'w'#218#209#180'oT'#127'z>9'#230'Ok4'#250#228'f'#31' '#0#244#249#203#178
- +#12#190#128#253#227'p'#252#185#227#184'aa'#29#130#244#163'j'#164#1'tMn'#0'H@'
- +#136#0#29#133#215#147'<'#218#248#233#222#250#23'3'#130#189'q'#10#194#31#0'{'
- +#191's'#245#227#170#209#187','#192#143#181'?'#192'5'#7'b]>\'#20#14'A'#11#208
- +'D'#144#151#10#136#156#159#251#164'_~'#18#254#129'C'#190#31's'#1#254#222#175
- +#127'A'#141#30#221'9'#129#147'8'#187#163#177'vYK'#250'_'#251'['#31#12#244'O{'
- +#194#141#202#159#231#142#237'o'#192#159#217#226#158'\'#178#252'8'#140'7[X'
- +#192'C'#242#167'Sc'#255#143#9#252#127#164'f'#163'}Q'#253#19#235'7Xo'#142#238
- +'m6'#251#144#240#244'Hz'#166#216'g'#12#144'#'#227'O'#21#210#255'.'#225#4#181
- +#254#187#180' '#230'?'#251#250#215#191#158'>O'#199#223#179'\'#158#231#241#249
- +#236#16#188'v'#237'ZD?'#166'I?'#142'M'#1':~]'#242#2#224#16#132'V'#176#218#159
- +'7n'#222#31#174'|'#138#253#1#220#16'$'#212#243#6#196#177#234'^{K'#213'z'#235
- +'L'#0'69'#168')'#249#1'5m'#10#232'D'#161'P'#207'1`'#252#2#158'8'#6#13#1'x:'
- +#195#235','#155#4#217'|'#170#254#227'o|^M'#182#31#156#246#169#156#232#208#160
- +#255#243#234#19#4'zl'#31#247'0A'#23#207#216#251#210#196#147#255'!'#192'5Y~'
- +#185#128#31#146'?'#19#181#127'!$'#144'Ng'#236#245#239#223#253#174#154#13'w4'
- +#248#209#223#15#170#127#134'x?'#236#254#157#183#229#27'!'#253#145#245'7'#161
- +#239#178'1'#127'I'#246'A'#143'?T'#254'm#'#227#143#204#229#217'q8'#254#220'q'
- +#18'0`-'#128#214#193#189'{'#247'0'#181'x'#11#141'C'#148#6#189'!'#1#248#5'6i{'
- +'e{'#210'}'#227#241#164#253#154'.'#24#242#25#208' '#129#176#214'P'#221#171'o'
- +'q'#255#128'@'#204#129#192#248#3#140'S'#208'!'#1#27#29'p'#27#140'B#p'#253#1
- +'v6'#226#167'\'#134#147'L)'#150's'#193#148#224#223#250#245#159'S'#211#189#173
- +#147#251#238#19#30'A\S'#221#151'^W'#215#190#240#139#234#245#191#240#13#213'X'
- +#127'N'#160'?'#202#253't<'#253'&'#191'7wm'#254#212'H'#254#2#252#25#131'_'''
- +#251'X'#181#31#14#192#217'L'#245#31'|_M'#247#183#216''#239#186#170#127#179#217#156#16
- +'^'#22#199#225#248'+]'#138#227#248#208'e'#223'cL'#1#218#174#199'q'#220'Y,'#22
- +'k'#196'vp'#2#26#18#192#246#6#189#180#247'`'#216'{s'#127#214#188'a'#253#1'a'
- +#164'g'#24#170#183'T'#239#198'[*nuu'#211#16'h'#2#13#153'h'#148#246#217#31'P3'
- +#230'@A'#2'z'#242'Q_'#151#17'{^'#209'r'#251#6#242#202#229#240'N'#185#167'X'
- +'Bv'#228#127#250#198#159'T'#227#199#247'O'#245'<'#158#215#128'F'#215#190#246
- +#138#186#242#179#127'Z}'#228'k'#191#161'z/'#127#244#216#190#235'i'#247#210
- +#230#243#155'F'#30#166#176'G'#156'}'#214#219#15#135'_R'#128#159#157'~'#211'"'
- ,#236#135#253#193#131#183#9#252#247#11#143'?'#252#4'Y'#170'B/'#153#223'$'#240
- +#199'~2sC~2'#193#7#167#251'*'#173#250#223#145'\'#255'GF'#245''''#201#143#196
- +#160#244'8'#165#191#190'.''3'#216#20#248#202'W'#190#226#147#25#16#175#172#172
- +'4'#8#252']'#250#161#27'2'#185'('#204#0#16#1'G'#5#8#176#157#187#131#149'O'#14
- +#231#141'K'#202')'#29#230#28#129'f['#245#174#127#146#236#255#150#245#9'0'#17
- +#196#146#31' '#154#128'I'#27'6'#181#3#158#211'_'#176#152's@'#251#8#220'^'#131
- +'O'#157#233#229#20#198'w'#254#233'7'#213';'#255#254#159')'#253#12#157#159#1
- +#226'mn^W'#151'>'#253'e'#245#234'/'#253'U'#181#249#214#23#143#241#203#158#208
- +#198'/'#175#188#206'H{'''#179'O'#247#242'3'#224#207'X'#234'g'#21#201#207#241
- +'~'#2'}'#6'{_'#136#0#165#189#147#157#247#24#252#186#181#151#158#212#211#207
- +#210#228#229#149#237#31#212#130#197#196#181#251#149#14#249#193#238#223#18#213
- +#31's'#252'q'#200#143#182'w'#8#15#195#231'Y'#236's'#132#203'vb'#195#166#9'_'
- +#191'~'#29#154'@'#11#181#2#240#7#208#15#191'*aA'#204'1'#8'=p5'#247#252#206
- +#157#254#234#167#198'I}'#213#23#167#160#23#232','#192#184#217'c'#18#8#26'uM'
- +#0'l'#18'D'#146')'#136#16#161'4'#18'A'#152#208#180#21#243#29#18'0'#221#133'<'
- +'!'#0#229#2#255'9D'#12#142'a6'#227#225#253#159#168#255#254#219#191#172#134
- +#247'~z'#130#183#236#217#6#8#186#190#178#169#214'>'#254#179#234#213'?'#251'+'
- +#234#218#159#248#165#163#191#249#176'k'#246'<'#158'PG'#218'kG'#191#201#231
- +#207'm#'#143#194#230'/'#210'{y'#153#27#169#191#208#192#135#148#135#250'O'#132
- +'0'#217#190#163'F[?"'#146#152'Ks'#15']'#223#143'?7'#187'{o7'#194#217#208#177
- +#251#231#244'l'#163#197#23#18'='#182'%'#215#159#193'O8'#128#25#176#141#132
- +#159#157#157#157#169'x'#253#13#248'_'#24#2#224#239's'#19#132#8#248#173'$I'
- +#216#31'@'#11'B'#130#208#4#216#31'@'#235#149'\'#249#157'w'#247#214'?='#205
- +#162#14#146#132#152#4#184'7'#0#145'@gMu'#174#189'%'#229#194#162#1#152#252#0
- +'h'#1#146'-X8'#6#203#154'@a'#18#248#197#228'#N1'#209'Y'#237'='#248#255#254
- +#205'?R?'#248'w'#255'DMw'#30#158#234'y'#4#245#166'jn\S+'#175'}'#130'$'#252
- +#159'R7'#190#244#231'T}'#253#202'i_'#158#202#200#203#210'_Rz='#227#236#147'r'
- +'^'#6#191#163#246'['#240#139#202#15#224#179'z'#207'*'#191#246#1#204'v'#31#168
- +#193#195#183#233'usn'#238#193#239'Cyo'#154#229'W'#187'{?'#236#196#147#190#168
- +'l'#214#238#23#167#223'.'#236'~ZX'#245#135#211#143'0'#240#152#222#187'O'#166
- +#241#4#9'?'#199#233#245#175#142#211'x'#202'}'#152#2#180#6#9'X'#127#0#217'?'
- +#151#29'S'#0#26#1#252#1#221'$'#243#187#239#246#215'?'#179#200#163#134'o'#204
- +#1#216#247'$'#233#153#4#174'|'#156'H'#160'nA'#207'f'#128'h'#4'L'#2#145'&'#1
- +#21#233#168#2#147'@h'#8'@r'#5'|'#129';'#214'2)'#225'Y'#159#166'|'#240#222#219
- +#234#143#255#249#223'W'#15#254#247#31#208'C99'#190'/'#162'k'#17#183'{'#170'u'
- +#245'e'#181#250#209#207#168'+'#159#251#170#186#250#249#175#210#245#175#159
- +#246'%x'#250'03L'#219#130#30'c'#231#23#253#251#140#167#223'H~V'#225#231'I'#1
- +'x'#6#255#156#155'{'#178'&@'#255#155#238#222'U'#163'G'#210#206'{Q'#168#253' '
- +#146#203#173'}L'#231#181#131'/q'#156'~H'#245'E'#188#127#15#133'='#180#141'F'
- +#144'P'#251#225#244'{D'#207#245#222'I'#218#253#238'8'#141'G|'#169'?@f'#22'b'
- +#167#160#210'Z'#0#182#215#233#1#236#204#147'`'#229#189#254#250#167#19#21#198
- +''#28#234'#p'#231'R'#217#151'I'
- +#184#15#142'>'#14#251#137#31'`'#188#253#30'-'#239'jR'#224'i'#188'S'#142#22#0
- +#252#27#205#193#237#245#198#240#145#11'~z'#182#140#221#15#240'o'#153'J?z'#230
- +#239#201'4'#223#232#240#131#6' '#199#150#237#247','#151#242#196#190#215#245#7
- +#208#197'h'#18#248'{'#164#10'm'#18#192#175'Hx'#144#179#4'iY'#3#9#204#210'x'
- +#237#246#254#250'''3'#207#15'Yr#<'#24'j'#18#8#27'm'#213'!'#18#136#154#29#2'~'
- +'h'#181#0#228#8'x'#236#20',H'#128#181#129'J'#152#208#212#17#24#18'`'#231' t'
- +#148#220#153#144#164'`'#132#234#147#246#244'+y'#10#4'1'#219'{'#172#230#253#29
- +'5'#31#236#210'zO-'#134#251'\9'#217'}'#249#13#213#185#249#250#217#149#224'G'
- +#189#142'K'#239'C'#17#222's[u'#219#16#159#11#254#170#212#151#220#254'L'#154
- +'z'#148#9'@K'#255#209#214#143#213'd'#239#30#189'n'#206#145#1'~'#159#228#248
- +#175#214'F'#15#174#180#251'w'#243#2#252#200#244#131#221#15#240#195#238#127','
- +'!'#191'{R'#223#15#27'n{:'#157#14#136#0#160#194'%''e'#247#31#245'r'#31#251'w'
- +'W'#243#3#200#28'@3'#209'Md'#10'*'#237#16#196#26'$'#176'J m'#141#23#181#205
- +#187#253#213#183#136#4#2'm'#207#11#9'p'#4#160#201#230'@D'#234#170#213#4#156
- +#181#23#11#17#24'M'#128'L'#2#21'j'#191#130'2s'#17#26's'#192'M'#30'2UEn'#163
- +#145'3l'#26'|'#232'F^'#10#226#8#224'M'#21#159#210#158'}'#137#239#187'i'#189
- +#218#230#215#128#207#13#248#173#228'_0'#200#217#241'7'#211#161#190#225#163
- ,#183#213#172#255'H'#146'|'#140#218#175'k'#251#187#209'd'#235'zw'#239'=m]d'
- +#153'x'#252#145#236#3#240'#'#151#127'['#233'y'#253#24#252#216'F'#178#207'I'
- +#198#251#15#27#167#253'('#151'R'#133'I'#11'h#'#25#136#180#128'K'#208#4'h'#31
- +'Z'#0'H'#0#164#176'B@lM'#147'x'#237'N'#127#245#19#169#23#198#218#179'/>'#1
- +#174#12#172#17#9'|L'#197#157'uM'#10#198#15'`'#192'/m'#198'=!'#2'_z'#10'('#19
- +'%'#16#231#160'2'#230#128#239#21#4'`'#174#214#139'>]'#241'y'#25'.'#234']sGl|'
- +'O'#202'wm'#3#143#170#179#207'8'#250#0'f'#212#243'/'#28#240#27#231#31#175#167
- +'j'#240#240#7#164'ImK'#140'?'#209#196#145'j'#240#175#213'F'#247'/'#183#145
- +#226'k'#193#159'I'#154'/g'#250')]'#226#251'H'#230#245#131#228#199#164#30#143
- +'1'#171#207'|>'#31#31'w'#170#239'Q.'#227'i'#223'F'#207'8'#5#209'@'#4']'#132
- +#208'P'#212#9#15'"O'#224#138#201#20#4#9'$y'#220#189#189#191#250#214'BE'#245
- +#18#9#136's'#176's'#249#13#21'w/'#177'/'#192'3'#181#2#177#244#16#176'&A'#164
- +#253#2'b'#14#168#208'/'#146#134#140'i '#13'F'#172'F`'#175#152#163#10#156#159
- +':'#163#23'f'#148#146'xl'#171'.}'#140#193#159'i'#201'oc'#251#169'n'#226#1#240
- +'+'''#204#151'K'#190'>'#171#244'3'#241#250#211#177'\B'#127#201't'#162#6#247
- +#191#175#18#228#246'''s'#157#21#232#128#127#163'1'#184#189#217#28'>'#210#138
- +'F'#150';'#146#31'*={'#252#149#238#237#7#240#223#151'p'#223'cH'#254#197'b1'
- +#186'v'#237#26#156#131''''#234#244#171#142#179#240#236'Z'#18#232't:1'#177'b'
- +#157'.T'#27#149#131#232'$'#4#2'0$ '#173#198'A'#2#205'L'#133#237#219#253#181
- +'7gY'#220#214'}'#0#196#174#143't)qk'#243#150'j'#172'^'#215#146#222#1#189#217
- +'f-'#160#166#147#139'8Dh'#219#142#7#133's0'#240#10#141#192'I rs'#137#205'f~'
- +#224'''='#225#10'?'#211#173'>'#175']'#130#142#248'h='#245#250','#191#178#185
- +#211#151#223#5#191#246#238#235#248#190'J'#181#202#175#4#176#156#155#159':'
- +#246#254'\'#131'?'#183'j'#191'd'#242#17#25'$'#147#161#234#223#255#158'Ji]H~'
- +#157#225#167#210','#191#220#217#255#201'j<'#217#21#193'o'#193#175#138#190'~'
- +#166#190#255#1#164#191#132#254#30#163#190#159#198#168#209'h'#204#143';'#207
- +#255'9'#222#165#227'?'#15'S:'#140#162#161#241'x'#140#134#162#29#169#25#184'd'
- +'4'#1#165#251#7#160#177'H'#143#174'X'#147#16#218#188#211'_'#251#216'8'#173
- +#173'x2'#239#160#206#254#211#18#191#190'rU'#181#214'oiM'#192#250#1'B'#157',$'
- +'d'#224'I%'#161#138#138#190#2#166#152'Hq'#132#192#244#23#240#203#145#2#167
- +#243'P.'#161#195#234#21#245#202#127#158'q'#228'O'#220'='#179#195'{'#234#129
- +#167#255#238'|'#201#207#21#144#27#129#175#14#11#237'9'#133'<*-b'#251#197#162
- +#129#207#210#127#190#144'p'#223'B'#180#129#5#255'o>'#216'a'#155'?'#157#142'u'
- +''''#31'Z'#148#128#223'#'#241#127#181#187#247#163'n8'#27','#3#191#210#225'>'
- +#128#31'-'#188#31#144'&'#203#14'?'#228#248'#'#220'G'#175#27#161#200'G'#157
- +#146#211#239#131#222#157'c='#23#248#3'~'#252#227#31#251'h%F'#154'@'#195#228#8
- +'`V!'#164#12#131#8'h'#141#164'!4'#26#237#210'Uk'#17#240#234#247#6'k'#175#15
- +#23#245#13'c'#14'0'#17'DP'#241#145':'#220'Sm2'#9'PG'#224'K?'#193#2#252#142'6'
- +#192#254#0'c'#14#232'm'#155'8Ti9f'#195#134#158#201'(tr'#207#171#253#7#204#173
- +'=KW'#250','#143#202#245#202#157#166#156'%'#208#27#162#200#164'eW'#150#29'H'
- +#231'Ui'#1'z'#227#237'O%'#212#151#207#231#142#195'O|'#0'D'#2#147#221#219'j'
- +#178#253#158#222'w$?>'#223#167#15#184#222#219'{'#167#21#204#199'K'#192'ob'
- +#253'h'#234#137'4_+'#249#233#153'}L'#160#223#165#231#23'5'#0' '#137'3'#1'~'
- +#231'2'#159#153#193'$'#240#189#239'}/@x'#16'$@Z@W'#26#137#184#154#0'"'#3#235
- +'('#28#162#27#129#18#227#248#254#160'wko'#222#188#234'['#245']k'#2#200#26#244
- +#227#26#153#4#31'Q'#181#206#166#150#248#174#244#23#223#128#206#17'0'#249#2
- +#129#205#30'TN'#6#161#237'@'#236#251#5#1'8m'#201#221#26#3#235#164#170#22#27
- +#157#181'+~F'#134'Wr'#228#185#155#249#1#240'k'''#159'H'#251#180#144#250#165
- +'t^'#168#251#137#238#215#175#9'@<'#254#226#237'7'#26#0#19#0#166#233#154'N'
- +#213#136#164#254'|'#180#171#227#251'IR'#2#127#160#146#217'K'#221#221#31#214
- +#131#197'T'#192'o'#28'~F'#242's'#129#15'r'#252#209#220#3#146#31#26#0#212#254
- +'('#138'v'#7#131#193#136#180#218#19'M'#243'='#210'u?'#237#19'XvN&<'#184#181
- +#181#21#211'Ek'#208#5'4$'#128'lA'#180#24#135')'#192'$@'#251']'#248#4#232'X'
- +#237#209#168#243#210#246#180'}SO8bH@2'#0#137#8#234#189#171#170#185#241'*'#131
- +#222's'#181#129'H'#147#129'''-'#199#149'q'#14'F'#21'm'#192'u'#16#154'z'#2'&'
- +#3'eg)'#202#29'2p'#181#255#220'!'#133#15'f'#26#188'(C'#210'u\'#137#159#23#181
- +#249#202'sT}'#199#201'W'#168#249'"'#245#197#214#231'2'#222#180'p'#242'1'#232
- +#165#148#215'z'#252#141#234'/'#170'>'#219#254#201'B-'#250#187'j'#184#245#14
- +#29#27#219#200#128#174#229#151#137';'#189#249#228#165#238#222#15#185#170#143
- +#235#8'l'#168#143'S|'#149'd'#249')'#237#224'C'#184#15'R'#255#1#212'~'#178#249
- +'w'#233#249#29'6'#155#205')i'#183#201'iz'#252#151#141#179#250#4#150'H'#160'A'
- +'c2'#153#160#145#8#155#3'B'#2' '#3#209#4'T'#151#128#136#190#131#181#253'Yc'
- +#243#225#168#251'Z'#166#194'PKn'#169'!'#8'C1'#9#186#164#13#188#193#213#132#0
- +'>'#28#129#158'D'#4#220#16#161#155'9'#168#156'Z'#2#229#18#129#231#23#179#22
- ,#251#198'I'#232'j'#3'E'#30'a'#238#148#25'z'#213#146#195#3#153'mg'#245#182#188
- +#223#187#249#4#127#134#233#191#167#156#198#28'|'#188#2'zP'#168#3'~'#211#173
- +#135'U}'#9#239')'#167'O?'#188#245#249#28#251#11'+'#249's)'#238#201'%'#207'?'
- +''''#240#143'wn'#171')-'#153'y]*R_f'#238'iG'#147#237#171#173#253#219#129#151
- +'&:'#151'(3e'#189#240#246'3'#248#149#206#242'CO?'#246#248#195#230'G'#168#15
- +#224#167'eH'#166#236#20#177#254#179#6'~}'#205#207#238#176#133'C'#4#254#136'.'
- +'b'#147'L'#130'.H@:'#10']6'#225'A%$'#128#16'!H`'#158#133#237#187#131#222#235
- +#179#172#214#230'y'#3#140'o'#192#132#10#163#186'j_zM'#197#221#205#2#248'f1'#4
- +#16'W'#142#7#186#211#144#178#243#19#6'em@'#26#143#148'#'#6#158#149#244#172#29
- +','#137#30#152#249#11#142'zG'#206#204#147#227#222#168#167#189' ?'#252#128'i'
- +#197#229'y'#14#248'3'''#150#175#28#27#223'Q'#247'y'#31#182#190#27#222'K'#11
- +#137#159#27#208''':'#181'7/'#145'@'#194#245#19'#'#146#250#243#225#142'h'#11
- +':'#188#167#138#30'~'#217#165'F'#255#246'Zc'#244#152'S{%'#212#167'tz/O'#223
- +'-s'#248'A'#237'7'#137'>'#15#207#19#248#143't'#239'N'#251#252#12#9#244#251
- +#253#184#213'j5'#232#226#162#197#248#154#132#4#225#16#188#12#173'@i'#18#232
- +'1'#9'('#175#158#7'~'#252'p'#208#189#185'?o]-'#146'|t'#184#15'&'#129'oL'#130
- +#245'W'#8#236#177#205#9#240'L'#5'a'#172'5'#6#171#9'p'#10'qPT'#21#210':'#15
- +#220')'#202#140'V'#224#21'D'#160#138#237'"JP'#172'K%'#200#206'f^9'#236'='#235
- +#173'z'#158'w'#245#153#31#215#188#152'>'#219'='#149#188#188#145';/'#178#245
- +#249'n'#18#143#177#243'MG^'#145#250'*u$'#191'c'#235#27'/?'#219#237#12#244'E'
- +#161#254#207#11'R'#192#255#23#240#242'?'#254'!i'#1#19#177#247'u|'#223'|n'#228
- +'/&'#215#218'{?i'#132's'#174#229#23'G'#4#236'}'#147#222';'#145'P'#31#171#253
- +'J'#194'}'#178'F'#169#239#222'y'#0#127#233#254#156#209#193#231'W%'#1'd'#12'"'
- +'Y'#136'.'#178'!'#1#152#5#151'0'#247#128#210'y'#2'm'#186#212'u'#146#184#241
- +'p'#222'X{0^'#185#149#145#236#215'@-'#155#4'H!'#6#9#196#157#13#201#7#144#136
- +#128#1#191')$'#10'+$ '#11#147#138'h'#6#156'N,'#145#130'\'#162#6'V'#27'x'#26
- +#17'8'#221#137'rG;'#240#202'^'#196''''#220#177#147#184#149#249#225#135'+'#167
- +'i'#140'{'#175#244'6'#167'<'#23#0'WO'#0'~^'#150#248#202#22#239'8N>c'#239#187
- +'v'#191#149#252#139#18#240'Y'#19#152'N'#213'd'#251#167'j6'#220'b'#130'@'#179
- +#15'+'#241'3=__'''#154'<'#190#210#234#223'!'#149'?'#205'm'#147'@]'#210#235'd'
- +#248#245#165#178#15#222#254'G'#146#215#255'H4'#129'}8'#252'666'#206'<'#248
- +#237#253'9'#227#195#146#128#18#159#128#146'2b"'#130#21'h'#2#146'%h'#178#5'9Y'
- +#136'$r'#155#192#211#160';'#23'''Y'#212#184';'#236#189'6Kk'#29'S'#0'd'#27#140
- +#8#184#163#214#26#19'APo'#21#17#1#167#138#208's'#251#10'<'#137#8#220#148'b'
- +#153#194#220#134#14#205#196'%'#165')'#204#202'k7'#132'h'#230'4'#176#135#14
- +#132#20#143'n:<'#151'q'#152'*o'#156'v'#246#144#145#236#230#127#249#146#216
- +#189'~'#157#14#227'I'#230#158'!'#2'k'#227'/Q'#247'S'#145#248#2'|'#181#208#149
- +'|J'#236'w'#215#222'7'#206'?E'#251#147#254'=5'#221#189#173#19#127#210'%*?}'
- +#209#229#198#224#189#149#198'h'#199#203'MI'#143#14#243')'#1'?'#173#199#180
- +#223#151#154'~4k'#132#196'GE'#31#182#183'I('#161#145'''{'#251#201'\=s'#14#191
- +'e'#227'<'#16#128'=OC'#2#251#251#251#17']'#228':]x'#174#29#136#162'h'#157#246
- +'a'#6'\'#18''''#225#134#212#14'th'#27'}'#4'b'#210#0#162'G'#195#206'K{U'#147
- +' '#212#201'C'#138#171#11'#U'#235']S'#245#181#27#156'M'#200#14'@'#199#4#0#1
- +'(''Dh'#136#192#148#24'+'#153#181'X'#249#229#198'#'#182#21'Y%'#179'P'#231#15
- +'-'''#3#207#209#255#139#222#4#166#151#161'{UN'#136#4#170#143#176#19#182'+m'
- +#229#5'Y'#149'CxN'#165#158#27#198'3N='''#150'oA'#159#154'm'#0'>#b'#0#160'u'
- +#17#143'Z'#20#13';'#173#199'?IJ>'#0#132#0#147#209#158#154#236#252'D-&'#131'B'
- +#213#135#169#128#207'pU'#254#238#238'O'#234'^2'#245't'#229'@'#213#211'?'#147
- +#22#222#168#234#219'q'#193#15'O'#127#24#134#232#235#223'_,'#22#227#25#141#243
- +#2'~'#140#243'B'#0#246'\'#221'<'#1'8'#252#232#194#183#232'p'#143'.'#254#186
- +'8'#7'A'#4#156','#132'V'#227'$'#129';$u'#27#180'_#'#240'E'#131'i}'#237#193
- +#164#247'j'#150#235#249#7#180#147'0`'#21#222#244#16#132'Y'#208'X{'#133#139
- +#138#188#208#137#6#200#220#3#134#8'4q'#4#162#29#136'&`{'#13'8]'#137#131#138
- +#163'P'#8#161'hF"'#19#152#28'H76'#161#195#162','#185#240#15'T='#3'G'#200'1'
- +#248#160'%'#203'y^yi'#25#240'z'#229'4'#218'TE|'#159'%'#189#153'l'#195#190#230
- +#160#154#207#246'~'#154#149#218'r+'#150#250#153#6#173#0'_'#137'='#175#164#131
- +#143'2'#4#144'h'#239#127':''u'#127#231']5'#239'?'#210#173#186'L'#26'p'#146#10
- +#209'h'#149#31#149'|'#151'['#253#187'P'#249'9'#188#143#254'}'#160'!m'#239#219
- +#24#191#1#191#210'e'#189#15'e'#198#222#199'R'#207'? '#1'4>K'#25'~G'#29#231
- +#137#0#236'9'#155#180'a'#218#142#26#141'F'#13#17#2#164#7#27#231#160'8'#5'/'
- +#217#218#1#29'&'#132's'#176#6#147' Sa'#252'h'#220'~'#169'?onz@'#166#137#20
- +#216'f!Z'#226#195',h'#192', B'#176'R'#223#1#188'Bd '#22'B'#16'M@9'#25#132#214
- +'I'#24'>A+8'#204'GP'#154#242#188#186'v:'#26'['#13#193#161#130#165#190#130'CB'
- +#143'O'#200#187#183#160'.%'#224#23#26'H.'#234'})Q'#199'%'#0#215#147'/'#158'}'
- ,#163#226#219'p'#158'q'#240'Y'#208#167'b'#231';'#158'}l'#11#192#181#202#175
- +#215':'#175#223'8'#2'%vO'#235#217#222'}5'#222#131#186'?'#211#199#229'3y'#157
- +#167'"'#245#147#201#149#230#254#237'f<'#27'z'#26#247'8'#15#146#250'%{'#223'&'
- +#248#208#178'C'#210#254'1'#9#153'G'#210#213'g'#155#128#191'K'#160#31#160#149
- +#23#13#152#8#231#10#252'K'#158#138's3,'#9#208#197#15'k4'#200#12'h"B'#16#4#193
- +#170#227#23#128'F'#0#18'X'#5'A B &A'#148#19#196''''#139#176#253'p'#178#242
- +#202','#141'ZE'#235#240#162'('#200#147'9'#10'k'#221'+'#170#182'rM'#5'h'#162
- +#17#154'y'#8#3#199#28'pM'#3#9#17#134'RK`'#10#140'l'#14'A Z'#129#201'$t'#218
- +#146'U'#137#160'j*'#148#202#146'+'#21#137#21'G'#162';'#242''''#146'A'#165#216
- +'f'#217'c'#235'Jw'#222#168#172'e;7'#137'<'#153#27#190'3'#137'<'#142#164'wc'
- +#249#2'|'#29#203'/'#192#175#137#192#9#241#217't^'#13'r'#237#3'H'#10''' -'#139
- +#225#14#219#249#9#171#251#186'I'#167#146'L>'#179#246#232#207'j}t'#127#189'1x'
- +#228#177#180#207'3'#147#214#171'$'#190'O'#203'\j'#249#135#226#233#135's'#15
- +#210#30#249#252'['#178#191'O'#207#220#160#223#239'O'#187#221#238#156#8' =o'
- +#224#175'>'#9#231'm'#148'J'#137'I'#19#136'%u'#152#157#131't'#140#181#1#144#0
- +#250#11#210'z'#141#253#2#202'k#}'#152#182'czDc rw'#218#186#180'=m_'#207'H'
- +#164#235#226#31#237'$'#132'fP'#168#249#145#170#181'/'#169#6#17#129#31'7'#180
- +#244'7j'#191'k'#14#24#127'@'#224#164#17#187#166#129#201'!p'#29#133#198'<'#176
- +#4#224'W'#18#139#180'G'#192#246'.'#180'='#11#141'iP'#152#3'n'#194'Q'#217';'
- +#239#29'XU"s'#202'Az'#217#181#144#187#161'='#137#215#231'y'#197#214#151'B'#29
- +#163#226'gy'#145#167'oSu'#139')'#183'\'#201'_H'#253#20'M5'#197'VO-'#9#184'a'
- +#190#220#170#251#198'!H'#18#127#184#173#166'{wU:'#27#22'f'#129#11'~'#241')'
- +#180#162#217'.I'#253';'#152#156#211'C/`}n'#172#242'+'#221#187#207#228#244#143
- +#140#167#159#182#183#197#219#191'Ej'#254'6'#9#24'h'#2'}'#147#215#239#244#241
- +'3'#192'?7'#224'w'#30#135's;,'#9#16#1#4#8#19#18#27#195'9'#216#154#205'f=h'#3
- +#244#127#244#26'D'#171'1h'#2#240#11#160'r'#144#211#135#17'% '#192'D'#244#17
- +'A'#146#249#241#163'I'#247#230'`'#214'X'#247'l'#241'O'#1'^?0 '#142#184#166#0
- +#206'B'#244#211'3'#166#0#167#13'['#208#23#161'A'#27'!'#136#180#244#207#131
- +#224'@wb'#235'#p*'#15#11'"P:'#164'h'#211#139#165']'#153'*L'#4#151#24#150'^"'
- +#175'r'#197#170#26#192'!'#14#190#18#15#184#245#246#216#204#242#146#189'o5'#0
- +'7W'#223#128#221'z'#244#141#202'/'#246'~'#166#167#219'V'#226#228#179#128#183
- +#29'{'#202#224#183#197'='#236#253'_'#168#217'`K'#205#246#239#17#240#199#146
- +#16#148'X'#147#1#251'J:'#246'D^2'#187#212#26#220'n'#215#166'}'#248#28'<'#143
- +'U~V'#252#233#146#177#163'Oz'#247'Me'#178'Nk'#239'C'#237#151#153'{9'#190#15
- +#149#159#20#206'1b'#252#245'z'#29#164'a'#234#249#237'U:O'#227#188#19#128#249
- +#13'H'#24#194#154'#'#4'p'#14#18#1'4E'#27'X5'#190#1'!'#1'6'#9'h'#191#7#191#0
- +'m'#195'A'#8'm'#128#222#231#251#163'$'#238'>'#28'uo.'#178#168#233#154#5#202
- +'I+V'#226''''#136#219#27#170#222#187#174#130'F'#235#160#212'7'#170#191'C'#4
- +#134'L'#148'K'#2#2'z'#229'U'#157#133#14')x'#166#10'Q9~'#130'J7cq$'#30#152#241
- +#232#176#154#3'[m'#231#188#196'm'#180'a6'#189'B+'#240#158#2'zW'#213#247'*'
- +#222'|'#29#215#207#172'Df'#7'`R'#168#251#158#1'}'#226'H~'#163#13'd'#134#8'2'
- +#142#223#207#6#143#24#248#217'bb'#237'~'#227#216#203'\u'#159#132#252'J}'#252
- +'p'#179'9x'#224#209#142#199#165#130#224#29#218'f%'#198':'#250'f'#210#187#207
- +'t'#238#133#167#223#130#31#19'v'#160#137#7#254#143#254'}'#163#209'h^'#241#244
- +'+u'#14#193#127#200#147'q.'#135#141#16#160#156#248#214#173'['#225#214#214'V'
- +#141#14#213#137#173#17'*'#236#145#250#134'b'#162'u''u'#24#251#200'#hC'#27#160
- +#237#26#251#6''#204'r'#143#204#130#246#229#221'Y'#243'J'#154#135#145'1'#11
- +#236':'#8#172#175#0'N'#191#184#181#166#234'+D'#4#245'N'#17#1'p{'#10#28#0#190
- +#16#131#235#24'tk'#11'l'#152'R'#230'3t'#29#134'Nv!k'#7'jIU'#162'\'#17#175#148
- +'\T'#190#213#182#143'A'#245'B'#26#233'_r'#240')I'#218#145'}3}'#182#19#194#179
- +#224#183#251#6#240'N"O'#213#203'/'#241'}'#227#236'c'#144#27#147'@r'#251#141
- +'6'#144'%s'#246#232'O'#25#248'3'#171#254'g'#198#163#239'F'#17'h'#187'I'#234
- +#254#229'F'#255'^'#28#192'3O'#146#158#5'>'#199#245'3'#201#231#183'R'#159#22
- +#19#226'c'#149#31#160#199#2#149'_'#8#1#29'|'#198#244#182')'#217#253' '#140
- +#132#180#206#236'<'#132#249#142#4#156#23'h'#176's'#240#219#223#254'6'#251#5
- +#232#166'E'#4#234':'#28#132'259'#155#4'XD'#27'0$'#208#165#183#146'>'#175#26#4
- +#167#24'f'#1#129'='#160#199'%'#220#157#183'6'#247'&'#173#203#137#10#226#3'D'
- +#224#23#246'>4'#130#176#209'!'#173'`'#147#8'a]'#249'a,m'#198#140#3#240'0'#167
- +#224'!'#5'F'#146'3'#224#149'|'#3#166#23'A1'#169#137'%'#2#153#224#196'LuV'#10
- +#18#10'7'#148#156#132#14#3'xF'#210'Wd'#153#145#246#7#28'{N'#252#222#149#252
- +#182'B'#207#237#200'c'#192'/'#132#160'\'#167#159#149#242#142#211#207#233#224
- +#131#255'-'#166#251'j1'#220#162'e'#155'I w'#205#128','#147#150'_'#236#220#195
- +'~'#222#138'g'#187#27#141#193#131'Z'#184#152#150#212'}'#199#214#151#182']'
- +#166'c/l'#249'}i'#226#193#158'~Z?Fl'#159#164#252'>='''#3'2/'#199#244','#205
- ,'{'#189#30#192#127'n'#237#253#165#128'9'#237#19'8'#166#223'T2'#9'h N'#211'di'
- +'O'#128#167#155'j'#137'@'#204#3#236#19#9#168#14#1#174'A'#251'u:'#30#25#179
- +#128'@'#21#236#205'Z'#27#187#227#230#229#133#10#235#218'F'#247#203#211#141#17
- +#1'('#223#183'ZA'#173#177#170'""'#131#176#185#162#163#4#230#181#142'3'#208'H'
- +'~'#255'0-'#192#152#8'&'#147#208#248#7#248#23'V2'#12#221#28#130#220#137#12#8
- +#27#152#196#220#131#209#130'Jz'#174#167#172'j/'#255'V'#226#245'+Iyc'#227#27
- +'{'#223'4'#227#176'Z'#128#1#186#172#165#192#166't'#220'M'#237'u'#215'('#203
- +#157#13#31'3'#240'S'#132#242'2'']W'#166#220#206'e'#209#192'O'#243'vm'#182#189
- +#217#24'>'#140'|H|'#28#23#191'>'#171#251#220'%'#208#205#232#227#240#30#242
- +#249'i'#189'/'#237#187#182#205'"'#206'?'#28#199'k'#166'F'#229''''#205'2;'#207
- +#246#254'a`y'#17'G'#201'$@'#168#176#213'j'#197#2'lT'#12'v'#197#25#184'J'#140
- +#143#232#0#22#248#5'D'#27'P-!'#2#152#5'a'#206'd'#128#174#225#190#191'7k'#174
- +#237#142'[W'#230'y'#216#176#206':'#3'|'#207'H'#242#162#2#17#154'@'#212#222' '
- +#173'`C'#5#141#142#227#252#11#184#231#160#231'8'#2#139#168'@u'#10'3'#207#2
- +#222'F'#5#2#209#4'\'#237#192#151#144#161#149#252'U'#7'`%'#159#192#12#183#149
- +'6'#239'+'#235#28#176#213'zF'#229'O'#171#234'~&fA'#230'T'#234#21#206'?~'#189
- +#209#0'*a'#191#18#9','#230'j6'#218'f'#208''''#211'A'#161'!'#152'L@'#199'l0}'
- +#0#16#210#235#198#147#199#27#4'|x'#246'M'#190#241#19#212'}k'#235#211#210#151
- +#238'='#12'~'#186#207#144#254#216#222#15#130#128#19'{h'#153#145#244'_ '#196
- +#247#162#168#252'K'#129#242#2#15'k'#18' J'#128#178'b'#186#185'54'#25'!R@'#227
- +'Q'#152#5'+ '#1#133'Y'#137'5'#9'@'#27#232#209#210#17#179#160#238'{~Lk'#16'A'
- +#8'"'#240#9'}'#251#179#250#234#206#164'ue'#150'!'#135#192#128#177#144#218#5
- +#176#3'K'#10'a'#212'Tq'#7'Z'#193#154#10'j'#141'2'#184#157#210'bo'#9'!'#184#9
- +'C'#133#25#224#21'~'#2'''R`o'#173'u'#11'H'#180#192'M$'#146'W'#185'~'#128#210
- +#172#185#178'*'#194'}'#174#244#207#156#233#180#225#240#203'd'#178#205#138#183
- +#191'*'#245#179#188#18#1'H'#212'b'#178#175#230'P'#241#199#187#156#216#147';6'
- +#189#251'~K '#244'}>1B'#183'6f'#224#7#200#15'6'#192#231#138#221'2'#240#149#6
- +'?'#128#143'N'#189'#'#201#229#223#23#240#195#185#135#25'y'#25#248#240#240'+M'
- +#14#211'N'#167'3G'#3#143'7'#223'|'#243#133'R'#249#15#0#228#180'O'#224#132'~#'
- +#155#4#208#6'h;Z]]'#141#160#13#200#140'D0'#11'z'#162#17#172#233#244'aM'#4#180
- +'&'#18'Pm'#186#235#220'l'#4'&'#129'o'#136' '#131'F'#224'y'#195#164#209#219
- +#153'4/O'#211'Z'#7#200#180#192'tH'#160'4'#231#128#152#0#232'I'#16#212'z*jt'
- +#201#168#232#210'~'#173#210'[`I'#231'!G'#213'/'#171#254'x'#173#18#159#128#241
- +#234'{'#182#152#168#8#4'x'#149#181'*7'#222'PE'#218#190#178#13'8'#157#146#221
- +#204#13#241#21#234#190'w'#192#23'P'#201#233'7'#145#0#2'v2'#27#170#20'v'#253
- +#164'O'#219#131'"'#219#207'x'#239#197#137#231#153#254'~v;'#231'p^'#167'6'#217
- +'^'#175#143#182'|'#143'sy'#213'2'#224';'#237#185#173#147'O'#233#9':'#160#214
- +#239#25#240#3#248'$'#12#246#200#222#135#3#16'z'#254#132'l'#253#217#139#230
- +#232'{'#26'8>,'#227#128'6P'#171#213'bz^0G'#22#166'*G'#159#129#30#28#133#240
- +#17#28#212#6'T'#211#152#5#4#180#18#17'(.'#25#11#163#253'yc}0k'#172#205#210
- +#168'Y'#0#180#172#198#27#245'>'#247#202#196#0'B'#8#27'+*'#170'wT'#0'B'#128#19
- +#209'!'#0#27#14#148#162#162'jc'#210#146#9#224'4"'#177'w'#185#218#140'D'#194
- +'~n'#233'n)'#12#232'j'#2#198#9#232#168#251'n'#184'/'#207'+I?yA'#0'H'#206'I'
- +#166'}'#150#244#201'tH'#255'J'#10''' '#155#20'i)4'#200'Q'#0'K&'#184#184'Y'
- +#138#4#158#149#218'x'#167#25#209#135'i'#204#231#154#160#24#248#0'<'#235#252
- +'b'#231'/*'#234#254'H'#226#250#198#214'G'#136'oW'#188#251'}'#186#215'C'#168
- +#251#176#245'www'#23'd'#231'sl'#255#19#159#248'D'#254#162#131#223'yB>4'#163
- +#164#13#192'7'#176#178#178#18#17#25#208'f'#204'}'#6'h'#1#216#225'(\1'#218#128
- +#210#26#2#250#18'"'#164'h'#136#0'Y'#132'1a.'#160'g=dg!'#20'r'#210#11#166'i'
- +#220#216#155'5'#215'G'#179#218'Z'#162#130#200'S'#5#25#20#146#220#169#7#240
- +#141#243#207#28#15#148#31'7Y;'#8#226#22'}B'#131#9#130#29#141#202'5'#3#156#181
- +#141#18#136#170#159#171#194'$'#200#171#209#1'U'#16#130#155#244#227'6'#222'4'
- +#7#149#201#4#212'$'#192' u'#18'}'#12#232#177'dp'#188#211#146'/'#198'l'#199'c'
- +#201#200'4/'#1#190#186'm'#181#137#204#250#20'`'#195'7'#195'y'#191'S'#159#236
- +'t'#163#233#158#199'I'#5'b'#143#232#188#131'Ll|l'#1#244#236#224's'#128#143
- +#134#29'#'#153#153#135#195'{'#198#222'7'#14'>'#216#249't'#175#199't'#159#167
- +'('#224'[b'#235';W'#224#197#29#31'6'#2#176#191#217'h'#3#155#155#155#254't:'
- +#13'1S1'#252#3'0'#11#232#223'-'#178#7#225#12'D6'#225#138'8'#7'W'#196'y'#168
- +#157#132#158#215#164#199#177'A'#159'V;@'#4#30#224#166'Q:'#152#215#187#253'Yc'
- +'}'#148#196'+'#185#22#233'V'#133'7)'#191'E'#135#225#162#243#176'K'#8#185#152
- +#0#164'x'#16#25#212#153#28#130#176#206')'#201'>'#214'd>'#148#10#139'J'#191
- +#244'`'#219#242'"G'#160#236#237#247'Jf@^$'#7#25'3'#1#248'K'#209'H'#19'@'#159
- +'p'#197']'#150#152#245#212#206#198#163#242#195#0#15#252'f%'#147#1#239'1'#251
- +#181'`1&'#21#127#167'GK'#232#193'!'#160'L'#237'0'#147'B'#154'iu'#223#177#241
- ,#171#18#223#216#249#3#1'?'#146'w'#0'~^'#144#194'K'#210#30#197';'#172#238'w'
- +#187#221#217#214#214'V'#226'x'#248'_X['#255#176#241'a$'#128#210'o_f'#22#208
- +#225#26#217#130#28'6$'#2#128'F'#208's'#23#209#6#208'k'#160'm'#136#128#128#140
- +'(CL'#251#16#211'Rc'#204#157#238'|'#180'*O'#9#206#251#179#198#234'h^'#235'M'
- +#211#168#157#230#162#25#24#199#158'r'#10#131'J'#132'`'#156#127#190'>ig'#187
- +#152#199#16']'#144#27'*'#8'"q:'#134'tX"'#17#158#164'"'#243#233#232#181'/Z'
- +#134#150#190#137#216#218'R)'#151'9'#139's'#28#146#28#18#158'_'#207#225'7'#7
- +#196#182#196#183#240#1#184#0'W'#165#130' 1#8T'#167#242#154#191#24#213#163#249
- +#176'G*>Zn'#23#17#8#145#246'8'#3#2'>x'#18#206'}''o'#223#134#244#164'K'#207
- +#184#2'|'#187#208'=d'#224'#'#172#135'L>"'#2#246#238'#'#149#151#8' '#251#176
- +'I}w|'#152#9#192#140#3'f'#1'B'#127#244'p'#196#198'QH'#255'o'#9#216#187#244' '
- +#245#184#150#128#136'@4'#2'v'#20'*'#204'T'#164#188':4'#2')4'#10#173'V'#224'#'
- +#29'E'#251#10#176#13#208#18#9#212#137#12#186#147'E'#220#157'$q'#139#224#16#26
- +'S'#161#232''''#232';'#205'D+'#246#190#152#2#150','#148#155'*l~'#150#252'@.'
- +#30':$$'#232#216#255#182'EW'#169'1'#191#201#250'S'#165'\'#0'['#221#167#138
- +#148'`'#6'u'#166'T'#158'/'#7'<'#214#181' '#25#215#131#249#176#25#207#251#237
- +'h6'#242#149'8'#243'<61'#140'moA'#175't'#202'.'#24#133#213'|Y'#230#198#179'o'
- +'T}'#19#211#151#5#158#254'>'#128'OD>'#140#162'h'#12#137'O'#199#167't'#127#23
- +'t<'#249'0'#170#251#203#198#5#1#20#195's'#205#130';w'#238#4#198'?'#128'9'#7
- +#232'!B'#205'@'#203#241#19#244'$'#140#200'k'#248#7#20'"'#6'9W'#26#214#161#209
- +#18#216#17'm@BQ'#24#248#30#200' '#160'c>'#180'^F'#165'/'#229'<'#244'wL$@'#132
- +#208#153'.'#162#206'4'#141#219#153#14#8#138#237'^T'#4#22'e'#194#170#168#10'T'
- +#254'R'#240#219#191'U'#207#127#241#207'J'#246'_'#197#7'`Gn'#205#0#3'z'#183
- +#145'g'#225'G(^g'#0#31#251#201#164#22#206#135#173'h>h'#147#164#15#252'4)^c'
- +#153#197#128'^Y'#21#255#160#180'/'#169#250#144#248'p'#224')'#1#187#164#242
- +#150#164#189#1'~'#171#213#154#141'F#'#246#236#147#169#151'~X'#213#253'e'#227
- +#130#0#202#227#128#127#192#16#1'=H'#28':'#164#127's2'#17#173'['#244#0#162#216
- +#168'+'#26#129#171#13#176#143#0#175#229#228'#'#223#135'Ya'#200' 8@'#6#128#174
- +#158'`'#132'a'#142'|<"'#132#246'x'#17#183#146'4'#168#207#179#176#190'H'#131
- +'Z'#170#160#219'k'#251#221'8'#245#140'K'#191'T'#13#184'$'#239#223#141#8#228
- +#203'~t5'#20'h'#134'['#251#239#185#210#221#253#191#6'n'#228#167#211#208#207
- +'fQ'#144#204#234#225'bL'#18'~'#16'.'#3#188#233#18'"'#182'C'#174#127#145#168
- +#248'E'#214#30'-'#11'g'#218'-'#171#234'+'#157#190#203#224#167'{'#224#18#192
- +#144'#'#179'I'#194#210#254#2#248'O'#31#23#4#176'|,%'#2'Z'#135#244'@'#177'F'#0
- +'`'#211#186'I*f'#139#236'J'#214#10#132#16#12#9'X"@'#19#18#218#6'y'#212'@'#6
- +' '#2#218#14#133#12'|'#218#151#194#2#206#177#169#16#130#178#128'N'#179' '#154
- +'fQm'#158#16')'#164'!'#19'C'#146#250#181'E'#22#214'r'#195#2'y'#17#247#207#221
- +#219#235#29#248'y2'#242#165#155#252#170'R'#11'0'#253'7'#240#178'E'#236#167
- +#179#200'O'#166'Q'#152#206#226' '#153#214'BZ'#252'd^'#10#31#28#4#188#212#222
- +#235#20']Ro'#178#220#168#19#185'JM'''#30'U'#150#246'('#207#157'J?>'#11'|'#168
- +#251't'#157#135#0#191#0#30'j>&'#221#132'I0E'#6#159#249#172'%'#192'_'#242'K?'
- +#188#227#130#0#158'<'#150#18#1'|'#4#237'6'#201#183#217#140';'#20#19#1#160#203
- +#144#169'5h'#201#186'm'#246#141#198#0#243'@i'#13#2#4#2'2`"'#144#133#181#2'!'
- +#4#175'B'#8#162#229#235'F'#0'E*'#191#201#243#247#2'"'#129'('#205#252' '#205
- +#149#159#229'~'#0#19'"'#203#184#160')'#160#181#143#207'&'#158#241#233'8'#142
- +#249'x'#15' '#233'{y'#202#139#162'Wy'#10#219#153'g'#142'y'#244#137'~'#158#6#4
- +'N'#218'N#?K0C'#14#127#181#237#249#167#247#204'1}Z'#185#20#11'j'#213#222#145
- +#240#12'B'#237#197#183'q{+'#237'Mi'#174#210#192#159'HW'#158#145'*'#128#15#169
- +#143#184'='#239#147#186#143#10#189'1'#173'!'#241#209#140'snl'#252'G'#143#30
- +'e'#23#192#127#250#184' '#128#163#13'K'#4#223#253#238'w=4%'#5#25#208#161#144
- +#164'N'#212'l6'#1'd'#214#10#232#129'lxz'#174'B'#180'('#3#240#153#4'h'#223#144
- +'C'#211#209#10'jB'#6#136#30'DJG'#16't'#20'A'#19#2#242#10#8#139#220#2'Dr'#130
- +#217'y^'#164#249#225#143#239#219'm'#140#220'sN'#250#224#207#240#14#252'#?'
- +#176#225#202#240#138#242' '#249#0'z;/'#210#133'9'#25#152#147'!3'#237'P'#212
- +#21'x'#158#199#217#3'.'#224#233'X"'#221'vy'#150#29#167'@'#7#224#7#152'a'#223
- +#143' '#229#165' '#135#215't|'#4#208'C'#210#3#244#240#230'c!'#2'^'#192#171'O'
- +#199#211#11#224'?'#219#184' '#128'g'#27'%"@'#212#224#210#165'K>I'#164#144#30
- +'D&'#3#180''''#4#168#145'a'#8'2'#192#2'2P'#152#202#220'Y'#132#8#140'i'#192
- +#230#1'k'#5#30';'#14']B`2'#160'c'#1'b'#8#162#29'0'#17#152#22' '#24'y'#145#223
- +#167'r'#183#11'`'#165#17#192#129'y'#9#151#254'J'#227#225'We'#253'_)'#227#164
- +#211'h'#215'L$'#130']'#25#231#157#150#242#136#238#231'6Vo='#248#6#240'R'#142
- +'k'#194'x'#0#255'd'#137#212#231'E'#18'vX'#189#23#21#127#14#208'c'#166']'#196
- +#241'WVV2x'#245#137#148#243#11#224'?'#219#184' '#128#247'7l^-'#194#135#244#16
- +'z'#198'<'#160#135#18#128'E'#143'B6'#17#224'/'#160'}'#16'B'#131#164#22#8#129
- ,'5'#0#172'}'#157'Q'#216#144'F'#165'L'#4'R'#177#200#239#177'D'#160#29#136#161
- +#199'A}'#144#129'v '#210#182#246#31'(]'#151' '#219#170#152'}'#132#165's'#209
- +'4'#200#156#244'!, '#160'Vy^v'#3'j'#183#164'W'#184#253#10'U>7'#157't'#217#129
- +''''#222'{'#165#165#188#5#190'S'#127#207'^|'#165#165'=/p'#236#161#209#6#253
- +'~'#168#243#19#172'%'#166'?!'#160'c'#31#196'0C=>'#169#247' '#142#132#142'!y'
- +#7#128#207#156'8'#190#156#253#5#232#159'e\'#16#192#7#27#150#8#240#0#186'Z'#1
- +'I'#168'`gg'#7'R;'#132#137#0#243#20'd'#0'p'#139#218'_'#23#240'#'#215#192#128
- +#159'5'#2'G30D`4'#3#215'g`'#9'Ai'#13#1'$'#16'pI?'#231#28's'#242#156'''`'#247
- +#12#17'('#19';8D'#19'p'#192#207#0'/'#8'AK~'#165'{'#230#27#213'>'#173#0#222
- +#196#233#141#138'o'#156'y'#0#191#241#228'O'#5#220'v'#27#199#1'~'#243#127#168
- +#245'x}'#20'Es'#0#31#210#30#234'='#17'jz'#227#198#141#20#160#135#180'w'#242
- +#245#249'|O'#251'a8'#143#227#130#0#158#223'8'#160#21#12#6#3#175#211#233#4#180
- +#248#244#0#179#153#0'I'#14'S'#129#30#234#152#30'n'#164#31'C'#202#215#232'X'
- +#141#142#25'S'#192#152#5#150#4#232#189#186'eY'#161#21#132'UBP'#154#20'x'#246
- +'$!'#4#156#147'/'#224#247'DK'#176#219#149#243#182#170#188'2'#210#221#181#225
- +'s''>/'#210']z'#234#25#208'/'#28#208'W'#213'|+'#245'E'#221#231#181#144#194#12
- +'*=IwH'#249#5'@O@_'#200'g&'#0'=T|c'#219#11#232#205'y'#186#235#139#241'>'#198
- +#5#1#28#207'Xj"'#208#218#7#25'@3'#160#7#157'M'#5','#4'nL'#127#142#233#206'"'
- +#151#16'|'#157'?`4'#6#248#22'P'#189#24#11#17'D'#134#16'@*'#244#186'RD'#1'D@'
- +#175'E'#196#194#19'2`"'#192#182#28#243#212#146'x`'#201#142'/'#0#159#27#21'_'
- +#21'j=7'#212#196'B'#223#195#192#167#207#157#211#246#1#2#192'B'#191'k'#230#2
- +#158#200#14#210#29#239'Y@'#194#131'H'#232'xj$'#189#1'=]'#175#188#162#226#187
- +#235#139#241#1#199#5#1#28#239#176#215#215'8'#14#141'f'#0'3aoo'#143#9'!@i'#218
- +'`'#16#192'l'#160#151#134' '#3#172'A'#8' '#7':'#206'k'#128#158'^'#202'k9'#30
- +#154#227'J'#252#4#202'1'#13#180'I'#192'f'#128'oH'#0#231#148'!.X'#144'@q'#178
- +#5#208'sQ'#237'-'#240#177#166#247'X'#201#175#196#161''''#4#176'0'#251#134#0
- +'d!<'''#6#228#144#236#176#223#23'Fk'#0#224#137#3#210#181#181#181#148'~?'#212
- +#250#140'L'#168#28#160#191'p'#232#157#204#184' '#128#147#27#165'D\'#233'Y'
- +#168'@'#8#208#12'n'#222#188#233'-#'#4#12#2'M '#160#14#5#212'au'#219#172#149
- +'&'#14#214#0'0'#0'v'#1'k6'#155#217't:'#205#232#156#243'e'#18'~'#9#224#171#219#23#227#152
- +#199#5#1#156#141'Q'#186#15#198'\'#192#182'1'#25#8'H'#30'H'#129'H'#192'#py'
- +#134#24#8#148#30#200#129#128#232#25'r'#160'}'#143'@j'#23':'#206#128#199'6>'
- +#19#219#4'V'#187#141#181#207#253'L'#148'"'#0#27#192#243'>}/o'#155#133#190'?'
- +#7#208#137'Dr'#128#156#190'+'#235#247#251'9'#129#222#2#29#146#189#221'n'#231
- +#6#236#248#156#11#192#159#205'qA'#0'gsT'#239#139''''#192'Q.1`'#13'r'#184'u'
- +#235#150'7'#28#14'-9'#224'8'#8#2'k'#179'O'#192#230'5'#8#3#235#245#245'u'#187
- +'m'#6#128#140'5Iy'#11'J'#2';o'#3#220'X?~'#252'8'#199'6@'#142#253'e@'#199#250
- +#16#176'/'#219#191#24#167'8.'#8#224'|'#141'e'#247#235#0'9`'#24#130'0'#3'D'
- +#177#236#3#161'Y`]'#175#215#15#0#211#128#218#29#6#224#24#0'9'#214#135#0#253
- +#176'c'#23#227#12#141#11#2'x1'#198#179#220#199#163#190#246#168#224#189#0#249
- +'9'#30#23#4'p1.'#198#135'x'#252#127'p'#251'ut'#3#215#244'"'#0#0#0#0'IEND'#174
- +'B`'#130'('#0#0#0#128#0#0#0#0#1#0#0#1#0' '#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0
- +#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#1#0#0#0#1#0#0#0#2#128#128#128#2'UUU'#3'@@@'#4'333'#5'III'#7'@@@'#8
- +'999'#9'999'#9'MMM'#10'FFF'#11'FFF'#11'FFF'#11'MMM'#10'999'#9'@@@'#8'@@@'#8
- +'UUU'#6'333'#5'UUU'#3#128#128#128#2#0#0#0#2#0#0#0#1#0#0#0#1#0#0#0#1#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#1#0#0#0#1#128#128#128#2'UUU'#3'UUU'#6'@@@'#8'FFF'#11'III'#14'<<'
- +'<'#17'III'#21'EEE'#26'DDD'#30'DDD"EEE%AAA''DDD)AAA+AAA+AAA+DDD)AAA''GGG$FFF'
- +'!DDD'#30'==='#25'@@@'#20'@@@'#16';;;'#13'FFF'#11'@@@'#8'333'#5'UUU'#3#128
- +#128#128#2#0#0#0#1#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#0#0#0
- +#2'UUU'#3'+++'#6'999'#9'NNN'#13'CCC'#19'BBB'#27'GGG$DDD-CCC5DDD'#211'SC6'#219'W@0'#227'[>+'#235']<('#238'^<'''#240
- +'_<%'#243'`<#'#245'a;"'#247'a:!'#248'a;"'#246'`<$'#245'_<%'#242'^='''#240'\='
- +')'#237'Z=,'#233'V@1'#225'RD8'#217'NG?'#210'JHD'#204'IHC'#204'HHD'#204'GEC'
- +#203'FEC'#202'EED'#198'EED'#195'DDC'#190'DDC'#183'DDD'#172'DDD'#157'DDD'#138
- +'DDDtCCC\DDDDCCC.@@@'#28'DDD'#15'III'#7'UUU'#3#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'UUU'#3'@@'
- +'@'#8'KKK'#17'HHH CCC5CCCPDDDlCCC'#134'DDC'#156'EED'#172'FEC'#185'GFD'#193'G'
- +'FC'#198'HFC'#202'IGD'#203'PE;'#213'VA0'#227']<('#239'a;#'#246'd9'#30#254'g:'
- +#29#255'g:'#30#255'i<'#30#255'j='#31#255'j>'#30#255'k>'#30#255'l?'#31#255'l@'
- +#31#255'mA'#31#255'nA'#31#255'm@'#31#255'l@'#31#255'l?'#31#255'k>'#30#255'j>'
- +#30#255'j='#31#255'i<'#30#255'g:'#30#255'f:'#29#255'd9'#31#252'`<#'#245'[=*'
- +#236'UA3'#223'MF?'#210'IHC'#204'HFD'#204'FFC'#203'FFE'#200'DDC'#197'EED'#191
- +'DCC'#182'DDD'#170'CCC'#152'CCC'#129'DDDfDDDKDDD1FFF'#29'@@@'#16'III'#7'UUU'
- +#3#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'UUU'#3'II'
- +'I'#7'@@@'#16'@@@ FFF7DDDRCCCoCCC'#140'DDC'#163'EED'#180'EED'#191'FFC'#198'I'
- +'GD'#201'ME?'#208'UA2'#224'\<('#238'b9 '#250'f:'#29#255'h;'#30#255'j>'#30#255
- +'m@'#31#255'oB '#255'qD '#255'sF '#255'uH!'#255'|L#'#255#128'O$'#255#133'Q%'
- +#255#136'S&'#255#139'V'''#255#143'X('#255#145'Y)'#255#142'W('#255#139'U'''
- +#255#135'S&'#255#131'Q%'#255#128'O$'#255'yK"'#255'tG!'#255'rE '#255'pD '#255
- +'nA '#255'l@'#31#255'j='#31#255'g;'#30#255'e9'#29#255'a;!'#247'Z=+'#234'RB5'
- +#221'JGC'#207'HFD'#204'FEC'#203'FFE'#200'EED'#196'DDC'#189'DDD'#177'CCC'#159
- +'DDD'#135'CCCjBBBMBBB2FFF'#29'III'#14'UUU'#6#128#128#128#2#0#0#0#1#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#2'333'#5';;;'#13'BBB'#27'AAA3BBBQDDDqDDD'#142'EED'#165
- +'EDB'#183'FEC'#194'HFD'#200'IFB'#205'SA3'#223'^;&'#242'e8'#29#255'g;'#30#255
- +'j>'#31#255'mA'#31#255'pD!'#255'tG!'#255'~M#'#255#141'W('#255#151']*'#255#160
- +'c-'#255#169'i0'#255#178'n1'#255#181'q2'#255#182's3'#255#183't3'#255#184't3'
- +#255#184'v3'#255#185'v4'#255#186'w3'#255#185'v3'#255#184'u3'#255#184't3'#255
- +#183't3'#255#182'r3'#255#181'q2'#255#175'l1'#255#166'h/'#255#158'a,'#255#149
- ,'\*'#255#138'U('#255'zK"'#255'sF '#255'pC '#255'l@'#31#255'i='#31#255'g;'#30
- +#255'c8'#31#252'[<*'#237'RC8'#218'IGD'#205'HFD'#204'EED'#201'DDC'#198'EED'
- +#191'DDD'#179'CCC'#161'DDD'#136'CCCkEEEJDDD-@@@'#24'FFF'#11'@@@'#4#0#0#0#1#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#1'UUU'#3'999'#9'FFF'#22'CCC*DDDGDDDiCCC'#138'EED'#165'FEC'#184'FEC'#194
- +'HHD'#200'QC9'#216'[<*'#237'c8'#31#253'g;'#30#255'j>'#31#255'nA '#255'sF!'
- +#255'|M#'#255#141'W('#255#158'a,'#255#173'k1'#255#181'r3'#255#185'v4'#255#187
- +'y4'#255#189'{4'#255#191'~5'#255#193#129'5'#255#195#131'5'#255#196#132'6'#255
- +#197#134'6'#255#198#134'6'#255#199#136'6'#255#200#136'6'#255#200#137'6'#255
- +#199#136'6'#255#198#135'6'#255#198#134'6'#255#197#133'5'#255#196#132'6'#255
- +#195#131'5'#255#193#128'5'#255#191'~4'#255#188'z4'#255#186'x4'#255#184'u3'
- +#255#181'q2'#255#168'i/'#255#153'_+'#255#137'T'''#255'yJ"'#255'rE '#255'm@'
- +#31#255'i<'#31#255'f:'#30#255'b9!'#249'X>.'#232'MD>'#212'HFD'#204'EED'#202'E'
- +'ED'#198'EED'#192'CCC'#180'CCC'#160'DDD'#132'DDDbCCCACCC&CCC'#19'@@@'#8'UUU'
- +#3#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'333'#5
- +'III'#14'>>>!DDD'#255
- +#232#177'>'#255#234#179'?'#255#236#181'>'#255#236#182'?'#255#237#183'?'#255
- ,#237#183'?'#255#238#183'@'#255#238#184'?'#255#238#185'?'#255#238#184'?'#255
- +#238#183'@'#255#237#182'?'#255#237#183'?'#255#236#182'?'#255#236#181'>'#255
- +#234#179'>'#255#232#176'>'#255#230#175'>'#255#229#172'='#255#227#169'='#255
- +#224#167'='#255#220#161'<'#255#217#157'<'#255#213#153';'#255#209#148':'#255
- +#204#142'9'#255#198#135'8'#255#193#129'7'#255#188'{6'#255#183't5'#255#171'k2'
- +#255#142'W)'#255'tH"'#255'nA '#255'h<'#31#255'd7'#30#255'[:('#240'KD?'#211'G'
- +'FD'#204'DDC'#201'EDD'#195'CCC'#182'CCC'#159'CCC}EEEUBBB2@@@'#24'999'#9'UUU'
- +#3#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#1'333'#5'III'#14'BBB#EEECCCCkEEE'#145'DDC'#174'FFE'#192'KE@'#206'Z;)'
- +#238'c8'#30#255'i<'#31#255'oB!'#255'|M%'#255#153'_-'#255#178'o4'#255#186'x6'
- +#255#192#128'7'#255#198#135'9'#255#204#142':'#255#209#149';'#255#214#155'='
- +#255#219#161'>'#255#223#167'>'#255#227#170'>'#255#230#174'?'#255#232#177'@'
- +#255#235#181'A'#255#237#183'A'#255#238#185'A'#255#240#187'A'#255#241#188'A'
- +#255#242#189'B'#255#243#190'A'#255#244#191'B'#255#244#192'B'#255#244#191'B'
- +#255#244#192'B'#255#244#192'B'#255#245#193'A'#255#244#192'B'#255#244#192'B'
- +#255#244#191'B'#255#244#192'B'#255#244#191'B'#255#243#190'A'#255#242#189'B'
- +#255#240#187'A'#255#239#186'A'#255#238#184'@'#255#237#183'A'#255#235#179'@'
- +#255#232#176'?'#255#229#173'?'#255#226#169'?'#255#223#165'>'#255#218#160'='
- +#255#213#153'<'#255#208#147';'#255#202#140':'#255#196#133'9'#255#190'~7'#255
- +#184'v6'#255#173'l3'#255#145'Y+'#255'uH$'#255'm@ '#255'g;'#31#255'b7'#31#253
- +'U>/'#230'IEC'#206'FFE'#202'EED'#199'CCC'#189'DDD'#170'DDD'#139'BBBdCCC=BBB'
- +#31'@@@'#12'UUU'#3#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#1'UUU'#6'KKK'#17'DDD)EEENDDDxDCC'#157'DDC'#182'GGC'#197'T=1'#225'a7 '
- +#252'g;'#31#255'l@ '#255'wI$'#255#154'^.'#255#179'o6'#255#186'x7'#255#193#128
- +'9'#255#200#137':'#255#207#146'<'#255#212#153'>'#255#217#159'>'#255#222#166
- +'?'#255#227#170'@'#255#231#175'A'#255#234#180'B'#255#236#182'B'#255#238#185
- +'B'#255#240#187'B'#255#242#190'D'#255#243#191'C'#255#244#192'D'#255#245#193
- +'C'#255#246#194'D'#255#247#194'D'#255#247#196'E'#255#247#196'D'#255#247#196
- +'D'#255#248#197'D'#255#248#197'D'#255#248#197'D'#255#248#197'D'#255#248#197
- +'D'#255#248#197'D'#255#248#196'D'#255#247#196'D'#255#247#196'D'#255#247#195
- +'E'#255#246#195'D'#255#245#193'D'#255#245#193'C'#255#244#192'D'#255#243#191
- +'C'#255#242#189'C'#255#240#186'C'#255#238#184'C'#255#236#182'B'#255#233#179
- +'B'#255#230#174'A'#255#226#169'@'#255#221#164'?'#255#216#157'>'#255#211#151
- +'='#255#205#143'<'#255#198#135':'#255#191#127'8'#255#184'w7'#255#174'l4'#255
- +#144'X+'#255'rE"'#255'j> '#255'e9'#30#255'_8"'#247'O@8'#219'GFD'#204'DDC'#201
- +'CCC'#194'CCC'#178'DDD'#151'DDDqDDDGGGG$III'#14'@@@'#4#0#0#0#1#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#2'III'#7'@@@'#20'CCC.DDDVCCC'#130'EED'#165'DDC'#189
- +'LB='#207']7$'#244'd7'#31#255'j> '#255'qE"'#255#140'W+'#255#174'l5'#255#186
- +'x8'#255#193#129':'#255#200#138'<'#255#207#146'>'#255#213#155'?'#255#220#163
- +'@'#255#225#169'A'#255#229#174'B'#255#233#179'D'#255#236#182'D'#255#239#185
- +'D'#255#241#189'E'#255#242#190'E'#255#244#192'E'#255#245#194'E'#255#246#195
- +'F'#255#247#195'F'#255#247#196'G'#255#247#197'F'#255#248#197'F'#255#248#197
- +'F'#255#249#198'F'#255#249#198'G'#255#249#198'G'#255#249#198'G'#255#249#198
- +'G'#255#249#198'G'#255#249#198'G'#255#249#198'G'#255#249#198'G'#255#249#198
- +'G'#255#249#198'G'#255#249#198'G'#255#249#198'F'#255#248#197'F'#255#248#197
- +'F'#255#247#196'F'#255#247#196'F'#255#247#195'F'#255#246#194'F'#255#244#193
- +'F'#255#243#191'E'#255#242#190'E'#255#240#188'E'#255#238#185'D'#255#235#181
- +'D'#255#232#178'C'#255#228#172'C'#255#223#167'B'#255#218#161'@'#255#212#153
- +'?'#255#205#144'='#255#198#135';'#255#191#127'9'#255#183'u7'#255#167'g3'#255
- +#130'P('#255'oB"'#255'h< '#255'c7'#30#255'X:*'#237'HFB'#207'EEE'#202'DCC'#197
- +'DDD'#184'CCC'#160'CCCzEEENFFF(@@@'#16'333'#5#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2
- +'III'#7'FFF'#22'BBB2CCC\DDD'#136'DDC'#171'EED'#192'Q?5'#219'a6'#31#252'f:'#31
- +#255'mA!'#255#127'N'''#255#164'f3'#255#182'u8'#255#190#127':'#255#199#138'='
- +#255#207#147'?'#255#213#155'A'#255#220#163'B'#255#225#170'D'#255#230#177'E'
- +#255#234#181'E'#255#237#184'F'#255#240#188'G'#255#242#189'G'#255#243#192'G'
- +#255#244#193'H'#255#245#194'H'#255#246#195'H'#255#247#196'H'#255#247#197'H'
- +#255#247#197'H'#255#248#198'H'#255#248#198'H'#255#248#197'H'#255#248#198'H'
- +#255#248#198'I'#255#249#198'I'#255#249#198'I'#255#249#198'I'#255#249#198'I'
- +#255#249#198'I'#255#249#198'I'#255#249#198'I'#255#249#198'I'#255#249#198'I'
- +#255#249#198'I'#255#249#198'I'#255#248#198'I'#255#248#198'H'#255#248#198'H'
- +#255#248#198'H'#255#248#198'H'#255#247#197'H'#255#247#196'I'#255#247#195'H'
- +#255#246#195'H'#255#245#195'H'#255#244#193'H'#255#243#191'G'#255#241#189'G'
- +#255#239#186'G'#255#236#183'F'#255#233#180'F'#255#229#175'D'#255#224#168'D'
- +#255#218#161'B'#255#211#153'@'#255#205#144'?'#255#196#134'='#255#188'{:'#255
- +#180'r8'#255#155'_/'#255'wJ$'#255'j? '#255'e8'#30#255']8#'#246'LB<'#213'FEE'
- +#203'EED'#199'DDD'#188'DDD'#165'DDD'#128'DDDSFFF,GGG'#18'+++'#6#0#0#0#1#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#2'III'#7'CCC'#23'BBB6DDDaCCC'#141'DDC'#174'GDB'#196'V:+'#233'c7'#30#255'h; '
- +#255'pC#'#255#146'Z-'#255#179'p7'#255#187'{;'#255#196#133'='#255#204#144'?'
- +#255#212#154'B'#255#219#163'E'#255#225#170'E'#255#230#176'G'#255#234#181'H'
- +#255#238#185'I'#255#240#189'I'#255#242#190'J'#255#243#192'J'#255#244#193'J'
- +#255#245#195'J'#255#246#195'J'#255#246#196'J'#255#247#196'K'#255#247#196'K'
- +#255#247#197'K'#255#247#197'K'#255#247#197'K'#255#247#197'J'#255#247#197'J'
- +#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#198'J'
- +#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#198'J'
- +#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#198'J'#255#247#197'J'
- +#255#247#197'J'#255#247#197'J'#255#247#197'K'#255#247#197'K'#255#247#197'K'
- +#255#247#196'K'#255#246#196'K'#255#246#196'J'#255#246#195'J'#255#245#195'J'
- +#255#244#194'J'#255#243#191'I'#255#241#189'I'#255#239#188'I'#255#236#184'H'
- +#255#233#180'H'#255#228#174'G'#255#223#168'E'#255#217#160'C'#255#210#151'B'
- +#255#202#141'?'#255#193#130'<'#255#185'x:'#255#174'm6'#255#134'S*'#255'mA"'
- +#255'f:'#31#255'a6'#30#253'R>4'#224'FFE'#203'EED'#200'CCC'#190'DDD'#169'CCC'
- +#133'CCCXAAA/CCC'#19'+++'#6#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#1'III'#7'CCC'#23'BBB6CCCcCCC'#144'EED'#177'JC>'#202
- +'[6"'#244'c8'#31#255'j?!'#255'xI&'#255#162'd2'#255#183'u:'#255#192#129'='#255
- +#200#140'@'#255#209#150'B'#255#217#160'E'#255#223#169'G'#255#229#176'H'#255
- +#233#181'J'#255#236#185'J'#255#239#188'K'#255#241#190'K'#255#242#192'K'#255
- +#243#193'L'#255#244#194'L'#255#245#195'L'#255#245#195'L'#255#245#195'L'#255
- +#246#196'L'#255#246#196'L'#255#246#196'L'#255#246#196'L'#255#246#196'M'#255
- +#246#196'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255
- +#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255
- +#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255
- +#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#197'M'#255#246#196'M'#255
- +#246#196'M'#255#246#196'M'#255#246#196'L'#255#246#196'L'#255#246#196'L'#255
- +#246#196'L'#255#245#195'L'#255#245#196'L'#255#244#195'M'#255#244#194'L'#255
- +#243#193'L'#255#242#192'L'#255#241#190'K'#255#238#188'K'#255#236#184'J'#255
- +#232#179'I'#255#228#173'H'#255#222#166'F'#255#215#158'E'#255#207#148'B'#255
- +#198#137'?'#255#190'~<'#255#180'r9'#255#150']/'#255'qE$'#255'h< '#255'b6'#30
- +#255'W9*'#235'GED'#204'DDC'#201'DDD'#192'CCC'#172'CCC'#137'DDDZAAA/GGG'#18'3'
- +'33'#5#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'+++'#6'II'
- +'I'#21'CCC5DDDbCCC'#145'DDC'#178'LB;'#206'^6 '#249'd8'#31#255'l@!'#255#131'Q'
- +'*'#255#172'k7'#255#186'z;'#255#196#133'?'#255#205#146'C'#255#213#156'E'#255
- +#220#165'G'#255#227#173'I'#255#232#180'K'#255#236#184'L'#255#238#187'L'#255
- ,#240#189'N'#255#241#191'N'#255#242#192'N'#255#243#193'N'#255#244#194'N'#255
- +#244#194'N'#255#244#194'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255
- +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255
- +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255
- +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255
- +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255
- +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255
- +#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255#244#195'O'#255
- +#244#195'O'#255#244#195'O'#255#244#194'O'#255#244#195'N'#255#244#194'N'#255
- +#243#193'N'#255#242#192'M'#255#241#190'N'#255#240#189'M'#255#237#186'M'#255
- +#235#182'L'#255#230#178'K'#255#225#171'I'#255#219#163'G'#255#211#153'D'#255
- +#202#143'B'#255#192#130'>'#255#183'u:'#255#164'f4'#255'yK&'#255'i=!'#255'c7'
- +#30#255'Z8%'#241'GEC'#205'DDC'#201'CCC'#193'DDD'#173'DDD'#136'BBBYDDD-KKK'#17
- +'333'#5#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'333'#5'CCC'#19'BBB2CCC_DD'
- +'D'#143'DDC'#178'M@8'#211'_5'#31#251'e9'#31#255'lA"'#255#144'Y/'#255#179'r9'
- +#255#188'}='#255#198#138'B'#255#208#149'D'#255#217#161'H'#255#223#170'K'#255
- +#229#177'L'#255#234#181'M'#255#236#186'N'#255#239#188'O'#255#240#190'P'#255
- +#241#191'P'#255#242#192'P'#255#242#192'P'#255#242#193'P'#255#243#193'P'#255
- +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255
- +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255
- +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255
- +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255
- +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255
- +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255
- +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255
- +#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#194'P'#255#243#193'P'#255
- +#242#193'P'#255#242#192'O'#255#242#192'P'#255#241#192'P'#255#240#190'P'#255
- +#238#188'O'#255#236#185'N'#255#232#180'M'#255#228#175'L'#255#222#167'I'#255
- +#215#159'H'#255#205#147'D'#255#196#134'@'#255#186'y<'#255#173'm7'#255#130'O*'
- +#255'j?!'#255'c8'#31#255'[7#'#245'HDA'#208'DDC'#201'CCC'#193'CCC'#172'CCC'
- +#134'AAAVAAA+@@@'#16'@@@'#4#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'@@@'#4'<<<'#17'CCC.CC'
- +'C[CCC'#140'EED'#176'O>5'#213'_5'#30#253'e9'#31#255'nB#'#255#151'\1'#255#181
- +'s:'#255#191#129'@'#255#201#142'C'#255#211#154'G'#255#219#164'K'#255#226#173
- +'M'#255#231#179'O'#255#234#184'P'#255#237#187'Q'#255#239#189'Q'#255#240#190
- +'R'#255#240#191'Q'#255#241#192'R'#255#241#192'R'#255#241#192'R'#255#242#192
- +'R'#255#242#192'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193
- +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193
- +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193
- +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193
- +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193
- +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193
- +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193
- +'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193'R'#255#242#193
- +'R'#255#242#192'R'#255#242#192'R'#255#241#192'R'#255#241#192'R'#255#241#192
- +'R'#255#240#191'Q'#255#240#190'R'#255#238#189'Q'#255#236#186'P'#255#234#182
- +'O'#255#230#177'N'#255#224#171'L'#255#217#162'J'#255#208#150'F'#255#198#138
- +'C'#255#188'}>'#255#177'o:'#255#136'S,'#255'k?"'#255'c8'#31#255'\6!'#248'JC?'
- +#211'DCC'#201'CCC'#193'CCC'#171'BBB'#131'DDDRAAA''777'#14'UUU'#3#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +'UUU'#3';;;'#13'AAA''CCCTBBB'#135'DDC'#174'N=5'#213'`4'#29#254'e9'#31#255'oC'
- +'$'#255#156'`3'#255#181'u<'#255#193#131'A'#255#204#146'E'#255#213#157'I'#255
- +#221#167'M'#255#227#175'O'#255#232#180'Q'#255#235#184'R'#255#237#187'S'#255
- +#238#189'S'#255#239#190'S'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255
- +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255
- +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255
- +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255
- ,#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255
- +#234#187'R'#255#202#161'G'#255#232#185'R'#255#240#191'T'#255#240#191'T'#255
- +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255
- +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255
- +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255
- +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255
- +#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255#240#191'T'#255
- +#239#189'S'#255#238#188'R'#255#236#186'R'#255#234#184'Q'#255#231#179'Q'#255
- +#226#173'O'#255#219#165'L'#255#211#154'H'#255#201#142'E'#255#190#128'@'#255
- +#179'q:'#255#140'V.'#255'l@"'#255'c8'#31#255'\4'#31#250'JC>'#211'CCC'#201'DD'
- +'D'#192'CCC'#168'CCC~DDDKFFF!MMM'#10#128#128#128#2#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#128#128#2'333'#10'@@@ EEE'
- +'JCCC~EDD'#169'L?8'#208'^4'#30#253'd8 '#255'pD%'#255#159'b4'#255#182'v='#255
- +#194#132'C'#255#205#147'H'#255#215#160'L'#255#222#169'O'#255#228#176'Q'#255
- +#232#181'S'#255#235#185'T'#255#236#187'T'#255#237#188'U'#255#238#189'U'#255
- +#238#190'U'#255#238#190'U'#255#238#191'U'#255#239#190'U'#255#239#190'U'#255
- +#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255
- +#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255
- +#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#181#144'@'#255
- +';/'#21#255#21#16#7#255#9#7#3#255#2#2#1#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1
- +#1#255#7#6#3#255#17#14#6#255#31#25#11#255'2'''#18#255'SB'#29#255#157'}8'#255
- +#233#186'S'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255
- +#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255
- +#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255
- +#239#190'U'#255#239#190'U'#255#239#190'U'#255#238#190'U'#255#238#190'U'#255
- +#238#190'U'#255#238#189'U'#255#237#188'U'#255#236#186'T'#255#234#184'T'#255
- +#231#180'S'#255#226#175'Q'#255#220#166'N'#255#212#156'K'#255#202#143'F'#255
- +#190#129'A'#255#179'r<'#255#145'Y0'#255'k?"'#255'c7'#31#255'[4 '#248'IC@'#209
- +'DDD'#200'CCC'#190'CCC'#163'DDDtCCCAEEE'#26'III'#7#0#0#0#1#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'III'#7'==='#25'AAA?CCCsBBB'
- +#162'K?;'#202'^4'#30#252'c8 '#255'oB%'#255#160'b5'#255#183'v>'#255#194#134'D'
- +#255#205#148'J'#255#215#161'M'#255#223#171'Q'#255#228#177'T'#255#232#182'U'
- +#255#234#185'V'#255#236#187'V'#255#236#187'V'#255#237#188'W'#255#237#189'W'
- +#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'
- +#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'
- +#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'
- +#255#237#188'W'#255#237#188'W'#255#159'~:'#255#16#13#6#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255#16#13#6
- +#255'9-'#21#255'y`,'#255#208#165'M'#255#237#188'W'#255#237#188'W'#255#237#188
- +'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188
- +'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#188
- +'W'#255#237#188'W'#255#237#188'W'#255#237#188'W'#255#237#189'W'#255#237#188
- +'W'#255#236#187'V'#255#235#186'V'#255#234#184'U'#255#231#180'U'#255#227#175
- +'R'#255#221#169'Q'#255#213#157'L'#255#202#144'H'#255#191#129'C'#255#180's='
- +#255#145'X0'#255'j>#'#255'b6'#31#255'Z5#'#245'GDB'#206'DDD'#200'CCC'#186'DDD'
- +#154'EEEhBBB6@@@'#20'333'#5#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#1'@@@'#4'GGG'#18'AAA3DDDfCCC'#152'IA>'#195'\4 '#250'c7'#31#255'm@#'#255
- +#156'_5'#255#182'v?'#255#194#134'E'#255#206#148'K'#255#215#161'O'#255#223#171
- +'S'#255#228#178'V'#255#232#182'V'#255#233#185'X'#255#234#186'X'#255#235#187
- +'X'#255#236#187'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188
- +'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188
- +'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188
- +'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255'9-'#21
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#6
- +#5#2#255'$'#29#14#255'ZH"'#255#169#135'@'#255#234#186'X'#255#236#188'X'#255
- ,#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255
- +#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255
- +#236#188'X'#255#236#187'X'#255#235#187'Y'#255#235#186'X'#255#234#186'X'#255
- +#233#184'W'#255#231#180'W'#255#227#176'T'#255#221#169'R'#255#213#158'N'#255
- +#203#145'J'#255#192#130'D'#255#179's='#255#139'U/'#255'i="'#255'a5'#30#255'X'
- +'7%'#242'FDC'#204'CCC'#198'DDD'#180'CCC'#144'CCC[AAA+III'#14'UUU'#3#0#0#0#1#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#128#128#2'@@@'#12'AAA''CCCWCCC'#140'GB?'
- +#185'Z4!'#247'a6'#30#255'j?"'#255#151']2'#255#181't>'#255#194#133'F'#255#206
- +#149'M'#255#215#161'Q'#255#223#170'T'#255#228#178'W'#255#231#181'Y'#255#232
- +#183'Y'#255#233#185'Z'#255#234#185'Y'#255#234#186'Y'#255#234#186'Y'#255#234
- +#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234
- +#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234
- +#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234
- +#186'Z'#255#234#186'Z'#255'C5'#26#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#1#1#1#255#20#16#8#255'K;'#29#255#189#150'I'#255#234#186'Z'#255#234#186
- +'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186
- +'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Z'#255#234#186'Y'#255#234#186
- +'Y'#255#234#185'Y'#255#233#185'Z'#255#232#183'Y'#255#230#181'X'#255#226#176
- +'W'#255#221#169'T'#255#213#159'O'#255#203#145'K'#255#190#129'D'#255#178'p='
- +#255#134'Q-'#255'g;"'#255'`4'#29#255'U7('#238'CCC'#202'DDD'#195'DDD'#173'BBB'
- +#131'CCCL@@@ 999'#9#0#0#0#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'III'#7'BBB'#27'CC'
- +'CEDDD|DDD'#170'V6%'#238'`5'#30#255'h<"'#255#145'Y1'#255#179's?'#255#192#132
- +'F'#255#205#148'M'#255#215#161'R'#255#222#171'U'#255#227#176'X'#255#230#181
- +'Z'#255#231#183'Z'#255#232#183'['#255#232#184'['#255#233#185'['#255#233#185
- +'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185
- +'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185
- +'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185
- +'['#255#233#185'['#255#233#185'['#255#127'd1'#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#13#11#5
- +#255'N>'#31#255#193#153'L'#255#233#185'['#255#233#185'['#255#233#185'['#255
- +#233#185'['#255#233#185'['#255#233#185'['#255#233#185'['#255#233#185'['#255
- +#233#185'['#255#233#184'['#255#232#184'['#255#232#183'Z'#255#231#182'Z'#255
- +#229#180'Y'#255#226#175'X'#255#220#168'U'#255#213#158'R'#255#201#144'K'#255
- +#189#127'D'#255#175'n<'#255#128'N+'#255'e9 '#255'_3'#29#255'Q;1'#227'CCC'#201
- +'CCC'#191'CCC'#163'CCCrAAA;FFF'#22'333'#5#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'@@@'#4'<<<'
- +#17'AAA3EEEhCCC'#156'R:/'#220'_3'#29#255'e: '#255#134'Q-'#255#178'p>'#255#190
- +#130'F'#255#203#145'M'#255#213#161'S'#255#221#170'W'#255#226#176'Z'#255#229
- +#180'Z'#255#230#182'\'#255#231#182'\'#255#231#183'\'#255#231#183'\'#255#231
- +#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231
- +#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231
- +#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231
- +#183'\'#255#231#183'\'#255#231#183'\'#255#180#142'G'#255#1#1#1#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#15#12#6#255'VE"'#255#215#171'V'#255
- +#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255
- +#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#182'\'#255
- +#230#181'['#255#228#178'['#255#225#175'Y'#255#219#168'W'#255#211#156'Q'#255
- +#200#142'K'#255#187'|D'#255#172'k<'#255'wF('#255'c7 '#255'^1'#30#254'K@:'#214
- +'DDD'#199'CCC'#184'CCC'#148'AAA^GGG+NNN'#13'UUU'#3#0#0#0#0#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'MMM'#10'@'
- +'@@$DDDSDDD'#139'L?8'#197'^1'#29#254'c7 '#255'wG)'#255#173'l<'#255#188#127'E'
- +#255#201#144'N'#255#212#158'T'#255#220#169'X'#255#225#175'['#255#228#179'\'
- +#255#229#180'\'#255#230#181']'#255#230#181']'#255#230#182']'#255#230#182']'
- +#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']'
- +#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']'
- +#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']'#255#230#182']'
- +#255#230#182']'#255#230#182']'#255#221#175'Y'#255#10#8#4#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1#255'4'
- +')'#21#255#184#146'J'#255#230#182']'#255#230#182']'#255#230#182']'#255#230
- +#182']'#255#230#182']'#255#230#182']'#255#230#182']'#255#230#181']'#255#229
- +#182']'#255#228#180']'#255#227#178'\'#255#224#174'['#255#218#166'W'#255#209
- +#155'R'#255#198#139'K'#255#184'zC'#255#162'd8'#255'l@$'#255'a5'#30#255'Z3 '
- +#249'FBA'#206'DDD'#196'CCC'#174'CCC'#129'BBBIFFF'#29'@@@'#8#0#0#0#1#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'333'#5'FF'
- +'F'#22'BBB>CCCvFA?'#174'Z3'#31#248'`5'#30#255'l@$'#255#163'd9'#255#184'{D'
- +#255#199#142'N'#255#210#156'T'#255#218#167'Y'#255#223#174'\'#255#226#177'^'
- +#255#228#179'^'#255#228#179'^'#255#228#180'_'#255#228#180'_'#255#228#180'_'
- +#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'
- +#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'
- +#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'
- +#255#228#180'_'#255#228#180'_'#255#228#180'_'#255'bM)'#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#27#21#11#255#140'o;'#255#228#180'_'#255#228#180
- +'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180
- +'_'#255#228#179'^'#255#227#179'^'#255#226#176']'#255#222#172'['#255#216#164
- +'X'#255#207#152'R'#255#195#137'K'#255#181'tA'#255#149'Z3'#255'g<"'#255'_3'#29
- +#255'V6'''#239'CCC'#201'CCC'#190'CCC'#159'CCCkCCC5GGG'#18'@@@'#4#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'@@@'#12'CCC'
- +'*DDD^DDD'#150'U6('#230'^2'#28#255'f:!'#255#149'Z3'#255#181'uB'#255#195#137
- +'K'#255#208#154'T'#255#216#165'Y'#255#221#172']'#255#225#176'^'#255#226#178
- +'_'#255#227#178'_'#255#227#178'_'#255#227#179'_'#255#227#179'_'#255#227#179
- +'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179
- +'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179
- +'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179
- +'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#13#10#6#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'&'#30#16#255#208#164
- +'W'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#178
- +'_'#255#227#178'_'#255#226#179'`'#255#226#177'_'#255#224#176'^'#255#220#170
- +'\'#255#214#162'X'#255#205#149'R'#255#191#131'I'#255#177'p?'#255#131'O.'#255
- +'c7 '#255']1'#29#255'N;3'#222'DDD'#199'DDD'#181'CCC'#140'DDDSDDD"999'#9#0#0#0
- +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'+++'#6'@@@'#24
- +'EEECCCC~K=7'#193']0'#28#255'b6'#31#255#129'M,'#255#177'o@'#255#191#131'J'
- +#255#204#149'S'#255#214#163'Z'#255#220#171']'#255#223#174'_'#255#225#176'`'
- +#255#225#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'
- +#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'
- +#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'
- ,#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'
- +#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#161'~D'#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#4#3#2
- +#255#134'i9'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255#226#177'`'#255
- +#226#177'`'#255#225#178'`'#255#225#177'`'#255#224#176'_'#255#222#174'^'#255
- +#219#169']'#255#212#159'X'#255#200#144'Q'#255#187'~G'#255#170'j<'#255'qB%'
- +#255'`5'#30#255'Z2'#31#250'FBA'#205'CCC'#193'DDD'#166'CCCsCCC9CCC'#19'@@@'#4
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'@@@'#12'AAA+BBB'
- +'aDBB'#155'Y3!'#244'_3'#29#255'l?$'#255#167'f;'#255#186'}H'#255#200#144'R'
- +#255#211#158'Y'#255#218#168']'#255#221#172'`'#255#223#174'a'#255#223#176'a'
- +#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'
- +#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'
- +#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'
- +#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176'b'
- +#255#224#176'b'#255#224#176'b'#255#224#176'b'#255'hR.'#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255'qY2'#255#224#176'b'#255#224#176'b'#255#224#176'b'#255#224#176
- +'b'#255#224#176'b'#255#224#176'b'#255#223#176'a'#255#223#174'`'#255#221#172
- +'_'#255#217#166']'#255#208#155'W'#255#196#139'O'#255#182'wE'#255#152'\5'#255
- +'e9!'#255'^2'#29#255'S7*'#233'DDD'#200'CCC'#183'DDD'#143'EEEUDDD"UUU'#9#0#0#0
- +#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'333'#5'@@@'#24'DDDDCCC~P8-'
- +#211']0'#29#255'c8!'#255#144'V2'#255#180'uD'#255#196#138'P'#255#207#155'X'
- +#255#215#165']'#255#220#171'`'#255#221#173'b'#255#222#174'a'#255#222#175'b'
- +#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'
- +#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'
- +#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'
- +#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'
- +#255#222#175'b'#255#222#175'b'#255#222#175'b'#255'VD&'#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#1#1#0#255#166#132'J'#255#222#175'b'#255#222#175'b'#255#222#175
- +'b'#255#222#175'b'#255#222#175'b'#255#222#175'b'#255#222#174'a'#255#221#173
- +'a'#255#219#170'`'#255#213#163'\'#255#205#150'V'#255#192#132'M'#255#176'oA'
- +#255'}K,'#255'a5'#31#255'\0'#28#254'I?;'#212'CCC'#194'DDD'#166'CCCrDDD8GGG'
- +#18'@@@'#4#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'FFF'#11'DDD)BBB`G@<'
- +#164'[1'#29#252'_3'#29#255'uD)'#255#174'l?'#255#189#130'L'#255#204#150'V'#255
- +#213#162'^'#255#217#168'`'#255#220#172'b'#255#221#173'b'#255#221#173'c'#255
- +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255
- +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255
- +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255
- +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255
- +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255'gQ.'#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- ,#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#8#6#4#255#207#163']'#255#221#173'c'#255
- +#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255#221#173'c'#255
- +#221#172'b'#255#219#171'b'#255#217#167'`'#255#211#159'['#255#200#145'T'#255
- +#185'{H'#255#164'd;'#255'h<#'#255'^1'#29#255'X3#'#244'DDD'#200'CCC'#183'DDD'
- +#142'DDDSFFF!@@@'#8#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@@'#4'III'#21'EEE?DD'
- +'D|S5'''#222'\1'#28#255'c8!'#255#158'_8'#255#183'yH'#255#198#142'S'#255#209
- +#158'\'#255#215#166'`'#255#218#170'b'#255#219#171'c'#255#219#171'd'#255#219
- +#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219
- +#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219
- +#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219
- +#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219
- +#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#213
- +#168'b'#255#3#3#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'M<#'#255#219#172
- +'d'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172'd'#255#219#172
- +'d'#255#219#171'd'#255#219#170'c'#255#217#168'b'#255#214#164'`'#255#207#153
- +'Z'#255#194#136'P'#255#178'rD'#255#139'R1'#255'a4'#31#255'\0'#28#255'L<5'#219
- +'CCC'#193'DDD'#164'CCCoCCC5@@@'#16'UUU'#3#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'@@@'#8
- +'BBB#CCCWHA='#158'\0'#28#253'_3'#29#255'~I+'#255#175'nB'#255#191#133'O'#255
- +#205#151'Z'#255#213#163'a'#255#216#167'c'#255#217#169'c'#255#218#170'd'#255
- +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255
- +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255
- +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255
- +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255
- +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255
- +#218#170'd'#255#218#170'd'#255'YF)'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#15#12#7#255#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#170'd'#255
- +#218#170'd'#255#218#170'd'#255#218#170'd'#255#218#169'c'#255#217#168'c'#255
- +#215#166'b'#255#211#160'_'#255#201#147'W'#255#187#127'L'#255#169'h>'#255'l=$'
- +#255'^1'#29#255'W3"'#244'DDD'#199'DDD'#180'DDD'#136'DDDKBBB'#27'UUU'#6#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0'UUU'#3'DDD'#15'EEE4BBBpS6)'#215'\1'#28#255'b7!'#255#158'_9'
- +#255#184'{J'#255#199#144'W'#255#209#158'_'#255#214#165'c'#255#216#168'd'#255
- +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255
- +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255
- +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255
- +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255
- +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255
- +#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255
- +'YD)'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#189#147'W'#255#217#168'd'
- +#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'#255#217#168'd'
- +#255#217#168'd'#255#216#168'd'#255#215#167'c'#255#213#164'a'#255#207#154']'
- +#255#195#138'S'#255#179'tF'#255#139'R1'#255'`5'#30#255'\0'#28#255'K=7'#216'D'
- +'DD'#191'DDD'#157'CCCcAAA+FFF'#11#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'+++'#6'EEE'#26'BBBIE?='
- +#144'Z0'#28#252'^2'#29#255'zF*'#255#174'mB'#255#192#135'R'#255#205#152'\'#255
- +#211#161'b'#255#214#165'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255
- +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255
- +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255
- +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255
- +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255
- +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255
- +#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255'jR1'#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255'fN/'#255#215#166'd'#255#215#166'd'#255#215#166'd'
- +#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'#255#215#166'd'
- +#255#215#167'e'#255#214#164'c'#255#210#159'a'#255#202#148'Z'#255#187#128'N'
- +#255#168'f='#255'i;#'#255'\1'#28#255'V3#'#242'CCC'#197'DDD'#173'BBB{FFF>@@@'
- +#20'@@@'#4#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#1'MMM'#10'FFF(CCC_R6*'#206'\0'#28#255'`5'#31#255#154'\8'
- +#255#182'yJ'#255#199#144'Y'#255#208#156'`'#255#212#163'd'#255#213#165'd'#255
- +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255
- +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255
- +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255
- +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255
- +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255
- +#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255
- +#214#165'e'#255#214#165'e'#255#214#165'e'#255#135'h@'#255#2#1#1#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'b'
- +'L/'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#214#165
- +'e'#255#214#165'e'#255#214#165'e'#255#214#165'e'#255#213#165'e'#255#213#164
- +'d'#255#211#161'c'#255#206#154'^'#255#194#139'U'#255#177'sF'#255#135'P/'#255
- +'^3'#29#255'[/'#27#255'J>9'#213'DDD'#185'CCC'#144'DDDSHHH III'#7#0#0#0#1#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'UUU'#3
- +'<<<'#17'DDD8DBAyZ0'#29#248'\1'#28#255'uB'''#255#172'lA'#255#190#132'Q'#255
- +#203#151'^'#255#209#160'c'#255#211#162'e'#255#212#163'e'#255#212#163'e'#255
- +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255
- +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255
- +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255
- +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255
- +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255
- +#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255
- +#212#163'e'#255#212#163'e'#255#212#163'e'#255#156'xK'#255#1#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'jQ2'#255#212
- +#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212
- +#163'e'#255#212#163'e'#255#212#163'e'#255#212#163'e'#255#212#162'e'#255#211
- +#162'd'#255#208#158'b'#255#200#147'['#255#186'~M'#255#165'd<'#255'd8!'#255'\'
- +'0'#28#255'T5'''#237'CCC'#193'DDD'#162'CCCjCCC.@@@'#12#0#0#0#2#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'333'#5'GGG'#25'BB'
- +'BIN:1'#174'[/'#27#255'^2'#29#255#145'T3'#255#180'vI'#255#196#142'Y'#255#206
- +#155'a'#255#209#161'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211
- +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211
- +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211
- ,#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211
- +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211
- +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211
- +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211
- +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255'O=&'#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'sX7'#255#211
- +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211
- +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#210
- +#161'f'#255#209#159'd'#255#204#153'`'#255#192#135'U'#255#175'pE'#255'~H+'#255
- +']0'#29#255'Z0'#28#253'FBA'#201'DDD'#176'CCC~FFF>CCC'#19'@@@'#4#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'999'#9'EEE%CCC[V3'
- +'$'#222'\0'#27#255'f7!'#255#167'd>'#255#187#128'Q'#255#200#148'^'#255#207#156
- +'d'#255#209#159'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160
- +'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160
- +'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160
- +'e'#255#209#160'e'#255#209#160'e'#255#151'tI'#255'2&'#25#255#27#21#13#255#15
- +#12#7#255#7#5#3#255#7#5#3#255' '#25#16#255'P='''#255#151'tI'#255#209#160'e'
- +#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'
- +#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'
- +#255#209#160'e'#255#209#160'e'#255#6#5#3#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#146'pF'#255#209#160'e'#255#209#160'e'#255
- +#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255
- +#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#160'e'#255#209#159'e'#255
- +#206#155'c'#255#198#143'['#255#182'zM'#255#151'Y6'#255'^3'#29#255'[/'#27#255
- +'N:1'#222'DDD'#185'DDD'#142'DDDOIII'#28'+++'#6#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2';;;'#13'DDD1F@=x[/'#28#253'\1'#28
- +#255'~G+'#255#174'oE'#255#193#137'X'#255#203#151'b'#255#207#156'e'#255#207
- +#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208
- +#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208
- +#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255'x[;'
- +#255#15#12#8#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#4#3#2#255'bJ0'#255#208#158'f'#255#208#158'f'
- +#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'
- +#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255'3'''#25#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#1#255#208#158'f'
- +#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'
- +#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'#255#208#158'f'
- +#255#208#158'f'#255#207#158'e'#255#206#156'd'#255#201#149'_'#255#189#131'T'
- +#255#169'h@'#255'j:#'#255'\0'#28#255'V3#'#242'DDD'#191'CCC'#156'BBB`AAA''333'
- +#10#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@@'#4'C'
- +'CC'#19'EEE?Q7+'#179'[/'#27#255'^1'#29#255#152'X6'#255#181'yM'#255#197#144']'
- +#255#204#153'c'#255#206#155'f'#255#206#156'e'#255#206#156'e'#255#206#156'e'
- +#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'
- +#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'
- +#255#202#154'c'#255'6)'#27#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#14#10#7#255#178#135'W'#255#206#156'e'#255#206#156'e'#255#206#156'e'
- +#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'
- +#255#206#156'e'#255'WB+'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- ,#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#29#22#14#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'
- +#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'
- +#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#206#156'e'#255#205#156'e'
- +#255#203#151'c'#255#194#139'Z'#255#176'qH'#255#131'K-'#255'\1'#28#255'[/'#27
- +#255'HA='#204'DDD'#169'DDDqEEE4III'#14#128#128#128#2#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'+++'#6'BBB'#27'EEENW2!'#228'[/'#27#255'i9!'
- +#255#168'e?'#255#187#130'T'#255#200#147'`'#255#203#153'e'#255#205#154'e'#255
- +#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255
- +#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255
- +#205#154'e'#255#205#154'e'#255#199#150'a'#255#19#14#9#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#7#6#4#255#178#133'W'
- +#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'
- +#255#205#154'e'#255#205#154'e'#255#205#154'e'#255'S>)'#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#128'a?'#255#205#154'e'#255#205#154'e'
- +#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'
- +#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'#255#205#154'e'
- +#255#205#154'e'#255#204#154'e'#255#203#152'd'#255#197#145'^'#255#182'zO'#255
- +#157'Z8'#255']1'#29#255'[/'#27#255'P9.'#226'CCC'#179'CCC'#129'CCCA@@@'#20'@@'
- +'@'#4#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'999'#9'EEE%EA?'
- +'b[/'#27#253'\0'#27#255#127'F*'#255#173'nG'#255#191#136'Z'#255#200#149'c'#255
- +#202#152'e'#255#202#152'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255
- +#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255
- +#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255#31#24#16#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#11#8#6#255#200#151'e'#255#202#153'e'#255#202#153'e'#255#202
- +#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255'O;'''
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255''''#29#19#255#202#153'e'#255
- +#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255
- +#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#153'e'#255
- +#202#153'e'#255#202#153'e'#255#202#153'e'#255#202#152'e'#255#202#151'd'#255
- +#199#147'b'#255#188#130'U'#255#168'e@'#255'k:"'#255'[/'#27#255'V3$'#241'CCC'
- +#186'BBB'#142'EEENBBB'#27'+++'#6#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#2'@@@'#12'DDD-O:0'#146'[/'#27#255'\0'#28#255#145'R2'#255#179'wM'
- +#255#194#141'^'#255#200#148'c'#255#201#150'e'#255#201#150'e'#255#201#150'e'
- +#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'
- +#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'
- +#255';,'#30#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'S>*'#255#201#150'e'
- +#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'
- +#255#201#150'e'#255'K8&'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#29#22#14#255
- +#184#138']'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255
- ,#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255
- +#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255#201#150'e'#255
- +#201#150'e'#255#200#149'd'#255#199#148'c'#255#191#136'['#255#173'mG'#255'}D('
- +#255'\0'#27#255'Z0'#28#253'DBB'#192'CCC'#152'DDDZBBB#@@@'#8#0#0#0#1#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#128#128#2'III'#14'CCC5T5'''#190'[/'#27#255
- +'_2'#29#255#162'^:'#255#184'}S'#255#195#142'`'#255#198#147'd'#255#199#148'd'
- +#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'
- +#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'
- +#255#199#148'd'#255#147'mJ'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#3#2#1#255#195#144'b'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255
- +#199#148'd'#255#199#148'd'#255#199#148'd'#255'H6$'#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#3#2#1#255#23#17#12
- +#255'qT8'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199
- +#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199
- +#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#199
- +#148'd'#255#199#148'd'#255#199#148'd'#255#199#148'd'#255#198#146'c'#255#193
- +#140'^'#255#178'uN'#255#143'O1'#255'\0'#28#255'[/'#27#255'J=7'#208'CCC'#161
- +'DDDfAAA+FFF'#11#0#0#0#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'UUU'#3'<<<'
- +#17'CCC=X1 '#227'[/'#27#255'm:"'#255#167'eA'#255#187#130'X'#255#195#143'a'
- +#255#196#144'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'
- +#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'
- +#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#19#14#10#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#135'cD'#255#197#145'c'#255#197
- +#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255'I5$'
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#19#14#10#255'4&'#26#255'cI2'#255
- +#161'vP'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197
- +#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197
- +#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197
- +#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197#145'c'#255#197
- +#145'c'#255#197#145'b'#255#196#144'c'#255#194#140'`'#255#182'|S'#255#159'\:'
- +#255']2'#28#255'[/'#27#255'Q8-'#226'DDD'#168'DDDqAAA3NNN'#13#128#128#128#2#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@@'#4':::'#22'G@/[/'#27
- +#254'[/'#27#255'}A&'#255#167'gD'#255#180'zW'#255#181'|Y'#255#181'|Y'#255#181
- +'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'
- +#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#136']C'#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#19#13#9#255#151'gJ'#255#181'|Y'#255#181'|Y'#255#181
- +'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'
- +#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#171'vU'#255'1"'#24#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'}V>'#255
- +#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181
- +'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'
- +#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255
- +#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181
- +'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'#255#181'|Y'
- +#255#181'|Y'#255#181'|Y'#255#178'wT'#255#161'];'#255'k8 '#255'[/'#27#255'V3#'
- +#238'DDD'#151'CCCWFFF!@@@'#8#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'FFF'#11
- +'K:3?[/'#27#255'[/'#27#255#131'F*'#255#169'iH'#255#179'xV'#255#180'zW'#255
- +#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180
- +'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255'<)'#29#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#1#1#1#255'O6&'#255#180'{W'#255#180'{W'#255#180'{W'#255#180
- +'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'
- +#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255
- +#180'{W'#255#142'aE'#255#27#19#13#255#2#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255
- ,#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#8#5#4#255
- +#135']A'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180
- +'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255'pL6'#255'+'#29#20#255'('#28#19
- +#255'*'#28#20#255'+'#29#21#255'-'#30#21#255'fF2'#255#180'{W'#255#180'{W'#255
- +#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180
- +'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'#255#180'{W'
- +#255#180'{W'#255#180'{W'#255#180'{W'#255#180'zX'#255#178'vU'#255#163'_>'#255
- +'r<"'#255'[/'#27#255'X2!'#243'CCC'#152'BBBYDDD"@@@'#8#0#0#0#1#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#2'FFF'#11'N8.J[/'#27#255'[/'#27#255#135'H,'#255#170'kI'#255
- +#178'wV'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179
- +'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'
- +#255#16#11#8#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#19#13#10#255#150'fJ'#255#179'yX'#255#179
- +'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'
- +#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255
- +#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179
- +'yX'#255'~V>'#255'=)'#30#255#19#13#9#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255'$'#24#17#255#172'uT'#255#179'yX'#255#179'yX'#255#179'yX'
- +#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#158'kN'#255'=)'#30#255#6
- +#4#3#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#6#4#3#255'?+'#31#255#164'oP'#255#179'yX'#255#179'yX'#255#179'yX'#255#179
- +'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'
- +#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255#179'yX'#255
- +#177'uU'#255#164'b@'#255'v?%'#255'[/'#27#255'Y1'#31#246'CCC'#152'BBBYDDD"@@@'
- +#8#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'FFF'#11'Q7+U[/'#27#255'\0'#28#255
- +#139'J-'#255#171'lL'#255#177'wW'#255#178'wV'#255#178'wV'#255#178'wV'#255#178
- +'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'
- +#255#178'wV'#255#172'sT'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1#255'O5&'#255#178'wV'#255#178'wV'
- +#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255
- +#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178
- +'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'
- +#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#176'wV'#255
- +'vO9'#255'7%'#27#255#16#10#8#255#1#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#11#8#6#255'9&'#28#255#137'\C'#255#178'wV'#255#178'wV'#255
- +#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255'M3%'
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'4"'#25#255#178'wV'
- +#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255
- +#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178'wV'#255#178
- +'wV'#255#178'wV'#255#176'tT'#255#165'cC'#255'yA'''#255'[/'#27#255'Z0'#29#250
- +'DDD'#150'CCCWFFF!III'#7#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'MMM'#10'R4'
- +'''^[/'#27#255'\0'#28#255#142'M.'#255#171'nN'#255#177'uV'#255#177'wX'#255#177
- +'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'
- +#255#177'wX'#255#177'wX'#255#177'wX'#255'gF3'#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#23#16#12#255#152'fK'#255#177
- +'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'
- +#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255
- +#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177
- +'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'
- +#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#173'uV'#255
- +#136'\D'#255#133'YB'#255#131'XA'#255#128'V@'#255#153'gL'#255#177'wX'#255#177
- +'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'
- +#255#177'wX'#255#177'wX'#255'S8)'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255'"'#23#17#255#175'wX'#255#177'wX'#255#177
- +'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'
- +#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#177'wX'#255#175'tU'#255
- +#166'eE'#255'}B)'#255'\0'#28#255'[/'#28#253'CCC'#148'CCCTBBB'#31'III'#7#0#0#0
- ,#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'999'#9'V4%h[/'#27#255'\0'#28#255#145'O0'
- +#255#171'mN'#255#175'sU'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255
- +#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175
- +'uW'#255'*'#29#21#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2
- +#1#1#255'X;,'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255
- +#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175
- +'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'
- +#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255
- +#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175
- +'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'
- +#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255
- +#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255'^?/'#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255'$'#24#18#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255
- +#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175'uW'#255#175
- +'uW'#255#175'uW'#255#175'uW'#255#175'sT'#255#166'eE'#255#128'D*'#255'\0'#28
- +#255'[/'#27#255'ECB'#149'CCCP@@@'#28'UUU'#6#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#1'@@@'#8'W3#q[/'#27#255'\1'#29#255#150'Q1'#255#171'mN'#255#174'sU'#255
- +#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175
- +'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#15#10#8#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#4#3#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#29#19#14#255#156'iM'#255#175'uV'#255
- +#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175
- +'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'
- +#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255
- +#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175
- +'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'
- +#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255
- +#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175
- +'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#11#7#6#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255'sM9'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255
- +#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175'uV'#255#175
- +'tV'#255#174'rS'#255#167'fG'#255#131'G,'#255'\0'#28#255'[/'#27#255'GA?'#150
- +'CCCLGGG'#25'333'#5#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'III'#7'W3#k[/'#27
- +#255'\1'#29#255#149'P2'#255#169'lM'#255#174'qT'#255#175'tV'#255#175'tV'#255
- +#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175
- +'tV'#255#175'tV'#255#175'tV'#255#9#6#4#255#0#0#0#255#0#0#0#255#0#0#0#255#136
- +'ZC'#255'T8*'#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#7#5#3#255
- +'bA0'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'
- +#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255
- +#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175
- +'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'
- +#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255
- +#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175
- +'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'
- +#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255
- +#165'nR'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#10#7#5#255#175'tV'#255#175
- +'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'#255#175'tV'
- +#255#175'tV'#255#175'tV'#255#175'tV'#255#174'sU'#255#173'qR'#255#166'eG'#255
- +#131'F,'#255'\0'#28#255'[/'#27#255'EA?'#145'DDDGFFF'#22'@@@'#4#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#1'333'#5'W3#\[/'#27#255'\1'#29#255#146'P3'#255#168
- +'jM'#255#173'pT'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'
- +#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255
- +#4#3#2#255#0#0#0#255#0#0#0#255#21#14#10#255#173'rU'#255#173'rU'#255#152'dK'
- +#255'dB1'#255'A+ '#255'D-!'#255#141']E'#255#173'rU'#255#173'rU'#255#173'rU'
- +#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255
- +#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173
- +'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'
- ,#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255
- +#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173
- +'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'
- +#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255
- +#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#169'pS'#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#139'\D'#255#173'rU'#255#173'rU'
- +#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255#173'rU'#255
- +#173'rU'#255#173'rU'#255#173'qT'#255#172'oR'#255#165'cF'#255#128'E+'#255'\0'
- +#28#255'[/'#27#255'CBA'#132'DDD@CCC'#19'UUU'#3#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0'@@@'#4'U2"L[/'#27#255'\1'#29#255#143'N3'#255#168'hK'#255#172'oT'
- +#255#173'qU'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255
- +#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#1#1#1#255#0#0#0
- +#255#0#0#0#255'nI7'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173
- +'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'
- +#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255
- +#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173
- +'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'
- +#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255
- +#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173
- +'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'
- +#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255
- +#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#2#1#1#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255'H0$'#255#173'rV'#255#173'rV'#255#173'rV'
- +#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255#173'rV'#255
- +#173'rV'#255#173'qU'#255#171'nQ'#255#165'dF'#255'~D+'#255'\1'#29#255'Z0'#28
- +#252'CCCzCCC9@@@'#16#128#128#128#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'U'
- +'UU'#3'T2#=[/'#27#255'\1'#29#255#140'N1'#255#166'gI'#255#171'oR'#255#173'qU'
- +#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255
- +#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#1#1#1#255#27#18#13#255'a@0'
- +#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255
- +#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173
- +'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'
- +#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255
- +#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173
- +'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'
- +#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255
- +#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173
- +'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'
- +#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255'$'#24#18#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#31#20#15#255#173'qU'#255#173'qU'#255#173'qU'#255
- +#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173'qU'#255#173
- +'qU'#255#172'pT'#255#169'lP'#255#164'aD'#255'{C*'#255'\1'#29#255'Y0'#30#247
- +'CCCoBBB2;;;'#13#0#0#0#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#128#128#128
- +#2'V6''-[/'#27#255'\1'#29#255#137'L0'#255#165'fH'#255#170'mQ'#255#172'pT'#255
- +#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172
- +'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#166'lS'#255#172'pU'#255#172'pU'
- +#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255
- +#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172
- +'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'
- +#255#172'pU'#255#172'pU'#255#172'pU'#255#168'nS'#255#134'WB'#255'b@0'#255'tK'
- +'9'#255#166'lS'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'
- +#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255
- +#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172
- +'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'
- +#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255
- +#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#129'T@'#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- ,#255#0#0#0#255#0#0#0#255#22#14#11#255#172'pU'#255#172'pU'#255#172'pU'#255#172
- +'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'#255#172'pU'
- +#255#172'oT'#255#170'mP'#255#163'`C'#255'xB*'#255'\1'#29#255'Y1'#31#241'BBBd'
- +'CCC*MMM'#10#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'T7*'#29
- +'[/'#27#255'\1'#29#255#134'J0'#255#165'dG'#255#169'lQ'#255#171'pU'#255#172'q'
- +'W'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'
- +#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255
- +#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172
- +'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'
- +#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255
- +#135'YD'#255'$'#24#18#255#3#2#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#8#5#4#255#30#20#16#255'xO='#255#172'qW'#255#172'qW'#255#172'qW'#255
- +#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172
- +'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'
- +#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255
- +#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172
- +'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#14#9#7#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#20#13#10#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'
- +#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#172'qW'#255#171'oT'#255
- +#169'jM'#255#162'_A'#255's>'''#255'\1'#29#255'X2 '#234'CCCXDDD"@@@'#8#0#0#0#1
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'C><'#9'[/'#27#247'\1'#29#255
- +'}F-'#255#164'bE'#255#169'lO'#255#171'pT'#255#172'qV'#255#172'qV'#255#172'qV'
- +#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255
- +#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172
- +'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'
- +#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255
- +#172'qV'#255#172'qV'#255#154'eM'#255#22#15#11#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#25#17#13#255#136'ZE'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'
- +#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255
- +#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172
- +'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'
- +#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255
- +#172'qV'#255'U7*'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#17#11#9#255#172'qV'#255#172
- +'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'#255#172'qV'
- +#255#172'qV'#255#172'qV'#255#171'oT'#255#168'jM'#255#161'^@'#255'k;%'#255'\0'
- +#28#255'V3#'#220'CCCLEEE'#26'333'#5#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0'+++'#6'[/'#28#214'\1'#29#255't@)'#255#162'`B'#255#168'jO'#255
- +#172'pV'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173
- +'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'
- +#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255
- +#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173
- +'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#144'_I'#255#6#4#3
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'Z;-'#255
- +#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173
- +'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'
- +#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255
- +#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173
- +'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#171'pV'#255#3#2#1#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255'!'#22#17#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'
- +#255#173'rX'#255#173'rX'#255#173'rX'#255#173'rX'#255#172'qX'#255#171'oU'#255
- +#167'hM'#255#160'[>'#255'b5!'#255'\0'#28#255'S5'''#196'EEE?CCC'#19'@@@'#4#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'UUU'#3'Z0'#29#176'\1'#29
- +#255'k:%'#255#162'^A'#255#169'jN'#255#173'qV'#255#174'sY'#255#174'sY'#255#174
- +'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'
- +#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255
- +#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174
- ,'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'
- +#255#151'dM'#255#4#2#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#1#1#1#255#136'YF'#255#174'sY'#255#174'sY'#255#174's'
- +'Y'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'
- +#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255
- +#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174
- +'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'
- +#255#174'sY'#255'5#'#27#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'G.$'#255#174'sY'#255#174'sY'#255
- +#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174
- +'sY'#255#174'sY'#255#172'pV'#255#167'gK'#255#153'X:'#255'^3'#31#255'\0'#28
- +#255'Q7+'#166'BBB2777'#14#0#0#0#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#2'Z0'#29#137'\0'#28#255'a5!'#255#160']>'#255#168'jN'#255
- +#173'sY'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175
- +'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'
- +#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255
- +#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175
- +'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#29#20#15#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#8
- +#5#4#255#169'rX'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'
- +#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255
- +#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175
- +'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'
- +#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#156'jR'#255#1#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255'yQ?'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255
- +#175'v\'#255#175'v\'#255#175'v\'#255#175'v\'#255#174'u['#255#172'qV'#255#166
- +'gJ'#255#143'S6'#255'^2'#31#255'[/'#27#255'O;2'#130'CCC&999'#9#0#0#0#1#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'Z0'#29'a\0'#28#255
- +'^3'#31#255#153'W;'#255#168'jN'#255#174'tZ'#255#176'x_'#255#176'y_'#255#176
- +'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'
- +#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255
- +#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176
- +'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255'oL='#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255']@2'#255#176'y_'#255#176'y_'#255#176
- +'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255'Z=1'#255')'#28#22#255#26#18#14
- +#255#14#10#8#255#10#7#5#255#23#16#12#255'+'#30#23#255'E0&'#255#138'_J'#255
- +#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176
- +'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'
- +#255#176'y_'#255'#'#24#19#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#172'w]'#255#176'y_'#255#176'y_'#255
- +#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176'y_'#255#176
- +'y_'#255#175'w^'#255#172'rW'#255#165'fI'#255#134'K2'#255']1'#30#255'[/'#27
- +#255'H?:ZBBB'#27'+++'#6#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0'X/'#29'7[/'#27#255'^2'#31#255#141'P5'#255#167'hK'#255#174
- +'sY'#255#177'x_'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'
- +#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255
- +#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177
- +'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'
- +#255#177'za'#255#177'za'#255#9#6#5#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255'%'#25#20#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255'bD6'#255#8
- +#6#4#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255'>+"'#255#175'za'#255#177'za'#255#177'za'#255#177'za'
- +#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255
- +#177'za'#255#177'za'#255#177'za'#255#136'^K'#255#0#0#0#255#0#0#0#255#0#0#0
- ,#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#16#11#9#255#177'za'#255#177
- +'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'#255#177'za'
- +#255#177'za'#255#177'za'#255#176'x^'#255#172'qV'#255#164'cF'#255'{E,'#255']1'
- +#30#255'Z0'#29#245'DDD'#255
- +'`5!'#255'\0'#28#255'T5'''#155'DDD'#30'III'#7#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'Z/'#28'w\0'#28#255
- +'`5!'#255#157'\?'#255#172'pU'#255#179'}d'#255#181#129'i'#255#182#129'j'#255
- +#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255
- +#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255
- +#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255
- +#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255
- +#182#129'j'#255#182#129'j'#255#182#129'j'#255'.!'#27#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#2#1#1#255#166'va'#255#182#129'j'#255#182#129'j'#255'A.&'
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#9#6#5#255#170'yd'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182
- +#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182
- +#129'j'#255#182#129'j'#255#182#129'j'#255#8#6#5#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#135'`O'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255
- +#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255#182#129'j'#255
- +#182#129'j'#255#182#129'j'#255#181#128'h'#255#177'za'#255#169'kP'#255#139'Q7'
- +#255'^3'#31#255'\0'#28#255'N9/\GGG'#18'UUU'#3#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'X.'#26'4\0'#28#255
- ,'^3'#31#255#141'S8'#255#170'mQ'#255#179'|c'#255#182#130'k'#255#184#132'm'#255
- +#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255
- +#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255
- +#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255
- +#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255
- +#184#132'm'#255#184#132'm'#255#184#132'm'#255#20#15#12#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255'N8.'#255#184#132'm'#255#184#132'm'#255#184#132'm'
- +#255#22#16#13#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#21#15#13#255#182#130'm'#255#184#132'm'#255#184#132
- +'m'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132
- +'m'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255'N8.'#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#23#17#13#255#184#132'm'#255#184#132'm'#255#184#132'm'#255
- +#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255#184#132'm'#255
- +#184#132'm'#255#184#132'm'#255#183#131'l'#255#182#129'j'#255#177'x_'#255#167
- +'hK'#255'zG/'#255']1'#30#255'Z0'#28#241'@@@(MMM'#10#0#0#0#1#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'='#31
- +#18#3'[/'#27#238']1'#30#255'{G/'#255#167'hL'#255#177'za'#255#183#131'l'#255
- +#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255
- +#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255
- +#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255
- +#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255
- +#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#26#19#16#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#12#9#7#255#185#134'p'#255#185#134'p'#255#185#134'p'
- +#255#185#134'p'#255#3#2#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'U>4'#255#185#134'p'#255#185
- +#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185
- +#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#25#18
- +#15#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255'xWI'#255#185#134'p'#255#185#134'p'#255#185#134
- +'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134'p'#255#185#134
- +'p'#255#185#134'p'#255#185#134'p'#255#184#134'o'#255#182#129'j'#255#175'v\'
- +#255#165'dG'#255'h;&'#255'\1'#29#255'X2 '#193'==='#25'+++'#6#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0'[/'#27#170'\1'#29#255'f9%'#255#164'bG'#255#175'v]'#255#183#131
- +'l'#255#186#135'r'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137
- +'s'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137
- +'s'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137
- +'s'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137
- +'s'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255'$'#27#23
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#129'_P'#255#186#137's'#255#186#137's'#255
- +#186#137's'#255#186#137's'#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255' '#23#19#255#186
- +#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186
- +#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186
- +#137's'#255#172#127'j'#255#7#5#4#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#12#9#7#255#186#137's'#255#186#137's'
- +#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'
- +#255#186#137's'#255#186#137's'#255#186#137's'#255#186#137's'#255#185#135'q'
- +#255#181#129'i'#255#173'qW'#255#149'X='#255'`5!'#255'\0'#28#255'V4%'#127'333'
- +#15#0#0#0#3#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'Z/'#27'O\0'#28#255'_4 '#255#144'U:'
- +#255#172'qV'#255#182#130'k'#255#187#137't'#255#188#139'u'#255#188#140'v'#255
- +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255
- +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255
- ,#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255
- +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255
- +#188#140'v'#255'1$'#31#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255':+$'#255#188#140'v'#255#188#140
- +'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#1#1#1#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#4#3#3#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255
- +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255
- +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255'}]N'#255'6("'
- +#255#14#11#9#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'S>5'#255
- +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255
- +#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255#188#140'v'#255
- +#188#139'u'#255#186#136'r'#255#180'~f'#255#169'kP'#255'|H1'#255'^2'#31#255'['
- +'/'#27#249'L=6+III'#7#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#5'[/'#27#235
- +']1'#30#255'wD/'#255#169'jO'#255#180#127'g'#255#187#137'u'#255#189#141'x'#255
- +#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255
- +#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255
- +#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255
- +#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255
- +#189#142'y'#255#189#142'y'#255'J7/'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#16#12#11#255#187#140'y'#255
- +#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#1
- +#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#181#136'u'#255#189#142'y'#255#189#142
- +'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142
- +'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142
- +'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#11#8#7#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#1#1#1#255#181#136's'#255#189#142'y'#255#189#142'y'#255#189
- +#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189#142'y'#255#189
- +#142'y'#255#189#142'y'#255#189#142'y'#255#189#141'x'#255#186#136'q'#255#177
- +'za'#255#164'dG'#255'f:&'#255'\1'#29#255'Y1'#31#186'@@@'#16'UUU'#3#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'Z/'#27#147'\1'#29#255'b8$'#255#160'bF'#255
- +#177'y`'#255#186#137's'#255#190#143'z'#255#191#145'|'#255#191#145'|'#255#191
- +#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191
- +#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191
- +#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191
- +#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#162
- +'{i'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#1#1#1#255#162'{i'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255
- +#191#145'|'#255#191#145'|'#255#191#145'|'#255#2#1#1#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1
- +#1#1#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145
- +'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145
- +'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145
- +'|'#255#191#145'|'#255#5#4#3#255#0#0#0#255#0#0#0#255#0#0#0#255'&'#29#25#255
- +#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255
- +#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255#191#145'|'#255
- +#191#145'|'#255#189#142'y'#255#184#134'o'#255#174'sY'#255#143'U;'#255'`5!'
- +#255'\0'#28#255'U3$`@@@'#8#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0'Z.'#27'5\0'#28#255'_4 '#255#137'Q8'#255#173'rX'#255#184#134'o'#255#190#144
- +'{'#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192
- +#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255
- +#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127
- +#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147
- +#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#14
- ,#11#9#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255' '
- +#24#21#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255
- +#192#147#127#255#192#147#127#255#192#147#127#255#4#3#3#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#8#6#5#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127
- +#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147
- +#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192
- +#147#127#255#192#147#127#255#192#147#127#255#1#1#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#137'iZ'#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147
- +#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192#147#127#255#192
- +#147#127#255#192#147#127#255#192#146'~'#255#189#142'y'#255#182#129'j'#255#169
- +'lP'#255'uD.'#255'^2'#31#255'[/'#28#237'NFB'#21'UUU'#3#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#211']1'#30#255'l>)'#255#167'iM'
- +#255#181#127'g'#255#190#143'z'#255#193#148#128#255#194#149#130#255#194#149
- +#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194
- +#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255
- +#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130
- +#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149
- +#130#255#194#149#130#255'G60'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255'ZE<'#255#194#149#130#255#194#149#130#255#194#149#130#255
- +#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#7#6#5#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#23#17#15#255#194#149#130#255#194#149#130#255#194#149#130
- +#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149
- +#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194
- +#149#130#255#194#149#130#255#194#149#130#255#179#137'x'#255#0#0#0#255#0#0#0
- +#255#0#0#0#255'-#'#30#255#194#149#130#255#194#149#130#255#194#149#130#255#194
- +#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255#194#149#130#255
- +#194#149#130#255#194#149#130#255#194#149#130#255#192#147#127#255#188#140'v'
- +#255#177'za'#255#156'_D'#255'a6#'#255'\1'#29#255'Y1'#31#153'@@@'#8#0#0#0#1#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'Z/'#27']\0'#28#255
- +'`5!'#255#143'V='#255#175'v]'#255#187#138'u'#255#193#149#129#255#195#152#132
- +#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152
- +#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195
- +#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255
- +#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133
- +#255#195#152#133#255#195#152#133#255#170#133't'#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#172#133'u'#255#195#152#133#255#195#152
- +#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#146
- +'rd'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'_JA'#255#195#152#133#255#195#152#133
- +#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152
- +#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195
- +#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#140'm`'#255#0#0
- +#0#255#0#0#0#255#6#5#4#255#186#145#127#255#195#152#133#255#195#152#133#255
- +#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#133
- +#255#195#152#133#255#195#152#133#255#195#152#133#255#195#152#132#255#192#147
- +#127#255#185#134'p'#255#172'pU'#255'|I2'#255'^3'#31#255'\0'#28#250'R5()UUU'#3
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#3
- +'[/'#27#221']1'#30#255'oA,'#255#169'lP'#255#183#131'l'#255#192#147#127#255
- +#196#154#135#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136
- +#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155
- +#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197
- +#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255
- +#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#26#20#18#255
- ,#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#8#6#5#255#197#155#136#255#197
- +#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255
- +#197#155#136#255#28#22#19#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#4#3#3#255#193#153#134#255
- +#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136
- +#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155
- +#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197
- +#155#136#255#182#143'~'#255'=0*'#255#7#5#5#255#130'fY'#255#197#155#136#255
- +#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136
- +#255#197#155#136#255#197#155#136#255#197#155#136#255#197#155#136#255#196#154
- +#136#255#195#152#133#255#190#144'{'#255#180'~f'#255#159'bG'#255'c8%'#255'\1'
- +#29#255'Z0'#30#163'III'#7#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27'g\0'#28#255'a6#'#255#147'Y@'#255#177
- +'za'#255#190#143'z'#255#196#154#135#255#198#157#139#255#198#157#139#255#198
- +#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255
- +#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139
- +#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157
- +#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198
- +#157#139#255'<0+'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'*!'#29#255
- +#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139
- +#255#198#157#139#255#164#130's'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'?2,'#255#198
- +#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255
- +#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139
- +#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157
- +#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198
- +#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255
- +#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139#255#198#157#139
- +#255#198#157#139#255#198#156#138#255#195#152#132#255#187#138't'#255#173'sY'
- +#255#127'L5'#255'^3'#31#255'\0'#28#252'U3$,'#128#128#128#2#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#7
- +'[/'#27#229'^2'#31#255'qB.'#255#171'nS'#255#185#134'p'#255#194#151#131#255
- +#198#158#140#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142
- +#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160
- +#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200
- +#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255
- +#200#160#142#255#200#160#142#255#200#160#142#255'9.)'#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255'hSJ'#255#200#160#142#255#200#160#142#255#200#160#142
- +#255#200#160#142#255#200#160#142#255#200#160#142#255'6+'''#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#6#5#5#255#184#148#131#255#200#160#142#255#200#160#142#255#200#160#142
- +#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160
- +#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200
- +#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255
- +#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142
- +#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160#142#255#200#160
- +#142#255#200#160#142#255#200#160#142#255#199#159#141#255#198#157#139#255#192
- +#147#127#255#181#127'g'#255#161'dI'#255'd:&'#255'\1'#29#255'Z0'#29#171'@@@'#4
- +#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27'q\1'#29#255'a6#'#255#143'W?'#255#177'za'#255
- +#191#144'|'#255#198#157#139#255#200#161#144#255#201#162#145#255#201#163#145
- +#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163
- +#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201
- +#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255
- +#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255'=2,'#255#0#0
- ,#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255'!'#27#24#255#197#161#143#255#201#163#145#255
- +#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#197#161#143
- +#255#3#2#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#1#1#1#255#149'zl'#255#201#163#145#255#201#163#145
- +#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163
- +#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201
- +#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255
- +#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145
- +#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#163
- +#145#255#201#163#145#255#201#163#145#255#201#163#145#255#201#162#145#255#200
- +#161#143#255#197#155#136#255#187#138'u'#255#173'rX'#255'|I3'#255'_4 '#255'\0'
- +#28#253'W1 2'#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#6'\0'#28#216'^2'#31#255
- +'i=)'#255#165'jP'#255#184#133'n'#255#196#152#134#255#201#162#145#255#202#164
- +#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202
- +#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255
- +#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148
- +#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165
- +#148#255'E82'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#2#255#1#1#1#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'.&"'#255#202#165#148#255#202#165#148
- +#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165
- +#148#255#146'wk'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'eRI'#255#202#165#148#255#202#165#148
- +#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165
- +#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202
- +#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255
- +#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148
- +#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165
- +#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202#165#148#255#202
- +#164#147#255#200#160#143#255#193#148#128#255#180'~f'#255#151'^D'#255'a7$'#255
- +'\1'#29#255'Z0'#28#156'UUU'#3#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27
- +'D\0'#28#255'`5!'#255#128'N8'#255#175'v]'#255#190#143'{'#255#200#159#142#255
- +#203#165#150#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151
- +#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167
- +#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204
- +#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255
- +#204#167#151#255'N?9'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'vaW'#255
- +#204#167#151#255#160#131'w'#255'cRI'#255'WG@'#255#168#137'|'#255#204#167#151
- +#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167
- +#151#255#204#167#151#255#204#167#151#255#145'wk'#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'G:4'#255#204#167
- +#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204
- +#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255
- +#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151
- +#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167
- +#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204
- +#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255#204#167#151#255
- +#204#167#151#255#204#167#150#255#202#165#148#255#198#155#138#255#186#137's'
- +#255#171'nU'#255'oB.'#255'^2'#31#255'\0'#28#235'V2"'#21#0#0#0#1#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#169'\1'#29#255'c9&'#255#155'aH'#255
- +#182#128'j'#255#195#152#133#255#202#164#148#255#205#169#154#255#206#169#155
- +#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169
- +#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206
- +#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255
- +#206#169#155#255#206#169#155#255#206#169#155#255'VGA'#255#0#0#0#255#0#0#0#255
- ,#0#0#0#255#5#4#4#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169
- +#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206
- +#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255
- +#206#169#155#255#152'}r'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#2#1#1#255'vaY'#255#206#169#155#255#206#169#155#255#206#169
- +#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206
- +#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255
- +#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155
- +#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169
- +#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206
- +#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255#206#169#155#255
- +#205#167#152#255#201#162#145#255#192#147#127#255#177'za'#255#138'T='#255'`6"'
- +#255'\1'#29#255'[0'#29'e'#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0'[/'#27#27'\0'#28#243'^3'#31#255'pC/'#255#171'oU'#255#188#138'u'
- +#255#199#158#141#255#205#169#154#255#207#171#157#255#207#172#158#255#207#172
- +#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207
- +#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255
- +#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158
- +#255#207#172#158#255'~i`'#255#0#0#0#255#0#0#0#255#0#0#0#255#22#18#16#255#207
- +#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255
- +#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158
- +#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172
- +#158#255'/''$'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#9#7#7#255
- +#164#136'~'#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158
- +#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172
- +#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207
- +#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255
- +#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158
- +#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172
- +#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#171#157#255#204
- +#167#151#255#196#153#136#255#183#131'l'#255#160'fK'#255'f;('#255']1'#30#255
- +'[/'#27#199'te^'#3#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0'[/'#27'q\0'#28#255'`6"'#255#130'P9'#255#177'x`'#255#192#146
- +#127#255#203#164#149#255#208#173#159#255#209#175#161#255#209#175#161#255#209
- +#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255
- +#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161
- +#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175
- +#161#255#199#167#153#255#0#0#0#255#0#0#0#255#0#0#0#255'.'#255#209#175#161
- +#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175
- +#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209
- +#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255
- +#209#175#161#255'*$!'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'"'#28#26#255#197#165#153#255
- +#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161
- +#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175
- +#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209
- +#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255
- +#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161
- +#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175#161#255#209#175
- +#161#255#209#175#161#255#209#175#161#255#209#174#160#255#207#171#157#255#200
- +#160#144#255#188#139'w'#255#171'pV'#255'rD0'#255'^3'#31#255'\0'#28#250'\2'#30
- +'1'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0'[/'#27#1'[/'#27#184']1'#30#255'c9&'#255#148'^E'#255#182#128'j'#255#197
- +#154#136#255#206#170#155#255#210#176#163#255#211#178#164#255#211#178#165#255
- +#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165
- +#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178
- ,#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211
- +#178#165#255#12#10#9#255#0#0#0#255#0#0#0#255'MA<'#255#211#178#165#255#211#178
- +#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211
- +#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255
- +#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165
- +#255#211#178#165#255#178#150#139#255'D95'#255#9#7#7#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'VIC'#255#211#178#165#255#211#178#165
- +#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178
- +#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211
- +#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255
- +#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165
- +#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178
- +#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211#178#165#255#211
- +#178#165#255#211#178#165#255#211#178#164#255#209#176#162#255#204#167#151#255
- +#193#148#129#255#177'x`'#255#129'P9'#255'`6"'#255'\0'#28#255'[0'#28't'#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0'[/'#27#21'\0'#28#229'^2'#31#255'i?+'#255#163'jP'#255#186#136
- +'s'#255#200#160#144#255#209#174#160#255#212#180#167#255#213#181#169#255#213
- +#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255
- +#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169
- +#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181
- +#169#255'.''%'#255#0#0#0#255',%#'#255#200#170#159#255#213#181#169#255#213#181
- +#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213
- +#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255
- +#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169
- +#255#213#181#169#255#213#181#169#255#213#181#169#255#139'vo'#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'.''$'#255#213#181#169#255#213#181#169
- +#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181
- +#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213
- +#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255
- +#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169
- +#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181
- +#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213#181#169#255#213
- +#181#169#255#213#181#169#255#212#180#168#255#211#178#165#255#207#171#157#255
- +#197#155#137#255#182#128'j'#255#148']E'#255'c9&'#255']1'#30#255'[/'#27#179#0
- +#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27'?\0'#28#252'_4 '#255'tF1'#255#172
- +'sY'#255#190#142'z'#255#203#165#150#255#211#178#164#255#213#183#170#255#214
- +#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255
- +#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172
- +#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184
- +#172#255#127'ng'#255'{ib'#255#214#184#172#255#214#184#172#255#214#184#172#255
- +#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172
- +#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184
- +#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214
- +#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255' '#28#26#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#14#12#11#255#209#180#168#255#214#184#172
- +#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184
- +#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214
- +#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255
- +#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172
- +#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184
- +#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214#184#172#255#214
- +#184#172#255#214#184#172#255#214#184#172#255#213#182#169#255#209#176#161#255
- +#200#161#143#255#186#135'q'#255#161'gO'#255'h=*'#255'^2'#31#255'\0'#28#226'W'
- +'-'#26#19#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27'}\1'#29#255'`6"'
- +#255'|M8'#255#175'x^'#255#192#147#127#255#205#170#154#255#213#181#169#255#215
- ,#185#173#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255
- +#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175
- +#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187
- +#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216
- +#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255
- +#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175
- +#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187
- +#175#255#216#187#175#255#216#187#175#255#216#187#175#255#187#162#151#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#2#255#180#156#146#255#216#187#175
- +#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187
- +#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216
- +#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255
- +#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175
- +#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187
- +#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216#187#175#255#216
- +#187#175#255#216#187#175#255#216#187#175#255#215#185#173#255#211#179#166#255
- +#202#165#148#255#188#139'w'#255#167'mU'#255'nC/'#255'^3'#31#255'\0'#28#251'Z'
- +'.'#27';'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#2'[/'#27
- +#170'\1'#29#255'a7$'#255#130'Q<'#255#178'{c'#255#195#151#132#255#208#173#159
- +#255#215#185#173#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189
- +#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217
- +#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255
- +#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178
- +#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189
- +#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217
- +#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255
- +#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255'.(&'#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#128'oi'#255#217#189#178#255#217#189#178
- +#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189
- +#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217
- +#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255
- +#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178
- +#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189
- +#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217#189#178#255#217
- +#189#178#255#217#189#178#255#217#188#177#255#213#183#170#255#205#168#153#255
- +#191#144'|'#255#170'rZ'#255'sF2'#255'`5!'#255'\0'#28#255'Z/'#27'g'#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#6'[/'#27
- +#188']1'#30#255'c9&'#255#136'V?'#255#180'~g'#255#197#154#136#255#209#176#162
- +#255#216#187#176#255#219#192#181#255#219#192#182#255#219#193#183#255#219#193
- +#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219
- +#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255
- +#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183
- +#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193
- +#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219
- +#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255
- +#219#193#183#255#219#193#183#255#158#138#131#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#1#1#1#255#131'sm'#255#219#193#183#255#219#193#183#255#219#193#183#255
- +#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183
- +#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193
- +#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219
- +#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255
- +#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183
- +#255#219#193#183#255#219#193#183#255#219#193#183#255#219#193#183#255#219#192
- +#182#255#218#191#180#255#215#185#173#255#207#172#156#255#193#147#128#255#174
- +'v^'#255'wJ6'#255'`6"'#255'\1'#29#255'[/'#27'~'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#12'[/'#27#203
- +']1'#30#255'c:'''#255#141'YC'#255#181#128'h'#255#198#155#138#255#210#177#164
- +#255#217#190#178#255#220#194#184#255#221#195#185#255#221#196#186#255#221#196
- +#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221
- +#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255
- +#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186
- +#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196
- +#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221
- +#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255
- +#221#196#186#255're_'#255#0#0#0#255#0#0#0#255#4#4#4#255#160#142#134#255#221
- +#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255
- +#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186
- +#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196
- +#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221
- +#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255
- +#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186#255#221#196#186
- +#255#221#196#186#255#221#196#186#255#221#195#185#255#219#193#183#255#216#187
- +#175#255#207#172#158#255#194#148#130#255#176'x_'#255'{M8'#255'a6#'#255'\1'#29
- +#255'[/'#27#148#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#21'\0'#28#217']1'#30#255'c:'''
- +#255#138'XB'#255#181#127'h'#255#197#156#137#255#211#178#164#255#218#191#180
- +#255#221#196#187#255#222#198#188#255#223#198#189#255#223#198#189#255#223#198
- +#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223
- +#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255
- +#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189
- +#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198
- +#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223
- +#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#221#196#187#255
- +#6#6#5#255#10#9#8#255#188#167#159#255#223#198#189#255#223#198#189#255#223#198
- +#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223
- +#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255
- +#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189
- +#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198
- +#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223
- +#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255#223#198#189#255
- +#222#198#188#255#221#196#186#255#217#188#177#255#208#173#159#255#193#149#129
- +#255#174'w^'#255'zM8'#255'a7$'#255'\1'#29#255'[/'#27#170'[/'#27#2#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0'[/'#27' \0'#28#223']1'#30#255'c:'''#255#132'T?'#255#180
- +'~g'#255#197#155#136#255#211#178#164#255#219#193#181#255#223#198#189#255#224
- +#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255
- +#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192
- +#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201
- +#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224
- +#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255
- +#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192
- +#255#224#201#192#255#224#201#192#255#134'xr'#255#205#184#176#255#224#201#192
- +#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201
- +#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224
- +#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255
- +#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192
- +#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201
- +#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224#201#192#255#224
- +#201#192#255#224#201#192#255#223#200#191#255#222#197#187#255#217#189#178#255
- +#207#172#158#255#192#147#127#255#171'u\'#255'vI6'#255'a6#'#255'\1'#29#255'[/'
- +#27#179'[/'#27#6#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#25'\'
- +'0'#28#209']1'#30#255'c9&'#255#128'Q='#255#177'{c'#255#195#151#133#255#209
- +#176#162#255#219#192#181#255#223#200#191#255#225#203#194#255#226#204#196#255
- +#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196
- +#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204
- +#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226
- +#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255
- +#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196
- +#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204
- +#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226
- +#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255
- +#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196
- +#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204
- +#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226
- +#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255#226#204#196#255
- +#226#204#196#255#226#204#196#255#226#203#195#255#225#202#193#255#222#198#188
- +#255#217#188#177#255#206#169#155#255#191#144'|'#255#168'qY'#255'rG3'#255'`6"'
- +#255'\1'#29#255'[/'#27#159'[/'#27#4#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0'[/'#27#15'\0'#28#193']1'#30#255'b8%'#255'yM8'#255#170
- +'u\'#255#192#146'~'#255#207#171#156#255#217#189#178#255#223#200#191#255#226
- +#205#197#255#227#206#198#255#228#207#199#255#228#207#199#255#228#207#199#255
- +#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199
- +#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207
- +#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228
- +#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255
- +#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199
- +#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207
- +#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228
- +#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255
- +#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199
- +#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207
- +#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228#207#199#255#228
- +#207#199#255#228#207#199#255#227#206#198#255#226#204#196#255#222#198#188#255
- +#215#185#173#255#202#165#148#255#187#137'u'#255#159'jR'#255'nD0'#255'`6"'#255
- +'\1'#29#255'[/'#27#137#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#8'[/'#27#175'\1'#29#255'`6"'#255'n'
- +'D0'#255#158'iR'#255#187#137'u'#255#202#165#148#255#215#186#174#255#223#199
- +#190#255#227#205#198#255#229#208#201#255#229#209#202#255#229#210#202#255#229
- +#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255
- +#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202
- +#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210
- +#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229
- +#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255
- +#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202
- +#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210
- +#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229
- +#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255
- +#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202
- +#255#229#210#202#255#229#210#202#255#229#210#202#255#229#210#202#255#229#209
- +#202#255#228#207#201#255#226#204#197#255#221#196#187#255#212#180#168#255#198
- +#157#140#255#183#130'l'#255#143'^G'#255'g>+'#255'_4 '#255'\1'#29#254'[/'#27
- +'q'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#3'[/'#27#132'\1'#29#254'_4 '#255'g>+'
- +#255#140'[F'#255#181#129'j'#255#198#155#138#255#211#178#165#255#221#195#185
- +#255#227#204#197#255#230#209#203#255#230#212#205#255#231#212#206#255#231#212
- +#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231
- +#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255
- +#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206
- +#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212
- +#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231
- +#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255
- +#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206
- +#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212
- +#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231
- +#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255#231#212#206#255
- +#231#212#206#255#231#211#206#255#230#211#205#255#229#209#201#255#225#203#194
- +#255#219#191#181#255#208#173#159#255#193#149#129#255#173'w`'#255'~Q='#255'c:'
- +''''#255'^2'#31#255'\0'#28#238'[/'#27'O'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0'[/'#27'F\0'#28#234'^2'#31#255'c:'''#255'zN:'#255#168's['#255
- +#190#143'{'#255#205#167#152#255#217#187#177#255#225#201#193#255#229#209#202
- +#255#232#213#207#255#232#214#209#255#233#215#210#255#233#215#210#255#233#215
- +#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233
- +#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255
- +#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210
- +#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215
- +#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233
- +#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255
- +#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210
- +#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215
- +#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233#215#210#255#233
- +#215#210#255#232#215#209#255#232#214#208#255#231#212#206#255#228#207#201#255
- +#223#198#189#255#213#182#170#255#200#160#144#255#186#136'r'#255#158'iR'#255
- +'pE2'#255'a7$'#255']1'#30#255'\0'#28#201'[/'#27#31#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#26'\0'#28#193']1'#30#255'`'
- +'6"'#255'iA.'#255#142']H'#255#179#128'h'#255#196#153#135#255#210#176#163#255
- +#220#194#184#255#227#205#198#255#231#212#206#255#233#216#211#255#234#217#212
- +#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218
- +#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234
- +#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255
- +#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213
- +#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218
- +#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234
- +#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255
- +#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213
- +#255#234#218#213#255#234#218#213#255#234#218#213#255#234#218#213#255#234#217
- +#212#255#234#216#211#255#233#215#210#255#230#211#205#255#226#203#195#255#218
- +#190#179#255#206#170#155#255#192#146#127#255#172'v`'#255#129'S?'#255'e<)'#255
- +'_4 '#255'\1'#29#255'[/'#27#143'[/'#27#5#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#3'[/'#27#127'\0'#28
- +#248'^3'#31#255'c:'''#255'sI6'#255#158'kT'#255#186#136's'#255#200#160#143#255
- ,#213#180#169#255#222#197#187#255#229#208#201#255#232#214#209#255#234#218#213
- +#255#235#219#215#255#236#220#215#255#236#220#216#255#236#220#216#255#236#220
- +#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236
- +#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255
- +#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216
- +#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220
- +#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236
- +#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255
- +#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216#255#236#220#216
- +#255#236#220#216#255#236#220#215#255#235#219#215#255#234#217#212#255#232#213
- +#207#255#227#205#198#255#219#193#183#255#209#176#162#255#196#153#136#255#181
- +#129'l'#255#145'`K'#255'lB0'#255'a7$'#255']1'#30#255'\0'#28#231'[/'#27'O'#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27'$\0'#28#185'\1'#29#255'`5!'#255
- +'f=*'#255#128'S>'#255#166'r['#255#188#139'v'#255#201#161#145#255#213#181#169
- +#255#223#197#189#255#229#209#202#255#233#216#210#255#235#219#215#255#236#221
- +#217#255#237#222#219#255#238#223#220#255#238#223#220#255#238#223#220#255#238
- +#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255
- +#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220
- +#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223
- +#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238
- +#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255
- +#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220#255#238#223#220
- +#255#237#222#219#255#237#222#218#255#236#221#217#255#235#218#214#255#232#214
- +#208#255#228#206#199#255#220#193#184#255#210#176#163#255#197#155#137#255#184
- +#134'o'#255#155'iR'#255'uI7'#255'c:'''#255'^3'#31#255'\1'#29#252'[/'#27#144
- +'[/'#27#14#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'['
- +'/'#27'U\0'#28#228']1'#30#255'`6"'#255'g>,'#255#127'R?'#255#164'qZ'#255#188
- +#139'v'#255#200#159#144#255#211#179#166#255#220#194#184#255#228#206#199#255
- +#232#214#209#255#235#219#215#255#237#222#219#255#238#225#221#255#239#225#222
- +#255#239#225#222#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226
- +#223#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226#223#255#239
- +#226#223#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226#223#255
- +#239#226#223#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226#223
- +#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226#223#255#239#226
- +#223#255#239#226#223#255#239#226#223#255#239#225#222#255#238#225#221#255#238
- +#224#220#255#237#222#218#255#235#218#214#255#231#212#206#255#226#203#195#255
- +#218#191#180#255#209#174#160#255#197#154#136#255#184#132'o'#255#154'hR'#255
- +'uK8'#255'e;('#255'_4 '#255'\1'#29#255'\0'#28#197'[/'#27'/'#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27
- +#12'[/'#27#134'\0'#28#242'^2'#31#255'a5#'#255'g>+'#255'|Q='#255#160'lV'#255
- +#184#133'p'#255#196#152#134#255#207#170#156#255#216#187#175#255#224#200#192
- +#255#230#210#203#255#234#216#211#255#236#220#216#255#238#224#220#255#239#226
- +#223#255#240#227#225#255#240#228#225#255#240#228#225#255#241#229#226#255#241
- +#229#226#255#241#229#226#255#241#229#226#255#241#229#227#255#241#229#227#255
- +#241#229#227#255#241#229#227#255#241#229#227#255#241#229#227#255#241#229#227
- +#255#241#229#227#255#241#229#227#255#241#229#226#255#241#229#226#255#241#229
- ,#226#255#241#229#226#255#240#228#225#255#240#228#225#255#240#227#224#255#239
- +#225#222#255#238#223#220#255#236#220#215#255#233#215#210#255#228#207#201#255
- +#222#196#187#255#213#183#170#255#204#166#150#255#192#147#127#255#179#127'i'
- +#255#150'fO'#255'tI7'#255'e;('#255'`5!'#255']1'#30#255'\0'#28#223'[/'#27'`[/'
- +#27#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#17'[/'#27#127'\0'#28#238']1'
- +#30#255'`6"'#255'e<)'#255'rI6'#255#142'_J'#255#170'wa'#255#188#140'w'#255#199
- +#158#141#255#208#173#159#255#216#186#175#255#222#196#187#255#227#206#198#255
- +#232#213#208#255#235#219#214#255#237#222#218#255#238#224#220#255#239#226#223
- +#255#240#227#225#255#241#229#226#255#242#230#228#255#242#230#228#255#242#231
- +#229#255#242#231#229#255#242#231#229#255#242#231#229#255#242#231#229#255#242
- +#231#229#255#242#231#229#255#242#230#228#255#241#229#227#255#241#229#226#255
- +#240#227#225#255#239#225#222#255#238#224#220#255#236#221#217#255#234#218#213
- +#255#231#211#206#255#226#204#196#255#220#194#184#255#214#183#171#255#206#169
- +#155#255#196#153#135#255#185#135'r'#255#162'q['#255#134'XD'#255'lC1'#255'c:'
- +''''#255'_4 '#255']0'#30#255'\0'#28#217'[/'#27'`[/'#27#4#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#13'[/'#27'w\0'#28#233
- +']1'#30#255'_4 '#255'b8%'#255'h?-'#255'zN;'#255#149'dP'#255#170'xa'#255#187
- +#137't'#255#194#150#131#255#202#164#148#255#210#176#163#255#216#187#175#255
- +#220#194#184#255#224#200#192#255#228#207#199#255#231#212#206#255#234#217#211
- +#255#236#220#215#255#236#222#217#255#237#222#219#255#238#223#220#255#238#223
- +#220#255#238#224#220#255#238#223#220#255#237#223#219#255#237#223#218#255#236
- +#221#217#255#235#219#215#255#233#216#210#255#230#211#204#255#227#204#197#255
- +#223#199#190#255#219#192#183#255#215#185#173#255#208#173#159#255#200#160#144
- +#255#192#146#127#255#183#133'o'#255#164's\'#255#142']J'#255'rI7'#255'f=*'#255
- +'a6#'#255'^3'#31#255'\1'#29#255'\0'#28#210'[/'#27'X[/'#27#2#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0'[/'#27#5'[/'#27'P\0'#28#173'\1'#29#249']1'#30#255'`5!'#255'c9&'#255'g'
- +'>,'#255'qH6'#255#133'YE'#255#153'iT'#255#172'yd'#255#186#136'q'#255#191#144
- +'}'#255#196#153#136#255#202#162#146#255#207#171#156#255#211#178#165#255#214
- +#183#171#255#216#186#175#255#217#188#177#255#218#190#179#255#219#191#182#255
- +#219#192#182#255#219#192#181#255#218#189#179#255#217#187#177#255#215#185#173
- +#255#213#182#169#255#210#176#163#255#205#169#154#255#200#160#144#255#195#151
- +#133#255#190#142'z'#255#183#132'o'#255#167'u_'#255#148'eP'#255#127'S@'#255'm'
- +'E2'#255'f=*'#255'b7%'#255'_4 '#255']1'#30#255'\0'#28#235'[/'#27#147'[/'#27
- +'5'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'['
- ,'/'#27#18'[/'#27'i\0'#28#199'\1'#29#254']1'#30#255'_4 '#255'a6#'#255'd9('#255
- +'g>,'#255'oF3'#255'}Q>'#255#138'[G'#255#149'fQ'#255#160'oZ'#255#170'xa'#255
- +#176'}h'#255#180#128'l'#255#183#133'p'#255#186#136's'#255#188#138'u'#255#188
- +#139'v'#255#187#138'u'#255#186#135'r'#255#183#132'n'#255#178#128'j'#255#174
- +'|e'#255#168'v`'#255#158'mW'#255#146'bN'#255#133'YE'#255'yM;'#255'mC1'#255'g'
- +'>+'#255'c9&'#255'`6"'#255'^3'#31#255']1'#30#255'\0'#28#248'\0'#28#173'[/'#27
- +'O[/'#27#5#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#20'[/'#27'V\0'#28#153
- +'\0'#28#220'\1'#29#255']1'#30#255'^3'#31#255'`5!'#255'a7$'#255'c9&'#255'e;('
- +#255'f=*'#255'g>,'#255'i@.'#255'jB0'#255'mE2'#255'qH5'#255'tJ7'#255'qG5'#255
- +'lC1'#255'jA0'#255'h?-'#255'g>+'#255'e<)'#255'd:('#255'c9&'#255'a6#'#255'`5!'
- +#255'^2'#31#255']1'#30#255'\1'#29#252'\0'#28#201'[/'#27#134'[/'#27'C[/'#27#8
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0'[/'#27#31'[/'#27'_[/'#27#138'\0'#28#176'\0'#28#213'\0'#28
- +#248'\1'#29#255'\1'#29#255'\1'#29#255']1'#30#255'^2'#31#255'^2'#31#255'^3'#31
- +#255'^3'#31#255'^3'#31#255'^2'#31#255']1'#30#255']1'#30#255'\1'#29#255'\1'#29
- +#255'\1'#29#255'\0'#28#241'\0'#28#203'\0'#28#165'[/'#27#127'[/'#27'N[/'#27#15
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0'[/'#27#2'[/'#27'![/'#27'E[/'#27'U[/'#27'a[/'#27'm[/'#27'y[/'#27
- +#134'\0'#29#141'[/'#27#130'[/'#27'v[/'#27'j[/'#27'^[/'#27'Q[/'#27'=[/'#27#23
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#128#0#255#255
- +#255#255#255#255#255#255#255#255#255#255#255#224#0#0#3#255#255#255#255#255
- +#255#255#255#255#255#255#254#0#0#0#0'?'#255#255#255#255#255#255#255#255#255
- +#255#240#0#0#0#0#7#255#255#255#255#255#255#255#255#255#255#128#0#0#0#0#0#255
- +#255#255#255#255#255#255#255#255#254#0#0#0#0#0#0'?'#255#255#255#255#255#255
- +#255#255#248#0#0#0#0#0#0#15#255#255#255#255#255#255#255#255#224#0#0#0#0#0#0#3
- +#255#255#255#255#255#255#255#255#128#0#0#0#0#0#0#0#255#255#255#255#255#255
- +#255#254#0#0#0#0#0#0#0#0'?'#255#255#255#255#255#255#252#0#0#0#0#0#0#0#0#31
- +#255#255#255#255#255#255#240#0#0#0#0#0#0#0#0#7#255#255#255#255#255#255#224#0
- +#0#0#0#0#0#0#0#3#255#255#255#255#255#255#128#0#0#0#0#0#0#0#0#1#255#255#255
- +#255#255#255#0#0#0#0#0#0#0#0#0#0#127#255#255#255#255#254#0#0#0#0#0#0#0#0#0#0
- +'?'#255#255#255#255#252#0#0#0#0#0#0#0#0#0#0#31#255#255#255#255#248#0#0#0#0#0
- +#0#0#0#0#0#15#255#255#255#255#240#0#0#0#0#0#0#0#0#0#0#7#255#255#255#255#224#0
- +#0#0#0#0#0#0#0#0#0#3#255#255#255#255#192#0#0#0#0#0#0#0#0#0#0#1#255#255#255
- +#255#128#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#0#0#0#0#0#0#0#0#0#0#0#127
- +#255#255#254#0#0#0#0#0#0#0#0#0#0#0#0#127#255#255#254#0#0#0#0#0#0#0#0#0#0#0#0
- +'?'#255#255#252#0#0#0#0#0#0#0#0#0#0#0#0#31#255#255#248#0#0#0#0#0#0#0#0#0#0#0
- +#0#15#255#255#240#0#0#0#0#0#0#0#0#0#0#0#0#7#255#255#240#0#0#0#0#0#0#0#0#0#0#0
- +#0#7#255#255#224#0#0#0#0#0#0#0#0#0#0#0#0#3#255#255#192#0#0#0#0#0#0#0#0#0#0#0
- +#0#3#255#255#192#0#0#0#0#0#0#0#0#0#0#0#0#1#255#255#128#0#0#0#0#0#0#0#0#0#0#0
- +#0#1#255#255#128#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#255#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#127#254#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#127#254#0#0#0#0#0#0#0#0#0#0#0#0#0#0'?'#254#0#0#0#0#0#0#0#0#0#0#0#0#0#0'?'
- +#252#0#0#0#0#0#0#0#0#0#0#0#0#0#0'?'#252#0#0#0#0#0#0#0#0#0#0#0#0#0#0#31#252#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#31#248#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#248#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#15#248#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#240#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#7#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#7#240#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#7#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#7#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3
- +#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#192#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#3#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#192#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0#1#192#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#192#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#3#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0#0#0#0#0#0#0#0#0#0#0#0#0#3#224#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#3#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#7#240#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#7#240#0#0#0#0#0#0#0#0#0#0#0#0#0#0#7#240#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#15#248#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#248#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15
- +#248#0#0#0#0#0#0#0#0#0#0#0#0#0#0#15#252#0#0#0#0#0#0#0#0#0#0#0#0#0#0#31#252#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#31#252#0#0#0#0#0#0#0#0#0#0#0#0#0#0'?'#254#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0'?'#254#0#0#0#0#0#0#0#0#0#0#0#0#0#0'?'#254#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#127#255#0#0#0#0#0#0#0#0#0#0#0#0#0#0#127#255#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#255#255#128#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#128#0#0#0#0#0#0#0#0
- +#0#0#0#0#1#255#255#128#0#0#0#0#0#0#0#0#0#0#0#0#1#255#255#192#0#0#0#0#0#0#0#0
- +#0#0#0#0#3#255#255#192#0#0#0#0#0#0#0#0#0#0#0#0#3#255#255#224#0#0#0#0#0#0#0#0
- +#0#0#0#0#7#255#255#224#0#0#0#0#0#0#0#0#0#0#0#0#15#255#255#240#0#0#0#0#0#0#0#0
- +#0#0#0#0#15#255#255#248#0#0#0#0#0#0#0#0#0#0#0#0#31#255#255#248#0#0#0#0#0#0#0
- +#0#0#0#0#0'?'#255#255#252#0#0#0#0#0#0#0#0#0#0#0#0#127#255#255#252#0#0#0#0#0#0
- +#0#0#0#0#0#0#255#255#255#254#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#255#0#0#0#0
- +#0#0#0#0#0#0#0#1#255#255#255#255#128#0#0#0#0#0#0#0#0#0#0#3#255#255#255#255
- +#128#0#0#0#0#0#0#0#0#0#0#7#255#255#255#255#192#0#0#0#0#0#0#0#0#0#0#15#255#255
- +#255#255#224#0#0#0#0#0#0#0#0#0#0#31#255#255#255#255#240#0#0#0#0#0#0#0#0#0#0
- +#31#255#255#255#255#248#0#0#0#0#0#0#0#0#0#0'?'#255#255#255#255#252#0#0#0#0#0
- +#0#0#0#0#0#127#255#255#255#255#254#0#0#0#0#0#0#0#0#0#1#255#255#255#255#255
- +#255#0#0#0#0#0#0#0#0#0#3#255#255#255#255#255#255#128#0#0#0#0#0#0#0#0#7#255
- +#255#255#255#255#255#224#0#0#0#0#0#0#0#0#15#255#255#255#255#255#255#240#0#0#0
- +#0#0#0#0#0#31#255#255#255#255#255#255#248#0#0#0#0#0#0#0#0#127#255#255#255#255
- +#255#255#254#0#0#0#0#0#0#0#0#255#255#255#255#255#255#255#255#128#0#0#0#0#0#0
- +#3#255#255#255#255#255#255#255#255#192#0#0#0#0#0#0#7#255#255#255#255#255#255
- +#255#255#240#0#0#0#0#0#0#31#255#255#255#255#255#255#255#255#252#0#0#0#0#0#0
- +#127#255#255#255#255#255#255#255#255#255#0#0#0#0#0#3#255#255#255#255#255#255
- +#255#255#255#255#224#0#0#0#0#15#255#255#255#255#255#255#255#255#255#255#252#0
- +#0#0#0#127#255#255#255#255#255#255#255#255#255#255#255#192#0#0#7#255#255#255
- +#255#255#255#255#255#255#255#255#255#254#0#1#255#255#255#255#255#255#255#255
- +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
- +#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255#255
- +#255#255#255#255#255#255#255#255#255'('#0#0#0'@'#0#0#0#128#0#0#0#1#0' '#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'@@@'#4'III'#7'III'#7
- +'333'#5#128#128#128#2#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'UUU'#6'DDD'
- +#15'FFF'#22'EEE'#26'DDD'#30'III#GGG/DDD'#30#255'j>'#31#253'g>#'#249'[>+'#235'PB8'#218'HE'
- +'C'#203'FEC'#195'EED'#184'DDD'#166'DDDqEEE4@@@'#20'@@@'#4#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1
- +'999'#9'BBB'#31'CCCPEDD'#143'FFE'#182'NB:'#211'Z?-'#231'g>#'#249'l?'#31#255
- +'zK$'#253#150']*'#255#165'h.'#255#172'm0'#255#180's2'#255#186'x4'#255#189'{4'
- +#255#192#127'5'#255#190'|4'#255#187'x4'#255#182'u3'#255#175'p1'#255#167'j/'
- +#255#156'b+'#255#131'R&'#254'oB '#255'i>!'#253'_>)'#238'S@6'#222'FEB'#203'DD'
- +'C'#190'DDD'#164'CCCkCCC.PPP'#16'UUU'#3#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#128#128#128#2'CCC'#19'BBBBDDD'#136'EED'#179'LA9'
- +#209'`=&'#243'k?'#31#255#127'N&'#254#154'`,'#255#176'q1'#255#191'~5'#255#200
- +#138'7'#255#207#145'8'#255#210#149'9'#255#213#153'9'#255#217#157':'#255#219
- +#160';'#255#221#162';'#255#220#162':'#255#217#158':'#255#215#155':'#255#211
- +#151'9'#255#208#146'8'#255#203#141'8'#255#194#129'6'#255#183'v4'#255#163'f.'
- +#255#137'U('#254'qC"'#254'f'
- +'>>!+++'#6#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@@'#4'BBB'#27'CC'
- +'C[CCB'#165'LD='#203']<('#238'j> '#255#135'R('#254#176'p3'#255#193#128'7'#255
- +#202#139'9'#255#211#151';'#255#220#162'<'#255#227#170'>'#255#232#176'?'#255
- +#234#180'?'#255#237#182'?'#255#239#185'@'#255#241#187'@'#255#242#188'A'#255
- +#241#187'@'#255#240#185'A'#255#238#183'@'#255#235#180'@'#255#233#178'?'#255
- +#229#173'>'#255#222#165'='#255#215#156'<'#255#205#144':'#255#196#133'8'#255
- +#185'x5'#255#152'^-'#255'oC"'#254'd<#'#247'QA7'#220'FFE'#200'CCC'#180'CCC}AA'
- +'A/UUU'#9#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'III'#7'CCC&DDDpECC'#180'X<,'#232'i='
- +'!'#254#128'O('#254#170'l3'#255#194#130':'#255#210#150'>'#255#220#163'?'#255
- +#227#171'A'#255#234#180'B'#255#240#187'D'#255#242#190'D'#255#244#193'E'#255
- +#246#194'D'#255#247#195'E'#255#248#197'E'#255#249#197'E'#255#249#198'E'#255
- +#249#197'E'#255#248#196'E'#255#247#195'E'#255#246#195'E'#255#245#194'D'#255
- +#243#191'D'#255#240#188'C'#255#236#183'C'#255#230#174'B'#255#223#165'@'#255
- +#215#156'?'#255#200#137';'#255#182'u6'#255#146'[,'#255'm@!'#254'`:%'#244'KA;'
- +#211'CCC'#189'CCC'#144'BBB>PPP'#16#128#128#128#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'999'#9'@@@4CCC'#133
- +'HD@'#192'_9$'#244'rE%'#254#164'h3'#255#191#127';'#255#206#146'?'#255#219#163
- +'C'#255#232#178'F'#255#238#185'G'#255#241#189'H'#255#244#193'H'#255#246#195
- +'I'#255#247#196'I'#255#247#197'J'#255#247#197'I'#255#247#198'I'#255#248#198
- +'I'#255#248#198'I'#255#248#197'I'#255#248#198'I'#255#248#198'I'#255#248#198
- +'I'#255#247#197'I'#255#247#197'I'#255#247#196'I'#255#246#196'I'#255#245#194
- +'H'#255#242#190'H'#255#239#187'H'#255#235#182'G'#255#224#168'D'#255#211#153
- +'A'#255#196#134'='#255#177'q7'#255#133'Q)'#254'e: '#253'N?7'#218'DDC'#195'CC'
- +'C'#160'FFFP@@@'#20#0#0#0#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0'III'#7'FFF3CCC'#145'LB;'#204'd:"'#250'|L('#254#180's9'#255
- +#202#143'A'#255#216#159'F'#255#228#174'I'#255#236#184'K'#255#241#191'L'#255
- +#243#193'M'#255#244#194'M'#255#244#195'M'#255#245#196'M'#255#245#195'M'#255
- +#245#195'M'#255#245#195'M'#255#245#195'M'#255#245#195'M'#255#245#195'M'#255
- +#245#195'M'#255#245#195'M'#255#245#195'M'#255#245#195'M'#255#245#195'M'#255
- +#245#195'M'#255#245#195'M'#255#245#196'M'#255#245#195'M'#255#244#194'M'#255
- +#243#194'M'#255#242#192'M'#255#238#186'L'#255#232#179'J'#255#220#165'F'#255
- +#208#150'C'#255#190#127'<'#255#147'[.'#255'h< '#255'S=1'#228'EED'#199'DDD'
- +#168'BBBUGGG'#18#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +'@@@'#4'FFF(EEE'#134'P?5'#212'e:!'#254#137'U,'#254#186'z='#255#208#150'E'#255
- +#224#171'L'#255#233#181'O'#255#238#187'P'#255#240#191'P'#255#242#192'Q'#255
- +#242#193'Q'#255#242#193'Q'#255#242#193'P'#255#242#193'Q'#255#242#193'Q'#255
- +#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255
- ,#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255
- +#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255#242#193'Q'#255
- +#242#193'Q'#255#242#193'Q'#255#241#192'Q'#255#239#189'P'#255#234#184'O'#255
- +#228#175'M'#255#215#159'I'#255#194#132'@'#255#160'd3'#255'k?"'#254'X:*'#236
- +'FDC'#201'CCC'#164'AAAG;;;'#13#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'U'
- +'UU'#3'BBB'#31'CCCvO=3'#211'f:'#31#255#150']2'#255#190#128'A'#255#211#155'I'
- +#255#226#175'Q'#255#234#185'S'#255#237#188'T'#255#238#190'T'#255#239#191'U'
- +#255#239#191'U'#255#239#191'U'#255#239#191'U'#255#239#191'U'#255#239#191'U'
- +#255#239#191'U'#255#239#191'U'#255#235#189'S'#255'|d,'#255'N>'#28#255'4*'#19
- +#255'=1'#22#255'WE'#31#255'w_*'#255#173#139'='#255#239#191'U'#255#239#191'U'
- +#255#239#191'U'#255#239#191'U'#255#239#191'U'#255#239#191'U'#255#239#191'U'
- +#255#239#191'U'#255#239#191'U'#255#239#190'T'#255#238#189'U'#255#236#187'S'
- +#255#230#179'R'#255#217#162'L'#255#198#138'D'#255#170'l8'#255'pC$'#254'Z8'''
- +#240'DBB'#197'CCC'#153'FFF:@@@'#8#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'FFF'#22
- +'BBBeJ?9'#195'b8 '#254#150']2'#255#194#133'E'#255#213#158'N'#255#226#176'T'
- +#255#233#185'W'#255#236#187'W'#255#236#188'X'#255#236#188'X'#255#236#188'X'
- +#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'
- +#255#236#188'X'#255'cO%'#255#4#3#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#18#14#7#255'A4'#24#255#134'k2'
- +#255#218#174'R'#255#236#188'X'#255#236#188'X'#255#236#188'X'#255#236#188'X'
- +#255#236#188'X'#255#236#188'X'#255#236#187'W'#255#234#186'W'#255#229#180'U'
- +#255#218#165'P'#255#201#143'H'#255#173'o<'#255'k>#'#254'S;-'#231'CCC'#193'CC'
- +'C'#141'DDD-fff'#5#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@@'#12'DDDKFA='#179'`7 '#251#137'S-'
- +#255#192#131'E'#255#214#161'Q'#255#226#176'W'#255#231#183'Y'#255#233#185'['
- +#255#233#186'['#255#234#185'Z'#255#234#185'Z'#255#234#185'Z'#255#234#185'Z'
- +#255#234#185'Z'#255#234#185'Z'#255#234#185'Z'#255#234#185'Z'#255'L<'#29#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#8#7#3#255'P'
- +'?'#31#255#203#161'N'#255#234#185'Z'#255#234#185'Z'#255#234#185'Z'#255#234
- +#185'Z'#255#233#186'['#255#232#183'Z'#255#228#178'Y'#255#219#167'T'#255#201
- +#143'K'#255#163'g8'#255'f: '#255'O=4'#222'DDD'#188'CCCzBBB'#27#0#0#0#1#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'U'
- +'UU'#3'GGG$D@@'#147'\6#'#245'{I*'#254#185'{C'#255#211#157'R'#255#225#175'Z'
- +#255#229#181'\'#255#230#183']'#255#230#183']'#255#230#183']'#255#230#183']'
- +#255#230#183']'#255#230#183']'#255#230#183']'#255#230#183']'#255#230#183']'
- +#255#230#183']'#255#138'm8'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#24#20#10#255'x_0'
- +#255#226#181'['#255#230#183']'#255#230#183']'#255#230#183']'#255#230#181'\'
- +#255#227#177'['#255#217#165'V'#255#196#136'J'#255#151']4'#255'b8 '#254'K@9'
- +#214'CCC'#175'AAAJ...'#11#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@@'#16'CCC\V6'''#228'nA&'#254#178'tA'#255#205
- +#151'R'#255#221#172'\'#255#226#179'_'#255#228#180'_'#255#228#180'_'#255#228
- +#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#228
- +#180'_'#255#228#180'_'#255#228#180'_'#255#228#180'_'#255#17#13#7#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#1#1#255'H9'#30#255#224#178']'
- +#255#228#180'_'#255#228#180'_'#255#227#179'^'#255#224#175']'#255#213#160'W'
- +#255#190#129'H'#255#137'T/'#255'^4 '#252'FB?'#201'CCC'#140'DDD"'#0#0#0#3#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@@'#4'FFF,J=7'
- +#175'`4'#30#255#165'g;'#255#200#144'Q'#255#217#166'\'#255#223#176'`'#255#225
- +#177'`'#255#225#177'a'#255#225#177'a'#255#225#177'a'#255#225#177'a'#255#225
- +#177'a'#255#225#177'a'#255#225#177'a'#255#225#177'a'#255#225#177'a'#255#225
- +#177'a'#255#218#171'^'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#11#9#5#255#196#154'U'#255#225#177'a'#255#225#177
- +'`'#255#224#177'a'#255#220#171'^'#255#208#154'W'#255#184'{F'#255'nA%'#254'T8'
- +'*'#233'DDD'#180'CCCX333'#15#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0'CCC'#19'CCCjY5#'#239'~J,'#254#191#132'M'#255#213#162']'#255
- ,#220#171'a'#255#221#173'c'#255#222#174'b'#255#222#174'b'#255#222#174'b'#255
- +#222#174'b'#255#222#174'b'#255#222#174'b'#255#222#174'b'#255#222#174'b'#255
- +#222#174'b'#255#222#174'b'#255#222#174'b'#255#154'yC'#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#15#11#6
- +#255#218#172'`'#255#222#174'b'#255#222#174'b'#255#221#173'b'#255#217#167'_'
- +#255#202#146'T'#255#156'a9'#255'^4'#30#254'G@='#206'DDD'#151'>>>)@@@'#4#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'UUU'#3'AAA+L;4'#188'b6 '#254#170
- +'l@'#255#206#152'Z'#255#217#168'b'#255#219#171'd'#255#219#171'd'#255#219#171
- +'d'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171
- +'d'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171
- +'d'#255#219#171'd'#255#26#20#12#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'oW3'#255#219#171'd'#255#219
- +#171'd'#255#219#171'd'#255#218#169'c'#255#212#161'_'#255#187#127'L'#255'uD)'
- +#254'W6('#238'CCC'#182'CCC[III'#14#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0'@@@'#12'EBBS[3'#31#244#134'O/'#255#192#134'Q'#255#212#162'b'#255#215
- +#167'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#216
- +#168'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#216
- +#168'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#216#168'd'#255#198
- +#154'\'#255#5#4#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255'!'#25#15#255#216#168'd'#255#216#168'd'#255#216#168
- +'d'#255#216#168'd'#255#214#166'd'#255#202#147'Y'#255#161'e='#255'^2'#29#255
- +'J?:'#208'CCC'#137'EEE'#26#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'C'
- +'CC'#23'O9/'#171'`3'#31#254#174'pD'#255#203#150']'#255#212#163'e'#255#213#164
- +'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164
- +'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164
- +'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164'e'#255#213#164
- +'e'#255#173#133'R'#255#3#2#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#22#17#11#255#213#164'e'#255#213#164'e'#255#213#164
- +'e'#255#213#164'e'#255#213#164'f'#255#209#158'a'#255#187#128'O'#255'yD)'#254
- +'W4$'#241'BBB'#169'DDD1@@@'#4#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'FFF(W4'
- +'$'#229'{E)'#255#191#134'T'#255#207#157'c'#255#210#160'f'#255#210#160'f'#255
- +#210#160'f'#255#210#160'f'#255#210#160'f'#255#210#160'f'#255#210#160'f'#255
- +#210#160'f'#255#152'tJ'#255'[E,'#255'K9$'#255'{]<'#255#196#149'_'#255#210#160
- +'f'#255#210#160'f'#255#210#160'f'#255#210#160'f'#255#210#160'f'#255#159'yM'
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'"'
- +#26#17#255#210#160'f'#255#210#160'f'#255#210#160'f'#255#210#160'f'#255#210
- +#160'f'#255#209#160'e'#255#199#146']'#255#156'_;'#255'\1'#28#254'FBA'#188'FF'
- +'FXNNN'#13#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'FFF'#11'F@=T\/'#28#253#151'\9'#255
- +#200#147'_'#255#207#156'e'#255#207#156'e'#255#207#156'e'#255#207#156'e'#255
- +#207#156'e'#255#207#156'e'#255#207#156'e'#255#178#135'W'#255'$'#27#17#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'N:&'#255#207#156'e'#255#207
- +#156'e'#255#207#156'e'#255#207#156'e'#255#207#156'e'#255#3#2#1#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'uX9'#255#207#156'e'#255#207
- +#156'e'#255#207#156'e'#255#207#156'e'#255#207#156'e'#255#207#157'e'#255#204
- +#153'b'#255#180'wK'#255'a4'#30#254'M;3'#216'DDD'#132'==='#25#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0'CCC'#19'N9.'#159'^2'#30#254#176'rI'#255#202#150'c'#255#203
- +#153'e'#255#203#153'f'#255#203#153'f'#255#203#153'f'#255#203#153'f'#255#203
- +#153'f'#255#163'zQ'#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#29#22#15#255#203#153'f'#255#203#153'f'#255#203#153
- +'f'#255#203#153'f'#255#14#10#7#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- ,#0#0#255#4#3#2#255#203#153'f'#255#203#153'f'#255#203#153'f'#255#203#153'f'
- +#255#203#153'f'#255#203#153'f'#255#203#153'f'#255#203#152'e'#255#190#134'X'
- +#255'yC)'#254'V5&'#239'DDD'#165'FFF('#128#128#128#2#0#0#0#0#0#0#0#0#0#0#0#0
- +'GGG'#25'V4%'#212's@&'#254#186#128'U'#255#199#148'd'#255#200#148'd'#255#200
- +#148'd'#255#200#148'd'#255#200#148'd'#255#200#148'd'#255#198#146'd'#255#12#9
- +#6#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#138'fE'#255#200#148'd'#255#200#148'd'#255#200#148'd'#255
- +#15#11#7#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'&'#28#19#255#145'kH'#255
- +#200#148'd'#255#200#148'd'#255#200#148'd'#255#200#148'd'#255#200#148'd'#255
- +#200#148'd'#255#200#148'd'#255#200#148'd'#255#194#141'^'#255#146'W6'#255'[0'
- +#28#254'EBB'#178'CCC9UUU'#6#0#0#0#0#0#0#0#0#0#0#0#0'JAA'#31'\1'#29#249#140'P'
- +'2'#255#190#135'\'#255#196#143'c'#255#196#143'c'#255#196#143'c'#255#196#143
- +'c'#255#196#143'c'#255#196#143'c'#255'>-'#31#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'&'
- +#28#19#255#196#143'c'#255#196#143'c'#255#196#143'c'#255#25#18#12#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#1
- +#255'*'#31#21#255'kM6'#255#187#137'_'#255#196#143'c'#255#196#143'c'#255#196
- +#143'c'#255#196#143'c'#255#196#143'c'#255#196#143'c'#255#196#143'c'#255#196
- +#143'c'#255#196#143'c'#255#196#143'c'#255#194#141'b'#255#170'kF'#255'\0'#28
- +#254'L<5'#203'CCCH333'#10#0#0#0#0#0#0#0#0#0#0#0#1'K3+@[/'#27#255#160'`>'#255
- +#190#136'_'#255#191#137'`'#255#191#137'`'#255#191#137'`'#255#191#137'`'#255
- +#191#137'`'#255#189#135'`'#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#30#21#15#255
- +#191#137'`'#255#191#137'`'#255#191#137'`'#255'aF1'#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#5#3#2#255#165'vS'#255#191#137'`'
- +#255#191#137'`'#255#191#137'`'#255#191#137'`'#255#191#137'`'#255#191#137'`'
- +#255#191#137'`'#255#191#137'`'#255#191#137'`'#255#191#137'`'#255#191#137'`'
- +#255#191#137'`'#255#191#137'`'#255#191#136'`'#255#178'vQ'#255'h7 '#253'Q8,'
- +#220'DDDV;;;'#13#0#0#0#0#0#0#0#0'UUU'#3'R4''^[/'#27#255#169'hF'#255#187#131
- +']'#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132
- +'^'#255'uS;'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'{W>'#255#187#132'^'#255
- +#187#132'^'#255#187#132'^'#255#185#130'^'#255#19#14#10#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#1#1#1#255#158'oO'#255#187#132'^'#255#187#132'^'
- +#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132'^'
- +#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#187#132'^'
- +#255#187#132'^'#255#187#132'^'#255#187#132'^'#255#181'{V'#255'r<"'#255'T6'''
- +#228'BBBd@@@'#16#0#0#0#0#0#0#0#0'UUU'#6'T5''}_2'#30#253#171'kI'#255#183'}Z'
- +#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255'. '#23#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#1#1#0#255'S9)'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'
- +#255#183'~Z'#255#173'xV'#255#31#21#15#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'b'
- +'C0'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'
- +#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255
- +#183'~Z'#255#183'~Z'#255#183'~Z'#255#183'~Z'#255#181'zV'#255'zA%'#255'X4$'
- +#237'DDDqCCC'#19#0#0#0#0#0#0#0#0'@@@'#8'U4%'#149'f5'#31#252#172'mK'#255#180
- +'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255#6#4#3
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#19#13#9#255#153'gK'#255#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'
- +#255#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255'{S<'#255'+'#29#21#255#7
- +#4#3#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1
- +#255'gF3'#255#180'yX'#255#180'yX'#255#180'yX'#255#139']D'#255'+'#29#21#255#8
- +#6#4#255#8#6#4#255#16#11#8#255'W:*'#255#178'wV'#255#180'yX'#255#180'yX'#255
- +#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255#180'yX'#255#179'yV'#255#131
- +'F+'#255'[3!'#245'CCCyIII'#21#0#0#0#0#0#0#0#0'UUU'#6'X3"'#165'n:"'#253#172'p'
- +'O'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#173'uU'
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1
- +#0#0#255'P6'''#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'
- ,#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255
- +#177'wW'#255#177'wW'#255#158'jM'#255'W;+'#255''''#26#19#255'"'#23#17#255'%'
- +#25#18#255'W:+'#255#167'qS'#255#177'wW'#255#177'wW'#255#177'wW'#255'@+'#31
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#3#2#1#255
- +#149'dI'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177'wW'#255#177
- +'wW'#255#177'vV'#255#139'M0'#255'[1'#30#250'DDDpCCC'#19#0#0#0#0#0#0#0#0'UUU'
- +#3'Y1'#31#182'v>%'#255#172'oQ'#255#175'tW'#255#175'tW'#255#175'tW'#255#175't'
- +'W'#255#175'tW'#255'}S?'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#26#17#13#255#150'cK'#255#175'tW'#255#175'tW'#255#175'tW'#255
- +#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175
- +'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'
- +#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255
- +#175'tW'#255'dC2'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#9#6#4#255#169'pU'#255#175'tW'#255#175'tW'#255#175't'
- +'W'#255#175'tW'#255#175'tW'#255#174'sU'#255#145'S6'#255']0'#28#254'DBBd@@@'
- +#16#0#0#0#0#0#0#0#0#0#0#0#0'Z0'#30#175'v=%'#255#171'nP'#255#174'rV'#255#174
- +'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255'L2&'#255#0#0#0#255'/'#31#23#255
- +'}R>'#255' '#21#16#255'!'#22#17#255#139'[E'#255#174'rV'#255#174'rV'#255#174
- +'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'
- +#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255
- +#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174
- +'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255'?*'#31#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'6#'#27
- +#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#173'qT'#255
- +#145'S7'#255'\1'#29#254'AAAV;;;'#13#0#0#0#0#0#0#0#0#0#0#0#0'Z1'#30#150'n;$'
- +#252#169'jM'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255
- +#149'bI'#255'@* '#255#170'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'
- +#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255
- +#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172
- +'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'
- +#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255
- +'G/#'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#24#16#12#255#172'qU'#255#172'qU'#255#172'qU'#255#172
- +'qU'#255#172'qU'#255#171'oS'#255#138'N3'#255'\2'#31#249'DDDG999'#9#0#0#0#0#0
- +#0#0#0#0#0#0#0'X1!|g7#'#250#167'gI'#255#172'pT'#255#172'qU'#255#172'qU'#255
- +#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172
- +'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'
- +#255#172'qU'#255'P5('#255')'#27#20#255#27#18#13#255'5#'#26#255'pJ8'#255#172
- +'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'
- +#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255
- +#172'qU'#255#172'qU'#255#162'jO'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#9#6#4#255#172'qU'#255#172
- +'qU'#255#172'qU'#255#172'qU'#255#172'qU'#255#170'mR'#255#131'I.'#255'[4"'#241
- +'FFF7UUU'#6#0#0#0#0#0#0#0#0#0#0#0#0'Y1!`b5 '#251#164'cG'#255#172'pU'#255#173
- +'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'
- +#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255
- +#173'rW'#255'}S?'#255#9#6#5#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#16#11#8#255#152'dM'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255
- +#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#173
- +'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255'$'#24#18#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#4#3#2#255#173'r'
- +'W'#255#173'rW'#255#173'rW'#255#173'rW'#255#173'rW'#255#170'mQ'#255'|C*'#255
- +'W4$'#229'CCC&'#0#0#0#2#0#0#0#0#0#0#0#0#0#0#0#0'X5!A^2'#31#254#162'bE'#255
- +#173'rV'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175
- +'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'
- +#255#175'tY'#255'{Q?'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#14#9#7#255#173'tY'#255#175'tY'#255#175'tY'#255
- +#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175
- +'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#132'XC'#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#21
- +#14#11#255#175'tY'#255#175'tY'#255#175'tY'#255#175'tY'#255#174'tY'#255#170'm'
- +'P'#255't?('#254'U5&'#203'@@@'#24#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'X0'#24' ^2'
- +#31#255#156'\A'#255#175'v\'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'
- +#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255
- ,#177'y`'#255#177'y`'#255#177'y`'#255#11#8#6#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#136']J'#255#177
- +'y`'#255#177'y`'#255'7%'#30#255#9#6#5#255#13#9#7#255#16#11#9#255#26#18#14#255
- +#139'_K'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255#177
- +'y`'#255#18#12#9#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255'<)!'#255#177'y`'#255#177'y`'#255#177'y`'#255#177'y`'#255#176
- +'x^'#255#169'kP'#255'j<&'#253'U4%'#168';;;'#13#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0'^2'#29#234#136'O4'#255#176'x^'#255#180'~f'#255#180'~f'#255#180'~f'
- +#255#180'~f'#255#180'~f'#255#180'~f'#255#180'~f'#255#180'~f'#255#180'~f'#255
- +#180'~f'#255#180'~f'#255#180'~f'#255#146'gS'#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#139'bO'#255#170'x`'#255#20#14#11#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255']A4'#255#180'~f'#255#180'~f'#255#180'~f'#255#180'~f'#255
- +#180'~f'#255'qO@'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#1#1#0#255#165't^'#255#180'~f'#255#180'~f'#255#180'~f'#255#180'~f'#255
- +#178'zb'#255#162'dH'#255'_3'#31#254'R6)c@@@'#4#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0'[/'#29#153'r?)'#252#174'sZ'#255#182#129'j'#255#183#131'l'#255#183
- +#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183
- +#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255'ZA5'
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#5#3#3#255#179#127'j'#255'uTE'#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'{XI'#255#183#131'l'
- +#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#20#15#12#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255':)"'#255#183#131'l'#255
- +#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#179'|c'#255#140
- +'R9'#255'\2'#31#248'@@6'#28#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +'[/'#29'E`5 '#252#166'iO'#255#183#131'l'#255#186#136'q'#255#186#136'q'#255
- +#186#136'q'#255#186#136'q'#255#186#136'q'#255#186#136'q'#255#186#136'q'#255
- +#186#136'q'#255#186#136'q'#255#186#136'q'#255#186#136'q'#255'\D8'#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255'oQC'#255#186#136'q'#255'X@6'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#12#9#7#255#186#136'q'#255#186
- +#136'q'#255#186#136'q'#255#186#136'q'#255#186#136'q'#255#148'lZ'#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#169'|g'#255#186#136'q'#255#186
- +#136'q'#255#186#136'q'#255#186#136'q'#255#185#134'q'#255#177'y`'#255'tB+'#254
- +'W2!'#194'III'#14#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@'#0#4'^3'
- +#30#245#144'W='#255#184#134'o'#255#189#141'x'#255#189#141'x'#255#189#141'x'
- +#255#189#141'x'#255#189#141'x'#255#189#141'x'#255#189#141'x'#255#189#141'x'
- +#255#189#141'x'#255#189#141'x'#255#189#141'x'#255'tWJ'#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'('#30#26#255
- +#189#141'x'#255#189#141'x'#255'?/('#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#187#139'v'#255#189#141
- +'x'#255#189#141'x'#255#189#141'x'#255#189#141'x'#255#189#141'x'#255#172#128
- +'m'#255'_G<'#255#1#0#0#255#0#0#0#255'-"'#28#255#189#141'x'#255#189#141'x'#255
- +#189#141'x'#255#189#141'x'#255#189#141'x'#255#186#137's'#255#171'oU'#255'a6"'
- +#253'T5$jUUU'#3#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'\/'
- +#27#170'vD,'#252#181#128'h'#255#190#144'{'#255#192#146'~'#255#192#146'~'#255
- +#192#146'~'#255#192#146'~'#255#192#146'~'#255#192#146'~'#255#192#146'~'#255
- +#192#146'~'#255#192#146'~'#255#192#146'~'#255#186#142'z'#255#1#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#1#1#255#186#142'z'
- +#255#192#146'~'#255#192#146'~'#255'=.('#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#192#146'~'#255#192
- +#146'~'#255#192#146'~'#255#192#146'~'#255#192#146'~'#255#192#146'~'#255#192
- +#146'~'#255#192#146'~'#255#0#0#0#255#0#0#0#255#167#127'n'#255#192#146'~'#255
- +#192#146'~'#255#192#146'~'#255#192#146'~'#255#191#145'}'#255#186#137's'#255
- +#149'[A'#255'^1'#31#250'F:.'#22#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0'\.'#28'H`5 '#252#164'jP'#255#190#143'z'#255#194#151#131
- +#255#194#151#131#255#194#151#131#255#194#151#131#255#194#151#131#255#194#151
- +#131#255#194#151#131#255#194#151#131#255#194#151#131#255#194#151#131#255#194
- +#151#131#255#27#21#18#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255' '#25#21#255#194#151#131#255#194#151#131#255#194#151#131#255'7*%'
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#12#9#8#255#194#151#131#255#194#151#131#255#194#151#131#255#194#151
- +#131#255#194#151#131#255#194#151#131#255#194#151#131#255#190#149#129#255#0#0
- ,#0#255'0% '#255#194#151#131#255#194#151#131#255#194#151#131#255#194#151#131
- +#255#194#151#131#255#192#147#127#255#180'~f'#255'q@+'#252'Z0'#29#180#0#0#0#2
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0']0'
- +#28#199'{H2'#252#184#134'o'#255#196#153#134#255#197#156#137#255#197#156#137
- +#255#197#156#137#255#197#156#137#255#197#156#137#255#197#156#137#255#197#156
- +#137#255#197#156#137#255#197#156#137#255#197#156#137#255'G81'#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255'WE='#255#197#156#137#255#197
- +#156#137#255#191#152#133#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#135'k^'#255#197#156#137#255#197
- +#156#137#255#197#156#137#255#197#156#137#255#197#156#137#255#197#156#137#255
- +#197#156#137#255#197#156#137#255#16#12#11#255#174#138'y'#255#197#156#137#255
- +#197#156#137#255#197#156#137#255#197#156#137#255#197#155#136#255#191#145'|'
- +#255#151'_F'#255'^3'#31#253'T2!-'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[0'#29'5_4 '#254#161'hP'#255#195#152#132
- +#255#200#161#143#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161
- +#144#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161#144#255#200
- +#161#144#255'xaW'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1
- +#255#171#138'{'#255#200#161#144#255#200#161#144#255#127'f\'#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255')!'#30#255
- +#200#161#144#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161#144
- +#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161#144#255#153'{n'
- +#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161#144#255#200#161
- +#144#255#198#156#138#255#181#128'h'#255'l>*'#252'Z1'#30#159#0#0#0#1#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0'^0'#27#173'uE/'#249#186#136'r'#255#201#162#145#255#203#165#150#255#203#165
- +#150#255#203#165#150#255#203#165#150#255#203#165#150#255#203#165#150#255#203
- +#165#150#255#203#165#150#255#203#165#150#255#163#132'x'#255#0#0#0#255#0#0#0
- +#255#26#21#19#255',$!'#255'-%!'#255#156'~s'#255#203#165#150#255#203#165#150
- +#255#203#165#150#255'@4/'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#4#3#3#255#186#151#138#255#203#165#150#255#203#165
- +#150#255#203#165#150#255#203#165#150#255#203#165#150#255#203#165#150#255#203
- +#165#150#255#203#165#150#255#203#165#150#255#203#165#150#255#203#165#150#255
- +#203#165#150#255#203#165#150#255#203#165#150#255#203#164#149#255#195#152#132
- +#255#146'\D'#255'_3'#31#247'R3'#30#25#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'Z-'#30'"^4 '#252#155
- +'cK'#255#196#153#136#255#206#169#155#255#207#171#156#255#207#171#156#255#207
- +#171#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207#171#156#255
- +#207#171#156#255#203#167#152#255#0#0#0#255#0#0#0#255#193#159#145#255#207#171
- +#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207
- +#171#156#255'E94'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#15#12#11#255#182#150#137#255#207#171#156#255#207#171#156#255#207#171#156
- +#255#207#171#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207#171
- +#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207#171#156#255#207
- +#171#156#255#207#171#156#255#206#170#155#255#201#162#145#255#178'}f'#255'h<('
- +#250'[0'#28#129#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0']1'#29#130'f:&'#250#171'u'
- +'^'#255#202#164#148#255#210#176#163#255#210#177#164#255#210#177#164#255#210
- +#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255
- +#210#177#164#255#2#1#1#255#27#22#21#255#210#177#164#255#210#177#164#255#210
- +#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255
- +#210#177#164#255'I=8'#255#6#5#4#255#0#0#0#255#0#0#0#255#0#0#0#255'''!'#31#255
- +#206#175#162#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177#164
- +#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177
- +#164#255#210#177#164#255#210#177#164#255#210#177#164#255#210#177#164#255#210
- +#177#164#255#210#176#163#255#206#170#155#255#188#139'w'#255'zI4'#252'^2'#29
- +#222']/'#23#11#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'^1'#29#181'oA-'
- +#249#182#132'n'#255#208#173#159#255#213#182#169#255#213#183#170#255#213#183
- +#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213
- +#183#170#255#12#10#9#255#159#136#127#255#213#183#170#255#213#183#170#255#213
- +#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255
- +#213#183#170#255#213#183#170#255#139'xo'#255#0#0#0#255#0#0#0#255'% '#30#255
- +#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170
- +#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183
- ,#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213#183#170#255#213
- +#183#170#255#213#183#170#255#211#178#165#255#196#152#134#255#136'T?'#254'`1 '
- +#243'U+'#28'$'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'U+'#21#12
- +']2'#30#218'zK5'#251#192#146#127#255#212#180#168#255#216#187#176#255#217#188
- +#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217
- +#188#177#255'o`Z'#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188
- +#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217
- +#188#177#255#217#188#177#255#27#24#22#255#0#0#0#255#9#8#7#255#209#180#171#255
- +#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177
- +#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188
- +#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217#188#177#255#217
- +#188#177#255#215#185#173#255#202#163#147#255#152'cM'#255'`5 '#252'X.'#27'B'#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'].'#23'!_'
- +'3 '#241#135'V@'#254#197#155#137#255#215#185#173#255#219#193#183#255#220#194
- +#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220
- +#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255
- +#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184
- +#255#220#194#184#255#4#4#4#255#13#11#11#255#197#173#164#255#220#194#184#255
- +#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184
- +#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194
- +#184#255#220#194#184#255#220#194#184#255#220#194#184#255#220#194#183#255#218
- +#190#179#255#205#169#154#255#165'pY'#255'b8$'#252'[/'#27'h'#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'Y1'#28'?_'
- +'3!'#249#132'T?'#252#193#148#130#255#215#186#174#255#223#198#189#255#223#200
- +#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223
- +#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255
- +#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191
- +#255#199#179#171#255#215#192#183#255#223#200#191#255#223#200#191#255#223#200
- +#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223
- +#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255#223#200#191#255
- +#223#200#191#255#223#200#191#255#223#199#190#255#219#192#183#255#203#165#150
- +#255#158'kS'#255'c9%'#251']0'#30#147#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'Z-'#25'3_3'#30
- +#234'wI5'#250#185#138'v'#255#215#186#174#255#225#203#194#255#227#205#197#255
- +#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197
- +#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205
- +#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227
- +#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255
- +#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197
- +#255#227#205#197#255#227#205#197#255#227#205#197#255#227#205#197#255#226#204
- +#196#255#220#194#183#255#200#159#143#255#144'_H'#254'a6"'#253'\1'#30'y'#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'\3'#31#25'^2'#29#207'nB.'#249#175'~i'#255
- +#213#182#169#255#225#202#193#255#230#209#203#255#230#211#205#255#230#211#205
- +#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211
- +#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230
- +#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255
- +#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205
- +#255#230#211#205#255#230#211#205#255#230#211#205#255#230#211#205#255#230#210
- +#204#255#227#205#198#255#219#191#181#255#193#149#131#255#131'R='#251'_4 '#247
- +'Z0'#26'O'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'` '#8']0'
- +#28#169'e:'''#250#148'aL'#255#196#153#136#255#220#193#183#255#229#209#202#255
- +#233#216#210#255#234#216#211#255#234#216#211#255#234#216#211#255#234#216#211
- +#255#234#216#211#255#234#216#211#255#234#216#211#255#234#216#211#255#234#216
- +#211#255#234#216#211#255#234#216#211#255#234#216#211#255#234#216#211#255#234
- +#216#211#255#234#216#211#255#234#216#211#255#234#216#211#255#234#216#211#255
- +#234#216#211#255#234#216#211#255#234#216#211#255#233#216#211#255#231#212#206
- ,#255#224#200#192#255#207#171#156#255#168'va'#255'rE1'#249'^3'#31#230'Y,'#28
- +'.'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0'^1'#29'h`3'#31#237'nA/'#249#158'mW'#255#203#165#150#255#224#201#192
- +#255#232#213#208#255#235#219#215#255#237#222#218#255#237#222#218#255#237#222
- +#218#255#237#222#218#255#237#222#218#255#237#222#218#255#237#222#218#255#237
- +#222#218#255#237#222#218#255#237#222#218#255#237#222#218#255#237#222#218#255
- +#237#222#218#255#237#222#218#255#237#222#218#255#237#222#218#255#237#222#218
- +#255#236#220#216#255#233#216#211#255#228#206#200#255#213#182#170#255#177#131
- +'n'#255'}M:'#250'a6"'#253']1'#29#155'U1'#24#21#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'].'#23#11
- +']1'#29'~`5!'#246'tF5'#249#166'u`'#255#202#164#148#255#221#195#186#255#230
- +#210#203#255#234#218#213#255#238#224#220#255#240#227#224#255#240#227#225#255
- +#240#227#225#255#240#227#225#255#240#227#225#255#240#227#225#255#240#227#225
- +#255#240#227#225#255#240#227#225#255#240#227#225#255#240#227#225#255#239#225
- +#222#255#236#220#215#255#232#213#207#255#225#203#194#255#210#176#164#255#183
- +#138'u'#255#133'UA'#252'c9&'#254'^2'#30#178'\.'#26''''#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'U1'#24#21']0'#30#147'`7"'#251'jA-'#249#133'UA'
- +#253#169'zf'#255#201#162#146#255#220#194#184#255#230#211#205#255#233#215#210
- +#255#234#217#212#255#236#220#215#255#237#222#218#255#238#223#220#255#237#222
- +#219#255#236#220#216#255#234#219#213#255#233#216#211#255#231#213#206#255#225
- +#203#194#255#209#174#160#255#181#136'u'#255#145'`L'#255'sG4'#249'c9&'#255'_2'
- +#30#198'].'#28'7'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0'U+'#28#18'\.'#27'^_1'#30#179'c7$'#248'h?,'#251#127
- +'Q;'#251#148'dN'#255#163't_'#255#175#129'n'#255#186#143'~'#255#198#157#141
- +#255#204#167#151#255#201#161#145#255#191#149#132#255#179#135'u'#255#167'ye'
- +#255#153'iT'#255#136'WC'#254'pE2'#249'c9&'#255'_3'#31#212'Z/'#27'|].'#29','#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'U9'#28#9'\.'#26'N^0'#29#157'`'
- +'4 '#203'c6#'#230'c7%'#249'd:('#255'f=*'#255'i?-'#252'g>+'#255'e;('#255'd9&'
- +#253'b7$'#237'a5!'#214'_1'#30#180'\/'#26'lX,'#26#29#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0'`0 '#16'[1'#24'*].'#27'B]1'#29'4\3'#31#25'UU'#0#3#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#255#248#15#255
- +#255#255#255#255#254#0#0#127#255#255#255#255#240#0#0#7#255#255#255#255#192#0
- +#0#1#255#255#255#255#0#0#0#0#255#255#255#252#0#0#0#0'?'#255#255#248#0#0#0#0
- +#31#255#255#240#0#0#0#0#7#255#255#192#0#0#0#0#3#255#255#128#0#0#0#0#1#255#255
- +#128#0#0#0#0#0#255#255#0#0#0#0#0#0#127#254#0#0#0#0#0#0#127#252#0#0#0#0#0#0'?'
- +#252#0#0#0#0#0#0#31#248#0#0#0#0#0#0#31#248#0#0#0#0#0#0#15#240#0#0#0#0#0#0#15
- ,#240#0#0#0#0#0#0#7#224#0#0#0#0#0#0#7#224#0#0#0#0#0#0#7#224#0#0#0#0#0#0#3#192
- +#0#0#0#0#0#0#3#192#0#0#0#0#0#0#3#192#0#0#0#0#0#0#1#192#0#0#0#0#0#0#1#192#0#0
- +#0#0#0#0#1#128#0#0#0#0#0#0#1#128#0#0#0#0#0#0#1#128#0#0#0#0#0#0#1#128#0#0#0#0
- +#0#0#1#128#0#0#0#0#0#0#1#128#0#0#0#0#0#0#1#192#0#0#0#0#0#0#1#192#0#0#0#0#0#0
- +#1#192#0#0#0#0#0#0#1#192#0#0#0#0#0#0#1#192#0#0#0#0#0#0#3#192#0#0#0#0#0#0#3
- +#224#0#0#0#0#0#0#3#224#0#0#0#0#0#0#7#224#0#0#0#0#0#0#7#224#0#0#0#0#0#0#7#240
- +#0#0#0#0#0#0#15#240#0#0#0#0#0#0#15#248#0#0#0#0#0#0#31#248#0#0#0#0#0#0#31#252
- +#0#0#0#0#0#0'?'#252#0#0#0#0#0#0#127#254#0#0#0#0#0#0#127#254#0#0#0#0#0#0#255
- +#255#0#0#0#0#0#1#255#255#128#0#0#0#0#3#255#255#192#0#0#0#0#7#255#255#224#0#0
- +#0#0#15#255#255#240#0#0#0#0#31#255#255#248#0#0#0#0'?'#255#255#254#0#0#0#0#127
- +#255#255#255#0#0#0#1#255#255#255#255#192#0#0#7#255#255#255#255#240#0#0#31#255
- +#255#255#255#254#0#0#255#255#255#255#255#255#248#31#255#255#255#255#255#255
- +#255#255#255#255#255'('#0#0#0'0'#0#0#0'`'#0#0#0#1#0' '#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0'UUU'#3'333'#5'UUU'#6'III'#7'@@@'#8'@@@'#8'III'#7
- +'UUU'#6'333'#5'UUU'#3#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'@@@'
- +#4'@@@'#8'@@@'#16'DDD1BBBMCCC_FCCrDBB'#129'FDD'#133'CCCvCCCcDDDRDDD('#240'l@!'#252'qE!'
- +#253'yJ$'#252#129'R&'#252#138'X)'#253#134'T('#253'}N%'#252'uG#'#252'oC"'#253
- +'h=#'#248'Z>.'#230'OC;'#211'FEC'#198'DDC'#187'BBB|CCC&999'#9#0#0#0#1#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#2'<<<'#17'CCCWEED'#170'OB9'#211'd=&'#244'qE"'#253#137'V)'#253
- +#164'h.'#255#186'y3'#255#194#130'5'#255#198#135'6'#255#203#140'7'#255#207#145
- +'8'#255#205#143'7'#255#201#137'7'#255#196#132'6'#255#192#127'5'#255#177'r1'
- +#255#152'_+'#254'{L%'#252'k?"'#251'[>-'#233'IEA'#203'EDD'#184'DDDq<<<'#30'@@'
- +'@'#4#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0'@@@'#4'BBB#EDD'#146'KB<'#205'a='''#242'yK&'#252#166'i/'#255#192#128'6'
- +#255#205#143'9'#255#217#159'<'#255#226#169'>'#255#230#173'>'#255#232#176'>'
- +#255#235#180'?'#255#237#182'@'#255#236#181'?'#255#234#178'>'#255#231#175'>'
- +#255#228#171'>'#255#223#165'<'#255#211#150':'#255#199#136'8'#255#182'v5'#255
- +#146'\,'#253'k@"'#252'W?1'#227'GFE'#199'CCC'#171'???=@@@'#8#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'III'#7'DDD8ECB'#170'[>,'#234'sF$'
- +#252#160'e0'#255#196#133';'#255#216#158'@'#255#227#170'A'#255#234#180'C'#255
- +#241#189'D'#255#245#193'E'#255#246#195'F'#255#247#195'F'#255#247#196'E'#255
- +#248#197'F'#255#248#197'E'#255#247#195'F'#255#247#194'F'#255#246#194'E'#255
- +#244#192'E'#255#238#184'C'#255#230#176'C'#255#223#166'A'#255#207#147'='#255
- +#182'w7'#255#138'V+'#253'h>#'#250'NA9'#215'CCC'#186'@@@[;;;'#13#0#0#0#1#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@@'#8'EEENGC?'#189'b;%'#245#139'W-'#253#190
- +#127';'#255#212#153'B'#255#227#172'F'#255#239#186'I'#255#242#191'J'#255#244
- +#193'K'#255#246#195'K'#255#247#196'K'#255#247#196'K'#255#247#196'L'#255#247
- +#196'L'#255#247#196'L'#255#247#196'L'#255#247#196'L'#255#247#196'K'#255#247
- +#196'K'#255#246#196'K'#255#245#195'J'#255#243#193'J'#255#242#190'J'#255#234
- +#180'H'#255#221#165'E'#255#202#142'@'#255#173'o5'#255'oC$'#252'T?3'#225'CCC'
- +#193'AAAy@@@'#16#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'+++'#6'DDD@K@<'#198'g<"'#250#154
- +'a2'#254#200#141'B'#255#222#168'J'#255#234#183'N'#255#239#189'P'#255#242#192
- +'P'#255#242#193'P'#255#243#193'P'#255#243#193'P'#255#243#193'P'#255#243#193
- +'P'#255#243#193'P'#255#243#193'P'#255#243#193'P'#255#243#193'P'#255#243#193
- ,'P'#255#243#193'P'#255#243#193'P'#255#243#193'P'#255#243#193'P'#255#242#193
- +'P'#255#242#193'P'#255#241#191'P'#255#238#187'N'#255#229#176'L'#255#214#158
- +'G'#255#183'y;'#255'yJ)'#252'[=,'#236'CCB'#195'EEEoFFF'#11#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'UUU'#3
- +'CCC.J?;'#190'g=#'#252#167'k7'#255#205#147'H'#255#226#173'P'#255#235#186'T'
- +#255#238#189'T'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'
- +#255#239#190'U'#255#239#190'U'#255#191#152'D'#255'A4'#23#255'>1'#22#255'D6'
- +#24#255'H9'#26#255'RA'#29#255#146's4'#255#228#182'Q'#255#239#190'U'#255#239
- +#190'U'#255#239#190'U'#255#239#190'U'#255#239#190'U'#255#238#190'U'#255#237
- +#187'T'#255#232#182'S'#255#217#162'M'#255#191#129'B'#255#132'R-'#253'[9('#240
- +'DDD'#191'CCCW@@@'#8#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#1'>>>'#29'F@='#169'd9#'#250#165'i8'#255#208#151'L'#255
- +#226#174'U'#255#233#184'Y'#255#235#186'Y'#255#235#187'Y'#255#235#187'Y'#255
- +#235#187'Y'#255#235#187'Y'#255#235#187'Y'#255#235#187'Y'#255'<0'#23#255#1#1#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#0#0#0#255#6
- +#5#2#255'*!'#16#255'w^-'#255#227#181'W'#255#235#187'Y'#255#235#187'Y'#255#235
- +#186'Y'#255#234#186'Y'#255#231#181'X'#255#218#164'Q'#255#194#133'E'#255'{J*'
- +#252'U=/'#230'CCC'#186'EEE?@@@'#4#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0'333'#10'DAAw_9%'#244#150'^4'#254#204#148'N'#255#225#175
- +'Y'#255#230#181'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255#231#183
- +'\'#255#231#183'\'#255#231#183'\'#255#231#183'\'#255'hR*'#255#1#1#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#1#1#0#255#1#1#0#255'*!'#17#255#164#130'B'#255#231#183'\'
- +#255#231#183'\'#255#231#182']'#255#228#179'['#255#217#165'V'#255#185'|C'#255
- +'nA'''#252'N>5'#219'CCC'#163'@@@'#20#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#128#128#128#2'@@@,W8*'#227#132'P/'#253#196#139'M'#255#220
- +#170'['#255#226#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227
- +#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#227#179'_'#255#4#3#2
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0
- +#255#7#6#3#255#178#141'J'#255#227#179'_'#255#227#179'_'#255#225#176'^'#255
- +#211#158'U'#255#174'q?'#255'c9"'#252'GA>'#203'BBB]III'#7#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0'FFF'#11'H>:'#150'e:#'#252#186'~H'#255#214#164'\'
- +#255#222#174'a'#255#223#175'b'#255#223#175'b'#255#223#175'b'#255#223#175'b'
- +#255#223#175'b'#255#223#175'b'#255#223#175'b'#255#223#175'b'#255#188#148'S'
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#1#1#1#255#154'yC'#255#223#175'b'#255#223#175'a'#255
- +#220#171'`'#255#204#150'U'#255#145'Y5'#254'Y8('#238'CCC'#175'FFF'#29#0#0#0#1
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'UUU'#3'AAA3Z7'''#236#148'\6'#255#207#154'Z'
- +#255#218#170'b'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171'd'
- +#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171'd'#255#219#171'd'
- +#255#211#165'`'#255#6#5#3#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#1#255#219#171'd'#255#219
- +#171'd'#255#219#171'd'#255#215#166'`'#255#189#129'M'#255'h=$'#252'H>;'#207'E'
- +'EEhIII'#7#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'III'#7'K<5'#137'h;$'#252#188#130
- +'O'#255#213#164'b'#255#215#167'd'#255#215#167'd'#255#215#167'd'#255#215#167
- +'d'#255#215#167'd'#255#215#167'd'#255#215#167'd'#255#215#167'd'#255#215#167
- +'d'#255#215#167'd'#255#215#167'd'#255#168#130'N'#255#1#1#1#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#200#155']'#255#215#167'd'#255#215#167'd'#255#215#166'd'#255#205#153']'
- +#255#153'`:'#255'[6$'#243'CCC'#164';;;'#13#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'7'
- +'77'#14'Z5%'#229#150'[8'#255#203#150'^'#255#211#162'e'#255#211#162'e'#255#211
- +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211
- +#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211#162'e'#255#211
- +#162'e'#255#142'mD'#255#1#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#145'pF'#255#211#162'e'#255#211#162
- +'e'#255#211#162'e'#255#210#159'd'#255#189#131'R'#255'f9#'#252'I@;'#202'===.'
- +#128#128#128#2#0#0#0#0#0#0#0#0#128#128#128#2'D??4]3'#30#252#181'yM'#255#206
- +#155'd'#255#207#157'f'#255#207#157'f'#255#207#157'f'#255#207#157'f'#255#205
- +#155'f'#255'S?('#255#1#1#1#255#1#0#0#255#3#2#1#255#15#11#7#255#169#128'S'#255
- ,#207#157'f'#255#207#157'f'#255#207#157'f'#255#16#12#8#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255#186#141'\'
- +#255#207#157'f'#255#207#157'f'#255#207#157'f'#255#207#157'e'#255#201#148'`'
- +#255#135'O0'#254'R9-'#226'BBBeIII'#7#0#0#0#0#0#0#0#0'UUU'#6'O8/'#141'o>'''
- +#251#193#139'['#255#203#151'e'#255#203#152'e'#255#203#152'e'#255#203#152'e'
- +#255#203#152'e'#255#23#17#11#255#1#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#1#1#1#255#153'rL'#255#203#152'e'#255#203#152'e'#255',!'#22#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255' '#24#16
- +#255#203#152'e'#255#203#152'e'#255#203#152'e'#255#203#152'e'#255#203#152'e'
- +#255#202#150'd'#255#165'jC'#255'\3!'#247'DDD'#151'MMM'#10#0#0#0#0#0#0#0#0'@@'
- +'@'#8'Z6%'#206#142'T5'#255#195#142'a'#255#198#145'c'#255#198#145'c'#255#198
- +#145'c'#255#198#145'c'#255'W@,'#255#1#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255'%'#27#19#255#198#145'c'#255#198#145'c'#255'U>+'
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255#1#1#1#255#27#20#13#255'vW;'
- +#255#198#145'c'#255#198#145'c'#255#198#145'c'#255#198#145'c'#255#198#145'c'
- +#255#198#145'c'#255#198#145'c'#255#184'}S'#255'`4 '#252'FA>'#183'@@@'#12#0#0
- +#0#0#0#0#0#0'999'#9']2'#30#243#166'gD'#255#192#138'`'#255#192#139'a'#255#192
- +#139'a'#255#192#139'a'#255#190#137'a'#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#8#6#4#255#192#139'a'#255#192#139
- +'a'#255#129']B'#255#1#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'Q;)'#255#192#139'a'
- +#255#192#139'a'#255#192#139'a'#255#192#139'a'#255#192#139'a'#255#192#139'a'
- +#255#192#139'a'#255#192#139'a'#255#192#139'a'#255#192#139'a'#255#188#132'['
- +#255'u@'''#252'M;3'#212'999'#18#0#0#0#0#0#0#0#0'FFF'#11'^1'#29#250#174'oK'
- +#255#186#131'\'#255#186#131'\'#255#186#131'\'#255#186#131'\'#255'vS:'#255#1#1
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255
- +'S:)'#255#186#131'\'#255#186#131'\'#255#184#129'\'#255'('#28#20#255#1#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255'Q9('#255#186#131'\'#255#186#131'\'#255#186#131'\'#255#186#131'\'#255#186
- +#131'\'#255#186#131'\'#255#186#131'\'#255#186#131'\'#255#186#131'\'#255#186
- +#131'\'#255#186#131'\'#255#186#130'['#255#131'I-'#255'Q9-'#221'FFF!'#0#0#0#1
- +#0#0#0#0'M33'#20'_2'#30#251#173'pN'#255#180'{X'#255#180'{X'#255#180'{X'#255
- +#180'{X'#255'-'#30#22#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#2#1#1#255'dE1'#255#180'{X'#255#180'{X'#255#180'{X'#255#180'{X'#255
- +#180'{X'#255'O6&'#255#2#1#1#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255'G0#'#255#180'{X'#255#180'{X'#255#178'{X'#255'hH3'#255'U:)'#255
- +'mK5'#255#180'{X'#255#180'{X'#255#180'{X'#255#180'{X'#255#180'{X'#255#180'{X'
- +#255#180'{X'#255#139'P3'#255'U7)'#231'BBB2UUU'#3#0#0#0#0'T1&,c5 '#249#174'rQ'
- +#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#8#5#4#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#1#0#0#255#27#18#13#255#164'nQ'#255#178'wW'#255#178
- +'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'
- +#255#142'_F'#255'H0#'#255#20#13#10#255#25#16#12#255'9'''#28#255'lI5'#255#178
- +'wW'#255#178'wW'#255'kG4'#255#1#1#1#255#1#1#0#255#1#0#0#255#1#0#0#255#3#2#1
- +#255'zQ<'#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#178'wW'#255#149
- +'W9'#255'Z5%'#238'DDD-'#128#128#128#2#0#0#0#0'Y3 Bj8#'#248#173'qS'#255#175't'
- +'W'#255#175'tW'#255#175'tW'#255#175'tW'#255#1#0#0#255#1#1#1#255#0#0#0#255#0#0
- +#0#255#5#3#3#255'cB2'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175
- +'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'
- +#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255
- +#173'rU'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#2#1
- +#1#255#152'eL'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#155'[>'
- +#255'\4"'#244'@@@'#28#0#0#0#1#0#0#0#0'X0!3g7"'#246#172'oR'#255#174'rV'#255
- +#174'rV'#255#174'rV'#255#166'lR'#255#7#5#3#255#131'VA'#255#155'fM'#255'oI7'
- +#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255
- +#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174
- +'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'#255#174'rV'
- +#255#153'dL'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#0#0#0#255'<'''#29#255#174'rV'#255#174'rV'#255#174'rV'#255#173'qU'#255#151'Y'
- +'='#255']6%'#239'333'#15#0#0#0#0#0#0#0#0'O1'''#25'b3'#31#247#168'jN'#255#172
- +'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'
- +#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#136'XD'#255
- ,'U7*'#255'^=/'#255'kE5'#255#170'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255
- +#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oU'#255#172
- +'oU'#255#172'oU'#255#5#3#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255'!'#21#16#255#172'oU'#255#172'oU'#255#172'oU'#255#172'oT'#255
- +#143'R7'#255'Y6('#225'@@@'#12#0#0#0#0#0#0#0#0'333'#5'_2'#31#248#167'hL'#255
- +#172'qW'#255#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172
- +'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255':&'#30#255#1#0#0#255
- +#1#1#0#255#1#1#1#255#1#1#0#255#4#2#2#255#133'WD'#255#172'qX'#255#172'qX'#255
- +#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172'qX'#255#172
- +'qX'#255#172'qX'#255'E.$'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#30#20#15#255#172'qX'#255#172'qX'#255#172'qX'#255#172'pV'#255
- +#134'K2'#255'V8)'#199'999'#9#0#0#0#0#0#0#0#0#0#0#0#1'_3'#30#239#164'fJ'#255
- +#175'w]'#255#175'w^'#255#175'w^'#255#175'w^'#255#175'w^'#255#175'w^'#255#175
- +'w^'#255#175'w^'#255#175'w^'#255#175'w^'#255'hF7'#255#1#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#7#5#4#255#175'w^'#255#175'w^'#255'{TB'
- +#255'X;/'#255']?2'#255#127'VD'#255#175'w^'#255#175'w^'#255#175'w^'#255#175'w'
- +'^'#255#165'qY'#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1
- +#255'fF7'#255#175'w^'#255#175'w^'#255#175'w^'#255#175'v\'#255'{D-'#253'S5('
- +#154'333'#5#0#0#0#0#0#0#0#0#0#0#0#0'a3'#30#200#149'Z?'#255#179'|c'#255#179'}'
- +'e'#255#179'}e'#255#179'}e'#255#179'}e'#255#179'}e'#255#179'}e'#255#179'}e'
- +#255#179'}e'#255#179'}e'#255#19#13#11#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#2#1#1#255#179'}e'#255'E0'''#255#1#0#0#255#1#1#0#255
- +#1#1#0#255#0#0#0#255'R:/'#255#179'}e'#255#179'}e'#255#179'}e'#255#179'}e'#255
- +'.!'#26#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#1#255#177'}e'#255#179
- +'}e'#255#179'}e'#255#179'}e'#255#175'v\'#255'g8$'#251'W7*O'#0#0#0#1#0#0#0#0#0
- +#0#0#0#0#0#0#0'[0'#29'lyD-'#249#181#128'i'#255#183#131'l'#255#183#131'l'#255
- +#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255
- +#183#131'l'#255#183#131'l'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255'"'#25#20#255#183#131'l'#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255'B/'''#255#183#131'l'#255#183#131'l'#255
- +#183#131'l'#255#169'yd'#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255'#'#25#21
- +#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#183#131'l'#255#167'lQ'#255
- +'^3'#31#248'@@@'#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'Y1'#30#26'b5 '#244#178'z'
- +'c'#255#187#138't'#255#187#138'u'#255#187#138'u'#255#187#138'u'#255#187#138
- +'u'#255#187#138'u'#255#187#138'u'#255#187#138'u'#255#187#138'u'#255#2#2#1#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#170'~j'#255#177
- +#130'o'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#4#3#3
- +#255#187#138'u'#255#187#138'u'#255#187#138'u'#255#187#138'u'#255'jNB'#255#11
- +#8#7#255#0#0#0#255#0#0#0#255#152'p`'#255#187#138'u'#255#187#138'u'#255#187
- +#138'u'#255#186#136'r'#255#144'W?'#255']6#'#193'333'#5#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0'`4'#31#217#160'gN'#255#190#143'{'#255#191#145'}'#255#191
- +#145'}'#255#191#145'}'#255#191#145'}'#255#191#145'}'#255#191#145'}'#255#191
- +#145'}'#255#191#145'}'#255#19#14#12#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255'7*$'#255#191#145'}'#255#164'|k'#255#1#1#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#2#2#1#255#191#145'}'#255#191#145'}'#255
- +#191#145'}'#255#191#145'}'#255#191#145'}'#255#191#145'}'#255#0#0#0#255#30#23
- +#20#255#191#145'}'#255#191#145'}'#255#191#145'}'#255#191#145'}'#255#187#138
- +'t'#255'p>('#249'Y2#U'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27
- +'huB+'#244#190#142'z'#255#195#152#132#255#195#152#132#255#195#152#132#255#195
- +#152#132#255#195#152#132#255#195#152#132#255#195#152#132#255#195#152#132#255
- +'A3,'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255#183#142'|'#255
- +#195#152#132#255#138'k]'#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#9#7#6#255#195#152#132#255#195#152#132#255#195#152#132#255#195
- +#152#132#255#195#152#132#255#195#152#132#255#1#1#1#255#160'}m'#255#195#152
- +#132#255#195#152#132#255#195#152#132#255#194#150#131#255#167'pW'#255'`4 '#240
- +'M33'#10#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@'#0#4'`3'#30#229
- +#164'nU'#255#197#156#137#255#199#159#141#255#199#159#141#255#199#159#141#255
- +#199#159#141#255#199#159#141#255#199#159#141#255#199#159#141#255'x`U'#255#1#1
- +#1#255#0#0#0#255#0#0#0#255#0#0#0#255#18#14#13#255#199#159#141#255#199#159#141
- +#255' '#26#23#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255
- +#139'oc'#255#199#159#141#255#199#159#141#255#199#159#141#255#199#159#141#255
- +#199#159#141#255#199#159#141#255'^KC'#255#199#159#141#255#199#159#141#255#199
- +#159#141#255#199#159#141#255#192#147#127#255'rB-'#249'\1 k'#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'\.'#28'Sn>('#243#194#149#131
- ,#255#202#165#148#255#203#165#149#255#203#165#149#255#203#165#149#255#203#165
- +#149#255#203#165#149#255#203#165#149#255#169#138'|'#255#0#0#0#255#1#1#1#255
- +#16#13#11#255#23#19#17#255#171#139'~'#255#203#165#149#255#203#165#149#255#3#3
- +#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'*"'#31#255#203#165
- +#149#255#203#165#149#255#203#165#149#255#203#165#149#255#203#165#149#255#203
- +#165#149#255#203#165#149#255#203#165#149#255#203#165#149#255#203#165#149#255
- +#203#165#149#255#201#162#145#255#163'mU'#255'_3'#31#227'U'#0#0#3#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'a3'#30#213#153
- +'eM'#254#204#167#151#255#207#172#158#255#207#172#158#255#207#172#158#255#207
- +#172#158#255#207#172#158#255#207#172#158#255#205#170#156#255#0#0#0#255'<1.'
- +#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172
- +#158#255#20#16#15#255#1#0#0#255#0#0#0#255#0#0#0#255#1#0#0#255'?40'#255#207
- +#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255
- +#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158#255#207#172#158
- +#255#207#172#158#255#207#171#156#255#192#147#127#255'k<'''#244'Z.'#29'L'#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +'^/'#27'&b5!'#240#174'{f'#255#209#176#162#255#212#180#167#255#212#180#167#255
- +#212#180#167#255#212#180#167#255#212#180#167#255#212#180#167#255#6#5#5#255
- +#179#151#140#255#212#180#167#255#212#180#167#255#212#180#167#255#212#180#167
- +#255#212#180#167#255#212#180#167#255'gXR'#255#0#0#0#255#0#0#0#255'gXR'#255
- +#212#180#167#255#212#180#167#255#212#180#167#255#212#180#167#255#212#180#167
- +#255#212#180#167#255#212#180#167#255#212#180#167#255#212#180#167#255#212#180
- +#167#255#212#180#167#255#211#179#166#255#202#162#146#255#127'M7'#248'`2'#31
- +#169#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0'[/'#26'Fg:#'#242#190#145#127#255#214#184#172#255#216
- +#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255
- +'k]X'#255#216#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255#216
- +#187#176#255#216#187#176#255#216#187#176#255'E<8'#255#0#0#0#255'>63'#255#216
- +#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255
- +#216#187#176#255#216#187#176#255#216#187#176#255#216#187#176#255#216#187#176
- +#255#216#187#176#255#216#187#175#255#210#176#163#255#147'_H'#252'`4'#31#210
- +'U++'#6#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'\0'#29'trB-'#242#198#157#140#255#218#191
- +#180#255#221#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255#221
- +#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255
- +#221#195#185#255#221#195#185#255#221#195#185#255',''%'#255'920'#255#221#195
- +#185#255#221#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255#221
- +#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255#221#195#185#255
- +#221#195#185#255#220#194#184#255#213#183#170#255#162'oW'#255'b5 '#232'].'#23
- +#22#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'_1'#30#138'l>)'#242#187#143'|'
- +#255#221#196#186#255#225#202#193#255#225#203#194#255#225#203#194#255#225#203
- +#194#255#225#203#194#255#225#203#194#255#225#203#194#255#225#203#194#255#225
- +#203#194#255#225#203#194#255#225#203#194#255#225#203#194#255#225#203#194#255
- +#225#203#194#255#225#203#194#255#225#203#194#255#225#203#194#255#225#203#194
- +#255#225#203#194#255#225#203#194#255#225#203#194#255#225#203#194#255#225#203
- +#194#255#224#201#192#255#212#180#168#255#149'aK'#252'a5!'#230']2'#25')'#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#28'\d9$'#241#172
- +'|h'#255#222#197#187#255#228#206#200#255#230#209#203#255#230#209#203#255#230
- +#209#203#255#230#209#203#255#230#209#203#255#230#209#203#255#230#209#203#255
- +#230#209#203#255#230#209#203#255#230#209#203#255#230#209#203#255#230#209#203
- +#255#230#209#203#255#230#209#203#255#230#209#203#255#230#209#203#255#230#209
- +#203#255#230#209#203#255#230#209#203#255#229#209#202#255#226#204#197#255#208
- +#173#159#255#131'R;'#245'a3'#31#207'Y3'#26#20#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'].'#28'7a5!'#236#137'WB'#248#201
- +#163#148#255#229#210#202#255#233#215#210#255#234#217#212#255#234#217#212#255
- +#234#217#212#255#234#217#212#255#234#217#212#255#234#217#212#255#234#217#212
- +#255#234#217#212#255#234#217#212#255#234#217#212#255#234#217#212#255#234#217
- +#212#255#234#217#212#255#234#217#212#255#234#217#212#255#234#216#211#255#231
- +#212#206#255#221#195#185#255#174#128'm'#255'm>*'#242'`1'#29#163'f33'#5#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0'b'''#20#13'`2'#29#140'd8$'#241#151'hR'#251#211#179#167#255#233#215
- +#210#255#236#220#215#255#237#222#219#255#238#225#221#255#238#225#221#255#238
- +#225#221#255#238#225#221#255#238#225#221#255#238#225#221#255#238#225#221#255
- +#238#225#221#255#238#225#221#255#238#223#220#255#236#221#217#255#234#219#213
- +#255#227#205#198#255#188#146#128#255'wH2'#242'b5 '#219'].'#27'B'#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'X1'#29#26'a3'#30#168'f:$'#242#134'T?'
- +#246#179#136'v'#255#214#183#172#255#235#218#214#255#238#225#221#255#239#226
- +#223#255#240#227#224#255#240#227#225#255#240#227#225#255#239#226#223#255#239
- +#225#222#255#238#224#220#255#226#204#196#255#199#161#145#255#158'o['#254'rD-'
- +#239'b4"'#232'^2'#30'\'#0#0#0#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0'`+ '#24']/'#30'fd6#'#197'c8#'#243'vE0'#240#140'ZF'
- +#247#156'mY'#255#171#127'm'#255#184#143#127#255#178#136'v'#255#164'wd'#255
- +#148'dP'#252#130'Q;'#243'l<('#239'b6"'#234'b5!'#151'Z-'#29'>UU'#0#3#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0'].'#23#11'Z/'#29'G^4 fa4!'#130'd6!'#166'd7#'#194
- +'d7"'#182'c6"'#150'_3'#31's\0'#29'YY/'#30'+'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#255#224#3#255#255#255
- +#255#255#254#0#0#127#255#255#255#255#248#0#0#31#255#255#255#255#224#0#0#7#255
- +#255#255#255#192#0#0#3#255#255#255#255#128#0#0#1#255#255#255#255#0#0#0#0#127
- +#255#255#254#0#0#0#0#127#255#255#252#0#0#0#0'?'#255#255#248#0#0#0#0#31#255
- +#255#240#0#0#0#0#15#255#255#240#0#0#0#0#15#255#255#224#0#0#0#0#7#255#255#224
- +#0#0#0#0#3#255#255#192#0#0#0#0#3#255#255#192#0#0#0#0#3#255#255#192#0#0#0#0#1
- +#255#255#128#0#0#0#0#1#255#255#128#0#0#0#0#1#255#255#128#0#0#0#0#1#255#255
- +#128#0#0#0#0#1#255#255#128#0#0#0#0#0#255#255#128#0#0#0#0#0#255#255#128#0#0#0
- +#0#0#255#255#128#0#0#0#0#0#255#255#128#0#0#0#0#1#255#255#128#0#0#0#0#1#255
- +#255#128#0#0#0#0#1#255#255#128#0#0#0#0#1#255#255#192#0#0#0#0#1#255#255#192#0
- +#0#0#0#3#255#255#192#0#0#0#0#3#255#255#224#0#0#0#0#7#255#255#224#0#0#0#0#7
- +#255#255#224#0#0#0#0#15#255#255#240#0#0#0#0#15#255#255#248#0#0#0#0#31#255#255
- +#248#0#0#0#0'?'#255#255#252#0#0#0#0'?'#255#255#254#0#0#0#0#127#255#255#255#0
- +#0#0#0#255#255#255#255#128#0#0#1#255#255#255#255#192#0#0#3#255#255#255#255
- +#224#0#0#15#255#255#255#255#248#0#0#31#255#255#255#255#254#0#0#127#255#255
- +#255#255#255#192#7#255#255#255#255#255#255#255#255#255#255#255#255'('#0#0#0
- +' '#0#0#0'@'#0#0#0#1#0' '#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#2'CCC'#19'FFF'#22'UUU'#3#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0'@@@'#12'EAAGDDB'#133'DDC'#181'HC?'#205'LA;'#213
- +'JB='#212'FC@'#204'EED'#185'DDC'#145'DDDSFFF'#22#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'III'#14'EEBoLA;'#208'eE-'#235'xK('
- +#246#131'R)'#250#139'W*'#251#149'_,'#252#145'\+'#252#136'V*'#250#128'Q('#249
- +'rI)'#244'\D2'#227'FB?'#207'CCC'#134'DDD'#30#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0'EEENMA9'#206'oF)'#245#147']-'#252#187'}4'#255#211#150'9'#255#224
- +#167';'#255#230#174'='#255#234#179'>'#255#233#178'>'#255#228#171'='#255#221
- +#163'<'#255#205#143'8'#255#175'r2'#255#131'R*'#250'eC,'#238'FB?'#205'CCCoUUU'
- +#3#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0'@@@'#4'GEA|dB+'#239#142'[.'#252#198#137'<'#255#227#172'C'#255
- +#236#183'E'#255#242#190'F'#255#246#195'G'#255#248#198'G'#255#249#199'H'#255
- +#249#198'H'#255#247#196'G'#255#245#193'G'#255#240#188'F'#255#234#180'D'#255
- +#220#163'A'#255#183'y8'#255'}O*'#250'WA4'#225'CCC'#152'<<<'#17#0#0#0#0#0#0#0
- ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#1'G@='#148
- +'lD*'#245#175'u8'#254#221#166'I'#255#234#182'M'#255#242#193'P'#255#243#194'O'
- +#255#244#195'O'#255#244#195'P'#255#244#195'P'#255#244#195'P'#255#244#195'P'
- +#255#244#195'P'#255#244#195'P'#255#243#194'O'#255#243#194'O'#255#240#190'O'
- +#255#230#179'L'#255#212#155'F'#255#148'^1'#252'`A.'#234'CCC'#171'@@@'#12#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'FA>vmB)'#247#189
- +#130'A'#255#224#172'P'#255#236#187'U'#255#238#189'W'#255#238#190'V'#255#238
- +#190'V'#255#238#190'V'#255'fQ%'#255#17#14#6#255#17#13#6#255#16#13#6#255',#'
- +#16#255#155'|8'#255#238#190'V'#255#238#190'V'#255#238#189'V'#255#238#189'W'
- +#255#233#184'U'#255#217#163'M'#255#164'l8'#254'_>+'#238'DDD'#147#128#128#128
- +#2#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'FDD=e?*'#243#183'}B'#255
- +#223#171'W'#255#232#183'['#255#232#183'\'#255#232#183'\'#255#232#183'\'#255
- +#232#183'\'#255'>1'#25#255#1#1#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255
- +#1#1#1#255#5#4#2#255#22#17#9#255'pX,'#255#218#171'V'#255#232#183'\'#255#230
- +#182'['#255#217#164'T'#255#152'a7'#252'V=1'#228'DDDb'#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#128#128#128#2'Z<-'#215#163'k='#254#217#166'['#255#226#178'`'
- +#255#226#179'a'#255#226#179'a'#255#226#179'a'#255#226#179'a'#255#226#179'a'
- +#255#5#4#2#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#3#3#1#255',#'#19#255#226#179'a'#255#225#177'_'
- +#255#208#154'T'#255#129'O1'#251'H?;'#205'@@@'#20#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0'J@<[vF,'#249#206#153'Y'#255#220#172'b'#255#220#172'c'#255#220#172'c'#255
- +#220#172'c'#255#220#172'c'#255#220#172'c'#255#205#160']'#255#4#3#2#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#1#0#0#255'.$'#21#255#220#172'c'#255#218#170'a'#255#190#132
- +'N'#255'c=)'#242'CCCz'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'\9('#218#177'vG'#255
- +#213#164'c'#255#214#166'e'#255#214#166'e'#255#214#166'e'#255#214#166'e'#255
- +#214#166'e'#255#214#166'e'#255#214#166'e'#255'v\8'#255#2#2#1#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#11#9#5#255#214#166'e'#255#214#166'e'#255#209#159'a'#255#139'Y'
- +'6'#252'K>7'#206'333'#5#0#0#0#0#0#0#0#0'?;9'#19'mA+'#247#201#148'^'#255#209
- +#159'e'#255#209#159'e'#255#209#159'e'#255#146'oF'#255#18#14#9#255#21#16#10
- +#255'O<&'#255#209#159'e'#255#209#159'e'#255'$'#27#17#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#11#8#5#255#209#159'e'#255#209#159'e'#255#208#158'e'#255#185#128'Q'#255
- +'^9)'#240'BBB6'#0#0#0#0#0#0#0#0'P8-q'#144'Z:'#252#201#150'd'#255#202#151'd'
- +#255#202#151'd'#255'uW:'#255#2#1#1#255#0#0#0#255#0#0#0#255#1#0#0#255'-!'#22
- +#255#202#151'd'#255'ZC-'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#5#4#3#255'gM3'#255#202#151'd'
- +#255#202#151'd'#255#202#151'd'#255#197#145'`'#255'l@*'#248'CCBo'#0#0#0#0#0#0
- +#0#0'^7$'#194#171'pK'#255#194#140'a'#255#194#140'a'#255#194#140'a'#255#6#4#3
- +#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#7#5#4#255#194#140'a'#255#139'eE'
- +#255#1#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#13
- +#9#6#255'wV<'#255#192#138'a'#255#194#140'a'#255#194#140'a'#255#194#140'a'#255
- +#194#140'a'#255#193#140'a'#255#137'T7'#252'K=6'#158#0#0#0#0#0#0#0#0'a6#'#220
- +#177'uQ'#255#185#129'['#255#185#129'['#255#127'Y>'#255#1#1#0#255#0#0#0#255#0
- +#0#0#255#0#0#0#255#2#1#1#255'8'''#27#255#185#129'['#255#185#129'['#255'+'#30
- +#21#255#2#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#13#9#6#255#179'}Y'
- +#255#185#129'['#255#185#129'['#255#185#129'['#255#185#129'['#255#185#129'['
- +#255#185#129'['#255#185#129'['#255#152'^>'#255'P:1'#190#0#0#0#0#0#0#0#0'c7#'
- +#227#175'sS'#255#178'xW'#255#178'xW'#255','#30#21#255#0#0#0#255#0#0#0#255#0#0
- +#0#255#5#4#3#255'uO:'#255#178'xW'#255#178'xW'#255#178'xW'#255#178'xW'#255'xP'
- +':'#255'('#26#19#255#10#7#5#255#10#7#5#255#28#19#13#255#168'rS'#255#163'nO'
- +#255#25#17#12#255#6#4#3#255#17#11#8#255'bB/'#255#178'xW'#255#178'xW'#255#178
- +'xW'#255#158'aB'#255'V9,'#210#0#0#0#0#0#0#0#0'f7"'#227#173'sT'#255#175'tW'
- +#255#175'tW'#255#15#10#7#255#13#8#6#255#5#4#3#255'+'#29#21#255#169'pU'#255
- +#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175
- +'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#175'tW'#255#17#11#8#255#0#0#0
- +#255#0#0#0#255#0#0#0#255#2#2#1#255#136'ZD'#255#175'tW'#255#175'tW'#255#161'd'
- +'G'#255'[8('#211#0#0#0#0#0#0#0#0'e6"'#218#171'nR'#255#173'qV'#255#173'qV'#255
- +#136'YC'#255#173'qV'#255#173'qV'#255#173'qV'#255#173'qV'#255#173'qV'#255'sK9'
- +#255'uM:'#255#159'gN'#255#173'qV'#255#173'qV'#255#173'qV'#255#173'qV'#255#173
- +'qV'#255#173'qV'#255#173'qV'#255'5"'#27#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0
- +#0#255'H/$'#255#173'qV'#255#173'qV'#255#153'^D'#255'Y8*'#188#0#0#0#0#0#0#0#0
- +'c5 '#203#170'kQ'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'
- ,#255#174'sY'#255#164'mU'#255#11#7#6#255#1#1#1#255#1#1#1#255#5#3#2#255#127'TA'
- +#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255#174'sY'#255
- +#128'UA'#255#2#1#1#255#0#0#0#255#0#0#0#255#0#0#0#255'J1&'#255#174'sY'#255#174
- +'sY'#255#147'X?'#255'S8,'#140#0#0#0#0#0#0#0#0'd4'#30#153#162'gM'#255#178'{c'
- +#255#178'{c'#255#178'{c'#255#178'{c'#255#178'{c'#255#178'{c'#255'A-$'#255#0#0
- +#0#255#0#0#0#255#0#0#0#255#0#0#0#255#20#14#11#255'xSB'#255#6#4#3#255#5#4#3
- +#255#18#12#10#255#170'u_'#255#178'{c'#255#178'{c'#255#9#6#5#255#0#0#0#255#0#0
- +#0#255#3#2#2#255#166's]'#255#178'{c'#255#178'{c'#255#131'P8'#252'S3$>'#0#0#0
- +#0#0#0#0#0'[/'#27'3'#137'T='#247#184#134'o'#255#184#134'o'#255#184#134'o'#255
- +#184#134'o'#255#184#134'o'#255#184#134'o'#255#14#10#9#255#0#0#0#255#0#0#0#255
- +#0#0#0#255#1#1#1#255'\C7'#255#14#10#8#255#0#0#0#255#0#0#0#255#0#0#0#255#14#10
- +#8#255#184#134'o'#255#184#134'o'#255'xWI'#255#2#1#1#255#0#0#0#255#18#14#11
- +#255#184#134'o'#255#184#134'o'#255#183#131'l'#255'h:&'#240#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0'n<%'#218#189#140'x'#255#190#143'z'#255#190#143'z'#255#190#143
- +'z'#255#190#143'z'#255#190#143'z'#255',!'#28#255#0#0#0#255#0#0#0#255#0#0#0
- +#255#9#7#6#255#190#143'z'#255#9#7#6#255#0#0#0#255#0#0#0#255#0#0#0#255#5#4#3
- +#255#190#143'z'#255#190#143'z'#255#190#143'z'#255#159'xe'#255#0#0#0#255#140
- +'jZ'#255#190#143'z'#255#190#143'z'#255#175'yc'#255'b6"'#193#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0'd4'#30#151#167's\'#254#196#154#135#255#196#154#135#255#196#154
- +#135#255#196#154#135#255#196#154#135#255'qYN'#255#0#0#0#255#0#0#0#255#1#1#1
- +#255'v]R'#255#194#152#133#255#5#4#4#255#0#0#0#255#0#0#0#255#0#0#0#255#10#8#7
- +#255#196#154#135#255#196#154#135#255#196#154#135#255#196#154#135#255'"'#27#24
- +#255#196#154#135#255#196#154#135#255#196#154#135#255#131'R<'#248'^1'#28'1'#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#14'o>('#224#198#157#140#255#202#163#146
- +#255#202#163#146#255#202#163#146#255#202#163#146#255#170#138'{'#255#0#0#0#255
- +#8#6#6#255#26#21#19#255#202#163#146#255#143'th'#255#1#1#1#255#0#0#0#255#0#0#0
- +#255#2#2#2#255#143'sg'#255#202#163#146#255#202#163#146#255#202#163#146#255
- +#202#163#146#255#191#155#138#255#202#163#146#255#202#163#146#255#183#135'r'
- +#255'd5 '#193#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'd3'#30'{'#156
- +'jS'#248#209#174#160#255#209#174#160#255#209#174#160#255#209#174#160#255#209
- +#174#160#255#2#2#2#255#205#172#158#255#209#174#160#255#209#174#160#255#169
- +#140#129#255#11#9#9#255#1#1#0#255#4#3#3#255#132'oe'#255#209#174#160#255#209
- +#174#160#255#209#174#160#255#209#174#160#255#209#174#160#255#209#174#160#255
- +#209#174#160#255#205#167#152#255'yG3'#235'[/'#27'"'#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'd4'#30#181#179#134'r'#254#215#185#173#255#215
- +#185#173#255#215#185#173#255#215#185#173#255'm^X'#255#215#185#173#255#215#185
- +#173#255#215#185#173#255#215#185#173#255#133'sk'#255#0#0#0#255#156#134'}'#255
- +#215#185#173#255#215#185#173#255#215#185#173#255#215#185#173#255#215#185#173
- +#255#215#185#173#255#215#185#173#255#214#183#172#255#143'^I'#243'b3'#29'`'#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#8'f6 '
- +#205#189#148#131#254#222#197#187#255#222#197#187#255#222#197#187#255#222#197
- +#187#255#222#197#187#255#222#197#187#255#222#197#187#255#222#197#187#255#127
- +'qk'#255#134'wq'#255#222#197#187#255#222#197#187#255#222#197#187#255#222#197
- +#187#255#222#197#187#255#222#197#187#255#222#197#187#255#220#193#183#255#159
- +'o['#247'd3'#30#147#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0'[/'#27#15'c3'#30#193#176#132'q'#248#228#206#199#255
- +#228#208#201#255#228#208#201#255#228#208#201#255#228#208#201#255#228#208#201
- +#255#228#208#201#255#228#208#201#255#228#208#201#255#228#208#201#255#228#208
- +#201#255#228#208#201#255#228#208#201#255#228#208#201#255#228#208#201#255#221
- +#196#186#255#141']I'#237'c3'#29#129#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#2'c3'#29#150
- +#135'XD'#231#208#176#164#255#235#219#215#255#235#219#215#255#235#219#215#255
- +#235#219#215#255#235#219#215#255#235#219#215#255#235#219#215#255#235#219#215
- +#255#235#219#215#255#235#219#215#255#235#219#215#255#232#214#209#255#189#149
- +#133#253'qA+'#220'a2'#29'O'#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27
- +'"e4'#30#185#144'cO'#235#195#158#144#254#230#209#203#255#242#231#229#255#242
- +#231#229#255#242#231#229#255#242#231#229#255#242#231#229#255#241#230#226#255
- +#220#193#184#255#180#141'|'#251'zK6'#226'd3'#30#142'[/'#27#10#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#28'b3'#29'{g5'#30
- +#198'xH2'#218#137']J'#229#156'r`'#236#151'mZ'#234#132'VB'#227'q?)'#213'f4'#30
- +#182'_1'#28'W[/'#27#11#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- ,#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#5'[/'
- +#27#30'[/'#27#22'[/'#27#1#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#255#252'?'#255
- +#255#192#3#255#255#0#0#255#254#0#0'?'#248#0#0#31#240#0#0#15#240#0#0#7#224#0#0
- +#7#192#0#0#3#192#0#0#3#192#0#0#1#128#0#0#1#128#0#0#1#128#0#0#1#128#0#0#1#128
- +#0#0#1#128#0#0#1#128#0#0#1#128#0#0#1#128#0#0#1#128#0#0#3#192#0#0#3#192#0#0#3
- +#192#0#0#7#224#0#0#7#240#0#0#15#240#0#0#31#248#0#0'?'#252#0#0#127#255#0#0#255
- +#255#192#3#255#255#252'?'#255'('#0#0#0#16#0#0#0' '#0#0#0#1#0' '#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +';;;'#13'ICB7M=4zL>6xFBA;@@@'#16#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0'III'#7'W;,'#171'nC('#245#145'`+'#250#181#127'2'#253#175
- +'z1'#253#139'\*'#250'h?&'#244'P=3'#159'@@@'#12#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0'K921d;'''#235#191#137'7'#254#249#198'E'#255#251#199'F'#255#251#200
- +'F'#255#251#200'F'#255#251#199'F'#255#246#194'E'#255#173'y3'#253'\9)'#229'E>'
- +';2'#0#0#0#0#0#0#0#0#0#0#0#0'>2,'#7'nC'''#238#223#171'N'#255#239#191'U'#255
- +#240#192'U'#255#164#131':'#255'@3'#23#255'J;'#26#255'~e-'#255#196#157'E'#255
- +#239#191'U'#255#212#159'J'#255'a<('#231'MMM'#10#0#0#0#0#0#0#0#0'[7('#183#195
- +#145'N'#254#228#180'_'#255#228#180'_'#255#228#180'_'#255''#25#255#0#0#0#255
- +#0#0#0#255#0#0#0#255#4#3#1#255'9-'#24#255#205#163'U'#255#175'~E'#253'Q:0'#168
- +#0#0#0#0'[/'#27#10#143'd@'#248#219#174'l'#255#219#173'l'#255#159'~N'#255#206
- +#163'f'#255'qY7'#255#0#0#0#255#0#0#0#255#0#0#0#255#0#0#0#255#1#1#0#255#152'x'
- +'K'#255#218#172'k'#255'zQ5'#246'UUU'#3'W4$H'#178#134'_'#254#213#169'x'#255'Y'
- +'F2'#255#0#0#0#255'L<+'#255#200#158'p'#255#8#6#4#255#0#0#0#255#0#0#0#255#18
- +#15#10#255'pY?'#255#213#169'x'#255#213#169'x'#255#157'tR'#251'M=74^6$'#154
- +#193#151'x'#255#179#144's'#255#6#5#4#255#27#21#17#255#155'|c'#255#206#165#132
- +#255#130'hS'#255'=1'''#255':/%'#255#170#137'm'#255#141'q['#255#166#133'j'#255
- +#206#165#132#255#178#135'l'#253'Q8,{c5 '#167#195#154#133#255#163#130'q'#255
- +#153'zj'#255#192#152#132#255#199#159#138#255#200#159#138#255#201#160#139#255
- +#201#160#139#255#201#160#139#255#154'zj'#255#1#1#1#255#29#23#20#255#197#157
- +#136#255#181#139'v'#255'X5%|_1'#28'V'#176#132'r'#254#199#159#141#255#199#159
- +#141#255#184#147#130#255'#'#28#25#255#27#22#19#255#167#133'v'#255#127'fZ'#255
- +#172#137'z'#255#197#157#139#255' '#26#23#255#15#12#11#255#187#150#133#255#156
- +'tb'#251'W1 0[/'#27#30#160'zk'#246#210#176#163#255#210#176#163#255#154#129'x'
- +#255#0#0#0#255' '#27#25#255#152#128'v'#255#4#3#3#255'>40'#255#210#176#163#255
- +#148'|s'#255'RD?'#255#210#176#163#255#140'fW'#243'[/'#27#2#0#0#0#0'tI6'#209
- +#216#188#178#255#221#195#185#255#213#188#178#255'$'#31#30#255#131'sn'#255'sf'
- +'`'#255#0#0#0#255'eYU'#255#221#195#185#255#221#195#185#255#204#180#170#255
- +#207#178#166#255'k>+'#182#0#0#0#0#0#0#0#0'[/'#27#31#156'xi'#240#232#213#207
- +#255#232#213#207#255#180#165#161#255#232#213#207#255#182#167#162#255'ICA'#255
- +#226#207#201#255#232#213#207#255#232#213#207#255#231#213#206#255#134'_O'#233
- +'[/'#27#12#0#0#0#0#0#0#0#0#0#0#0#0'd3'#30'e'#171#139'~'#240#239#226#224#255
- +#242#231#229#255#242#231#229#255#240#229#227#255#242#231#229#255#242#231#229
- +#255#242#231#229#255#235#221#216#255#153'uh'#236'a2'#29'?'#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#0#0#0#0'\0'#27'*'#131'\I'#215#212#191#183#252#239#229#226#255
- +#253#250#252#255#253#249#250#255#236#223#220#255#204#180#172#250'yM;'#196'[/'
- +#27#23#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0'[/'#27#3'[/'
- +#27'>c3'#29#131'uI4'#190'oA-'#183'b2'#29'v[/'#27'4'#0#0#0#0#0#0#0#0#0#0#0#0#0
- +#0#0#0#0#0#0#0#248#31#172'A'#224#7#172'A'#192#3#172'A'#128#1#172'A'#128#1#172
- +'A'#0#0#172'A'#0#0#172'A'#0#0#172'A'#0#0#172'A'#0#0#172'A'#0#0#172'A'#128#1
- +#172'A'#128#1#172'A'#192#3#172'A'#224#7#172'A'#240#31#172'A'
-]);
-
diff --git a/demos_lazarus/Demo25/project1.manifest b/demos_lazarus/Demo25/project1.manifest
deleted file mode 100644
index 515fede..0000000
--- a/demos_lazarus/Demo25/project1.manifest
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Your application description here.
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/demos_lazarus/Demo25/project1.rc b/demos_lazarus/Demo25/project1.rc
deleted file mode 100644
index cd8e7b0..0000000
--- a/demos_lazarus/Demo25/project1.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-#define RT_MANIFEST 24
-#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
-#define ISOLATIONAWARE_MANIFEST_RESOURCE_ID 2
-#define ISOLATIONAWARE_NOSTATICIMPORT_MANIFEST_RESOURCE_ID 3
-
-CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "project1.manifest"
-MAINICON ICON "project1.ico"
diff --git a/demos_lazarus/Demo25/project1.res b/demos_lazarus/Demo25/project1.res
deleted file mode 100644
index 708df3c..0000000
Binary files a/demos_lazarus/Demo25/project1.res and /dev/null differ
diff --git a/demos_lazarus/Demo25/unit1.lfm b/demos_lazarus/Demo25/unit1.lfm
deleted file mode 100644
index f71828c..0000000
--- a/demos_lazarus/Demo25/unit1.lfm
+++ /dev/null
@@ -1,147 +0,0 @@
-object Form1: TForm1
- Left = 372
- Height = 522
- Top = 100
- Width = 795
- Caption = 'Form1'
- ClientHeight = 522
- ClientWidth = 795
- OnCreate = FormCreate
- LCLVersion = '0.9.28.2'
- object Panel1: TPanel
- Left = 0
- Height = 522
- Top = 0
- Width = 795
- Align = alClient
- ClientHeight = 522
- ClientWidth = 795
- TabOrder = 0
- object Memo1: TMemo
- Left = 1
- Height = 231
- Top = 1
- Width = 793
- Align = alTop
- TabOrder = 0
- end
- object PairSplitter1: TPairSplitter
- Left = 1
- Height = 8
- Top = 232
- Width = 793
- Align = alTop
- Position = 45
- object PairSplitterSide1: TPairSplitterSide
- Cursor = crArrow
- Left = 0
- Height = 8
- Top = 0
- Width = 45
- end
- object PairSplitterSide2: TPairSplitterSide
- Cursor = crArrow
- Left = 50
- Height = 8
- Top = 0
- Width = 743
- end
- end
- object Memo2: TMemo
- Left = 1
- Height = 168
- Top = 240
- Width = 793
- Align = alClient
- Lines.Strings = (
- 'class XYZ(object):'
- ' pass'
- ''
- 'class Foo:'
- ' def __init__(Self, Value=0):'
- ' Self.Value = Value'
- ' def __del__(Self):'
- ' print "delete", Self'
- ' def __add__(self, other):'
- ' return Foo(self.Value + other.Value)'
- ' def Inc(Self, AValue = 1):'
- ' Self.Value = Self.Value + AValue'
- ' def GetSelf(Self):'
- ' return Self'
- ' def GetValue(Self):'
- ' return Self.Value'
- ' def SetABC(Self, A, B, C):'
- ' Self.A = A'
- ' Self.B = B'
- ' Self.C = C'
- ' def Add(Self, AFooInst):'
- ' Self.Value = Self.Value + AFooInst.Value'
- 'class Bar(Foo):'
- ' def Inc(Self, AValue = 1):'
- ' Self.Value = Self.Value - AValue'
- 'def Add(a, b):'
- ' return a + b'
- 'def MakeList(a, b, c, d):'
- ' return [a, b, c, d]'
- ''
- 'f = Foo()'
- 'print "Created", f'
- 'f.Inc()'
- 'f.Inc(2)'
- 'b = Bar()'
- 'b.Inc()'
- 'b.Inc(2)'
- )
- TabOrder = 2
- end
- object Panel2: TPanel
- Left = 1
- Height = 113
- Top = 408
- Width = 793
- Align = alBottom
- ClientHeight = 113
- ClientWidth = 793
- TabOrder = 3
- object Button1: TButton
- Left = 15
- Height = 25
- Top = 8
- Width = 75
- Caption = 'Execute'
- OnClick = Button1Click
- TabOrder = 0
- end
- object btnTestIntegers: TButton
- Left = 119
- Height = 25
- Top = 8
- Width = 75
- Caption = 'Test Integers'
- OnClick = btnTestIntegersClick
- TabOrder = 1
- end
- object cbTestIntegers: TCheckBox
- Left = 122
- Height = 19
- Top = 41
- Width = 66
- Caption = 'Included'
- TabOrder = 2
- end
- end
- end
- object PythonEngine1: TPythonEngine
- IO = PythonGUIInputOutput1
- left = 96
- top = 48
- end
- object PythonGUIInputOutput1: TPythonGUIInputOutput
- DelayWrites = True
- UnicodeIO = False
- RawOutput = False
- Output = Memo1
- left = 338
- top = 48
- end
-end
diff --git a/demos_lazarus/Demo25/unit1.lrs b/demos_lazarus/Demo25/unit1.lrs
deleted file mode 100644
index 619b7de..0000000
--- a/demos_lazarus/Demo25/unit1.lrs
+++ /dev/null
@@ -1,40 +0,0 @@
-LazarusResources.Add('TForm1','FORMDATA',[
- 'TPF0'#6'TForm1'#5'Form1'#4'Left'#3't'#1#6'Height'#3#10#2#3'Top'#2'd'#5'Width'
- +#3#27#3#7'Caption'#6#5'Form1'#12'ClientHeight'#3#10#2#11'ClientWidth'#3#27#3
- +#8'OnCreate'#7#10'FormCreate'#10'LCLVersion'#6#8'0.9.28.2'#0#6'TPanel'#6'Pan'
- +'el1'#4'Left'#2#0#6'Height'#3#10#2#3'Top'#2#0#5'Width'#3#27#3#5'Align'#7#8'a'
- +'lClient'#12'ClientHeight'#3#10#2#11'ClientWidth'#3#27#3#8'TabOrder'#2#0#0#5
- +'TMemo'#5'Memo1'#4'Left'#2#1#6'Height'#3#231#0#3'Top'#2#1#5'Width'#3#25#3#5
- +'Align'#7#5'alTop'#8'TabOrder'#2#0#0#0#13'TPairSplitter'#13'PairSplitter1'#4
- +'Left'#2#1#6'Height'#2#8#3'Top'#3#232#0#5'Width'#3#25#3#5'Align'#7#5'alTop'#8
- +'Position'#2'-'#0#17'TPairSplitterSide'#17'PairSplitterSide1'#6'Cursor'#7#7
- +'crArrow'#4'Left'#2#0#6'Height'#2#8#3'Top'#2#0#5'Width'#2'-'#0#0#17'TPairSpl'
- +'itterSide'#17'PairSplitterSide2'#6'Cursor'#7#7'crArrow'#4'Left'#2'2'#6'Heig'
- +'ht'#2#8#3'Top'#2#0#5'Width'#3#231#2#0#0#0#5'TMemo'#5'Memo2'#4'Left'#2#1#6'H'
- +'eight'#3#168#0#3'Top'#3#240#0#5'Width'#3#25#3#5'Align'#7#8'alClient'#13'Lin'
- +'es.Strings'#1#6#18'class XYZ(object):'#6#6' pass'#6#0#6#10'class Foo:'#6#30
- +' def __init__(Self, Value=0):'#6#22' Self.Value = Value'#6#20' def __d'
- +'el__(Self):'#6#24' print "delete", Self'#6#27' def __add__(self, other)'
- +':'#6'( return Foo(self.Value + other.Value)'#6#28' def Inc(Self, AValue'
- +' = 1):'#6'$ Self.Value = Self.Value + AValue'#6#20' def GetSelf(Self):'
- +#6#15' return Self'#6#21' def GetValue(Self):'#6#21' return Self.Valu'
- +'e'#6#28' def SetABC(Self, A, B, C):'#6#14' Self.A = A'#6#14' Self.B '
- +'= B'#6#14' Self.C = C'#6#26' def Add(Self, AFooInst):'#6', Self.Valu'
- +'e = Self.Value + AFooInst.Value'#6#15'class Bar(Foo):'#6#28' def Inc(Self,'
- +' AValue = 1):'#6'$ Self.Value = Self.Value - AValue'#6#14'def Add(a, b):'
- +#6#14' return a + b'#6#25'def MakeList(a, b, c, d):'#6#21' return [a, b, c'
- +', d]'#6#0#6#9'f = Foo()'#6#18'print "Created", f'#6#7'f.Inc()'#6#8'f.Inc(2)'
- +#6#9'b = Bar()'#6#7'b.Inc()'#6#8'b.Inc(2)'#0#8'TabOrder'#2#2#0#0#6'TPanel'#6
- +'Panel2'#4'Left'#2#1#6'Height'#2'q'#3'Top'#3#152#1#5'Width'#3#25#3#5'Align'#7
- +#8'alBottom'#12'ClientHeight'#2'q'#11'ClientWidth'#3#25#3#8'TabOrder'#2#3#0#7
- +'TButton'#7'Button1'#4'Left'#2#15#6'Height'#2#25#3'Top'#2#8#5'Width'#2'K'#7
- +'Caption'#6#7'Execute'#7'OnClick'#7#12'Button1Click'#8'TabOrder'#2#0#0#0#7'T'
- +'Button'#15'btnTestIntegers'#4'Left'#2'w'#6'Height'#2#25#3'Top'#2#8#5'Width'
- +#2'K'#7'Caption'#6#13'Test Integers'#7'OnClick'#7#20'btnTestIntegersClick'#8
- +'TabOrder'#2#1#0#0#9'TCheckBox'#14'cbTestIntegers'#4'Left'#2'z'#6'Height'#2
- +#19#3'Top'#2')'#5'Width'#2'B'#7'Caption'#6#8'Included'#8'TabOrder'#2#2#0#0#0
- +#0#13'TPythonEngine'#13'PythonEngine1'#2'IO'#7#21'PythonGUIInputOutput1'#4'l'
- +'eft'#2'`'#3'top'#2'0'#0#0#21'TPythonGUIInputOutput'#21'PythonGUIInputOutput'
- +'1'#11'DelayWrites'#9#9'UnicodeIO'#8#9'RawOutput'#8#6'Output'#7#5'Memo1'#4'l'
- +'eft'#3'R'#1#3'top'#2'0'#0#0#0
-]);
diff --git a/demos_lazarus/Demo25/unit1.pas b/demos_lazarus/Demo25/unit1.pas
deleted file mode 100644
index b1f0380..0000000
--- a/demos_lazarus/Demo25/unit1.pas
+++ /dev/null
@@ -1,269 +0,0 @@
-unit Unit1;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
- StdCtrls, ExtCtrls, PairSplitter, PythonEngine, PythonGUIInputOutput;
-
-type
-
- { TForm1 }
-
- TForm1 = class(TForm)
- Button1: TButton;
- btnTestIntegers: TButton;
- cbTestIntegers: TCheckBox;
- Memo1: TMemo;
- Memo2: TMemo;
- PairSplitter1: TPairSplitter;
- PairSplitterSide1: TPairSplitterSide;
- PairSplitterSide2: TPairSplitterSide;
- Panel1: TPanel;
- Panel2: TPanel;
- PythonEngine1: TPythonEngine;
- PythonGUIInputOutput1: TPythonGUIInputOutput;
- procedure btnTestIntegersClick(Sender: TObject);
- procedure Button1Click(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- private
- { private declarations }
- fVerbose : Boolean;
- procedure Log( const AText : String );
- procedure RunSelectedTests;
- public
- { public declarations }
- end;
-
-var
- Form1: TForm1;
-
-implementation
-
-Uses
- VarPyth;
-
-{ TForm1 }
-
-
-procedure TForm1.Button1Click(Sender: TObject);
-begin
- PythonEngine1.ExecStrings( Memo2.Lines );
-end;
-
-procedure TForm1.btnTestIntegersClick(Sender: TObject);
-var
- a, b, c : Variant;
- big : Int64;
-begin
- // initialize the operands
- a := VarPythonCreate(2);
- Assert(VarIsPython(a));
- Assert(VarIsPythonNumber(a));
- Assert(VarIsPythonInteger(a));
- Assert(Integer(a) = 2);
-
- b := VarPythonCreate(3);
- Assert(VarIsPython(b));
- Assert(VarIsPythonNumber(b));
- Assert(VarIsPythonInteger(b));
- Assert(Integer(b) = 3);
-
- // arithmetic operations
- //----------------------
-
- // addition
- c := a + b;
- // check result of operation
- Assert( Integer(c) = 5 );
- // check that operation did not change the content of operands.
- Assert(Integer(a) = 2);
- Assert(Integer(b) = 3);
- // now with a litteral
- c := a + b + 1;
- Assert( Integer(c) = 6 );
- c := a + 1 + b;
- Assert( Integer(c) = 6 );
- c := 1 + a + b;
- Assert( Integer(c) = 6 );
-
- // substraction
- c := b - a;
- Assert( Integer(c) = 1 );
- // now with a litteral
- c := b - a - 1;
- Assert( Integer(c) = 0 );
- c := b - 1 - a;
- Assert( Integer(c) = 0 );
- c := 1 - b - a;
- Assert( Integer(c) = -4 );
-
- // multiplication
- c := a * b;
- Assert( Integer(c) = 6 );
- // now with a litteral
- c := a * b * 2;
- Assert( Integer(c) = 12 );
- c := a * 2 * b;
- Assert( Integer(c) = 12 );
- c := 2 * a * b;
- Assert( Integer(c) = 12 );
-
- // integer division
- c := b div a;
- Assert( Integer(c) = 1 );
-
- // division: in Python a division between 2 integers is the same as the integer division
- c := b / a;
- Assert( c = 1.5 );
- Assert( Integer(c) = 2 );
-
- // modulus
- c := b mod a;
- Assert( Integer(c) = 1 );
- c := BuiltinModule.divmod(b, a); // this returns a tuple whose first item is the result of the division,
- // and second item the modulo.
- if VarIsPythonSequence(c) and (c.Length = 2) then
- begin
- Assert(Integer(c.GetItem(0)) = 1); // division
- Assert(Integer(c.GetItem(1)) = 1); // modulo
- end;
-
- // power
- c := BuiltinModule.pow(a, b);
- Assert(c = 8);
-
- // negation
- c := -a;
- Assert( Integer(c) = -2 );
-
- // logical operations
- //------------------
-
- // inverse
- c := not a; // in python it would be: c = ~2
- Assert( Integer(c) = -3 );
-
- // shift left (<<)
- c := a shl b;
- Assert( Integer(c) = 16 );
- c := a shl 1;
- Assert( Integer(c) = 4 );
-
- // shift right (>>)
- c := a shl b;
- c := c shr b;
- Assert( Integer(c) = Integer(a) );
- c := b shr 1;
- Assert( Integer(c) = 1 );
-
- // and
- c := a and (a*5);
- Assert( Integer(c) = Integer(a) );
- c := a and 6;
- Assert( Integer(c) = Integer(a) );
-
- // or
- c := a or b;
- Assert( Integer(c) = 3 );
- c := a or 3;
- Assert( Integer(c) = 3 );
-
- // xor
- c := a xor b;
- Assert( Integer(c) = 1 );
- c := a xor 3;
- Assert( Integer(c) = 1 );
-
- // comparisons
- //------------
-
- // equal
- c := a = b;
- Assert(c = False);
- c := a = a;
- Assert(c = True);
- Assert( a = 2);
-
- // not equal
- c := a <> b;
- Assert(c = True);
- Assert( not (c = b) );
- c := a <> a;
- Assert(c = False);
- Assert( a = 2);
-
- // greater than
- c := a > b; Assert(c = False);
- c := b > a; Assert(c = True);
- Assert( a > 1);
-
- // greater or equal than
- c := a >= b; Assert(c = False);
- c := b >= a; Assert(c = True);
- c := a >= a; Assert(c = True);
- Assert( a >= 2 );
-
- // less than
- c := a < b; Assert(c = True);
- c := b < a; Assert(c = False);
- Assert( a < 6);
-
- // less or equal than
- c := a <= b; Assert(c = True);
- c := b <= a; Assert(c = False);
- c := a <= a; Assert(c = True);
- Assert( a <= 2);
-
- // parenthesis
- c := a * ((a * b) div b);
- Assert( c = a*2 );
-
- // copy
- c := a;
- Assert( c = a);
- Assert( VarIsSame(c, a) ); // checks if 2 variants share the same Python object.
-
- // test long long (Int64)
- big := Int64(MaxInt)*4;
- b := VarPythonCreate(big);
- Assert( b = big );
- Assert( b <> big+1 );
- Assert( b > MaxInt );
- Assert( MaxInt < b );
- Assert( b+1 = big+1 );
- Assert( b*2 = big*2 );
- Assert( b div 2 = big div 2 );
- c := VarPythonCreate(True);
- Assert(VarIsBool(c));
- Assert(VarIsTrue(c));
- c := VarPythonCreate(False);
- Assert(VarIsBool(c));
- Assert(not VarIsTrue(c));
-
- // Done!
- Log('Integer test was Ok.');end;
-
-procedure TForm1.FormCreate(Sender: TObject);
-begin
- fVerbose := True;
-end;
-
-procedure TForm1.Log(const AText: String);
-begin
- if fVerbose then
- Memo1.Lines.Add(AText);
-end;
-
-procedure TForm1.RunSelectedTests;
-begin
-
-end;
-
-initialization
- {$I unit1.lrs}
-
-end.
-
diff --git a/demos_lazarus/Demo31/Project1.lpi b/demos_lazarus/Demo31/Project1.lpi
deleted file mode 100644
index 1e998ff..0000000
--- a/demos_lazarus/Demo31/Project1.lpi
+++ /dev/null
@@ -1,342 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/demos_lazarus/Demo31/Project1.lpr b/demos_lazarus/Demo31/Project1.lpr
deleted file mode 100644
index 2a8c920..0000000
--- a/demos_lazarus/Demo31/Project1.lpr
+++ /dev/null
@@ -1,18 +0,0 @@
-program Project1;
-
-{.$I Definition.Inc}
-uses
- Interfaces,
- Forms,
- Unit1 in 'Unit1.pas' {Form1},
- WrapDelphiTypes in '..\..\Components\Sources\Core\WrapDelphiTypes.pas',
- Unit2 in 'Unit2.pas' {TestForm};
-
-{$R *.res}
-
-begin
- Application.Initialize;
- Application.CreateForm(TForm1, Form1);
- Application.CreateForm(TTestForm, TestForm);
- Application.Run;
-end.
diff --git a/demos_lazarus/Demo31/Project1.res b/demos_lazarus/Demo31/Project1.res
deleted file mode 100644
index e66ecf8..0000000
Binary files a/demos_lazarus/Demo31/Project1.res and /dev/null differ
diff --git a/demos_lazarus/Demo31/Unit1.lfm b/demos_lazarus/Demo31/Unit1.lfm
deleted file mode 100644
index a4a1d97..0000000
--- a/demos_lazarus/Demo31/Unit1.lfm
+++ /dev/null
@@ -1,476 +0,0 @@
-object Form1: TForm1
- Left = 659
- Height = 647
- Top = 47
- Width = 685
- VertScrollBar.Range = 210
- ActiveControl = Memo1
- Caption = 'Form1'
- ClientHeight = 647
- ClientWidth = 668
- Color = clBtnFace
- Font.Color = clWindowText
- Font.Height = 11
- Font.Name = 'MS Sans Serif'
- Font.Pitch = fpVariable
- OnCreate = FormCreate
- LCLVersion = '0.9.30.2'
- Visible = True
- object Splitter1: TSplitter
- Cursor = crVSplit
- Left = 0
- Height = 3
- Top = 169
- Width = 668
- Align = alTop
- ResizeAnchor = akTop
- end
- object Memo1: TMemo
- Left = 0
- Height = 434
- Top = 172
- Width = 668
- Align = alClient
- Lines.Strings = (
- 'from spam import DelphiVersion, MainForm, DVar, CreateComponent, Application, Screen, mrOk, Form, Button, CheckBox, caFree'
- 'from spam import Point, Monitor, DrawGrid, gdSelected, clBlue, ssCtrl, PageControl, TabSheet'
- 'if DelphiVersion >= 6:'
- ' from spam import mdNearest'
- 'import unittest'
- 'import sys'
- 'py_major, py_minor = sys.version_info[:2]'
- ''
- 'class MyForm(Form):'
- ' def __init__(self, Owner):'
- ' self.Caption = ''Subclassed form'''
- ' self.btnClose = Button(self)'
- ' self.btnClose.Parent = self'
- ' self.btnClose.Caption = ''Close'''
- ' self.btnClose.SetBounds(10, 10, 120, 30)'
- ' self.btnClose.OnClick = self.btnCloseClick'
- ''
- ' self.chkCanClose = CheckBox(self)'
- ' self.chkCanClose.Parent = self'
- ' self.chkCanClose.Caption = ''Can close?'''
- ' self.chkCanClose.SetBounds(10, 50, 120, 30)'
- ''
- ' self.grdTest = DrawGrid(self)'
- ' self.grdTest.Parent = self'
- ' self.grdTest.SetBounds(10, 100, 300, 250)'
- ' self.grdTest.OnDrawCell = self.grdTestDrawCell'
- ' self.grdTest.OnSelectCell = self.grdTestSelectCell'
- ''
- ' self.OnCloseQuery = self.MyFormCloseQuery'
- ' self.OnClose = self.MyFormClose'
- ' self.Width = 400'
- ' self.Height = 400'
- ''
- ' def btnCloseClick(self, Sender):'
- ' print "Close!"'
- ' self.Close()'
- ''
- ' def MyFormCloseQuery(self, Sender, CanClose):'
- ' CanClose.Value = self.chkCanClose.Checked'
- ''
- ' def MyFormClose(self, Sender, Action):'
- ' Action.Value = caFree'
- ''
- ' def grdTestDrawCell(self, Sender, Col, Row, Rect, State):'
- ' if gdSelected in State:'
- ' Sender.Canvas.Brush.Color = clBlue # 0x00ff0000 # blue'
- ' print "Cell[%d, %d] is selected, Rect=%s, State=%s" % (Col, Row, Rect, State)'
- ' Sender.Canvas.TextRect(Rect, Rect.Left+2, Rect.Top+2, "%d @ %d" % (Col, Row))'
- ''
- ' def grdTestSelectCell(self, Sender, Col, Row, CanSelect):'
- ' if Col == 2 and Row == 2:'
- ' CanSelect.Value = False'
- ''
- 'class TTestForm(Form):'
- ' def __init__(self, Owner):'
- ' self.Caption = self.Caption + '' - changed by Python subclass'''
- ' self.BindMethodsToEvents()'
- ''
- ' def handle_btnAdd_OnClick(self, Sender):'
- ' self.ListBox1.Items.Add(self.Edit1.Text)'
- ''
- 'class TestDelphiWrapper(unittest.TestCase):'
- ''
- ' def testReadWriteProperties(self):'
- ' DVar.SValue = ''Weight'''
- ' self.assertEqual(DVar.SValue, ''Weight'')'
- ' DVar.IValue = 70'
- ' self.assertEqual(DVar.IValue, 70)'
- ' MainForm.Caption = ''PyDelphi rocks!'' #setting properties'
- ' self.assertEqual(MainForm.Caption, ''PyDelphi rocks!'')'
- ' print'
- ' print ''MainForm.ActiveControl='', MainForm.ActiveControl # class properties'
- ' MainForm.BorderStyle = ''bsSizeable'' #enumeration property'
- ' MainForm.Anchors = [''akTop'', ''akLeft''] #set property'
- ' self.assertEqual(MainForm.Anchors, [''akTop'', ''akLeft''])'
- ''
- ' def testTObject(self):'
- ' self.assertEqual(MainForm.ClassName, ''TForm1'')'
- ' self.assert_(MainForm.InheritsFrom(''TObject''))'
- ''
- ' def testMethodCall(self):'
- ' if DelphiVersion >= 7:'
- ' DVar.SetMeUp(''Age'', 25)'
- ' self.assertEqual(DVar.SValue, ''Age'')'
- ' self.assertEqual(DVar.IValue, 25)'
- ' print'
- ' print DVar.DescribeMe() #method calls'
- ''
- ' def testRepr(self):'
- ' print'
- ' print ''Representation of Delphi objects'''
- ' print DVar'
- ' print MainForm'
- ' if DelphiVersion >= 7:'
- ' print DVar.DescribeMe # method object'
- ' print DVar.SL # TStrings'
- ''
- ' def testTStrings(self):'
- ' SL = DVar.SL'
- ' self.assertEqual(len(SL), 2)'
- ' print'
- ' for i in DVar.SL: print i, '' contains '', DVar.SL[i]'
- ' SL.Add(''New String'')'
- ' self.assertEqual(len(SL), 3)'
- ' self.assertEqual(SL.IndexOf(''New String''), 2)'
- ' self.assertEqual(SL[0], ''Form1'')'
- ' self.assertEqual(SL.Objects[0], MainForm)'
- ' self.assertEqual(MainForm in SL.Objects, True)'
- ' SL[2] = ''Changed'''
- ' self.assertEqual(SL[2], ''Changed'')'
- ' self.assertEqual(SL.Objects[2], None)'
- ' SL.Objects[2] = MainForm'
- ' self.assertEqual(SL.Objects[2], MainForm)'
- ' self.assertEqual(MainForm in SL.Objects, True)'
- ' SL.Delete(2)'
- ' self.assertEqual(len(SL), 2)'
- ' print "str(SL) =", str(SL)'
- ' SL.Assign([1, 2, 3])'
- ' self.assertEqual(len(SL), 3)'
- ' self.assertEqual(''2'' in SL, True)'
- ' self.assertEqual(SL[1], ''2'')'
- ' tmp = [''a'', ''b'', ''c'']'
- ' SL.Assign(tmp)'
- ' self.assertEqual(SL.ToList(), tmp)'
- ' tmp = (''a'', ''b'', ''c'')'
- ' SL.Assign(tmp)'
- ' self.assertEqual(SL.ToTuple(), tmp)'
- ''
- ' def testTComponent(self):'
- ' self.assertEqual(MainForm.Name, ''Form1'')'
- ' count = MainForm.ComponentCount'
- ' def SetComponentCount():'
- ' MainForm.ComponentCount = 3'
- ' if py_major == 2 and py_minor < 5:'
- ' self.assertRaises(TypeError, SetComponentCount)'
- ' else:'
- ' self.assertRaises(AttributeError, SetComponentCount)'
- ' self.assertEquals(MainForm.__owned__, False)'
- ''
- ' def testSubComponents(self):'
- ' MainForm.Button1.Caption = ''Click me!!'''
- ' self.assertEqual(MainForm.Button1.Caption, ''Click me!!'')'
- ' # test alternate mapping notation'
- ' MainForm[''Button1''].Caption = ''Click me!!!!'''
- ' self.assertEqual(MainForm[''Button1''].Caption, ''Click me!!!!'')'
- ' self.assertEqual(MainForm.Button1.Caption, ''Click me!!!!'')'
- ' # Test Owner property and DelphiObject comparison'
- ' self.assert_(MainForm.Button1.Owner == MainForm)'
- ' print [i.Name for i in MainForm.Components]'
- ''
- ' def testCreateComponent(self):'
- ' NewButton = CreateComponent(''TButton'', None)'
- ' self.assertEquals(NewButton.__bound__, True)'
- ' self.assertEquals(NewButton.__owned__, True)'
- ' NewButton.Free()'
- ' self.assertEquals(NewButton.__bound__, False)'
- ''
- ' def testWinControls(self):'
- ' self.assertEqual(MainForm.Panel1.Parent, MainForm)'
- ' print'
- ' print ''MainForm contains '', MainForm.ControlCount, '' controls'''
- ' print [i.Name for i in MainForm.Controls]'
- ''
- ' def testForm(self):'
- ' MyForm = CreateComponent(''TForm'', None)'
- ' MyForm.Name = ''MyForm'''
- ' MyForm.Caption = ''Python Generated Form'''
- ' MyForm.Height = 300'
- ' MyForm.Width = 310'
- ' MyForm.Position = ''poDefaultPosOnly'''
- ' PC = PageControl(MyForm)'
- ' PC.Name = "MyPageControl"'
- ' PC.Parent = MyForm'
- ' PC.Align = "alClient"'
- ' P1 = TabSheet(MyForm)'
- ' P1.PageControl = PC'
- ' P1.Caption = "Page 1"'
- ' LB = CreateComponent(''TListBox'', MyForm)'
- ' B1 = CreateComponent(''TButton'', MyForm)'
- ' B2 = CreateComponent(''TButton'', MyForm)'
- ' Edit = CreateComponent(''TEdit'', MyForm)'
- ' LB.Name = ''ListBox1'''
- ' LB.Parent = P1'
- ' LB.Left = 20'
- ' LB.Top = 14'
- ' LB.Width = 121'
- ' LB.Height = 97'
- ' LB.TabOrder = 0'
- ' B1.Name = ''Button1'''
- ' B1.Parent = P1'
- ' B1.Left = 185'
- ' B1.Top = 60'
- ' B1.Width = 75'
- ' B1.Height = 25'
- ' B1.Caption = ''Add to list'''
- ' B1.TabOrder = 1'
- ' Edit.Name = ''Edit1'''
- ' Edit.Parent = P1'
- ' Edit.Left = 168'
- ' Edit.Top = 27'
- ' Edit.Width = 121'
- ' Edit.Height = 21'
- ' Edit.TabOrder = 2'
- ' Edit.Text = ''Add me to List'''
- ' B2.Name = ''Button2'''
- ' B2.Parent = P1'
- ' B2.Left = 121'
- ' B2.Top = 125'
- ' B2.Width = 75'
- ' B2.Height = 25'
- ' B2.Caption = ''Close'''
- ' B2.ModalResult = mrOk'
- ' B2.TabOrder = 3'
- ' def ClickHandler(Sender):'
- ' print Sender.Name, '' was clicked'''
- ' LB.Items.Add(Edit.Text)'
- ' B1.OnClick = ClickHandler'
- ' def KeyPressHandler(Sender, Key):'
- ' if Key.Value == ''a'':'
- ' Key.Value = ''z'''
- ' Edit.OnKeyPress = KeyPressHandler'
- ' def KeyDownHandler(Sender, Key, Shift):'
- ' # forbid Ctrl+Home'
- ' if Key.Value == 36 and ssCtrl in Shift:'
- ' Key.Value = 0'
- ' Edit.OnKeyDown = KeyDownHandler'
- ' BtnNextPage = Button(MyForm)'
- ' BtnNextPage.Parent = P1'
- ' BtnNextPage.SetBounds(10, 200, 150, 24)'
- ' BtnNextPage.Caption = "Select Next Page"'
- ' def NextPageClick(Sender):'
- ' Sender.Owner.MyPageControl.SelectNextPage(True, True)'
- ' BtnNextPage.OnClick = NextPageClick'
- ' P2 = TabSheet(MyForm)'
- ' P2.PageControl = PC'
- ' P2.Caption = "Page 2"'
- ' BtnGotoPage3 = Button(MyForm)'
- ' BtnGotoPage3.Parent = P2'
- ' BtnGotoPage3.SetBounds(10, 10, 150, 24)'
- ' BtnGotoPage3.Caption = "Goto Page 3"'
- ' def GotoPage3Click(Sender):'
- ' Sender.Owner.MyPageControl.ActivePage = Sender.Owner.Page3'
- ' BtnGotoPage3.OnClick = GotoPage3Click'
- ''
- ' P3 = TabSheet(MyForm)'
- ' P3.PageControl = PC'
- ' P3.Caption = "Page 3"'
- ' P3.Name = "Page3"'
- ' BtnGotoFirstPage = Button(MyForm)'
- ' BtnGotoFirstPage.Parent = P3'
- ' BtnGotoFirstPage.SetBounds(10, 10, 150, 24)'
- ' BtnGotoFirstPage.Caption = "Goto First Page"'
- ' def GotoFirstPageClick(Sender):'
- ' PC.ActivePageIndex = 0'
- ' BtnGotoFirstPage.OnClick = GotoFirstPageClick'
- ' chkAllowChange = CheckBox(MyForm)'
- ' chkAllowChange.Parent = P3'
- ' chkAllowChange.SetBounds(10, 40, 150, 24)'
- ' chkAllowChange.Caption = "Allow Page Change?"'
- ' chkAllowChange.Checked = True'
- ''
- ' def PCChanging(Sender, AllowChange):'
- ' AllowChange.Value = chkAllowChange.Checked'
- ' PC.OnChanging = PCChanging'
- ''
- ' MyForm.ShowModal()'
- ''
- ' def testFormSubclass(self):'
- ' f = MyForm(Application)'
- ' try:'
- ' print f.ShowModal()'
- ' finally:'
- ' f.Free()'
- ''
- ' def testFormSubclass2(self):'
- ' f = TTestForm(Application)'
- ' try:'
- ' print f.ShowModal()'
- ' finally:'
- ' f.Free()'
- ''
- ' def testPointConversions(self):'
- ' p1 = Point(10, 10)'
- ' p = MainForm.ClientToScreen(p1)'
- ' print p'
- ' p2 = MainForm.ScreenToClient(p)'
- ' self.assertEqual(p2.X, p1.X)'
- ' self.assertEqual(p2.Y, p1.Y)'
- ''
- ' def testObjectNotification(self):'
- ' DVar.IValue = 0'
- ' def ChangeHandler(Sender):'
- ' print Sender'
- ' Sender.IValue = 55'
- ' DVar.OnChange = ChangeHandler'
- ' if DelphiVersion >= 7:'
- ' DVar.TriggerChange()'
- ' self.assertEqual(DVar.IValue, 55)'
- ' DVar.OnChange = None'
- ' DVar.IValue = 0'
- ' DVar.TriggerChange()'
- ' self.assertEqual(DVar.IValue, 0)'
- ''
- ' def testActions(self):'
- ' self.assertEqual(MainForm.ActionList1.ActionCount, 1)'
- ' self.assertEqual(MainForm.ActionList1.Actions[0], MainForm.actTest)'
- ' self.assertEqual(MainForm.actTest in MainForm.ActionList1, True)'
- ' DVar.IValue = 0'
- ' MainForm.actTest.Execute()'
- ' self.assertEqual(DVar.IValue, 1)'
- ' def ActionHandler(Sender):'
- ' print "Action", Sender.Name, "executed from Python"'
- ' DVar.IValue = 2'
- ' self.assertEqual(MainForm.actTest.OnExecute, None)'
- ' MainForm.actTest.OnExecute = ActionHandler'
- ' self.assertEqual(MainForm.actTest.OnExecute, ActionHandler)'
- ' DVar.IValue = 0'
- ' MainForm.actTest.Execute()'
- ' self.assertEqual(DVar.IValue, 2)'
- ' MainForm.actTest.OnExecute = None'
- ' self.assertEqual(MainForm.actTest.OnExecute, None)'
- ''
- ' def testScreen(self):'
- ' self.assertEqual(Screen.DataModuleCount, 0)'
- ' self.assertEqual(Screen.FormCount > 0, True)'
- ' self.assertEqual(Screen.CustomFormCount > 0, True)'
- ' idx = -1'
- ' for i, f in enumerate(Screen.Forms):'
- ' if f == MainForm:'
- ' idx = i'
- ' break;'
- ' self.assertEqual(idx > -1, True)'
- ' self.assertEqual(Screen.Forms[idx], MainForm)'
- ' self.assertEqual(Screen.CustomForms[idx], MainForm)'
- ' self.assertEqual(Screen.Width > 0, True)'
- ' self.assertEqual(Screen.Height > 0, True)'
- ' MainForm.Button1.SetFocus()'
- ' self.assertEqual(Screen.ActiveControl, MainForm.Button1)'
- ' def ActiveControlChangeHandler(Sender):'
- ' print "ActiveControlChangeHandler fired"'
- ' print "New active constrol is", Sender.ActiveControl.Name'
- ' DVar.IValue = 2'
- ' self.assertEqual(Screen.OnActiveControlChange, None)'
- ' Screen.OnActiveControlChange = ActiveControlChangeHandler'
- ' self.assertEqual(Screen.OnActiveControlChange, ActiveControlChangeHandler)'
- ' DVar.IValue = 0'
- ' self.assertEqual(DVar.IValue, 0)'
- ' MainForm.Memo2.SetFocus()'
- ' self.assertEqual(DVar.IValue, 2)'
- ' Screen.OnActiveControlChange = None'
- ' self.assertEqual(Screen.OnActiveControlChange, None)'
- ' DVar.IValue = 0'
- ' MainForm.Button1.SetFocus()'
- ' self.assertEqual(DVar.IValue, 0)'
- ' if DelphiVersion >= 6:'
- ' m = Screen.MonitorFromPoint(Point(10, 10), mdNearest)'
- ' self.assertEqual(isinstance(m, Monitor), True)'
- ''
- ' def testPublished(self):'
- ' L = MainForm.__published__'
- ' self.assertEqual(len(L) > 0, True)'
- ' self.assertEqual(''Caption'' in L, True)'
- ' self.assertEqual(''OnShow'' in L, True)'
- ''
- 'if __name__ == ''__main__'':'
- ' try:'
- ' unittest.main()'
- ' except SystemExit:'
- ' pass'
- ' MainForm.ActiveControl = MainForm.Memo2 # Class property!'
- ''
- ' '
- ' '
- )
- ScrollBars = ssVertical
- TabOrder = 0
- end
- object Panel1: TPanel
- Left = 0
- Height = 41
- Top = 606
- Width = 668
- Align = alBottom
- BevelOuter = bvNone
- ClientHeight = 41
- ClientWidth = 668
- TabOrder = 1
- object Button1: TButton
- Left = 8
- Height = 25
- Top = 8
- Width = 75
- Caption = 'Execute'
- OnClick = Button1Click
- TabOrder = 0
- end
- end
- object Memo2: TMemo
- Left = 0
- Height = 169
- Top = 0
- Width = 668
- Align = alTop
- ScrollBars = ssBoth
- TabOrder = 2
- end
- object PyEngine: TPythonEngine
- IO = PythonGUIInputOutput1
- left = 16
- top = 16
- end
- object PythonModule: TPythonModule
- Engine = PyEngine
- Events = <
- item
- Name = 'TestFunction'
- OnExecute = PythonModuleEvents0Execute
- DocString.Strings = (
- 'doc for TestFunction'
- )
- end>
- ModuleName = 'spam'
- Errors = <>
- left = 56
- top = 16
- end
- object PythonGUIInputOutput1: TPythonGUIInputOutput
- UnicodeIO = False
- RawOutput = False
- Output = Memo2
- left = 168
- top = 17
- end
- object ActionList1: TActionList
- left = 96
- top = 80
- object actTest: TAction
- Caption = 'Test'
- OnExecute = actTestExecute
- end
- end
-end
diff --git a/demos_lazarus/Demo31/Unit1.pas b/demos_lazarus/Demo31/Unit1.pas
deleted file mode 100644
index 6a5b450..0000000
--- a/demos_lazarus/Demo31/Unit1.pas
+++ /dev/null
@@ -1,204 +0,0 @@
-unit Unit1;
-
-{.$I Definition.Inc}
-
-interface
-
-uses
- SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- StdCtrls, ExtCtrls, ComCtrls,
- PythonEngine, PythonGUIInputOutput, WrapDelphi, ActnList;
-
-type
- TForm1 = class(TForm)
- Splitter1: TSplitter;
- Memo1: TMemo;
- PyEngine: TPythonEngine;
- PythonModule: TPythonModule;
- Panel1: TPanel;
- Button1: TButton;
- PythonGUIInputOutput1: TPythonGUIInputOutput;
- Memo2: TMemo;
- ActionList1: TActionList;
- actTest: TAction;
- procedure Button1Click(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure PythonModuleEvents0Execute(Sender: TObject; PSelf,
- Args: PPyObject; var Result: PPyObject);
- procedure actTestExecute(Sender: TObject);
- private
- public
- PyDelphiWrapper : TPyDelphiWrapper;
- end;
-
-
-var
- Form1: TForm1;
-
-implementation
-
-{$R *.lfm}
-
-Uses
- TypInfo,
- Variants,
- VarPyth;
-
-
-//////////////////////////////////////////////////////////////////////////
-// Using TPyDelphiObject you can wrap any Delphi object exposing published
-// properties and methods. Note that the conditional defines TYPEINFO and
-// METHODINFO need to be on
-//////////////////////////////////////////////////////////////////////////
-
-{$TYPEINFO OFF}
-{$IFNDEF FPC}{$METHODINFO OFF}{$ENDIF}
-Type
-TTestBase = class
- fdouble : double;
- function DoubleDValue : double; // not visible in subclasses
-published
- property DValue : Double read fdouble write fdouble; // will be visible in subclasses
-end;
-
-function TTestBase.DoubleDValue : double;
-begin
- Result := 2 * fdouble;
-end;
-
-type
-{$TYPEINFO ON}
-{$IFNDEF FPC}{$METHODINFO ON}{$ENDIF}
-TTestClass = class(TTestBase, IFreeNotification)
-private
- fSValue : string;
- fIValue : integer;
- fSL : TStrings;
- fOnChange: TNotifyEvent;
- fFreeNotifImpl : IFreeNotification;
- // implementation of interface IUnknown
- function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
- function _AddRef: Integer; stdcall;
- function _Release: Integer; stdcall;
-protected
- property FreeNotifImpl : IFreeNotification read fFreeNotifImpl implements IFreeNotification;
-public
- constructor Create;
- destructor Destroy; override;
- procedure SetMeUp(S: string; I : Integer);
- function DescribeMe(): string;
- procedure TriggerChange;
-published
- property SL : TStrings read fSL;
- property SValue : string read fSValue write fSValue;
- property IValue : integer read fIValue write fIValue;
- property OnChange : TNotifyEvent read fOnChange write fOnChange;
-end;
-{$TYPEINFO OFF}
-{$IFNDEF FPC}{$METHODINFO OFF}{$ENDIF}
-
-constructor TTestClass.Create;
-begin
- inherited;
- fFreeNotifImpl := TFreeNotificationImpl.Create(Self);
- fSL := TStringList.Create;
- fSL.AddObject('Form1', Form1);
- fSL.AddObject('Form1.Button1', Form1.Button1);
-end;
-
-destructor TTestClass.Destroy;
-begin
- fSL.Free;
- inherited;
-end;
-
-procedure TTestClass.SetMeUp(S: string; I : Integer);
-begin
- SValue := S;
- IValue := I;
-end;
-
-function TTestClass.Describeme() : string;
-begin
- Result := fSValue + ' : ' + IntToStr(IValue);
-end;
-
-procedure TTestClass.TriggerChange;
-begin
- if Assigned(fOnChange) then
- fOnChange(Self);
-end;
-
-function TTestClass._AddRef: Integer;
-begin
- Result := -1; // we don't want reference counting
-end;
-
-function TTestClass._Release: Integer;
-begin
- Result := -1; // we don't want reference counting
-end;
-
-function TTestClass.QueryInterface(const IID: TGUID; out Obj): HResult;
-begin
- if GetInterface(IID, Obj) then
- Result := 0
- else
- Result := E_NOINTERFACE;
-end;
-
-{ TForm1 }
-
-procedure TForm1.Button1Click(Sender: TObject);
-var
- p : PPyObject;
-begin
- actTest.OnExecute := actTestExecute;
-
- // Wrap the Form itself.
- p := PyDelphiWrapper.Wrap(Self);
- PythonModule.SetVar( 'MainForm', p );
- PyEngine.Py_DecRef(p);
-
- // Now wrap the an instance our TestClass
- // This time we would like the object to be destroyed when the PyObject
- // is destroyed, so we need to set its Owned property to True;
- p := PyDelphiWrapper.Wrap(TTestClass.Create, soOwned);
- PythonModule.SetVar( 'DVar', p );
- PyEngine.Py_DecRef(p);
-
- {$IF DEFINED(FPC_VER) and (FPC_VER >= 5)}
- p := PyEngine.PyInt_FromLong(FPC_VER);
- {ELSE}
- p := PyEngine.PyInt_FromLong(4);
- {$IFEND}
- PythonModule.SetVar( 'DelphiVersion', p );
- PyEngine.Py_DecRef(p);
-
- // Excecute the script
- PyEngine.ExecStrings( memo1.Lines );
-end;
-
-
-procedure TForm1.FormCreate(Sender: TObject);
-begin
- PyDelphiWrapper := TPyDelphiWrapper.Create(Self); // no need to destroy
- PyDelphiWrapper.Engine := PyEngine;
- PyDelphiWrapper.Module := PythonModule;
- PyDelphiWrapper.Initialize; // Should only be called if PyDelphiWrapper is created at run time
-end;
-
-procedure TForm1.PythonModuleEvents0Execute(Sender: TObject; PSelf,
- Args: PPyObject; var Result: PPyObject);
-begin
- ShowMessage(VarPythonCreate(Args).GetItem(0));
- Result := PyEngine.ReturnNone;
-end;
-
-procedure TForm1.actTestExecute(Sender: TObject);
-begin
- Memo2.Lines.Add('Delphi event actTestExecute fired');
- Import('spam').DVar.IValue := 1;
-end;
-
-end.
diff --git a/demos_lazarus/Demo31/Unit2.lfm b/demos_lazarus/Demo31/Unit2.lfm
deleted file mode 100644
index b5979eb..0000000
--- a/demos_lazarus/Demo31/Unit2.lfm
+++ /dev/null
@@ -1,62 +0,0 @@
-object TestForm: TTestForm
- Left = 725
- Height = 341
- Top = 200
- Width = 614
- ClientHeight = 341
- ClientWidth = 614
- LCLVersion = '1.5'
- object CheckBox1: TCheckBox
- Left = 96
- Height = 22
- Top = 16
- Width = 91
- Caption = 'CheckBox1'
- TabOrder = 0
- end
- object CheckBox2: TCheckBox
- Left = 96
- Height = 22
- Top = 56
- Width = 91
- Caption = 'CheckBox2'
- Checked = True
- State = cbChecked
- TabOrder = 1
- end
- object btnClose: TButton
- Left = 88
- Height = 25
- Top = 256
- Width = 75
- Caption = 'Close'
- OnClick = btnCloseClick
- TabOrder = 2
- end
- object Edit1: TEdit
- Left = 96
- Height = 25
- Top = 96
- Width = 121
- TabOrder = 3
- Text = 'Edit1'
- end
- object ListBox1: TListBox
- Left = 328
- Height = 169
- Top = 48
- Width = 249
- ItemHeight = 0
- ScrollWidth = 247
- TabOrder = 4
- TopIndex = -1
- end
- object btnAdd: TButton
- Left = 104
- Height = 25
- Top = 128
- Width = 75
- Caption = 'Add'
- TabOrder = 5
- end
-end
diff --git a/demos_lazarus/Demo31/Unit2.pas b/demos_lazarus/Demo31/Unit2.pas
deleted file mode 100644
index 50181c7..0000000
--- a/demos_lazarus/Demo31/Unit2.pas
+++ /dev/null
@@ -1,42 +0,0 @@
-unit Unit2;
-
-{$MODE Delphi}
-
-interface
-
-uses
- SysUtils,
- Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls;
-
-type
- TTestForm = class(TForm)
- CheckBox1: TCheckBox;
- CheckBox2: TCheckBox;
- btnClose: TButton;
- Edit1: TEdit;
- ListBox1: TListBox;
- btnAdd: TButton;
- procedure btnCloseClick(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
-
-var
- TestForm: TTestForm;
-
-implementation
-
-{$R *.lfm}
-
-procedure TTestForm.btnCloseClick(Sender: TObject);
-begin
- Close;
-end;
-
-initialization
- RegisterClass(TTestForm);
-end.
-
diff --git a/demos_lazarus/Python_Console/formmain.pas b/demos_lazarus/Python_Console/formmain.pas
index dd24664..b2c989a 100644
--- a/demos_lazarus/Python_Console/formmain.pas
+++ b/demos_lazarus/Python_Console/formmain.pas
@@ -42,15 +42,15 @@ implementation
{$R *.lfm}
const
- cPyLibraryWindows = 'python37.dll';
- cPyLibraryLinux = 'libpython3.7m.so.1.0';
- cPyLibraryMac = '/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib';
- cPyZipWindows = 'python37.zip';
+ cPyLibraryWindows: string = 'python37.dll';
+ cPyLibraryLinux: string = 'libpython3.8.so.1.0'; //default in Ubuntu 20.x
+ cPyLibraryMac: string = '/Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7.dylib';
+ cPyZipWindows: string = 'python37.zip';
function Py_s0(Self, Args : PPyObject): PPyObject; cdecl;
begin
with GetPythonEngine do
- Result:= PyString_FromString('1.0.0');
+ Result:= PyUnicode_FromString('1.0.0');
end;
function Py_s1(Self, Args : PPyObject): PPyObject; cdecl;
@@ -58,7 +58,13 @@ function Py_s1(Self, Args : PPyObject): PPyObject; cdecl;
S0: string = 'begin.Привет.end';
begin
with GetPythonEngine do
- Result:= PyString_FromString(PChar(S0));
+ Result:= PyUnicode_FromString(PChar(S0));
+end;
+
+function Py_n1(Self, Args : PPyObject): PPyObject; cdecl;
+begin
+ with GetPythonEngine do
+ Result:= PyLong_FromLong(-100000);
end;
{ TfmMain }
@@ -83,6 +89,7 @@ procedure TfmMain.PythonModule1Initialization(Sender: TObject);
begin
AddMethod('s0', @Py_s0, '');
AddMethod('s1', @Py_s1, '');
+ AddMethod('n1', @Py_n1, '');
end;
end;
@@ -110,6 +117,8 @@ procedure TfmMain.InitFonts;
end;
procedure TfmMain.PythonEngineAfterInit(Sender: TObject);
+const
+ NTest: Longint = 1 shl 30;
var
dir: string;
begin
@@ -118,6 +127,9 @@ procedure TfmMain.PythonEngineAfterInit(Sender: TObject);
Py_SetSysPath([dir+'DLLs', dir+cPyZipWindows], false);
{$endif}
Py_SetSysPath([dir+'Py'], true);
+
+ //test for LongInt
+ //Caption:= BoolToStr(PythonEngine.PyInt_AsLong(PythonEngine.PyInt_FromLong(NTest)) = NTest, true);
end;
procedure TfmMain.DoPy_InitEngine;
@@ -133,5 +145,30 @@ procedure TfmMain.DoPy_InitEngine;
PythonEngine.LoadDll;
end;
+{$ifdef darwin}
+procedure InitMacLibPath;
+var
+ N: integer;
+ S: string;
+begin
+ for N:= 11 downto 5 do
+ begin
+ S:= Format('/Library/Frameworks/Python.framework/Versions/3.%d/lib/libpython3.%d.dylib',
+ [N, N]);
+ if FileExists(S) then
+ begin
+ cPyLibraryMac:= S;
+ exit;
+ end;
+ end;
+end;
+{$endif}
+
+initialization
+
+ {$ifdef darwin}
+ InitMacLibPath;
+ {$endif}
+
end.
diff --git a/demos_lazarus/Python_Thread/TestPyThread.lpi b/demos_lazarus/Python_Thread/TestPyThread.lpi
new file mode 100644
index 0000000..44596dc
--- /dev/null
+++ b/demos_lazarus/Python_Thread/TestPyThread.lpi
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demos_lazarus/Demo04/project1.lpr b/demos_lazarus/Python_Thread/TestPyThread.lpr
similarity index 72%
rename from demos_lazarus/Demo04/project1.lpr
rename to demos_lazarus/Python_Thread/TestPyThread.lpr
index c450b0c..2e862e4 100644
--- a/demos_lazarus/Demo04/project1.lpr
+++ b/demos_lazarus/Python_Thread/TestPyThread.lpr
@@ -1,4 +1,4 @@
-program project1;
+program TestPyThread;
{$mode objfpc}{$H+}
@@ -7,17 +7,12 @@
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
- Forms, Unit1;
+ Forms, Unit1, testThds
+ { you can add units after this };
-{$IFDEF WINDOWS}
-{$R project1.rc}
-{$ENDIF}
-{$IFDEF UNIX}
{$R *.res}
-{$ENDIF}
begin
- //{$I project1.lrs}
RequireDerivedFormResource:=True;
Application.Scaled:=True;
Application.Initialize;
diff --git a/demos_lazarus/Python_Thread/TestPyThread.res b/demos_lazarus/Python_Thread/TestPyThread.res
new file mode 100644
index 0000000..2a393ca
Binary files /dev/null and b/demos_lazarus/Python_Thread/TestPyThread.res differ
diff --git a/demos_lazarus/Python_Thread/testThread.py b/demos_lazarus/Python_Thread/testThread.py
new file mode 100644
index 0000000..5095c1a
--- /dev/null
+++ b/demos_lazarus/Python_Thread/testThread.py
@@ -0,0 +1,12 @@
+# coding: utf8
+# script for testing PythonThread
+# Jurassic Pork october 2020
+import time
+print('Coundown Thread1 :')
+time.sleep(1.0)
+i = 1
+while i < 5:
+ print('Thread1 : ',5 - i)
+ i += 1
+ time.sleep(1.0)
+print('Thread1 terminated')
diff --git a/demos_lazarus/Python_Thread/testthds.pas b/demos_lazarus/Python_Thread/testthds.pas
new file mode 100644
index 0000000..23b9a47
--- /dev/null
+++ b/demos_lazarus/Python_Thread/testthds.pas
@@ -0,0 +1,71 @@
+unit Testthds;
+
+ {$mode objfpc}{$H+}
+
+
+interface
+
+uses
+ Classes,
+ Graphics, ExtCtrls, Forms,
+ PythonEngine;
+
+type
+
+{ TTestThread }
+
+ TTestThread = class(TPythonThread)
+ private
+ FScript: TStrings;
+ running : Boolean;
+
+ protected
+ procedure ExecuteWithPython; override;
+ public
+ constructor Create( AThreadExecMode: TThreadExecMode; script: TStrings);
+ procedure Stop;
+ end;
+
+
+implementation
+
+
+{ TTestThread }
+
+constructor TTestThread.Create( AThreadExecMode: TThreadExecMode; script: TStrings);
+begin
+ fScript := script;
+ FreeOnTerminate := True;
+ ThreadExecMode := AThreadExecMode;
+ inherited Create(False);
+end;
+
+procedure TTestThread.ExecuteWithPython;
+begin
+ running := true;
+ try
+ with GetPythonEngine do
+ begin
+ if Assigned(fScript) then
+ ExecStrings(fScript);
+ end;
+ finally
+ running := false;
+ end;
+end;
+
+procedure TTestThread.Stop;
+begin
+ with GetPythonEngine do
+ begin
+ if running then
+ begin
+ PyEval_AcquireThread(self.ThreadState);
+ PyErr_SetString(PyExc_KeyboardInterrupt^, 'Terminated');
+ PyEval_ReleaseThread(self.ThreadState);
+ end;
+ end;
+end;
+
+
+end.
diff --git a/demos_lazarus/Python_Thread/unit1.lfm b/demos_lazarus/Python_Thread/unit1.lfm
new file mode 100644
index 0000000..3b806e1
--- /dev/null
+++ b/demos_lazarus/Python_Thread/unit1.lfm
@@ -0,0 +1,85 @@
+object Form1: TForm1
+ Left = 159
+ Height = 240
+ Top = 207
+ Width = 504
+ Caption = 'Thread Python Test'
+ ClientHeight = 240
+ ClientWidth = 504
+ OnCloseQuery = FormCloseQuery
+ object ScriptBtn: TButton
+ Left = 6
+ Height = 35
+ Top = 199
+ Width = 138
+ Anchors = [akLeft, akBottom]
+ Caption = 'Start script'
+ Font.CharSet = ANSI_CHARSET
+ Font.Color = clBlack
+ Font.Height = -16
+ Font.Name = 'Segoe UI'
+ Font.Pitch = fpVariable
+ Font.Quality = fqDraft
+ Font.Style = [fsBold]
+ OnClick = ScriptBtnClick
+ ParentFont = False
+ TabOrder = 0
+ end
+ object Memo1: TMemo
+ Left = 6
+ Height = 180
+ Top = 6
+ Width = 495
+ Anchors = [akTop, akLeft, akRight, akBottom]
+ ParentFont = False
+ ScrollBars = ssAutoBoth
+ TabOrder = 1
+ end
+ object ThreadBtn: TButton
+ Left = 166
+ Height = 35
+ Top = 199
+ Width = 176
+ Anchors = [akLeft, akBottom]
+ Caption = 'Start 3 threads'
+ Font.CharSet = ANSI_CHARSET
+ Font.Color = clBlack
+ Font.Height = -16
+ Font.Name = 'Segoe UI'
+ Font.Pitch = fpVariable
+ Font.Quality = fqDraft
+ Font.Style = [fsBold]
+ OnClick = ThreadBtnClick
+ ParentFont = False
+ TabOrder = 2
+ end
+ object StopThreadBtn: TButton
+ Left = 368
+ Height = 35
+ Top = 199
+ Width = 132
+ Anchors = [akRight, akBottom]
+ Caption = 'Stop threads'
+ Font.CharSet = ANSI_CHARSET
+ Font.Color = clBlack
+ Font.Height = -16
+ Font.Name = 'Segoe UI'
+ Font.Pitch = fpVariable
+ Font.Quality = fqDraft
+ Font.Style = [fsBold]
+ OnClick = StopThreadBtnClick
+ ParentFont = False
+ TabOrder = 3
+ end
+ object PythonEngine1: TPythonEngine
+ DllName = 'python38.dll'
+ DllPath = 'M:/dev/python38'
+ APIVersion = 1013
+ RegVersion = '3.8'
+ UseLastKnownVersion = False
+ InitThreads = True
+ PyFlags = [pfDebug, pfInteractive]
+ Left = 64
+ Top = 26
+ end
+end
diff --git a/demos_lazarus/Python_Thread/unit1.pas b/demos_lazarus/Python_Thread/unit1.pas
new file mode 100644
index 0000000..ebf6c2c
--- /dev/null
+++ b/demos_lazarus/Python_Thread/unit1.pas
@@ -0,0 +1,128 @@
+unit Unit1;
+
+{$mode objfpc}{$H+}
+
+
+interface
+
+uses
+ Classes, SysUtils, Forms, Controls,
+ Graphics, Dialogs, StdCtrls,strUtils,
+ PythonEngine,Testthds;
+
+type
+
+ { TForm1 }
+
+ TForm1 = class(TForm)
+ ScriptBtn: TButton;
+ ThreadBtn: TButton;
+ StopThreadBtn: TButton;
+ Memo1: TMemo;
+ PythonEngine1: TPythonEngine;
+ procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
+ procedure ScriptBtnClick(Sender: TObject);
+ procedure StopThreadBtnClick(Sender: TObject);
+ procedure ThreadBtnClick(Sender: TObject);
+
+ private
+ OwnThreadState: PPyThreadState;
+ ThreadsRunning: Integer;
+ procedure ThreadDone(Sender: TObject);
+ procedure InitThreads(ThreadExecMode: TThreadExecMode);
+
+
+ public
+ Thread1 : TTestThread;
+ Thread2 : TTestThread;
+ Thread3 : TTestThread;
+ end;
+
+var
+ Form1: TForm1;
+
+implementation
+
+{$R *.lfm}
+
+{ TForm1 }
+procedure TForm1.InitThreads(ThreadExecMode: TThreadExecMode);
+var script1,script2,script3 : TStringList;
+begin
+script1 := TStringList.Create();
+script2 := TStringList.Create();
+script3 := TStringList.Create();
+script1.LoadFromFile('testThread.py');
+ThreadsRunning := 3;
+Memo1.Clear;
+Memo1.Append('Starting 3 threads');
+with GetPythonEngine do
+ begin
+ OwnThreadState := PyEval_SaveThread();
+
+ Thread1 := TTestThread.Create( ThreadExecMode, script1);
+ Thread1.OnTerminate := @ThreadDone;
+ script2.Text := ReplaceStr(script1.Text,'Thread1','Thread2');
+ script2.Text := ReplaceStr(script2.Text,'(1.0)','(1.4)');
+ Thread2 := TTestThread.Create( ThreadExecMode, script2);
+ Thread2.OnTerminate := @ThreadDone;
+ script3.Text := ReplaceStr(script1.Text,'Thread1','Thread3');
+ script3.Text := ReplaceStr(script3.Text,'(1.0)','(1.9)');
+ Thread3 := TTestThread.Create( ThreadExecMode, script3);
+ Thread3.OnTerminate := @ThreadDone;
+
+end;
+ScriptBtn.Enabled := False;
+ThreadBtn.Enabled := False;
+StopThreadBtn.Enabled := True;
+
+end;
+procedure TForm1.ThreadDone(Sender: TObject);
+begin
+ Dec(ThreadsRunning);
+ if ThreadsRunning = 0 then
+ begin
+ Memo1.Append('all the threads Terminated');
+ GetPythonEngine.PyEval_RestoreThread(OwnThreadState);
+ ScriptBtn.Enabled := True;
+ ThreadBtn.Enabled := True;
+ StopThreadBtn.Enabled := False;
+ Thread1 := nil;
+ Thread2 := nil;
+ Thread3 := nil;
+ end;
+end;
+
+procedure TForm1.ScriptBtnClick(Sender: TObject);
+var script : TStringList;
+begin
+script := TStringList.Create();
+script.LoadFromFile('testThread.py');
+script.Text := ReplaceStr(script.Text,'Thread1','Script');
+Memo1.Clear;
+Memo1.Append('Starting Python Script');
+GetPythonEngine.ExecStrings(script);
+Memo1.Append('Python Script Terminated');
+end;
+
+procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: boolean);
+begin
+ CanClose := ThreadsRunning = 0;
+end;
+
+
+procedure TForm1.ThreadBtnClick(Sender: TObject);
+begin
+ InitThreads(emNewInterpreter);
+end;
+
+procedure TForm1.StopThreadBtnClick(Sender: TObject);
+begin
+ if Assigned(Thread1) and not Thread1.Finished then Thread1.Stop();
+ if Assigned(Thread2) and not Thread2.Finished then Thread2.Stop();
+ if Assigned(Thread3) and not Thread3.Finished then Thread3.Stop();
+end;
+
+
+end.
+
diff --git a/doc_original/Changes.txt b/doc_original/Changes.txt
deleted file mode 100644
index 9f18398..0000000
--- a/doc_original/Changes.txt
+++ /dev/null
@@ -1,1249 +0,0 @@
-This is the list of all changes since the first release:
-
-----------------------------------------------------------------------
-1.2 error handling in run component
-----------------------------------------------------------------------
-1.3 Inserted functionality and definitions got from
- Grzegorz Makarewicz
- mak@mikroplan.com.pl
- http://www.mikroplan.com.pl/home/mak/python
- Thank you for permission and help!
-----------------------------------------------------------------------
-1.4 Cleaning up, eliminating German comments, further tests
- Inserted some ideas from Andrew Robinson,
- andy@hps1.demon.co.uk
-----------------------------------------------------------------------
-1.5 Initialization String, some minor functionalities
-----------------------------------------------------------------------
-2.0 18/12/1997
- Extended by Morgan Martinet (mmm@imaginet.fr)
- The architecture of the system was changed a lot !
- See the text files (Documentation and tutorial) for more infos.
- * Works with Python 1.5 Beta 2
- * Renamed unit as PythonEngine
- * Cleaned the formatting of the source code
- * Reorganized some parts of the source
- * Reorganized the content of the components
- * Used exceptions instead of error variables
- * Suppressed the script, methods and InitModule of TPytRun,
- because there are new components for that.
- * We use the ExitProcess function instead of Halt, because
- Halt does not unload the Dlls before it leaves.
- * When defining methods, there's no need to add a blank method
- for the last one, because we allways allocate n+1 methods,
- and the new allocated data is allways cleared.
- * Renamed classes, in order to avoid name conflicts
- with the previous components, which can coexist:
- TDynDll --> TDynamicDll
- TPytDll --> TPythonInterface
- TPytRun --> TPythonEngine (It hosts the interpreter)
-
- * Added components
- TEngineClient
- TMethodsContainer
- TPythonType --> Lets you create a new Type object
- TPythonModule --> Lets you create a new module
- TPythonDelphiVar --> Lets you create Python variables
- that are bound to Delphi.
- TPythonOutput --> Works as a console for displaying
- Python outputs.
-
-----------------------------------------------------------------------
-2.01
- * Py_BuildValue modified to support floats thanks to Grzegorz Makarewicz
- * Renamed the functions Exec_command -> ExecString
- Eval_command -> EvalString
- * Added the functions EvalStringAsStr and EvalStringsAsStr
- * Added a delay mechanism for the output, in order to let threads write
- to output. There are 2 new functions in the module pyio:
- SetDelayWrites(1/0) -> (de)activates the delaying
- SetMaxLines(val) -> sets the # of lines of the output
- * Added 2 functions to convert Python objects to variants and vice versa:
- PyObjectAsVariant
- VariantAsPyObject
- VarRecAsPyObject
- * Removed the flag argument of the AddMethod procedure, because it must
- be always 1.
- * Checked if the VarName attribute of a TPythonDelphiVar does already
- exist and raise an exception.
- * Added functions CheckSyntax, CheckEvalSyntax, CheckExecSyntax.
- * Added functions MakePyTuple, MakePyList,
- ArrayToPyTuple, ArrayToPyList, ArrayToPyDict
- StringsToPyList, StringsToPyTuple,
- PyListToStrings, PyTupleToStrings
- * Added a function ReturnNone that returns a
- Py_None object, correctly incremented.
- * Extended the exception classes in Delphi that map the exceptions of Python.
- Now, there's a one to one maping.
-
-----------------------------------------------------------------------
-2.02 07/01/1998
- * modified Py_BuildValue to handle currencies as python doubles.
- * Added method TMethodsContainer.MethodWrap to call Delphi Methods
- from Python.
-
-----------------------------------------------------------------------
-2.03 09/01/1998
- * Removed MethodWrap and added AddDelphiMethod.
- I added a new type TDelphiMethod wich will constrain
- to declare a valid delphi method to pass to Python.
- Now it simplifies the declaration of a method, and it
- checks the type of the method passed.
- * Added Demo7 to show the new functionality of the Delphi
- methods. I show in this demo how to use ArrayToPyTuple
- in the getlong2 function.
-
-----------------------------------------------------------------------
-2.04 12/01/1998
- * Removed the DelphiObject argument of the AddDelphiMethod because
- it could be extracted from the DelphiMethod arg (look at the trick !).
-
-----------------------------------------------------------------------
-2.05 13/01/1998
- * Added a property APIVersion in order to use different versions of
- Python.
- * Added GetOfObjectCallBack in the MethodCallback.pas and used it in
- the AddDelphiMethod.
-
-----------------------------------------------------------------------
-2.06 27/01/1998
- * Changed how TPythonEngine checks if it already exists.
- Now you can open several forms containing each a TPythonEngine,
- but you can't drop 2 TPythonEngine on the same form, and when
- your application will execute it will check that there's only one
- instance of TPythonEngine.
- * Added a new property "ExecModule" that lets you specify in which
- module your code will be executed. By default it's "__main__".
- * Added a new system that lets you create new Python types with
- Delphi classes. So, you can use the inheritence and polymorphism
- in your Python types ! And it is more easier to build !
- * Changed the tutorial, and added a demo8 that shows you how to use
- the Delphi classes.
-----------------------------------------------------------------------
-2.07 02/02/1998
- * Added a property "AutoFinalize" to TPythonEngine that enables or not
- the call to Py_Finalize in the destructor of TPythonEngine.
- It's usefull for the Python modules as Dlls.
- * Added a Demo9 to show how to build a Python module as a Dll
- and explained it in the tutorial.
- * Changed TPythonType so that it automatically creates a variable
- containing the type and labelled with the TypeName in its
- linked module. Now you can check the type of an object like this:
- if type(obj) is spam.Point:
- ...
-----------------------------------------------------------------------
-2.08 05/02/1998
- * Changed the Input/Output mechanism thanks to Mark Watts.
- Renamed TPythonOutput as TPythonInputOutput. It is now a
- base class that can be derived in order to output on what
- you want (a RichEdit for instance).
- There are 2 new events OnSendData and OnReceiveData that let
- you send/receive data to/from Python where you want without
- deriving a new class. You can use it if you want to send
- the output to a file for debuging purposes.
- There's a new component TPythonGUIInputOutput that has a property
- Output that redirects the output to a RichEdit.
- * Changed all demos to reflect the new design.
- * Changed tutorial
- * Changed Demo9, use module.Initialize instead of module.MakeModule
- * cleaned up the "uses" part of the units. Used MessageBox instead of
- MessageDlg.
-----------------------------------------------------------------------
-2.09 08/02/1998
- * Added a property "Errors" to TPythonModule that lets you
- define python errors and then raise them easily with the
- 3 methods RaiseError, RaiseErrorFmt and RaiseErrorObj of TPythonModule.
- Errors is a collection of TError items.
- TError must have a Name (that will be used to define a string
- variable into the module). You can define the property "Text"
- that will define the content of the string error, if it is of type String.
- If you don't define it, then we will use the property "Name" instead.
- The property "ErrorType" lets you select between a String error or
- a class error. The latter has the advantage of containing instance variables
- that provide infos when we catch an error. And because of the class hierarchy,
- we can catch a parent class. So, if you define the ErrorType to etClass, then
- you can provide the name of the parent class. If it is empty, then there's no
- parent ! You can define in which module the parent class can be found (we will
- IMPORT this module, so it can be any module, internal or external), else it
- will use the module's name of the TPythonModule where the errors are located.
- * Changed demo8 to show the use of errors inside an object.
- * Updated tutorial.txt
- * Updated PyDelphi for the new input/output mechanism.
-----------------------------------------------------------------------
-2.10 12/02/1998
- * When the Name of an Error is changed, then we update all Errors that
- are derived from. We check if this Name does not already exist in the
- TError collection.
- * When the Module of an Error is changed, then we update all Errors that
- where referencing it.
- * Reactived the AddClient/RemoveClient of a TClientEngine when in
- design mode. It seems that there's no crash.
-----------------------------------------------------------------------
-2.11 19/03/1998
- * Corrected a bug in TMethodsContainer.ReallocMethods, because the
- function realloc did not clear the new allocated memory.
- * Imported function Py_malloc of the python15.dll
- * Made procedure TEngineClient.SetEngine virtual
-----------------------------------------------------------------------
-2.12 06/04/1998
- * Added PyFunction_Check to TPythonInterface
- * Added FindFunction, EvalPyFunction, EvalFunction and EvalFunctionNoArgs
- to TPythonEngine for a more sophisticated interface from Delphi
- to Python functions
-----------------------------------------------------------------------
-======================================================================
-----------------------------------------------------------------------
-3.00 29/11/1998
- Updated for compatibility to Delphi 4:
- * TPythonModule.Clients published -> public
- * TPythonDelphiVar.VarObject published -> public
- * PythonVCLStd not regenerated with VCL Generator to
- provide backward compatibility to Delphi 3.
-
- Following points conditional compiled with
- $IFDEF DELPHI4_OR_HIGHER (Delphi 4, Compiler VER120):
- * Included Definition.Inc to have central conditional defines.
- * Python_Controls,Delphi_Controls: uses ImgList added
- * Properties TCustomImageList.DragCursor and
- TCustomImageList.Dragging removed.
- * TDesigner in Python_Forms, Delphi_Forms deleted,
- because of missing in Delphi 4
-
- * Added all missing functions from Python/C API Reference Manual
- part "8. Initialization, Finalization, and Threads" except
- Py_GetCompiler (which is not exported by the DLL). The Py_GetPlatform
- is a cheat; the result will always be "win32" (even if running
- Delphi 5 under LINUX!). Py_Get(Exec)Prefix return empty strings!
- * PyFrameObject updated
- * PyInterpreterState and PyThreadState added.
- * Added Properties InterpreterState and ThreadState to TPythonEngine
- * Added published property InitThreads to PythonEngine.
- * Added TPythonThread class.
-----------------------------------------------------------------------
-3.01 25/05/1999
- * Fixed bug in method TPythonModule.Initialize
- the event OnInitialize was fired before the module was created
- * Added Date support in method TPythonEngine.VariantAsPyObject
- Any TDateTime type is converted to a tuple of the form:
- (year, month, day, hours, minutes, seconds, milliseconds)
- * Added Date support in method TPythonEngine.PyObjectAsVariant
- Any tuple of the form:
- (year, month, day, hours, minutes, seconds, milliseconds)
- is converted in a TDateTime
- * Added methods SetVar, GetVar, DeleteVar, SetVarFromVariant,
- GetVarAsVariant to the TPythonModule.
- They let you easily create/modify/read/delete vars inside a Python module.
- * Fixed a RefCount leak in ArrayToPyDict
- * Added Demo10 implementing new Python types mapping the VCL components
- TTable and TQuery for easy Database access from inside Python.
- * Added method FindClient to TPythonEngine
- * Fixed small bug in Repr method of a PyObject : it returned the
- classname of TPythonEngine instead of this of the TPyObject !
- * Fixed bugs with Number, Sequence and Mapping services : they were
- not available.
- * Fixed missing reference to the function Py_GetBuildInfo in python15.dll
- of Python 1.5.2
- --> full compatible with last version 1.5.2
- * Renamed package Python.dpk to Python_d3.dpk
- * Added package for Delphi 4 (Python_d4.dpk)
- * Removed references to the TPythonVCLStd when compiling with Delphi 4
-----------------------------------------------------------------------
-3.02 10/06/1999
- * Added global function PythonOK to test if the Python engine is
- created and valid.
- * Extended the VCL Generator. Now we support the methods call.
-----------------------------------------------------------------------
-3.03 13/06/1999
- * Fixed bug in method TPythonModule.Initialize
- The last fix from version 3.01 caused a bug !
- the event OnInitialize MUST be fired before the module was created
- because it's the place where you add the Module methods !
- I restored it as it was and I added a new event : OnAfterInitialize
- which lets you define vars inside the module after is has been created.
- * Added method InitializeForNewInterpreter to the TPythonModule which
- lets you initialize the module again in a new interpreter.
- Calling the method initialize could not work because it tested
- if the module was already created.
- * Added Demo11 which shows you the use of threads inside Python and Delphi.
- * Added property ThreadExecMode to TPythonThread class.
-----------------------------------------------------------------------
-3.04 25/06/1999
- * Added dynamic creation of the TRecentFiles component in PyDelphi
- in order to avoid its installation.
- * Added support of varArray and sequences in the VariantAsPyObject
- and PyObjectAsVariant conversion methods of TPythonEngine.
- Now a varArray is converted in a Python list of values, and a
- Python sequence (a list, a tuple or the like) is converted to
- an array of variant.
- * Extended Demo10 : added Locate and lookup support in example2
- * VCL Generator now supports generation for Delphi 4
-----------------------------------------------------------------------
-3.05 15/07/1999
- * Fixed a bug with TPythonDelphiVar found by Robert Ruehlmann :
- could not get type of object (print type(DelphiVar))
-----------------------------------------------------------------------
-3.06 01/09/1999
- * Extended Demo10 : added Range support in example2
- * Fixed a bug in Demo10 if we wanted to iterate on an
- empty table.
- * Fixed a bug in PyObjectAsVariant introduced in 3.04
-----------------------------------------------------------------------
-3.07 14/09/1999
- * In TPythonEngine.Destroy, use Py_Finalize first, before
- the finalization of modules, because Python frees objects
- stored in modules and this must happen prior to the destruction
- of their associated types.
- * Rewrote the TPythonDelphiVar using a Delphi class
- * Replaced the variant storage in a TPythonDelphiVar with
- a Python object. That way you can store any Python object.
- * Added two new events to TPythonDelphiVar that let you work
- with a Python object instead of a Variant:
- OnExtGetValue and OnExtSetValue
- * Added new property ValueObject to TPythonDelphiVar, which
- lets you access the object stored inside as a PPyObject.
- * Updated tutorial.txt
- * Updated Demo4
-----------------------------------------------------------------------
-3.08 16/09/1999
- * Added method IsVariantOk to TPythonDelphiVar wich checks if
- a variant is one of the standard types (integer, string...)
- * Fixed small bug in PyObjectAsVariant method of TPythonEngine,
- it didn't return a variant of type varNull if no compatible
- type was found, but returned instead a variant whose value
- was varNull.
- * Changed DateTime support as tuple to reflect the Python format
- (year, month, day, hour, min, sec, DayOfWeek, JulianDay, DayLight)
- according to a fix proposed by Jose Alberto Hernandis Talens
- (jhernandis@arrakis.es).
- * Added methods SetToList and ListToSet to TPythonEngine that
- let you convert a Delphi set to a Python list, or the opposite.
- * Added method IsDelphiObject to TPythonEngine which lets you
- test a Python object, in order to know if the underlying object
- is a Delphi class (that inherits from TPyObject).
- * Fixed a bug found in TPythonEngine.FindFunction:
- if the function was not found, Python raised an exception that
- was visible only on the next execution of a script.
- * Fixed a bug in the finalization of the Python engine:
- GetPythonEngine calls TPythonEngine.Initialized to check if Python
- is properly initialized, but Initialized calls Py_IsInitialized to
- check it, and this functions returns falls after a call to
- Py_Finalize.
- But Py_Finalize clears all modules and their attributes, which
- may call your object destructor, which will use some Python API
- but it will raise an exception because it will detect that
- Python is no more initialized !
- So, I've added a property to TPythonEngine (Finalizing) that
- GetPythonEngine will check before Initialized. If it's true
- (it is the case only when calling Py_Finalize), then no exception
- is raised.
- * Added a public method Finalize to TPythonEngine, that lets
- you finalize Python yourself, instead of waiting that
- the TPythonEngine object is destroyed by the form.
- * Extended Demo10
- * Checked compatibility with Delphi 5.
- It's fine : there was nothing to do ;-)
- * Added a package for Delphi 5
-----------------------------------------------------------------------
-3.09 29/09/1999
- * Added event OnPathInitialization to TPythonEngine that will let
- you define the Python path in the Windows Registry if it was not
- already done.
- * Updated tutorial.txt and added a warning in the Demo8
- * Added property DocString to the TPythonType that lets you define
- a documentation string for your type.
- * Added property DocString to the TPythonModule that lets you define
- a documentation string for your module.
- * Extracted the VCL Generator in an external project.
- * Added DocStrings to all types, modules and methods of
- the Demo10. Look at example2.
- * Added a test with IsDelphiObject in the function
- PythonToDelphi.
- * Introduced events in VCL Objects of Demo10
-----------------------------------------------------------------------
-3.10 11/10/1999
- * in function pyio_write, we forbid the printing of any other thread
- than the main thread, because we could not get to a stable state
- in multi-threading.
- * Added a docstring for the CreateXXX functions that instantiate
- a type XXX.
- * Added more events in Demo10
- * Added a new property __properties__ to the types mapping the
- VCL objects in Demo10, which returns a list of
- all available properties. It's like the __methods__ property
- but for the properties.
- * Added alias "__members__" to "__properties__"
- * Added properties InstanceCount, CreateHits, DeleteHits to
- the TPythonType, which keep track of the instances allocation.
- * Added function GetTypesStats to the pyio module, which will
- gather the stats of each type in a list of tuples.
- Look at Demo10, example5.
- * Added method CheckError to TPythonEngine.
- It simply checks if a Python error occurred and if yes, it
- prints the Python error and raises a Delphi exception.
- * NEW ! NEW ! NEW ! :
- Added PythonAtom unit from Olivier Deckmyn (olivier.deckmyn@mail.dotcom.fr)
- It lets you elegantly access any Python object as an Ole object !!!
- You can look at the Demo12 and PythonAtom.hlp
- * In Demo10, splitted file pyDatabase.pas in pyDB.pas and pyDBTables.pas
- to reflect the VCL unit names.
- * NEW ! NEW ! NEW ! :
- Added new component TPythonDatabase that implements the VCL units
- DB and DBTables for Database access. Look at Demo13.
- * Added Demo13 that shows the use of the TPythonDatabase component.
- It it the same demo as Demo10, but with the new component.
- * Added new package PythonVCL_d3.pkg for the TPythonDatabase component.
- * Added new package PythonVCL_d4.pkg for the TPythonDatabase component.
- * Added new package PythonVCL_d5.pkg for the TPythonDatabase component.
- * Updated readme.txt and tutorial.txt
-----------------------------------------------------------------------
-3.11 14/10/1999
- * Added Demo14 that builds a DLL module from the database components
- that will give you access to the database stuff from any Python application,
- even from the Python console.
- * Updated readme.txt and tutorial.txt
- * Added new property "Traceback" to TPythonEngine, which lets you
- browse the traceback after the execution of a Python script that
- raised an exception. This property is a TPythonTraceback object
- that contains a list of Items (TTracebackItem). Each item
- contains the filename, lineno and context informations.
- This list is automatically refreshed when using TPythonEngine
- execution methods, but if you use Python core API, you may call
- the Refresh methods at any time (but after the PyErr_Print function),
- or you should better call the CheckError method of TPythonEngine.
- * TPythonEngine.CheckError refreshes automatically the Traceback.
- * In design mode, each new droped EngineClient will automatically find
- a TPythonEngine and link to it through the Engine property.
-----------------------------------------------------------------------
-3.12 24/11/1999
- * In TPythonEngine.RemoveClient, we call TPythonEngine.Finalize, if running,
- in order to finalize the Python virtual machine BEFORE any TEngineClient
- is destroyed by Delphi, because if it occurrs prior to Py_Finalize, the destruction
- of a Python object which uses an already destroyed TEngineClient would cause
- a memory crash !
- * In PyObjectDestructor, we check if PythonOk before call the object destructor.
- This avoids crashes with Dlls.
- * Made some cleaning in all demos to work properly with Delphi5
- * Updated readme.txt and tutorial.txt
- * Made an installer that handles all the installation of Python for Delphi
- in all versions of Delphi (3 to 5).
-----------------------------------------------------------------------
-3.13 29/11/1999
- * Enhanced checking of date in TPythonEngine.PyObjectAsVariant
- * Added Demo15
- * Updated tutorial.txt
- * Changed representation string of a TPythonDelphiVar
- * Removed "Evaluate" button in all demos, except in Demo02.
- * In PyDelphi, used TPythonEngine.Traceback and fixed name collapse between
- form and type.
-----------------------------------------------------------------------
-3.14 08/12/1999
- * TPythonGUIInputOutput now supports any kind of TCustomMemo, it means that you
- can use a TMemo or a TRichEdit.
- * Changed Demo1 that uses a TMemo instead of a TReachEdit
- * Updated tutorial.txt
- * Changed Demo10 and Demo13: added example6 that shows how to subclass any
- Python object with a Proxy class.
- * Added file deployment.txt that gives some hints on deploying a Delphi application
- using Python.
- * Added Demo15, that presents 2 examples of interaction between Delphi and Python.
- These examples were posted on the Python for Delphi mailing list.
-----------------------------------------------------------------------
-3.15 25/02/2000
- * Enhanced method TPythonEngine.VariantAsPyObject: added support for multi-dimensional
- variant arrays (limited to 3 dimensions)
- * Added demo17 that shows the use of variant arrays of 2 dimensions.
- * Renamed TCallType constants to :
- TCallType = (ctSTDCALL, ctCDECL);
- in order to avoid a name conflict in C++ Builder.
- * Added C++ Builder compilation support, thanks to Sergey A. Kosmakov (sergek@etr.ru)
- * Added Demo18 for C++ Builder: shows how to use the python15.dll in a console app.
- * Added Demo19 for C++ Builder: it's a replicate of Demo05
- * Added Demo20 for C++ Builder: it's a replicate of Demo08
- * Updated tutorial.txt
- * Added file C++ Builder Notes.txt
- * Updated definition.inc
-----------------------------------------------------------------------
-3.16 29/11/2000
- * Fixed a small bug in CheckRegistry: if the registry key
- containing the path was not defined, it tried to write something
- even if the event OnPathInitialization was undefined.
- Under NT, if not administrator, it would raise an exception as
- it's forbidden to write under the HKEY_LOCAL_MACHINE without the
- admin rights.
- * Changed Dietmar's email: dbudelsky@web.de
- * Added method TPythonEngine.SetProgramArgs which will set the command line arguments transmitted
- to the application in the sys.argv list.
- * Added C++ Builder 5 packages
- * Added new property UseWindowsConsole to TPythonEngine, that lets you use a Windows Text console
- instead of a TMemo. If you set it to True, then don't use the RedirectIO !
- The main advantage is that it works very well with multi-threading !
- It works only if the property is set prior to loading the Python DLL.
- * Gene Chiaramonte (gchiaramonte@mail.com) fixed a bug in PythonAtom: the order of method arguments
- had to be reversed !
- * Sigve Tjora (public@tjora.no) fixed a reference counting bug in PythonAtom.
- * Sigve Tjora (public@tjora.no) made some interesting enhancements in PythonAtom:
- - allow pythonAtoms to be passed as arguments to python methods.
- Probably PythonDelphi variables can be used to, but it has not been tested.
- - allow results from pythonAtom methods to be used as arguments to other pythonAtom methods.
-
- * Sigve Tjora Updated demo12 to demonstrate the use of its new feature.
- * Mark Derricutt (mark@talios.com) added an "Events" collection for defining Python methods
- in a TPythonModule. This will ease the declaration of new methods !!!
- * Added Demo21 which introduces the new Events collection feature.
- * Added Demo22 which presents the new UseWindowsConsole property of TPythonEngine, and
- uses the new possibility to extract command line arguments.
- We execute a threaded program, which runs fine with the Windows console.
- With threaded programs, you must always take care that the calling thread finishes after all
- created threads ! This is easily done using the threading module and its "join" method.
- Note for Python 1.5.2 version :
- if you're using the "threading" module, you should do a TPythonEngine.Finalize in the
- OnClose event of your form, otherwise you'll get an access violation ! I don't know why ?
- It works fine with the new 1.6 or 2.0 versions.
- * Added Demo23 which is basically the same as Demo22, but uses the Delphi Log (since Delphi4) window
- for displaying Python output instead of using the Windows console. The main advantage is that you
- can scroll the log window, and save its content to a file, but the drawback is that you must
- run Delphi !
- * Updated tutorial.txt
- * allowed the possibility of doing Initialize/Finalize several times in TPythonEngine, in order
- to clear the engine memory.
- * Added property UseLastKnownVersion to TPythonEngine. If true, PythonEngine will attempt to load
- automatically the latest known Python dll.
- * Python for Delphi works fine with the latest version 1.6, and with the version 2.0
- But I couldn't generate a python20.lib file for the C++ Builder users ! So, just use the component
- which uses dynamic linking, and avoid the static linking of the Dll.
- * Python for Delphi installs correctly under Windows 2000.
- * Fixed a bug in TPythonModule.GetVar. If the var was not found, it would raise a Python exception
- the next time you execute a script.
- * Igor E. Poteryaev (jah@mail.ru) updated some new API definitions matching the new version 2.0
- * Added new methods to the TPyObject class for supporting new API introduced in version 2.0
- * Added 2 properties to TPythonEngine: GlobalVars and LocalVars.
- You can set a Python dictionary that will be used by the TPythonEngine.Run_CommandAsObject
- method. Set properties will increment the reference count of the object.
- * Sigve Tjora subclassed TPythonEngine (TAtomPythonEngine) in a new unit AtomPythonEngine.pas,
- because he had to use the PythonAtom.pas unit, and we don't want to use Com code in the
- PythonEngine.pas unit. The unit is added to the Python_d?.dpk package.
- * Stefan Franke [franke@meso.net] fixed a bug in PythonAtom.pas:
- when you called a Python function that returned a result and if you didn't assign the returned
- value to a Delphi variable, you would get an access violation.
- * Fixed a bug in PyObjectAsVariant: if the Python object was a class instance, that didn't implement
- the sequence API, it would raise a Python exception. Now, we check that the sequence API is
- properly implemented, and return a Null variant if not.
- * Added Demo25 made by Sigve Tjora for demonstrating the use of the TAtomPythonEngine.
-
-----------------------------------------------------------------------
-3.17b1 09/07/2001
- * Added compatibility with Python 2.1
- * Yuri Filimonov (fil65@mail.ru) fixed a bug in the asm code of Py_BuildValue: the EBX register was
- not correctly restored.
- * Added compatibility with Delphi6
- * Added unit VarPyth.pas that replaces the PythonAtom.pas, using the new variant custom types of D6.
- * In PythonEngine.pas, added functions:
- PyObject_DelItem
- PyObject_IsInstance
- PyObject_IsSubclass
- PySequence_Contains
- GetMainModule
- * Extracted the definition of the PYTHON symbols from PythonEngine.pas to Definition.inc
- * Added Demo25 that runs several unit tests for validating the new VarPyth.pas functionality.
- It's a good start to look at all that's possible...
-----------------------------------------------------------------------
-3.17b2 22/07/2001
- * Fixed a bug in TPythonEngine.PyObjectAsVariant thanks to cipherhaze@yahoo.com.au:
- the Python strings containing a zero were truncated when beeing converted
- to a variant.
-
- * in PythonEngine.pas:
- - added method TPythonEngine.PySequence_DelSlice
- - added var TPythonInterface.Py_OptimizeFlag
- - added var TPythonInterface.Py_InteractiveFlag
- - added var TPythonInterface.Py_NoSiteFlag
- - added var TPythonInterface.Py_TabcheckFlag
- - added var TPythonInterface.Py_UnicodeFlag
- - added property TPythonEngine.PyFlags that lets you enable some Python flags very easily,
- like Verbose mode, or Optimize, thanks to a thread started in the mailing list.
-
- * in VarPyth.pas:
- - added function VarAsPython --> cast a variant into a Python variant.
- - added function GetAtom --> compatibility mode with former PythonAtom.pas
- you can use the VarPyth unit instead of PythonAtom, and get the same behaviour of PythonAtom
- when instanciating the Python variants with the function GetAtom.
- Note however, that you must replace all your OleVariant types with Variant.
- You can test it on Demo12: in the uses statement, replace PythonAtom with VarPyth,
- and declare myAtom as a Variant, instead of OleVariant. That's all!
- But if you're instanciating the Python variants with VarPythonCreate, you'll get the new
- behaviour, so you can benefit from the 2 worlds, simultaneously!
- - added function len --> return the length of a collection. Same as the len function of Python
- and same as using the Length property or Length() method.
- So, len(obj) = obj.Length = obj.Length()
- - added function _type --> return the type object of a Python object
- - added function VarIsSameType --> checks if 2 python variants have the same Python type.
- - added function VarIsTrue --> return true if the variant is different from zero or None.
- This is the same as casting a variant to a boolean.
- - added function Ellipsis that can be used in GetSlice or SetSlice, if you don't want to specifiy
- explicitly the length of sequence. So, foo.GetSlice(2, Ellipsis) is equivalent with foo[2:]
- - added function BuiltinModule that returns the __builtin__ module object, that contains all
- the builtin functions that you can use directly:
- _hash := BuiltinModule.hash(foo)
- - added special method DelSlice for sequence objects, that does the same as: del list[x:y]
-----------------------------------------------------------------------
-3.17 27/08/2001 (final)
- * Added file py21.lib in the Components folder, it's the lib file for Python 2.1 that allows you
- to use the C native APIs of the Python dll.
- * Updated the C++ demos to use the py21.lib file
- * Updated include files with Python 2.1 version.
- * Updated file C++ Builder Notes.txt
- * Fixed a bug thanks to Gene Chiaramonte: when running an application with no component for Python output,
- an exception was raised while closing the form that hosted PythonEngine, because it tried to restore the initial streams,
- whereas no redirection was done.
- * Added function NewPythonTuple to VarPyth.pas
- * Updated Demo25: added a test for the dates.
- * Finished update for changes from version 2.1:
- - added enum bsRichCompare to set TBasicServices
- - added virtual method RichCompare to TPyObject
- - added property TypeFlags to TPythonType for setting new behaviours like tpfHaveRichCompare.
-----------------------------------------------------------------------
-3.18 02/11/2001
- * mitchchapman@earthlink.net fixed a bug in the VarPyth.pas unit: a crash occurred with some
- variants used by ref, with an integer value corresponding to the ID of the VarPython custom
- variant type.
- * Added access to the variable Py_NotImplemented that should be used in the new coercion model of
- version 2.1
- * Added Kylix support!!! But I have 1 issue:
- - the varargs functions don't work in Kylix (cf PyArg_Parse and PyArg_ParseTuple)
- * Started converting the demos to cross-platform usage: Demo01, 02, 03, 07, 09 and 25
- * Added new beta version 2.2 to the list of the known versions, and started implementing modifications:
- changed the record definitions of the PythonType object, and Code object, that caused a problem
- for parsing the traceback. Be sure to define the symbol PYTHON22 before including the definition.inc
- because I won't set it as a default until the 2.2 becomes official.
- Warning! The date module has introduced a new time_struct for storing a date/time value
- in new beta version 2.2.
- Maybe the traceback has changed also.
- * Added file "Kylix Notes.txt"
- * Made the code compatible with the last service pack update for Delphi 6.
-----------------------------------------------------------------------
-3.19 16/11/2001
- * Fixed Kylix port issue: the PyArg_Parse and PyArg_ParseTuple now work properly
- thanks to Stefan.Hoffmeister@Econos.de
- * Finished converting the demos to cross-platform usage: Demo04, 05, 06, 08, 11, 16, 17, 21, 22, 23.
- Note that the remaining demos are simply not portable (they use TTable or PythonAtom).
- * Continued implementation of the news from version 2.2 of Python.
- * Fixed some problems when using the PYTHONXX defines, thanks to Andy Bulka (abulka@netspace.net.au).
-----------------------------------------------------------------------
-3.20 08/01/2002
- * Fixed a ifdef bug in PythonEngine.pas
- * Fixed a bug in VarPyth.pas: when setting a property of a Python object, the assigned value
- was converted from/to a variant, even when it was a VarPython variant!
- * Added APIs for Long objects, and compatibility between Python long objects and Int64 variants.
- * Used new Python2.2 APIs for true division (/) and floor division (div) inside VarPyth.
- You can now override these behaviours inside your TPyObject classes.
- * Added Iter and IterNext new services of Python2.2 to TPythonType.
- * Added Traverse and Clear new services of Python2.0 to TPythonType (they are used with Garbage collection).
- * Added UNICODE support. A Python Unicode string is kept as wide string inside a variant.
- A variant is converted into a Python Unicode string only if the symbol PREFER_UNICODE is defined inside the
- file definition.inc
- Added APIs PyUnicode_FromWideChar, PyUnicode_AsWideChar
- Added methods Unicode_check, PyUnicode_AsWideString, PyUnicode_FromWideString
- Note that UNICODE was introduced in Python 2.0
- Note that it will work under Kylix, but I deactivated it as I've got a bug with the WideString conversions.
- * Added function VarPythonEval to VarPyth.pas, that returns a new Python variant from the evaluation of a Python
- expression. This is the same as VarPythonCreate(GetPythonEngine.EvalString(MyExpression))
- * Ready for the new time_struct object of Python 2.2 that replaces the tuple of 9 items, but that remains compatible
- with it.
- * Updated the list of Python exceptions, with their Delphi mapping, using version 2.2.
- * Updated set of Python flags up to Python 2.2
- * Changed the way of loading the latest version of Python when UseLatestKnownVersion is true:
- first we always start from the version which PythonForDelphi was compiled for, and if we don't find it we
- try to upgrade the version, only if the new version is compatible with the compiled version.
- So, if P4D was compiled for Python 1.5.2 it will only look for python15.dll, and won't try to use python22.dll.
- If P4D was compiled for Python 2.1.1 it will first look for python21.dll, then for python22.dll as it's compatible.
- * Rewrote the way to extract the traceback content by using PyObject_GetAttrString API instead of direct access to
- the traceback record object, to avoid compatibility issues between different versions of Python.
- * Added PyWeakRef and PyWrapper APIs, from Python 2.2.
- * Updated file "Kylix Notes.txt"
-----------------------------------------------------------------------
-3.21 06/03/2002
- * Fixed a compilation problem when using PYTHON15 symbol.
- * Added a default implementation of TCriticalSection for Delphi3 that misses the unit SyncObjs.pas.
- * Added property DllPath to specify a folder where the Python Dll should be searched. You can define this property
- at runtime, using the event OnBeforeLoad.
- * Fixed a bug with custom variants and Int64, introduced by the UpdatePack2 of Delphi6.
- * Modified installer to let the user choose a default version of Python before compiling the packages.
- * Fixed the WideString/Unicode bug in Kylix. In fact, it was not due to Borland but to Python itself! Python on Linux is supposed
- to use UCS2 strings, whereas it actually uses UCS4 strings!!!
- * Added a new define HAS_MODIFIED_DISPINVOKE to Definition.inc, to distinguish between Delphi6, Kylix1 and Kylix2, as Kylix2 uses
- a modified interface of the method DispInvoke of the custom variants, that has a PVarData parameter instead of a
- (var xxx : TVarData).
- * Updated file "Kylix Notes.txt"
- * Modified DispInvoke of the VarPyth unit.
- * PythonForDelphi is up and running with the latest versions of Delphi and Kylix (and Python),
- but note that there's a problem with Kylix2 (I used the OpenEdition): all compiles and works fine, but the IDE
- crashes when a form hosting PythonForDelphi components is closed! I don't know why, as it works fine with Kylix1
- and all Delphi versions! I'll have to investigate further...
-----------------------------------------------------------------------
-3.22 22/03/2002
- * Removed a warning when compiling PythonGUIInputOutput.pas, thanks to Mitch Chapman (mitchchapman@earthlink.net)
- * Updated Demo25, and allowed it to work with Python2.0 or higher.
-----------------------------------------------------------------------
-3.23 20/10/2002
- * Delphi7 Ready.
- * Fixed a nasty bug that occurred in some cases, but that should have always occurred. To allow multiple Finalize/Initialize
- sequences, I moved the ClearEngine loop from the Finalize method to the Destroy method of TPythonEngine.
- It was wrong, because when the TPythonEngine was destroyed it tried to call the ClearEngine method of each
- of its clients, that were usually already destroyed! The problem appears only when there are a lot of Python components,
- otherwise it seems that the memory allocated for the client component is still available for the process
- and thus doesn't cause an access violation. This bug was originally discovered by Dietmar.
- * Fixed a memory leak in unit VarPyth.pas, in function VarPythonEval
- * Fixed a memory leak in Demo25.
- * Problem with Kylix3: I can't get the package to compile because it fails with an internal error.
- However if you use the Python units inside a project it will compile without any problem! Anyway, I still
- have issues with the components in design time, because Delphi IDE freezes when closing a form hosting the
- components. So, it may be a workaround for both problems to dynamically create the Python components.
-----------------------------------------------------------------------
-3.24 29/01/2003
- * Fixed nasty bug that would freeze Kylix2 IDE (and maybe Delphi6/7 in some cases):
- in unit PythonGUIInputOutput.pas, method TPythonGUIInputOutput.Notification did not call inherited!
- * Fixed bug in PythonEngine.pas, in VariantAsPyObject when called by VarPyth.TPythonVariantType.VarDataToPythonObject.
- It caused a variant memory error when doing a dict.SetValue('key', ''); (empty string).
- Bug reported by Andy Bulka [abulka@netspace.net.au]
- * Added Python 2.3 compatibility:
- - new bool type: PyBool_Check, PyBool_FromLong
- - new date, time, datetime, delta... types from new datetime module
- - new property DatetimeConversionMode in TPythonEngine allowing to decide how a variant containing
- a datetime should be converted into a Python object.
- Presently there are only 2 modes: the default is dcmToTuple (a tuple containing year, month, day...)
- and starting with Python2.3 you get dcmToDatetime that will use the new datetime objects of the
- datetime module. I could not set it as default to avoid breaking existing code.
- - new exceptions: PyExc_FutureWarning, PyExc_PendingDeprecationWarning, PyExc_UnicodeDecodeError,
- PyExc_UnicodeEncodeError, PyExc_UnicodeTranslateError
-
- - new APIs (note that some of them were missing since previous Python versions):
- PyType_IsSubtype, PyObject_TypeCheck, PyBaseString_Check
- PyObject_GC_Malloc, PyObject_GC_New, PyObject_GC_NewVar, PyObject_GC_Resize,
- PyObject_GC_Del, PyObject_GC_Track, PyObject_GC_UnTrack
- PyType_IS_GC, PyObject_IS_GC
- PySlice_GetIndicesEx, PySlice_Check
- PyString_DecodeEscape, PyString_Repr
-
- - new behaviour:
-
- With Python2.3 the following functions return True if the Python object is the expected type or
- one of its descendants:
- PyString_Check
- PyFloat_Check
- PyInt_Check
- PyLong_Check
- PyTuple_Check
- PyList_Check
- PyDict_Check
- PyModule_Check
- PyUnicode_Check
-
- To check if a Python object is really (and only) the expected type then use the new functions instead:
- PyString_CheckExact
- PyFloat_CheckExact
- PyInt_CheckExact
- PyLong_CheckExact
- PyTuple_CheckExact
- PyList_CheckExact
- PyDict_CheckExact
- PyModule_CheckExact
- PyUnicode_CheckExact
-
- * in unit VarPyth.pas, added functions:
-
- VarIsSubtypeOf
- VarIsPythonDateTime
- VarIsPythonDate
- VarIsPythonTime
- VarIsPythonDateTimeTZ
- VarIsPythonDateTimeDelta
- VarIsPythonTimeTZ
- VarIsPythonTZInfo
- VarIsBool
- VarIsEnum
- DatetimeModule
-
- - updated Demo25 to reflect last additions made to VarPyth.pas
-
-
-----------------------------------------------------------------------
-3.25 5/04/2003
-
- * Added compatibility with Python 2.3b2 that refactored the new datetime module.
-
- * Allowed TPyObject instances to be created without a TPythonType, in order to use them outside
- P4D context (give nil as argument). This is a suggestion made by Gert Steyn [gert@ise.co.za]
-
- * Fixed a bug in TPythonType.TypeFlagsAsInt where some flags where forgotten
- (tpfHeapType, tpfBaseType, tpfReady, tpfReadying, tpfHaveGC)
- thanks to jacoboy1234 [fan_jacob@hotmail.com]
-
- * Added APIs PyObject_GenericGetAttr, PyObject_GenericSetAttr,
- PyType_GenericAlloc, PyType_GenericNew, PyType_Ready, PyObject_Free
-
- * Added new class TMembersContainer allowing TPythonType to define members of a type
- and added class method RegisterMembers to TPyObject, allowing type objects to define
- their members, to be used when subclassing an existing type.
-
- * Added new class TGetSetContainer allowing TPythonType to define properties with
- Get/Set accessor functions, and added class method RegisterGetSets to TPyObject,
- allowing type objects to define their properties, to be used when
- subclassing an existing type.
-
- * Allowed any TPythonType (and related TPyObject class) to become a base type
- that may be subclassed within Python.
- To use this feature, simply select tpfBaseType in the TypeFlags property of TPythonType,
- then override TPyObject.RegisterMembers in your Python/Delphi class and expose each
- of your instance member as a MemberDef (call AType.AddMember(...)).
- You can override TPyObject.RegisterGetSets in you need to expose properties
- with Get/Set accessor functions.
-
- You should not override GetAttr and SetAttr anymore and you should not
- select the Basic services flags [bsGetAttr, bsSetAttr].
- Instead, simply select the flags [bsGetAttrO, bsSetAttrO] and the class
- TPyObject does simply call PyObject_GenericGetAttr in GetAttrO
- and PyObject_GenericSetAttr in SetAttrO.
- The Python Generic Get/Set functions will use new slots introduced in
- the type object for specifying a list of members (class fields),
- a list of get/set functions (like properties in Delphi) and a list
- of methods. That way a subclass can introduce its own members/get,set/methods
- and call the others coming from the base classes.
-
- You can override the new Init method of TPyObject if you want to perform the same kind
- of initialization that you would do in the __init__ method of a Python class.
- Note however that by default the CreateWith constructor of TPyObject will be called
- when instanciating a new subtype, allowing you to get constructor arguments as you
- already did with regular types.
-
- Note that for a subtype instance, the memory allocated will come from
- Python heap and not from Delphi. So, we have a reserved space inside the subtype
- instance where we plug our Delphi class definition. This is tricky but it works!
-
- Note that TPyObject now has a new attribute IsSubType set to True when a subtype
- is instanciated.
-
- Note that if tpfBaseType is set, you can now instanciate a type by calling its type
- object instead of relying on the CreateXXX function. Ex: p = spam.Point(3, 2)
- In that case Python acts as it would create a subtype instance by using the
- tp_new slot of your type, but the type pointer given is the one of your TPythonType.
- So, your TPyObject instance will have memory allocated by Python (prop PythonAlloc
- is true) and the property IsSubType will be set to False.
-
- Note that to enable this double behaviour, I had to change the way a TPyObject is
- allocated: I removed the first two fields (ob_refcnt and ob_type) and replaced them
- with public properties, and redefined NewInstance and FreeInstance to
- allocate a bigger chunk of memory (with Sizeof(PyObject) more) and offseted the
- Self pointer to start after the PyObject header (containing the space reserved
- for the ob_refcnt and ob_type fields). So, when the ob_refcnt and ob_type properties
- access their associated data, they pick it from this extra hidden header.
- Note that when using GetSelf, it will return a pointer to the the start of this
- hidden header. And the Adjust method will correct Self to move after this header.
- Finally, in FreeInstance, we free the memory only if PythonAlloc is False.
-
- A B C
- +-------------------++------------------------------------------------------+
- | PyObject header || TPyObject class |
- +----------+--------++-----------------+------------+----------+------------+
- |ob_refcnt |ob_type ||hidden Class Ptr |PythonType |IsSubType |PythonAlloc |
- |integer |pointer ||pointer |TPythonType |Boolean |Boolean |
- |4 bytes |4 bytes ||4 bytes |4 bytes |1 byte |1 byte |
- +----------+--------++-----------------+------------+----------+------------+
-
- ^ ^
- | |
- ptr returned ptr returned by Adjust
- by GetSelf
-
- - a Python object must start at A.
- - a Delphi class class must start at B
- - TPyObject.InstanceSize will return C-B
- - Sizeof(TPyObject) will return B-A
- - The total memory allocated for a TPyObject instance will be C-A,
- even if its InstanceSize is C-B.
- - When turning a Python object pointer into a Delphi instance pointer, PythonToDelphi
- will offset the pointer from A to B.
- - When turning a Delphi instance into a Python object pointer, GetSelf will offset
- Self from B to A.
- - Properties ob_refcnt and ob_type will call GetSelf to access their data.
-
-
- Subclassing TPyObject in Delphi (TPyPoint = class(TPyObject))
-
- A B C D
- +-------------------++------------------------------------------------------+-----------------+
- | PyObject header || TPyObject class | TPyPoint class |
- +----------+--------++-----------------+------------+----------+------------+--------+--------+
- |ob_refcnt |ob_type ||hidden Class Ptr |PythonType |IsSubType |PythonAlloc |x |y |
- |integer |pointer ||pointer |TPythonType |Boolean |Boolean |integer |integer |
- |4 bytes |4 bytes ||4 bytes |4 bytes |1 byte |1 byte |4 bytes |4 bytes |
- +----------+--------++-----------------+------------+----------+------------+--------+--------+
-
- - TPyPoint.InstanceSize will return D-B
- - The total memory allocated for a TPyPoint instance will be D-A
- - The Python type object will have D-A in its tp_basicsize slot.
- - in RegisterMembers, calling
- PythonType.AddMember('x', mtInt, Integer(@TPyPoint(nil).x), mfDefault, 'x coordinate');
- will produce an offset of C-A, instead of C-B, because AddMember will add
- automatically B-A to the offset.
-
-
-
- Subclassing TPyPoint in Python (class MyPoint(spam.Point))
-
-
- A B C D E
- +-------------------++------------------------------------------------------+-----------------+---------+
- | PyObject header || TPyObject class | TPyPoint class | MyPoint |
- +----------+--------++-----------------+------------+----------+------------+--------+--------+---------+
- |ob_refcnt |ob_type ||hidden Class Ptr |PythonType |IsSubType |PythonAlloc |x |y |Dict |
- |integer |pointer ||pointer |TPythonType |Boolean |Boolean |integer |integer |pointer |
- |4 bytes |4 bytes ||4 bytes |4 bytes |1 byte |1 byte |4 bytes |4 bytes |4 bytes |
- +----------+--------++-----------------+------------+----------+------------+--------+--------+---------+
-
- - The total memory allocated for a MyPoint instance will be E-A
- - The Python type object will have E-A in its tp_basicsize slot.
- - The Python type object will have D-A in its tp_dictoffset slot (it is the tp_basicsize of
- the inherited type, accessible through tp_base).
- - The memory allocation is done by Python, that also initializes parts A-B and D-E,
- leaving us an available space between B and D. That's why we can't have the
- ob_refcnt and ob_type fields inside the TPyObject class definition, as they would
- appear in the free space available for the parent types and would not be used
- by Python. This would not be an issue, except for calculating the exact member offsets.
-
- So, hiding the PyObject header and ensuring this always comes first, makes it consistent
- in all cases for the member offsets to remain valid.
-
-
- * Added Demo26 to show how you can build base types (This is an adaptation of Demo8),
- and updated Tutorial.txt for giving some explanations to the new way of building
- types allowing subclassing.
-
- * Allowed a TPythonType to be dynamically created after everything has already been
- setup. It means that the module hosting the type will effectively have a variable
- referencing the new Type object and a CreateXXX function for creating new instances
- of that type.
-----------------------------------------------------------------------
-3.26 6/09/2004
-
- * Added compatibility with new version 2.4 of Python (Alpha presently)
- * Added new document "Deploying P4D.PDF" explaining how you can deploy your own version of Python (using a private folder).
- * Fixed a bug in PythonEngine.pas: when trying to convert a variant containing an empty string to a Python object,
- the application could crash with a Memory error exception.
- * Fixed a small memory leak when instanciating TPythonEngine at runtime, without an Owner, then TPythonEngine would leak
- and internal TPythonModule used for redirecting I/O. (thanks to t.handler@n-tree.com)
- * Fixed a problem in demo 16 / Example 1 (missing a __str__ override in the wrapper class)
-
-----------------------------------------------------------------------
-3.27 01/12/2004
- * added method flush when redirecting IO. This was fix made by Qi Wenmin (dumm@libr.3322.org):
-In my work I find a little problem with the RedirectIO feature. I enable the RedirectIO and add a stream handler of logging package to the logger. When I launch the script in Delphi, the engine reports the stream handler has no flush() method. So I make some change with PythonEngine.pas, add the following codes into the code constant in the TPythonEngine.DoRedirectIO method:
-
- * fixed a bug when the datetime module was not deployed, P4D would raise an exception while executing
- RedirectIO.
-
- * added new event OnSysPathInit to TPythonEngine. This event is fired immediately after Py_Initialize and
- will provide the list object stored in sys.path, containing all the folders used by Python to find
- an imported module.
- This will allow you to extend the path when you have a custom installation that is not allowed to touch
- the windows registry/filesystem.
- Example:
-
-procedure TForm1.PythonEngine1SysPathInit(Sender : TObject; PathList : PPyObject);
-var
- folder : PPyObject;
-begin
- with GetPythonEngine do
- begin
- folder := PyString_FromString('c:\myapp\mymodules');
- PyList_Append(PathList, folder);
- Py_XDecRef(folder);
- end;
-end;
-
- * fixed a bug: when using a Python iterator, eventhough you caught the stop exception, a 'Stop iteration' message was displayed in the output.
-
- * added function iter to VarPyth.pas that will return an iterator object for the specified container argument.
- Example:
-var
- _iter : Variant;
- _value : Variant;
-begin
- _iter := iter(VarPythonCreate([1, 2, 3, 4], stTuple));
- try
- while True do
- begin
- _value := iter.next();
- [...]
- end;
- except
- on E: EPyStopIteration do
- begin
- // End of sequence
- end;
- end;
-end;
-
- * added PyDict_Copy api
-
- * added overloaded ExecStrings/EvalStrings methods that let you provide your own global/local dictionaries.
- Note that you can still use the TPythonEngine properties LocalVars and GlobalVars.
-
- * added demo27 showing the possibilities of container indexing:
-#index:
-s[0]
-#slice
-s[0:2]
-#ellipsis
-s[...]
-#extended slice
-s[0:2:2]
-#multidimensional slice:
-s[10, 10:20, 20:100:5, ...]
-
- * added demo28 showing how to implement an iterator over a sequence (a simple TStringList wrapper)
-
- * added support for Delphi 2005
-----------------------------------------------------------------------
-3.28 23/04/2005
-
- * Fixed a bug in PyObjectAsVariant thanks to Kiriakos Vlahos [kvlahos@london.edu]
- Testing for Boolean values should be done before Integer values, as Boolean inherit from Integers.
-
- * Fixed a bug in ArrayToPyTuple, ArrayToPyList and ArrayToPyDict when giving empty string as argument
- thanks to Dietmar Budelsky.
-
- * Added demo 29 showing how to exchange images between Delphi and Python Imaging Library (PIL).
-
- * In PythonEngine.pas, added APIs:
- - PyObject_Call
- - PyErr_SetInterrupt
-
- * Added new feature to VarPyth: you can now invoke functions or methods using named parameters.
- A big advantage of named parameters over regular parameters is that the order of parameters is not important
- and help invoking functions with many optional parameters, as you can only specify the one you need.
- Note that any Python function can be invoked with or without named parameters, and that you can mix regular and named parameters.
-
-Python code:
-def MakeList(a, b, c):
- return [a, b, c]
-
-Delphi code:
-var
- _main : Variant;
- L : Variant;
-begin
- _main := MainModule;
- L := _main.MakeList(1, 2, 3); // L = [1, 2, 3] (this is the old way)
- L := _main.MakeList(1, c := 3, b := 2); // L = [1, 2, 3] Note that you can mix regular and named parameters.
- L := _main.MakeList(c := 3, a := 1, b := 2); // L = [1, 2, 3] Only named parameters
-
- * Added Demo30 to show how you can use named parameters.
-
- * Added Project PythonIDE thanks to a donation of Kiriakos Vlahos [kvlahos@london.edu].
- PyScripter was not designed to compete with other Python IDE tools
- but rather to serve the purpose of providing a strong scripting
- solution for Delphi Applications. However it is a reasonably
- good stand-alone Python IDE.
-
- Features:
-
- - Easy Integration with Delphi applications
- - Syntax Highlighting
- - Brace Highlighting
- - Python source code utilities ((un)tabify, (un)comment, (un)indent)
- - Code Explorer
- - File Explorer with filter
- - Easy configuration and browsing of the Python Path
- - Access to Python manuals through the Help menu
- and context sensitive help (press F1 on a Python keyword
- inside the editor)
- - Integrated Python Interpreter
- - Command History
- - Alt-UP : previous command
- - Alt-Down : next command
- - Esc : clear command
- - Code Completion
- - Call Tips
- - Integrated Python Debugging
- - Debug Windows
- - Call Stack
- - Variables Window
- - Watches Window
- - BreakPoints Window
- - Modern UI with docked forms
- - Persistent configurable IDE options
-
- Note that P4D only contains PythonIDE source code, but you can download a compiled version from
- http://mmm-experts.com/Downloads.aspx?ProductId=4
-
- If you want to rebuild it by yourself, you'll need to look at PythonIDE\Readme.txt for the required
- component packages.
-
- * Flagged GetAtom of PythonAtom.pas and TAtomPythonEngine of AtomPythonEngine.pas as deprecated when
- using Delphi 6 or later.
- You should replace TAtomPythonEngine by TPythonEngine and PythonAtom.pas by VarPyth.pas.
-
- Note that VarPyth and PythonAtom act differently. So, simply changing the unit may compile but
- your application may crash at runtime because PythonAtom converts Python sequences into variant arrays
- for instance, whereas VarPyth will keep the Python sequence object and let you act on it.
- See discussions in the yahoo group and Andy's tutorial about latest techniques:
- http://www.atug.com/andypatterns/PythonDelphiLatest.htm
-
- Converting TAtomPythonEngine is easy: open the form or datamodule hosting the component,
- View as text (Alt + F12), replace TAtomPythonEngine by TPythonEngine, View as Form (Alt + F12),
- in the unit, replace TAtomPythonEngine by TPythonEngine nad replace AtomPythonEngine by PythonEngine (in the uses).
- Save.
-
- Note that eventhough you get a deprecated warning, it still works as it is and you're not required to do the change.
- It's only better to do it for the future and for the additional benefits of VarPyth...
-
- * Updated file 'Deploying P4D.pdf' to refer to the Python tool that helps collect all module dependencies.
-
-----------------------------------------------------------------------
-3.29 28/08/2005
-
- * Fixed bug in TPythonType, reported by Roar Larsen [roar@tordivel.no], where a Access Violation would occur
- when exceeding 10 methods/getsets/members in a new base type (tpfBaseType option).
-
- * Fixed bug found by daydaysy [ildg@163.com] where VarIsPythonClass would
- return False when checking a new style Python class inheriting from object (class Foo(object): pass).
-
- * Used exported API for function PyImport_ExecCodeModule instead of duplicating code
-
- * Added APIs PyObject_GetIter, PyIter_Next and PyIter_Check to TPythonEngine
-
- * Added changes sent by Chris Nicolai :
- added PyThreadState_SetAsyncExc -- throw an exception into _another_ thread!!
- added new PyThreadState members from Python2.3
-
- * Addew new virtual class procedure SetupType to TPyObject, allowing the class to
- setup its associated Python type. This is very useful when building a hierarchy of classes,
- and thus avoiding copy&paste of the type services for each TPythonType. Instead, setup the type
- in the base class, and introduce in the subclasses the new services when they're implemented.
-
- * Added methods AddMethodWithKeywords/AddDelphiMethodWithKeywords to TPythonModule and TPythonType,
- allowing you to create functions receiving keyword parameters: foo(param1=val1, param2=val2...)
-
- * Added function VarPythonIsIterator to VarPyth.pas (and rewrote functions len and iter)
-
- * Added new component TPyDelphiWrapper originally written and donated by Kiriakos Vlahos [kvlahos@london.edu]
- It allows you to interact with Delphi VCL objects from Python. It works with Delphi5 or above.
- It also helps expose your own Delphi classes to Python more easily with Delphi 7 or later.
-
- Look at the documentation embedded at the beginning of the WrapDelphi.pas unit.
-
- * Added Demos 31 and 32 that show how you can benefit from WrapDelphi.
-
- * Added support for Free Pascal Compiler (http://www.freepascal.org/)
- and Lazarus Project (http://www.lazarus.freepascal.org/)
- Thanks to Michiel du Toit (micdutoit@hsbfn.com)
-
- * Added new folder "Modules" containing the folder "Delphi" which contains a Dll project for building
- a Python .pyd module in order to expose the VCL to a regular Python interpreter.
- Modules also constains a very simple Python script relying on Delphi.pyd for displaying a simple form.
- Note that you must ensure that Delphi.pyd is accessible from the Python path, before trying to run
- TestApp.py
-
-----------------------------------------------------------------------
-3.30 18/12/2005
-
- * Added function VarModuleHasObject to VarPyth.pas (done by Dietmar) to check if a module contains a specific object.
- * Fixed Bug in P4D that would prevent a script from printing unicode strings.
- * Made breaking change to TPythonEngine: the pyio module which is used to redirect input/output
- is not imported any more (pyio = __import__("pyio")) to avoid polluting the list of
- imported module (change made by Kiriakos Vlahos).
- * Included new release 1.3 of PyScripter source code.
- * Updated WrapDelphi:
- - Added new unit WrapDelphiWindows (to define a couple of symbols only)
- - Added new unit WrapDelphiComCtrls
- - Added new unit WrapDelphiGrids
- - Added new unit WrapDelphiGraphics
- - Added new unit WrapDelphiButtons
- - Wrapped TSize
- - Wrapped TCanvas, TGraphic, TBitmap, TMetaFile, TIcon, TPicture
- - Wrapped TKeyPressEvent, TKeyEvent
- - Made a breaking change when dealing with property sets:
- now we expect a sequence of strings. Each string should have the name as the enumeration in the set.
- Ex: MainForm.Anchors = ['akLeft', 'akTop']
- Of course, a set property will now return a list of strings.
- In the past, it would have returned an integer containing all the bits of the set,
- and it would have accepted to assign either the same kind of integer value or
- a string like "[akLeft, akTop]".
- - Made a breaking change when dealing with property enumerations:
- return a string representing its value instead of the ordinal value.
- - You don't need to call explicitely RegisterClass for your registered Python types as it will be done
- automatically for you in RegisterDelphiWrapper. But it is still usefull if you need to create VCL objects
- that have no wrapper, using the CreateComponent helper function.
- - Thanks to Fabio Chelly who used WrapDelphi, reported errors and contributed.
-
-----------------------------------------------------------------------
-3.31 5/3/2006
-
- * Added support for Delphi 2006
- * Updated WrapDelphi:
- - Wrapped TPageControl
- - Wrapped TTabSheet
- * Fixed a very rare but nasty bug thanks to Samuel Iseli - Vertec AG [samuel.iseli@vertec.ch]
- On some Windows Server 2003 machines, a P4D application using custom Types or Modules would
- crash. After investigation, Samuel found out that this was related to a Bios feature
- that would prevent code from running when the code was located on a memory page that was
- not flagged as executable. This was the case for all the generated callbacks that would
- wrap Delphi methods. After looking at Borland's solution regarding the MakeObjectInstance code
- we knew that we had do a VirtualAlloc(nil, PageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE).
- Samuel wrote a simple memory allocator using pages of virtual alloc, and replaced the old
- GetMem/FreeMem calls. And we could also get rid of the list of created callbacks as we have
- now our own custom allocator, which should speed up application's exit as we can free pages
- instead of blocks.
- * Simplified PythonEngine.pas to take into account an excellent suggestion of Samuel Iseli:
- the TPythonType was registering callbacks for each type's service, where the type's method
- would simply forward the work to the TPyObject instance. Instead of using callbacks,
- we can now use simple static functions which should also speed up a P4D application a little.
- * Added version 1.5 of PyScripter source code.
-
-
-----------------------------------------------------------------------
-3.32 8/10/2006
-
- * Added support for loading the Python 2.5. No change was introduced yet to take into account
- the 2.5 specificity.
- I had to disable the following 2 APIs which are not exported anymore: PyRange_New and PySymtableEntry_Type.
- I removed the exception PyExc_OverflowWarning.
- I added EPyBaseException exception and changed the hierarchy to reflect latest changes:
-
-BaseException # New in Python 2.5
-|- KeyboardInterrupt
-|- SystemExit
-|- Exception
- |- (all other current built-in exceptions)
-
-
- * Introduced a potential breaking change to P4D: the conditional symbol PREFER_UNICODE is now defined
- by default. Which means that any string stored in a variant will be converted to a Python unicode string.
- If you don't want that, then make sure that this symbol is not defined in definition.inc
- Note also that PyString_Check has been modified to accept unicode strings. If you want to
- discriminate, use PyString_CheckExact.
- * Kiriakos made changes to TPythonInputOutput to allow wide strings in I/O and thus support
- international chars. It introduces 2 news events OnSendUniData/OnReceiveUniData.
- This new behaviour will be activated only if you define the PREFER_UNICODE symbol and set
- the new UnicodeIO property.
- * Fixed bug into the new callback allocator thanks to Samuel Iseli. In some very rare cases,
- the empty space of a memory page was wrong and could crash the application.
- * Fixed a bug into TPythonEngine.PyObject_AsVariant that prevented a date to be converted
- to a real date variant. It was considered as a float, thanks to Oliver Bock .
- * Fixed a bug in TPythonEngine.PyObjectAsString when the submitted object is a unicode string.
- * Added api PySeqIter_New to TPythonEngine
- * Added api PyObject_CallMethodStr and PyObject_CallMethodWithArgs to TPythonEngine
- thanks to Dietmar Budelsky.
- * Added methods Repaint and Invalidate to the TControl wrapper
- * Added package files for C++Builder 6 thanks to Philippe BOURGAULT
- * Created a Wiki at http://py4d.pbwiki.com/ thanks to a suggestion of Oliver Bock
- This will allow any person involved with P4D to collaborate on building
- a useful documentation (at last ;-)
- * Added methods ClientToScreen and ScreenToClient to the TControl wrapper thanks to Joachim.
- * Added changes made by Samuel Iseli to WrapDelphiGrids:
- I added an indexed property for setting column widths (ColWidths[i]) and methods to get / set cell contents of stringgrid to the gridwrapper.
- I thought it was easier to do the cell get/set with separate methods GetCell(col,row), SetCell(col, row, value) instead of trying to imitate the Delphi 2dim array property (Cells[col, row]).
- * Made fields fDefaultIterType and fDefaultContainerType of TPyDelphiWrapper protected as a
- request made by Samuel Iseli.
- * Added new property "Version" to TPythonEngine returning the current version of P4D as a string as a
- request made by Roar Larsen.
diff --git a/doc_original/Deployment.txt b/doc_original/Deployment.txt
deleted file mode 100644
index adc9391..0000000
--- a/doc_original/Deployment.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-See document "Deploying P4D.PDF" first.
-
-When you want to distribute your Delphi application using Python,
-here's what you have to do:
-- install the whole Lib directory of the standard Python distribution
-(i.e. c:\program files\Python\Lib)
-This folder is necessary for the exceptions.py module that defines the Exception
-objects, if you're using them.
-Note that the file exceptions.py does not exist any more with versions of Python
-equal or greater than 2.0
-- optionally install the whole DLLs directory of the standard Python distribution
-(i.e. c:\program files\Python\DLLs)
-- install the python15.dll in the system folder
-- In your application, use the OnPathInitialization of the TPythonEngine
-and define the path with the Lib and DLLs folders you have installed. Add your
-own folders that contain your python modules.
-Note that each folder must be separated with a semi-colon (;) in the path string.
-
-That's all !
diff --git a/doc_original/Readme.txt b/doc_original/Readme.txt
deleted file mode 100644
index 6b99b7f..0000000
--- a/doc_original/Readme.txt
+++ /dev/null
@@ -1,137 +0,0 @@
-##############################################################
-## This is the Python for Delphi project ##
-##############################################################
-
-AUTHORS:
-~~~~~~~~
-Dr. Dietmar Budelsky
- dbudelsky@web.de
-
-Morgan Martinet
- 4723, Brebeuf
- H2J 3L2 MONTREAL (QC)
- CANADA
-
- e-mail: p4d@mmm-experts.com
-
-
-This project is the result of the merging of their two separate projects.
-
-PURPOSE:
-~~~~~~~~
- Provide an interface to the Python language in Delphi.
-
-COPYRIGHT:
-~~~~~~~~~~
- This source code is distributed with no WARRANTY, for no reason or use.
- Everyone is allowed to use and change this code free for his own tasks
- and projects, as long as this header and its copyright text is intact.
- For changed versions of this code, which are public distributed the
- following additional conditions have to be fullfilled:
- 1) The header has to contain a comment on the change and the author of it.
- 2) A copy of the changed source has to be sent to one of the above E-Mail
- addresses or our then valid address, if this is possible to the
- author.
- The second condition has the target to maintain an up to date central
- version of the components. If this condition is not acceptable for
- confidential or legal reasons, everyone is free to derive components
- or to generate a diff file to our or other original sources.
-
-FILES:
-~~~~~~
- Readme.txt This file.
- Python.txt Infos about Python, and further references.
- Changes.txt List of all changes since the first release.
- Tutorial.txt A simple tutorial to use the PythonEngine
- To do.txt A to do list.
- Deploying P4D.pdf Notes on the Deployment of your applications using Python for Delphi.
- C++ Builder Notes.txt Notes on using C++Builder with the Python for Delphi components.
- PythonAtom.hlp A help file explaining the use of TPythonAtom
- Demos A folder containing several demos of Python for Delphi.
- Components\Python.* The "Python for Delphi" packages.
- Components\Sources\Core The source folder of the core "Python for Delphi".
- Lib Library of Python modules.
- PythonIDE A Python developpment environment written in Delphi.
- See PythonIDE\Readme.txt for the required components.
- Modules Contains the Delphi\Delphi.dpr project that creates the Modules\Delphi.pyd Python module
- that allows you to interact with Delphi VCL objects from Python.
-
-INSTALLATION:
-~~~~~~~~~~~~~
- install the Python for Windows distribution (http://www.python.org/).
-
- 1) Install the core components
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- For Delphi 3, install the "Python_d3" package located in the Components folder
- and add the folder "...\Components\Sources\Core".
-
- For Delphi 4, install the "Python_d4" package located in the Components folder
- and add the folder "...\Components\Sources\Core".
-
- For Delphi 5, install the "Python_d5" package located in the Components folder
- and add the folder "...\Components\Sources\Core".
-
- For Delphi 6, install the "Python_d6" package located in the Components folder
- and add the folder "...\Components\Sources\Core".
-
- For Delphi 7, install the "Python_d7" package located in the Components folder
- and add the folder "...\Components\Sources\Core".
-
- 2) Install the VCL components (this is optional)
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- For Delphi 3, install the "PythonVCL_d3" package located in the Components folder
- and add the folder "...\Components\Sources\VCL".
-
- For Delphi 4, install the "PythonVCL_d4" package located in the Components folder
- and add the folder "...\Components\Sources\VCL".
-
- For Delphi 5, install the "PythonVCL_d5" package located in the Components folder
- and add the folder "...\Components\Sources\VCL".
-
- For Delphi 6, install the "PythonVCL_d6" package located in the Components folder
- and add the folder "...\Components\Sources\VCL".
-
- For Delphi 7, install the "PythonVCL_d7" package located in the Components folder
- and add the folder "...\Components\Sources\VCL".
-
- 3) Build PythonIDE (This is optional)
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- You can download the latest build of this application from
- http://mmm-experts.com/Downloads.aspx?ProductId=4
-
- If you want to rebuild PythonIDE by yourself, you must look at PythonIDE\Readme.txt
- for the required component packages to install first.
-
-
- 3) Build Modules\Delphi\Delphi.dpr (This is optional)
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- Once the project is build you can either extend the Python path with ..\Modules or
- copy ..Modules\Delphi.pyd to C:\Python24\DLLs, to be able to import the Delphi module
- from Python.
-
- Note that you can try this module by invoking the ..\Modules\TestApp.py script.
-
-NOTE:
-~~~~~
- Don't forget to look at the tutorial file (tutorial.txt) which introduces the
- demos.
-
- Visit the site http://starship.python.net/crew/mhammond/ and get the last version
- of Pythonwin. It's a really good Python IDE, that you must have for serious
- Python programming and debugging !
-
-UPDATE:
-~~~~~~~
- You'll find the latest version at http://mmm-experts.com/
-
-DISTRIBUTION:
-~~~~~~~~~~~~~
- You are free to distribute your applications built with Python for Delphi,
- but don't forget to install the python15.dll in the window\system folder of
- your client, or install the Python for windows distribution (it needs more
- space on the harddisk, but it's better because there are all Python modules
- and the help).
diff --git a/doc_original/Tutorial.txt b/doc_original/Tutorial.txt
deleted file mode 100644
index a3a3824..0000000
--- a/doc_original/Tutorial.txt
+++ /dev/null
@@ -1,840 +0,0 @@
-Using Python components.
-Here's a simple tutorial, each step is linked to a demo project (demoXXX)
-located in the Demos folder.
-
---------------------------------------------------------------
-1) A simple Python evaluator: (Kylix ready)
---------------------------------------------------------------
- Create a new Form
- Drop a TMemo (or a TRichEdit)
- Drop a TPythonGUIInputOutput for displaying Python's messages
- Drop a TMemo for the source code
- Drop a TPythonEngine
- Connect the attribute IO of the TPythonEngine to the TPythonGUIInputOutput.
- Connect the attribute Output of TPythonGUIInputOutput to the TRichEdit.
- Drop a TButton and call it "Execute script"
- Double-click on the button and add:
- PythonEngine1.ExecStrings( Memo1.Lines );
- That's all !
- Compile and execute.
- Write in the Memo1: print 2+2
- Click on the Execute button
- You should see in the Output window: 4
-
---------------------------------------------------------------
-2) Evaluate a Python expression (Kylix ready)
---------------------------------------------------------------
- WARNING !!! The evaluation of an expression works only for arithmetic expressions
- and not for instructions ! The use of variables and functions is of course allowed
- but constructs like for, def, class, print, import... are not allowed.
- Use Exec... instead (like ExecStrings).
-
- Create a new Form
- Drop a TMemo (or a TRichEdit)
- Drop a TPythonGUIInputOutput for displaying Python's messages
- Drop a TMemo for the source code
- Drop a TPythonEngine
- Connect the attribute IO of the TPythonEngine to the TPythonGUIInputOutput.
- Connect the attribute Output of TPythonGUIInputOutput to the TRichEdit.
- Drop a TButton and call it "Evaluate script"
- Double-click on the button and add:
- var
- Result : PPyObject;
- begin
- with PythonEngine1 do
- begin
- Result := EvalStrings( Memo1.Lines );
- if Assigned(Result) then
- begin
- ShowMessage(Format('Eval: %s',[PyObjectAsString(Result)]));
- Py_DECREF(Result);
- end
- else
- ShowMessage('Could not evaluate the script');
- // Or you could simply use:
- // ShowMessage('Eval: ' + EvalStringsAsStr( Memo1.Lines ) );
- end;
- That's all !
- Compile and execute.
- Write in the Memo1: print 2+2
- Click on the Execute button
- You should see in the Output window: 4
-
---------------------------------------------------------------
-3) Defining Python/Delphi vars (simple case): (Kylix ready)
---------------------------------------------------------------
- Warning ! If you access the Python/Delphi vars with
- the variant interface, you'll have to use simple types
- like integers, floats or strings.
- If you want to use any Python object type, don't use
- variants, but use the Extended interface OnExtGetData, OnExtSetData
- and the ValueObject property. But in this case, be careful with the
- reference counting ! Study carefully the Demo4 example.
-
-
- Drop a TPythonDelphiVar
- Connect its Engine attribute to PythonEngine1
- Change the name of the variable in the VarName attribute and set it to "test".
- Drop a Button and call it "Show var content"
- Double-click on it, and add:
- ShowMessage( 'Value = ' + PythonDelphiVar1.ValueAsString );
-
- Run the application, and type in the source window:
- varname.Value = 10
- print varname, varname.Value
- Click on the Execute button
- Click on the "Show var content button"
-
- So, you can read/write the variable's content in both Python and Delphi !
-
---------------------------------------------------------------
-4) Defining Python/Delphi vars (advanced case): (Kylix ready)
---------------------------------------------------------------
- Warning ! If you access to the Python/Delphi vars with
- the variant interface, you'll have to use simple types
- like integers, floats or strings.
- If you want to use any Python object type, don't use
- variants, but use the Extended interface OnExtGetData, OnExtSetData
- and the ValueObject property. But in this case, be careful with the
- reference counting ! Study carefully the Demo4 example.
-
- Use what you did at 3)
- Drop a TEdit component
- Click on the PythonDelphiVar1 object, show its events
- Double-click on the OnGetData attribute, and add:
- Data := Edit1.Text;
- Double-click on the OnSetData attribute, and add:
- Edit1.Text := Data;
- Double-click on the OnChange attribute, and add:
- with Sender as TPythonDelphiVar do
- ShowMessage( 'Var test changed: ' + ValueAsString );
- Add the following line to the private section:
- FMyPythonObject : PPyObject;
- Drop a TPythonDelphiVar
- Connect its Engine attribute to PythonEngine1
- Change the name of the variable in the VarName attribute and set it to "object".
- Double-click on the OnExtGetData attribute, and add:
- with GetPythonEngine do
- begin
- Data := FMyPythonObject;
- Py_XIncRef(Data); // This is very important
- end;
- Double-click on the OnExtSetData attribute, and add:
- with GetPythonEngine do
- begin
- Py_XDecRef(FMyPythonObject); // This is very important
- FMyPythonObject := Data;
- Py_XIncRef(FMyPythonObject); // This is very important
- end;
-
- Run the application, and type in the source window:
- print "Current value of var test is: ", varname
- varname.Value = "New value set by Python"
- print "-----------------------------------------------------"
- class C:
- def __init__(Self, Arg):
- Self.Arg = Arg
- def __str__(Self):
- return ""
- print "Current value of var object is: ", object
- object.Value = C("Hello !")
- print "New value is:", object
- Click on the Execute button, and look at the Edit1 component.
-
---------------------------------------------------------------
-5) Defining a new Module: (Kylix ready)
---------------------------------------------------------------
- Drop a TPythonModule
- Connect its Engine attribute to PythonEngine1
- Change the ModuleName attribute to "spam"
- Select its events, and Double-click on "OnInitialization" and add:
- with Sender as TPythonModule do
- AddMethod( 'foo', spam_foo, 1, 'foo' );
- Before the PythonModule1Initialization procedure, add:
- function spam_foo( self, args : PPyObject ) : PPyObject; cdecl;
- begin
- with GetPythonEngine do
- begin
- ShowMessage( 'args of foo: '+PyObjectAsString(args) );
- Result := Py_None;
- Py_IncRef(Result);
- end;
- end;
-
- Run the application, and type in the source window:
- import spam
- print spam.foo( "Hello", 1 )
- Click on the Execute button, and look at the Message dialog.
-
---------------------------------------------------------------
-6) Defining a new Type: (Kylix ready)
---------------------------------------------------------------
- A new type is more complex, because you must define a record
- that contains the objects attributes. It must always contain
- the two attributes at first:
- ob_refcnt : Integer;
- ob_type : PPyTypeObject;
- Drop a TPythonType
- Connect its Engine attribute to PythonEngine1
- Change the TypeName attribute to "MyObject"
- You must define procedures that will handle all kind of access
- to the object: Destructor, Get attribute, Set attribute, print...
- You must define its own methods
- You'll need a function in a module that will create an
- instance of that object.
- You must set the attributes of the Type record.
- Add the Objects's methods to the PythonType.
-
- Look at the demo6 for more information about this.
- There's a complete implementation of a new type
- object "Point", which contains two attributes (x and y),
- and one method (OffsetBy).
- The object is created by the function CreatePoint of
- the spam module.
-
---------------------------------------------------------------
-7) Using Delphi methods as Python functions (Kylix ready)
---------------------------------------------------------------
- This demo is the same as the previous one (6) but it introduces
- the use of Delphi methods instead of global functions for the
- python functions of Modules or Types.
-
- Note: Look at (21) for the new Events feature, which will ease the
- declaration of new Python functions.
-
---------------------------------------------------------------
-8) Using Delphi classes for new Python types (Kylix ready)
---------------------------------------------------------------
- Warning for Python version below 2.0:
- Python must be correctly installed otherwise this demo
- will fail. It needs indeed the file exceptions.py
- located in the lib folder of the Python distribution
- in order to initialize correctly the Exceptions as
- Python objects instead of strings.
- If you want to distribute your application with the
- Python Dll, don't forget to copy this file (and maybe the
- whole lib folder) and use the event OnPathInitialization
- of TPythonEngine to initialize properly your Python
- environment.
-
- Note: Look at (21) for the new Events feature, which will ease the
- declaration of new Python methods.
-
- Note: Loot at (26) if you're interested in building a new type that
- may be subclassed inside Python.
-
- Note: Look at (32) if you're using Delphi7 or later as it can make
- your life much easier when trying to expose a regular Delphi
- class to Python. See also the WrapDelphi.pas unit.
-
- Look at demo8, it's a default template that yous should follow
- if you want to build new Python types.
- Create a new project.
- Drop a TRichEdit
- Drop a TPythonGUIInputOutput for displaying Python's messages
- Drop a TPythonEngine on the form.
- Connect the attribute IO of the TPythonEngine to the TPythonGUIInputOutput.
- Connect the attribute Output of TPythonGUIInputOutput to the TRichEdit.
- Drop a TMemo
- Drop a TButton
- Double click on it and add:
- PythonEngine1.ExecStrings( Memo1.Lines );
- Drop a TPythonModule
- Change its property "ModuleName" to "spam"
- Connect it to the PythonEngine1
- Double-click on the property "Errors"
- Add an error
- name it "PointError"
- set it to etClass
- Add an error
- name it "EBadPoint"
- set it to etClass
- Double-click on "ParentClass"
- Set Name to "PointError"
- Drop a TPythonType
- Connect it to the PythonEngine1
- Change the property "TypeName" to "Point"
- Connect the property "Module" to the PythonModule1
- Define the services you'll use in the property "Services"
- Double-click on its event "OnInitialization" and add:
- PythonType1.PyObjectClass := TPyPoint;
- Add this code to the interface section of the unit:
- // This is a Delphi class implementing a new Python type
- // it must derive from TPyObject or one of its descendants.
- // Then it must override some methods, like the constructors,
- // the RegisterMethods and the type services' virtual methods.
- TPyPoint = class(TPyObject)
- x, y : Integer;
-
- // Constructors & Destructors
- constructor Create( APythonType : TPythonType ); override;
- constructor CreateWith( PythonType : TPythonType; args : PPyObject ); override;
-
- // Type services
- ////////////////
-
- // Basic services
- function GetAttr(key : PChar) : PPyObject; override;
- function SetAttr(key : PChar; value : PPyObject) : Integer; override;
- function Repr : PPyObject; override;
-
- // Class methods
- class procedure RegisterMethods( PythonType : TPythonType ); override;
-
- // Methods of TPyPoint
- procedure OffsetBy( dx, dy : Integer );
-
- // Interface methods
- function DoOffsetBy( args : PPyObject ) : PPyObject; cdecl;
- function DoRaiseError( args : PPyObject ) : PPyObject; cdecl;
- end;
-
- Add this code to the implementation section of the unit:
-
- // We override the constructors
-
- constructor TPyPoint.Create( APythonType : TPythonType );
- begin
- inherited;
- x := 0;
- y := 0;
- end;
-
- // Don't call the Create constructor of TPyPoint, because
- // we call the inherited constructor CreateWith that calls
- // the Create constructor first, and because the constructors
- // are virtual, TPyPoint.Create will be automatically be called.
-
- constructor TPyPoint.CreateWith( PythonType : TPythonType; args : PPyObject );
- begin
- inherited;
- with GetPythonEngine do
- begin
- if PyArg_ParseTuple( args, 'ii:CreatePoint', [@x, @y] ) = 0 then
- exit;
- end;
- end;
-
- // Then we override the needed services
-
- function TPyPoint.GetAttr(key : PChar) : PPyObject;
- begin
- with GetPythonEngine do
- begin
- if key = 'x' then
- Result := PyInt_FromLong( x )
- // Or Result := PyInt_FromLong( x )
- else if key = 'y' then
- Result := PyInt_FromLong( y )
- // Or Result := PyInt_FromLong( y )
- else
- Result := inherited GetAttr(key);
- end;
- end;
-
- function TPyPoint.SetAttr(key : PChar; value : PPyObject) : Integer;
- begin
- Result := 0;
- with GetPythonEngine do
- begin
- if key = 'x' then
- begin
- if PyArg_Parse( value, 'i:Point.SetAttr', [@x] ) = 0 then
- Result := -1;
- end
- else if key = 'y' then
- begin
- if PyArg_Parse( value, 'i:Point.SetAttr', [@y] ) = 0 then
- Result := -1;
- end
- else
- Result := inherited SetAttr(key, value);
- end;
- end;
-
- function TPyPoint.Repr : PPyObject;
- begin
- with GetPythonEngine do
- Result := PyString_FromString( PChar(Format('(%d, %d)',[x, y])) );
- // or Result := PyString_FromString( PChar(Format('(%d, %d)',[x, y])) );
- end;
-
- // Class methods
- // We register the methods of our type
-
- class procedure TPyPoint.RegisterMethods( PythonType : TPythonType );
- begin
- inherited;
- with PythonType do
- begin
- AddMethod( 'OffsetBy', @TPyPoint.DoOffsetBy, 'Point.OffsetBy( dx, dy )' );
- AddMethod( 'RaiseError', @TPyPoint.DoRaiseError, 'Point.RaiseError()' );
- end;
- end;
-
- // Methods of TPyPoint
- // They do the real actions on the object
- // It's better to split the functions that interface
- // Delphi to Python and the functions that do the
- // real implementation.
-
- procedure TPyPoint.OffsetBy( dx, dy : Integer );
- begin
- Inc( x, dx );
- Inc( y, dy );
- end;
-
- // Interface methods
- // They will be called directly by Python, so we extract the
- // python arguments and we call the method that will really do
- // the action.
-
- function TPyPoint.DoOffsetBy( args : PPyObject ) : PPyObject;
- var
- dx, dy : Integer;
- begin
- with GetPythonEngine do
- begin
- // We adjust the transmitted self argument
- Adjust(@Self);
- // first we extract the arguments
- if PyArg_ParseTuple( args, 'ii:Point.Offset', [@dx, @dy] ) <> 0 then
- begin
- // if it's ok, then we call the method that does the job
- // with the correct arguments
- OffsetBy( dx, dy );
- // Finally, we return nothing
- Result := ReturnNone;
- end
- else // the arguments were not right
- Result := nil;
- end;
- end;
-
- // Here's an example of how you can raise errors defined
- // in the module linked to our type.
- function TPyPoint.DoRaiseError( args : PPyObject ) : PPyObject;
- begin
- with GetPythonEngine do
- begin
- // We adjust the transmitted self argument
- Adjust(@Self);
- // This is a simple call:
- //GetModule.RaiseError( 'PointError', 'this is an example of raising an error !' );
- // This is an advanced call:
- // We provide the instance vars as a dictionary, so that we can intercept the
- // error with "except" and extract informations from the error object.
- // ArrayToPyDict needs a list of pairs: varName (string), varValue (anything)
- GetModule.RaiseErrorObj( 'EBadPoint', 'this is an example of raising an error !',
- ArrayToPyDict( ['a', 1, 'b', 2, 'c', 3] ) );
- Result := nil;
- end;
- end;
-
- Compile and execute this application, then type in the memo
- the following text and execute it:
- import spam
- p = spam.CreatePoint(2, 5)
- print p
- p.OffsetBy( 3, 3 )
- print p.x, p.y
- print dir(spam)
- print spam.Point
- print "p = ", p, " --> ",
- if type(p) is spam.Point:
- print "p is a Point"
- else:
- print "p is not a point"
- p = 2
- print "p = ", p, " --> ",
- if type(p) is spam.Point:
- print "p is a Point"
- else:
- print "p is not a point"
- p = spam.CreatePoint(2, 5)
- try:
- print "raising an error of class EBadPoint"
- p.RaiseError() # it will raise spam.EBadPoint
- except spam.PointError, what: #it shows you that you can intercept a parent class
- print "Catched an error derived from PointError"
- print "Error class = ", what.__class__, " a =", what.a, " b =", what.b, " c =", what.c
-
- # You can raise error from a Python script to !
- print "------------------------------------------------------------------"
- print "Errors in a Python script"
- try:
- raise spam.EBadPoint, "this is a test !"
- except:
- pass
-
- try:
- err = spam.EBadPoint()
- err.a = 1
- err.b = 2
- err.c = 3
- raise err
- except spam.PointError, what: #it shows you that you can intercept a parent class
- print "Catched an error dirived from PointError"
- print "Error class = ", what.__class__, " a =", what.a, " b =", what.b, " c =", what.c
-
-
-
---------------------------------------------------------------
-9) Making a Python module as a Dll (Kylix ready)
---------------------------------------------------------------
- The demo9 contains 2 delphi projects: one for the application
- and one for the dll. The dll extension is renamed as ".pyd".
- The application script does an "import demodll" that will try
- to find first an internal module, then a "demodll.dll" or a
- "demodll.pyd".
- Python executes a procedure named initXXX in the dll, where
- XXX must be the name of the module (in this case it will be
- "demodll"). So, your dll must export only one procedure like this:
- procedure initXXX; cdecl;
-
- In the function initXXX of our DLL, we create an instance of
- TPythonEngine and we define its property "AutoFinalize" to False,
- because TPythonEngine must absolutely not call the function
- Py_Finalize. After you call its method LoadDll.
- Then we create an instance of TPythonModule, we setup its name,
- the engine used, add the methods and finally call Initialize.
- At last, you add a finalize section in order to free the two instances.
-
- WARNING !!! Python cares about letter case, so check if the
- resulting Dll is "demodll.pyd", all in lowercase, otherwise
- the "import demodll" statement won't find the module.
-
---------------------------------------------------------------
-10) Mapping Delphi VCL components inside Python.
---------------------------------------------------------------
- Full mapping of TTable and TQuery that lets you access
- Database from inside Python as you would do it with Delphi.
-
- Look at the demo, I tried to put some comments and I think it is
- self-explicit.
-
- It shows you how you can use Delphi class inheritence for
- making new Python types and avoid duplication of code.
-
- It shows you how to use some special object services like
- sequences.
-
- It shows you how you can subclass any Python object, using
- a Proxy class (see example 6).
-
---------------------------------------------------------------
-11) Using Threads inside Python. (Kylix ready)
---------------------------------------------------------------
- Demonstrates how you can execute python code that interacts with
- Delphi in threads.
-
---------------------------------------------------------------
-12) Using PythonAtom. (Deprecated since Delphi 6, See VarPyth instead)
---------------------------------------------------------------
- Look at Demo12
-
- Simply add the PythonAtom in the uses clause, declare a new var of type OleVariant
- and call the function getAtom( any Python object ). It will return a new OleVariant
- that will let you access properties or methods very simply, as you would do with Word !
-
- var
- pObject : PPyObject;
- myAtom : OleVariant;
- myString : String;
- begin
- pObject := ... a python object ...(using a TPythonDelphiVar.ValueObject for example);
- myAtom := getAtom(pObject); // This is the magic object
- myAtom.myMethod();
- myString := myAtom.myProperty.myProperty2;
- myAtom.myProperty.myProperty3:='Olivier';
- ShowMessage(myAtom.myMethod2('Olivier'));
- ShowMessage(myAtom.myListProperty[3]);
- // Or anything ! Note that type conversion are automatic !
- end;
-
- Note that if you use TPythonDelphiVar.ValueObject, you must decrement the reference on
- the returned object !
-
---------------------------------------------------------------
-13) Using TPythonDatabase.
---------------------------------------------------------------
- Look at Demo13
-
- This demo is based on the Demo10, but uses the TPythonDatabase
- component that was built from the Demo10, in order to let
- you easily access a Database from Python.
-
---------------------------------------------------------------
-14) Making a Dll with TPythonDatabase
---------------------------------------------------------------
-
- Here's how you can make a Dll that will contain the Database components
- in order to let you access a database from any Python application, even
- from the Python console !
-
- Please, compile the database.dpr project prior to Project1.dpr !
-
- If you want to use this module, from anywhere, you must copy the file
- database.pyd in a folder that's in Python's path, like ...\Python\Lib
-
- WARNING !!! Python cares about letter case, so check if the
- resulting Dll is "database.pyd", all in lowercase, otherwise
- the "import database" statement won't find the module.
-
---------------------------------------------------------------
-15) Using a TDataset descendant with Python, except TTable and TQuery.
---------------------------------------------------------------
-
- If you're using a special Dataset object, like TClientDataset or
- a FlashFiler table, this demo is for you !
- Note, that this will only allow you to use the TDataset interface and
- not the methods introduced in the TDataset subclass ! If you need to,
- then study the unit pyDBTables.pas and do the same as we do for a
- TTable or a TQuery !
-
- Add the pyDB unit to your uses clause.
- In the module event OnAfterInitialization, of your dedicated module,
- or simply just before you execute your instructions, do the following things:
-
- - Instanciate your Delphi dataset subclass: ds := TClientDataset.Create(nil);
- - Initialize it properly: ds.DatabaseName := 'DBDemos';
- ds.TableName := 'animals.dbf';
- ds.Active := True;
- - Create the Python interface: obj := NewDataset(ds, True)
- where 'True' means that the Python wrapper will own the delphi dataset object and
- free it. It avoids memory crashes if the TDataset subclass is destroyed
- before the Python engine is finalized. If you encounter such a problem,
- you can use the PythonEngine1.Finalize explicit method before any object is
- destroyed in your form.
- - Define a var containing our object : PythonModule1.SetVar( 'Dataset', obj );
- where PythonModule1 is the TPythonModule object you want to use
- 'Dataset' is the var name in the module that will contain our dataset object
- obj contains the Python object interface
- - Don't forget to decrement 'obj': GetPythonEngine.Py_XDecRef(obj);
-
- This demo shows you how to add a function to your module, that will allow your
- Python script to create its own instances of the Dataset subclass (look at the
- DoCreateTable function).
-
---------------------------------------------------------------
-16) Using a TDelphiVar or Module methods ? (Kylix ready)
---------------------------------------------------------------
-
- Here are examples of 2 differents solutions that let you read/write properties stored
- in your Delphi application (this examples were posted on the Python for Delphi
- mailing list) :
- - The first example uses a DelphiVar that contains a dictionary.
- - The second example uses a new modules (props) that publishes 3 functions
- GetProperty, SetProperty and GetPropertyList
-
- In both examples, I show you how you can simplify any implementation with a
- Proxy class that will use either the DelphiVar or the module functions.
-
-
---------------------------------------------------------------
-17) Using variant arrays of 2 dimensions (Kylix ready)
---------------------------------------------------------------
-
- This demo creates a variant array of 2 dimensions, then
- converts it to a Python object (a list of sub lists) with
- the method VariantAsPyObject.
- The Python list is then converted back to a variant array with
- PyObjectAsVariant, but notice that it is not an array of 2 dimensions,
- but an array of variant arrays.
- Because when PyObjectAsVariant converts a Python sequence it returns
- a variant array and this method is recursive. So, if we have another
- sequence as an item, we'll get an array that will be stored in the
- array.
- This way lets you have any depth of sub-sequences, but you can only
- convert 1, 2 or 3 dimensions variant arrays to Python sequences.
-
---------------------------------------------------------------
-18) C++ Builder: using the Python Dll in a console application
---------------------------------------------------------------
-
-Create a new project application using the console
-Edit the project options and adds the folder \Components\Include to
-the Include directory.
-Adds #include at the beginning of your source
-followed by: using namespace Py;
-Drop the py15.lib to your project folder and add it to the project
-Write Python code and compile !
-
---------------------------------------------------------------
-19) C++ Builder: this is a replicate of the Delphi Demo05
---------------------------------------------------------------
-
---------------------------------------------------------------
-20) C++ Builder: this is a replicate of the Delphi Demo08
---------------------------------------------------------------
-
---------------------------------------------------------------
-21) Using Events in TPythonModule or TPythonType (Kylix ready)
---------------------------------------------------------------
-
-This demo is inspired of the demos 7 and 8, but uses the new feature of the TPythonModule
-and TPythonType: now there's a collection property called Events, which lets you add
-easily your own Module functions, or Type methods.
-Simply double click on the Events property, then add a new CollectionItem, name your event, add
-a DocString if you want to document your function, and double click on the OnExecute event,
-then write the code to implement your function. That's all !
-Note the difference with a TPythonType: you don't use the Adjust procedure, put simply use the
-PythonToDelphi function to convert the PSelf argument to a Delphi instance pointer.
-
---------------------------------------------------------------
-22) Using Threading, Windows Console and Command line arguments (Kylix ready)
---------------------------------------------------------------
-When doing multithreading, be sure that the calling thread finishes after all created threads,
-otherwise your application will hang ! This is easily done by using the threading module of the
-standard Python distribution, and calling the "join" method of the thread objects.
-
-If you want to display messages in your threads, you can't use the PythonForDelphi redirection to
-a memo, as the VCL is not thread safe !
-So, a simple way is to use the new TPythonEngine.UseWindowsConsole property which will use a
-Windows threadsafe console.
-
-In this demo, we use the sys.argv list which contains the command line arguments.
-
-Note for Python 1.5.2:
-if you're using the threading module, you should do a TPythonEngine.Finalize in the
-OnClose event of your form, otherwise you'll get an access violation ! I don't know why ?
-Because it works fine with new 1.6 version !
-
---------------------------------------------------------------
-23) Using Threading and Delphi log window. (Kylix ready)
---------------------------------------------------------------
-This is the same demo as Demo22, but we use the Delphi log window for displaying Python output,
-instead of the Windows console.
-The main advantage is that you can scroll the log window, and save its content to a file,
-but the drawback is that you must run Delphi !
-
-To do it, you must drop a TPythonInputOutput component (instead of the TPythonGUIInputOutput),
-connect it to the TPythonEngine through the IO property, double-click on the TPythonInputOutput.OnSendData
-event and write:
-
-procedure TForm1.PythonInputOutput1SendData(Sender: TObject;
- const Data: String);
-begin
- OutputDebugString( PChar(Data) );
-end;
-
---------------------------------------------------------------
-24) Using TAtomPythonEngine (Deprecated since Delphi 6, See VarPyth instead)
---------------------------------------------------------------
-This demo describes how you can make Delphi methods that are going to be
-used from python without even thinking about conversion and reference
-counting by the use of PythonAtoms and AtomPythonEngine. The Demo is a
-modified version of Demo 5, but the techniques described here can be used
-in aspects of python/delphi programming as well.
-
-The demo describes the use of the PyObjectAsVariant method defined in
-AtomPythonEngine. It returns PythonAtoms when the Python object isn't of a
-standard variant type (string, integer, array etc.). AtomPythonEngine is a
-drop in for PythonEngine with all functionality inherited except for the
-PyObjectAsVariant that is extended as stated above.
-
-The VariantAsPyObject of PythonEngine is also shown to work on
-PythonAtoms.
-
---------------------------------------------------------------
-25) Using VarPyth.pas (Kylix ready)
---------------------------------------------------------------
-Here's a unit test for demonstrating most of what you can do with the
-new custom variant that wraps up the Python objects.
-
---------------------------------------------------------------
-26) Demo8 revisited to allow the new Python type to be subclassed
---------------------------------------------------------------
-Warning! Type subclassing is allowed only in Python 2.2 and later.
-
- Note: Look at (32) if you're using Delphi7 or later as it can make
- your life much easier when trying to expose a regular Delphi
- class to Python. See also the WrapDelphi.pas unit.
-
-You should not override GetAttr and SetAttr anymore and you should not
-select the Basic services flags [bsGetAttr, bsSetAttr].
-Instead, simply select the flags [bsGetAttrO, bsSetAttrO] and the class
-TPyObject does simply call PyObject_GenericGetAttr in GetAttrO
-and PyObject_GenericSetAttr in SetAttrO.
-The Python Generic Get/Set functions will use new slots introduced in
-the type object for specifying a list of members (class fields),
-a list of get/set functions (like properties in Delphi) and a list
-of methods. That way a subclass can introduce its own members/get,set/methods
-and call the others coming from the base classes.
-
-So, now You can override the class methods RegisterMembers and RegisterGetSets
-for allowing your type to be subclassed and offer attributes and
-methods to its subclasses.
-
-This demo declares two members for x and y fields, and one get/set for
-accessing the name fields which is a Delphi string and thus needs to
-be converted from/to Python object.
-The old way of registering methods has not changed at all.
-
---------------------------------------------------------------
-27) Container indexing
---------------------------------------------------------------
-#index:
-s[0]
-#slice
-s[0:2]
-#ellipsis
-s[...]
-#extended slice
-s[0:2:2]
-#multidimensional slice:
-s[10, 10:20, 20:100:5, ...]
-
---------------------------------------------------------------
-28) Iterator (Kylix ready)
---------------------------------------------------------------
-
-This demo implements a new container type wrapping a TStringList
-and shows how to return an iterator that will browse the container's content.
-
---------------------------------------------------------------
-29) Using Python Imaging Library (PAL)
---------------------------------------------------------------
-
-This demo shows how to exchange images between Delphi and the
-Python Imaging Library.
-This demo relies on VarPyth.pas and thus on Delphi 6 or above.
-You need also the library that you can get at:
-http://www.pythonware.com/products/pil/
-
---------------------------------------------------------------
-30) Using Named Parameters (Kylix ready)
---------------------------------------------------------------
-
-This demo shows how you can use named parameters when invoking Python functions or methods.
-This requires VarPyth.
-Look at the code in TForm1.Button1Click
-
---------------------------------------------------------------
-31) Using WrapDelphi to access Delphi Form attributes (Requires Delphi5 or later)
---------------------------------------------------------------
-
-This Demo shows how you expose a Delphi Form to Python, or your
-own custom Delphi classes.
-Note that it will use its full potential with Delphi7 or later.
-
---------------------------------------------------------------
-32) Demo08 revisited using WrapDelphi (Requires Delphi7 or later)
---------------------------------------------------------------
-
-This Demo shows how you can expose a Delphi class much simpler
-using WrapDelphi.
-
---------------------------------------------------------------
-33) Using Threads inside Python II.
---------------------------------------------------------------
-Enhanced Demo 11 showing how to properly interrupt running
-threads.
---------------------------------------------------------------
-
-
-That's all folks !!!
-Hope this helps to build cool Python/Delphi applications.
-
-Morgan
-
diff --git a/doc_original/deploying p4d.pdf b/doc_original/deploying p4d.pdf
deleted file mode 100644
index 735dfd1..0000000
Binary files a/doc_original/deploying p4d.pdf and /dev/null differ
diff --git a/python4lazarus/Definition.Inc b/python4lazarus/Definition.Inc
index 3cee703..6407265 100644
--- a/python4lazarus/Definition.Inc
+++ b/python4lazarus/Definition.Inc
@@ -22,198 +22,26 @@
(**************************************************************************)
/////////////////////////////////////////////////////////////////////////////
-// Select a Python version by commenting out the corresponding line, or
-// modify the default Python version below, in the Python versions section.
+// Delphi, C++ Builder versions
/////////////////////////////////////////////////////////////////////////////
-//{$DEFINE PYTHON25}
-//{$DEFINE PYTHON26}
-//{$DEFINE PYTHON27}
-//{$DEFINE PYTHON32}
-//{$DEFINE PYTHON33}
-//{$DEFINE PYTHON34}
-//{$DEFINE PYTHON35}
-//{$DEFINE PYTHON36}
-//{$DEFINE PYTHON37}
-//{$DEFINE PYTHON38}
-
-/////////////////////////////////////////////////////////////////////////////
-// Python for Delphi settings. Comment out the setting you want to enable.
-/////////////////////////////////////////////////////////////////////////////
-
-{$DEFINE PREFER_UNICODE} // this will convert a variant containing an OleStr to a UniCode Python string.
-
-/////////////////////////////////////////////////////////////////////////////
-// OS symbols. Note that MSWINDOWS is defined from Delphi6/Kylix.
-/////////////////////////////////////////////////////////////////////////////
-
-{$IFNDEF MSWINDOWS}
- {$IFDEF WIN32}
- {$DEFINE MSWINDOWS}
- {$ENDIF}
-{$ENDIF}
-
-/////////////////////////////////////////////////////////////////////////////
-// Delphi, C++ Builder and Kylix versions
-/////////////////////////////////////////////////////////////////////////////
-
-{$IFDEF VER90} // Delphi 2.0
- {$DEFINE DELPHI2}
-{$ENDIF}
-{$IFDEF VER93} // C++ Builder 1.0
- {$DEFINE CBUILDER1}
-{$ENDIF}
-{$IFDEF VER100} // Delphi 3.0
- {$DEFINE DELPHI3}
-{$ENDIF}
-{$IFDEF VER110} // C++ Builder 3.0
- {$DEFINE CBUILDER3}
- {$DEFINE DELPHI3_OR_HIGHER}
- {$ObjExportAll On}
-{$ENDIF}
-{$IFDEF VER120} // Delphi 4.0
- {$DEFINE DELPHI4}
- {$DEFINE DELPHI4_OR_HIGHER}
-{$ENDIF}
-{$IFDEF VER125} // C++ Builder 4.0
- {$DEFINE CBUILDER4}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$ObjExportAll On}
-{$ENDIF}
-{$IFDEF VER130} // Delphi 5.0
- {$DEFINE DELPHI5}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$IFDEF BCB} { Borland C++Builder 5.0 }
- {$DEFINE CBUILDER3}
- {$DEFINE CBUILDER4}
- {$DEFINE CBUILDER5}
- {$ObjExportAll On}
- {$ENDIF}
-{$ENDIF}
-{$IFDEF VER140} // Delphi 6.0
- {$DEFINE DELPHI6}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$IFDEF BCB} { Borland C++Builder 6.0 }
- {$DEFINE CBUILDER3}
- {$DEFINE CBUILDER4}
- {$DEFINE CBUILDER5}
- {$DEFINE CBUILDER6}
- {$ObjExportAll On}
- {$ENDIF}
-{$ENDIF}
-{$IFDEF VER150} // Delphi 7.0
- {$DEFINE DELPHI7}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
-{$ENDIF}
-{$IFDEF VER160} // Delphi 8
- {$DEFINE DELPHI8}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
-{$ENDIF}
-{$IFDEF VER170} // Delphi 2005
- {$DEFINE DELPHI2005}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
-{$ENDIF}
-{$IFDEF VER180} // Delphi 2006
- {$DEFINE DELPHI2006}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
-{$ENDIF}
-{$IFDEF VER190} // Delphi 2007
- {$DEFINE DELPHI2007}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
-{$ENDIF}
-{$IFDEF VER200} // Delphi 2009
- {$DEFINE DELPHI2009}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
-{$ENDIF}
{$IFDEF VER210} // Delphi 2010
{$DEFINE DELPHI2010}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
{$DEFINE DELPHI2010_OR_HIGHER}
{$ENDIF}
{$IFDEF VER220} // Delphi XE
{$DEFINE DELPHIXE}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$ENDIF}
{$IFDEF VER230} // Delphi XE2
{$DEFINE DELPHIXE2}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
{$ENDIF}
{$IFDEF VER240} // Delphi XE3
{$DEFINE DELPHIXE3}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
@@ -221,15 +49,6 @@
{$ENDIF}
{$IFDEF VER250} // Delphi XE4
{$DEFINE DELPHIXE4}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
@@ -238,15 +57,6 @@
{$ENDIF}
{$IFDEF VER260} // Delphi XE5
{$DEFINE DELPHIXE5}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
@@ -256,15 +66,6 @@
{$ENDIF}
{$IFDEF VER270} // Delphi XE6
{$DEFINE DELPHIXE6}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
@@ -275,15 +76,6 @@
{$ENDIF}
{$IFDEF VER280} // Delphi XE7
{$DEFINE DELPHIXE7}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
@@ -295,15 +87,6 @@
{$ENDIF}
{$IFDEF VER290} // Delphi XE8
{$DEFINE DELPHIXE8}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
@@ -316,15 +99,6 @@
{$ENDIF}
{$IFDEF VER300} // Delphi 10
{$DEFINE DELPHI10}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
@@ -334,19 +108,10 @@
{$DEFINE DELPHIXE6_OR_HIGHER}
{$DEFINE DELPHIXE7_OR_HIGHER}
{$DEFINE DELPHIXE8_OR_HIGHER}
- {$DEFINE DELPHIX10_OR_HIGHER}
+ {$DEFINE DELPHI10_OR_HIGHER}
{$ENDIF}
{$IFDEF VER310} // Delphi 10.1
- {$DEFINE DELPHI10.1}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
+ {$DEFINE DELPHI10_1}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
@@ -357,19 +122,10 @@
{$DEFINE DELPHIXE7_OR_HIGHER}
{$DEFINE DELPHIXE8_OR_HIGHER}
{$DEFINE DELPHI10_OR_HIGHER}
- {$DEFINE DELPHI10.1_OR_HIGHER}
+ {$DEFINE DELPHI10_1_OR_HIGHER}
{$ENDIF}
{$IFDEF VER320} // Delphi 10.2
- {$DEFINE DELPHI10.2}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
+ {$DEFINE DELPHI10_2}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
@@ -380,20 +136,11 @@
{$DEFINE DELPHIXE7_OR_HIGHER}
{$DEFINE DELPHIXE8_OR_HIGHER}
{$DEFINE DELPHI10_OR_HIGHER}
- {$DEFINE DELPHI10.1_OR_HIGHER}
- {$DEFINE DELPHI10.2_OR_HIGHER}
+ {$DEFINE DELPHI10_1_OR_HIGHER}
+ {$DEFINE DELPHI10_2_OR_HIGHER}
{$ENDIF}
{$IFDEF VER330} // Delphi 10.3
- {$DEFINE DELPHI10.3}
- {$DEFINE DELPHI4_OR_HIGHER}
- {$DEFINE DELPHI5_OR_HIGHER}
- {$DEFINE DELPHI6_OR_HIGHER}
- {$DEFINE DELPHI7_OR_HIGHER}
- {$DEFINE DELPHI8_OR_HIGHER}
- {$DEFINE DELPHI2005_OR_HIGHER}
- {$DEFINE DELPHI2006_OR_HIGHER}
- {$DEFINE DELPHI2007_OR_HIGHER}
- {$DEFINE DELPHI2009_OR_HIGHER}
+ {$DEFINE DELPHI10_3}
{$DEFINE DELPHI2010_OR_HIGHER}
{$DEFINE DELPHIXE_OR_HIGHER}
{$DEFINE DELPHIXE2_OR_HIGHER}
@@ -404,116 +151,86 @@
{$DEFINE DELPHIXE7_OR_HIGHER}
{$DEFINE DELPHIXE8_OR_HIGHER}
{$DEFINE DELPHI10_OR_HIGHER}
- {$DEFINE DELPHI10.1_OR_HIGHER}
- {$DEFINE DELPHI10.2_OR_HIGHER}
- {$DEFINE DELPHI10.3_OR_HIGHER}
-{$ENDIF}
-/////////////////////////////////////////////////////////////////////////////
-// Python versions
-/////////////////////////////////////////////////////////////////////////////
-
-// Here we select a default Python version, if no version was explicitely specified.
-// Note that the installer will let the user specify its default Python version, and
-// thus will edit this file.
-
-{$IFNDEF PYTHON38}
- {$IFNDEF PYTHON37}
- {$IFNDEF PYTHON36}
- {$IFNDEF PYTHON35}
- {$IFNDEF PYTHON34}
- {$IFNDEF PYTHON33}
- {$IFNDEF PYTHON32}
- {$IFNDEF PYTHON27}
- {$IFNDEF PYTHON26}
- {$IFNDEF PYTHON25}
- {------}
- {$DEFINE PYTHON27}
- {------}
- {$ENDIF}
- {$ENDIF}
- {$ENDIF}
- {$ENDIF}
- {$ENDIF}
- {$ENDIF}
- {$ENDIF}
- {$ENDIF}
- {$ENDIF}
+ {$DEFINE DELPHI10_1_OR_HIGHER}
+ {$DEFINE DELPHI10_2_OR_HIGHER}
+ {$DEFINE DELPHI10_3_OR_HIGHER}
{$ENDIF}
-
-{$IFDEF PYTHON25}
- {$DEFINE PYTHON25_OR_HIGHER}
-{$ENDIF}
-{$IFDEF PYTHON26}
- {$DEFINE PYTHON25_OR_HIGHER}
- {$DEFINE PYTHON26_OR_HIGHER}
-{$ENDIF}
-{$IFDEF PYTHON27}
- {$DEFINE PYTHON25_OR_HIGHER}
- {$DEFINE PYTHON26_OR_HIGHER}
- {$DEFINE PYTHON27_OR_HIGHER}
-{$ENDIF}
-{$IFDEF PYTHON32}
- {$DEFINE PYTHON25_OR_HIGHER}
- {$DEFINE PYTHON26_OR_HIGHER}
- {$DEFINE PYTHON27_OR_HIGHER}
- {$DEFINE PYTHON32_OR_HIGHER}
-{$ENDIF}
-{$IFDEF PYTHON33}
- {$DEFINE PYTHON25_OR_HIGHER}
- {$DEFINE PYTHON26_OR_HIGHER}
- {$DEFINE PYTHON27_OR_HIGHER}
- {$DEFINE PYTHON32_OR_HIGHER}
- {$DEFINE PYTHON33_OR_HIGHER}
-{$ENDIF}
-{$IFDEF PYTHON34}
- {$DEFINE PYTHON25_OR_HIGHER}
- {$DEFINE PYTHON26_OR_HIGHER}
- {$DEFINE PYTHON27_OR_HIGHER}
- {$DEFINE PYTHON32_OR_HIGHER}
- {$DEFINE PYTHON33_OR_HIGHER}
- {$DEFINE PYTHON34_OR_HIGHER}
-{$ENDIF}
-{$IFDEF PYTHON35}
- {$DEFINE PYTHON25_OR_HIGHER}
- {$DEFINE PYTHON26_OR_HIGHER}
- {$DEFINE PYTHON27_OR_HIGHER}
- {$DEFINE PYTHON32_OR_HIGHER}
- {$DEFINE PYTHON33_OR_HIGHER}
- {$DEFINE PYTHON34_OR_HIGHER}
- {$DEFINE PYTHON35_OR_HIGHER}
-{$ENDIF}
-{$IFDEF PYTHON36}
- {$DEFINE PYTHON25_OR_HIGHER}
- {$DEFINE PYTHON26_OR_HIGHER}
- {$DEFINE PYTHON27_OR_HIGHER}
- {$DEFINE PYTHON32_OR_HIGHER}
- {$DEFINE PYTHON33_OR_HIGHER}
- {$DEFINE PYTHON34_OR_HIGHER}
- {$DEFINE PYTHON35_OR_HIGHER}
- {$DEFINE PYTHON36_OR_HIGHER}
-{$ENDIF}
-{$IFDEF PYTHON37}
- {$DEFINE PYTHON25_OR_HIGHER}
- {$DEFINE PYTHON26_OR_HIGHER}
- {$DEFINE PYTHON27_OR_HIGHER}
- {$DEFINE PYTHON32_OR_HIGHER}
- {$DEFINE PYTHON33_OR_HIGHER}
- {$DEFINE PYTHON34_OR_HIGHER}
- {$DEFINE PYTHON35_OR_HIGHER}
- {$DEFINE PYTHON36_OR_HIGHER}
- {$DEFINE PYTHON37_OR_HIGHER}
+{$IFDEF VER340} // Delphi 10.4
+ {$DEFINE DELPHI10_4}
+ {$DEFINE DELPHI2010_OR_HIGHER}
+ {$DEFINE DELPHIXE_OR_HIGHER}
+ {$DEFINE DELPHIXE2_OR_HIGHER}
+ {$DEFINE DELPHIXE3_OR_HIGHER}
+ {$DEFINE DELPHIXE4_OR_HIGHER}
+ {$DEFINE DELPHIXE5_OR_HIGHER}
+ {$DEFINE DELPHIXE6_OR_HIGHER}
+ {$DEFINE DELPHIXE7_OR_HIGHER}
+ {$DEFINE DELPHIXE8_OR_HIGHER}
+ {$DEFINE DELPHI10_OR_HIGHER}
+ {$DEFINE DELPHI10_1_OR_HIGHER}
+ {$DEFINE DELPHI10_2_OR_HIGHER}
+ {$DEFINE DELPHI10_3_OR_HIGHER}
+ {$DEFINE DELPHI10_4_OR_HIGHER}
+ {$IF RTLVERSION1042}
+ {$DEFINE DELPHI10_4_2} //Delphi 10.4.2
+ {$ENDIF RTLVERSION1042}
+{$ENDIF}
+{$IFDEF VER350} // Delphi 11
+ {$DEFINE DELPHI11}
+ {$DEFINE DELPHI2010_OR_HIGHER}
+ {$DEFINE DELPHIXE_OR_HIGHER}
+ {$DEFINE DELPHIXE2_OR_HIGHER}
+ {$DEFINE DELPHIXE3_OR_HIGHER}
+ {$DEFINE DELPHIXE4_OR_HIGHER}
+ {$DEFINE DELPHIXE5_OR_HIGHER}
+ {$DEFINE DELPHIXE6_OR_HIGHER}
+ {$DEFINE DELPHIXE7_OR_HIGHER}
+ {$DEFINE DELPHIXE8_OR_HIGHER}
+ {$DEFINE DELPHI10_OR_HIGHER}
+ {$DEFINE DELPHI10_1_OR_HIGHER}
+ {$DEFINE DELPHI10_2_OR_HIGHER}
+ {$DEFINE DELPHI10_3_OR_HIGHER}
+ {$DEFINE DELPHI10_4_OR_HIGHER}
+ {$DEFINE DELPHI11_OR_HIGHER}
{$ENDIF}
-{$IFDEF PYTHON38}
- {$DEFINE PYTHON25_OR_HIGHER}
- {$DEFINE PYTHON26_OR_HIGHER}
- {$DEFINE PYTHON27_OR_HIGHER}
- {$DEFINE PYTHON32_OR_HIGHER}
- {$DEFINE PYTHON33_OR_HIGHER}
- {$DEFINE PYTHON34_OR_HIGHER}
- {$DEFINE PYTHON35_OR_HIGHER}
- {$DEFINE PYTHON36_OR_HIGHER}
- {$DEFINE PYTHON37_OR_HIGHER}
- {$DEFINE PYTHON38_OR_HIGHER}
+{$IFDEF VER360} // Delphi 12
+ {$DEFINE DELPHI2010_OR_HIGHER}
+ {$DEFINE DELPHIXE_OR_HIGHER}
+ {$DEFINE DELPHI12}
+ {$DEFINE DELPHIXE2_OR_HIGHER}
+ {$DEFINE DELPHIXE3_OR_HIGHER}
+ {$DEFINE DELPHIXE4_OR_HIGHER}
+ {$DEFINE DELPHIXE5_OR_HIGHER}
+ {$DEFINE DELPHIXE6_OR_HIGHER}
+ {$DEFINE DELPHIXE7_OR_HIGHER}
+ {$DEFINE DELPHIXE8_OR_HIGHER}
+ {$DEFINE DELPHI10_OR_HIGHER}
+ {$DEFINE DELPHI10_1_OR_HIGHER}
+ {$DEFINE DELPHI10_2_OR_HIGHER}
+ {$DEFINE DELPHI10_3_OR_HIGHER}
+ {$DEFINE DELPHI10_4_OR_HIGHER}
+ {$DEFINE DELPHI11_OR_HIGHER}
+ {$DEFINE DELPHI12_OR_HIGHER}
+{$ENDIF}
+{$IFDEF VER370} // Delphi 13
+ {$DEFINE DELPHI2010_OR_HIGHER}
+ {$DEFINE DELPHIXE_OR_HIGHER}
+ {$DEFINE DELPHI13}
+ {$DEFINE DELPHIXE2_OR_HIGHER}
+ {$DEFINE DELPHIXE3_OR_HIGHER}
+ {$DEFINE DELPHIXE4_OR_HIGHER}
+ {$DEFINE DELPHIXE5_OR_HIGHER}
+ {$DEFINE DELPHIXE6_OR_HIGHER}
+ {$DEFINE DELPHIXE7_OR_HIGHER}
+ {$DEFINE DELPHIXE8_OR_HIGHER}
+ {$DEFINE DELPHI10_OR_HIGHER}
+ {$DEFINE DELPHI10_1_OR_HIGHER}
+ {$DEFINE DELPHI10_2_OR_HIGHER}
+ {$DEFINE DELPHI10_3_OR_HIGHER}
+ {$DEFINE DELPHI10_4_OR_HIGHER}
+ {$DEFINE DELPHI11_OR_HIGHER}
+ {$DEFINE DELPHI12_OR_HIGHER}
+ {$DEFINE DELPHI13_OR_HIGHER}
{$ENDIF}
/////////////////////////////////////////////////////////////////////////////
@@ -526,19 +243,54 @@
{$IFDEF FPC}
{$MODE DELPHI}
+
{$IFDEF CPU64}
+ {$DEFINE CPU64BITS}
{$DEFINE CPUX64}
{$ENDIF CPU64}
- {$IFDEF CPU32}
+
+ {$IFDEF CPU86}
{$DEFINE CPUX86}
- {$ENDIF CPU32}
+ {$ENDIF CPU86}
+
{$IFDEF DARWIN}
+ {$DEFINE OSX}
{$DEFINE MACOS}
- {$DEFINE ALIGN_STACK}
{$IFDEF CPU32}
{$DEFINE MACOS32}
{$ENDIF CPU32}
+ {$IFDEF CPU64}
+ {$DEFINE MACOS64}
+ {$DEFINE OSX64}
+ {$ENDIF CPU64}
{$ENDIF DARWIN}
+
+ {$IFDEF CPUARM}
+ {$DEFINE CPUARM32}
+ {$ENDIF}
+
+ {$IFDEF CPUAARCH64}
+ {$DEFINE CPUARM}
+ {$DEFINE CPUARM64}
+ {$ENDIF}
+
+ {$IFDEF UNIX}
+ {$DEFINE POSIX}
+ {$ENDIF UNIX}
+
+ {$IFDEF ANDROID}
+ {$DEFINE POSIX}
+ {$ENDIF ANDROID}
{$ENDIF FPC}
+{$IFDEF DELPHIXE_OR_HIGHER}
+ {$DEFINE EXTENDED_RTTI}
+{$ENDIF DELPHIXE_OR_HIGHER}
+
+{$IFDEF DELPHIXE4_OR_HIGHER}
+ {$LEGACYIFEND ON}
+{$ENDIF DELPHIXE4_OR_HIGHER}
+{$IFDEF MACOS}
+ {$DEFINE DARWIN}
+{$ENDIF MACOS}
diff --git a/python4lazarus/MethodCallBack.pas b/python4lazarus/MethodCallBack.pas
index 07f2c96..022e21d 100644
--- a/python4lazarus/MethodCallBack.pas
+++ b/python4lazarus/MethodCallBack.pas
@@ -17,6 +17,7 @@
(* Morgan Martinet (p4d@mmm-experts.com) *)
(* Samuel Iseli (iseli@vertec.ch) *)
(* Andrey Gruzdev (andrey.gruzdev@gmail.com) *)
+(* Lucas Belo (lucas.belo@live.com) *)
(**************************************************************************)
(* This source code is distributed with no WARRANTY, for no reason or use.*)
(* Everyone is allowed to use and change this code free, as long as this *)
@@ -32,7 +33,7 @@ interface
uses SysUtils;
type
- TCallType = (ctSTDCALL, ctCDECL);
+ TCallType = (ctSTDCALL, ctCDECL, ctARMSTD);
TCallBack = procedure of object;
function GetCallBack( self: TObject; method: Pointer;
@@ -127,6 +128,9 @@ implementation
PtrCalcType = NativeInt;
{$ENDIF}
+ EMProtectError = class(Exception)
+ end;
+
{$IFNDEF MSWINDOWS}
{$IFDEF FPC}
function mmap(Addr: Pointer; Len: Integer; Prot: Integer; Flags: Integer; FileDes: Integer; Off: Integer): Pointer; cdecl;
@@ -151,6 +155,9 @@ procedure GetCodeMem(var ptr: PByte; size: integer);
var
page: PCodeMemPage;
block: PCodeMemBlock;
+ {$IFNDEF MSWINDOWS}
+ flags: integer;
+ {$ENDIF}
begin
//---allocates Block from executable memory
// executable memory is requested in pages via VirtualAlloc
@@ -174,13 +181,40 @@ procedure GetCodeMem(var ptr: PByte; size: integer);
ptr := nil;
exit;
end;
- mprotect(page, PageSize, PROT_READ or PROT_WRITE or PROT_EXEC);
- {$ENDIF}
+ {
+ macOS for M1 has a bug (Apple Feedback FB8994773) in which mprotect
+ rejects a permission change from NONE -> RWX, resulting a "Permission
+ Denied" error.
+ Solution: give RW permission, make memory changes, then change RW to X
+ }
+ {$IF DEFINED(OSX) AND DEFINED(CPUARM64)}
+ flags := PROT_READ or PROT_WRITE;
+ {$ELSE}
+ flags := PROT_READ or PROT_WRITE or PROT_EXEC;
+ {$IFEND}
+ if mprotect(page, PageSize, flags) <> 0 then
+ raise EMProtectError.CreateFmt('MProtect error: %s', [
+ SysErrorMessage({$IFDEF FPC}GetLastOSError{$ELSE}GetLastError{$ENDIF}())]);
+ {$ENDIF}
page^.next:=CodeMemPages;
CodeMemPages:=page;
// init pointer to end of page
page^.CodeBlocks:=Pointer(PtrCalcType(page) + PageSize);
+ {$IF DEFINED(OSX) AND DEFINED(CPUARM64)}
+ end else begin
+ {
+ macOS for M1 has a bug (Apple Feedback FB8994773) in which mprotect
+ rejects a permission change from NONE -> RWX.
+ Solution: give RW permission, make memory changes, then change RW to X
+ }
+ //RW permission to the entire page for new changes...
+ if mprotect(page, PageSize, PROT_READ or PROT_WRITE) <> 0 then
+ raise EMProtectError.CreateFmt('MProtect error: %s', [
+ SysErrorMessage({$IFDEF FPC}GetLastOSError{$ELSE}GetLastError{$ENDIF}())]);
end;
+ {$ELSE}
+ end;
+ {$IFEND}
//---blocks are assigned starting from the end of the page
block:=Pointer(PtrCalcType(page^.codeBlocks) - (size + sizeof(PCodeMemBlock)));
@@ -258,6 +292,34 @@ function CodeMemPageCount: integer;
end;
end;
+procedure DeleteCallBack( Proc: Pointer);
+begin
+ FreeCodeMem(Proc);
+end;
+
+procedure FreeCallBacks;
+var
+ page, nextpage: PCodeMemPage;
+begin
+ // free each allocated page
+ page := CodeMemPages;
+ while page <> nil do
+ begin
+ nextpage := page^.Next;
+
+ // free the memory
+ {$IFDEF MSWINDOWS}
+ VirtualFree(page, 0, MEM_RELEASE);
+ {$ELSE}
+ //FreeMem(page);
+ munmap(page,PageSize);
+ {$ENDIF}
+
+ page := nextpage;
+ end;
+ CodeMemPages := nil;
+end;
+
function GetOfObjectCallBack( CallBack: TCallBack;
argnum: Integer; calltype: TCallType): Pointer;
begin
@@ -266,15 +328,17 @@ function GetOfObjectCallBack( CallBack: TCallBack;
argnum, calltype);
end;
-{$IFDEF CPUX64}
-{$DEFINE 64_BIT_CALLBACK}
-{$ELSE}
-{$IFDEF MACOS}
-{$DEFINE ALIGNED_32_BIT_CALLBACK}
-{$ELSE}
-{$DEFINE SIMPLE_32_BIT_CALLBACK}
-{$ENDIF MACOS}
-{$ENDIF CPUX64}
+{$IFNDEF CPUARM}
+ {$IFDEF CPUX64}
+ {$DEFINE 64_BIT_CALLBACK}
+ {$ELSE}
+ {$IFDEF MACOS}
+ {$DEFINE ALIGNED_32_BIT_CALLBACK}
+ {$ELSE}
+ {$DEFINE SIMPLE_32_BIT_CALLBACK}
+ {$ENDIF MACOS}
+ {$ENDIF CPUX64}
+{$ENDIF CPUARM}
{$IFDEF SIMPLE_32_BIT_CALLBACK}
// win32 inplementation
@@ -565,35 +629,138 @@ function GetCallBack( self: TObject; method: Pointer;
end;
{$ENDIF}
-procedure DeleteCallBack( Proc: Pointer);
+{$IFDEF CPUARM32}
+function GetCallBack(Self: TObject; Method: Pointer; ArgNum: Integer;
+ CallType: TCallType): Pointer;
+const
+ S1: array[0..123] of byte = (
+//big-endian
+//offset :
+ {+ 0:} $80, $40, $2d, $e9, // push {r7, lr}
+ {+ 4:} $0d, $70, $a0, $e1, // mov r7, sp
+ {+ 8:} $1e, $04, $2d, $e9, // push {r1, r2, r3, r4, sl}
+ {+ c:} $5c, $40, $9f, $e5, // ldr r4, [pc, #92] ; 70
+ {+ 10:} $00, $00, $54, $e3, // cmp r4, #0
+ {+ 14:} $04, $d0, $4d, $c0, // subgt sp, sp, r4
+ {+ 18:} $04, $50, $a0, $c1, // movgt r5, r4
+ {+ 1c:} $04, $50, $85, $c2, // addgt r5, r5, #4
+ {+ 20:} $04, $60, $a0, $c1, // movgt r6, r4
+ {+ 24:} $04, $60, $46, $c2, // subgt r6, r6, #4
+ {+ 28:} $09, $00, $00, $cb, // blgt 54
+ {+ 2c:} $0f, $00, $2d, $e9, // push {r0, r1, r2, r3}
+ {+ 30:} $3c, $00, $9f, $e5, // ldr r0, [pc, #60] ; 74
+ {+ 34:} $0e, $00, $bd, $e8, // pop {r1, r2, r3}
+ {+ 38:} $38, $a0, $9f, $e5, // ldr sl, [pc, #56] ; 78
+ {+ 3c:} $3a, $ff, $2f, $e1, // blx sl
+ {+ 40:} $00, $00, $54, $e3, // cmp r4, #0
+ {+ 44:} $04, $d0, $8d, $c0, // addgt sp, sp, r4
+ {+ 48:} $04, $40, $9d, $e4, // pop {r4} ; (ldr r4, [sp], #4)
+ {+ 4c:} $1e, $04, $bd, $e8, // pop {r1, r2, r3, r4, sl}
+ {+ 50:} $80, $80, $bd, $e8, // pop {r7, pc}
+//offset + 00000054 :
+ {+ 54:} $05, $a0, $97, $e7, // ldr sl, [r7, r5]
+ {+ 58:} $06, $a0, $8d, $e7, // str sl, [sp, r6]
+ {+ 5c:} $04, $50, $45, $e2, // sub r5, r5, #4
+ {+ 60:} $04, $60, $46, $e2, // sub r6, r6, #4
+ {+ 64:} $00, $00, $56, $e3, // cmp r6, #0
+ {+ 68:} $f9, $ff, $ff, $aa, // bge 54
+ {+ 6c:} $1e, $ff, $2f, $e1, // bx lr
+//offset + 00000070
+ {+ 70:} $00, $00, $00, $00, // stack space for stack parameters
+ {+ 74:} $00, $00, $00, $00, // Self
+ {+ 78:} $00, $00, $00, $00 // Method
+);
+const
+ ARM_INSTRUCTION_SIZE = 4;
+ ARM_ARGUMENT_COUNT_IN_REGISTERS = 4;
+var
+ P, Q: PByte;
+ LLiteralPool: TArray;
+ I: Integer;
begin
- FreeCodeMem(Proc);
+ GetCodeMem(Q, SizeOf(S1));
+ P := Q;
+ Move(S1, P^, SizeOf(S1));
+
+ LLiteralPool := TArray.Create(
+ Pointer((ArgNum - ARM_ARGUMENT_COUNT_IN_REGISTERS) * ARM_INSTRUCTION_SIZE),
+ Self,
+ Method);
+
+ Inc(P, Length(S1) - (Length(LLiteralPool) * SizeOf(pointer)));
+ for I := Low(LLiteralPool) to High(LLiteralPool) do begin
+ Move(LLiteralPool[I], P^, SizeOf(pointer));
+ Inc(P, SizeOf(pointer));
+ end;
+
+ Result := Pointer(Q); //set arm mode
end;
+{$ENDIF CPUARM32}
-procedure FreeCallBacks;
+{$IFDEF CPUARM64}
+function GetCallBack(Self: TObject; Method: Pointer; ArgNum: Integer;
+ CallType: TCallType): Pointer;
+const
+ S1: array[0..79] of byte = (
+//big-endian
+//offset <_start>:
+ $fd, $7b, $bf, $a9, // stp x29, x30, [sp, #-16]!
+ $fd, $03, $00, $91, // mov x29, sp
+ $e0, $07, $bf, $a9, // stp x0, x1, [sp, #-16]!
+ $e2, $0f, $bf, $a9, // stp x2, x3, [sp, #-16]!
+ $e4, $17, $bf, $a9, // stp x4, x5, [sp, #-16]!
+ $e6, $1f, $bf, $a9, // stp x6, x7, [sp, #-16]!
+ $0a, $00, $00, $10, // adr x10, #0 <_start+0x18>
+ $40, $15, $40, $f9, // ldr x0, [x10, #40]
+ $49, $19, $40, $f9, // ldr x9, [x10, #48]
+ $e7, $2f, $c1, $a8, // ldp x7, x11, [sp], #16
+ $e5, $1b, $c1, $a8, // ldp x5, x6, [sp], #16
+ $e3, $13, $c1, $a8, // ldp x3, x4, [sp], #16
+ $e1, $0b, $c1, $a8, // ldp x1, x2, [sp], #16
+ $20, $01, $3f, $d6, // blr x9
+ $fd, $7b, $c1, $a8, // ldp x29, x30, [sp], #16
+ $c0, $03, $5f, $d6, // ret
+ $00, $00, $00, $00, // .word 0x00000000 //Self
+ $00, $00, $00, $00, // .word 0x00000000
+ $00, $00, $00, $00, // .word 0x00000000 //Method
+ $00, $00, $00, $00 // .word 0x00000000
+);
var
- page, nextpage: PCodeMemPage;
+ P, Q: PByte;
+ LLiteralPool: TArray;
+ I: Integer;
begin
- // free each allocated page
- page := CodeMemPages;
- while page <> nil do
- begin
- nextpage := page^.Next;
+ GetCodeMem(Q, SizeOf(S1));
+ P := Q;
+ Move(S1, P^, SizeOf(S1));
- // free the memory
- {$IFDEF MSWINDOWS}
- VirtualFree(page, 0, MEM_RELEASE);
- {$ELSE}
- //FreeMem(page);
- munmap(page,PageSize);
- {$ENDIF}
+ LLiteralPool := TArray.Create(Self, Method);
- page := nextpage;
+ Inc(P, Length(S1) - (Length(LLiteralPool) * SizeOf(pointer)));
+ for I := Low(LLiteralPool) to High(LLiteralPool) do begin
+ Move(LLiteralPool[I], P^, SizeOf(pointer));
+ Inc(P, SizeOf(pointer));
end;
- CodeMemPages := nil;
+
+ {$IF DEFINED(OSX) AND DEFINED(CPUARM64)}
+ {
+ macOS for M1 has a bug (Apple Feedback FB8994773) in which mprotect
+ rejects a permission change from NONE -> RWX.
+ Solution: give RW permission, make memory changes, then change RW to X
+ }
+ //X permission to the entire page for executions...
+ if mprotect(CodeMemPages, PageSize, PROT_EXEC) <> 0 then
+ raise EMProtectError.CreateFmt('MProtect error: %s', [
+ SysErrorMessage({$IFDEF FPC}GetLastOSError{$ELSE}GetLastError{$ENDIF}())]);
+ {$IFEND}
+
+ Result := Pointer(Q); //set arm mode
end;
+{$ENDIF CPUARM64}
initialization
+
finalization
FreeCallBacks;
+
end.
diff --git a/python4lazarus/PythonAction.pas b/python4lazarus/PythonAction.pas
index cfa5caa..184f931 100644
--- a/python4lazarus/PythonAction.pas
+++ b/python4lazarus/PythonAction.pas
@@ -124,7 +124,7 @@ function TPythonAction.PythonClear(pself, args: PPyObject): PPyObject;
ClearMethods;
with GetPythonEngine, RegisteredMethods do
begin
- Result := PyInt_FromLong(Count);
+ Result := PyLong_FromLong(Count);
end;
end;
@@ -146,7 +146,7 @@ function TPythonAction.PythonRegister(pself, args: PPyObject): PPyObject;
begin
Py_XINCREF(func);
Add(func);
- Result := PyInt_FromLong(Count);
+ Result := PyLong_FromLong(Count);
end;
end;
@@ -168,7 +168,7 @@ function TPythonAction.PythonUnregister(pself, args: PPyObject): PPyObject;
begin
Py_XDECREF(func);
Remove(func);
- Result := PyInt_FromLong(Count);
+ Result := PyLong_FromLong(Count);
end;
end;
diff --git a/python4lazarus/PythonEngine.pas b/python4lazarus/PythonEngine.pas
index b0706c5..7d7141e 100644
--- a/python4lazarus/PythonEngine.pas
+++ b/python4lazarus/PythonEngine.pas
@@ -2,8 +2,8 @@
(* *)
(* Module: Unit 'PythonEngine' Copyright (c) 1997 *)
(* *)
-(* Version: 3.0 Dr. Dietmar Budelsky *)
-(* Sub-Version: 0.33 dbudelsky@web.de *)
+(* Dr. Dietmar Budelsky *)
+(* dbudelsky@web.de *)
(* Germany *)
(* *)
(* Morgan Martinet *)
@@ -12,6 +12,9 @@
(* CANADA *)
(* e-mail: p4d@mmm-experts.com *)
(* *)
+(* PyScripter *)
+(* e-mail: pyscripter@gmail.com *)
+(* *)
(* Project page: https://github.com/pyscripter/python4delphi *)
(**************************************************************************)
(* Functionality: Delphi Components that provide an interface to the *)
@@ -31,9 +34,7 @@
(* Stefan Hoffmeister (Stefan.Hoffmeister@Econos.de) *)
(* Michiel du Toit (micdutoit@hsbfn.com) - Lazarus Port *)
(* Chris Nicolai (nicolaitanes@gmail.com) *)
-(* Kiriakos Vlahos (kvlahos@london.edu) *)
(* Andrey Gruzdev (andrey.gruzdev@gmail.com) *)
-(* Alexey Torgashin (support@uvviewsoft.com) *)
(**************************************************************************)
(* This source code is distributed with no WARRANTY, for no reason or use.*)
(* Everyone is allowed to use and change this code free for his own tasks *)
@@ -59,17 +60,10 @@
{ TODO -oMMM : implement tp_as_buffer slot }
{ TODO -oMMM : implement Attribute descriptor and subclassing stuff }
-{$IFNDEF FPC}
- {$IFNDEF DELPHI7_OR_HIGHER}
- Error! Delphi 7 or higher is required!
- {$ENDIF}
-{$ENDIF}
-
-{$IF defined(LINUX) or (defined(BSD) and not defined(DARWIN)) or defined(SOLARIS) or defined(HAIKU)}
- {$define _so_files}
+{$IF defined(UNIX) and not defined(DARWIN)}
+{$define _so_files}
{$ENDIF}
-
interface
uses
@@ -109,44 +103,47 @@ interface
DllName : String;
RegVersion : String;
APIVersion : Integer;
- CanUseLatest : Boolean;
end;
const
{$ifdef windows}
- PYTHON_KNOWN_VERSIONS: array[1..7] of TPythonVersionProp =
+ PYTHON_KNOWN_VERSIONS: array[1..10] of TPythonVersionProp =
(
- (DllName: 'python27.dll'; RegVersion: '2.7'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'python33.dll'; RegVersion: '3.3'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'python34.dll'; RegVersion: '3.4'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'python35.dll'; RegVersion: '3.5'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'python36.dll'; RegVersion: '3.6'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'python37.dll'; RegVersion: '3.7'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'python38.dll'; RegVersion: '3.8'; APIVersion: 1013; CanUseLatest: True)
+ (DllName: 'python34.dll'; RegVersion: '3.4'; APIVersion: 1013),
+ (DllName: 'python35.dll'; RegVersion: '3.5'; APIVersion: 1013),
+ (DllName: 'python36.dll'; RegVersion: '3.6'; APIVersion: 1013),
+ (DllName: 'python37.dll'; RegVersion: '3.7'; APIVersion: 1013),
+ (DllName: 'python38.dll'; RegVersion: '3.8'; APIVersion: 1013),
+ (DllName: 'python39.dll'; RegVersion: '3.9'; APIVersion: 1013),
+ (DllName: 'python310.dll'; RegVersion: '3.10'; APIVersion: 1013),
+ (DllName: 'python311.dll'; RegVersion: '3.11'; APIVersion: 1013),
+ (DllName: 'python312.dll'; RegVersion: '3.12'; APIVersion: 1013),
+ (DllName: 'python313.dll'; RegVersion: '3.13'; APIVersion: 1013)
);
{$endif}
{$ifdef _so_files}
- PYTHON_KNOWN_VERSIONS: array[1..7] of TPythonVersionProp =
+ PYTHON_KNOWN_VERSIONS: array[1..9] of TPythonVersionProp =
(
- (DllName: 'libpython2.7.so'; RegVersion: '2.7'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.3m.so'; RegVersion: '3.3'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.4m.so'; RegVersion: '3.4'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.5m.so'; RegVersion: '3.5'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.6m.so'; RegVersion: '3.6'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.7m.so'; RegVersion: '3.7'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.8m.so'; RegVersion: '3.8'; APIVersion: 1013; CanUseLatest: True)
+ (DllName: 'libpython3.5m.so'; RegVersion: '3.5'; APIVersion: 1013),
+ (DllName: 'libpython3.6m.so'; RegVersion: '3.6'; APIVersion: 1013),
+ (DllName: 'libpython3.7m.so'; RegVersion: '3.7'; APIVersion: 1013),
+ (DllName: 'libpython3.8.so'; RegVersion: '3.8'; APIVersion: 1013),
+ (DllName: 'libpython3.9.so'; RegVersion: '3.9'; APIVersion: 1013),
+ (DllName: 'libpython3.10.so'; RegVersion: '3.10'; APIVersion: 1013),
+ (DllName: 'libpython3.11.so'; RegVersion: '3.11'; APIVersion: 1013),
+ (DllName: 'libpython3.12.so'; RegVersion: '3.12'; APIVersion: 1013),
+ (DllName: 'libpython3.13.so'; RegVersion: '3.13'; APIVersion: 1013)
);
{$endif}
{$ifdef darwin}
- PYTHON_KNOWN_VERSIONS: array[1..7] of TPythonVersionProp =
+ PYTHON_KNOWN_VERSIONS: array[1..6] of TPythonVersionProp =
(
- (DllName: 'libpython2.7.dylib'; RegVersion: '2.7'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.3.dylib'; RegVersion: '3.3'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.4.dylib'; RegVersion: '3.4'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.5.dylib'; RegVersion: '3.5'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.6.dylib'; RegVersion: '3.6'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.7.dylib'; RegVersion: '3.7'; APIVersion: 1013; CanUseLatest: True),
- (DllName: 'libpython3.8.dylib'; RegVersion: '3.8'; APIVersion: 1013; CanUseLatest: True)
+ (DllName: 'libpython3.8.dylib'; RegVersion: '3.8'; APIVersion: 1013),
+ (DllName: 'libpython3.9.dylib'; RegVersion: '3.9'; APIVersion: 1013),
+ (DllName: 'libpython3.10.dylib'; RegVersion: '3.10'; APIVersion: 1013),
+ (DllName: 'libpython3.11.dylib'; RegVersion: '3.11'; APIVersion: 1013),
+ (DllName: 'libpython3.12.dylib'; RegVersion: '3.12'; APIVersion: 1013),
+ (DllName: 'libpython3.13.dylib'; RegVersion: '3.13'; APIVersion: 1013)
);
{$endif}
@@ -158,6 +155,8 @@ interface
METH_VARARGS = $0001;
METH_KEYWORDS = $0002;
+ METH_CLASS = $0010;
+ METH_STATIC = $0020;
// Masks for the co_flags field of PyCodeObject
CO_OPTIMIZED = $0001;
@@ -172,23 +171,54 @@ interface
Py_NE = 3;
Py_GT = 4;
Py_GE = 5;
+
+ {$IFDEF CPUARM}
+ DEFAULT_CALLBACK_TYPE: TCallType = TCallType.ctARMSTD;
+ {$ELSE}
+ DEFAULT_CALLBACK_TYPE: TCallType = TCallType.ctCDECL;
+ {$ENDIF CPUARM}
+
type
// Delphi equivalent used by TPyObject
TRichComparisonOpcode = (pyLT, pyLE, pyEQ, pyNE, pyGT, pyGE);
+
+
+// C long is 8 bytes in non-Windows 64-bit operating systems
+// Same Delphi's LongInt but not fpc LongInt which is always 4 bytes
+// Hence the following
+{$IFDEF MSWINDOWS}
+ C_Long = Integer;
+ C_ULong = Cardinal;
+{$ELSE}
+ C_Long = NativeInt;
+ C_ULong = NativeUInt;
+{$ENDIF}
+
+// wchar_t is 4 bytes on Linux/OS X/Android but 2 bytes on Windows
+{$IFDEF POSIX}
+ PWCharT = PUCS4Char;
+ PPWCharT = ^PUCS4Char;
+ WCharTString = UCS4String;
+{$ELSE}
+ PWCharT = PWideChar;
+ PPWCharT = PPWideChar;
+ WCharTString = UnicodeString;
+{$ENDIF}
+
const
-{Type flags (tp_flags) introduced in version 2.0
+{
+Type flags (tp_flags)
-These flags are used to extend the type structure in a backwards-compatible
-fashion. Extensions can use the flags to indicate (and test) when a given
-type structure contains a new feature. The Python core will use these when
-introducing new functionality between major revisions (to avoid mid-version
-changes in the PYTHON_API_VERSION).
+These flags are used to change expected features and behavior for a
+particular type.
Arbitration of the flag bit positions will need to be coordinated among
-all extension writers who publically release their extensions (this will
-be fewer than you might expect!)..
+all extension writers who publicly release their extensions (this will
+be fewer than you might expect!).
-Python 1.5.2 introduced the bf_getcharbuffer slot into PyBufferProcs.
+Most flags were removed as of Python 3.0 to make room for new flags. (Some
+flags are not for backwards compatibility but to indicate the presence of an
+optional feature; these flags remain of course.)
Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value.
@@ -196,140 +226,80 @@ interface
given type object has a specified feature.
}
-// PyBufferProcs contains bf_getcharbuffer
- Py_TPFLAGS_HAVE_GETCHARBUFFER = (1 shl 0);
-
-// PySequenceMethods contains sq_contains
- Py_TPFLAGS_HAVE_SEQUENCE_IN = (1 shl 1);
-
-// Objects which participate in garbage collection (see objimp.h)
- Py_TPFLAGS_GC = (1 shl 2);
-
-// PySequenceMethods and PyNumberMethods contain in-place operators
- Py_TPFLAGS_HAVE_INPLACEOPS = (1 shl 3);
-
-// PyNumberMethods do their own coercion */
- Py_TPFLAGS_CHECKTYPES = (1 shl 4);
+// Set if the type object is dynamically allocated
+ Py_TPFLAGS_HEAPTYPE = (C_ULong(1) shl 9);
- Py_TPFLAGS_HAVE_RICHCOMPARE = (1 shl 5);
+// Set if the type allows subclassing
+ Py_TPFLAGS_BASETYPE = (C_ULong(1) shl 10);
-// Objects which are weakly referencable if their tp_weaklistoffset is >0
-// XXX Should this have the same value as Py_TPFLAGS_HAVE_RICHCOMPARE?
-// These both indicate a feature that appeared in the same alpha release.
+// Set if the type is 'ready' -- fully initialized
+ Py_TPFLAGS_READY = (C_ULong(1) shl 12);
- Py_TPFLAGS_HAVE_WEAKREFS = (1 shl 6);
+// Set while the type is being 'readied', to prevent recursive ready calls
+ Py_TPFLAGS_READYING = (C_ULong(1) shl 13);
-// tp_iter is defined
- Py_TPFLAGS_HAVE_ITER = (1 shl 7);
+// Objects support garbage collection (see objimp.h)
+ Py_TPFLAGS_HAVE_GC = (C_ULong(1) shl 14);
-// New members introduced by Python 2.2 exist
- Py_TPFLAGS_HAVE_CLASS = (1 shl 8);
+// Set if the type implements the vectorcall protocol (PEP 590) */
+ _Py_TPFLAGS_HAVE_VECTORCALL = (C_ULong(1) shl 11);
-// Set if the type object is dynamically allocated
- Py_TPFLAGS_HEAPTYPE = (1 shl 9);
+// Objects behave like an unbound method
+ Py_TPFLAGS_METHOD_DESCRIPTOR = (C_ULong(1) shl 17);
-// Set if the type allows subclassing
- Py_TPFLAGS_BASETYPE = (1 shl 10);
+// Objects support type attribute cache
+ Py_TPFLAGS_HAVE_VERSION_TAG = (C_ULong(1) shl 18);
+ Py_TPFLAGS_VALID_VERSION_TAG = (C_ULong(1) shl 19);
-// Set if the type is 'ready' -- fully initialized
- Py_TPFLAGS_READY = (1 shl 12);
+// Type is abstract and cannot be instantiated
+ Py_TPFLAGS_IS_ABSTRACT = (C_ULong(1) shl 20);
-// Set while the type is being 'readied', to prevent recursive ready calls
- Py_TPFLAGS_READYING = (1 shl 13);
+// These flags are used to determine if a type is a subclass.
+ Py_TPFLAGS_LONG_SUBCLASS = (C_ULong(1) shl 24);
+ Py_TPFLAGS_LIST_SUBCLASS = (C_ULong(1) shl 25);
+ Py_TPFLAGS_TUPLE_SUBCLASS = (C_ULong(1) shl 26);
+ Py_TPFLAGS_BYTES_SUBCLASS = (C_ULong(1) shl 27);
+ Py_TPFLAGS_UNICODE_SUBCLASS = (C_ULong(1) shl 28);
+ Py_TPFLAGS_DICT_SUBCLASS = (C_ULong(1) shl 29);
+ Py_TPFLAGS_BASE_EXC_SUBCLASS = (C_ULong(1) shl 30);
+ Py_TPFLAGS_TYPE_SUBCLASS = (C_ULong(1) shl 31);
-// Objects support garbage collection (see objimp.h)
- Py_TPFLAGS_HAVE_GC = (1 shl 14);
-
- Py_TPFLAGS_DEFAULT = Py_TPFLAGS_HAVE_GETCHARBUFFER
- or Py_TPFLAGS_HAVE_SEQUENCE_IN
- or Py_TPFLAGS_HAVE_INPLACEOPS
- or Py_TPFLAGS_HAVE_RICHCOMPARE
- or Py_TPFLAGS_HAVE_WEAKREFS
- or Py_TPFLAGS_HAVE_ITER
- or Py_TPFLAGS_HAVE_CLASS
- or Py_TPFLAGS_BASETYPE
- ;
+ Py_TPFLAGS_DEFAULT = Py_TPFLAGS_BASETYPE or Py_TPFLAGS_HAVE_VERSION_TAG;
// See function PyType_HasFeature below for testing the flags.
// Delphi equivalent used by TPythonType
type
- TPFlag = (tpfHaveGetCharBuffer, tpfHaveSequenceIn, tpfGC, tpfHaveInplaceOps,
- tpfCheckTypes, tpfHaveRichCompare, tpfHaveWeakRefs
- ,tpfHaveIter, tpfHaveClass, tpfHeapType, tpfBaseType, tpfReady, tpfReadying, tpfHaveGC
- );
+ TPFlag = (tpfHeapType, tpfBaseType, tpfReady, tpfReadying, tpfHaveGC,
+ tpVectorCall, tpMethodDescriptor, tpHaveVersionTag,
+ tpValidVersionTag, tpIsAbstract, tpLongSubclass,
+ tpListSubClass, tpTupleSubclass, tpBytesSubclass,
+ tpBaseExcSubclass, tpTypeSubclass);
TPFlags = set of TPFlag;
const
- TPFLAGS_DEFAULT = [tpfHaveSequenceIn, tpfHaveInplaceOps,
- tpfHaveRichCompare, tpfHaveIter,
- tpfHaveClass, tpfBaseType
- ];
+ TPFLAGS_DEFAULT = [tpfBaseType, tpHaveVersionTag];
+
//------- Python opcodes ----------//
-Const
+const
single_input = 256;
file_input = 257;
eval_input = 258;
- p4d_funcdef = 259;
- p4d_parameters = 260;
- p4d_varargslist = 261;
- p4d_fpdef = 262;
- p4d_fplist = 263;
- p4d_stmt = 264;
- p4d_simple_stmt = 265;
- p4d_small_stmt = 266;
- p4d_expr_stmt = 267;
- p4d_augassign = 268;
- p4d_print_stmt = 269;
- p4d_del_stmt = 270;
- p4d_pass_stmt = 271;
- p4d_flow_stmt = 272;
- p4d_break_stmt = 273;
- p4d_continue_stmt = 274;
- p4d_return_stmt = 275;
- p4d_raise_stmt = 276;
- p4d_import_stmt = 277;
- p4d_import_as_name = 278;
- p4d_dotted_as_name = 279;
- p4d_dotted_name = 280;
- p4d_global_stmt = 281;
- p4d_exec_stmt = 282;
- p4d_assert_stmt = 283;
- p4d_compound_stmt = 284;
- p4d_if_stmt = 285;
- p4d_while_stmt = 286;
- p4d_for_stmt = 287;
- p4d_try_stmt = 288;
- p4d_except_clause = 289;
- p4d_suite = 290;
- p4d_test = 291;
- p4d_and_test = 291;
- p4d_not_test = 293;
- p4d_comparison = 294;
- p4d_comp_op = 295;
- p4d_expr = 296;
- p4d_xor_expr = 297;
- p4d_and_expr = 298;
- p4d_shift_expr = 299;
- p4d_arith_expr = 300;
- p4d_term = 301;
- p4d_factor = 302;
- p4d_power = 303;
- p4d_atom = 304;
- p4d_listmaker = 305;
- p4d_lambdef = 306;
- p4d_trailer = 307;
- p4d_subscriptlist = 308;
- p4d_subscript = 309;
- p4d_sliceop = 310;
- p4d_exprlist = 311;
- p4d_testlist = 312;
- p4d_dictmaker = 313;
- p4d_classdef = 314;
- p4d_arglist = 315;
- p4d_argument = 316;
- p4d_list_iter = 317;
- p4d_list_for = 318;
- p4d_list_if = 319;
+
+ // UnicodeObject.h
+ const
+ // Return values of the PyUnicode_KIND() macro
+
+ {
+ PyUnicode_WCHAR_KIND is deprecated. Will be removed in Python 12.
+ String contains only wstr byte characters. This is only possible
+ when the string was created with a legacy API and _PyUnicode_Ready()
+ has not been called yet.
+ }
+ PyUnicode_WCHAR_KIND = 0;
+
+ PyUnicode_1BYTE_KIND = 1;
+ PyUnicode_2BYTE_KIND = 2;
+ PyUnicode_4BYTE_KIND = 4;
// structmember.h
const
@@ -376,14 +346,11 @@ interface
//#######################################################
const
- ErrInit = -300;
CR = #13;
LF = #10;
TAB = #09;
CRLF = CR+LF;
-
-
//#######################################################
//## ##
//## Global declarations, nothing Python specific ##
@@ -414,7 +381,6 @@ interface
PPyObject = ^PyObject;
PPPyObject = ^PPyObject;
PPPPyObject = ^PPPyObject;
- PPyIntObject = ^PyIntObject;
PPyTypeObject = ^PyTypeObject;
PPySliceObject = ^PySliceObject;
@@ -429,30 +395,18 @@ interface
lenfunc = function( ob1 : PPyObject): NativeInt; cdecl;
coercion = function( ob1,ob2 : PPPyObject): integer; cdecl;
ssizeargfunc = function( ob1 : PPyObject; i: NativeInt): PPyObject; cdecl;
- ssizessizeargfunc = function( ob1 : PPyObject; i1, i2: NativeInt):
- PPyObject; cdecl;
ssizeobjargproc = function( ob1 : PPyObject; i: NativeInt; ob2 : PPyObject):
integer; cdecl;
- ssizessizeobjargproc = function( ob1: PPyObject; i1, i2: NativeInt;
- ob2: PPyObject): integer; cdecl;
objobjargproc = function( ob1,ob2,ob3 : PPyObject): integer; cdecl;
pydestructor = procedure(ob: PPyObject); cdecl;
- printfunc = function( ob: PPyObject; var f: file; i: integer): integer; cdecl;
getattrfunc = function( ob1: PPyObject; name: PAnsiChar): PPyObject; cdecl;
setattrfunc = function( ob1: PPyObject; name: PAnsiChar; ob2: PPyObject): integer; cdecl;
- cmpfunc = function( ob1,ob2: PPyObject): integer; cdecl;
reprfunc = function( ob: PPyObject): PPyObject; cdecl;
hashfunc = function( ob: PPyObject): NativeInt; cdecl; // !! in 2.x it is still a LongInt
getattrofunc = function( ob1,ob2: PPyObject): PPyObject; cdecl;
setattrofunc = function( ob1,ob2,ob3: PPyObject): integer; cdecl;
-/// jah 29-sep-2000 : updated for python 2.0
-/// added from object.h
- getreadbufferproc = function ( ob1: PPyObject; i: NativeInt; ptr: Pointer): NativeInt; cdecl;
- getwritebufferproc= function ( ob1: PPyObject; i: NativeInt; ptr: Pointer): NativeInt; cdecl;
- getsegcountproc = function ( ob1: PPyObject; i: NativeInt): NativeInt; cdecl;
- getcharbufferproc = function ( ob1: PPyObject; i: NativeInt; const pstr: PAnsiChar): NativeInt; cdecl;
objobjproc = function ( ob1, ob2: PPyObject): integer; cdecl;
visitproc = function ( ob1: PPyObject; ptr: Pointer): integer; cdecl;
traverseproc = function ( ob1: PPyObject; proc: visitproc; ptr: Pointer): integer; cdecl;
@@ -466,50 +420,7 @@ interface
newfunc = function ( subtype: PPyTypeObject; args, kwds : PPyObject) : PPyObject; cdecl;
allocfunc = function ( self: PPyTypeObject; nitems : NativeInt) : PPyObject; cdecl;
- PyNumberMethods200 = {$IFNDEF CPUX64}packed{$ENDIF} record
- nb_add : binaryfunc;
- nb_subtract : binaryfunc;
- nb_multiply : binaryfunc;
- nb_divide : binaryfunc;
- nb_remainder : binaryfunc;
- nb_divmod : binaryfunc;
- nb_power : ternaryfunc;
- nb_negative : unaryfunc;
- nb_positive : unaryfunc;
- nb_absolute : unaryfunc;
- nb_nonzero : inquiry;
- nb_invert : unaryfunc;
- nb_lshift : binaryfunc;
- nb_rshift : binaryfunc;
- nb_and : binaryfunc;
- nb_xor : binaryfunc;
- nb_or : binaryfunc;
- nb_coerce : coercion;
- nb_int : unaryfunc;
- nb_long : unaryfunc;
- nb_float : unaryfunc;
- nb_oct : unaryfunc;
- nb_hex : unaryfunc;
- nb_inplace_add : binaryfunc;
- nb_inplace_subtract : binaryfunc;
- nb_inplace_multiply : binaryfunc;
- nb_inplace_divide : binaryfunc;
- nb_inplace_remainder : binaryfunc;
- nb_inplace_power : ternaryfunc;
- nb_inplace_lshift : binaryfunc;
- nb_inplace_rshift : binaryfunc;
- nb_inplace_and : binaryfunc;
- nb_inplace_xor : binaryfunc;
- nb_inplace_or : binaryfunc;
- nb_floor_divide : binaryfunc;
- nb_true_divide : binaryfunc;
- nb_inplace_floor_divide : binaryfunc;
- nb_inplace_true_divide : binaryfunc;
- nb_index : unaryfunc;
- end;
- PPyNumberMethods200 = ^PyNumberMethods200;
-
- PyNumberMethods300 = {$IFNDEF CPUX64}packed{$ENDIF} record
+ PyNumberMethods = {$IFNDEF CPUX64}packed{$ENDIF} record
nb_add : binaryfunc;
nb_subtract : binaryfunc;
nb_multiply : binaryfunc;
@@ -547,22 +458,19 @@ interface
nb_matrix_multiply : binaryfunc; // new in python 3.5
nb_inplace_matrix_multiply : binaryfunc; // new in python 3.5
end;
- PPyNumberMethods300 = ^PyNumberMethods300;
+ PPyNumberMethods = ^PyNumberMethods;
PySequenceMethods = {$IFNDEF CPUX64}packed{$ENDIF} record
sq_length : lenfunc;
sq_concat : binaryfunc;
sq_repeat : ssizeargfunc;
sq_item : ssizeargfunc;
- sq_slice : ssizessizeargfunc;
+ was_sq_slice : Pointer; // empty slot in python 3.x
sq_ass_item : ssizeobjargproc;
- sq_ass_slice : ssizessizeobjargproc;
-
-/// jah 29-sep-2000 : updated for python 2.0
-/// added from .h
- sq_contains : objobjproc;
- sq_inplace_concat : binaryfunc;
- sq_inplace_repeat : ssizeargfunc;
+ was_sq_ass_slice : Pointer; // empty slot in python 3.x
+ sq_contains : objobjproc;
+ sq_inplace_concat : binaryfunc;
+ sq_inplace_repeat : ssizeargfunc;
end;
PPySequenceMethods = ^PySequenceMethods;
@@ -573,16 +481,6 @@ interface
end;
PPyMappingMethods = ^PyMappingMethods;
-/// jah 29-sep-2000 : updated for python 2.0
-/// added from .h
- PyBufferProcs = {$IFNDEF CPUX64}packed{$ENDIF} record
- bf_getreadbuffer : getreadbufferproc;
- bf_getwritebuffer : getwritebufferproc;
- bf_getsegcount : getsegcountproc;
- bf_getcharbuffer : getcharbufferproc;
- end;
- PPyBufferProcs = ^PyBufferProcs;
-
Py_complex = {$IFNDEF CPUX64}packed{$ENDIF} record
real : double;
imag : double;
@@ -593,12 +491,6 @@ interface
ob_type: PPyTypeObject;
end;
- PyIntObject = {$IFNDEF CPUX64}packed{$ENDIF} record
- ob_refcnt : NativeInt;
- ob_type : PPyTypeObject;
- ob_ival : LongInt;
- end;
-
_frozen = {$IFNDEF CPUX64}packed{$ENDIF} record
name : PAnsiChar;
code : PByte;
@@ -754,21 +646,21 @@ interface
ob_refcnt: NativeInt;
ob_type: PPyTypeObject;
ob_size: NativeInt; // Number of items in variable part
- tp_name: PAnsiChar; // For printing
+ tp_name: PAnsiChar; // For printing
tp_basicsize, tp_itemsize: NativeInt; // For allocation
// Methods to implement standard operations
- tp_dealloc: pydestructor;
- tp_print: printfunc; // not available and replaced in Python 3.x
- tp_getattr: getattrfunc;
- tp_setattr: setattrfunc;
- tp_compare: cmpfunc; // not available and replaced in Python 3.x
- tp_repr: reprfunc;
+ tp_dealloc: pydestructor;
+ tp_vectorcall_offset: NativeInt;
+ tp_getattr: getattrfunc;
+ tp_setattr: setattrfunc;
+ tp_as_async: Pointer; // not implemented
+ tp_repr: reprfunc;
// Method suites for standard classes
- tp_as_number: Pointer; //PPyNumberMethods
+ tp_as_number: PPyNumberMethods;
tp_as_sequence: PPySequenceMethods;
tp_as_mapping: PPyMappingMethods;
@@ -781,9 +673,9 @@ interface
tp_setattro: setattrofunc;
// Functions to access object as input/output buffer
- tp_as_buffer: PPyBufferProcs;
+ tp_as_buffer: Pointer; // PPyBufferProcs - not implemented
// Flags to define presence of optional/expanded features
- tp_flags: LongInt;
+ tp_flags: C_ULong;
tp_doc: PAnsiChar; // Documentation string
@@ -822,8 +714,9 @@ interface
tp_subclasses : PPyObject;
tp_weaklist : PPyObject;
tp_del : PyDestructor;
- tp_version_tag : NativeUInt; // Type attribute cache version tag. Added in version 2.6
+ tp_version_tag : Cardinal; // Type attribute cache version tag. Added in version 2.6
tp_finalize : PyDestructor;
+ tp_vectorcall : Pointer; // not implemented
//More spares
tp_xxx1 : NativeInt;
tp_xxx2 : NativeInt;
@@ -837,212 +730,12 @@ interface
tp_xxx10 : NativeInt;
end;
- PPyMethodChain = ^PyMethodChain;
- PyMethodChain = {$IFNDEF CPUX64}packed{$ENDIF} record
- methods: PPyMethodDef;
- link: PPyMethodChain;
- end;
-
- PPyClassObject = ^PyClassObject;
- PyClassObject = {$IFNDEF CPUX64}packed{$ENDIF} record
- // Start of the Head of an object
- ob_refcnt : NativeInt;
- ob_type : PPyTypeObject;
- // End of the Head of an object
- cl_bases : PPyObject; // A tuple of class objects
- cl_dict : PPyObject; // A dictionary
- cl_name : PPyObject; // A string
- // The following three are functions or NULL
- cl_getattr : PPyObject;
- cl_setattr : PPyObject;
- cl_delattr : PPyObject;
- end;
-
- PPyInstanceObject = ^PyInstanceObject;
- PyInstanceObject = {$IFNDEF CPUX64}packed{$ENDIF} record
- // Start of the Head of an object
- ob_refcnt : NativeInt;
- ob_type : PPyTypeObject;
- // End of the Head of an object
- in_class : PPyClassObject; // The class object
- in_dict : PPyObject; // A dictionary
- end;
-
-{ Instance method objects are used for two purposes:
- (a) as bound instance methods (returned by instancename.methodname)
- (b) as unbound methods (returned by ClassName.methodname)
- In case (b), im_self is NULL
-}
-
- PPyMethodObject = ^PyMethodObject;
- PyMethodObject = {$IFNDEF CPUX64}packed{$ENDIF} record
- // Start of the Head of an object
- ob_refcnt : NativeInt;
- ob_type : PPyTypeObject;
- // End of the Head of an object
- im_func : PPyObject; // The function implementing the method
- im_self : PPyObject; // The instance it is bound to, or NULL
- im_class : PPyObject; // The class that defined the method
- end;
-
-
- // Bytecode object, compile.h
- PPyCodeObject = ^PyCodeObject;
- PyCodeObject = {$IFNDEF CPUX64}packed{$ENDIF} record
- ob_refcnt : NativeInt;
- ob_type : PPyTypeObject;
- co_argcount : Integer; // #arguments, except *args
- co_nlocals : Integer; // #local variables
- co_stacksize : Integer; // #entries needed for evaluation stack
- co_flags : Integer; // CO_..., see below
- co_code : PPyObject; // instruction opcodes (it hides a PyStringObject)
- co_consts : PPyObject; // list (constants used)
- co_names : PPyObject; // list of strings (names used)
- co_varnames : PPyObject; // tuple of strings (local variable names)
- co_freevars : PPyObject; // tuple of strings (free variable names)
- co_cellvars : PPyObject; // tuple of strings (cell variable names)
- // The rest doesn't count for hash/cmp
- co_filename : PPyObject; // string (where it was loaded from)
- co_name : PPyObject; // string (name, for reference)
- co_firstlineno : Integer; // first source line number
- co_lnotab : PPyObject; // string (encoding addr<->lineno mapping)
- end;
-
-
// from pystate.h
- PPyInterpreterState = ^PyInterpreterState;
- PPyThreadState = ^PyThreadState;
- PPyFrameObject = ^PyFrameObject;
-
- // Interpreter environments
- PyInterpreterState = {$IFNDEF CPUX64}packed{$ENDIF} record
- next : PPyInterpreterState;
- tstate_head : PPyThreadState;
-
-// The strucure has changed between versions beyond this point.
-// Not safe to use members
-// modules : PPyObject;
-// sysdict : PPyObject;
-// builtins : PPyObject;
-
- //Spares
- is_xxx1 : NativeInt;
- is_xxx2 : NativeInt;
- is_xxx3 : NativeInt;
- is_xxx4 : NativeInt;
- is_xxx5 : NativeInt;
- is_xxx6 : NativeInt;
- is_xxx7 : NativeInt;
- is_xxx8 : NativeInt;
- is_xxx9 : NativeInt;
- end;
-
- // Thread specific information
- PyThreadState = {$IFNDEF CPUX64}packed{$ENDIF} record
- {prev : PPyThreadState; introduced in python 3.4}
- next : PPyThreadState;
- interp : PPyInterpreterState;
- interp34 : PPyInterpreterState;
-
-// The strucure has changed between versions beyond this point.
-// Not safe to use members
-//
-// frame : PPyFrameObject;
-// recursion_depth: integer;
-// ticker : integer;
-// tracing : integer;
-//
-// sys_profilefn : Pointer; // c-functions for profile/trace
-// sys_tracefn : Pointer;
-// sys_profilefunc: PPyObject;
-// sys_tracefunc : PPyObject;
-//
-// curexc_type : PPyObject;
-// curexc_value : PPyObject;
-// curexc_traceback: PPyObject;
-//
-// exc_type : PPyObject;
-// exc_value : PPyObject;
-// exc_traceback : PPyObject;
-//
-// dict : PPyObject;
-// tick_counter :Integer;
-// gilstate_counter :Integer;
-//
-// async_exc :PPyObject; { Asynchronous exception to raise }
-// thread_id :LongInt; { Thread id where this tstate was created }
- //Spares
- ts_xxx1 : NativeInt;
- ts_xxx2 : NativeInt;
- ts_xxx3 : NativeInt;
- ts_xxx4 : NativeInt;
- ts_xxx5 : NativeInt;
- ts_xxx6 : NativeInt;
- ts_xxx7 : NativeInt;
- ts_xxx8 : NativeInt;
- ts_xxx9 : NativeInt;
- ts_xxx10 : NativeInt;
- ts_xxx11 : NativeInt;
- ts_xxx12 : NativeInt;
- ts_xxx13 : NativeInt;
- ts_xxx14 : NativeInt;
- ts_xxx15 : NativeInt;
- ts_xxx16 : NativeInt;
- ts_xxx17 : NativeInt;
- ts_xxx18 : NativeInt;
- ts_xxx19 : NativeInt;
-
- { XXX signal handlers should also be here }
- end;
-
- // from frameobject.h
-
- PPyTryBlock = ^PyTryBlock;
- PyTryBlock = {$IFNDEF CPUX64}packed{$ENDIF} record
- b_type : Integer; // what kind of block this is
- b_handler : Integer; // where to jump to find handler
- b_level : Integer; // value stack level to pop to
- end;
-
- CO_MAXBLOCKS = 0..19;
- PyFrameObject = {$IFNDEF CPUX64}packed{$ENDIF} record
- // Start of the VAR_HEAD of an object.
- ob_refcnt : NativeInt;
- ob_type : PPyTypeObject;
- ob_size : NativeInt; // Number of items in variable part
- // End of the Head of an object
- f_back : PPyFrameObject; // previous frame, or NULL
- f_code : PPyCodeObject; // code segment
- f_builtins : PPyObject; // builtin symbol table (PyDictObject)
- f_globals : PPyObject; // global symbol table (PyDictObject)
- f_locals : PPyObject; // local symbol table (PyDictObject)
- f_valuestack : PPPyObject; // points after the last local
- (* Next free slot in f_valuestack. Frame creation sets to f_valuestack.
- Frame evaluation usually NULLs it, but a frame that yields sets it
- to the current stack top. *)
- f_stacktop : PPPyObject;
- f_trace : PPyObject; // Trace function
- f_exc_type, f_exc_value, f_exc_traceback: PPyObject;
- f_tstate : PPyThreadState;
- f_lasti : Integer; // Last instruction if called
- f_lineno : Integer; // Current line number
- f_iblock : Integer; // index in f_blockstack
- f_blockstack : array[CO_MAXBLOCKS] of PyTryBlock; // for try and loop blocks
- f_localsplus : array[0..0] of PPyObject; // locals+stack, dynamically sized
- end;
-
- // From traceback.c
- PPyTraceBackObject = ^PyTraceBackObject;
- PyTraceBackObject = {$IFNDEF CPUX64}packed{$ENDIF} record
- // Start of the Head of an object
- ob_refcnt : NativeInt;
- ob_type : PPyTypeObject;
- // End of the Head of an object
- tb_next : PPyTraceBackObject;
- tb_frame : PPyFrameObject;
- tb_lasti : Integer;
- tb_lineno : Integer;
- end;
+ // the structure of PyInterpreterState and PyThreadState is considered
+ // an implementation detail. It has been changing between python versions
+ // and there is no real use of accessing these structures directly.
+ PPyInterpreterState = Pointer;
+ PPyThreadState = Pointer;
// Parse tree node interface
@@ -1059,22 +752,11 @@ interface
PPyCompilerFlags = ^PyCompilerFlags;
PyCompilerFlags = {$IFNDEF CPUX64}packed{$ENDIF} record
flags : integer;
+ cf_feature_version : integer; //added in Python 3.8
end;
- // From weakrefobject.h
-
- PPyWeakReference = ^PyWeakReference;
- PyWeakReference = {$IFNDEF CPUX64}packed{$ENDIF} record
- // Start of the Head of an object
- ob_refcnt : NativeInt;
- ob_type : PPyTypeObject;
- // End of the Head of an object
- wr_object : PPyObject;
- wr_callback : PPyObject;
- hash : NativeInt;
- wr_prev : PPyWeakReference;
- wr_next : PPyWeakReference;
- end;
+ const
+ PyCF_ONLY_AST = $0400;
// from datetime.h
@@ -1371,10 +1053,12 @@ EPyRuntimeError = class (EPyStandardError);
EPyNotImplementedError = class (EPyRuntimeError);
EPySyntaxError = class (EPyStandardError)
public
- EFileName: AnsiString;
- ELineStr: AnsiString;
+ EFileName: UnicodeString;
+ ELineStr: UnicodeString;
ELineNumber: Integer;
EOffset: Integer;
+ EEndLineNumber: Integer;
+ EEndOffset: Integer;
end;
EPyIndentationError = class (EPySyntaxError);
EPyTabError = class (EPyIndentationError);
@@ -1552,26 +1236,22 @@ TDynamicDll = class(TComponent)
//-------------------------------------------------------
type
+ (*$HPPEMIT 'typedef int __cdecl (*TPyArg_Parse)(void * args, char * format, ...);' *)
+ TPyArg_Parse = function( args: PPyObject; format: PAnsiChar {;....}) : Integer; cdecl varargs;
+ {$EXTERNALSYM TPyArg_Parse}
- { TPythonInterface }
-
- TPythonInterface=class(TDynamicDll)
- private
- DLL_Py_GetBuildInfo:
- function : PAnsiChar; cdecl;
- DLL_PyCode_Addr2Line:
- function ( co: PPyCodeObject; addrq : Integer ) : Integer; cdecl;
- DLL_PyImport_ExecCodeModule:
- function ( const name : AnsiString; codeobject : PPyObject) : PPyObject; cdecl;
+ (*$HPPEMIT 'typedef int __cdecl (*TPyArg_ParseTupleAndKeywords)(void * args, void * kw, char * format, char** kwargs, ...);' *)
+ TPyArg_ParseTupleAndKeywords = function( args: PPyObject; kw: PPyObject; format: PAnsiChar; kwargs: PPAnsiChar {;...}): Integer; cdecl varargs;
+ {$EXTERNALSYM TPyArg_ParseTupleAndKeywords}
- DLL_PyString_FromString: function( str: PAnsiChar): PPyObject; cdecl;
- DLL_Py_FlushLine:procedure; cdecl;
- procedure DetectPythonVersionFromLibName(const Str: AnsiString);
+ (*$HPPEMIT 'typedef int __cdecl (*TPy_BuildValue)(char * format, ...);' *)
+ TPy_BuildValue = function( format: PAnsiChar {;...}): Pointer; cdecl varargs;
+ {$EXTERNALSYM TPy_BuildValue}
+ TPythonInterface=class(TDynamicDll)
protected
FInitialized: Boolean;
FFinalizing: Boolean;
- FIsPython3000: Boolean;
FMajorVersion: integer;
FMinorVersion: integer;
FBuiltInModuleName: String;
@@ -1579,7 +1259,6 @@ TPythonInterface=class(TDynamicDll)
procedure AfterLoad; override;
function GetQuitMessage : String; override;
procedure CheckPython;
- function GetUnicodeTypeSuffix : String;
public
// define Python flags. See file pyDebug.h
@@ -1588,21 +1267,15 @@ TPythonInterface=class(TDynamicDll)
Py_InteractiveFlag: PInt;
Py_OptimizeFlag: PInt;
Py_NoSiteFlag: PInt;
- Py_UseClassExceptionsFlag: PInt;
Py_FrozenFlag: PInt;
- Py_TabcheckFlag: PInt;
- Py_UnicodeFlag: PInt;
Py_IgnoreEnvironmentFlag: PInt;
- Py_DivisionWarningFlag: PInt;
- //_PySys_TraceFunc: PPPyObject;
- //_PySys_ProfileFunc: PPPPyObject;
PyImport_FrozenModules: PP_frozen;
Py_None: PPyObject;
Py_Ellipsis: PPyObject;
- Py_False: PPyIntObject;
- Py_True: PPyIntObject;
+ Py_False: PPyObject;
+ Py_True: PPyObject;
Py_NotImplemented: PPyObject;
PyExc_AttributeError: PPPyObject;
@@ -1626,11 +1299,9 @@ TPythonInterface=class(TDynamicDll)
PyExc_Exception: PPPyObject;
PyExc_FloatingPointError: PPPyObject;
PyExc_LookupError: PPPyObject;
- PyExc_StandardError: PPPyObject;
PyExc_AssertionError: PPPyObject;
PyExc_EnvironmentError: PPPyObject;
PyExc_IndentationError: PPPyObject;
- PyExc_MemoryErrorInst: PPPyObject;
PyExc_NotImplementedError: PPPyObject;
PyExc_OSError: PPPyObject;
PyExc_TabError: PPPyObject;
@@ -1652,19 +1323,14 @@ TPythonInterface=class(TDynamicDll)
PyExc_UnicodeEncodeError: PPPyObject;
PyExc_UnicodeTranslateError: PPPyObject;
+ PyCode_Type: PPyTypeObject;
PyType_Type: PPyTypeObject;
PyCFunction_Type: PPyTypeObject;
- PyCObject_Type: PPyTypeObject;
- PyClass_Type: PPyTypeObject;
- PyCode_Type: PPyTypeObject;
PyComplex_Type: PPyTypeObject;
PyDict_Type: PPyTypeObject;
- PyFile_Type: PPyTypeObject;
PyFloat_Type: PPyTypeObject;
PyFrame_Type: PPyTypeObject;
PyFunction_Type: PPyTypeObject;
- PyInstance_Type: PPyTypeObject;
- PyInt_Type: PPyTypeObject;
PyList_Type: PPyTypeObject;
PyLong_Type: PPyTypeObject;
PyMethod_Type: PPyTypeObject;
@@ -1672,10 +1338,9 @@ TPythonInterface=class(TDynamicDll)
PyObject_Type: PPyTypeObject;
PyRange_Type: PPyTypeObject;
PySlice_Type: PPyTypeObject;
- PyString_Type: PPyTypeObject;
+ PyBytes_Type: PPyTypeObject;
PyTuple_Type: PPyTypeObject;
PyBaseObject_Type: PPyTypeObject;
- PyBuffer_Type: PPyTypeObject;
PyCallIter_Type: PPyTypeObject;
PyCell_Type: PPyTypeObject;
PyClassMethod_Type: PPyTypeObject;
@@ -1689,20 +1354,11 @@ TPythonInterface=class(TDynamicDll)
_PyWeakref_RefType: PPyTypeObject;
_PyWeakref_ProxyType: PPyTypeObject;
_PyWeakref_CallableProxyType: PPyTypeObject;
- PyBaseString_Type: PPyTypeObject;
PyBool_Type: PPyTypeObject;
PyEnum_Type: PPyTypeObject;
- //PyArg_GetObject: function(args : PPyObject; nargs, i: integer; p_a: PPPyObject): integer; cdecl;
- //PyArg_GetLong: function(args : PPyObject; nargs, i: integer; p_a: PLong): integer; cdecl;
- //PyArg_GetShort: function(args : PPyObject; nargs, i: integer; p_a: PShort): integer; cdecl;
- //PyArg_GetFloat: function(args : PPyObject; nargs, i: integer; p_a: PFloat): integer; cdecl;
- //PyArg_GetString: function(args : PPyObject; nargs, i: integer; p_a: PAnsiString): integer; cdecl;
- //PyArgs_VaParse: function (args : PPyObject; format: PAnsiChar; va_list: array of const): integer; cdecl;
- // Does not work!
- // Py_VaBuildValue: function (format: PAnsiChar; va_list: array of const): PPyObject; cdecl;
- //PyBuiltin_Init: procedure; cdecl;
-
+ Py_GetBuildInfo: function : PAnsiChar; cdecl;
+ PyImport_ExecCodeModule: function ( const name : AnsiString; codeobject : PPyObject) : PPyObject; cdecl;
PyComplex_FromCComplex: function(c: Py_complex):PPyObject; cdecl;
PyComplex_FromDoubles: function(realv,imag : double):PPyObject; cdecl;
PyComplex_RealAsDouble: function(op : PPyObject ): double; cdecl;
@@ -1711,19 +1367,13 @@ TPythonInterface=class(TDynamicDll)
PyCFunction_GetFunction: function(ob : PPyObject): Pointer; cdecl;
PyCFunction_GetSelf: function(ob : PPyObject): PPyObject; cdecl;
PyCallable_Check: function(ob : PPyObject): integer; cdecl;
- PyCObject_FromVoidPtr: function(cobj, destruct : Pointer): PPyObject; cdecl;
- PyCObject_AsVoidPtr: function(ob : PPyObject): Pointer; cdecl;
- PyClass_New: function (ob1,ob2,ob3 : PPyObject): PPyObject; cdecl;
- PyClass_IsSubclass: function (ob1, ob2 : PPyObject): integer cdecl;
- Py_InitModule4: function( name: PAnsiChar; methods: PPyMethodDef; doc: PAnsiChar;
- passthrough: PPyObject; Api_Version: Integer):PPyObject; cdecl;
PyModule_Create2: function(moduledef: PPyModuleDef; Api_Version: Integer):PPyObject; cdecl;
PyErr_BadArgument: function: integer; cdecl;
PyErr_BadInternalCall: procedure; cdecl;
PyErr_CheckSignals: function: integer; cdecl;
PyErr_Clear: procedure; cdecl;
- PyErr_Fetch: procedure( errtype, errvalue, errtraceback: PPPyObject); cdecl;
+ PyErr_Fetch: procedure(out errtype, errvalue, errtraceback: PPyObject); cdecl;
PyErr_NoMemory: function: PPyObject; cdecl;
PyErr_Occurred: function: PPyObject; cdecl;
PyErr_Print: procedure; cdecl;
@@ -1735,11 +1385,12 @@ TPythonInterface=class(TDynamicDll)
PyErr_WarnEx: function (ob: PPyObject; text: PAnsiChar; stack_level: NativeInt): integer; cdecl;
PyErr_WarnExplicit: function (ob: PPyObject; text: PAnsiChar; filename: PAnsiChar; lineno: integer; module: PAnsiChar; registry: PPyObject): integer; cdecl;
PyImport_GetModuleDict: function: PPyObject; cdecl;
- PyInt_FromLong: function( x: LongInt):PPyObject; cdecl;
- PyArg_Parse: function( args: PPyObject; format: PAnsiChar {;....}) : Integer; cdecl varargs;
- PyArg_ParseTuple: function( args: PPyObject; format: PAnsiChar {;...}): Integer; cdecl varargs;
- PyArg_ParseTupleAndKeywords: function( args: PPyObject; kw: PPyObject; format: PAnsiChar; kwargs: PPAnsiChar {;...}): Integer; cdecl varargs;
- Py_BuildValue: function( format: PAnsiChar {;...}): PPyObject; cdecl varargs;
+
+ PyArg_Parse: TPyArg_Parse;
+ PyArg_ParseTuple: TPyArg_Parse;
+ PyArg_ParseTupleAndKeywords: TPyArg_ParseTupleAndKeywords;
+ Py_BuildValue: TPy_BuildValue;
+
Py_Initialize: procedure; cdecl;
Py_Exit: procedure( RetVal: Integer); cdecl;
PyEval_GetBuiltins: function: PPyObject; cdecl;
@@ -1753,6 +1404,7 @@ TPythonInterface=class(TDynamicDll)
PyDict_Values: function(mp: PPyObject):PPyObject; cdecl;
PyDict_Items: function(mp: PPyObject):PPyObject; cdecl;
PyDict_Size: function(mp: PPyObject):NativeInt; cdecl;
+ PyDict_Update: function (a: PPyObject; b: PPyObject):Integer; cdecl;
PyDict_DelItemString: function(dp : PPyObject;key : PAnsiChar ):integer; cdecl;
PyDict_New: function: PPyObject; cdecl;
PyDict_GetItemString: function( dp: PPyObject; key: PAnsiChar): PPyObject; cdecl;
@@ -1764,12 +1416,10 @@ TPythonInterface=class(TDynamicDll)
PyRun_String: function( str: PAnsiChar; start: Integer; globals: PPyObject;
locals: PPyObject): PPyObject; cdecl;
PyRun_SimpleString: function( str: PAnsiChar): Integer; cdecl;
- PyString_AsString: function( ob: PPyObject): PAnsiChar; cdecl;
- PyString_AsStringAndSize: function( ob: PPyObject; var buffer: PAnsiChar; var size: NativeInt): integer; cdecl;
- PySys_SetArgv: procedure( argc: Integer; argv: PPAnsiChar); cdecl;
- PySys_SetArgv3000: procedure( argc: Integer; argv: PPWideChar); cdecl;
+ PyBytes_AsString: function( ob: PPyObject): PAnsiChar; cdecl;
+ PyBytes_AsStringAndSize: function( ob: PPyObject; var buffer: PAnsiChar; var size: NativeInt): integer; cdecl;
+ PySys_SetArgv: procedure( argc: Integer; argv: PPWCharT); cdecl;
- PyCFunction_New: function(md:PPyMethodDef;ob:PPyObject):PPyObject; cdecl;
PyCFunction_NewEx: function(md:PPyMethodDef;self, ob:PPyObject):PPyObject; cdecl;
// Removed. Use PyEval_CallObjectWithKeywords with third argument nil
// PyEval_CallObject: function(callable_obj, args:PPyObject):PPyObject; cdecl;
@@ -1777,34 +1427,26 @@ TPythonInterface=class(TDynamicDll)
PyEval_GetFrame:function :PPyObject; cdecl;
PyEval_GetGlobals:function :PPyObject; cdecl;
PyEval_GetLocals:function :PPyObject; cdecl;
- //PyEval_GetOwner:function :PPyObject; cdecl;
- PyEval_GetRestricted:function :integer; cdecl;
PyEval_InitThreads:procedure; cdecl;
PyEval_RestoreThread:procedure( tstate: PPyThreadState); cdecl;
PyEval_SaveThread:function :PPyThreadState; cdecl;
- PyFile_FromString:function (pc1,pc2:PAnsiChar):PPyObject; cdecl;
PyFile_GetLine:function (ob:PPyObject;i:integer):PPyObject; cdecl;
- PyFile_Name:function (ob:PPyObject):PPyObject; cdecl;
- PyFile_SetBufSize:procedure(ob:PPyObject;i:integer); cdecl;
- PyFile_SoftSpace:function (ob:PPyObject;i:integer):integer; cdecl;
PyFile_WriteObject:function (ob1,ob2:PPyObject;i:integer):integer; cdecl;
PyFile_WriteString:procedure(s:PAnsiChar;ob:PPyObject); cdecl;
PyFloat_AsDouble:function (ob:PPyObject):DOUBLE; cdecl;
PyFloat_FromDouble:function (db:double):PPyObject; cdecl;
+ PyFloat_FromString:function (str:PPyObject):PPyObject; cdecl;
PyFunction_GetCode:function (ob:PPyObject):PPyObject; cdecl;
PyFunction_GetGlobals:function (ob:PPyObject):PPyObject; cdecl;
PyFunction_New:function (ob1,ob2:PPyObject):PPyObject; cdecl;
PyImport_AddModule:function (name:PAnsiChar):PPyObject; cdecl;
- PyImport_GetMagicNumber:function :LONGINT; cdecl;
+ PyImport_GetMagicNumber:function :C_Long; cdecl;
PyImport_ImportFrozenModule:function (key:PAnsiChar):integer; cdecl;
PyImport_ImportModule:function (name:PAnsiChar):PPyObject; cdecl;
PyImport_Import:function (name:PPyObject):PPyObject; cdecl;
- //PyImport_Init:procedure; cdecl;
PyImport_ReloadModule:function (ob:PPyObject):PPyObject; cdecl;
- PyInstance_New:function (obClass, obArg, obKW:PPyObject):PPyObject; cdecl;
- PyInt_AsLong:function (ob:PPyObject):LONGINT; cdecl;
PyList_Append:function (ob1,ob2:PPyObject):integer; cdecl;
PyList_AsTuple:function (ob:PPyObject):PPyObject; cdecl;
PyList_GetItem:function (ob:PPyObject;i:NativeInt):PPyObject; cdecl;
@@ -1817,15 +1459,16 @@ TPythonInterface=class(TDynamicDll)
PyList_Size:function (ob:PPyObject):NativeInt; cdecl;
PyList_Sort:function (ob:PPyObject):integer; cdecl;
PyLong_AsDouble:function (ob:PPyObject):DOUBLE; cdecl;
- PyLong_AsLong:function (ob:PPyObject):LONGINT; cdecl;
+ PyLong_AsLong:function (ob:PPyObject):C_Long; cdecl;
PyLong_FromDouble:function (db:double):PPyObject; cdecl;
- PyLong_FromLong:function (l:longint):PPyObject; cdecl;
+ PyLong_FromLong:function (l:C_Long):PPyObject; cdecl;
PyLong_FromString:function (pc:PAnsiChar;var ppc:PAnsiChar;i:integer):PPyObject; cdecl;
- PyLong_FromUnsignedLong:function(val:cardinal) : PPyObject; cdecl;
- PyLong_AsUnsignedLong:function(ob:PPyObject) : Cardinal; cdecl;
- PyLong_FromUnicode:function(ob:PPyObject; a, b : integer) : PPyObject; cdecl;
- PyLong_FromLongLong:function(val:Int64) : PPyObject; cdecl;
- PyLong_AsLongLong:function(ob:PPyObject) : Int64; cdecl;
+ PyLong_FromUnsignedLong:function(val:C_ULong): PPyObject; cdecl;
+ PyLong_AsUnsignedLong:function(ob:PPyObject): C_ULong; cdecl;
+ PyLong_FromUnicodeObject:function(ob:PPyObject; base : integer): PPyObject; cdecl;
+ PyLong_FromLongLong:function(val:Int64): PPyObject; cdecl;
+ PyLong_FromUnsignedLongLong:function(val:UInt64) : PPyObject; cdecl;
+ PyLong_AsLongLong:function(ob:PPyObject): Int64; cdecl;
PyLong_FromVoidPtr:function(p: Pointer): PPyObject; cdecl;
PyMapping_Check:function (ob:PPyObject):integer; cdecl;
PyMapping_GetItemString:function (ob:PPyObject;key:PAnsiChar):PPyObject; cdecl;
@@ -1833,7 +1476,8 @@ TPythonInterface=class(TDynamicDll)
PyMapping_HasKeyString:function (ob:PPyObject;key:PAnsiChar):integer; cdecl;
PyMapping_Length:function (ob:PPyObject):NativeInt; cdecl;
PyMapping_SetItemString:function (ob:PPyObject; key:PAnsiChar; value:PPyObject):integer; cdecl;
- PyMethod_Class:function (ob:PPyObject):PPyObject; cdecl;
+ PyMapping_Keys:function(mp: PPyObject):PPyObject; cdecl;
+ PyMapping_Values:function(mp: PPyObject):PPyObject; cdecl;
PyMethod_Function:function (ob:PPyObject):PPyObject; cdecl;
PyMethod_New:function (ob1,ob2,ob3:PPyObject):PPyObject; cdecl;
PyMethod_Self:function (ob:PPyObject):PPyObject; cdecl;
@@ -1843,13 +1487,10 @@ TPythonInterface=class(TDynamicDll)
PyNumber_Add:function (ob1,ob2:PPyObject):PPyObject; cdecl;
PyNumber_And:function (ob1,ob2:PPyObject):PPyObject; cdecl;
PyNumber_Check:function (ob:PPyObject):integer; cdecl;
- PyNumber_Coerce:function (var ob1,ob2:PPyObject):integer; cdecl;
- PyNumber_Divide:function (ob1,ob2:PPyObject):PPyObject; cdecl;
PyNumber_FloorDivide:function (ob1,ob2:PPyObject):PPyObject; cdecl;
PyNumber_TrueDivide:function (ob1,ob2:PPyObject):PPyObject; cdecl;
PyNumber_Divmod:function (ob1,ob2:PPyObject):PPyObject; cdecl;
PyNumber_Float:function (ob:PPyObject):PPyObject; cdecl;
- PyNumber_Int:function (ob:PPyObject):PPyObject; cdecl;
PyNumber_Invert:function (ob:PPyObject):PPyObject; cdecl;
PyNumber_Long:function (ob:PPyObject):PPyObject; cdecl;
PyNumber_Lshift:function (ob1,ob2:PPyObject):PPyObject; cdecl;
@@ -1862,17 +1503,16 @@ TPythonInterface=class(TDynamicDll)
PyNumber_Rshift:function (ob1,ob2:PPyObject):PPyObject; cdecl;
PyNumber_Subtract:function (ob1,ob2:PPyObject):PPyObject; cdecl;
PyNumber_Xor:function (ob1,ob2:PPyObject):PPyObject; cdecl;
- PyOS_InitInterrupts:procedure; cdecl;
PyOS_InterruptOccurred:function :integer; cdecl;
PyObject_CallObject:function (ob,args:PPyObject):PPyObject; cdecl;
PyObject_CallMethod : function ( obj : PPyObject; method, format : PAnsiChar {...}) : PPyObject; cdecl varargs;
- PyObject_Compare: function (ob1,ob2:PPyObject):integer; cdecl;
PyObject_RichCompare:function (ob1,ob2:PPyObject;opid:integer):PPyObject; cdecl;
PyObject_RichCompareBool:function (ob1,ob2:PPyObject;opid:integer):Integer; cdecl;
PyObject_GetAttr:function (ob1,ob2:PPyObject):PPyObject; cdecl;
PyObject_GetAttrString:function (ob:PPyObject;c:PAnsiChar):PPyObject; cdecl;
PyObject_GetItem:function (ob,key:PPyObject):PPyObject; cdecl;
PyObject_DelItem:function (ob,key:PPyObject):PPyObject; cdecl;
+ PyObject_HasAttr:function (ob, attr_name:PPyObject):integer; cdecl;
PyObject_HasAttrString:function (ob:PPyObject;key:PAnsiChar):integer; cdecl;
PyObject_Hash:function (ob:PPyObject):NativeInt; cdecl;
PyObject_IsTrue:function (ob:PPyObject):integer; cdecl;
@@ -1893,7 +1533,7 @@ TPythonInterface=class(TDynamicDll)
PyObject_Call:function (ob, args, kw:PPyObject):PPyObject; cdecl;
PyObject_GenericGetAttr:function (obj, name : PPyObject) : PPyObject; cdecl;
PyObject_GenericSetAttr:function (obj, name, value : PPyObject) : Integer; cdecl;
- PyObject_GC_Malloc:function (size:NativeUInt):PPyObject; cdecl;
+ PyObject_Malloc:function (size:NativeUInt):PPyObject; cdecl;
PyObject_GC_New:function (t:PPyTypeObject):PPyObject; cdecl;
PyObject_GC_NewVar:function (t:PPyTypeObject; size:NativeInt):PPyObject; cdecl;
PyObject_GC_Resize:function (t:PPyObject; newsize:NativeInt):PPyObject; cdecl;
@@ -1914,25 +1554,23 @@ TPythonInterface=class(TDynamicDll)
PySequence_DelSlice:function (ob:PPyObject;i1,i2:NativeInt):integer; cdecl;
PySequence_Tuple:function (ob:PPyObject):PPyObject; cdecl;
PySequence_Contains:function (ob, value:PPyObject):integer; cdecl;
+ PySequence_List:function (o:PPyObject):PPyObject; cdecl;
PySeqIter_New: function(obj : PPyObject) : PPyObject; cdecl;
PySlice_GetIndices:function (ob:PPySliceObject;length:NativeInt;var start,stop,step:NativeInt):integer; cdecl;
PySlice_GetIndicesEx:function (ob:PPySliceObject;length:NativeInt;var start,stop,step,slicelength:NativeInt):integer; cdecl;
PySlice_New:function (start,stop,step:PPyObject):PPyObject; cdecl;
- PyString_Concat:procedure(var ob1:PPyObject;ob2:PPyObject); cdecl;
- PyString_ConcatAndDel:procedure(var ob1:PPyObject;ob2:PPyObject); cdecl;
- PyString_Format:function (ob1,ob2:PPyObject):PPyObject; cdecl;
- PyString_FromStringAndSize:function (s:PAnsiChar;i:NativeInt):PPyObject; cdecl;
- PyString_Size:function (ob:PPyObject):NativeInt; cdecl;
- PyString_DecodeEscape:function(s:PAnsiChar; len:NativeInt; errors:PAnsiChar; unicode:NativeInt; recode_encoding:PAnsiChar):PPyObject; cdecl;
- PyString_Repr:function(ob:PPyObject; smartquotes:integer):PPyObject; cdecl;
+ PyBytes_Concat:procedure(var ob1:PPyObject;ob2:PPyObject); cdecl;
+ PyBytes_ConcatAndDel:procedure(var ob1:PPyObject;ob2:PPyObject); cdecl;
+ PyBytes_FromString:function (s:PAnsiChar):PPyObject; cdecl;
+ PyBytes_FromStringAndSize:function (s:PAnsiChar;i:NativeInt):PPyObject; cdecl;
+ PyBytes_Size:function (ob:PPyObject):NativeInt; cdecl;
+ PyBytes_DecodeEscape:function(s:PAnsiChar; len:NativeInt; errors:PAnsiChar; unicode:NativeInt; recode_encoding:PAnsiChar):PPyObject; cdecl;
+ PyBytes_Repr:function(ob:PPyObject; smartquotes:integer):PPyObject; cdecl;
PySys_GetObject:function (s:PAnsiChar):PPyObject; cdecl;
- //PySys_Init:procedure; cdecl;
PySys_SetObject:function (s:PAnsiChar;ob:PPyObject):integer; cdecl;
PySys_SetPath:procedure(path:PAnsiChar); cdecl;
- //PyTraceBack_Fetch:function :PPyObject; cdecl;
PyTraceBack_Here:function (p:pointer):integer; cdecl;
PyTraceBack_Print:function (ob1,ob2:PPyObject):integer; cdecl;
- //PyTraceBack_Store:function (ob:PPyObject):integer; cdecl;
PyTuple_GetItem:function (ob:PPyObject;i:NativeInt):PPyObject; cdecl;
PyTuple_GetSlice:function (ob:PPyObject;i1,i2:NativeInt):PPyObject; cdecl;
PyTuple_New:function (size:NativeInt):PPyObject; cdecl;
@@ -1942,52 +1580,49 @@ TPythonInterface=class(TDynamicDll)
PyType_GenericAlloc:function(atype: PPyTypeObject; nitems:NativeInt) : PPyObject; cdecl;
PyType_GenericNew:function(atype: PPyTypeObject; args, kwds : PPyObject) : PPyObject; cdecl;
PyType_Ready:function(atype: PPyTypeObject) : integer; cdecl;
- PyUnicode_FromWideChar:function (const w:PWideChar; size:NativeInt):PPyObject; cdecl;
- PyUnicode_AsWideChar:function (unicode: PPyObject; w:PWideChar; size:NativeInt):integer; cdecl;
+ PyUnicode_FromWideChar:function (const w:PWCharT; size:NativeInt):PPyObject; cdecl;
+ PyUnicode_FromString:function (s:PAnsiChar):PPyObject; cdecl;
+ PyUnicode_FromStringAndSize:function (s:PAnsiChar;i:NativeInt):PPyObject; cdecl;
+ PyUnicode_FromKindAndData:function (kind:integer;const buffer:pointer;size:NativeInt):PPyObject; cdecl;
+ PyUnicode_AsWideChar:function (unicode: PPyObject; w:PWCharT; size:NativeInt):integer; cdecl;
+ PyUnicode_AsUTF8:function (unicode: PPyObject):PAnsiChar; cdecl;
+ PyUnicode_AsUTF8AndSize:function (unicode: PPyObject; size: PNativeInt):PAnsiChar; cdecl;
PyUnicode_Decode:function (const s:PAnsiChar; size: NativeInt; const encoding : PAnsiChar; const errors: PAnsiChar):PPyObject; cdecl;
+ PyUnicode_DecodeUTF16:function (const s:PAnsiChar; size: NativeInt; const errors: PAnsiChar; byteoder: PInteger):PPyObject; cdecl;
PyUnicode_AsEncodedString:function (unicode:PPyObject; const encoding:PAnsiChar; const errors:PAnsiChar):PPyObject; cdecl;
PyUnicode_FromOrdinal:function (ordinal:integer):PPyObject; cdecl;
- PyUnicode_FromString:function (s:PAnsiChar):PPyObject; cdecl;
- PyUnicode_GetSize:function (unicode:PPyObject):NativeInt; cdecl;
+ PyUnicode_GetLength:function (unicode:PPyObject):NativeInt; cdecl;
PyWeakref_GetObject: function ( ref : PPyObject) : PPyObject; cdecl;
PyWeakref_NewProxy: function ( ob, callback : PPyObject) : PPyObject; cdecl;
PyWeakref_NewRef: function ( ob, callback : PPyObject) : PPyObject; cdecl;
PyWrapper_New: function ( ob1, ob2 : PPyObject) : PPyObject; cdecl;
PyBool_FromLong: function ( ok : Integer) : PPyObject; cdecl;
- PyThreadState_SetAsyncExc: function(t_id :LongInt; exc :PPyObject) : Integer; cdecl;
+ PyThreadState_SetAsyncExc: function(t_id:C_ULong; exc:PPyObject) : Integer; cdecl;
Py_AtExit:function (proc: AtExitProc):integer; cdecl;
- //Py_Cleanup:procedure; cdecl;
- Py_CompileStringFlags:function (s1,s2:PAnsiChar;i:integer;flags:PPyCompilerFlags):PPyObject; cdecl;
- Py_CompileStringExFlags:function (s1,s2:PAnsiChar;i:integer;flags:PPyCompilerFlags;optimize:integer):PPyObject; cdecl;
+ Py_CompileStringExFlags:function (str,filename:PAnsiChar;start:integer;flags:PPyCompilerFlags;optimize:integer):PPyObject; cdecl;
Py_FatalError:procedure(s:PAnsiChar); cdecl;
- Py_FindMethod:function (md:PPyMethodDef;ob:PPyObject;key:PAnsiChar):PPyObject; cdecl;
- Py_FindMethodInChain:function (mc:PPyMethodChain;ob:PPyObject;key:PAnsiChar):PPyObject; cdecl;
_PyObject_New:function (obt:PPyTypeObject;ob:PPyObject):PPyObject; cdecl;
- _PyString_Resize:function (var ob:PPyObject;i:NativeInt):integer; cdecl;
+ _PyBytes_Resize:function (var ob:PPyObject;i:NativeInt):integer; cdecl;
Py_Finalize : procedure; cdecl;
PyErr_ExceptionMatches : function ( exc : PPyObject) : Integer; cdecl;
PyErr_GivenExceptionMatches : function ( raised_exc, exc : PPyObject) : Integer; cdecl;
- PyEval_EvalCode : function ( co : PPyCodeObject; globals, locals : PPyObject) : PPyObject; cdecl;
+ PyEval_EvalCode : function ( co : PPyObject; globals, locals : PPyObject) : PPyObject; cdecl;
Py_GetVersion : function : PAnsiChar; cdecl;
Py_GetCopyright : function : PAnsiChar; cdecl;
- Py_GetExecPrefix : function : PAnsiChar; cdecl;
- Py_GetPath : function : PAnsiChar; cdecl;
- Py_SetPythonHome : procedure (home : PAnsiChar); cdecl;
- Py_GetPythonHome : function : PAnsiChar; cdecl;
- Py_SetPythonHome3000 : procedure (home : PWideChar); cdecl;
- Py_GetPythonHome3000 : function : PWideChar; cdecl;
- Py_GetPrefix : function : PAnsiChar; cdecl;
- Py_GetProgramName : function : PAnsiChar; cdecl;
+ Py_GetExecPrefix : function : PWCharT; cdecl;
+ Py_GetPath : function : PWCharT; cdecl;
+ Py_SetPath : procedure (path: PWCharT); cdecl;
+ Py_SetPythonHome : procedure (home : PWCharT); cdecl;
+ Py_GetPythonHome : function : PWCharT; cdecl;
+ Py_GetPrefix : function : PWCharT; cdecl;
+ Py_GetProgramName : function : PWCharT; cdecl;
PyParser_SimpleParseStringFlags : function ( str : PAnsiChar; start, flags : Integer) : PNode; cdecl;
PyNode_Free : procedure( n : PNode ); cdecl;
PyErr_NewException : function ( name : PAnsiChar; base, dict : PPyObject ) : PPyObject; cdecl;
- Py_Malloc : function ( size : NativeInt ) : Pointer;
- PyMem_Malloc : function ( size : NativeInt ) : Pointer;
+ PyMem_Malloc : function ( size : NativeUInt ) : Pointer;
-{New exported Objects in Python 1.5}
- Py_SetProgramName : procedure( name: PAnsiChar); cdecl;
- Py_SetProgramName3000 : procedure( name: PWideChar); cdecl;
+ Py_SetProgramName : procedure( name: PWCharT); cdecl;
Py_IsInitialized : function : integer; cdecl;
Py_GetProgramFullPath : function : PAnsiChar; cdecl;
Py_NewInterpreter : function : PPyThreadState; cdecl;
@@ -2007,94 +1642,63 @@ TPythonInterface=class(TDynamicDll)
PyErr_SetInterrupt : procedure; cdecl;
PyGILState_Ensure : function() : PyGILstate_STATE; cdecl;
PyGILState_Release : procedure(gilstate : PyGILState_STATE); cdecl;
-{Further exported Objects, may be implemented later}
-{
- PyCode_New: Pointer;
- PyFile_AsFile: Pointer;
- PyFile_FromFile: Pointer;
- PyFloat_AsString: Pointer;
- PyFrame_BlockPop: Pointer;
- PyFrame_BlockSetup: Pointer;
- PyFrame_ExtendStack: Pointer;
- PyFrame_FastToLocals: Pointer;
- PyFrame_LocalsToFast: Pointer;
- PyFrame_New: Pointer;
- PyGrammar_AddAccelerators: Pointer;
- PyGrammar_FindDFA: Pointer;
- PyGrammar_LabelRepr: Pointer;
- PyInstance_DoBinOp: Pointer;
- PyInt_GetMax: Pointer;
- PyMarshal_Init: Pointer;
- PyMarshal_ReadLongFromFile: Pointer;
- PyMarshal_ReadObjectFromFile: Pointer;
- PyMarshal_ReadObjectFromString: Pointer;
- PyMarshal_WriteLongToFile: Pointer;
- PyMarshal_WriteObjectToFile: Pointer;
- PyMember_Get: Pointer;
- PyMember_Set: Pointer;
- PyNode_AddChild: Pointer;
- PyNode_Compile: Pointer;
- PyNode_New: Pointer;
- PyOS_GetLastModificationTime: Pointer;
- PyOS_Readline: Pointer;
- PyOS_strtol: Pointer;
- PyOS_strtoul: Pointer;
- PyObject_CallFunction: Pointer;
- PyObject_Print: Pointer;
- PyParser_AddToken: Pointer;
- PyParser_Delete: Pointer;
- PyParser_New: Pointer;
- PyParser_ParseFile: Pointer;
- PyParser_ParseString: Pointer;
- PyParser_SimpleParseFile: Pointer;
- PyRun_AnyFile: Pointer;
- PyRun_File: Pointer;
- PyRun_InteractiveLoop: Pointer;
- PyRun_InteractiveOne: Pointer;
- PyRun_SimpleFile: Pointer;
- PySys_GetFile: Pointer;
- PyToken_OneChar: Pointer;
- PyToken_TwoChars: Pointer;
- PyTokenizer_Free: Pointer;
- PyTokenizer_FromFile: Pointer;
- PyTokenizer_FromString: Pointer;
- PyTokenizer_Get: Pointer;
- Py_Main: Pointer;
- _PyParser_Grammar: Pointer;
- _PyParser_TokenNames: Pointer;
- _PyThread_Started: Pointer;
- _Py_c_diff: Pointer;
- _Py_c_neg: Pointer;
- _Py_c_pow: Pointer;
- _Py_c_prod: Pointer;
- _Py_c_quot: Pointer;
- _Py_c_sum: Pointer;
-}
- // Not exported in Python 3.8 and implemented as functions
- function PyParser_SimpleParseString( str : PAnsiChar; start : Integer) : PNode; cdecl;
- function Py_CompileString( s1,s2:PAnsiChar;i:integer) : PPyObject; cdecl;
+ // Not exported in Python 3.8 and implemented as functions - this has been fixed
+ // TODO - deal with the following:
+ // the PyParser_* functions are deprecated in python 3.9 and will be removed in
+ // Python 3.10
+ function PyParser_SimpleParseString(str : PAnsiChar; start : Integer) : PNode; cdecl;
+ function Py_CompileString(str,filename:PAnsiChar;start:integer) : PPyObject; cdecl;
// functions redefined in Delphi
- procedure Py_INCREF ( op: PPyObject);
- procedure Py_DECREF ( op: PPyObject);
- procedure Py_XINCREF ( op: PPyObject);
- procedure Py_XDECREF ( op: PPyObject);
-
- function PyCode_Addr2Line( co: PPyCodeObject; addrq : Integer ) : Integer; cdecl;
- function Py_GetBuildInfo: PAnsiChar; cdecl;
- function PyImport_ExecCodeModule( const AName : AnsiString; codeobject : PPyObject) : PPyObject;
- function PyString_Check( obj : PPyObject ) : Boolean;
- function PyString_CheckExact( obj : PPyObject ) : Boolean;
+ class procedure Py_INCREF(op: PPyObject); static; inline;
+ class procedure Py_DECREF(op: PPyObject); static; inline;
+ class procedure Py_XINCREF(op: PPyObject); static; inline;
+ class procedure Py_XDECREF(op: PPyObject); static; inline;
+ (* Safely decref `op` and set `op` to NULL, especially useful in tp_clear
+ * and tp_dealloc implementations.
+ *
+ * Note that "the obvious" code can be deadly:
+ *
+ * Py_XDECREF(op);
+ * op = NULL;
+ *
+ * Typically, `op` is something like self->containee, and `self` is done
+ * using its `containee` member. In the code sequence above, suppose
+ * `containee` is non-NULL with a refcount of 1. Its refcount falls to
+ * 0 on the first line, which can trigger an arbitrary amount of code,
+ * possibly including finalizers (like __del__ methods or weakref callbacks)
+ * coded in Python, which in turn can release the GIL and allow other threads
+ * to run, etc. Such code may even invoke methods of `self` again, or cause
+ * cyclic gc to trigger, but-- oops! --self->containee still points to the
+ * object being torn down, and it may be in an insane state while being torn
+ * down. This has in fact been a rich historic source of miserable (rare &
+ * hard-to-diagnose) segfaulting (and other) bugs.
+ *
+ * The safe way is:
+ *
+ * Py_CLEAR(op);
+ *
+ * That arranges to set `op` to NULL _before_ decref'ing, so that any code
+ * triggered as a side-effect of `op` getting torn down no longer believes
+ * `op` points to a valid object.
+ *
+ * There are cases where it's safe to use the naive code, but they're brittle.
+ * For example, if `op` points to a Python integer, you know that destroying
+ * one of those can't cause problems -- but in part that relies on that
+ * Python integers aren't currently weakly referencable. Best practice is
+ * to use Py_CLEAR() even if you can't think of a reason for why you need to.
+ *)
+ class procedure Py_CLEAR(var op: PPyObject); static; inline;
+
+ function PyBytes_Check( obj : PPyObject ) : Boolean;
+ function PyBytes_CheckExact( obj : PPyObject ) : Boolean;
function PyFloat_Check( obj : PPyObject ) : Boolean;
function PyFloat_CheckExact( obj : PPyObject ) : Boolean;
- function PyInt_Check( obj : PPyObject ) : Boolean;
- function PyInt_CheckExact( obj : PPyObject ) : Boolean;
function PyLong_Check( obj : PPyObject ) : Boolean;
function PyLong_CheckExact( obj : PPyObject ) : Boolean;
function PyTuple_Check( obj : PPyObject ) : Boolean;
function PyTuple_CheckExact( obj : PPyObject ) : Boolean;
- function PyInstance_Check( obj : PPyObject ) : Boolean;
function PyClass_Check( obj : PPyObject ) : Boolean;
function PyType_CheckExact( obj : PPyObject ) : Boolean;
function PyMethod_Check( obj : PPyObject ) : Boolean;
@@ -2115,14 +1719,9 @@ TPythonInterface=class(TDynamicDll)
function PyWeakref_CheckRef( obj : PPyObject ) : Boolean;
function PyWeakref_CheckProxy( obj : PPyObject ) : Boolean;
function PyBool_Check( obj : PPyObject ) : Boolean;
- function PyBaseString_Check( obj : PPyObject ) : Boolean;
function PyEnum_Check( obj : PPyObject ) : Boolean;
function PyObject_TypeCheck(obj:PPyObject; t:PPyTypeObject) : Boolean;
- function Py_InitModule( const AName : PAnsiChar; md : PPyMethodDef) : PPyObject;
- function Py_InitModule3000( const md : PyModuleDef) : PPyObject;
- function PyString_FromString( str: PAnsiChar): PPyObject; virtual; abstract;
- function PyString_AsDelphiString( ob: PPyObject): AnsiString; virtual; abstract;
- procedure Py_FlushLine; cdecl;
+ function Py_InitModule( const md : PyModuleDef) : PPyObject;
// Constructors & Destructors
constructor Create(AOwner: TComponent); override;
@@ -2133,7 +1732,6 @@ TPythonInterface=class(TDynamicDll)
// Public properties
property Initialized : Boolean read FInitialized;
property Finalizing : Boolean read FFinalizing;
- property IsPython3000 : Boolean read FIsPython3000;
property MajorVersion : integer read FMajorVersion;
property MinorVersion : integer read FMinorVersion;
property BuiltInModuleName: String read FBuiltInModuleName write FBuiltInModuleName;
@@ -2154,8 +1752,8 @@ TPythonInterface=class(TDynamicDll)
TEngineClient = class;
TPathInitializationEvent = procedure ( Sender : TObject; var Path : String ) of Object;
TSysPathInitEvent = procedure ( Sender : TObject; PathList : PPyObject ) of Object;
- TPythonFlag = (pfDebug, pfInteractive, pfNoSite, pfOptimize, pfTabcheck, pfUnicode, pfVerbose,
- pfUseClassExceptionsFlag, pfFrozenFlag, pfIgnoreEnvironmentFlag, pfDivisionWarningFlag);
+ TPythonFlag = (pfDebug, pfInteractive, pfNoSite, pfOptimize, pfVerbose,
+ pfFrozenFlag, pfIgnoreEnvironmentFlag);
TPythonFlags = set of TPythonFlag;
@@ -2178,30 +1776,32 @@ TPythonTraceback = class
destructor Destroy; override;
procedure Clear;
- procedure Refresh;
+ procedure Refresh(pytraceback: PPyObject = nil);
+ procedure AddItem(const Context, FileName: string; LineNo: Integer);
property ItemCount : Integer read GetItemCount;
property Items[ idx : Integer ] : TTracebackItem read GetItem;
property Limit : Integer read FLimit write FLimit;
end;
+ TPythonType = class; //forward declaration
+
{$IF not Defined(FPC) and (CompilerVersion >= 23)}
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
{$IFEND}
TPythonEngine = class(TPythonInterface)
private
+ FVenvPythonExe: string;
FInitScript: TStrings;
FIO: TPythonInputOutput;
FRedirectIO: Boolean;
FOnAfterInit: TNotifyEvent;
FClients: TList;
- FLock: TCriticalSection;
FExecModule: AnsiString;
FAutoFinalize: Boolean;
- FProgramName: AnsiString;
- FProgramNameW: UnicodeString;
- FPythonHome: AnsiString;
- FPythonHomeW: UnicodeString;
+ FProgramName: WCharTString;
+ FPythonHome: WCharTString;
+ FPythonPath: WCharTString;
FInitThreads: Boolean;
FOnPathInitialization: TPathInitializationEvent;
FOnSysPathInit: TSysPathInitEvent;
@@ -2221,14 +1821,19 @@ TPythonEngine = class(TPythonInterface)
FPyDateTime_TZInfoType: PPyObject;
FPyDateTime_TimeTZType: PPyObject;
FPyDateTime_DateTimeTZType: PPyObject;
+ function GetPythonHome: UnicodeString;
+ function GetProgramName: UnicodeString;
+ function GetPythonPath: UnicodeString;
+ procedure SetPythonPath(const Value: UnicodeString);
protected
+ procedure Initialize;
+ procedure Finalize;
procedure AfterLoad; override;
procedure BeforeLoad; override;
procedure DoOpenDll(const aDllName : String); override;
procedure SetInitScript(Value: TStrings);
function GetThreadState: PPyThreadState;
- function GetInterpreterState: PPyInterpreterState;
procedure SetInitThreads(Value: Boolean);
function GetClientCount : Integer;
function GetClients( idx : Integer ) : TEngineClient;
@@ -2249,26 +1854,29 @@ TPythonEngine = class(TPythonInterface)
destructor Destroy; override;
// Public methods
- procedure Initialize;
- procedure Finalize;
- procedure Lock;
- procedure Unlock;
- procedure SetPythonHome(const PythonHome: String);
+ procedure SetPythonHome(const PythonHome: UnicodeString);
+ procedure SetProgramName(const ProgramName: UnicodeString);
function IsType(ob: PPyObject; obt: PPyTypeObject): Boolean;
- function GetAttrString(obj: PPyObject; AName: PAnsiChar):PAnsiChar;
- function Run_CommandAsString(const command : AnsiString; mode : Integer) : String;
- function Run_CommandAsObject(const command : AnsiString; mode : Integer) : PPyObject; inline;
- function Run_CommandAsObjectWithDict(const command : AnsiString; mode : Integer; locals, globals : PPyObject) : PPyObject;
- procedure ExecString(const command : AnsiString); overload; inline;
- procedure ExecStrings( strings : TStrings ); overload;
- function EvalString(const command : AnsiString) : PPyObject; overload; inline;
- function EvalStringAsStr(const command : AnsiString) : String; inline;
- function EvalStrings( strings : TStrings ) : PPyObject; overload;
- procedure ExecString(const command : AnsiString; locals, globals : PPyObject ); overload; inline;
- procedure ExecStrings( strings : TStrings; locals, globals : PPyObject ); overload;
- function EvalString( const command : AnsiString; locals, globals : PPyObject ) : PPyObject; overload; inline;
- function EvalStrings( strings : TStrings; locals, globals : PPyObject ) : PPyObject; overload;
- function EvalStringsAsStr( strings : TStrings ) : String;
+ function Run_CommandAsString(const command: AnsiString; mode: Integer; const FileName: string = ''): string;
+ function Run_CommandAsObject(const command: AnsiString; mode: Integer; const FileName: string = ''): PPyObject;
+ function Run_CommandAsObjectWithDict(const command: AnsiString; mode: Integer; locals, globals: PPyObject; const FileName: string = ''): PPyObject;
+ function EncodeString (const str: UnicodeString): AnsiString; {$IFDEF FPC}overload;{$ENDIF}
+ {$IFDEF FPC}
+ overload;
+ function EncodeString (const str: AnsiString): AnsiString; overload;
+ {$ENDIF}
+ function EncodeWindowsFilePath(const str: string): AnsiString;
+ procedure ExecString(const command: AnsiString; const FileName: string = ''); overload;
+ procedure ExecStrings(strings: TStrings; const FileName: string = ''); overload;
+ procedure ExecString(const command: AnsiString; locals, globals: PPyObject; const FileName: string = ''); overload;
+ procedure ExecFile(const FileName: string; locals: PPyObject = nil; globals: PPyObject = nil); overload;
+ procedure ExecStrings(strings: TStrings; locals, globals: PPyObject; const FileName: string = ''); overload;
+ function EvalString(const command: AnsiString; const FileName: string = ''): PPyObject; overload;
+ function EvalStringAsStr(const command: AnsiString; const FileName: string = ''): string;
+ function EvalStrings(strings: TStrings; const FileName: string = ''): PPyObject; overload;
+ function EvalString(const command: AnsiString; locals, globals: PPyObject; const FileName: string = ''): PPyObject; overload;
+ function EvalStrings(strings: TStrings; locals, globals: PPyObject; const FileName: string = ''): PPyObject; overload;
+ function EvalStringsAsStr(strings: TStrings; const FileName: string = ''): string;
function EvalPyFunction(pyfunc, pyargs:PPyObject): Variant;
function EvalFunction(pyfunc:PPyObject; args: array of const): Variant;
function EvalFunctionNoArgs(pyfunc:PPyObject): Variant;
@@ -2281,6 +1889,7 @@ TPythonEngine = class(TPythonInterface)
procedure AddClient( client : TEngineClient );
procedure RemoveClient( client : TEngineClient );
function FindClient( const aName : AnsiString ) : TEngineClient;
+ function FindPythonType( const TypeName : AnsiString ) : TPythonType;
function TypeByName( const aTypeName : AnsiString ) : PPyTypeObject;
function ModuleByName( const aModuleName : AnsiString ) : PPyObject;
function MethodsByName( const aMethodsContainer: AnsiString ) : PPyMethodDef;
@@ -2294,11 +1903,11 @@ TPythonEngine = class(TPythonInterface)
function ArrayToPyDict( items : array of const) : PPyObject;
function StringsToPyList( strings : TStrings ) : PPyObject;
function StringsToPyTuple( strings : TStrings ) : PPyObject;
- procedure PyListToStrings( list : PPyObject; strings : TStrings );
+ procedure PyListToStrings(list: PPyObject; Strings: TStrings; ClearStrings: Boolean = True);
procedure PyTupleToStrings( tuple: PPyObject; strings : TStrings );
- function PyUnicode_AsWideString( obj : PPyObject ) : UnicodeString;
- function PyUnicode_FromWideString( const AString : UnicodeString) : PPyObject;
function ReturnNone : PPyObject;
+ function ReturnTrue : PPyObject;
+ function ReturnFalse : PPyObject;
function FindModule( const ModuleName : AnsiString ) : PPyObject;
function FindFunction(ModuleName,FuncName: AnsiString): PPyObject;
function SetToList( data : Pointer; size : Integer ) : PPyObject;
@@ -2318,23 +1927,29 @@ TPythonEngine = class(TPythonInterface)
function PyTZInfo_Check( obj : PPyObject ) : Boolean;
function PyTZInfo_CheckExact( obj : PPyObject ) : Boolean;
{ end date/time functions }
- function PyString_FromString( str: PAnsiChar): PPyObject; override;
- function PyString_AsDelphiString( ob: PPyObject): AnsiString; override;
- function PyString_AsAnsiString( ob: PPyObject): AnsiString;
- function PyString_AsWideString( ob: PPyObject): UnicodeString;
+
+ { String conversion }
+ function PyUnicodeFromString(const AString : UnicodeString) : PPyObject; overload;
+ function PyUnicodeFromString(const AString: AnsiString): PPyObject; overload;
+ function PyUnicodeAsString( obj : PPyObject ) : UnicodeString;
+ function PyUnicodeAsUTF8String( obj : PPyObject ) : RawByteString;
+ function PyBytesAsAnsiString( obj : PPyObject ) : AnsiString;
// Public Properties
property ClientCount : Integer read GetClientCount;
property Clients[ idx : Integer ] : TEngineClient read GetClients;
property ExecModule : AnsiString read FExecModule write FExecModule;
property ThreadState: PPyThreadState read GetThreadState;
- property InterpreterState: PPyInterpreterState read GetInterpreterState;
property Traceback : TPythonTraceback read FTraceback;
property LocalVars : PPyObject read FLocalVars Write SetLocalVars;
property GlobalVars : PPyObject read FGlobalVars Write SetGlobalVars;
property IOPythonModule: TObject read FIOPythonModule; {TPythonModule}
+ property PythonHome: UnicodeString read GetPythonHome write SetPythonHome;
+ property ProgramName: UnicodeString read GetProgramName write SetProgramName;
+ property PythonPath: UnicodeString read GetPythonPath write SetPythonPath;
published
property AutoFinalize: Boolean read FAutoFinalize write FAutoFinalize default True;
+ property VenvPythonExe: string read FVenvPythonExe write FVenvPythonExe;
property DatetimeConversionMode: TDatetimeConversionMode read FDatetimeConversionMode write FDatetimeConversionMode default DEFAULT_DATETIME_CONVERSION_MODE;
property InitScript: TStrings read FInitScript write SetInitScript;
property InitThreads: Boolean read FInitThreads write SetInitThreads default False;
@@ -2365,8 +1980,6 @@ TEngineClient = class(TComponent)
procedure SetEngine( val : TPythonEngine ); virtual;
procedure Loaded; override;
- procedure Notification( AComponent: TComponent;
- Operation: TOperation); override;
procedure ModuleReady(Sender : TObject); virtual;
public
// Constructors & destructors
@@ -2453,7 +2066,7 @@ TMethodsContainer = class(TEngineClient)
FMethodCount : Integer;
FAllocatedMethodCount : Integer;
FMethods : PPyMethodDef;
- FModuleDef : PyModuleDef; // for Python 3000
+ FModuleDef : PyModuleDef;
FEventDefs: TEventDefs;
procedure AllocMethods;
@@ -2479,6 +2092,12 @@ TMethodsContainer = class(TEngineClient)
function AddMethodWithKeywords( AMethodName : PAnsiChar;
AMethod : PyCFunctionWithKW;
ADocString : PAnsiChar ) : PPyMethodDef;
+ function AddClassMethodWithKeywords( AMethodName : PAnsiChar;
+ AMethod : PyCFunctionWithKW;
+ ADocString : PAnsiChar ) : PPyMethodDef;
+ function AddStaticMethodWithKeywords( AMethodName : PAnsiChar;
+ AMethod : PyCFunctionWithKW;
+ ADocString : PAnsiChar ) : PPyMethodDef;
function AddDelphiMethod( AMethodName : PAnsiChar;
ADelphiMethod: TDelphiMethod;
ADocString : PAnsiChar ) : PPyMethodDef;
@@ -2680,7 +2299,8 @@ TPythonModule = class(TMethodsContainer)
procedure DefineDocString;
procedure Initialize; override;
procedure InitializeForNewInterpreter;
- procedure AddClient( client : TEngineClient );
+ procedure AddClient(Client : TEngineClient);
+ procedure RemoveClient(Client : TEngineClient);
function ErrorByName( const AName : AnsiString ) : TError;
procedure RaiseError( const error, msg : AnsiString );
procedure RaiseErrorFmt( const error, format : AnsiString; Args : array of const );
@@ -2711,9 +2331,6 @@ TPythonModule = class(TMethodsContainer)
//-- --
//-------------------------------------------------------
-type
- TPythonType = class; //forward declaration
-
{
A B C
+-------------------++------------------------------------------------------+
@@ -2755,7 +2372,7 @@ TPyObject = class
// Constructors & Destructors
constructor Create( APythonType : TPythonType ); virtual;
- constructor CreateWith( APythonType : TPythonType; args : PPyObject ); virtual;
+ constructor CreateWith(APythonType: TPythonType; args, kwds: PPyObject); virtual;
destructor Destroy; override;
class function NewInstance: TObject; override;
@@ -2795,7 +2412,6 @@ TPyObject = class
function NbAdd( obj : PPyObject) : PPyObject; virtual;
function NbSubtract( obj : PPyObject) : PPyObject; virtual;
function NbMultiply( obj : PPyObject) : PPyObject; virtual;
- function NbDivide( obj : PPyObject) : PPyObject; virtual;
function NbFloorDivide( obj : PPyObject) : PPyObject; virtual;
function NbTrueDivide( obj : PPyObject) : PPyObject; virtual;
function NbMatrixMultiply( obj : PPyObject) : PPyObject; virtual;
@@ -2805,7 +2421,6 @@ TPyObject = class
function NbNegative : PPyObject; virtual;
function NbPositive : PPyObject; virtual;
function NbAbsolute : PPyObject; virtual;
- function NbNonZero : Integer; virtual;
function NbBool : Integer; virtual;
function NbInvert : PPyObject; virtual;
function NbLShift( obj : PPyObject) : PPyObject; virtual;
@@ -2813,12 +2428,8 @@ TPyObject = class
function NbAnd( obj : PPyObject) : PPyObject; virtual;
function NbXor( obj : PPyObject) : PPyObject; virtual;
function NbOr( obj : PPyObject) : PPyObject; virtual;
- function NbCoerce( obj : PPPyObject) : Integer; virtual;
function NbInt : PPyObject; virtual;
- function NbLong : PPyObject; virtual;
function NbFloat : PPyObject; virtual;
- function NbOct : PPyObject; virtual;
- function NbHex : PPyObject; virtual;
function NbInplaceAdd( obj : PPyObject): PPyObject; virtual;
function NbInplaceSubtract( obj : PPyObject): PPyObject; virtual;
function NbInplaceMultiply( obj : PPyObject): PPyObject; virtual;
@@ -2838,9 +2449,7 @@ TPyObject = class
function SqConcat( obj : PPyObject) : PPyObject; virtual;
function SqRepeat( val : NativeInt ) : PPyObject; virtual;
function SqItem( idx : NativeInt ) : PPyObject; virtual;
- function SqSlice( idx1, idx2 : NativeInt ) : PPyObject; virtual;
function SqAssItem( idx : NativeInt; obj : PPyObject) : Integer; virtual;
- function SqAssSlice( idx1, idx2 : NativeInt; obj : PPyObject): integer; virtual;
function SqContains( obj: PPyObject): integer; virtual;
function SqInplaceConcat( obj : PPyObject): PPyObject; virtual;
function SqInplaceRepeat( i: NativeInt): PPyObject; virtual;
@@ -2857,7 +2466,7 @@ TPyObject = class
end;
TPyObjectClass = class of TPyObject;
- TBasicServices = set of (bsPrint, bsGetAttr, bsSetAttr,
+ TBasicServices = set of (bsGetAttr, bsSetAttr,
bsRepr, bsCompare, bsHash,
bsStr, bsGetAttrO, bsSetAttrO,
bsCall,
@@ -2868,35 +2477,29 @@ TPyObjectClass = class of TPyObject;
// since version 2.2
bsIter, bsIterNext);
TNumberServices = set of (nsAdd, nsSubtract, nsMultiply,
- nsDivide, nsRemainder, nsDivmod,
+ nsRemainder, nsDivmod,
nsPower, nsNegative, nsPositive,
- nsAbsolute, nsNonZero, nsInvert,
+ nsAbsolute, nsInvert,
nsLShift, nsRShift, nsAnd,
- nsXor, nsOr, nsCoerce,
- nsInt, nsLong, nsFloat,
- nsOct, nsHex,
- // since version 2.2
+ nsXor, nsOr,
+ nsInt, nsFloat,
nsFloorDivide, nsTrueDivide,
// since version 3.0
nsMatrixMultiply, nsBool);
// TInplaceNumberServices exists since version 2.0
TInplaceNumberServices = set of (nsInplaceAdd, nsInplaceSubtract,
- nsInplaceMultiply, nsInplaceDivide,
+ nsInplaceMultiply,
nsInplaceRemainder, nsInplacePower,
nsInplaceLShift, nsInplaceRShift,
nsInplaceAnd, nsInplaceXor, nsInplaceOr,
- // since version 2.2
nsInplaceFloorDivide, nsInplaceTrueDivide,
// since version 3.0
nsInplaceMatrixMultiply);
TSequenceServices = set of (ssLength, ssConcat, ssRepeat,
- ssItem, ssSlice, ssAssItem,
- ssAssSlice,
- // since version 2.0
- ssContains,
- ssInplaceConcat,
+ ssItem, ssAssItem,
+ ssContains, ssInplaceConcat,
ssInplaceRepeat
);
@@ -2936,7 +2539,7 @@ TPythonType = class(TGetSetContainer)
FPrefix : AnsiString;
FCreateFuncName : AnsiString;
FServices : TTypeServices;
- FNumber: Pointer; // points either to PyNumberMethods200 or PyNumberMethods300;
+ FNumber: PyNumberMethods;
FSequence: PySequenceMethods;
FMapping: PyMappingMethods;
FCurrentDocString: AnsiString;
@@ -2957,10 +2560,11 @@ TPythonType = class(TGetSetContainer)
procedure SetModule( val : TPythonModule );
procedure SetServices( val : TTypeServices );
procedure SetTypeName( const val : AnsiString );
- function CreateMethod( pSelf, args : PPyObject ) : PPyObject; cdecl;
+ procedure SetBaseType(AType: TPythonType);
+ function CreateMethod(pSelf, args, kwds: PPyObject): PPyObject; cdecl;
procedure InitServices;
procedure SetDocString( value : TStringList );
- function TypeFlagsAsInt : LongInt;
+ function TypeFlagsAsInt : C_ULong;
function GetMembersStartOffset : Integer; override;
procedure ModuleReady(Sender : TObject); override;
procedure ReallocMethods; override;
@@ -2981,12 +2585,13 @@ TPythonType = class(TGetSetContainer)
procedure Initialize; override;
procedure Finalize; override;
function CreateInstance : PPyObject;
- function CreateInstanceWith( args : PPyObject ) : PPyObject;
+ function CreateInstanceWith(args, kwds: PPyObject): PPyObject;
procedure AddTypeVar;
property TheType : PyTypeObject read FType write FType;
property TheTypePtr : PPyTypeObject read GetTypePtr;
property PyObjectClass : TPyObjectClass read FPyObjectClass write SetPyObjectClass stored False;
+ property BaseType: TPythonType write SetBaseType;
property InstanceCount : Integer read FInstanceCount;
property CreateHits : Integer read FCreateHits;
property DeleteHits : Integer read FDeleteHits;
@@ -3069,15 +2674,15 @@ TPyVar = class(TPyObject)
// Constructors & Destructors
constructor Create( APythonType : TPythonType ); override;
- constructor CreateWith( APythonType : TPythonType; args : PPyObject ); override;
+ constructor CreateWith(APythonType: TPythonType; args, kwds: PPyObject); override;
destructor Destroy; override;
// Type services
////////////////
// Basic services
- function GetAttr(key : PAnsiChar) : PPyObject; override;
- function SetAttr(key : PAnsiChar; value : PPyObject) : Integer; override;
+ function GetAttrO( key: PPyObject) : PPyObject; override;
+ function SetAttrO( key, value: PPyObject) : Integer; override;
function Repr : PPyObject; override;
// Class methods
@@ -3102,30 +2707,25 @@ TPyVar = class(TPyObject)
{$HINTS OFF}
TPythonThread = class(TThread)
private
- f_savethreadstate: PPyThreadState;
- fInterpreterState: PPyInterpreterState;
fThreadState: PPyThreadState;
fThreadExecMode: TThreadExecMode;
-
-// Do not overwrite Execute! Use ExecuteWithPython instead!
+ private class {$if FPC_FULLVERSION>=30200} threadvar {$else} var {$endif}
+ f_savethreadstate: PPyThreadState;
+ private
+ // Do not overwrite Execute! Use ExecuteWithPython instead!
procedure Execute; override;
protected
procedure ExecuteWithPython; virtual; abstract;
-
- procedure Py_Begin_Allow_Threads;
- procedure Py_End_Allow_Threads;
-// The following procedures are redundant and only for
-// compatibility to the C API documentation.
- procedure Py_Begin_Block_Threads;
- procedure Py_Begin_Unblock_Threads;
-
public
- property InterpreterState: PPyInterpreterState read fInterpreterState
- write fInterpreterState
- default nil;
- property ThreadState: PPyThreadState read fThreadState
- write fThreadState;
- property ThreadExecMode: TThreadExecMode read fThreadExecMode;
+ class procedure Py_Begin_Allow_Threads;
+ class procedure Py_End_Allow_Threads;
+ // The following procedures are redundant and only for
+ // compatibility to the C API documentation.
+ class procedure Py_Begin_Block_Threads;
+ class procedure Py_Begin_Unblock_Threads;
+
+ property ThreadState : PPyThreadState read fThreadState;
+ property ThreadExecMode: TThreadExecMode read fThreadExecMode write fThreadExecMode;
end;
{$HINTS ON}
@@ -3163,6 +2763,8 @@ procedure PyObjectDestructor( pSelf : PPyObject); cdecl;
procedure FreeSubtypeInst(ob:PPyObject); cdecl;
procedure Register;
function PyType_HasFeature(AType : PPyTypeObject; AFlag : Integer) : Boolean;
+function SysVersionFromDLLName(const DLLFileName : string): string;
+procedure PythonVersionFromDLLName(LibName: string; out MajorVersion, MinorVersion: integer);
{ Helper functions}
(*
@@ -3214,6 +2816,16 @@ function _IsBufferAscii(buf: PAnsiChar): boolean; inline;
Result := true;
end;
+(*******************************************************)
+(** **)
+(** Resource strings **)
+(** **)
+(*******************************************************)
+resourcestring
+SPyConvertionError = 'Conversion Error: %s expects a %s Python object';
+SPyExcStopIteration = 'Stop Iteration';
+SPyExcSystemError = 'Unhandled SystemExit exception. Code: %s';
+
(*******************************************************)
(** **)
(** Globals **)
@@ -3395,7 +3007,8 @@ procedure TDynamicDll.DoOpenDll(const aDllName : String);
FDLLHandle := Windows.LoadLibrary(PChar(S));
{$else}
//Linux: need here RTLD_GLOBAL, so Python can do "import ctypes"
- FDLLHandle := PtrInt(dlopen(PAnsiChar(S), RTLD_LAZY+RTLD_GLOBAL));
+ //Haiku: without RTLD_NOW it doesn't seem to detect the library or plugins without running with "LD_PRELOAD ..."
+ FDLLHandle := PtrInt(dlopen(PAnsiChar(S), {$ifdef haiku}RTLD_NOW{$else}RTLD_LAZY{$endif}+RTLD_GLOBAL));
{$endif}
end;
end;
@@ -3589,34 +3202,12 @@ constructor TPythonInterface.Create(AOwner: TComponent);
FAutoUnload := True;
end;
-procedure TPythonInterface.DetectPythonVersionFromLibName(const Str: AnsiString);
-var
- NPos: integer;
-begin
- //Win: "python34.dll"
- //Linux: "libpython3.4.so"
- NPos := Pos('python', LowerCase(Str));
- if NPos>0 then
- begin
- Inc(NPos, Length('python'));
- FIsPython3000 := Str[NPos]='3';
- FMajorVersion := StrToIntDef(Str[NPos], 3);
- Inc(NPos);
- if Str[NPos]='.' then
- Inc(NPos);
- FMinorVersion := StrToIntDef(Str[NPos], 3);
- end;
-end;
-
procedure TPythonInterface.AfterLoad;
begin
inherited;
+ PythonVersionFromDLLName(DLLName, FMajorVersion, FMinorVersion);
- DetectPythonVersionFromLibName(DLLName);
- if FIsPython3000 then
- FBuiltInModuleName := 'builtins'
- else
- FBuiltInModuleName := '__builtin__';
+ FBuiltInModuleName := 'builtins';
try
MapDll;
@@ -3644,54 +3235,20 @@ procedure TPythonInterface.CheckPython;
raise Exception.Create('Python is not properly initialized' );
end;
-// https://github.com/Alexey-T/Python-for-Lazarus/issues/16
-function TPythonInterface.GetUnicodeTypeSuffix : String;
-begin
- if (fMajorVersion > 3) or ((fMajorVersion = 3) and (fMinorVersion >= 3)) then
- Result := ''
- else
- if APIVersion >= 1011 then
- Result :=
- {$if defined(windows) or defined(darwin) or defined(solaris)}
- 'UCS2'
- {$else}
- 'UCS4'
- {$endif}
- else
- Result := '';
-end;
-
procedure TPythonInterface.MapDll;
-var
- UnicodeSuffix: AnsiString;
begin
- UnicodeSuffix:= GetUnicodeTypeSuffix;
-
Py_DebugFlag := Import('Py_DebugFlag');
Py_VerboseFlag := Import('Py_VerboseFlag');
Py_InteractiveFlag := Import('Py_InteractiveFlag');
Py_OptimizeFlag := Import('Py_OptimizeFlag');
Py_NoSiteFlag := Import('Py_NoSiteFlag');
Py_FrozenFlag := Import('Py_FrozenFlag');
- if not IsPython3000 then begin
- Py_UseClassExceptionsFlag := Import('Py_UseClassExceptionsFlag');
- Py_TabcheckFlag := Import('Py_TabcheckFlag');
- Py_UnicodeFlag := Import('Py_UnicodeFlag');
- end;
- if (fMajorVersion < 3) or ((fMajorVersion = 3) and (fMinorVersion <3)) then
- Py_DivisionWarningFlag := Import('Py_DivisionWarningFlag');
Py_IgnoreEnvironmentFlag := Import('Py_IgnoreEnvironmentFlag');
- //_PySys_TraceFunc := Import('_PySys_TraceFunc');
- //_PySys_ProfileFunc := Import('_PySys_ProfileFunc');
-
Py_None := Import('_Py_NoneStruct');
Py_Ellipsis := Import('_Py_EllipsisObject');
- if IsPython3000 then
- Py_False := Import('_Py_FalseStruct')
- else
- Py_False := Import('_Py_ZeroStruct');
+ Py_False := Import('_Py_FalseStruct');
Py_True := Import('_Py_TrueStruct');
Py_NotImplemented := Import('_Py_NotImplementedStruct');
@@ -3718,10 +3275,6 @@ procedure TPythonInterface.MapDll;
PyExc_Exception := Import('PyExc_Exception');
PyExc_FloatingPointError := Import('PyExc_FloatingPointError');
PyExc_LookupError := Import('PyExc_LookupError');
- if not IsPython3000 then begin
- PyExc_StandardError := Import('PyExc_StandardError');
- PyExc_MemoryErrorInst := Import('PyExc_MemoryErrorInst');
- end;
PyExc_AssertionError := Import('PyExc_AssertionError');
PyExc_EnvironmentError := Import('PyExc_EnvironmentError');
PyExc_IndentationError := Import('PyExc_IndentationError');
@@ -3730,7 +3283,7 @@ procedure TPythonInterface.MapDll;
PyExc_TabError := Import('PyExc_TabError');
PyExc_UnboundLocalError := Import('PyExc_UnboundLocalError');
PyExc_UnicodeError := Import('PyExc_UnicodeError');
- {$IFDEF windows}
+ {$IFDEF MSWINDOWS}
PyExc_WindowsError := Import('PyExc_WindowsError');
{$ENDIF}
PyExc_Warning := Import('PyExc_Warning');
@@ -3747,22 +3300,12 @@ procedure TPythonInterface.MapDll;
PyExc_UnicodeTranslateError:= Import('PyExc_UnicodeTranslateError');
PyType_Type := Import('PyType_Type');
PyCFunction_Type := Import('PyCFunction_Type');
- if not IsPython3000 then begin
- PyCObject_Type := Import('PyCObject_Type'); // Removed in Python 3.2
- PyClass_Type := Import('PyClass_Type');
- end;
PyCode_Type := Import('PyCode_Type');
PyComplex_Type := Import('PyComplex_Type');
PyDict_Type := Import('PyDict_Type');
- if not IsPython3000 then
- PyFile_Type := Import('PyFile_Type');
PyFloat_Type := Import('PyFloat_Type');
PyFrame_Type := Import('PyFrame_Type');
PyFunction_Type := Import('PyFunction_Type');
- if not IsPython3000 then
- PyInstance_Type := Import('PyInstance_Type');
- if not IsPython3000 then
- PyInt_Type := Import('PyInt_Type');
PyList_Type := Import('PyList_Type');
PyLong_Type := Import('PyLong_Type');
PyMethod_Type := Import('PyMethod_Type');
@@ -3770,15 +3313,10 @@ procedure TPythonInterface.MapDll;
PyObject_Type := Import('PyObject_Type');
PyRange_Type := Import('PyRange_Type');
PySlice_Type := Import('PySlice_Type');
- if not IsPython3000 then
- PyString_Type := Import('PyString_Type')
- else
- PyString_Type := Import('PyBytes_Type');
+ PyBytes_Type := Import('PyBytes_Type');
PyTuple_Type := Import('PyTuple_Type');
PyUnicode_Type := Import('PyUnicode_Type');
PyBaseObject_Type := Import('PyBaseObject_Type');
- if not IsPython3000 then
- PyBuffer_Type := Import('PyBuffer_Type');
PyCallIter_Type := Import('PyCallIter_Type');
PyCell_Type := Import('PyCell_Type');
PyClassMethod_Type := Import('PyClassMethod_Type');
@@ -3791,19 +3329,9 @@ procedure TPythonInterface.MapDll;
_PyWeakref_RefType := Import('_PyWeakref_RefType');
_PyWeakref_ProxyType := Import('_PyWeakref_ProxyType');
_PyWeakref_CallableProxyType:=Import('_PyWeakref_CallableProxyType');
- if not IsPython3000 then
- PyBaseString_Type := Import('PyBaseString_Type');
PyBool_Type := Import('PyBool_Type');
PyEnum_Type := Import('PyEnum_Type');
- //@PyArg_GetObject := Import('PyArg_GetObject');
- //@PyArg_GetLong := Import('PyArg_GetLong');
- //@PyArg_GetShort := Import('PyArg_GetShort');
- //@PyArg_GetFloat := Import('PyArg_GetFloat');
- //@PyArg_GetString := Import('PyArg_GetString');
- //@PyArgs_VaParse := Import('PyArgs_VaParse');
- //@Py_VaBuildValue := Import('Py_VaBuildValue');
- //@PyBuiltin_Init := Import('PyBuiltin_Init');
PyComplex_FromCComplex := Import('PyComplex_FromCComplex');
PyComplex_FromDoubles := Import('PyComplex_FromDoubles');
PyComplex_RealAsDouble := Import('PyComplex_RealAsDouble');
@@ -3812,12 +3340,6 @@ procedure TPythonInterface.MapDll;
PyCFunction_GetFunction := Import('PyCFunction_GetFunction');
PyCFunction_GetSelf := Import('PyCFunction_GetSelf');
PyCallable_Check := Import('PyCallable_Check');
- if not IsPython3000 then begin
- PyClass_New := Import('PyClass_New');
- PyClass_IsSubclass := Import('PyClass_IsSubclass');
- PyCObject_FromVoidPtr := Import('PyCObject_FromVoidPtr'); // Removed in Python 3.2
- PyCObject_AsVoidPtr := Import('PyCObject_AsVoidPtr');
- end;
PyDict_GetItem := Import('PyDict_GetItem');
PyDict_SetItem := Import('PyDict_SetItem');
PyDict_DelItem := Import('PyDict_DelItem');
@@ -3829,11 +3351,11 @@ procedure TPythonInterface.MapDll;
PyDict_Size := Import('PyDict_Size');
PyDict_DelItemString := Import('PyDict_DelItemString');
PyDict_Copy := Import('PyDict_Copy');
+ PyDict_New := Import('PyDict_New');
+ PyDict_Update := Import('PyDict_Update');
+ PyDict_SetItemString := Import('PyDict_SetItemString');
PyDictProxy_New := Import('PyDictProxy_New');
- if not IsPython3000 then
- Py_InitModule4 := {$IFDEF CPUX64}Import('Py_InitModule4_64'){$ELSE}Import('Py_InitModule4'){$ENDIF}
- else
- PyModule_Create2 := Import('PyModule_Create2');
+ PyModule_Create2 := Import('PyModule_Create2');
PyErr_Print := Import('PyErr_Print');
PyErr_SetNone := Import('PyErr_SetNone');
PyErr_SetObject := Import('PyErr_SetObject');
@@ -3851,305 +3373,232 @@ procedure TPythonInterface.MapDll;
PyErr_WarnExplicit := Import('PyErr_WarnExplicit');
PyEval_GetBuiltins := Import('PyEval_GetBuiltins');
PyImport_GetModuleDict := Import('PyImport_GetModuleDict');
- if IsPython3000 then
- PyInt_FromLong := Import('PyLong_FromLong')
- else
- PyInt_FromLong := Import('PyInt_FromLong');
PyArg_Parse := Import('PyArg_Parse');
PyArg_ParseTuple := Import('PyArg_ParseTuple');
PyArg_ParseTupleAndKeywords := Import('PyArg_ParseTupleAndKeywords');
Py_BuildValue := Import('Py_BuildValue');
Py_Initialize := Import('Py_Initialize');
- PyDict_New := Import('PyDict_New');
- PyDict_SetItemString := Import('PyDict_SetItemString');
PyModule_GetDict := Import('PyModule_GetDict');
PyObject_Str := Import('PyObject_Str');
PyRun_String := Import('PyRun_String');
PyRun_SimpleString := Import('PyRun_SimpleString');
PyDict_GetItemString := Import('PyDict_GetItemString');
- if not IsPython3000 then begin
- PyString_AsString := Import('PyString_AsString');
- PyString_AsStringAndSize := Import('PyString_AsStringAndSize')
- end else begin
- PyString_AsString := Import('PyBytes_AsString');
- PyString_AsStringAndSize := Import('PyBytes_AsStringAndSize');
- end;
- if not IsPython3000 then
- DLL_PyString_FromString := Import('PyString_FromString');
- if not IsPython3000 then
- PySys_SetArgv := Import('PySys_SetArgv')
- else
- PySys_SetArgv3000 := Import('PySys_SetArgv');
+ PySys_SetArgv := Import('PySys_SetArgv');
Py_Exit := Import('Py_Exit');
- if IsPython3000 then
- PyCFunction_NewEx :=Import('PyCFunction_NewEx')
- else
- PyCFunction_New :=Import('PyCFunction_New');
-
- PyEval_CallObjectWithKeywords:=Import('PyEval_CallObjectWithKeywords');
- PyEval_GetFrame :=Import('PyEval_GetFrame');
- PyEval_GetGlobals :=Import('PyEval_GetGlobals');
- PyEval_GetLocals :=Import('PyEval_GetLocals');
- //@PyEval_GetOwner :=Import('PyEval_GetOwner');
- if not IsPython3000 then
- PyEval_GetRestricted :=Import('PyEval_GetRestricted');
- PyEval_InitThreads :=Import('PyEval_InitThreads');
- PyEval_RestoreThread :=Import('PyEval_RestoreThread');
- PyEval_SaveThread :=Import('PyEval_SaveThread');
- if not IsPython3000 then
- PyFile_FromString :=Import('PyFile_FromString');
- PyFile_GetLine :=Import('PyFile_GetLine');
- if not IsPython3000 then
- PyFile_Name :=Import('PyFile_Name');
- if not IsPython3000 then
- PyFile_SetBufSize :=Import('PyFile_SetBufSize');
- if not IsPython3000 then
- PyFile_SoftSpace :=Import('PyFile_SoftSpace');
- PyFile_WriteObject :=Import('PyFile_WriteObject');
- PyFile_WriteString :=Import('PyFile_WriteString');
- PyFloat_AsDouble :=Import('PyFloat_AsDouble');
- PyFloat_FromDouble :=Import('PyFloat_FromDouble');
- PyFunction_GetCode :=Import('PyFunction_GetCode');
- PyFunction_GetGlobals :=Import('PyFunction_GetGlobals');
- PyFunction_New :=Import('PyFunction_New');
- PyImport_AddModule :=Import('PyImport_AddModule');
- PyImport_GetMagicNumber :=Import('PyImport_GetMagicNumber');
- PyImport_ImportFrozenModule:=Import('PyImport_ImportFrozenModule');
- PyImport_ImportModule :=Import('PyImport_ImportModule');
- PyImport_Import :=Import('PyImport_Import');
- //PyImport_Init :=Import('PyImport_Init');
- PyImport_ReloadModule :=Import('PyImport_ReloadModule');
- if not IsPython3000 then
- PyInstance_New :=Import('PyInstance_New');
- if IsPython3000 then
- PyInt_AsLong :=Import('PyLong_AsLong')
- else
- PyInt_AsLong :=Import('PyInt_AsLong');
- PyList_Append :=Import('PyList_Append');
- PyList_AsTuple :=Import('PyList_AsTuple');
- PyList_GetItem :=Import('PyList_GetItem');
- PyList_GetSlice :=Import('PyList_GetSlice');
- PyList_Insert :=Import('PyList_Insert');
- PyList_New :=Import('PyList_New');
- PyList_Reverse :=Import('PyList_Reverse');
- PyList_SetItem :=Import('PyList_SetItem');
- PyList_SetSlice :=Import('PyList_SetSlice');
- PyList_Size :=Import('PyList_Size');
- PyList_Sort :=Import('PyList_Sort');
- PyLong_AsDouble :=Import('PyLong_AsDouble');
- PyLong_AsLong :=Import('PyLong_AsLong');
- PyLong_FromDouble :=Import('PyLong_FromDouble');
- PyLong_FromLong :=Import('PyLong_FromLong');
- PyLong_FromString :=Import('PyLong_FromString');
- PyLong_FromString :=Import('PyLong_FromString');
- PyLong_FromUnsignedLong :=Import('PyLong_FromUnsignedLong');
- PyLong_AsUnsignedLong :=Import('PyLong_AsUnsignedLong');
- PyLong_FromUnicode :=Import('PyLong_FromUnicode');
- PyLong_FromLongLong :=Import('PyLong_FromLongLong');
- PyLong_AsLongLong :=Import('PyLong_AsLongLong');
- PyLong_FromVoidPtr :=Import('PyLong_FromVoidPtr');
- PyMapping_Check :=Import('PyMapping_Check');
- PyMapping_GetItemString :=Import('PyMapping_GetItemString');
- PyMapping_HasKey :=Import('PyMapping_HasKey');
- PyMapping_HasKeyString :=Import('PyMapping_HasKeyString');
- PyMapping_Length :=Import('PyMapping_Length');
- PyMapping_SetItemString :=Import('PyMapping_SetItemString');
- if not IsPython3000 then
- PyMethod_Class :=Import('PyMethod_Class');
- PyMethod_Function :=Import('PyMethod_Function');
- PyMethod_New :=Import('PyMethod_New');
- PyMethod_Self :=Import('PyMethod_Self');
- PyModule_GetName :=Import('PyModule_GetName');
- PyModule_New :=Import('PyModule_New');
- PyNumber_Absolute :=Import('PyNumber_Absolute');
- PyNumber_Add :=Import('PyNumber_Add');
- PyNumber_And :=Import('PyNumber_And');
- PyNumber_Check :=Import('PyNumber_Check');
- if not IsPython3000 then
- PyNumber_Coerce :=Import('PyNumber_Coerce');
- if IsPython3000 then
- PyNumber_Divide :=Import('PyNumber_TrueDivide')
- else
- PyNumber_Divide :=Import('PyNumber_Divide');
- PyNumber_FloorDivide :=Import('PyNumber_FloorDivide');
- PyNumber_TrueDivide :=Import('PyNumber_TrueDivide');
- PyNumber_Divmod :=Import('PyNumber_Divmod');
- PyNumber_Float :=Import('PyNumber_Float');
- if not IsPython3000 then
- PyNumber_Int :=Import('PyNumber_Int');
- PyNumber_Invert :=Import('PyNumber_Invert');
- PyNumber_Long :=Import('PyNumber_Long');
- PyNumber_Lshift :=Import('PyNumber_Lshift');
- PyNumber_Multiply :=Import('PyNumber_Multiply');
- PyNumber_Negative :=Import('PyNumber_Negative');
- PyNumber_Or :=Import('PyNumber_Or');
- PyNumber_Positive :=Import('PyNumber_Positive');
- PyNumber_Power :=Import('PyNumber_Power');
- PyNumber_Remainder :=Import('PyNumber_Remainder');
- PyNumber_Rshift :=Import('PyNumber_Rshift');
- PyNumber_Subtract :=Import('PyNumber_Subtract');
- PyNumber_Xor :=Import('PyNumber_Xor');
- PyOS_InitInterrupts :=Import('PyOS_InitInterrupts');
- PyOS_InterruptOccurred :=Import('PyOS_InterruptOccurred');
- PyObject_CallObject :=Import('PyObject_CallObject');
- PyObject_CallMethod :=Import('PyObject_CallMethod');
- if not IsPython3000 then
- PyObject_Compare :=Import('PyObject_Compare');
- PyObject_RichCompare :=Import('PyObject_RichCompare');
- PyObject_RichCompareBool :=Import('PyObject_RichCompareBool');
- PyObject_GetAttr :=Import('PyObject_GetAttr');
- PyObject_GetAttrString :=Import('PyObject_GetAttrString');
- PyObject_GetItem :=Import('PyObject_GetItem');
- PyObject_DelItem :=Import('PyObject_DelItem');
- PyObject_HasAttrString :=Import('PyObject_HasAttrString');
- PyObject_Hash :=Import('PyObject_Hash');
- PyObject_IsTrue :=Import('PyObject_IsTrue');
- PyObject_Length :=Import('PyObject_Length');
- PyObject_Repr :=Import('PyObject_Repr');
- PyObject_SetAttr :=Import('PyObject_SetAttr');
- PyObject_SetAttrString :=Import('PyObject_SetAttrString');
- PyObject_SetItem :=Import('PyObject_SetItem');
- PyObject_Init :=Import('PyObject_Init');
- PyObject_InitVar :=Import('PyObject_InitVar');
- PyObject_New :=Import('_PyObject_New');
- PyObject_NewVar :=Import('_PyObject_NewVar');
- PyObject_Free :=Import('PyObject_Free');
- PyObject_GetIter :=Import('PyObject_GetIter');
- PyIter_Next :=Import('PyIter_Next');
- PyObject_IsInstance :=Import('PyObject_IsInstance');
- PyObject_IsSubclass :=Import('PyObject_IsSubclass');
- PyObject_Call :=Import('PyObject_Call');
- PyObject_GenericGetAttr :=Import('PyObject_GenericGetAttr');
- PyObject_GenericSetAttr :=Import('PyObject_GenericSetAttr');
- PyObject_GC_Malloc :=Import('_PyObject_GC_Malloc');
- PyObject_GC_New :=Import('_PyObject_GC_New');
- PyObject_GC_NewVar :=Import('_PyObject_GC_NewVar');
- PyObject_GC_Resize :=Import('_PyObject_GC_Resize');
- PyObject_GC_Del :=Import('PyObject_GC_Del');
- PyObject_GC_Track :=Import('PyObject_GC_Track');
- PyObject_GC_UnTrack :=Import('PyObject_GC_UnTrack');
- PySequence_Check :=Import('PySequence_Check');
- PySequence_Concat :=Import('PySequence_Concat');
- PySequence_Count :=Import('PySequence_Count');
- PySequence_GetItem :=Import('PySequence_GetItem');
- PySequence_GetSlice :=Import('PySequence_GetSlice');
- PySequence_In :=Import('PySequence_In');
- PySequence_Index :=Import('PySequence_Index');
- PySequence_Length :=Import('PySequence_Length');
- PySequence_Repeat :=Import('PySequence_Repeat');
- PySequence_SetItem :=Import('PySequence_SetItem');
- PySequence_SetSlice :=Import('PySequence_SetSlice');
- PySequence_DelSlice :=Import('PySequence_DelSlice');
- PySequence_Tuple :=Import('PySequence_Tuple');
- PySequence_Contains :=Import('PySequence_Contains');
- PySlice_GetIndices :=Import('PySlice_GetIndices');
- PySeqIter_New :=Import('PySeqIter_New');
- PySlice_GetIndicesEx :=Import('PySlice_GetIndicesEx');
- PySlice_New :=Import('PySlice_New');
- if not IsPython3000 then begin
- PyString_Concat :=Import('PyString_Concat');
- PyString_ConcatAndDel :=Import('PyString_ConcatAndDel');
- PyString_Format :=Import('PyString_Format');
- PyString_FromStringAndSize:=Import('PyString_FromStringAndSize');
- PyString_Size :=Import('PyString_Size');
- PyString_DecodeEscape :=Import('PyString_DecodeEscape');
- PyString_Repr :=Import('PyString_Repr');
- end else begin
- PyString_Concat :=Import('PyBytes_Concat');
- PyString_ConcatAndDel :=Import('PyBytes_ConcatAndDel');
- PyString_FromStringAndSize:=Import('PyBytes_FromStringAndSize');
- PyString_Size :=Import('PyBytes_Size');
- PyString_DecodeEscape :=Import('PyBytes_DecodeEscape');
- PyString_Repr :=Import('PyBytes_Repr');
- end;
- PySys_GetObject :=Import('PySys_GetObject');
- //PySys_Init :=Import('PySys_Init');
- PySys_SetObject :=Import('PySys_SetObject');
- PySys_SetPath :=Import('PySys_SetPath');
- //PyTraceBack_Fetch :=Import('PyTraceBack_Fetch');
- PyTraceBack_Here :=Import('PyTraceBack_Here');
- PyTraceBack_Print :=Import('PyTraceBack_Print');
- //@PyTraceBack_Store :=Import('PyTraceBack_Store');
- PyTuple_GetItem :=Import('PyTuple_GetItem');
- PyTuple_GetSlice :=Import('PyTuple_GetSlice');
- PyTuple_New :=Import('PyTuple_New');
- PyTuple_SetItem :=Import('PyTuple_SetItem');
- PyTuple_Size :=Import('PyTuple_Size');
- PyType_IsSubtype :=Import('PyType_IsSubtype');
- PyType_GenericAlloc :=Import('PyType_GenericAlloc');
- PyType_GenericNew :=Import('PyType_GenericNew');
- PyType_Ready :=Import('PyType_Ready');
- PyUnicode_FromWideChar :=Import(Format('PyUnicode%s_FromWideChar',[UnicodeSuffix]));
- PyUnicode_AsWideChar :=Import(Format('PyUnicode%s_AsWideChar',[UnicodeSuffix]));
- PyUnicode_Decode :=Import(Format('PyUnicode%s_Decode',[UnicodeSuffix]));
- PyUnicode_AsEncodedString :=Import(Format('PyUnicode%s_AsEncodedString',[UnicodeSuffix]));
- PyUnicode_FromOrdinal :=Import(Format('PyUnicode%s_FromOrdinal',[UnicodeSuffix]));
- PyUnicode_FromString :=Import(Format('PyUnicode%s_FromString',[UnicodeSuffix]));
- PyUnicode_GetSize :=Import(Format('PyUnicode%s_GetSize',[UnicodeSuffix]));
- PyWeakref_GetObject :=Import('PyWeakref_GetObject');
- PyWeakref_NewProxy :=Import('PyWeakref_NewProxy');
- PyWeakref_NewRef :=Import('PyWeakref_NewRef');
- PyWrapper_New :=Import('PyWrapper_New');
- PyBool_FromLong :=Import('PyBool_FromLong');
- PyThreadState_SetAsyncExc :=Import('PyThreadState_SetAsyncExc');
- Py_AtExit :=Import('Py_AtExit');
- //Py_Cleanup :=Import('Py_Cleanup');
- Py_FatalError :=Import('Py_FatalError');
- if not IsPython3000 then begin
- Py_FindMethod :=Import('Py_FindMethod');
- Py_FindMethodInChain :=Import('Py_FindMethodInChain');
- DLL_Py_FlushLine :=Import('Py_FlushLine');
- _PyString_Resize :=Import('_PyString_Resize');
- Py_CompileStringFlags :=Import('Py_CompileStringFlags');
- end else begin
- _PyString_Resize :=Import('_PyBytes_Resize');
- Py_CompileStringExFlags :=Import('Py_CompileStringExFlags');
- end;
- _PyObject_New :=Import('_PyObject_New');
- Py_Finalize :=Import('Py_Finalize');
- if getProcAddress( FDLLHandle, 'PyCode_Addr2Line' ) <> nil then
- DLL_PyCode_Addr2Line := Import('PyCode_Addr2Line');
- if getProcAddress( FDLLHandle, 'PyImport_ExecCodeModule' ) <> nil then
- DLL_PyImport_ExecCodeModule := Import('PyImport_ExecCodeModule');
- //@PyClass_IsSubclass :=Import('PyClass_IsSubclass');
- PyErr_ExceptionMatches :=Import('PyErr_ExceptionMatches');
- PyErr_GivenExceptionMatches:=Import('PyErr_GivenExceptionMatches');
- PyEval_EvalCode :=Import('PyEval_EvalCode');
- Py_GetVersion :=Import('Py_GetVersion');
- Py_GetCopyright :=Import('Py_GetCopyright');
- Py_GetExecPrefix :=Import('Py_GetExecPrefix');
- Py_GetPath :=Import('Py_GetPath');
- if IsPython3000 then
- Py_SetPythonHome3000 :=Import('Py_SetPythonHome')
- else
- Py_SetPythonHome :=Import('Py_SetPythonHome');
- if IsPython3000 then
- Py_GetPythonHome3000 :=Import('Py_GetPythonHome')
- else
- Py_GetPythonHome :=Import('Py_GetPythonHome');
- Py_GetPrefix :=Import('Py_GetPrefix');
- Py_GetProgramName :=Import('Py_GetProgramName');
- PyParser_SimpleParseStringFlags := Import('PyParser_SimpleParseStringFlags');
- PyNode_Free :=Import('PyNode_Free');
- PyErr_NewException :=Import('PyErr_NewException');
-/// jah 29-sep-2000 : updated for python 2.0
-/// replaced Py_Malloc with PyMem_Malloc
-///--- @Py_Malloc := Import ('Py_Malloc');
-///+++ @Py_Malloc := Import ('PyMem_Malloc');
+ PyCFunction_NewEx := Import('PyCFunction_NewEx');
+
+ PyEval_CallObjectWithKeywords:= Import('PyEval_CallObjectWithKeywords');
+ PyEval_GetFrame := Import('PyEval_GetFrame');
+ PyEval_GetGlobals := Import('PyEval_GetGlobals');
+ PyEval_GetLocals := Import('PyEval_GetLocals');
+ PyEval_InitThreads := Import('PyEval_InitThreads');
+ PyEval_RestoreThread := Import('PyEval_RestoreThread');
+ PyEval_SaveThread := Import('PyEval_SaveThread');
+ PyFile_GetLine := Import('PyFile_GetLine');
+ PyFile_WriteObject := Import('PyFile_WriteObject');
+ PyFile_WriteString := Import('PyFile_WriteString');
+ PyFloat_AsDouble := Import('PyFloat_AsDouble');
+ PyFloat_FromDouble := Import('PyFloat_FromDouble');
+ PyFloat_FromString := Import('PyFloat_FromString');
+ PyFunction_GetCode := Import('PyFunction_GetCode');
+ PyFunction_GetGlobals := Import('PyFunction_GetGlobals');
+ PyFunction_New := Import('PyFunction_New');
+ PyImport_AddModule := Import('PyImport_AddModule');
+ PyImport_GetMagicNumber := Import('PyImport_GetMagicNumber');
+ PyImport_ImportFrozenModule:= Import('PyImport_ImportFrozenModule');
+ PyImport_ImportModule := Import('PyImport_ImportModule');
+ PyImport_Import := Import('PyImport_Import');
+ PyImport_ReloadModule := Import('PyImport_ReloadModule');
+ PyList_Append := Import('PyList_Append');
+ PyList_AsTuple := Import('PyList_AsTuple');
+ PyList_GetItem := Import('PyList_GetItem');
+ PyList_GetSlice := Import('PyList_GetSlice');
+ PyList_Insert := Import('PyList_Insert');
+ PyList_New := Import('PyList_New');
+ PyList_Reverse := Import('PyList_Reverse');
+ PyList_SetItem := Import('PyList_SetItem');
+ PyList_SetSlice := Import('PyList_SetSlice');
+ PyList_Size := Import('PyList_Size');
+ PyList_Sort := Import('PyList_Sort');
+ PyLong_AsDouble := Import('PyLong_AsDouble');
+ PyLong_AsLong := Import('PyLong_AsLong');
+ PyLong_FromDouble := Import('PyLong_FromDouble');
+ PyLong_FromLong := Import('PyLong_FromLong');
+ PyLong_FromString := Import('PyLong_FromString');
+ PyLong_FromString := Import('PyLong_FromString');
+ PyLong_FromUnsignedLong := Import('PyLong_FromUnsignedLong');
+ PyLong_AsUnsignedLong := Import('PyLong_AsUnsignedLong');
+ PyLong_FromUnicodeObject := Import('PyLong_FromUnicodeObject');
+ PyLong_FromLongLong := Import('PyLong_FromLongLong');
+ PyLong_FromUnsignedLongLong := Import('PyLong_FromUnsignedLongLong');
+ PyLong_AsLongLong := Import('PyLong_AsLongLong');
+ PyLong_FromVoidPtr := Import('PyLong_FromVoidPtr');
+ PyMapping_Check := Import('PyMapping_Check');
+ PyMapping_GetItemString := Import('PyMapping_GetItemString');
+ PyMapping_HasKey := Import('PyMapping_HasKey');
+ PyMapping_HasKeyString := Import('PyMapping_HasKeyString');
+ PyMapping_Length := Import('PyMapping_Length');
+ PyMapping_SetItemString := Import('PyMapping_SetItemString');
+ PyMapping_Keys := Import('PyMapping_Keys');
+ PyMapping_Values := Import('PyMapping_Values');
+ PyMethod_Function := Import('PyMethod_Function');
+ PyMethod_New := Import('PyMethod_New');
+ PyMethod_Self := Import('PyMethod_Self');
+ PyModule_GetName := Import('PyModule_GetName');
+ PyModule_New := Import('PyModule_New');
+ PyNumber_Absolute := Import('PyNumber_Absolute');
+ PyNumber_Add := Import('PyNumber_Add');
+ PyNumber_And := Import('PyNumber_And');
+ PyNumber_Check := Import('PyNumber_Check');
+ PyNumber_FloorDivide := Import('PyNumber_FloorDivide');
+ PyNumber_TrueDivide := Import('PyNumber_TrueDivide');
+ PyNumber_Divmod := Import('PyNumber_Divmod');
+ PyNumber_Float := Import('PyNumber_Float');
+ PyNumber_Invert := Import('PyNumber_Invert');
+ PyNumber_Long := Import('PyNumber_Long');
+ PyNumber_Lshift := Import('PyNumber_Lshift');
+ PyNumber_Multiply := Import('PyNumber_Multiply');
+ PyNumber_Negative := Import('PyNumber_Negative');
+ PyNumber_Or := Import('PyNumber_Or');
+ PyNumber_Positive := Import('PyNumber_Positive');
+ PyNumber_Power := Import('PyNumber_Power');
+ PyNumber_Remainder := Import('PyNumber_Remainder');
+ PyNumber_Rshift := Import('PyNumber_Rshift');
+ PyNumber_Subtract := Import('PyNumber_Subtract');
+ PyNumber_Xor := Import('PyNumber_Xor');
+ PyOS_InterruptOccurred := Import('PyOS_InterruptOccurred');
+ PyObject_CallObject := Import('PyObject_CallObject');
+ PyObject_CallMethod := Import('PyObject_CallMethod');
+ PyObject_RichCompare := Import('PyObject_RichCompare');
+ PyObject_RichCompareBool := Import('PyObject_RichCompareBool');
+ PyObject_GetAttr := Import('PyObject_GetAttr');
+ PyObject_GetAttrString := Import('PyObject_GetAttrString');
+ PyObject_GetItem := Import('PyObject_GetItem');
+ PyObject_DelItem := Import('PyObject_DelItem');
+ PyObject_HasAttr := Import('PyObject_HasAttr');
+ PyObject_HasAttrString := Import('PyObject_HasAttrString');
+ PyObject_Hash := Import('PyObject_Hash');
+ PyObject_IsTrue := Import('PyObject_IsTrue');
+ PyObject_Length := Import('PyObject_Length');
+ PyObject_Repr := Import('PyObject_Repr');
+ PyObject_SetAttr := Import('PyObject_SetAttr');
+ PyObject_SetAttrString := Import('PyObject_SetAttrString');
+ PyObject_SetItem := Import('PyObject_SetItem');
+ PyObject_Init := Import('PyObject_Init');
+ PyObject_InitVar := Import('PyObject_InitVar');
+ PyObject_New := Import('_PyObject_New');
+ PyObject_NewVar := Import('_PyObject_NewVar');
+ PyObject_Free := Import('PyObject_Free');
+ PyObject_GetIter := Import('PyObject_GetIter');
+ PyIter_Next := Import('PyIter_Next');
+ PyObject_IsInstance := Import('PyObject_IsInstance');
+ PyObject_IsSubclass := Import('PyObject_IsSubclass');
+ PyObject_Call := Import('PyObject_Call');
+ PyObject_GenericGetAttr := Import('PyObject_GenericGetAttr');
+ PyObject_GenericSetAttr := Import('PyObject_GenericSetAttr');
+ PyObject_Malloc := Import('PyObject_Malloc');
+ PyObject_GC_New := Import('_PyObject_GC_New');
+ PyObject_GC_NewVar := Import('_PyObject_GC_NewVar');
+ PyObject_GC_Resize := Import('_PyObject_GC_Resize');
+ PyObject_GC_Del := Import('PyObject_GC_Del');
+ PyObject_GC_Track := Import('PyObject_GC_Track');
+ PyObject_GC_UnTrack := Import('PyObject_GC_UnTrack');
+ PySequence_Check := Import('PySequence_Check');
+ PySequence_Concat := Import('PySequence_Concat');
+ PySequence_Count := Import('PySequence_Count');
+ PySequence_GetItem := Import('PySequence_GetItem');
+ PySequence_GetSlice := Import('PySequence_GetSlice');
+ PySequence_In := Import('PySequence_In');
+ PySequence_Index := Import('PySequence_Index');
+ PySequence_Length := Import('PySequence_Length');
+ PySequence_Repeat := Import('PySequence_Repeat');
+ PySequence_SetItem := Import('PySequence_SetItem');
+ PySequence_SetSlice := Import('PySequence_SetSlice');
+ PySequence_DelSlice := Import('PySequence_DelSlice');
+ PySequence_Tuple := Import('PySequence_Tuple');
+ PySequence_Contains := Import('PySequence_Contains');
+ PySequence_List := Import('PySequence_List');
+ PySlice_GetIndices := Import('PySlice_GetIndices');
+ PySeqIter_New := Import('PySeqIter_New');
+ PySlice_GetIndicesEx := Import('PySlice_GetIndicesEx');
+ PySlice_New := Import('PySlice_New');
+ PyBytes_AsString := Import('PyBytes_AsString');
+ PyBytes_AsStringAndSize := Import('PyBytes_AsStringAndSize');
+ PyBytes_Concat := Import('PyBytes_Concat');
+ PyBytes_ConcatAndDel := Import('PyBytes_ConcatAndDel');
+ PyBytes_FromString := Import('PyBytes_FromString');
+ PyBytes_FromStringAndSize := Import('PyBytes_FromStringAndSize');
+ PyBytes_Size := Import('PyBytes_Size');
+ PyBytes_DecodeEscape := Import('PyBytes_DecodeEscape');
+ PyBytes_Repr := Import('PyBytes_Repr');
+ _PyBytes_Resize := Import('_PyBytes_Resize');
+ PySys_GetObject := Import('PySys_GetObject');
+ PySys_SetObject := Import('PySys_SetObject');
+ PySys_SetPath := Import('PySys_SetPath');
+ PyTraceBack_Here := Import('PyTraceBack_Here');
+ PyTraceBack_Print := Import('PyTraceBack_Print');
+ PyTuple_GetItem := Import('PyTuple_GetItem');
+ PyTuple_GetSlice := Import('PyTuple_GetSlice');
+ PyTuple_New := Import('PyTuple_New');
+ PyTuple_SetItem := Import('PyTuple_SetItem');
+ PyTuple_Size := Import('PyTuple_Size');
+ PyType_IsSubtype := Import('PyType_IsSubtype');
+ PyType_GenericAlloc := Import('PyType_GenericAlloc');
+ PyType_GenericNew := Import('PyType_GenericNew');
+ PyType_Ready := Import('PyType_Ready');
+ PyUnicode_FromWideChar := Import('PyUnicode_FromWideChar');
+ PyUnicode_FromString := Import('PyUnicode_FromString');
+ PyUnicode_FromStringAndSize := Import('PyUnicode_FromStringAndSize');
+ PyUnicode_FromKindAndData := Import('PyUnicode_FromKindAndData');
+ PyUnicode_AsWideChar := Import('PyUnicode_AsWideChar');
+ PyUnicode_AsUTF8 := Import('PyUnicode_AsUTF8');
+ PyUnicode_AsUTF8AndSize := Import('PyUnicode_AsUTF8AndSize');
+ PyUnicode_Decode := Import('PyUnicode_Decode');
+ PyUnicode_DecodeUTF16 := Import('PyUnicode_DecodeUTF16');
+ PyUnicode_AsEncodedString := Import('PyUnicode_AsEncodedString');
+ PyUnicode_FromOrdinal := Import('PyUnicode_FromOrdinal');
+ PyUnicode_GetLength := Import('PyUnicode_GetLength');
+ PyWeakref_GetObject := Import('PyWeakref_GetObject');
+ PyWeakref_NewProxy := Import('PyWeakref_NewProxy');
+ PyWeakref_NewRef := Import('PyWeakref_NewRef');
+ PyWrapper_New := Import('PyWrapper_New');
+ PyBool_FromLong := Import('PyBool_FromLong');
+ PyThreadState_SetAsyncExc := Import('PyThreadState_SetAsyncExc');
+ Py_AtExit := Import('Py_AtExit');
+ Py_FatalError := Import('Py_FatalError');
+ Py_CompileStringExFlags := Import('Py_CompileStringExFlags');
+ _PyObject_New := Import('_PyObject_New');
+ Py_Finalize := Import('Py_Finalize');
+ PyImport_ExecCodeModule := Import('PyImport_ExecCodeModule');
+ PyErr_ExceptionMatches := Import('PyErr_ExceptionMatches');
+ PyErr_GivenExceptionMatches := Import('PyErr_GivenExceptionMatches');
+ PyEval_EvalCode := Import('PyEval_EvalCode');
+ Py_GetVersion := Import('Py_GetVersion');
+ Py_GetCopyright := Import('Py_GetCopyright');
+ Py_GetExecPrefix := Import('Py_GetExecPrefix');
+ Py_GetPath := Import('Py_GetPath');
+ Py_SetPath := Import('Py_SetPath');
+ Py_SetPythonHome := Import('Py_SetPythonHome');
+ Py_GetPythonHome := Import('Py_GetPythonHome');
+ Py_GetPrefix := Import('Py_GetPrefix');
+ Py_GetProgramName := Import('Py_GetProgramName');
+
+ if (FMajorVersion = 3) and (MinorVersion < 10) then
+ begin
+ PyParser_SimpleParseStringFlags := Import('PyParser_SimpleParseStringFlags');
+ PyNode_Free := Import('PyNode_Free');
+ end;
+
+ PyErr_NewException := Import('PyErr_NewException');
try
- Py_Malloc := Import ('PyMem_Malloc');
PyMem_Malloc := Import ('PyMem_Malloc');
except
end;
- if not IsPython3000 then
- Py_SetProgramName := Import('Py_SetProgramName')
- else
- Py_SetProgramName3000 := Import('Py_SetProgramName');
+ Py_SetProgramName := Import('Py_SetProgramName');
Py_IsInitialized := Import('Py_IsInitialized');
Py_GetProgramFullPath := Import('Py_GetProgramFullPath');
- if getProcAddress( FDLLHandle, 'Py_GetBuildInfo' ) <> nil then
- DLL_Py_GetBuildInfo := Import('Py_GetBuildInfo');
+ Py_GetBuildInfo := Import('Py_GetBuildInfo');
Py_NewInterpreter := Import('Py_NewInterpreter');
Py_EndInterpreter := Import('Py_EndInterpreter');
PyEval_AcquireLock := Import('PyEval_AcquireLock');
@@ -4169,12 +3618,9 @@ procedure TPythonInterface.MapDll;
PyGILState_Release := Import('PyGILState_Release');
end;
-function TPythonInterface.Py_CompileString( s1,s2:PAnsiChar;i:integer):PPyObject; cdecl;
+function TPythonInterface.Py_CompileString(str,filename:PAnsiChar;start:integer):PPyObject;
begin
- if IsPython3000 then
- Result := Py_CompileStringExFlags(s1, s2, i, nil, -1)
- else
- Result := Py_CompileStringFlags(s1, s2, i, nil);
+ Result := Py_CompileStringExFlags(str, filename, start, nil, -1);
end;
function TPythonInterface.PyParser_SimpleParseString( str : PAnsiChar; start : integer) : PNode; cdecl;
@@ -4182,12 +3628,12 @@ function TPythonInterface.PyParser_SimpleParseString( str : PAnsiChar; start : i
Result := PyParser_SimpleParseStringFlags(str, start, 0);
end;
-procedure TPythonInterface.Py_INCREF(op: PPyObject);
+class procedure TPythonInterface.Py_INCREF(op: PPyObject);
begin
Inc(op^.ob_refcnt);
end;
-procedure TPythonInterface.Py_DECREF(op: PPyObject);
+class procedure TPythonInterface.Py_DECREF(op: PPyObject);
begin
with op^ do begin
Dec(ob_refcnt);
@@ -4197,116 +3643,37 @@ procedure TPythonInterface.Py_DECREF(op: PPyObject);
end;
end;
-procedure TPythonInterface.Py_XINCREF(op: PPyObject);
+class procedure TPythonInterface.Py_XINCREF(op: PPyObject);
begin
if op <> nil then Py_INCREF(op);
end;
-procedure TPythonInterface.Py_XDECREF(op: PPyObject);
+class procedure TPythonInterface.Py_XDECREF(op: PPyObject);
begin
if op <> nil then Py_DECREF(op);
end;
-// This function is copied from compile.c because it was not
-// exported in the Dll
-function TPythonInterface.PyCode_Addr2Line( co: PPyCodeObject; addrq : Integer ) : Integer; cdecl;
-var
- size : Integer;
- p : PAnsiChar;
- line : Integer;
- addr : Integer;
- cpt : Integer;
-begin
- if Assigned(DLL_PyCode_Addr2Line) then
- begin
- Result := DLL_PyCode_Addr2Line( co, addrq );
- Exit;
- end;
- size := PyString_Size(co^.co_lnotab) div 2;
- p := PyString_AsString(co^.co_lnotab);
- line := co^.co_firstlineno;
- addr := 0;
- cpt := 0;
- while (size-1) >= 0 do
- begin
- Dec(size);
- Inc( addr, Ord(p[cpt]) );
- Inc(cpt);
- if addr > addrq then
- Break;
- Inc( line, Ord(p[cpt]) );
- Inc(cpt);
- end;
- Result := line;
-end;
-
-function TPythonInterface.Py_GetBuildInfo : PAnsiChar; cdecl;
-begin
- if Assigned(DLL_Py_GetBuildInfo) then
- begin
- Result := DLL_Py_GetBuildInfo;
- Exit;
- end;
- Result := 'No build info';
-end;
-function TPythonInterface.PyImport_ExecCodeModule( const AName : AnsiString; codeobject : PPyObject) : PPyObject;
-var
- m, d, v, modules : PPyObject;
+class procedure TPythonInterface.Py_CLEAR(var op: PPyObject);
+Var
+ _py_tmp : PPyObject;
begin
- if Assigned(DLL_PyImport_ExecCodeModule) then
+ _py_tmp := op;
+ if _py_tmp <> nil then
begin
- Result := DLL_PyImport_ExecCodeModule(PAnsiChar(AName), codeobject);
- Exit;
+ op := nil;
+ Py_DECREF(_py_tmp);
end;
- CheckPython;
- m := PyImport_AddModule(PAnsiChar(AName));
- if not Assigned(m) then
- begin
- Result := nil;
- Exit;
- end;
- d := PyModule_GetDict(m);
- if PyDict_GetItemString(d, '__builtins__') = nil then
- begin
- if PyDict_SetItemString(d, '__builtins__', PyEval_GetBuiltins) <> 0 then
- begin
- Result := nil;
- Exit;
- end;
- end;
- // Remember the fielname as the __file__ attribute
- if PyDict_SetItemString(d, '__file__', PPyCodeObject(codeobject)^.co_filename) <> 0 then
- PyErr_Clear; // Not important enough to report
- v := PyEval_EvalCode(PPyCodeObject(codeobject), d, d); // XXX owner ?
- if not Assigned(v) then
- begin
- Result := nil;
- Exit;
- end;
- Py_XDECREF(v);
- modules := PyImport_GetModuleDict;
- if PyDict_GetItemString(modules, PAnsiChar(AName)) = nil then
- begin
- PyErr_SetString(PyExc_ImportError^,
- PAnsiChar(AnsiString(Format('Loaded module %.200s not found in sys.modules', [AName]))));
- Result := nil;
- Exit;
- end;
- Py_XINCREF(m);
- Result := m;
end;
-function TPythonInterface.PyString_Check( obj : PPyObject ) : Boolean;
+function TPythonInterface.PyBytes_Check( obj : PPyObject ) : Boolean;
begin
- Result := PyObject_TypeCheck(obj, PyString_Type);
- if not Result then
- Result := PyObject_TypeCheck(obj, PyUnicode_Type);
+ Result := PyObject_TypeCheck(obj, PyBytes_Type);
end;
-function TPythonInterface.PyString_CheckExact(obj: PPyObject): Boolean;
+function TPythonInterface.PyBytes_CheckExact(obj: PPyObject): Boolean;
begin
- Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyString_Type));
+ Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyBytes_Type));
end;
function TPythonInterface.PyFloat_Check( obj : PPyObject ) : Boolean;
@@ -4319,22 +3686,6 @@ function TPythonInterface.PyFloat_CheckExact(obj: PPyObject): Boolean;
Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyFloat_Type));
end;
-function TPythonInterface.PyInt_Check( obj : PPyObject ) : Boolean;
-begin
- if IsPython3000 then
- Result := PyObject_TypeCheck(obj, PyLong_Type)
- else
- Result := PyObject_TypeCheck(obj, PyInt_Type);
-end;
-
-function TPythonInterface.PyInt_CheckExact(obj: PPyObject): Boolean;
-begin
- if IsPython3000 then
- Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyLong_Type))
- else
- Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyInt_Type));
-end;
-
function TPythonInterface.PyLong_Check( obj : PPyObject ) : Boolean;
begin
Result := PyObject_TypeCheck(obj, PyLong_Type);
@@ -4355,14 +3706,9 @@ function TPythonInterface.PyTuple_CheckExact(obj: PPyObject): Boolean;
Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyTuple_Type));
end;
-function TPythonInterface.PyInstance_Check( obj : PPyObject ) : Boolean;
-begin
- Result := Assigned( obj ) and (not IsPython3000) and (obj^.ob_type = PPyTypeObject(PyInstance_Type));
-end;
-
function TPythonInterface.PyClass_Check( obj : PPyObject ) : Boolean;
begin
- Result := Assigned( obj ) and not IsPython3000 and (obj^.ob_type = PPyTypeObject(PyClass_Type));
+ Result := Assigned( obj ) and (PyObject_IsInstance(obj, PPyObject(PyType_Type)) <> 0);
end;
function TPythonInterface.PyType_CheckExact( obj : PPyObject ) : Boolean;
@@ -4417,11 +3763,9 @@ function TPythonInterface.PyFunction_Check( obj : PPyObject ) : Boolean;
(obj^.ob_type = PPyTypeObject(PyFunction_Type)));
end;
-function TPythonInterface.PyIter_Check( obj : PPyObject ) : Boolean;
+function TPythonInterface.PyIter_Check(obj: PPyObject): Boolean;
begin
- Result := Assigned( obj ) and
- (IsPython3000 or (PyType_HasFeature(obj^.ob_type, Py_TPFLAGS_HAVE_ITER))
- and Assigned(obj^.ob_type^.tp_iternext));
+ Result := Assigned(obj) and Assigned(obj^.ob_type^.tp_iternext);
end;
function TPythonInterface.PyUnicode_Check( obj : PPyObject ) : Boolean;
@@ -4467,14 +3811,6 @@ function TPythonInterface.PyBool_Check( obj : PPyObject ) : Boolean;
Result := PyObject_TypeCheck(obj, PyBool_Type);
end;
-function TPythonInterface.PyBaseString_Check( obj : PPyObject ) : Boolean;
-begin
- if IsPython3000 then
- Result:= PyObject_TypeCheck(obj, PyUnicode_Type)
- else
- Result := PyObject_TypeCheck(obj, PyBaseString_Type);
-end;
-
function TPythonInterface.PyEnum_Check( obj : PPyObject ) : Boolean;
begin
Result := Assigned( obj ) and (obj^.ob_type = PPyTypeObject(PyEnum_Type));
@@ -4487,13 +3823,7 @@ function TPythonInterface.PyObject_TypeCheck(obj : PPyObject; t : PPyTypeObject)
Result := PyType_IsSubtype(obj^.ob_type, t) = 1;
end;
-function TPythonInterface.Py_InitModule( const AName : PAnsiChar; md : PPyMethodDef) : PPyObject;
-begin
- CheckPython;
- Result := Py_InitModule4( AName, md, nil, nil, APIVersion );
-end;
-
-function TPythonInterface.Py_InitModule3000(const md: PyModuleDef): PPyObject;
+function TPythonInterface.Py_InitModule(const md: PyModuleDef): PPyObject;
Var
modules : PPyObject;
begin
@@ -4507,12 +3837,6 @@ function TPythonInterface.Py_InitModule3000(const md: PyModuleDef): PPyObject;
GetPythonEngine.CheckError;
end;
-procedure TPythonInterface.Py_FlushLine; cdecl;
-begin
- if Assigned(DLL_Py_FlushLine) then
- DLL_Py_FlushLine;
-end;
-
(*******************************************************)
(** **)
(** class TPythonTraceback **)
@@ -4543,6 +3867,18 @@ destructor TPythonTraceback.Destroy;
inherited;
end;
+procedure TPythonTraceback.AddItem(const Context, FileName: string;
+ LineNo: Integer);
+var
+ Item: TTracebackItem;
+begin
+ Item := TTracebackItem.Create;
+ Item.Context := Context;
+ Item.FileName := FileName;
+ Item.LineNo := LineNo;
+ FItems.Add(Item);
+end;
+
procedure TPythonTraceback.Clear;
var
i : Integer;
@@ -4565,7 +3901,6 @@ procedure TPythonTraceback.Clear;
}
procedure TPythonTraceback.Refresh;
var
-// tb, tb1 : PPyTraceBackObject;
tb, tb1 : PPyObject;
obj : PPyObject;
frame : PPyObject;
@@ -4581,8 +3916,8 @@ procedure TPythonTraceback.Refresh;
// get the limit of the traceback
alimit := FLimit;
limitv := PySys_GetObject('tracebacklimit');
- if Assigned(limitv) and PyInt_Check(limitv) then
- alimit := PyInt_AsLong(limitv);
+ if Assigned(limitv) and PyLong_Check(limitv) then
+ alimit := PyLong_AsLong(limitv);
tb := PySys_GetObject('last_traceback');
tb1 := tb;
Py_XIncRef(tb1);
@@ -4671,7 +4006,6 @@ constructor TPythonEngine.Create(AOwner: TComponent);
i : Integer;
begin
inherited;
- FLock := TCriticalSection.Create;
FInitScript := TstringList.Create;
FClients := TList.Create;
FRedirectIO := True;
@@ -4692,18 +4026,21 @@ constructor TPythonEngine.Create(AOwner: TComponent);
end;
destructor TPythonEngine.Destroy;
+var
+ I: Integer;
begin
LocalVars := nil;
GlobalVars := nil;
Destroying;
Finalize;
-{$IFDEF FPC}
+ for I := 0 to ClientCount - 1 do
+ Clients[I].ClearEngine;
+{$IFDEF FPC} // See https://github.com/Alexey-T/Python-for-Lazarus/issues/29
inherited;
-{$ENDIF} // Free our objects
+{$ENDIF}
FClients.Free;
FInitScript.Free;
FTraceback.Free;
- FLock.Free;
{$IFNDEF FPC}
inherited;
{$ENDIF}
@@ -4712,7 +4049,6 @@ destructor TPythonEngine.Destroy;
procedure TPythonEngine.Finalize;
var
i: integer;
- canDetachClients : Boolean;
begin
// switch off redirection when the component is destroying,
// because the form or datamodule is beeing closed, and
@@ -4735,28 +4071,17 @@ procedure TPythonEngine.Finalize;
Finalize;
end;
// Then finalize Python, if we have to
- if Initialized and FAutoFinalize then
+ if Initialized and FAutoFinalize then begin
try
- FFinalizing := True;
- Py_Finalize;
- finally
- FFinalizing := False;
- FInitialized := False;
- end;
- // Detach our clients, when engine is beeing destroyed or one of its clients.
- canDetachClients := csDestroying in ComponentState;
- if not canDetachClients then
- for i := 0 to ClientCount - 1 do
- if csDestroying in Clients[i].ComponentState then
- begin
- canDetachClients := True;
- Break;
+ try
+ FFinalizing := True;
+ Py_Finalize;
+ finally
+ FFinalizing := False;
+ FInitialized := False;
end;
- if canDetachClients then
- begin
- for i := 0 to ClientCount - 1 do
- Clients[i].ClearEngine;
- FClients.Clear;
+ except
+ end;
end;
// Free our reference
gPythonEngine := nil;
@@ -4770,16 +4095,6 @@ procedure TPythonEngine.Finalize;
FPyDateTime_DateTimeTZType := nil;
end;
-procedure TPythonEngine.Lock;
-begin
- FLock.Enter;
-end;
-
-procedure TPythonEngine.Unlock;
-begin
- FLock.Leave;
-end;
-
procedure TPythonEngine.AfterLoad;
begin
inherited;
@@ -4795,10 +4110,10 @@ procedure TPythonEngine.BeforeLoad;
procedure TPythonEngine.DoOpenDll(const aDllName : String);
var
- i : Integer;
+ i: Integer;
begin
if UseLastKnownVersion then
- for i:= Integer(COMPILED_FOR_PYTHON_VERSION_INDEX) to High(PYTHON_KNOWN_VERSIONS) do
+ for i:= Integer(COMPILED_FOR_PYTHON_VERSION_INDEX) downto 1 do
begin
RegVersion := PYTHON_KNOWN_VERSIONS[i].RegVersion;
FDLLHandle := SafeLoadLibrary(GetDllPath+PYTHON_KNOWN_VERSIONS[i].DllName);
@@ -4808,10 +4123,12 @@ procedure TPythonEngine.DoOpenDll(const aDllName : String);
APIVersion := PYTHON_KNOWN_VERSIONS[i].APIVersion;
Exit;
end;
- if not PYTHON_KNOWN_VERSIONS[i].CanUseLatest then
- Break;
- end;
- inherited;
+ end
+ else
+ begin
+ RegVersion := SysVersionFromDLLName(aDllName);
+ inherited;
+ end;
end;
procedure TPythonEngine.AssignPyFlags;
@@ -4832,14 +4149,7 @@ procedure TPythonEngine.AssignPyFlags;
SetFlag(Py_OptimizeFlag, pfOptimize in FPyFlags);
SetFlag(Py_NoSiteFlag, pfNoSite in FPyFlags);
SetFlag(Py_FrozenFlag, pfFrozenFlag in FPyFlags);
- if not IsPython3000 then begin
- SetFlag(Py_UseClassExceptionsFlag, pfUseClassExceptionsFlag in FPyFlags);
- SetFlag(Py_UnicodeFlag, pfUnicode in FPyFlags);
- SetFlag(Py_TabcheckFlag, pfTabcheck in FPyFlags);
- end;
SetFlag(Py_IgnoreEnvironmentFlag, pfIgnoreEnvironmentFlag in FPyFlags);
- if Assigned(Py_DivisionWarningFlag) then
- SetFlag(Py_DivisionWarningFlag, pfDivisionWarningFlag in FPyFlags);
end;
procedure TPythonEngine.Initialize;
@@ -4847,7 +4157,19 @@ procedure TPythonEngine.Initialize;
procedure InitSysPath;
var
_path : PPyObject;
+ const Script =
+ 'import sys' + sLineBreak +
+ 'sys.executable = r"%s"' + sLineBreak +
+ 'path = sys.path' + sLineBreak +
+ 'for i in range(len(path)-1, -1, -1):' + sLineBreak +
+ ' if path[i].find("site-packages") > 0:' + sLineBreak +
+ ' path.pop(i)' + sLineBreak +
+ 'import site' + sLineBreak +
+ 'site.main()' + sLineBreak +
+ 'del sys, path, i, site';
begin
+ if VenvPythonExe <> '' then
+ ExecString(AnsiString(Format(Script, [VenvPythonExe])));
_path := PySys_GetObject('path');
if Assigned(FOnSysPathInit) then
FOnSysPathInit(Self, _path);
@@ -4906,38 +4228,13 @@ procedure TPythonEngine.Initialize;
if Assigned(gPythonEngine) then
raise Exception.Create('There is already one instance of TPythonEngine running' );
- {$IFDEF FPC}
- //this allows you to just call Initialize to create a non-IDE instance with
- //Lazarus.
- if(AutoLoad and not IsHandleValid) then begin
- LoadDLL;//Calls initialize
- exit;
- end;
- {$ENDIF}
-
gPythonEngine := Self;
- //CheckRegistry; //AT: disabled
-
- if IsPython3000 then begin
- if Assigned(Py_SetProgramName3000) then
- begin
- FProgramNameW := ParamStr(0);
- Py_SetProgramName3000(PWideChar(FProgramNameW));
- end
- end else begin
- if Assigned(Py_SetProgramName) then
- begin
- FProgramName := ParamStr(0);
- Py_SetProgramName(PAnsiChar(FProgramName));
- end
- end;
+ CheckRegistry;
+ if Assigned(Py_SetProgramName) and (Length(FProgramName) > 0) then
+ Py_SetProgramName(PWCharT(FProgramName));
AssignPyFlags;
- if FPythonHomeW<>'' then begin
- if IsPython3000 then
- Py_SetPythonHome3000(PWideChar(FPythonHomeW))
- else
- Py_SetPythonHome(PAnsiChar(FPythonHome));
- end;
+ if Length(FPythonHome) > 0 then
+ Py_SetPythonHome(PWCharT(FPythonHome));
Py_Initialize;
if Assigned(Py_IsInitialized) then
FInitialized := Py_IsInitialized() <> 0
@@ -4967,17 +4264,6 @@ procedure TPythonEngine.SetInitScript(Value: TStrings);
FInitScript.Assign(Value);
end;
-function TPythonEngine.GetInterpreterState: PPyInterpreterState;
-var
- res: PPyThreadState;
-begin
- if Assigned(PyThreadState_Get) then begin
- res:= PyThreadState_Get;
- Result := res^.interp;
- end else
- Result := nil;
-end;
-
function TPythonEngine.GetThreadState: PPyThreadState;
begin
if Assigned(PyThreadState_Get) then
@@ -5008,24 +4294,10 @@ function TPythonEngine.GetClients( idx : Integer ) : TEngineClient;
procedure TPythonEngine.Notification( AComponent: TComponent;
Operation: TOperation);
-var
- i : Integer;
begin
inherited;
- if Operation = opRemove then
- begin
- if AComponent = IO then
- IO := nil
- else
- begin
- for i := 0 to ClientCount - 1 do
- if Clients[i] = AComponent then
- begin
- RemoveClient( Clients[i] );
- Break;
- end;
- end;
- end;
+ if (Operation = opRemove) and (AComponent = IO) then
+ IO := nil
end;
procedure TPythonEngine.CheckRegistry;
@@ -5074,62 +4346,36 @@ procedure TPythonEngine.CheckRegistry;
procedure TPythonEngine.SetProgramArgs;
var
- buff : PAnsiChar;
- argv : PPAnsiChar;
- i, argc : Integer;
- L : array of AnsiString;
- wargv : PPWideChar;
- wbuff : PWideChar;
- {$IFDEF UNIX}
- UCS4L : array of UCS4String;
- {$ELSE}
- WL : array of UnicodeString;
- {$ENDIF}
+ I, argc : Integer;
+ wargv : array of PWCharT;
+ WL : array of WCharTString;
+ TempS: UnicodeString;
begin
// we build a string list of the arguments, because ParamStr returns a volatile string
- // and we want to build an array of PAnsiChar, pointing to valid strings.
+ // and we want to build an array of PWCharT, pointing to valid strings.
argc := ParamCount;
- if not IsPython3000 then begin
- SetLength(L, argc+1);
- GetMem( buff, sizeof(PAnsiChar)*(argc+1) );
- try
- argv := PPAnsiChar(buff);
- // get the strings
- // build the PAnsiChar array
- for i := 0 to argc do begin
- L[i] := AnsiString(ParamStr(i));
- argv^[i] := PAnsiChar(L[i]);
- end;
- // set the argv list of the sys module with the application arguments
- PySys_SetArgv( argc+1, argv );
- finally
- FreeMem( buff );
- end;
- end else begin
- GetMem(wbuff, sizeof(PWideChar)*(argc+1));
- try
- wargv := PPWideChar(wbuff);
- // build the PWideChar array
- {$IFDEF UNIX}
- // Note that Linux uses UCS4 strings, whereas it declares using UCS2 strings!!!
- SetLength(UCS4L, argc+1);
- for i := 0 to argc do begin
- UCS4L[i] := WideStringToUCS4String(ParamStr(i));
- wargv^[i] := @UCS4L[i][0];
- end;
- {$ELSE}
- SetLength(WL, argc+1);
- for i := 0 to argc do begin
- WL[i] := UnicodeString(ParamStr(i));
- wargv^[i] := PWideChar(WL[i]);
- end;
- {$ENDIF}
- // set the argv list of the sys module with the application arguments
- PySys_SetArgv3000( argc + 1, wargv );
- finally
- FreeMem( wbuff );
- end;
+ SetLength(wargv, argc + 1);
+ // build the PWCharT array
+ SetLength(WL, argc+1);
+ for I := 0 to argc do begin
+ {
+ ... the first entry should refer to the script file to be executed rather
+ than the executable hosting the Python interpreter. If there isn’t a
+ script that will be run, the first entry in argv can be an empty string.
+ }
+ if I = 0 then
+ TempS := ''
+ else
+ TempS := ParamStr(I);
+ {$IFDEF POSIX}
+ WL[I] := UnicodeStringToUCS4String(TempS);
+ {$ELSE}
+ WL[I] := UnicodeString(TempS);
+ {$ENDIF}
+ wargv[I] := PWCharT(WL[I]);
end;
+ // set the argv list of the sys module with the application arguments
+ PySys_SetArgv( argc + 1, PPWCharT(wargv) );
end;
procedure TPythonEngine.InitWinConsole;
@@ -5194,29 +4440,71 @@ procedure TPythonEngine.SetPyFlags(const Value: TPythonFlags);
end; // of if
end;
-procedure TPythonEngine.SetPythonHome(const PythonHome: String);
+function TPythonEngine.GetPythonHome: UnicodeString;
begin
- FPythonHomeW := PythonHome;
- FPythonHome := PythonHome;
+{$IFDEF POSIX}
+ if Length(FPythonHome) = 0 then
+ Result := ''
+ else
+ Result := UCS4StringToUnicodeString(FPythonHome);
+{$ELSE}
+ Result := FPythonHome;
+{$ENDIF}
end;
-function TPythonEngine.IsType(ob: PPyObject; obt: PPyTypeObject): Boolean;
+function TPythonEngine.GetPythonPath: UnicodeString;
begin
- result := ob^.ob_type = obt;
+{$IFDEF POSIX}
+ if (Length(FPythonPath) > 0) then
+ Result := UCS4StringToUnicodeString(FPythonPath)
+ else
+ Result := '';
+{$ELSE}
+ Result := FPythonPath;
+{$ENDIF}
end;
-function TPythonEngine.GetAttrString(obj: PPyObject; AName: PAnsiChar):PAnsiChar;
-var
- attr: PPyObject;
+function TPythonEngine.GetProgramName: UnicodeString;
begin
- CheckPython;
- result := nil;
- attr := PyObject_GetAttrString(obj, AName);
- if attr <> nil then begin
- result := PyString_AsString(attr);
- Py_XDECREF(attr);
- end;
- PyErr_Clear;
+{$IFDEF POSIX}
+ if Length(FProgramName) = 0 then
+ Result := ''
+ else
+ Result := UCS4StringToUnicodeString(FProgramName);
+{$ELSE}
+ Result := FProgramName;
+{$ENDIF}
+end;
+procedure TPythonEngine.SetPythonHome(const PythonHome: UnicodeString);
+begin
+{$IFDEF POSIX}
+ FPythonHome := UnicodeStringToUCS4String(PythonHome);
+{$ELSE}
+ FPythonHome := PythonHome;
+{$ENDIF}
+end;
+
+procedure TPythonEngine.SetPythonPath(const Value: UnicodeString);
+begin
+{$IFDEF POSIX}
+ FPythonPath := UnicodeStringToUCS4String(Value);
+{$ELSE}
+ FPythonPath := Value;
+{$ENDIF}
+end;
+
+procedure TPythonEngine.SetProgramName(const ProgramName: UnicodeString);
+begin
+{$IFDEF POSIX}
+ FProgramName := UnicodeStringToUCS4String(ProgramName);
+{$ELSE}
+ FProgramName := ProgramName;
+{$ENDIF}
+end;
+
+function TPythonEngine.IsType(ob: PPyObject; obt: PPyTypeObject): Boolean;
+begin
+ result := ob^.ob_type = obt;
end;
function TPythonEngine.EvalPyFunction(pyfunc, pyargs:PPyObject): Variant;
@@ -5244,9 +4532,7 @@ function TPythonEngine.EvalPyFunction(pyfunc, pyargs:PPyObject): Variant;
Py_DECREF(presult);
end;
end;
- Py_FlushLine;
except
- Py_FlushLine;
if PyErr_Occurred <> nil then
CheckError(False)
else
@@ -5278,40 +4564,55 @@ function TPythonEngine.EvalFunctionNoArgs(pyfunc:PPyObject): Variant;
end;
end;
-function TPythonEngine.EvalStringAsStr(const command : AnsiString) : String;
+function TPythonEngine.EvalStringAsStr(const command: AnsiString; const
+ FileName: string = ''): string;
begin
- Result := Run_CommandAsString( command, eval_input );
+ Result := Run_CommandAsString(command, eval_input, FileName);
end;
-function TPythonEngine.EvalString(const command : AnsiString) : PPyObject;
+function TPythonEngine.EvalString(const command: AnsiString; const FileName:
+ string = ''): PPyObject;
begin
- Result := Run_CommandAsObject( command, eval_input );
+ Result := Run_CommandAsObject(command, eval_input, FileName);
end;
-procedure TPythonEngine.ExecString(const command : AnsiString);
+procedure TPythonEngine.ExecString(const command: AnsiString; const FileName:
+ string = '');
begin
- Py_XDecRef( Run_CommandAsObject( command, file_input ) );
+ Py_XDecRef(Run_CommandAsObject(command, file_input, FileName));
end;
-function TPythonEngine.Run_CommandAsString(const command : AnsiString; mode : Integer) : String;
+function TPythonEngine.Run_CommandAsString(const command: AnsiString; mode:
+ Integer; const FileName: string = ''): string;
var
- v : PPyObject;
+ PRes : PPyObject;
begin
Result := '';
- v := Run_CommandAsObject( command, mode );
- Result := PyObjectAsString( v );
- Py_XDECREF(v);
+ PRes := Run_CommandAsObject(command, mode, FileName);
+ Result := PyObjectAsString(PRes);
+ Py_XDECREF(PRes);
end;
-function TPythonEngine.Run_CommandAsObject(const command : AnsiString; mode : Integer) : PPyObject;
+function TPythonEngine.Run_CommandAsObject(const command: AnsiString; mode:
+ Integer; const FileName: string = ''): PPyObject;
begin
- Result := Run_CommandAsObjectWithDict(command, mode, nil, nil);
+ Result := Run_CommandAsObjectWithDict(command, mode, nil, nil, FileName);
end;
-function TPythonEngine.Run_CommandAsObjectWithDict(const command : AnsiString; mode : Integer; locals, globals : PPyObject) : PPyObject;
+function TPythonEngine.Run_CommandAsObjectWithDict(const command: AnsiString;
+ mode: Integer; locals, globals: PPyObject; const FileName: string =
+ ''): PPyObject;
+{
+ This is the core function for executing/evaluating python code
+ Parameters:
+ - command: utf-8 encoded AnsiString with the code that will be executed or evaluated
+ - mode: one of the constants file_input, single_input, eval_input
+ - locals, globals: python dictionaries with local/global namespaces. Can be nil.
+ - FileName; optional string used when debugging code with external debuggers
+}
var
m : PPyObject;
- _locals, _globals : PPyObject;
+ _locals, _globals, Code : PPyObject;
begin
CheckPython;
Result := nil;
@@ -5337,12 +4638,14 @@ function TPythonEngine.Run_CommandAsObjectWithDict(const command : AnsiString; m
_globals := _locals;
try
- Result := PyRun_String(PAnsiChar(CleanString(command)), mode, _globals, _locals);
+ Code := Py_CompileString(PAnsiChar(CleanString(command)),
+ PAnsiChar(EncodeString(FileName)), mode);
+ if Code = nil then
+ CheckError(False);
+ Result := PyEval_EvalCode(Code, _globals, _locals );
if Result = nil then
CheckError(False);
- Py_FlushLine;
except
- Py_FlushLine;
if PyErr_Occurred <> nil then
CheckError(False)
else
@@ -5350,40 +4653,62 @@ function TPythonEngine.Run_CommandAsObjectWithDict(const command : AnsiString; m
end;
end;
+procedure TPythonEngine.ExecStrings(strings: TStrings; const FileName: string =
+ '');
+begin
+ Py_XDecRef(Run_CommandAsObject(EncodeString(strings.Text), file_input, FileName));
+end;
-procedure TPythonEngine.ExecStrings( strings : TStrings );
+function TPythonEngine.EvalStrings(strings: TStrings; const FileName: string =
+ ''): PPyObject;
begin
- Py_XDecRef( Run_CommandAsObject( strings.Text, file_input ) );
+ Result := Run_CommandAsObject(EncodeString(strings.Text) , eval_input, FileName);
end;
-function TPythonEngine.EvalStrings( strings : TStrings ) : PPyObject;
+procedure TPythonEngine.ExecFile(const FileName: string; locals,
+ globals: PPyObject);
+var
+ SL: TStringList;
begin
- Result := Run_CommandAsObject( strings.Text, eval_input );
+ SL := TStringList.Create;
+ try
+ SL.LoadFromFile(FileName, TEncoding.UTF8);
+ ExecStrings(SL, locals, globals, FileName);
+ finally
+ SL.Free;
+ end;
end;
-procedure TPythonEngine.ExecString(const command : AnsiString; locals, globals : PPyObject );
+procedure TPythonEngine.ExecString(const command: AnsiString; locals, globals:
+ PPyObject; const FileName: string = '');
begin
- Py_XDecRef( Run_CommandAsObjectWithDict( command, file_input, locals, globals ) );
+ Py_XDecRef(Run_CommandAsObjectWithDict(command, file_input, locals, globals, FileName));
end;
-procedure TPythonEngine.ExecStrings( strings : TStrings; locals, globals : PPyObject );
+procedure TPythonEngine.ExecStrings(strings: TStrings; locals, globals:
+ PPyObject; const FileName: string = '');
begin
- Py_XDecRef( Run_CommandAsObjectWithDict( strings.Text, file_input, locals, globals ) );
+ Py_XDecRef( Run_CommandAsObjectWithDict(EncodeString(strings.Text),
+ file_input, locals, globals, FileName));
end;
-function TPythonEngine.EvalString( const command : AnsiString; locals, globals : PPyObject ) : PPyObject;
+function TPythonEngine.EvalString(const command: AnsiString; locals, globals:
+ PPyObject; const FileName: string = ''): PPyObject;
begin
- Result := Run_CommandAsObjectWithDict( command, eval_input, locals, globals );
+ Result := Run_CommandAsObjectWithDict(command, eval_input, locals, globals, FileName);
end;
-function TPythonEngine.EvalStrings( strings : TStrings; locals, globals : PPyObject ) : PPyObject;
+function TPythonEngine.EvalStrings(strings: TStrings; locals, globals:
+ PPyObject; const FileName: string = ''): PPyObject;
begin
- Result := Run_CommandAsObjectWithDict( strings.Text, eval_input, locals, globals );
+ Result := Run_CommandAsObjectWithDict(EncodeString(strings.Text),
+ eval_input, locals, globals, FileName);
end;
-function TPythonEngine.EvalStringsAsStr( strings : TStrings ) : String;
+function TPythonEngine.EvalStringsAsStr(strings: TStrings; const FileName:
+ string = ''): string;
begin
- Result := Run_CommandAsString( strings.Text, eval_input );
+ Result := Run_CommandAsString(EncodeString(strings.Text), eval_input, FileName);
end;
function TPythonEngine.CheckEvalSyntax( const str : AnsiString ) : Boolean;
@@ -5419,14 +4744,16 @@ procedure TPythonEngine.RaiseError;
Result := E;
end;
- function DefineSyntaxError( E : EPySyntaxError; const sType, sValue : String; err_type, err_value : PPyObject ) : EPySyntaxError;
+ function DefineSyntaxError( E : EPySyntaxError; const sType, sValue : UnicodeString; err_type, err_value : PPyObject ) : EPySyntaxError;
var
- s_value : String;
- s_line : String;
- s_filename : String;
- i_line_number : Integer;
- i_offset : Integer;
- tmp : PPyObject;
+ s_value : UnicodeString;
+ s_line : UnicodeString;
+ s_filename : UnicodeString;
+ i_line_number : Integer;
+ i_offset : Integer;
+ i_end_line_number : Integer;
+ i_end_offset : Integer;
+ tmp : PPyObject;
begin
Result := E;
Result.EName := sType;
@@ -5436,64 +4763,82 @@ procedure TPythonEngine.RaiseError;
s_filename := '';
i_line_number := 0;
i_offset := 0;
+ i_end_line_number := 0;
+ i_end_offset := 0;
// Sometimes there's a tuple instead of instance...
- if PyTuple_Check( err_value ) and (PyTuple_Size( err_value) >= 2) then
+ if PyTuple_Check(err_value) and (PyTuple_Size( err_value) >= 2) then
begin
- s_value := PyString_AsDelphiString(PyTuple_GetItem( err_value, 0));
+ s_value := PyObjectAsString(PyTuple_GetItem( err_value, 0));
err_value := PyTuple_GetItem( err_value, 1);
if PyTuple_Check( err_value ) and (PyTuple_Size( err_value) >= 4) then
begin
- i_line_number := PyInt_AsLong(PyTuple_GetItem( err_value, 1));
- i_offset := PyInt_AsLong(PyTuple_GetItem( err_value, 2));
- s_line := Trim(PyString_AsDelphiString(PyTuple_GetItem( err_value, 3)));
+ i_line_number := PyLong_AsLong(PyTuple_GetItem( err_value, 1));
+ i_offset := PyLong_AsLong(PyTuple_GetItem( err_value, 2));
+ s_line := Trim(PyObjectAsString(PyTuple_GetItem( err_value, 3)));
end;
end else
// Is it an instance of the SyntaxError class ?
- if (PyInstance_Check( err_value ) and (PyClass_IsSubclass( PPyObject(PPyInstanceObject(err_value)^.in_class), err_type ) <> 0)) or
- ((PyType_IsSubtype(PPyTypeObject(err_type), PPyTypeObject(PyExc_SyntaxError^)) = 1) and IsType(err_value, PPyTypeObject(err_type))) then
- begin
- // Get the filename
- tmp := PyObject_GetAttrString(err_value, 'filename');
- if tmp <> nil then begin
- if PyString_Check(tmp) then
- s_filename := PyString_AsDelphiString(tmp)
- else if tmp = Py_None then
- s_filename := '???';
- Py_XDECREF(tmp);
- end;
- // Get the text containing the error, cut of carriage return
- tmp := PyObject_GetAttrString(err_value, 'text');
- if Assigned(tmp) and PyString_Check(tmp) then
- s_line := Trim(PyString_AsDelphiString(tmp));
- Py_XDECREF(tmp);
- // Get the offset where the error should appear
- tmp := PyObject_GetAttrString(err_value, 'offset' );
- if Assigned(tmp) and PyInt_Check(tmp) then
- i_offset := PyInt_AsLong(tmp);
+ if (PyType_IsSubtype(PPyTypeObject(err_type), PPyTypeObject(PyExc_SyntaxError^)) = 1)
+ and IsType(err_value, PPyTypeObject(err_type))
+ then
+ begin
+ // Get the filename
+ tmp := PyObject_GetAttrString(err_value, 'filename');
+ if tmp <> nil then begin
+ if PyUnicode_Check(tmp) then
+ s_filename := PyUnicodeAsString(tmp)
+ else if tmp = Py_None then
+ s_filename := '???';
Py_XDECREF(tmp);
- // Get the line number of the error
- tmp := PyObject_GetAttrString(err_value, 'lineno' );
- if Assigned(tmp) and PyInt_Check(tmp) then
- i_line_number := PyInt_AsLong(tmp);
+ end;
+ // Get the text containing the error, cut of carriage return
+ tmp := PyObject_GetAttrString(err_value, 'text');
+ if Assigned(tmp) and PyUnicode_Check(tmp) then
+ s_line := Trim(PyUnicodeAsString(tmp));
+ Py_XDECREF(tmp);
+ // Get the offset where the error should appear
+ tmp := PyObject_GetAttrString(err_value, 'offset' );
+ if Assigned(tmp) and PyLong_Check(tmp) then
+ i_offset := PyLong_AsLong(tmp);
+ Py_XDECREF(tmp);
+ // Get the line number of the error
+ tmp := PyObject_GetAttrString(err_value, 'lineno' );
+ if Assigned(tmp) and PyLong_Check(tmp) then
+ i_line_number := PyLong_AsLong(tmp);
+ Py_XDECREF(tmp);
+ // Get the message of the error
+ tmp := PyObject_GetAttrString(err_value, 'msg' );
+ if Assigned(tmp) and PyUnicode_Check(tmp) then
+ s_value := PyUnicodeAsString(tmp);
+ Py_XDECREF(tmp);
+ if (MajorVersion > 3) or (MinorVersion >= 10) then
+ begin
+ // Get the end offset of the error
+ tmp := PyObject_GetAttrString(err_value, 'end_offset' );
+ if Assigned(tmp) and PyLong_Check(tmp) then
+ i_end_offset := PyLong_AsLong(tmp);
Py_XDECREF(tmp);
- // Get the message of the error
- tmp := PyObject_GetAttrString(err_value, 'msg' );
- if Assigned(tmp) and PyString_Check(tmp) then
- s_value := PyString_AsDelphiString(tmp);
+ // Get the end line number of the error
+ tmp := PyObject_GetAttrString(err_value, 'end_lineno' );
+ if Assigned(tmp) and PyLong_Check(tmp) then
+ i_end_line_number := PyLong_AsLong(tmp);
Py_XDECREF(tmp);
end;
+ end;
// If all is ok
if s_value <> '' then
begin
with Result do
begin
- Message := Format('%s: %s (line %d, offset %d): ''%s''', [sType,s_value,i_line_number, i_offset,s_line]);
- EName := sType;
- EValue := s_value;
- EFileName := s_filename;
- ELineNumber := i_line_number;
- EOffset := i_offset;
- ELineStr := s_line;
+ Message := Format('%s: %s (line %d, offset %d): ''%s''', [sType,s_value,i_line_number, i_offset,s_line]);
+ EName := sType;
+ EValue := s_value;
+ EFileName := s_filename;
+ ELineNumber := i_line_number;
+ EOffset := i_offset;
+ EEndLineNumber := i_end_line_number;
+ EEndOffset := i_end_offset;
+ ELineStr := s_line;
end;
end
else
@@ -5502,11 +4847,8 @@ procedure TPythonEngine.RaiseError;
function GetTypeAsString( obj : PPyObject ) : String;
begin
- if PyClass_Check( obj ) then
- with PPyClassObject(obj)^ do
- Result := PyString_AsDelphiString(cl_name)
- else if PyType_CheckExact( obj ) then
- Result := String(PPyTypeObject(obj).tp_name)
+ if PyType_CheckExact( obj ) then
+ Result := string(PPyTypeObject(obj).tp_name)
else
Result := PyObjectAsString(obj);
end;
@@ -5597,8 +4939,6 @@ procedure TPythonEngine.RaiseError;
raise Define( EPySystemError.Create(''), s_type, s_value )
else if (PyErr_GivenExceptionMatches(err_type, PyExc_MemoryError^) <> 0) then
raise Define( EPyMemoryError.Create(''), s_type, s_value )
- else if (not IsPython3000) and (PyErr_GivenExceptionMatches(err_type, PyExc_StandardError^) <> 0) then
- raise Define( EPyStandardError.Create(''), s_type, s_value )
else if (PyErr_GivenExceptionMatches(err_type, PyExc_UserWarning^) <> 0) then
raise Define( EPyUserWarning.Create(''), s_type, s_value )
else if (PyErr_GivenExceptionMatches(err_type, PyExc_DeprecationWarning^) <> 0) then
@@ -5623,35 +4963,26 @@ procedure TPythonEngine.RaiseError;
raise EPythonError.Create('RaiseError: couldn''t fetch last exception');
end;
-function TPythonEngine.PyObjectAsString( obj : PPyObject ) : String;
+function TPythonEngine.PyObjectAsString( obj : PPyObject ) : string;
+//differs from Python4Delphi- Alexey
var
- s : PPyObject;
-// i : Integer;
-// tmp : PAnsiChar;
- w : UnicodeString;
+ S : PPyObject;
begin
- CheckPython;
Result := '';
if not Assigned( obj ) then
Exit;
if PyUnicode_Check(obj) then
begin
- w := PyUnicode_AsWideString(obj);
- Result := w;
+ Result := PyUnicodeAsUTF8String(obj);
Exit;
end;
- s := PyObject_Str( obj );
- if Assigned(s) and PyString_Check(s) then
- begin
- Result := PyString_AsDelphiString(s);
-// tmp := PyString_AsString(s);
-// SetLength( Result, PyString_Size(s)+1 );
-// Result := '';
-// for i := 0 to PyString_Size(s) - 1 do
-// Insert( tmp[i], Result, i+1 );
- end;
- Py_XDECREF(s);
+ S := PyObject_Str( obj );
+ if Assigned(S) and PyUnicode_Check(S) then
+ begin
+ Result := PyUnicodeAsUTF8String(S);
+ end;
+ Py_XDECREF(S);
end;
procedure TPythonEngine.DoRedirectIO;
@@ -5667,6 +4998,8 @@ procedure TPythonEngine.DoRedirectIO;
' return self.pyio.read(size)'+LF+
' def flush(self):' + LF +
' pass' + LF +
+ ' def isatty(self):' + LF +
+ ' return False' + LF +
'sys.old_stdin=sys.stdin'+LF+
'sys.old_stdout=sys.stdout'+LF+
'sys.old_stderr=sys.stderr'+LF+
@@ -5710,7 +5043,7 @@ procedure TPythonEngine.RemoveClient( client : TEngineClient );
// is not predictable and may cause some memory crashes !
if (csDesigning in ComponentState) then
FClients.Remove( client )
- else if (Initialized) then begin
+ else if Initialized then begin
FClients.Remove( client );
if (ClientCount = 0) then
Finalize;
@@ -5731,6 +5064,27 @@ function TPythonEngine.FindClient( const aName : AnsiString ) : TEngineClient;
end;
end;
+function TPythonEngine.EncodeString(const str: UnicodeString): AnsiString; {$IFDEF FPC}overload;{$ENDIF}
+begin
+ Result := UTF8Encode(str)
+end;
+
+{$IFDEF FPC}
+function TPythonEngine.EncodeString (const str: AnsiString): AnsiString; overload;
+begin
+ Result := UTF8Encode(str);
+end;
+{$ENDIF}
+
+function TPythonEngine.EncodeWindowsFilePath(const str: string): AnsiString;
+{PEP 529}
+begin
+ if (MajorVersion > 3) or ((MajorVersion = 3) and (MinorVersion >=6) )then
+ Result := UTF8Encode(str)
+ else
+ Result := AnsiString(str);
+end;
+
function TPythonEngine.TypeByName( const aTypeName : AnsiString ) : PPyTypeObject;
var
i : Integer;
@@ -5847,13 +5201,9 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject;
y, m, d, h, mi, sec, ms, jd, wd : WORD;
dt : TDateTime;
dl : Integer;
- myInt : NativeInt;
wStr : UnicodeString;
- Disp : IDispatch;
- DispID : Integer;
args : PPyObject;
begin
- Disp := nil;
//Dereference Variant
DerefV := V;
while VarType(DeRefV) = varByRef or varVariant do
@@ -5872,7 +5222,7 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject;
varShortInt,
varWord,
varLongWord,
- varInteger: Result := PyInt_FromLong( DeRefV );
+ varInteger: Result := PyLong_FromLong( LongInt(DeRefV) );
varInt64: Result := PyLong_FromLongLong( DeRefV );
varSingle,
varDouble,
@@ -5886,7 +5236,7 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject;
begin
wd := (DayOfWeek( dt ) + 7 - 2) mod 7; // In Python, Monday is the first day (=0)
jd := Round(EncodeDate(y,m,d)-EncodeDate(y,1,1))+1; // This shoud be the Julian day, the day in a year (0-366)
- dl := -1; // This is daylight save... ??????? I don't know what it is...
+ dl := -1; // This is daylight save... ?Ξ?Ξ? I don't know what it is...
Result := ArrayToPyTuple( [y, m, d, h, mi, sec, wd, jd, dl] );
end
else if (DatetimeConversionMode = dcmToDatetime) then
@@ -5910,17 +5260,17 @@ function TPythonEngine.VariantAsPyObject( const V : Variant ) : PPyObject;
wStr := ''
else
wStr := DeRefV;
- Result := PyUnicode_FromWideChar( PWideChar(wStr), Length(wStr) );
+ Result := PyUnicodeFromString(wStr);
end;
varString:
begin
s := AnsiString(DeRefV);
- Result := PyString_FromStringAndSize(PAnsiChar(s), Length(s));
+ Result := PyBytes_FromStringAndSize(PAnsiChar(s), Length(s));
end;
varUString:
begin
- wStr := DeRefV;
- Result := PyUnicode_FromWideChar( PWideChar(wStr), Length(wStr) );
+ wStr := DeRefV;
+ Result := PyUnicodeFromString(wStr);
end;
else
if VarType(DeRefV) and varArray <> 0 then
@@ -5953,8 +5303,8 @@ function TPythonEngine.PyObjectAsVariant( obj : PPyObject ) : Variant;
begin
member := PyObject_GetAttrString( obj, PAnsiChar(AMember) );
CheckError(False);
- if PyInt_Check(member) then
- Result := PyInt_AsLong(member)
+ if PyLong_Check(member) then
+ Result := PyLong_AsLong(member)
else
raise EPythonError.CreateFmt('Unexpected type found in member %s of a time_struct object', [AMember]);
Py_XDecRef(member);
@@ -6024,17 +5374,17 @@ function TPythonEngine.PyObjectAsVariant( obj : PPyObject ) : Variant;
else if PyTuple_Check( obj ) and (PyTuple_Size(obj) = 9) then
begin
for i := 0 to 8 do
- if not PyInt_Check(PyTuple_GetItem(obj, i)) then
+ if not PyLong_Check(PyTuple_GetItem(obj, i)) then
Exit;
- y := PyInt_AsLong( PyTuple_GetItem(obj, 0) );
- m := PyInt_AsLong( PyTuple_GetItem(obj, 1) );
- d := PyInt_AsLong( PyTuple_GetItem(obj, 2) );
- h := PyInt_AsLong( PyTuple_GetItem(obj, 3) );
- mi := PyInt_AsLong( PyTuple_GetItem(obj, 4) );
- sec := PyInt_AsLong( PyTuple_GetItem(obj, 5) );
- wd := PyInt_AsLong( PyTuple_GetItem(obj, 6) );
- jd := PyInt_AsLong( PyTuple_GetItem(obj, 7) );
- dl := PyInt_AsLong( PyTuple_GetItem(obj, 8) );
+ y := PyLong_AsLong( PyTuple_GetItem(obj, 0) );
+ m := PyLong_AsLong( PyTuple_GetItem(obj, 1) );
+ d := PyLong_AsLong( PyTuple_GetItem(obj, 2) );
+ h := PyLong_AsLong( PyTuple_GetItem(obj, 3) );
+ mi := PyLong_AsLong( PyTuple_GetItem(obj, 4) );
+ sec := PyLong_AsLong( PyTuple_GetItem(obj, 5) );
+ wd := PyLong_AsLong( PyTuple_GetItem(obj, 6) );
+ jd := PyLong_AsLong( PyTuple_GetItem(obj, 7) );
+ dl := PyLong_AsLong( PyTuple_GetItem(obj, 8) );
if not (m in [1..12]) or
not (d in [1..31]) or
not (h in [0..23]) or
@@ -6075,13 +5425,10 @@ function TPythonEngine.PyObjectAsVariant( obj : PPyObject ) : Variant;
Result := PyObject_IsTrue(obj) = 1
else if PyLong_Check(obj) then
Result := PyLong_AsLongLong(obj)
- // changed the order of Long and int check (KV)
- else if PyInt_Check(obj) then
- Result := PyInt_AsLong(obj)
else if PyUnicode_Check(obj) then
- Result := PyUnicode_AsWideString(obj)
- else if PyString_Check(obj) then
- Result := PyObjectAsString(obj)
+ Result := PyUnicodeAsString(obj)
+ else if PyBytes_Check(obj) then
+ Result := AnsiString(PyBytes_AsString(obj))
else if ExtractDate( Result ) then
begin
// Nothing to do
@@ -6115,50 +5462,50 @@ function TPythonEngine.PyObjectAsVariant( obj : PPyObject ) : Variant;
function TPythonEngine.VarRecAsPyObject( v : TVarRec ) : PPyObject;
begin
case v.VType of
- vtInteger: Result := PyInt_FromLong( v.VInteger );
- vtBoolean: Result := PyInt_FromLong( Integer(v.VBoolean) );
- vtChar: Result := PyString_FromString( PAnsiChar(AnsiString(v.VChar)) );
+ vtInteger: Result := PyLong_FromLong( v.VInteger );
+ vtBoolean: Result := PyLong_FromLong( Integer(v.VBoolean) );
+ vtChar: Result := PyUnicodeFromString(AnsiString(v.VChar));
vtExtended: Result := PyFloat_FromDouble( v.VExtended^ );
vtString:
begin
if Assigned(v.VString) then
- Result := PyString_FromString(PAnsiChar(AnsiString(v.VString^)))
+ Result := PyUnicodeFromString(AnsiString(v.VString^))
else
- Result := PyString_FromString( '' );
+ Result := PyUnicodeFromString('');
end;
- vtPChar: Result := PyString_FromString( v.VPChar );
+ vtPChar: Result := PyUnicodeFromString(AnsiString(v.VPChar));
vtAnsiString:
begin
if Assigned(v.VAnsiString) then
- Result := PyString_FromString( v.VAnsiString )
+ Result := PyUnicodeFromString(PAnsiChar(v.VAnsiString))
else
- Result := PyString_FromString('');
+ Result := PyUnicodeFromString('');;
end;
vtCurrency: Result := PyFloat_FromDouble( v.VCurrency^ );
vtVariant: Result := VariantAsPyObject( v.VVariant^ );
vtPointer: Result := v.VPointer;
vtInt64: Result := PyLong_FromLongLong( v.VInt64^ );
- vtWideChar: Result := PyUnicode_FromWideString( v.VWideChar );
+ vtWideChar: Result := PyUnicodeFromString( v.VWideChar );
vtPWideChar:
begin
if Assigned(v.VPWideChar) then
- Result := PyUnicode_FromWideString( UnicodeString(v.VPWideChar) )
+ Result := PyUnicodeFromString( UnicodeString(v.VPWideChar) )
else
- Result := PyUnicode_FromWideString( '' );
+ Result := PyUnicodeFromString( '' );
end;
vtWideString:
begin
if Assigned(v.VWideString) then
- Result := PyUnicode_FromWideString( WideString(v.VWideString) )
+ Result := PyUnicodeFromString( WideString(v.VWideString) )
else
- Result := PyUnicode_FromWideString( '' );
+ Result := PyUnicodeFromString( '' );
end;
vtUnicodeString:
begin
if Assigned(v.VUnicodeString) then
- Result := PyUnicode_FromWideString( UnicodeString(v.VUnicodeString) )
+ Result := PyUnicodeFromString( UnicodeString(v.VUnicodeString) )
else
- Result := PyUnicode_FromWideString( '' );
+ Result := PyUnicodeFromString( '' );
end;
else
Raise Exception.Create('Argument type not allowed');
@@ -6313,7 +5660,7 @@ function TPythonEngine.StringsToPyList( strings : TStrings ) : PPyObject;
raise EPythonError.Create('Could not create a new list object');
for i := 0 to strings.Count - 1 do
PyList_SetItem( Result, i,
- PyString_FromString( PAnsiChar(AnsiString(strings.Strings[i])) ) );
+ PyUnicodeFromString( strings.Strings[i]) );
end;
function TPythonEngine.StringsToPyTuple( strings : TStrings ) : PPyObject;
@@ -6325,18 +5672,20 @@ function TPythonEngine.StringsToPyTuple( strings : TStrings ) : PPyObject;
raise EPythonError.Create('Could not create a new tuple object');
for i := 0 to strings.Count - 1 do
PyTuple_SetItem( Result, i,
- PyString_FromString( PAnsiChar(AnsiString(strings.Strings[i])) ) );
+ PyUnicodeFromString( strings.Strings[i]) );
end;
-procedure TPythonEngine.PyListToStrings( list : PPyObject; strings : TStrings );
+procedure TPythonEngine.PyListToStrings(list: PPyObject; Strings: TStrings;
+ ClearStrings: Boolean = True);
var
i : Integer;
begin
if not PyList_Check(list) then
raise EPythonError.Create('the python object is not a list');
- strings.Clear;
+ if ClearStrings then
+ Strings.Clear;
for i := 0 to PyList_Size( list ) - 1 do
- strings.Add( PyObjectAsString( PyList_GetItem( list, i ) ) );
+ Strings.Add( PyObjectAsString( PyList_GetItem( list, i ) ) );
end;
procedure TPythonEngine.PyTupleToStrings( tuple: PPyObject; strings : TStrings );
@@ -6350,48 +5699,69 @@ procedure TPythonEngine.PyTupleToStrings( tuple: PPyObject; strings : TStrings )
strings.Add( PyObjectAsString( PyTuple_GetItem( tuple, i ) ) );
end;
-function TPythonEngine.PyUnicode_AsWideString( obj : PPyObject ) : UnicodeString;
+function TPythonEngine.PyBytesAsAnsiString(obj: PPyObject): AnsiString;
var
- _size : Integer;
-{$IFDEF unix}
- _ucs4Str : UCS4String;
-{$ENDIF}
+ buffer: PAnsiChar;
+ size: NativeInt;
+begin
+ if PyBytes_Check(obj) then
+ begin
+ PyBytes_AsStringAndSize(obj, buffer, size);
+ SetString(Result, buffer, size);
+ end
+ else
+ raise EPythonError.CreateFmt(SPyConvertionError, ['PyBytesAsAnsiString', 'Bytes']);
+end;
+
+function TPythonEngine.PyUnicodeAsString(obj : PPyObject) : UnicodeString;
+var
+ Buffer: PAnsiChar;
+ Size: NativeInt;
+ NewSize: Cardinal;
begin
if PyUnicode_Check(obj) then
begin
- //_size := PySequence_Length(obj); //not fully correct for some Unicode
- _size := PyUnicode_GetSize(obj);
- if _size > 0 then
- begin
-{$IFDEF unix}
- // Note that Linux uses UCS4 strings, whereas it declares using UCS2 strings!!!
- SetLength(_ucs4Str, _size+1);
- if PyUnicode_AsWideChar(obj, @_ucs4Str[0], _size) <> _size then
- raise EPythonError.Create('Could not copy the whole Unicode string into its buffer');
- Result := UCS4StringToWideString(_ucs4Str);
- // remove trailing zeros (needed by Kylix1)
- while (Length(Result) > 0) and (Result[Length(Result)] = #0) do
- Delete(Result, Length(Result), 1);
-{$ELSE}
- SetLength(Result, _size);
- if PyUnicode_AsWideChar(obj, @Result[1], _size) <> _size then
- raise EPythonError.Create('Could not copy the whole Unicode string into its buffer');
-{$ENDIF}
- end
+ // Size does not include the final #0
+ Buffer := PyUnicode_AsUTF8AndSize(obj, @Size);
+ SetLength(Result, Size);
+ if (Size = 0) or (Buffer = nil) then
+ Exit;
+
+ // The second argument is the size of the destination (Result) including #0
+ NewSize := Utf8ToUnicode(PUnicodeChar(Result), Size + 1, Buffer, Size);
+ // NewSize includes #0
+ SetLength(Result, NewSize - 1);
+ end
+ else
+ raise EPythonError.CreateFmt(SPyConvertionError, ['PyUnicodeAsString', 'Unicode']);
+end;
+
+function TPythonEngine.PyUnicodeAsUTF8String( obj : PPyObject ) : RawByteString;
+var
+ buffer: PAnsiChar;
+ size: NativeInt;
+begin
+ if PyUnicode_Check(obj) then
+ begin
+ Result := '';
+ buffer := PyUnicode_AsUTF8AndSize(obj, @size);
+ if Assigned(buffer) then
+ SetString(Result, buffer, size)
else
Result := '';
+ SetCodePage(Result, CP_UTF8, False);
end
else
- raise EPythonError.Create('PyUnicode_AsWideString expects a Unicode Python object');
+ raise EPythonError.CreateFmt(SPyConvertionError, ['PyUnicodeAsUTF8String', 'Unicode']);
end;
-function TPythonEngine.PyUnicode_FromWideString( const AString : UnicodeString) : PPyObject;
-{$IFDEF unix}
+function TPythonEngine.PyUnicodeFromString(const AString : UnicodeString) : PPyObject;
+{$IFDEF POSIX}
var
_ucs4Str : UCS4String;
{$ENDIF}
begin
-{$IFDEF unix}
+{$IFDEF POSIX}
// Note that Linux uses UCS4 strings, whereas it declares using UCS2 strings!!!
_ucs4Str := WideStringToUCS4String(AString);
Result := PyUnicode_FromWideChar( {PWideChar}(@_ucs4Str[0]), Length(_ucs4Str)-1 {trim trailing zero});
@@ -6400,12 +5770,24 @@ function TPythonEngine.PyUnicode_FromWideString( const AString : UnicodeString)
{$ENDIF}
end;
+function TPythonEngine.ReturnFalse : PPyObject;
+begin
+ Result := Py_False;
+ Py_INCREF( Result );
+end;
+
function TPythonEngine.ReturnNone : PPyObject;
begin
Result := Py_None;
Py_INCREF( Result );
end;
+function TPythonEngine.ReturnTrue : PPyObject;
+begin
+ Result := Py_True;
+ Py_INCREF( Result );
+end;
+
function TPythonEngine.FindModule( const ModuleName : AnsiString ) : PPyObject;
var
modules, m : PPyObject;
@@ -6418,6 +5800,19 @@ function TPythonEngine.FindModule( const ModuleName : AnsiString ) : PPyObject;
Result := nil;
end;
+function TPythonEngine.FindPythonType(const TypeName: AnsiString): TPythonType;
+var
+ i : Integer;
+begin
+ Result := nil;
+ for i := 0 to ClientCount - 1 do
+ if (Clients[i] is TPythonType) and (TPythonType(Clients[i]).TypeName = TypeName) then
+ begin
+ Result := TPythonType(Clients[i]);
+ Break;
+ end;
+end;
+
function TPythonEngine.FindFunction(ModuleName,FuncName: AnsiString): PPyObject;
var
module,func: PPyObject;
@@ -6469,7 +5864,7 @@ function TPythonEngine.SetToList( data : Pointer; size : Integer ) : PPyObject;
for i := 0 to size*8-1 do
if GetBit(i) then
begin
- PyList_SetItem( Result, cpt, PyInt_FromLong(i) );
+ PyList_SetItem( Result, cpt, PyLong_FromLong(i) );
Inc(cpt);
end;
end;
@@ -6496,14 +5891,36 @@ procedure TPythonEngine.ListToSet( List : PPyObject; data : Pointer; size : Inte
end;
procedure TPythonEngine.CheckError(ACatchStopEx : Boolean = False);
+
+ procedure ProcessSystemExit;
+ var
+ errtype, errvalue, errtraceback: PPyObject;
+ SErrValue: string;
+ begin
+ // PyErr_Fetch clears the error. The returned python objects are new references
+ PyErr_Fetch(errtype, errvalue, errtraceback);
+ Traceback.Refresh(errtraceback);
+ SErrValue := PyObjectAsString(errvalue);
+ Py_XDECREF(errtype);
+ Py_XDECREF(errvalue);
+ Py_XDECREF(errtraceback);
+ raise EPySystemExit.CreateResFmt(@SPyExcSystemError, [SErrValue]);
+ end;
+
+var
+ PyException: PPyObject;
begin
- if PyErr_Occurred <> nil then
+ PyException := PyErr_Occurred;
+ if PyException <> nil then
begin
- if ACatchStopEx and (PyErr_GivenExceptionMatches(PyErr_Occurred, PyExc_StopIteration^) <> 0) then
+ if ACatchStopEx and (PyErr_GivenExceptionMatches(PyException, PyExc_StopIteration^) <> 0) then
begin
PyErr_Clear;
- raise EPyStopIteration.Create('Stop iteration');
+ raise EPyStopIteration.CreateRes(@SPyExcStopIteration);
end
+ else if PyErr_GivenExceptionMatches(PyException, PyExc_SystemExit^) <> 0 then
+ // Special treatment for SystemExit. Calling PyErr_Print would terminate the process
+ ProcessSystemExit
else
begin
PyErr_Print;
@@ -6518,7 +5935,7 @@ function TPythonEngine.GetMainModule : PPyObject;
Result := PyImport_AddModule(PAnsiChar(ExecModule));
end;
-function TPythonEngine.PyTimeStruct_Check( obj : PPyObject ) : Boolean;
+function TPythonEngine.PyTimeStruct_Check(obj : PPyObject) : Boolean;
begin
Result := Assigned(FTimeStruct) and (Pointer(obj^.ob_type) = FTimeStruct);
end;
@@ -6573,45 +5990,12 @@ function TPythonEngine.PyTZInfo_CheckExact( obj : PPyObject ) : Boolean;
Result := Assigned(FPyDateTime_DateType) and (Pointer(obj^.ob_type) = FPyDateTime_TZInfoType);
end;
-function TPythonEngine.PyString_AsDelphiString(ob: PPyObject): AnsiString;
-begin
- if PyUnicode_Check(ob) then
- Result := AnsiString(PyUnicode_AsWideString(ob))
- else
- Result := AnsiString(PyString_AsString(ob));
-end;
-
-function TPythonEngine.PyString_AsAnsiString( ob: PPyObject): AnsiString;
-begin
- if PyUnicode_Check(ob) then
- Result := AnsiString(PyUnicode_AsWideString(ob))
- else
- Result := AnsiString(PyString_AsString(ob));
-end;
-
-function TPythonEngine.PyString_AsWideString( ob: PPyObject): UnicodeString;
-begin
- if PyUnicode_Check(ob) then
- Result := PyUnicode_AsWideString(ob)
- else
- Result := UnicodeString(PyString_AsString(ob));
-end;
-
-function TPythonEngine.PyString_FromString( str: PAnsiChar): PPyObject;
-var
- _text : UnicodeString;
+function TPythonEngine.PyUnicodeFromString(const AString: AnsiString): PPyObject;
begin
- if IsPython3000 then
- begin
- _text := UnicodeString(str);
- Result := PyUnicode_FromWideString(_text);
- end
- else
- Result := DLL_PyString_FromString(str);
+ Result := PyUnicodeFromString(UnicodeString(AString));
end;
-
(*******************************************************)
(** **)
(** class TEngineClient **)
@@ -6651,6 +6035,10 @@ constructor TEngineClient.Create( AOwner : TComponent );
destructor TEngineClient.Destroy;
begin
+ // if the client is destroyed before the Python Engine then
+ // we need to finalize it. Otherwise it will already be finalized
+ if FInitialized then
+ Finalize;
Engine := nil; // This detaches the client from the Engine.
if Assigned( FOnDestroy ) then
FOnDestroy( Self );
@@ -6664,14 +6052,6 @@ procedure TEngineClient.Loaded;
FOnCreate( Self );
end;
-procedure TEngineClient.Notification( AComponent: TComponent; Operation: TOperation);
-begin
- inherited;
- if Operation = opRemove then
- if AComponent = FEngine then
- FEngine := nil;
-end;
-
procedure TEngineClient.Initialize;
begin
if FInitialized then
@@ -6909,12 +6289,26 @@ function TMethodsContainer.AddMethodWithKeywords( AMethodName : PAnsiChar;
Result^.ml_flags := Result^.ml_flags or METH_KEYWORDS;
end;
+function TMethodsContainer.AddStaticMethodWithKeywords(AMethodName: PAnsiChar;
+ AMethod: PyCFunctionWithKW; ADocString: PAnsiChar): PPyMethodDef;
+begin
+ Result := AddMethodWithKeywords(AMethodName, AMethod, ADocString);
+ Result^.ml_flags := Result^.ml_flags or METH_STATIC;
+end;
+
+function TMethodsContainer.AddClassMethodWithKeywords(AMethodName: PAnsiChar;
+ AMethod: PyCFunctionWithKW; ADocString: PAnsiChar): PPyMethodDef;
+begin
+ Result := AddMethodWithKeywords(AMethodName, AMethod, ADocString);
+ Result^.ml_flags := Result^.ml_flags or METH_CLASS;
+end;
+
function TMethodsContainer.AddDelphiMethod( AMethodName : PAnsiChar;
ADelphiMethod: TDelphiMethod;
ADocString : PAnsiChar ) : PPyMethodDef;
begin
Result := AddMethod( AMethodName,
- GetOfObjectCallBack( TCallBack(ADelphiMethod), 2, ctCDECL),
+ GetOfObjectCallBack( TCallBack(ADelphiMethod), 2, DEFAULT_CALLBACK_TYPE),
ADocString );
end;
@@ -6923,7 +6317,7 @@ function TMethodsContainer.AddDelphiMethodWithKeywords( AMethodName : PAnsiCh
ADocString : PAnsiChar ) : PPyMethodDef;
begin
Result := AddMethod( AMethodName,
- GetOfObjectCallBack( TCallBack(ADelphiMethod), 3, ctCDECL),
+ GetOfObjectCallBack( TCallBack(ADelphiMethod), 3, DEFAULT_CALLBACK_TYPE),
ADocString );
Result^.ml_flags := Result^.ml_flags or METH_KEYWORDS;
end;
@@ -7258,6 +6652,7 @@ procedure TError.Assign(Source: TPersistent);
begin
Name := TError(Source).Name;
Text := TError(Source).Text;
+ ErrorType := TError(Source).ErrorType;
Exit;
end;
inherited Assign(Source);
@@ -7302,7 +6697,7 @@ procedure TError.BuildError( const ModuleName : AnsiString );
with Owner.Owner.Engine do
begin
if ErrorType = etString then
- Error := PyString_FromString( PAnsiChar(Text) )
+ Error := PyUnicodeFromString(Text)
else if ErrorType = etClass then
begin
if FParentClass.Name <> '' then
@@ -7322,13 +6717,12 @@ procedure TError.RaiseError( const msg : AnsiString );
begin
Owner.Owner.CheckEngine;
with Owner.Owner.Engine do
- PyErr_SetString( Error, PAnsiChar(msg) );
+ PyErr_SetString(Error, PAnsiChar(EncodeString(msg)));
end;
procedure TError.RaiseErrorObj( const msg : AnsiString; obj : PPyObject );
var
args, res, str : PPyObject;
- inst : PPyInstanceObject;
i : Integer;
keys : PPyObject;
key : PPyObject;
@@ -7347,21 +6741,12 @@ procedure TError.RaiseErrorObj( const msg : AnsiString; obj : PPyObject );
Py_DECREF(args);
if not Assigned(res) then
raise Exception.CreateFmt('TError.RaiseErrorObj: Could not create an instance of "%s"', [Self.Name]);
- if PyInstance_Check( res ) then
- begin
- inst := PPyInstanceObject(res);
- Py_XDECREF( inst^.in_dict );
- inst^.in_dict := obj;
- str := PyString_FromString( PAnsiChar(msg) );
- PyDict_SetItemString( obj, 'args', str );
- Py_XDecRef(str);
- end
- else if PyObject_TypeCheck(res, PPyTypeObject(PyExc_Exception^)) then
+ if PyObject_TypeCheck(res, PPyTypeObject(PyExc_Exception^)) then
begin
args := PyTuple_New(1);
if not Assigned(args) then
raise Exception.Create('TError.RaiseErrorObj: Could not create an empty tuple');
- str := PyString_FromString( PAnsiChar(msg) );
+ str := PyUnicodeFromString(msg);
PyTuple_SetItem(args, 0, str);
res := PyEval_CallObjectWithKeywords(Error, args, nil);
Py_DECREF(args);
@@ -7383,7 +6768,8 @@ procedure TError.RaiseErrorObj( const msg : AnsiString; obj : PPyObject );
end
else
raise Exception.Create('TError.RaiseErrorObj: I didn''t get an instance' );
- PyErr_SetObject( Error, res );
+ PyErr_SetObject(Error, res);
+ Py_XDECREF(res);
end
else
PyErr_SetObject( Error, obj );
@@ -7510,7 +6896,7 @@ procedure TPythonModule.DefineDocString;
if DocString.Text <> '' then
begin
doc :=
- PyString_FromString(PChar(CleanString(FDocString.Text, False)));
+ PyUnicodeFromString(CleanString(FDocString.Text, False));
PyObject_SetAttrString( FModule, '__doc__', doc );
Py_XDecRef(doc);
CheckError(False);
@@ -7525,15 +6911,12 @@ procedure TPythonModule.MakeModule;
Exit;
with Engine do
begin
- if IsPython3000 then begin
- FillChar(FModuleDef, SizeOf(FModuleDef), 0);
- FModuleDef.m_base.ob_refcnt := 1;
- FModuleDef.m_name := PAnsiChar(ModuleName);
- FModuleDef.m_methods := MethodsData;
- FModuleDef.m_size := -1;
- FModule := Py_InitModule3000( ModuleDef );
- end else
- FModule := Py_InitModule( PAnsiChar(ModuleName), MethodsData );
+ FillChar(FModuleDef, SizeOf(FModuleDef), 0);
+ FModuleDef.m_base.ob_refcnt := 1;
+ FModuleDef.m_name := PAnsiChar(ModuleName);
+ FModuleDef.m_methods := MethodsData;
+ FModuleDef.m_size := -1;
+ FModule := Py_InitModule( ModuleDef );
DefineDocString;
end;
end;
@@ -7569,9 +6952,10 @@ procedure TPythonModule.InitializeForNewInterpreter;
end;
end;
-procedure TPythonModule.AddClient( client : TEngineClient );
+procedure TPythonModule.AddClient(Client : TEngineClient);
begin
- FClients.Add( client );
+ if FClients.IndexOf(Client) < 0 then
+ FClients.Add(Client);
end;
function TPythonModule.ErrorByName( const AName : AnsiString ) : TError;
@@ -7602,6 +6986,12 @@ procedure TPythonModule.RaiseErrorObj( const error, msg : AnsiString; obj : PPyO
ErrorByName( error ).RaiseErrorObj( msg, obj );
end;
+procedure TPythonModule.RemoveClient(Client: TEngineClient);
+begin
+ // Remove does not raise an exception if not found
+ FClients.Remove(Client);
+end;
+
procedure TPythonModule.BuildErrors;
var
i : Integer;
@@ -7689,11 +7079,12 @@ function TPythonModule.GetVarAsVariant( const varName : AnsiString ) : Variant;
with Engine do
begin
obj := GetVar( varName );
- try
- Result := PyObjectAsVariant( obj );
- finally
- Py_XDecRef(obj);
- end;
+ if Assigned(obj) then
+ try
+ Result := PyObjectAsVariant( obj );
+ finally
+ Py_XDecRef(obj);
+ end;
end;
end;
@@ -7722,7 +7113,8 @@ constructor TPyObject.Create( APythonType : TPythonType );
end;
end;
-constructor TPyObject.CreateWith( APythonType : TPythonType; args : PPyObject );
+constructor TPyObject.CreateWith(APythonType: TPythonType; args, kwds:
+ PPyObject);
begin
Create( APythonType );
end;
@@ -7816,7 +7208,7 @@ function TPyObject.GetAttr(key : PAnsiChar) : PPyObject;
begin
with GetPythonEngine do
begin
- PyKey := PyString_FromString(key);
+ PyKey := PyUnicodeFromString(key);
try
Result := PyObject_GenericGetAttr(GetSelf, PyKey)
finally
@@ -7831,15 +7223,15 @@ function TPyObject.SetAttr(key : PAnsiChar; value : PPyObject) : Integer;
begin
Result := -1;
PyErr_SetString (PyExc_AttributeError^,
- PAnsiChar(AnsiString(Format('Unknown attribute "%s"',[key]))));
+ PAnsiChar(EncodeString(Format('Unknown attribute "%s"',[key]))));
end;
end;
function TPyObject.Repr : PPyObject;
begin
- with GetPythonEngine do
- Result :=
- PyString_FromString( PAnsiChar(AnsiString(Format('<%s at %x>', [PythonType.TypeName, NativeInt(self)]))) );
+ Result :=
+ GetPythonEngine.PyUnicodeFromString( Format('<%s at %x>',
+ [PythonType.TypeName, NativeInt(self)]) );
end;
function TPyObject.Compare( obj: PPyObject) : Integer;
@@ -7935,11 +7327,6 @@ function TPyObject.NbMultiply( obj : PPyObject) : PPyObject;
Result := nil;
end;
-function TPyObject.NbDivide( obj : PPyObject) : PPyObject;
-begin
- Result := nil;
-end;
-
function TPyObject.NbFloorDivide( obj : PPyObject) : PPyObject;
begin
Result := nil;
@@ -7985,11 +7372,6 @@ function TPyObject.NbAbsolute : PPyObject;
Result := nil;
end;
-function TPyObject.NbNonZero : Integer;
-begin
- Result := -1;
-end;
-
function TPyObject.NbBool : Integer;
begin
Result := 0;
@@ -8025,36 +7407,16 @@ function TPyObject.NbOr( obj : PPyObject) : PPyObject;
Result := nil;
end;
-function TPyObject.NbCoerce( obj : PPPyObject) : Integer;
-begin
- Result := 0;
-end;
-
function TPyObject.NbInt : PPyObject;
begin
Result := nil;
end;
-function TPyObject.NbLong : PPyObject;
-begin
- Result := nil;
-end;
-
function TPyObject.NbFloat : PPyObject;
begin
Result := nil;
end;
-function TPyObject.NbOct : PPyObject;
-begin
- Result := nil;
-end;
-
-function TPyObject.NbHex : PPyObject;
-begin
- Result := nil;
-end;
-
function TPyObject.NbInplaceAdd(obj: PPyObject): PPyObject;
begin
Result := nil;
@@ -8146,21 +7508,11 @@ function TPyObject.SqItem( idx : NativeInt ) : PPyObject;
Result := GetPythonEngine.ReturnNone;
end;
-function TPyObject.SqSlice( idx1, idx2 : NativeInt ) : PPyObject;
-begin
- Result := GetPythonEngine.ReturnNone;
-end;
-
function TPyObject.SqAssItem( idx : NativeInt; obj : PPyObject) : Integer;
begin
Result := -1;
end;
-function TPyObject.SqAssSlice( idx1, idx2 : NativeInt; obj : PPyObject): integer;
-begin
- Result := -1;
-end;
-
function TPyObject.SqContains(obj: PPyObject): integer;
begin
Result := -1;
@@ -8218,7 +7570,7 @@ class procedure TPyObject.SetupType(APythonType: TPythonType);
constructor TTypeServices.Create;
begin
inherited;
- FBasic := [bsGetAttr, bsSetAttr, bsRepr, bsStr];
+ FBasic := [bsGetAttrO, bsSetAttrO, bsRepr, bsStr];
end;
procedure TTypeServices.AssignTo( Dest: TPersistent );
@@ -8294,13 +7646,21 @@ procedure TPythonType.SetModule( val : TPythonModule );
begin
if val <> FModule then
begin
+ if Assigned(FModule) then
+ begin
+ FModule.RemoveFreeNotification(Self);
+ FModule.RemoveClient(Self);
+ end;
FModule := val;
if Assigned(val) then
+ begin
+ val.FreeNotification(Self);
if Initialized and not (csLoading in ComponentState) then
if val.Initialized then
AddTypeVar
else
val.AddClient(Self);
+ end;
end;
end;
@@ -8323,9 +7683,9 @@ procedure TPythonType.SetTypeName( const val : AnsiString );
end;
end;
-function TPythonType.CreateMethod( pSelf, args : PPyObject ) : PPyObject;
+function TPythonType.CreateMethod(pSelf, args, kwds: PPyObject): PPyObject;
begin
- Result := CreateInstanceWith( args );
+ Result := CreateInstanceWith(args, kwds);
end;
procedure TPythonType.ReallocGetSets;
@@ -8350,32 +7710,22 @@ procedure TPythonType.ReallocMethods;
FType.tp_methods := MethodsData;
end;
+procedure TPythonType.SetBaseType(AType: TPythonType);
+begin
+ if AType = nil then
+ FType.tp_base := nil
+ else
+ FType.tp_base := @AType.FType;
+end;
+
procedure TPythonType.SetDocString( value : TStringList );
begin
FDocString.Assign( value );
end;
-function TPythonType.TypeFlagsAsInt : LongInt;
+function TPythonType.TypeFlagsAsInt : C_ULong;
begin
Result := 0;
- if tpfHaveGetCharBuffer in TypeFlags then
- Result := Result or Py_TPFLAGS_HAVE_GETCHARBUFFER;
- if tpfHaveSequenceIn in TypeFlags then
- Result := Result or Py_TPFLAGS_HAVE_SEQUENCE_IN;
- if tpfGC in TypeFlags then
- Result := Result or Py_TPFLAGS_GC;
- if tpfHaveInplaceOps in TypeFlags then
- Result := Result or Py_TPFLAGS_HAVE_INPLACEOPS;
- if tpfCheckTypes in TypeFlags then
- Result := Result or Py_TPFLAGS_CHECKTYPES;
- if tpfHaveRichCompare in TypeFlags then
- Result := Result or Py_TPFLAGS_HAVE_RICHCOMPARE;
- if tpfHaveWeakRefs in TypeFlags then
- Result := Result or Py_TPFLAGS_HAVE_WEAKREFS;
- if tpfHaveIter in TypeFlags then
- Result := Result or Py_TPFLAGS_HAVE_ITER;
- if tpfHaveClass in TypeFlags then
- Result := Result or Py_TPFLAGS_HAVE_CLASS;
if tpfHeapType in TypeFlags then
Result := Result or Py_TPFLAGS_HEAPTYPE;
if tpfBaseType in TypeFlags then
@@ -8386,6 +7736,28 @@ function TPythonType.TypeFlagsAsInt : LongInt;
Result := Result or Py_TPFLAGS_READYING;
if tpfHaveGC in TypeFlags then
Result := Result or Py_TPFLAGS_HAVE_GC;
+ if tpVectorCall in TypeFlags then
+ Result := Result or _Py_TPFLAGS_HAVE_VECTORCALL;
+ if tpMethodDescriptor in TypeFlags then
+ Result := Result or Py_TPFLAGS_METHOD_DESCRIPTOR;
+ if tpHaveVersionTag in TypeFlags then
+ Result := Result or Py_TPFLAGS_HAVE_VERSION_TAG;
+ if tpValidVersionTag in TypeFlags then
+ Result := Result or Py_TPFLAGS_VALID_VERSION_TAG;
+ if tpIsAbstract in TypeFlags then
+ Result := Result or Py_TPFLAGS_IS_ABSTRACT;
+ if tpLongSubclass in TypeFlags then
+ Result := Result or Py_TPFLAGS_LONG_SUBCLASS;
+ if tpListSubClass in TypeFlags then
+ Result := Result or Py_TPFLAGS_LIST_SUBCLASS;
+ if tpTupleSubclass in TypeFlags then
+ Result := Result or Py_TPFLAGS_TUPLE_SUBCLASS;
+ if tpBytesSubclass in TypeFlags then
+ Result := Result or Py_TPFLAGS_BYTES_SUBCLASS;
+ if tpBaseExcSubclass in TypeFlags then
+ Result := Result or Py_TPFLAGS_BASE_EXC_SUBCLASS;
+ if tpTypeSubclass in TypeFlags then
+ Result := Result or Py_TPFLAGS_TYPE_SUBCLASS;
end;
// Type services
@@ -8490,7 +7862,7 @@ function TPythonType.NewSubtypeInst( aType: PPyTypeObject; args, kwds : PPyObje
obj.ob_type := aType;
obj.IsSubtype := aType <> @FType;
obj.PythonAlloc := True;
- obj.CreateWith(Self, args);
+ obj.CreateWith(Self, args, kwds);
if Engine.PyErr_Occurred <> nil then
begin
Engine.Py_DECREF(Result);
@@ -8527,11 +7899,6 @@ function TPythonType_NbMultiply( pSelf, obj : PPyObject) : PPyObject; cdecl;
Result := PythonToDelphi(pSelf).NbMultiply( obj );
end;
-function TPythonType_NbDivide( pSelf, obj : PPyObject) : PPyObject; cdecl;
-begin
- Result := PythonToDelphi(pSelf).NbDivide( obj );
-end;
-
function TPythonType_NbFloorDivide( pSelf, obj : PPyObject) : PPyObject; cdecl;
begin
Result := PythonToDelphi(pSelf).NbFloorDivide( obj );
@@ -8577,11 +7944,6 @@ function TPythonType_NbAbsolute( pSelf : PPyObject ) : PPyObject; cdecl;
Result := PythonToDelphi(pSelf).NbAbsolute;
end;
-function TPythonType_NbNonZero( pSelf : PPyObject ) : Integer; cdecl;
-begin
- Result := PythonToDelphi(pSelf).NbNonZero;
-end;
-
function TPythonType_NbBool( pSelf : PPyObject ) : Integer; cdecl;
begin
Result := PythonToDelphi(pSelf).NbBool;
@@ -8617,36 +7979,16 @@ function TPythonType_NbOr( pSelf, obj : PPyObject) : PPyObject; cdecl;
Result := PythonToDelphi(pSelf).NbOr( obj );
end;
-function TPythonType_NbCoerce( pSelf, obj : PPPyObject) : Integer; cdecl;
-begin
- Result := PythonToDelphi(pSelf^).NbCoerce( obj );
-end;
-
function TPythonType_NbInt( pSelf : PPyObject ) : PPyObject; cdecl;
begin
Result := PythonToDelphi(pSelf).NbInt;
end;
-function TPythonType_NbLong( pSelf : PPyObject ) : PPyObject; cdecl;
-begin
- Result := PythonToDelphi(pSelf).NbLong;
-end;
-
function TPythonType_NbFloat( pSelf : PPyObject ) : PPyObject; cdecl;
begin
Result := PythonToDelphi(pSelf).NbFloat;
end;
-function TPythonType_NbOct( pSelf : PPyObject ) : PPyObject; cdecl;
-begin
- Result := PythonToDelphi(pSelf).NbOct;
-end;
-
-function TPythonType_NbHex( pSelf : PPyObject ) : PPyObject; cdecl;
-begin
- Result := PythonToDelphi(pSelf).NbHex;
-end;
-
function TPythonType_NbInplaceAdd(pSelf, obj: PPyObject): PPyObject; cdecl;
begin
Result := PythonToDelphi(pSelf).NbInplaceAdd( obj );
@@ -8739,22 +8081,11 @@ function TPythonType_SqItem( pSelf : PPyObject; idx : NativeInt ) : PPyObject;
Result := PythonToDelphi(pSelf).SqItem( idx );
end;
-function TPythonType_SqSlice( pSelf : PPyObject; idx1, idx2 : NativeInt ) : PPyObject; cdecl;
-begin
- Result := PythonToDelphi(pSelf).SqSlice( idx1, idx2 );
-end;
-
function TPythonType_SqAssItem( pSelf : PPyObject; idx : NativeInt; obj : PPyObject) : Integer; cdecl;
begin
Result := PythonToDelphi(pSelf).SqAssItem( idx, obj );
end;
-function TPythonType_SqAssSlice( pSelf : PPyObject; idx1, idx2 : NativeInt; obj : PPyObject): integer; cdecl;
-begin
- Result := PythonToDelphi(pSelf).SqAssSlice( idx1, idx2, obj );
-end;
-
-
// Mapping services
function TPythonType_MpLength( pSelf : PPyObject ) : NativeInt; cdecl;
@@ -8788,6 +8119,7 @@ function TPythonType_SqInplaceRepeat(pSelf : PPyObject; i: NativeInt): PPyObject
end;
procedure TPythonType.InitServices;
+{ Called from TPythonType.Initialize which first calls CheckEngine - FEngine is alread assigned }
begin
with FType do
begin
@@ -8807,8 +8139,6 @@ procedure TPythonType.InitServices;
tp_repr := TPythonType_Repr;
if bsStr in Services.Basic then
tp_str := TPythonType_Str;
- if bsCompare in Services.Basic then
- tp_compare := TPythonType_Compare;
if bsHash in Services.Basic then
tp_hash := TPythonType_Hash;
if bsGetAttrO in Services.Basic then
@@ -8831,127 +8161,70 @@ procedure TPythonType.InitServices;
begin
tp_init := TPythonType_InitSubtype;
tp_alloc := TPythonType_AllocSubtypeInst;
- tp_new := GetCallBack( Self, @TPythonType.NewSubtypeInst, 3, ctCDECL);
+ tp_new := GetCallBack( Self, @TPythonType.NewSubtypeInst, 3, DEFAULT_CALLBACK_TYPE);
tp_free := FreeSubtypeInst;
tp_methods := MethodsData;
tp_members := MembersData;
tp_getset := GetSetData;
end;
- // Number services
+ // Number services
if Services.Number <> [] then
begin
- if GetPythonEngine.IsPython3000 then
- begin
- FNumber := AllocMem(SizeOf(PyNumberMethods300)); // zeroes memory
- with PPyNumberMethods300(FNumber)^ do
- begin
- if nsAdd in Services.Number then nb_add := TPythonType_NbAdd; // #3.1
- if nsSubtract in Services.Number then nb_subtract := TPythonType_NbSubtract; // #3.2
- if nsMultiply in Services.Number then nb_multiply := TPythonType_NbMultiply; // #3.3
- if nsDivide in Services.Number then; // gone in Python 3.x
- if nsFloorDivide in Services.Number then nb_floor_divide := TPythonType_NbFloorDivide; // #3.30
- if nsTrueDivide in Services.Number then nb_true_divide := TPythonType_NbTrueDivide; // #3.31
- if (nsMatrixMultiply in Services.Number) and ((GetPythonEngine.MajorVersion > 3)
- or ((GetPythonEngine.MajorVersion = 3) and (GetPythonEngine.MinorVersion >= 5)))
- then
- nb_matrix_multiply := TPythonType_NbMatrixMultiply; // #3.35
- if nsRemainder in Services.Number then nb_remainder := TPythonType_NbRemainder; // #3.4
- if nsDivmod in Services.Number then nb_divmod := TPythonType_NbDivmod; // #3.5
- if nsPower in Services.Number then nb_power := TPythonType_NbPower; // #3.6
- if nsNegative in Services.Number then nb_negative := TPythonType_NbNegative; // #3.7
- if nsPositive in Services.Number then nb_positive := TPythonType_NbPositive; // #3.8
- if nsAbsolute in Services.Number then nb_absolute := TPythonType_NbAbsolute; // #3.9
- if nsNonZero in Services.Number then ; // gone in Python 3.x
- if nsBool in Services.Number then nb_bool := TPythonType_NbBool; // #3.10
- if nsInvert in Services.Number then nb_invert := TPythonType_NbInvert; // #3.11
- if nsLShift in Services.Number then nb_lshift := TPythonType_NbLShift; // #3.12
- if nsRShift in Services.Number then nb_rshift := TPythonType_NbRShift; // #3.13
- if nsAnd in Services.Number then nb_and := TPythonType_NbAnd; // #3.14
- if nsXor in Services.Number then nb_xor := TPythonType_NbXor; // #3.15
- if nsOr in Services.Number then nb_or := TPythonType_NbOr; // #3.16
- if nsCoerce in Services.Number then ;// gone in Python 3.x
- if nsInt in Services.Number then nb_int := TPythonType_NbInt; // #3.17
- if nsLong in Services.Number then ;// gone in Python 3.x, now nb_reserved
- if nsFloat in Services.Number then nb_float := TPythonType_NbFloat; // #3.19
- if nsOct in Services.Number then ;// gone in Python 3.x
- if nsHex in Services.Number then ;// gone in Python 3.x
- if nsInplaceAdd in Services.InplaceNumber then nb_inplace_add := TPythonType_NbInplaceAdd; // #3.20
- if nsInplaceSubtract in Services.InplaceNumber then nb_inplace_subtract := TPythonType_NbInplaceSubtract; // #3.21
- if nsInplaceMultiply in Services.InplaceNumber then nb_inplace_multiply := TPythonType_NbInplaceMultiply; // #3.22
- if nsInplaceDivide in Services.InplaceNumber then ;// gone in Python 3.x
- if nsInplaceFloorDivide in Services.InplaceNumber then nb_inplace_floor_divide := TPythonType_NbInplaceFloorDivide; // #3.32
- if nsInplaceTrueDivide in Services.InplaceNumber then nb_inplace_true_divide := TPythonType_NbInplaceTrueDivide; // #3.33
- if nsInplaceRemainder in Services.InplaceNumber then nb_inplace_remainder := TPythonType_NbInplaceRemainder; // #3.23
- if nsInplacePower in Services.InplaceNumber then nb_inplace_power := TPythonType_NbInplacePower; // #3.24
- if nsInplaceLShift in Services.InplaceNumber then nb_inplace_lshift := TPythonType_NbInplaceLShift; // #3.25
- if nsInplaceRShift in Services.InplaceNumber then nb_inplace_rshift := TPythonType_NbInplaceRShift; // #3.26
- if nsInplaceAnd in Services.InplaceNumber then nb_inplace_and := TPythonType_NbInplaceAnd; // #3.27
- if nsInplaceXor in Services.InplaceNumber then nb_inplace_xor := TPythonType_NbInplaceXor; // #3.28
- if nsInplaceOr in Services.InplaceNumber then nb_inplace_or := TPythonType_NbInplaceOr; // #3.29
- if (nsInplaceMatrixMultiply in Services.InplaceNumber) and
- ((GetPythonEngine.MajorVersion > 3) or ((GetPythonEngine.MajorVersion = 3)
- and (GetPythonEngine.MinorVersion >= 5)))
- then
- nb_inplace_matrix_multiply := TPythonType_NbInplaceMatrixMultiply; // #3.36
- end;
- end
- else
+ tp_as_number := @FNumber;
+
+ with FNumber do
begin
- FNumber := AllocMem(SizeOf(PyNumberMethods200));
- with PPyNumberMethods200(FNumber)^ do
- begin
- if nsAdd in Services.Number then nb_add := TPythonType_NbAdd; // #2.1
- if nsSubtract in Services.Number then nb_subtract := TPythonType_NbSubtract; // #2.2
- if nsMultiply in Services.Number then nb_multiply := TPythonType_NbMultiply; // #2.3
- if nsDivide in Services.Number then nb_divide := TPythonType_NbDivide; // #2.4
- if nsFloorDivide in Services.Number then nb_floor_divide := TPythonType_NbFloorDivide; // #2.35
- if nsTrueDivide in Services.Number then nb_true_divide := TPythonType_NbTrueDivide; // #2.36
- if nsMatrixMultiply in Services.Number then ;// new in Python 3.x
- if nsRemainder in Services.Number then nb_remainder := TPythonType_NbRemainder; // #2.5
- if nsDivmod in Services.Number then nb_divmod := TPythonType_NbDivmod; // #2.6
- if nsPower in Services.Number then nb_power := TPythonType_NbPower; // #2.7
- if nsNegative in Services.Number then nb_negative := TPythonType_NbNegative; // #2.8
- if nsPositive in Services.Number then nb_positive := TPythonType_NbPositive; // #2.9
- if nsAbsolute in Services.Number then nb_absolute := TPythonType_NbAbsolute; // #2.10
- if nsNonZero in Services.Number then nb_nonzero := TPythonType_NbNonZero; // #2.11
- if nsBool in Services.Number then // new in Python 3.x
- if nsInvert in Services.Number then nb_invert := TPythonType_NbInvert; // #2.12
- if nsLShift in Services.Number then nb_lshift := TPythonType_NbLShift; // #2.13
- if nsRShift in Services.Number then nb_rshift := TPythonType_NbRShift; // #2.14
- if nsAnd in Services.Number then nb_and := TPythonType_NbAnd; // #2.15
- if nsXor in Services.Number then nb_xor := TPythonType_NbXor; // #2.16
- if nsOr in Services.Number then nb_or := TPythonType_NbOr; // #2.17
- if nsCoerce in Services.Number then nb_coerce := TPythonType_NbCoerce; // #2.18
- if nsInt in Services.Number then nb_int := TPythonType_NbInt; // #2.19
- if nsLong in Services.Number then nb_long := TPythonType_NbLong; // #2.20
- if nsFloat in Services.Number then nb_float := TPythonType_NbFloat; // #2.21
- if nsOct in Services.Number then nb_oct := TPythonType_NbOct; // #2.22
- if nsHex in Services.Number then nb_hex := TPythonType_NbHex; // #2.23
- if nsInplaceAdd in Services.InplaceNumber then nb_inplace_add := TPythonType_NbInplaceAdd; // #2.24
- if nsInplaceSubtract in Services.InplaceNumber then nb_inplace_subtract := TPythonType_NbInplaceSubtract; // #2.25
- if nsInplaceMultiply in Services.InplaceNumber then nb_inplace_multiply := TPythonType_NbInplaceMultiply; // #2.26
- if nsInplaceDivide in Services.InplaceNumber then nb_inplace_divide := TPythonType_NbInplaceDivide; // #2.27
- if nsInplaceFloorDivide in Services.InplaceNumber then nb_inplace_floor_divide := TPythonType_NbInplaceFloorDivide; // #2.37
- if nsInplaceTrueDivide in Services.InplaceNumber then nb_inplace_true_divide := TPythonType_NbInplaceTrueDivide; // #2.38
- if nsInplaceRemainder in Services.InplaceNumber then nb_inplace_remainder := TPythonType_NbInplaceRemainder; // #2.28
- if nsInplacePower in Services.InplaceNumber then nb_inplace_power := TPythonType_NbInplacePower; // #2.29
- if nsInplaceLShift in Services.InplaceNumber then nb_inplace_lshift := TPythonType_NbInplaceLShift; // #2.30
- if nsInplaceRShift in Services.InplaceNumber then nb_inplace_rshift := TPythonType_NbInplaceRShift; // #2.31
- if nsInplaceAnd in Services.InplaceNumber then nb_inplace_and := TPythonType_NbInplaceAnd; // #2.32
- if nsInplaceXor in Services.InplaceNumber then nb_inplace_xor := TPythonType_NbInplaceXor; // #2.33
- if nsInplaceOr in Services.InplaceNumber then nb_inplace_or := TPythonType_NbInplaceOr; // #2.34
- if nsInplaceMatrixMultiply in Services.InplaceNumber then ; // new in Python 3.5
- end;
+ if nsAdd in Services.Number then nb_add := TPythonType_NbAdd; // #3.1
+ if nsSubtract in Services.Number then nb_subtract := TPythonType_NbSubtract; // #3.2
+ if nsMultiply in Services.Number then nb_multiply := TPythonType_NbMultiply; // #3.3
+ if nsFloorDivide in Services.Number then nb_floor_divide := TPythonType_NbFloorDivide; // #3.30
+ if nsTrueDivide in Services.Number then nb_true_divide := TPythonType_NbTrueDivide; // #3.31
+ if (nsMatrixMultiply in Services.Number) and ((FEngine.MajorVersion > 3)
+ or ((FEngine.MajorVersion = 3) and (FEngine.MinorVersion >= 5)))
+ then
+ nb_matrix_multiply := TPythonType_NbMatrixMultiply; // #3.35
+ if nsRemainder in Services.Number then nb_remainder := TPythonType_NbRemainder; // #3.4
+ if nsDivmod in Services.Number then nb_divmod := TPythonType_NbDivmod; // #3.5
+ if nsPower in Services.Number then nb_power := TPythonType_NbPower; // #3.6
+ if nsNegative in Services.Number then nb_negative := TPythonType_NbNegative; // #3.7
+ if nsPositive in Services.Number then nb_positive := TPythonType_NbPositive; // #3.8
+ if nsAbsolute in Services.Number then nb_absolute := TPythonType_NbAbsolute; // #3.9
+ if nsBool in Services.Number then nb_bool := TPythonType_NbBool; // #3.10
+ if nsInvert in Services.Number then nb_invert := TPythonType_NbInvert; // #3.11
+ if nsLShift in Services.Number then nb_lshift := TPythonType_NbLShift; // #3.12
+ if nsRShift in Services.Number then nb_rshift := TPythonType_NbRShift; // #3.13
+ if nsAnd in Services.Number then nb_and := TPythonType_NbAnd; // #3.14
+ if nsXor in Services.Number then nb_xor := TPythonType_NbXor; // #3.15
+ if nsOr in Services.Number then nb_or := TPythonType_NbOr; // #3.16
+ if nsInt in Services.Number then nb_int := TPythonType_NbInt; // #3.17
+ if nsFloat in Services.Number then nb_float := TPythonType_NbFloat; // #3.19
+ if nsInplaceAdd in Services.InplaceNumber then nb_inplace_add := TPythonType_NbInplaceAdd; // #3.20
+ if nsInplaceSubtract in Services.InplaceNumber then nb_inplace_subtract := TPythonType_NbInplaceSubtract; // #3.21
+ if nsInplaceMultiply in Services.InplaceNumber then nb_inplace_multiply := TPythonType_NbInplaceMultiply; // #3.22
+ if nsInplaceFloorDivide in Services.InplaceNumber then nb_inplace_floor_divide := TPythonType_NbInplaceFloorDivide; // #3.32
+ if nsInplaceTrueDivide in Services.InplaceNumber then nb_inplace_true_divide := TPythonType_NbInplaceTrueDivide; // #3.33
+ if nsInplaceRemainder in Services.InplaceNumber then nb_inplace_remainder := TPythonType_NbInplaceRemainder; // #3.23
+ if nsInplacePower in Services.InplaceNumber then nb_inplace_power := TPythonType_NbInplacePower; // #3.24
+ if nsInplaceLShift in Services.InplaceNumber then nb_inplace_lshift := TPythonType_NbInplaceLShift; // #3.25
+ if nsInplaceRShift in Services.InplaceNumber then nb_inplace_rshift := TPythonType_NbInplaceRShift; // #3.26
+ if nsInplaceAnd in Services.InplaceNumber then nb_inplace_and := TPythonType_NbInplaceAnd; // #3.27
+ if nsInplaceXor in Services.InplaceNumber then nb_inplace_xor := TPythonType_NbInplaceXor; // #3.28
+ if nsInplaceOr in Services.InplaceNumber then nb_inplace_or := TPythonType_NbInplaceOr; // #3.29
+ if (nsInplaceMatrixMultiply in Services.InplaceNumber) and
+ ((FEngine.MajorVersion > 3) or ((FEngine.MajorVersion = 3)
+ and (FEngine.MinorVersion >= 5)))
+ then
+ nb_inplace_matrix_multiply := TPythonType_NbInplaceMatrixMultiply; // #3.36
end;
- tp_as_number := FNumber;
end;
// Sequence services
if Services.Sequence <> [] then
+ begin
tp_as_sequence := @FSequence;
- with FSequence do
+ with FSequence do
begin
if ssLength in Services.Sequence then
sq_length := TPythonType_SqLength;
@@ -8961,12 +8234,8 @@ procedure TPythonType.InitServices;
sq_repeat := TPythonType_SqRepeat;
if ssItem in Services.Sequence then
sq_item := TPythonType_SqItem;
- if ssSlice in Services.Sequence then
- sq_slice := TPythonType_SqSlice;
if ssAssItem in Services.Sequence then
sq_ass_item := TPythonType_SqAssItem;
- if ssAssSlice in Services.Sequence then
- sq_ass_slice := TPythonType_SqAssSlice;
if ssContains in Services.Sequence then
sq_contains := TPythonType_SqContains;
if ssInplaceConcat in Services.Sequence then
@@ -8974,12 +8243,14 @@ procedure TPythonType.InitServices;
if ssInplaceRepeat in Services.Sequence then
sq_inplace_repeat := TPythonType_SqInplaceRepeat;
end;
+ end;
// Mapping services
if Services.Mapping <> [] then
+ begin
tp_as_mapping := @FMapping;
- with FMapping do
+ with FMapping do
begin
if msLength in Services.Mapping then
mp_length := TPythonType_MpLength;
@@ -8988,6 +8259,7 @@ procedure TPythonType.InitServices;
if msAssSubscript in Services.Mapping then
mp_ass_subscript := TPythonType_MpAssSubscript;
end;
+ end;
end;
end;
@@ -9007,9 +8279,9 @@ destructor TPythonType.Destroy;
begin
if gVarType = Self then
gVarType := nil;
+ Module := nil;
FDocString.Free;
FServices.Free;
- FreeMem(FNumber);
inherited;
end;
@@ -9041,7 +8313,8 @@ procedure TPythonType.Initialize;
procedure TPythonType.Finalize;
begin
- Engine.Py_XDECREF(FCreateFunc);
+ if Assigned(Engine) then
+ Engine.Py_CLEAR(FCreateFunc);
FCreateFunc := nil;
inherited;
end;
@@ -9065,14 +8338,14 @@ function TPythonType.CreateInstance : PPyObject;
end;
end;
-function TPythonType.CreateInstanceWith( args : PPyObject ) : PPyObject;
+function TPythonType.CreateInstanceWith(args, kwds: PPyObject): PPyObject;
var
obj : TPyObject;
begin
CheckEngine;
with Engine do
begin
- obj := PyObjectClass.CreateWith( Self, args );
+ obj := PyObjectClass.CreateWith(Self, args, kwds);
obj.ob_type := @FType;
if PyErr_Occurred <> nil then
begin
@@ -9087,7 +8360,7 @@ function TPythonType.CreateInstanceWith( args : PPyObject ) : PPyObject;
procedure TPythonType.AddTypeVar;
var
d : PPyObject;
- meth : TDelphiMethod;
+ meth : TDelphiMethodWithKW;
begin
CheckEngine;
Assert(Module <> nil);
@@ -9100,13 +8373,11 @@ procedure TPythonType.AddTypeVar;
begin
meth := CreateMethod;
FCreateFuncDef.ml_name := PAnsiChar(FCreateFuncName);
- FCreateFuncDef.ml_meth := GetOfObjectCallBack( TCallBack(meth), 2, ctCDECL);
- FCreateFuncDef.ml_flags := METH_VARARGS;
+ FCreateFuncDef.ml_meth := GetOfObjectCallBack(TCallBack(meth), 3, DEFAULT_CALLBACK_TYPE);
+ FCreateFuncDef.ml_flags := METH_KEYWORDS;
FCreateFuncDef.ml_doc := PAnsiChar(FCreateFuncDoc);
- if GetPythonEngine.IsPython3000 then
- FCreateFunc := Engine.PyCFunction_NewEx(@FCreateFuncDef, nil, nil)
- else
- FCreateFunc := Engine.PyCFunction_New(@FCreateFuncDef, nil);
+ FCreateFunc := Engine.PyCFunction_NewEx(@FCreateFuncDef, nil, nil);
+ Engine.Py_INCREF(FCreateFunc);
end;
Assert(Assigned(FCreateFunc));
end;
@@ -9342,7 +8613,7 @@ constructor TPyVar.Create( APythonType : TPythonType );
// the Create constructor first, and because the constructors
// are virtual, TPyVar.Create will be automatically be called.
-constructor TPyVar.CreateWith( APythonType : TPythonType; args : PPyObject );
+constructor TPyVar.CreateWith(APythonType: TPythonType; args, kwds: PPyObject);
begin
inherited;
with GetPythonEngine do
@@ -9367,26 +8638,26 @@ destructor TPyVar.Destroy;
// Then we override the needed services
-function TPyVar.GetAttr(key : PAnsiChar) : PPyObject;
+function TPyVar.GetAttrO( key: PPyObject) : PPyObject;
begin
with GetPythonEngine do
begin
- if CompareText( AnsiString(key), 'Value') = 0 then
+ if CompareText( PyObjectAsString(key), 'Value') = 0 then
Result := GetValue
else
- Result := inherited GetAttr(key);
+ Result := inherited GetAttrO(key);
end;
end;
-function TPyVar.SetAttr(key : PAnsiChar; value : PPyObject) : Integer;
+function TPyVar.SetAttrO( key, value: PPyObject) : Integer;
begin
Result := 0;
with GetPythonEngine do
begin
- if CompareText( AnsiString(key), 'Value' ) = 0 then
+ if CompareText( PyObjectAsString(key), 'Value' ) = 0 then
SetValue( value )
else
- Result := inherited SetAttr(key, value);
+ Result := inherited SetAttrO(key, value);
end;
end;
@@ -9399,8 +8670,8 @@ function TPyVar.Repr : PPyObject;
obj := GetValue;
try
Result :=
- PyString_FromString( PAnsiChar(AnsiString(Format('<%s: %s>',
- [PythonType.TypeName, PyObjectAsString(obj)]))) );
+ PyUnicodeFromString(Format('<%s: %s>',
+ [PythonType.TypeName, PyObjectAsString(obj)]) );
finally
Py_XDecRef(obj);
end;
@@ -9513,29 +8784,22 @@ procedure TPyVar.SetValueFromVariant( const value : Variant );
procedure TPythonThread.Execute;
var
- withinterp: Boolean;
global_state : PPyThreadState;
gilstate : PyGILState_STATE;
begin
- withinterp := Assigned( fInterpreterState);
with GetPythonEngine do
begin
- if withinterp then
+ if fThreadExecMode = emNewState then
begin
- fThreadExecMode := emNewState;
- fThreadState := PyThreadState_New( fInterpreterState);
- if Assigned(fThreadState) then
- begin
- PyEval_AcquireThread(fThreadState);
+ gilstate := PyGILState_Ensure();
+ try
+ fThreadState := GetThreadState;
ExecuteWithPython;
- PyEval_ReleaseThread( fThreadState);
- PyThreadState_Clear( fThreadState);
- PyThreadState_Delete( fThreadState);
- end else
- raise EPythonError.Create( 'Could not create a new thread state');
- end else {withinterp}
+ finally
+ PyGILState_Release(gilstate);
+ end;
+ end else {fThreadExecMode}
begin
- fThreadExecMode := emNewInterpreter;
gilstate := PyGILState_Ensure();
global_state := PyThreadState_Get;
PyThreadState_Swap(nil);
@@ -9555,24 +8819,24 @@ procedure TPythonThread.Execute;
end;
-procedure TPythonThread.Py_Begin_Allow_Threads;
+class procedure TPythonThread.Py_Begin_Allow_Threads;
begin
with GetPythonEngine do
f_savethreadstate := PyEval_SaveThread;
end;
-procedure TPythonThread.Py_End_Allow_Threads;
+class procedure TPythonThread.Py_End_Allow_Threads;
begin
with GetPythonEngine do
PyEval_RestoreThread( f_savethreadstate);
end;
-procedure TPythonThread.Py_Begin_Block_Threads;
+class procedure TPythonThread.Py_Begin_Block_Threads;
begin
Py_End_Allow_Threads;
end;
-procedure TPythonThread.Py_Begin_Unblock_Threads;
+class procedure TPythonThread.Py_Begin_Unblock_Threads;
begin
Py_Begin_Allow_Threads;
end;
@@ -9597,7 +8861,7 @@ function pyio_write(self, args : PPyObject) : PPyObject;
if GetCurrentThreadId <> MainThreadId then
with GetPythonEngine do
begin
- if RedirectIO and (IO <> nil) and (IO.ClassName <> 'TPythonInputOutput') then
+ if RedirectIO and (IO <> nil) and (IO.ClassName <> 'TPythonInputOutput') and not IO.DelayWrites then
begin
Result := GetPythonEngine.ReturnNone;
Exit;
@@ -9612,10 +8876,9 @@ function pyio_write(self, args : PPyObject) : PPyObject;
if RedirectIO and (IO <> nil) and Assigned(a1) then
begin
if PyUnicode_Check(a1) then
- IO.Write(PyUnicode_AsWideString(a1))
+ IO.Write(PyUnicodeAsString(a1))
else
- if PyString_Check(a1) then
- IO.Write(PyObjectAsString(a1));
+ IO.Write(IOString(PyObjectAsString(a1)));
end;
Result := ReturnNone;
end
@@ -9640,23 +8903,19 @@ function pyio_read(self, args : PPyObject) : PPyObject;
if Assigned(IO) then
if IO.UnicodeIO then begin
Widetxt := IO.ReceiveUniData;
- // KV!!!!!!
if PyErr_Occurred <> nil then
Result := nil
else
- // KV!!!!!!
- Result := PyUnicode_FromWideString(PWideChar(Widetxt));
+ Result := PyUnicodeFromString(PWideChar(Widetxt));
end else begin
txt := IO.ReceiveData;
- // KV!!!!!!
if PyErr_Occurred <> nil then
Result := nil
else
- // KV!!!!!!
- Result := PyString_FromString(PAnsiChar(txt));
+ Result := PyUnicodeFromString(txt);
end
else
- Result := PyString_FromString(PAnsiChar(txt));
+ Result := PyUnicodeFromString(txt);
end
else
Result := ReturnNone;
@@ -9710,29 +8969,13 @@ function pyio_GetTypesStats(self, args : PPyObject) : PPyObject;
with GetPythonEngine do
begin
Result := PyTuple_New(4);
- PyTuple_SetItem( Result, 0, PyString_FromString(PAnsiChar(T.TypeName)) );
- PyTuple_SetItem( Result, 1, PyInt_FromLong(T.InstanceCount) );
- PyTuple_SetItem( Result, 2, PyInt_FromLong(T.CreateHits) );
- PyTuple_SetItem( Result, 3, PyInt_FromLong(T.DeleteHits) );
+ PyTuple_SetItem( Result, 0, PyUnicodeFromString(T.TypeName));
+ PyTuple_SetItem( Result, 1, PyLong_FromLong(T.InstanceCount) );
+ PyTuple_SetItem( Result, 2, PyLong_FromLong(T.CreateHits) );
+ PyTuple_SetItem( Result, 3, PyLong_FromLong(T.DeleteHits) );
end;
end;
- function FindType( const TName : AnsiString ) : TPythonType;
- var
- i : Integer;
- begin
- Result := nil;
- with GetPythonEngine do
- for i := 0 to ClientCount - 1 do
- if Clients[i] is TPythonType then
- with TPythonType(Clients[i]) do
- if TypeName = TName then
- begin
- Result := TPythonType(Clients[i]);
- Break;
- end;
- end;
-
var
i : Integer;
T : TPythonType;
@@ -9746,7 +8989,7 @@ function pyio_GetTypesStats(self, args : PPyObject) : PPyObject;
for i := 0 to PyTuple_Size(args)-1 do
begin
str := AnsiString(PyObjectAsString( PyTuple_GetItem(args, i) ));
- T := FindType( str );
+ T := FindPythonType( str );
if Assigned(T) then
begin
obj := HandleType( T );
@@ -9766,9 +9009,6 @@ function pyio_GetTypesStats(self, args : PPyObject) : PPyObject;
end;
-
-
-
(*******************************************************)
(** **)
(** Global procedures **)
@@ -9779,9 +9019,8 @@ function GetPythonEngine : TPythonEngine;
begin
if not Assigned( gPythonEngine ) then
raise Exception.Create( 'No Python engine was created' );
- if not gPythonEngine.Finalizing then
- if not gPythonEngine.Initialized then
- raise Exception.Create( 'The Python engine is not properly initialized' );
+ if not gPythonEngine.Finalizing and not gPythonEngine.Initialized then
+ raise Exception.Create( 'The Python engine is not properly initialized' );
Result := gPythonEngine;
end;
@@ -9820,6 +9059,14 @@ procedure Register;
TPythonType, TPythonModule, TPythonDelphiVar]);
end;
+function SysVersionFromDLLName(const DLLFileName : string): string;
+var
+ Minor, Major: integer;
+begin
+ PythonVersionFromDLLName(DLLFileName, Major, Minor);
+ Result := Format('%d.%d', [Major, Minor]);
+end;
+
function PyType_HasFeature(AType : PPyTypeObject; AFlag : Integer) : Boolean;
begin
//(((t)->tp_flags & (f)) != 0)
@@ -9845,28 +9092,10 @@ procedure MaskFPUExceptions(ExceptionsMasked : boolean;
{$endif}
end;
-(*
-function CleanString(const s : AnsiString; AppendLF : Boolean) : AnsiString;
-var
- i : Integer;
-begin
- result := s;
- if s = '' then
- Exit;
- i := Pos(AnsiString(CR),s);
- while i > 0 do
- begin
- Delete( result, i, 1 );
- i := PosEx(AnsiString(CR),result, i);
- end;
- if AppendLF and (result[length(result)] <> LF) then
- Result := Result + LF;
-end;
-*)
-
function CleanString(const s : AnsiString; AppendLF : Boolean) : AnsiString;
begin
Result := AdjustLineBreaks(s, tlbsLF);
+ if Result = '' then Exit;
if AppendLF and (result[length(result)] <> LF) then
Result := Result + LF;
end;
@@ -9917,5 +9146,55 @@ function IsPythonVersionRegistered(PythonVersion : AnsiString;
end;
{$ENDIF}
+procedure PythonVersionFromDLLName(LibName: string; out MajorVersion, MinorVersion: integer);
+//Windows: 'c:\some\path\python310.dll'
+//Linux: '/some/path/libpython3.10m.so'
+const
+ cPython = 'python';
+ DefaultMajor = 3;
+ DefaultMinor = 4;
+var
+ NPos: integer;
+ ch: char;
+begin
+ MajorVersion:= DefaultMajor;
+ MinorVersion:= DefaultMinor;
+ LibName:= LowerCase(ExtractFileName(LibName)); //strip path
+ NPos:= Pos(cPython, LibName);
+ if NPos=0 then exit;
+ Inc(NPos, Length(cPython));
+ if NPos>Length(LibName) then exit;
+ ch:= LibName[NPos];
+ case ch of
+ '2'..'5': //support major versions 2...5
+ MajorVersion:= StrToIntDef(ch, DefaultMajor);
+ else
+ exit;
+ end;
+ Delete(LibName, 1, NPos);
+ if LibName='' then exit;
+ case LibName[1] of
+ '.': //Unix name with dot
+ Delete(LibName, 1, 1);
+ '0'..'9': //Windows name w/o dot
+ begin end;
+ else //unknown char after major version
+ exit;
+ end;
+ //strip file extension and handle 'libpython3.10m.so'
+ for NPos:= 1 to Length(LibName) do
+ begin
+ case LibName[NPos] of
+ '.', 'a'..'z':
+ begin
+ SetLength(LibName, NPos-1);
+ Break
+ end;
+ end;
+ end;
+ //the rest is minor version number '0'...'999'
+ MinorVersion:= StrToIntDef(LibName, DefaultMinor);
+end;
+
end.
diff --git a/python4lazarus/PythonGUIInputOutput.pas b/python4lazarus/PythonGUIInputOutput.pas
index f8f79e6..83d80f4 100644
--- a/python4lazarus/PythonGUIInputOutput.pas
+++ b/python4lazarus/PythonGUIInputOutput.pas
@@ -182,9 +182,18 @@ procedure TPythonGUIInputOutput.WriteOutput;
begin
if FQueue.Count = 0 then
Exit;
- S := FQueue.Strings[ 0 ];
- FQueue.Delete(0);
- DisplayString( S )
+
+ Lock;
+ try
+ while FQueue.Count > 0 do
+ begin
+ S := FQueue.Strings[ 0 ];
+ FQueue.Delete(0);
+ DisplayString( S );
+ end;
+ finally
+ Unlock;
+ end;
end;
{PUBLIC METHODS}
diff --git a/python4lazarus/PythonVersions.pas b/python4lazarus/PythonVersions.pas
index f5d60ff..6b746de 100644
--- a/python4lazarus/PythonVersions.pas
+++ b/python4lazarus/PythonVersions.pas
@@ -1,7 +1,6 @@
{-----------------------------------------------------------------------------
Unit Name: PythonVersions
- Author: Kiriakos
- Date: PyScripter
+ Author: PyScripter
Purpose: Discover and get info about Python versions
Part of the Python for Delphi library
@@ -57,8 +56,7 @@ TPythonVersion = record
The function result has the semantics of Delphi compare functions
-1: A is bigger (newer), 0: equal versions, 1: B is bigger (newer)
*)
- function CompareVersions(A, B : string) : Integer;
-
+ function CompareVersions(A, B : string) : Integer;
{$IFDEF MSWINDOWS}
(* Checks whether an executable was compiled for X64 *)
@@ -69,11 +67,14 @@ TPythonVersion = record
function GetRegisteredPythonVersion(SysVersion: string;
out PythonVersion: TPythonVersion): Boolean;
(* Returns all registered Python versions *)
- function GetRegisteredPythonVersions : TPythonVersions;
+ function GetRegisteredPythonVersions(const MinVersion: string = '0.0';
+ const MaxVersion: string = '100.100'): TPythonVersions;
(* Returns the highest numbered registered Python version *)
- function GetLatestRegisteredPythonVersion(out PythonVersion: TPythonVersion): Boolean;
+ function GetLatestRegisteredPythonVersion(out PythonVersion: TPythonVersion;
+ const MinVersion: string = '0.0'; const MaxVersion: string = '100.100'): Boolean;
function PythonVersionFromPath(const Path: string; out PythonVersion: TPythonVersion;
- AcceptVirtualEnvs: Boolean = True): Boolean;
+ AcceptVirtualEnvs: Boolean = True; const MinVersion: string = '0.0';
+ const MaxVersion: string = '100.100'): Boolean;
{$ENDIF}
implementation
@@ -92,7 +93,9 @@ implementation
function TPythonVersion.GetDLLName: string;
begin
{$IFDEF MSWINDOWS}
- Result := 'python' + SysVersion[1] + SysVersion[3] + '.dll';
+ Result := SysVersion;
+ Delete(Result, 2, 1);
+ Result := 'python' + Result + '.dll';
{$ELSE}
Result := 'libpython' + SysVersion + '.so';
{$ENDIF}
@@ -101,13 +104,7 @@ function TPythonVersion.GetDLLName: string;
function TPythonVersion.ExpectedArchitecture: string;
begin
Result := '';
- {$IFDEF CPUX64}
- Result := '64bit';
- {$ENDIF}
- {$IFDEF CPU64}
- Result := '64bit';
- {$ENDIF}
- {$IFDEF CPU64bits}
+ {$IF Defined(CPUX64) or Defined(CPU64) or Defined(CPU64bits)}
Result := '64bit';
{$ENDIF}
if Result = '' then
@@ -169,17 +166,24 @@ function TPythonVersion.GetDisplayName: string;
function TPythonVersion.GetHelpFile: string;
var
PythonHelpFilePath: string;
+ HtmlIndex: string;
Res: Integer;
SR: TSearchRec;
begin
Result := FHelpFile;
- // for unregistered Python
- if (Result = '') and (InstallPath <> '') then
+ // for unregistered Python or python 11
+ if ((Result = '') or (ExtractFileExt(Result) = '.html')) and (InstallPath <> '') then
begin
- PythonHelpFilePath := InstallPath + '\Doc\python*.chm';
+ PythonHelpFilePath := IncludeTrailingPathDelimiter(InstallPath) + 'Doc\python*.chm';
Res := FindFirst(PythonHelpFilePath, faAnyFile, SR);
if Res = 0 then
- Result := InstallPath + '\Doc\' + SR.Name;
+ Result := IncludeTrailingPathDelimiter(InstallPath) + 'Doc\' + SR.Name
+ else if Result = '' then
+ begin
+ HtmlIndex := IncludeTrailingPathDelimiter(InstallPath) + 'Doc\html\index.html';
+ if FileExists(HtmlIndex) then
+ Result := HtmlIndex;
+ end;
FindClose(SR);
end;
end;
@@ -400,7 +404,8 @@ function GetRegisteredPythonVersion(SysVersion: string;
PythonVersion.IsRegistered := Result;
end;
-function GetRegisteredPythonVersions : TPythonVersions;
+function GetRegisteredPythonVersions(const MinVersion: string = '0.0';
+ const MaxVersion: string = '100.100'): TPythonVersions;
Var
Count: Integer;
I: Integer;
@@ -409,27 +414,40 @@ function GetRegisteredPythonVersions : TPythonVersions;
Count := 0;
SetLength(Result, High(PYTHON_KNOWN_VERSIONS));
for I := High(PYTHON_KNOWN_VERSIONS) downto 1 do
+ begin
+ if CompareVersions(PYTHON_KNOWN_VERSIONS[I].RegVersion, MaxVersion) < 0 then
+ continue;
+ if CompareVersions(PYTHON_KNOWN_VERSIONS[I].RegVersion, MinVersion) > 0 then
+ break;
if GetRegisteredPythonVersion(PYTHON_KNOWN_VERSIONS[I].RegVersion, PythonVersion) then
begin
Result[Count] := PythonVersion;
Inc(Count);
end;
+ end;
SetLength(Result, Count);
end;
-function GetLatestRegisteredPythonVersion(out PythonVersion: TPythonVersion): Boolean;
+function GetLatestRegisteredPythonVersion(out PythonVersion: TPythonVersion;
+ const MinVersion: string = '0.0'; const MaxVersion: string = '100.100'): Boolean;
Var
I: Integer;
begin
+ Result := False;
for I := High(PYTHON_KNOWN_VERSIONS) downto 1 do
begin
- Result := GetRegisteredPythonVersion(PYTHON_KNOWN_VERSIONS[I].RegVersion, PythonVersion);
- if Result then break;
+ if CompareVersions(PYTHON_KNOWN_VERSIONS[I].RegVersion, MaxVersion) < 0 then
+ continue;
+ if CompareVersions(PYTHON_KNOWN_VERSIONS[I].RegVersion, MinVersion) > 0 then
+ break;
+ if GetRegisteredPythonVersion(PYTHON_KNOWN_VERSIONS[I].RegVersion, PythonVersion) then
+ Exit(True);
end;
end;
function PythonVersionFromPath(const Path: string; out PythonVersion: TPythonVersion;
- AcceptVirtualEnvs: Boolean = True): Boolean;
+ AcceptVirtualEnvs: Boolean = True; const MinVersion: string = '0.0';
+ const MaxVersion: string = '100.100'): Boolean;
function FindPythonDLL(APath : string): string;
Var
@@ -438,15 +456,15 @@ function PythonVersionFromPath(const Path: string; out PythonVersion: TPythonVer
DLLFileName: string;
begin
Result := '';
- Handle := FindFirstFile(PWideChar(APath+'\python??.dll'), FindFileData);
+ Handle := FindFirstFile(PWideChar(APath+'\python*.dll'), FindFileData);
if Handle = INVALID_HANDLE_VALUE then Exit; // not python dll
DLLFileName:= FindFileData.cFileName;
// skip if python3.dll was found
- if Length(DLLFileName) <> 12 then FindNextFile(Handle, FindFileData);
+ if Length(DLLFileName) <= 11 then FindNextFile(Handle, FindFileData);
if Handle = INVALID_HANDLE_VALUE then Exit;
Windows.FindClose(Handle);
DLLFileName:= FindFileData.cFileName;
- if Length(DLLFileName) = 12 then
+ if Length(DLLFileName) > 11 then
Result := DLLFileName;
end;
@@ -506,16 +524,20 @@ function PythonVersionFromPath(const Path: string; out PythonVersion: TPythonVer
end;
PythonVersion.DLLPath := DLLPath;
- SysVersion := GetPythonVersionFromDLLName(DLLFileName);
+ SysVersion := SysVersionFromDLLName(DLLFileName);
PythonVersion.SysVersion := SysVersion;
PythonVersion.fSysArchitecture := PythonVersion.ExpectedArchitecture;
- for I := High(PYTHON_KNOWN_VERSIONS) downto 1 do
- if PYTHON_KNOWN_VERSIONS[I].RegVersion = SysVersion then begin
- Result := True;
- break;
- end;
+ if (CompareVersions(MinVersion, SysVersion) >= 0) and
+ (CompareVersions(MaxVersion, SysVersion) <= 0)
+ then
+ // Full search in case some python version is not supported
+ for I := High(PYTHON_KNOWN_VERSIONS) downto 1 do
+ if PYTHON_KNOWN_VERSIONS[I].RegVersion = SysVersion then begin
+ Result := True;
+ break;
+ end;
end;
{$ENDIF}
diff --git a/python4lazarus/VarPyth.pas b/python4lazarus/VarPyth.pas
new file mode 100644
index 0000000..29f2328
--- /dev/null
+++ b/python4lazarus/VarPyth.pas
@@ -0,0 +1,2180 @@
+{$I Definition.Inc}
+
+unit VarPyth;
+
+(**************************************************************************)
+(* *)
+(* Module: Unit 'VarPyth' Copyright (c) 2001 *)
+(* *)
+(* Version: 1.0 Morgan Martinet *)
+(* Sub-Version: 0.7 4723 rue Brebeuf *)
+(* H2J 3L2 MONTREAL (QC) *)
+(* CANADA *)
+(* e-mail: p4d@mmm-experts.com *)
+(* *)
+(**************************************************************************)
+(* Functionality: This allows you to use Python objects like COM *)
+(* automation objects, inside your Delphi source code. *)
+(* This is a replacement of the former PythonAtom.pas *)
+(* that uses the new custom variant types introduced *)
+(* in Delphi6. *)
+(**************************************************************************)
+(* Contributors: *)
+(**************************************************************************)
+(* This source code is distributed with no WARRANTY, for no reason or use.*)
+(* Everyone is allowed to use and change this code free for his own tasks *)
+(* and projects, as long as this header and its copyright text is intact. *)
+(* For changed versions of this code, which are public distributed the *)
+(* following additional conditions have to be fullfilled: *)
+(* 1) The header has to contain a comment on the change and the author of *)
+(* it. *)
+(* 2) A copy of the changed source has to be sent to the above E-Mail *)
+(* address or my then valid address, if this is possible to the *)
+(* author. *)
+(* The second condition has the target to maintain an up to date central *)
+(* version of the component. If this condition is not acceptable for *)
+(* confidential or legal reasons, everyone is free to derive a component *)
+(* or to generate a diff file to my or other original sources. *)
+(**************************************************************************)
+
+interface
+
+uses
+ Variants, PythonEngine, Classes;
+
+type
+ TSequenceType = (stTuple, stList);
+
+{ Python variant creation utils }
+function VarPythonCreate( AObject : PPyObject ) : Variant; overload;
+function VarPythonCreate( const AValue : Variant ) : Variant; overload;
+function VarPythonCreate( const AValues : array of const; ASequenceType : TSequenceType = stList ) : Variant; overload;
+function VarPythonEval( const APythonExpression : AnsiString) : Variant;
+
+{ Python variant helper functions }
+function VarPython: TVarType;
+function VarIsPython(const AValue: Variant): Boolean;
+function VarAsPython(const AValue: Variant): Variant;
+function ExtractPythonObjectFrom(const AValue : Variant) : PPyObject;
+function VarIsSame(const A, B : Variant ) : Boolean; // checks if 2 variants share the same Python object.
+function VarIsSameType(const A, B : Variant ) : Boolean; // checks if 2 variants are of the same Python type.
+function VarIsPythonSequence(const AValue: Variant): Boolean;
+function VarIsPythonMapping(const AValue: Variant): Boolean;
+function VarIsPythonNumber(const AValue: Variant): Boolean;
+function VarIsPythonString(const AValue: Variant): Boolean;
+function VarIsPythonInteger(const AValue: Variant): Boolean;
+function VarIsPythonFloat(const AValue: Variant): Boolean;
+function VarIsPythonTuple(const AValue: Variant): Boolean;
+function VarIsPythonList(const AValue: Variant): Boolean;
+function VarIsPythonDict(const AValue: Variant): Boolean;
+function VarIsPythonClass(const AValue: Variant): Boolean;
+function VarIsPythonMethod(const AValue: Variant): Boolean;
+function VarIsPythonFunction(const AValue: Variant): Boolean;
+function VarIsPythonModule(const AValue: Variant): Boolean;
+function VarIsPythonCallable(const AValue: Variant): Boolean;
+function VarIsPythonIterator(const AValue: Variant): Boolean;
+function VarIsPythonUnicode(const AValue: Variant): Boolean;
+function VarIsPythonDateTime(const AValue: Variant): Boolean;
+function VarIsPythonDate(const AValue: Variant): Boolean;
+function VarIsPythonTime(const AValue: Variant): Boolean;
+function VarIsPythonDateTimeDelta(const AValue: Variant): Boolean;
+function VarIsPythonTZInfo(const AValue: Variant): Boolean;
+function VarIsBool(const AValue: Variant): Boolean;
+function VarIsEnum(const AValue: Variant): Boolean;
+function VarIsInstanceOf(const AInstance, AClass : Variant): Boolean;
+function VarIsSubclassOf(const ADerived, AClass : Variant): Boolean;
+function VarIsSubtypeOf(const ADerived, AType : Variant): Boolean;
+function VarIsNone(const AValue : Variant): Boolean;
+function VarIsTrue(const AValue : Variant): Boolean;
+
+function VarModuleHasObject(const AModule : Variant; aObj: AnsiString): Boolean;
+
+function NewPythonList( const ASize : Integer = 0 ): Variant;
+function NewPythonTuple( const ASize : Integer ): Variant;
+function NewPythonDict: Variant;
+
+// Not really needed since you can assign a PythonVariant to a string anyway
+// but it is slightly faster and in some places avoids the declaration of a variable
+function VarPythonAsString(AValue : Variant) : string;
+{$IFDEF FPC}
+// to work around http://mantis.freepascal.org/view.php?id=20849)
+function VarPythonToVariant(AValue : Variant): Variant;
+{$ENDIF}
+
+function None: Variant;
+function Ellipsis: Variant;
+function MainModule: Variant; // return the main module that's used for executing a script.
+function BuiltinModule: Variant; // return the builtin module
+function SysModule: Variant; // return the builtin module 'sys'
+function DatetimeModule: Variant; // return the builtin module 'datetime'
+function Import(const AModule: string): Variant; // import a Python module and return the module object.
+function Reload(const AModule: Variant): Variant; //reload a Python imported module and return the module object.
+function len(const AValue : Variant ): NativeInt; // return the length of a Python collection.
+function _type(const AValue : Variant ): Variant; // return the type object of a Python object.
+function iter(const AValue : Variant ): Variant; // return an iterator for the container AValue. You can call the 'next' method of the iterator until you catch the EPyStopIteration exception.
+
+type
+ TVarPyEnumerator = record
+ private
+ FIterator: Variant;
+ FCurrent: Variant;
+ public
+ constructor Create(const AValue: Variant);
+ function MoveNext: Boolean; inline;
+ function GetCurrent: Variant; inline;
+ property Current: Variant read GetCurrent;
+ end;
+
+ TVarPyEnumerateHelper = record
+ private
+ FIterable: Variant;
+ public
+ constructor Create(const AValue: Variant);
+ function GetEnumerator: TVarPyEnumerator;
+ end;
+
+function VarPyIterate(const AValue: Variant): TVarPyEnumerateHelper;
+
+// Adds a python iterable items to a TStrings
+procedure VarPyToStrings(const AValue : Variant; const AStrings: TStrings);
+
+implementation
+
+uses
+ VarUtils, SysUtils, TypInfo;
+
+type
+ TNamedParamDesc = record
+ Index : Integer;
+ Name : AnsiString;
+ end;
+ TNamedParamArray = array of TNamedParamDesc;
+
+{$IF not defined(FPC) and (defined(OSX64) or defined(LINUX) or not defined(DELPHI10_4_OR_HIGHER))}
+ {$DEFINE PATCHEDSYSTEMDISPINVOKE} //To correct memory leaks
+{$IFEND}
+
+ { Python variant type handler }
+ TPythonVariantType = class(TInvokeableVariantType, IVarInstanceReference)
+ protected
+ fNamedParams : TNamedParamArray;
+ function LeftPromotion(const V: TVarData; const AOperator: TVarOp;
+ out RequiredVarType: TVarType): Boolean; override;
+ function RightPromotion(const V: TVarData; const AOperator: TVarOp;
+ out RequiredVarType: TVarType): Boolean; override;
+ function GetInstance(const V: TVarData): TObject;
+ function EvalPython(const V: TVarData; const AName: AnsiString;
+ const Arguments: TVarDataArray): PPyObject;
+ function VarDataToPythonObject( AVarData : TVarData ) : PPyObject;
+ procedure PyhonVarDataCreate( var Dest : TVarData; AObject : PPyObject );
+ {$IFDEF FPC}
+ procedure VarDataClear(var Dest: TVarData);
+ procedure VarDataCopyNoInd(var Dest: TVarData; const Source: TVarData);
+ procedure VarDataCastTo(var Dest: TVarData; const Source: TVarData;
+ const AVarType: TVarType); overload;
+ {$ELSE}
+ function FixupIdent(const AText: string): string; override;
+ {$ENDIF FPC}
+ public
+ procedure Clear(var V: TVarData); override;
+ function IsClear(const V: TVarData): Boolean; override;
+ procedure Copy(var Dest: TVarData; const Source: TVarData;
+ const Indirect: Boolean); override;
+ procedure Cast(var Dest: TVarData; const Source: TVarData); override;
+ procedure CastTo(var Dest: TVarData; const Source: TVarData;
+ const AVarType: TVarType); override;
+
+ procedure BinaryOp(var Left: TVarData; const Right: TVarData;
+ const AOperator: TVarOp); override;
+ procedure UnaryOp(var Right: TVarData; const AOperator: TVarOp); override;
+ function CompareOp(const Left: TVarData; const Right: TVarData;
+ const AOperator: TVarOp): Boolean; override;
+ function DoFunction(var Dest: TVarData; const V: TVarData;
+ const AName: string; const Arguments: TVarDataArray): Boolean; override;
+ function DoProcedure(const V: TVarData; const AName: string;
+ const Arguments: TVarDataArray): Boolean; override;
+ function GetProperty(var Dest: TVarData; const V: TVarData;
+ const AName: string): Boolean; override;
+ function SetProperty({$IFDEF FPC}var{$ELSE}const{$ENDIF} V: TVarData; const AName: string;
+ const Value: TVarData): Boolean; override;
+ {$IFDEF DELPHIXE7_OR_HIGHER}
+ procedure DispInvoke(Dest: PVarData;
+ [Ref] const Source: TVarData; CallDesc: PCallDesc; Params: Pointer);override;
+ {$ELSE}
+ procedure DispInvoke(Dest: PVarData;
+ var Source: TVarData; CallDesc: PCallDesc; Params: Pointer);override;
+ {$ENDIF}
+ end;
+
+var
+ { Python variant type handler instance }
+ PythonVariantType: TPythonVariantType = nil;
+
+type
+ { Python data that the Python variant points to }
+ TPythonData = class(TObject)
+ private
+ fPyObject: PPyObject;
+ function GetAsString: string;
+ procedure SetPyObject(const Value: PPyObject);
+ function GetAsVariant: Variant;
+ function GetAsWideString: UnicodeString;
+ function GetAsAnsiString: AnsiString;
+ public
+ constructor Create(AObject : PPyObject);
+ destructor Destroy; override;
+
+ // query state
+ function IsNone : Boolean;
+
+ // non-destructive operations
+ function Equal(const Right: TPythonData): Boolean;
+ function LessThan(const Right: TPythonData): Boolean;
+ function LessOrEqualThan(const Right: TPythonData): Boolean;
+ function GreaterThan(const Right: TPythonData): Boolean;
+ function GreaterOrEqualThan(const Right: TPythonData): Boolean;
+
+ // destructive operations
+ procedure DoAdd(const Right: TPythonData);
+ procedure DoSubtract(const Right: TPythonData);
+ procedure DoMultiply(const Right: TPythonData);
+ procedure DoDivide(const Right: TPythonData);
+ procedure DoIntDivide(const Right: TPythonData);
+ procedure DoModulus(const Right: TPythonData);
+ procedure DoShiftLeft(const Right: TPythonData);
+ procedure DoShiftRight(const Right: TPythonData);
+ procedure DoAnd(const Right: TPythonData);
+ procedure DoOr(const Right: TPythonData);
+ procedure DoXor(const Right: TPythonData);
+ procedure DoNegate;
+ procedure DoNot;
+
+ // conversion
+ property AsString: string read GetAsString;
+ property AsAnsiString: AnsiString read GetAsAnsiString;
+ property AsVariant: Variant read GetAsVariant;
+ property AsWideString: UnicodeString read GetAsWideString;
+
+ // data
+ property PyObject : PPyObject read fPyObject write SetPyObject;
+ end;
+
+type
+ { Helper record that helps crack open TVarData }
+ TPythonVarData = packed record
+ VType: TVarType;
+ Reserved1, Reserved2, Reserved3: Word;
+ VPython: TPythonData;
+ Reserved4: Integer;
+ {$IFDEF CPU64BITS}
+ Reserved5: Integer; // size is 24 bytes in 64bit
+ {$ENDIF CPU64BITS}
+ end;
+
+
+resourcestring
+ SMultiDimensionalPropsNotSupported = 'Multi-dimensional sequences or mappings are not supported in Python';
+ SCantConvertArg = 'Can''t convert argument #%d of %s into a Python object';
+ SCantConvertKeyToPythonObject = 'Can''t convert Key into a Python object';
+ SCantConvertValueToPythonObject = 'Can''t convert Value into a Python object';
+ SCantCreateNewSequenceObject = 'Can''t create a new sequence object';
+ SExpectedPythonVariant = 'Expected a Python variant';
+
+{ Python variant creation utils }
+
+function VarPythonCreate( AObject : PPyObject ) : Variant;
+begin
+ VarClear(Result);
+ if Assigned(AObject) then
+ begin
+ TPythonVarData(Result).VType := VarPython;
+ TPythonVarData(Result).VPython := TPythonData.Create(AObject);
+ end; // of if
+end;
+
+function VarPythonCreate( const AValue : Variant ) : Variant;
+var
+ _value : PPyObject;
+begin
+ if VarIsPython(AValue) then
+ Result := AValue
+ else
+ with GetPythonEngine do
+ begin
+ _value := VariantAsPyObject(AValue);
+ try
+ Result := VarPythonCreate( _value );
+ finally
+ Py_XDecRef(_value);
+ end;
+ end; // of with
+end;
+
+function VarPythonCreate( const AValues : array of const; ASequenceType : TSequenceType = stList ) : Variant;
+var
+ i : Integer;
+ _seq, _item : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ if ASequenceType = stTuple then
+ _seq := PyTuple_New( High(AValues)-Low(AValues)+1 )
+ else
+ _seq := PyList_New( High(AValues)-Low(AValues)+1 );
+ if not Assigned(_seq) then
+ raise Exception.Create(SCantCreateNewSequenceObject);
+ try
+ for i := Low(AValues) to High(AValues) do
+ begin
+ if (AValues[i].VType = vtVariant) and VarIsPython(AValues[i].VVariant^) then
+ begin
+ _item := ExtractPythonObjectFrom( AValues[i].VVariant^ );
+ Py_XIncRef(_item);
+ end
+ else
+ _item := VarRecAsPyObject( AValues[i] );
+ if ASequenceType = stTuple then
+ PyTuple_SetItem( _seq, i, _item )
+ else
+ PyList_SetItem( _seq, i, _item );
+ end; // of for
+ Result := VarPythonCreate( _seq );
+ finally
+ Py_XDecRef(_seq);
+ end; // of try
+ end; // of with
+end;
+
+function VarPythonEval( const APythonExpression : AnsiString) : Variant;
+var
+ _obj : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _obj := EvalString(APythonExpression);
+ try
+ Result := VarPythonCreate( _obj );
+ finally
+ Py_XDecRef(_obj);
+ end;
+ end;
+end;
+
+function VarPython: TVarType;
+begin
+ Result := PythonVariantType.VarType;
+end;
+
+function VarIsPython(const AValue: Variant): Boolean;
+begin
+ Result := (TVarData(AValue).VType and varTypeMask) = VarPython;
+end;
+
+function VarAsPython(const AValue: Variant): Variant;
+begin
+ if not VarIsPython(AValue) then
+ VarCast(Result, AValue, VarPython)
+ else
+ Result := AValue;
+end;
+
+// note that the returned reference to the Python object is a borrowed reference (not pre-incremented).
+function ExtractPythonObjectFrom(const AValue : Variant) : PPyObject;
+begin
+ if VarIsPython(AValue) then
+ Result := TPythonVarData(AValue).VPython.PyObject
+ else
+ Result := nil;
+end;
+
+function VarIsSame(const A, B : Variant ) : Boolean;
+begin
+ Result := ExtractPythonObjectFrom(A) = ExtractPythonObjectFrom(B);
+end;
+
+function VarIsSameType(const A, B : Variant ) : Boolean;
+var
+ _obj1, _obj2 : PPyObject;
+begin
+ _obj1 := ExtractPythonObjectFrom(A);
+ _obj2 := ExtractPythonObjectFrom(B);
+ Result := Assigned(_obj1) and Assigned(_obj2) and (_obj1^.ob_type = _obj2^.ob_type);
+end;
+
+//------------------------------------------------------------------------------
+{ Python variant helper functions }
+function VarIsPythonSequence(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ (GetPythonEngine.PySequence_Check(ExtractPythonObjectFrom(AValue)) <> 0);
+end;
+
+function VarIsPythonMapping(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ (GetPythonEngine.PyMapping_Check(ExtractPythonObjectFrom(AValue)) <> 0);
+end;
+
+function VarIsPythonNumber(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ (GetPythonEngine.PyNumber_Check(ExtractPythonObjectFrom(AValue)) <> 0);
+end;
+
+function VarIsPythonString(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyUnicode_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonInteger(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyLong_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonFloat(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyFloat_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonTuple(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyTuple_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonList(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyList_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonDict(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyDict_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonClass(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ (GetPythonEngine.PyClass_Check(ExtractPythonObjectFrom(AValue))
+ or (GetPythonEngine.PyObject_HasAttrString(ExtractPythonObjectFrom(AValue), '__bases__') <> 0));
+end;
+
+function VarIsPythonMethod(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyMethod_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonFunction(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyFunction_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonModule(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyModule_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonCallable(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ (GetPythonEngine.PyCallable_Check(ExtractPythonObjectFrom(AValue)) <> 0);
+end;
+
+function VarIsPythonIterator(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ (GetPythonEngine.PyIter_Check(ExtractPythonObjectFrom(AValue)));
+end;
+
+function VarIsPythonUnicode(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyUnicode_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonDateTime(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyDateTime_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonDate(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyDate_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonTime(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyTime_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonDateTimeDelta(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyDelta_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsPythonTZInfo(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyTZInfo_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsBool(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyBool_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsEnum(const AValue: Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ GetPythonEngine.PyEnum_Check(ExtractPythonObjectFrom(AValue));
+end;
+
+function VarIsInstanceOf(const AInstance, AClass : Variant): Boolean;
+begin
+ with GetPythonEngine do
+ begin
+ Result := VarIsPython(AInstance) and VarIsPython(AClass) and
+ (PyObject_IsInstance( ExtractPythonObjectFrom(AInstance),
+ ExtractPythonObjectFrom(AClass)) <> 0);
+ CheckError;
+ end; // of with
+end;
+
+function VarIsSubclassOf(const ADerived, AClass : Variant): Boolean;
+begin
+ with GetPythonEngine do
+ begin
+ Result := VarIsPython(ADerived) and VarIsPython(AClass) and
+ (PyObject_IsSubclass( ExtractPythonObjectFrom(ADerived),
+ ExtractPythonObjectFrom(AClass)) <> 0);
+ CheckError;
+ end; // of with
+end;
+
+function VarIsSubtypeOf(const ADerived, AType : Variant): Boolean;
+begin
+ with GetPythonEngine do
+ begin
+ Result := VarIsPython(ADerived) and VarIsPython(AType) and
+ (PyType_IsSubtype( ExtractPythonObjectFrom(ADerived)^.ob_type,
+ PPyTypeObject(ExtractPythonObjectFrom(AType))) <> 0);
+ CheckError;
+ end; // of with
+end;
+
+function VarIsNone(const AValue : Variant): Boolean;
+begin
+ Result := VarIsPython(AValue) and
+ (ExtractPythonObjectFrom(AValue) = GetPythonEngine.Py_None);
+end;
+
+function VarIsTrue(const AValue : Variant): Boolean;
+begin
+ Result := AValue; // the cast into a boolean will call the PyObject_IsTrue API.
+end;
+
+function VarModuleHasObject(const AModule : Variant; aObj: AnsiString): Boolean;
+begin
+ with GetPythonEngine do
+ Result := VarIsPython(AModule) and
+ PyModule_Check(ExtractPythonObjectFrom(AModule)) and
+ Assigned(PyDict_GetItemString(
+ PyModule_GetDict(ExtractPythonObjectFrom(AModule)),PAnsiChar(aObj)));
+end;
+
+function NewPythonList( const ASize : Integer = 0 ): Variant;
+var
+ _list : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _list := PyList_New(ASize);
+ try
+ Result := VarPythonCreate( _list );
+ finally
+ Py_XDecRef(_list);
+ end; // of try
+ end; // of with
+end;
+
+function NewPythonTuple( const ASize : Integer ): Variant;
+var
+ _tuple : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _tuple := PyTuple_New(ASize);
+ try
+ Result := VarPythonCreate( _tuple );
+ finally
+ Py_XDecRef(_tuple);
+ end; // of try
+ end; // of with
+end;
+
+function NewPythonDict: Variant;
+var
+ _dict : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _dict := PyDict_New;
+ try
+ Result := VarPythonCreate( _dict );
+ finally
+ Py_XDecRef(_dict);
+ end; // of try
+ end; // of with
+end;
+
+function VarPythonAsString(AValue : Variant) : string;
+begin
+ if VarIsPython(AValue) then
+ Result := TPythonVarData(AValue).VPython.AsString
+ else
+ Result := AValue;
+end;
+
+{$IFDEF FPC}
+function VarPythonToVariant(AValue : Variant): Variant;
+begin
+ if VarIsPython(AValue) then
+ Result :=
+ GetPythonEngine.PyObjectAsVariant(TPythonVarData(AValue).VPython.PyObject)
+ else
+ Result := AValue;
+end;
+{$ENDIF}
+
+function None : Variant;
+begin
+ with GetPythonEngine do
+ Result := VarPythonCreate(Py_None);
+end;
+
+function Ellipsis : Variant;
+begin
+ with GetPythonEngine do
+ Result := VarPythonCreate(Py_Ellipsis);
+end;
+
+function MainModule : Variant;
+var
+ _main : PPyObject;
+begin
+ _main := GetPythonEngine.GetMainModule; // the refcount is not pre-incremented
+ Assert(Assigned(_main));
+ Result := VarPythonCreate(_main);
+end;
+
+function BuiltinModule : Variant;
+begin
+ Result := Import(GetPythonEngine.BuiltInModuleName);
+end;
+
+function SysModule : Variant;
+begin
+ Result := Import('sys');
+end;
+
+function DatetimeModule : Variant; // return the builtin module 'datetime'
+begin
+ Result := Import('datetime');
+end;
+
+function Import(const AModule: string): Variant;
+var
+ _module : PPyObject;
+ _module_name : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _module_name := PyUnicodeFromString(AModule);
+ try
+ _module := PyImport_Import(_module_name);
+ CheckError;
+ finally
+ Py_XDecRef(_module_name);
+ end; // of try
+ Assert(Assigned(_module));
+ try
+ Result := VarPythonCreate(_module);
+ finally
+ Py_XDecRef(_module);
+ end; // of try
+ end; // of with
+end;
+
+function Reload(const AModule: Variant): Variant;
+var
+ LModule: PPyObject;
+begin
+ with GetPythonEngine() do begin
+ LModule := PyImport_ReloadModule(ExtractPythonObjectFrom(AModule));
+ CheckError();
+ Assert(Assigned(LModule));
+ try
+ Result := VarPythonCreate(LModule);
+ finally
+ Py_XDecRef(LModule);
+ end; // of try
+ end; // of with
+end;
+
+function GetObjectLength(AObject: PPyObject): NativeInt;
+begin
+ with GetPythonEngine do
+ begin
+ PyErr_Clear;
+ Result := PyObject_Length(AObject);
+ CheckError;
+ end; // of with
+end;
+
+// returns the length of a Python collection.
+function len(const AValue : Variant ) : NativeInt;
+begin
+ if VarIsPython(AValue) then
+ Result := GetObjectLength( ExtractPythonObjectFrom(AValue) )
+ else
+ raise Exception.Create(SExpectedPythonVariant);
+end;
+
+function _type(const AValue : Variant ) : Variant;
+begin
+ if VarIsPython(AValue) then
+ Result := VarPythonCreate( PPyObject( ExtractPythonObjectFrom(AValue)^.ob_type ) )
+ else
+ raise Exception.Create(SExpectedPythonVariant);
+end;
+
+function iter(const AValue : Variant ) : Variant;
+var
+ _iter : PPyObject;
+begin
+ if VarIsPython(AValue) then
+ with GetPythonEngine do
+ begin
+ PyErr_Clear;
+ _iter := PyObject_GetIter(ExtractPythonObjectFrom(AValue));
+ CheckError;
+ try
+ Result := VarPythonCreate(_iter);
+ finally
+ Py_XDecRef(_iter);
+ end;
+ end
+ else
+ raise Exception.Create(SExpectedPythonVariant);
+end;
+
+//------------------------------------------------------------------------------
+{ TPythonVariantType }
+
+procedure TPythonVariantType.BinaryOp(var Left: TVarData;
+ const Right: TVarData; const AOperator: TVarOp);
+begin
+ if Right.VType = VarType then
+ case Left.VType of
+ varString, varUString:
+ case AOperator of
+ opAdd:
+ Variant(Left) := Variant(Left) + TPythonVarData(Right).VPython.AsString;
+ else
+ RaiseInvalidOp;
+ end; // of varString
+ else
+ if Left.VType = VarType then
+ case AOperator of
+ opAdd:
+ TPythonVarData(Left).VPython.DoAdd(TPythonVarData(Right).VPython);
+ opSubtract:
+ TPythonVarData(Left).VPython.DoSubtract(TPythonVarData(Right).VPython);
+ opMultiply:
+ TPythonVarData(Left).VPython.DoMultiply(TPythonVarData(Right).VPython);
+ opDivide:
+ TPythonVarData(Left).VPython.DoDivide(TPythonVarData(Right).VPython);
+ opIntDivide:
+ TPythonVarData(Left).VPython.DoIntDivide(TPythonVarData(Right).VPython);
+ opModulus:
+ TPythonVarData(Left).VPython.DoModulus(TPythonVarData(Right).VPython);
+ opShiftLeft:
+ TPythonVarData(Left).VPython.DoShiftLeft(TPythonVarData(Right).VPython);
+ opShiftRight:
+ TPythonVarData(Left).VPython.DoShiftRight(TPythonVarData(Right).VPython);
+ opAnd:
+ TPythonVarData(Left).VPython.DoAnd(TPythonVarData(Right).VPython);
+ opOr:
+ TPythonVarData(Left).VPython.DoOr(TPythonVarData(Right).VPython);
+ opXor:
+ TPythonVarData(Left).VPython.DoXor(TPythonVarData(Right).VPython);
+ else
+ RaiseInvalidOp;
+ end // of case
+ else
+ RaiseInvalidOp;
+ end // of case
+ else
+ RaiseInvalidOp;
+end;
+
+procedure TPythonVariantType.Cast(var Dest: TVarData;
+ const Source: TVarData);
+var
+ _object : PPyObject;
+begin
+ _object := VarDataToPythonObject(Source);
+ try
+ PyhonVarDataCreate( Dest, _object );
+ finally
+ GetPythonEngine.Py_XDECREF(_object);
+ end;
+end;
+
+procedure TPythonVariantType.CastTo(var Dest: TVarData;
+ const Source: TVarData; const AVarType: TVarType);
+var
+ V : Variant;
+begin
+ if Source.VType = VarType then
+ case AVarType of
+ varOleStr:
+ VarDataFromOleStr(Dest, TPythonVarData(Source).VPython.AsWideString);
+ varUString:
+ {$IFDEF FPC}
+ VarDataFromOleStr(Dest, TPythonVarData(Source).VPython.AsWideString);
+ {$ELSE}
+ VarDataFromStr(Dest, TPythonVarData(Source).VPython.AsWideString);
+ {$ENDIF}
+ varString:
+ // Preserve AnsiStrings
+ {$IFDEF FPC}
+ Variant(Dest) := TPythonVarData(Source).VPython.AsWideString;
+ {$ELSE}
+ VarDataFromLStr(Dest, TPythonVarData(Source).VPython.AsAnsiString);
+ {$ENDIF}
+ else
+ if AVarType and varTypeMask = varBoolean then
+ begin
+ Dest.VType := varBoolean;
+ Dest.VBoolean := GetPythonEngine.PyObject_IsTrue( TPythonVarData(Source).VPython.PyObject ) = 1;
+ end
+ else
+ begin
+ V := TPythonVarData(Source).VPython.AsVariant;
+ VarDataCastTo(Dest, TVarData(V), AVarType);
+ end;
+ end // of case
+ else
+ inherited;
+end;
+
+{$IFDEF FPC}
+procedure TPythonVariantType.VarDataClear(var Dest: TVarData);
+begin
+ VarClear(Variant(Dest));
+end;
+
+procedure TPythonVariantType.VarDataCopyNoInd(var Dest: TVarData; const Source: TVarData);
+begin
+ VarCopyNoInd(Variant(Dest), Variant(Source));
+end;
+
+procedure TPythonVariantType.VarDataCastTo(var Dest: TVarData; const Source: TVarData;
+ const AVarType: TVarType); overload;
+begin
+ VarCast(Variant(Dest), Variant(Source), AVarType);
+end;
+{$ENDIF}
+
+procedure TPythonVariantType.Clear(var V: TVarData);
+begin
+ V.VType := varEmpty;
+ FreeAndNil(TPythonVarData(V).VPython);
+end;
+
+function TPythonVariantType.CompareOp(const Left, Right: TVarData;
+ const AOperator: TVarOp): Boolean;
+begin
+ Result := False;
+ if (Left.VType = VarType) and (Right.VType = VarType) then
+ case AOperator of
+ opCmpEQ:
+ Result := TPythonVarData(Left).VPython.Equal(TPythonVarData(Right).VPython);
+ opCmpNE:
+ Result := not TPythonVarData(Left).VPython.Equal(TPythonVarData(Right).VPython);
+ opCmpLT:
+ Result := TPythonVarData(Left).VPython.LessThan(TPythonVarData(Right).VPython);
+ opCmpLE:
+ Result := TPythonVarData(Left).VPython.LessOrEqualThan(TPythonVarData(Right).VPython);
+ opCmpGT:
+ Result := TPythonVarData(Left).VPython.GreaterThan(TPythonVarData(Right).VPython);
+ opCmpGE:
+ Result := TPythonVarData(Left).VPython.GreaterOrEqualThan(TPythonVarData(Right).VPython);
+ else
+ RaiseInvalidOp;
+ end // of case
+ else
+ RaiseInvalidOp;
+end;
+
+procedure TPythonVariantType.Copy(var Dest: TVarData;
+ const Source: TVarData; const Indirect: Boolean);
+begin
+ if Indirect and VarDataIsByRef(Source) then
+ VarDataCopyNoInd(Dest, Source)
+ else
+ PyhonVarDataCreate( Dest, TPythonVarData(Source).VPython.PyObject );
+end;
+
+procedure SetClearVarToEmptyParam(var V: TVarData);
+begin
+ VarClear(Variant(V));
+ V.VType := varError;
+{$IFNDEF FPC}
+ V.VError := VAR_PARAMNOTFOUND;
+{$ELSE}
+ V.VError := HRESULT($80020004); {DISP_E_PARAMNOTFOUND}
+{$ENDIF}
+end;
+
+const
+ CDoMethod = $01;
+ CPropertyGet = $02;
+ CPropertySet = $04;
+
+{$IF defined(PATCHEDSYSTEMDISPINVOKE) and (defined(OSX64) or defined(LINUX))}
+{
+ Fixes https://quality.embarcadero.com/browse/RSP-28097
+}
+var
+ _EmptyBSTR: PWideChar = nil;
+
+Const
+ SDispatchError = 'Variant method calls not supported';
+
+procedure _DispInvokeError;
+begin
+ raise EVariantDispatchError.Create(SDispatchError);
+end;
+
+function GetDispatchInvokeArgs(CallDesc: PCallDesc; Params: Pointer; var Strings: TStringRefList; OrderLTR : Boolean): TVarDataArray;
+const
+ { Parameter type masks - keep in sync with decl.h/ap* enumerations}
+ atString = $48;
+ atUString = $4A;
+ atVarMask = $3F;
+ atTypeMask = $7F;
+ atByRef = $80;
+var
+ I: Integer;
+ ArgType: Byte;
+ PVarParm: PVarData;
+ StringCount: Integer;
+ VAList: TVarArgList;
+ Temp: Pointer;
+begin
+ VAList := TVarArgList(Params^);
+ StringCount := 0;
+ SetLength(Result, CallDesc^.ArgCount);
+ for I := 0 to CallDesc^.ArgCount-1 do
+ begin
+ ArgType := CallDesc^.ArgTypes[I];
+
+ if OrderLTR then
+ PVarParm := @Result[I]
+ else
+ PVarParm := @Result[CallDesc^.ArgCount-I-1];
+
+ if (ArgType and atByRef) = atByRef then
+ begin
+ Temp := VarArgGetValue(VAList, Pointer);
+ if (ArgType and atTypeMask) = atString then
+ begin
+ PVarData(PVarParm)^.VType := varByRef or varOleStr;
+ PVarData(PVarParm)^.VPointer := Strings[StringCount].FromAnsi( PAnsiString(Temp));
+ Inc(StringCount);
+ end
+ else
+ if (ArgType and atTypeMask) = atUString then
+ begin
+ PVarData(PVarParm)^.VType := varByRef or varOleStr;
+ PVarData(PVarParm)^.VPointer := Strings[StringCount].FromUnicode(PUnicodeString(Temp));
+ Inc(StringCount);
+ end
+ else
+ begin
+ if ((ArgType and atTypeMask) = varVariant) and
+ ((PVarData(Temp)^.VType = varString) or (PVarData(Temp)^.VType = varUString)) then
+ VarCast(PVariant(Temp)^, PVariant(Temp)^, varOleStr);
+ //PVarData(PVarParm)^.VType := varByRef or (ArgType and atTypeMask);
+
+ ArgType := ArgType and atTypeMask;
+ if DispatchUnsignedAsSigned then
+ case ArgType of
+ varUInt64: ArgType := varInt64;
+ varUInt32: ArgType := varInteger;
+ varWord: ArgType := varSmallint;
+ varByte: ArgType := varShortInt;
+ end;
+ PVarData(PVarParm)^.VType := varByRef or ArgType;
+
+ PVarData(PVarParm)^.VPointer := Temp;
+ end;
+ end
+ else // ByVal
+ begin
+ PVarParm^.VType := ArgType;
+ case ArgType of
+ varEmpty, varNull: ; // Only need to set VType
+ varInteger: PVarParm^.VInteger := VarArgGetValue(VAList, Integer);
+ varSingle: PVarParm^.VSingle := VarArgGetValue(VAList, Single);
+ varDouble: PVarParm^.VDouble := VarArgGetValue(VAList, Double);
+ varCurrency: PVarParm^.VCurrency := VarArgGetValue(VAList, Currency);
+ varDate: PVarParm^.VDate := VarArgGetValue(VAList, TDateTime);
+ varOleStr: PVarParm^.VPointer := VarArgGetValue(VAList, Pointer);
+ varDispatch: PVarParm^.VDispatch := VarArgGetValue(VAList, Pointer);
+ varError: PVarParm^.VError := HRESULT($80020004); //DISP_E_PARAMNOTFOUND;
+ varBoolean: PVarParm^.VBoolean := VarArgGetValue(VAList, Boolean);
+ varVariant:
+ begin
+ PVarParm^.VType := varEmpty;
+{$IFDEF CPUX64}
+
+// PVariant(PVarParm)^ := PVariant(Params^)^;
+ PVariant(PVarParm)^ := VarArgGetValue(VAList, PVariant)^;
+{$ELSE}
+// PVariant(PVarParm)^ := PVariant(Params)^;
+ PVariant(PVarParm)^ := VarArgGetValue(VAList, Variant);
+{$ENDIF}
+ end;
+ varUnknown: PVarParm^.VUnknown := VarArgGetValue(VAList, Pointer);
+ varSmallint: PVarParm^.VSmallInt := VarArgGetValue(VAList, SmallInt);
+ varShortInt: PVarParm^.VShortInt := VarArgGetValue(VAList, ShortInt);
+ varByte: PVarParm^.VByte := VarArgGetValue(VAList, Byte);
+ varWord:
+ begin
+ if DispatchUnsignedAsSigned then
+ begin
+ PVarParm^.VType := varInteger;
+ PVarParm^.VInteger := Integer(VarArgGetValue(VAList, Word));
+ end else
+ PVarParm^.VWord := VarArgGetValue(VAList, Word);
+ end;
+ varUInt32:
+ begin
+ if DispatchUnsignedAsSigned then
+ begin
+ PVarParm^.VType := varInteger;
+ PVarParm^.VInteger := Integer(VarArgGetValue(VAList, Cardinal));
+ end else
+ PVarParm^.VUInt32 := VarArgGetValue(VAList, Cardinal);
+ end;
+ varInt64: PVarParm^.VInt64 := VarArgGetValue(VAList, Int64);
+ varUInt64:
+ begin
+ if DispatchUnsignedAsSigned then
+ begin
+ PVarParm^.VType := varInt64;
+ PVarParm^.VInt64 := VarArgGetValue(VAList, Int64); //Int64(PInt64(Params)^);
+ end else
+ PVarParm^.VUInt64 := VarArgGetValue(VAList, UInt64); //PUInt64(Params)^;
+ end;
+ atString:
+ begin
+ PVarParm^.VType := varOleStr;
+ Temp := VarArgGetValue(VAList, Pointer);
+ if AnsiString(Temp) <> '' then
+ begin
+ {
+ This line causes a crash and is replaced with the one below in line with unicode strings
+ PVarParm^.VPointer := PWideChar(Strings[StringCount].FromAnsi(PAnsiString(Temp))^);
+ }
+ PVarParm^.VPointer := PWideChar(Strings[StringCount].FromAnsi(@AnsiString(Temp))^);
+ Strings[StringCount].Ansi := nil;
+ Inc(StringCount);
+ end
+ else
+ PVarParm^.VPointer := _EmptyBSTR;
+ end;
+ atUString:
+ begin
+ PVarParm^.VType := varOleStr;
+ Temp := VarArgGetValue(VAList, Pointer);
+ if UnicodeString(Temp) <> '' then
+ begin
+ PVarParm^.VPointer := PWideChar(Strings[StringCount].FromUnicode(@UnicodeString(Temp))^);
+ Strings[StringCount].Unicode := nil;
+ Inc(StringCount);
+ end
+ else
+ PVarParm^.VPointer := _EmptyBSTR;
+ end;
+ else
+ // Unsupported Var Types
+ //varDecimal = $000E; { vt_decimal 14 } {UNSUPPORTED as of v6.x code base}
+ //varUndef0F = $000F; { undefined 15 } {UNSUPPORTED per Microsoft}
+ //varRecord = $0024; { VT_RECORD 36 }
+ //varString = $0100; { Pascal string 256 } {not OLE compatible }
+ //varAny = $0101; { Corba any 257 } {not OLE compatible }
+ //varUString = $0102; { Unicode string 258 } {not OLE compatible }
+ _DispInvokeError;
+ end;
+ end;
+ end;
+end;
+{$IFEND}
+
+{$IFDEF DELPHIXE7_OR_HIGHER}
+procedure TPythonVariantType.DispInvoke(Dest: PVarData;
+ [Ref] const Source: TVarData; CallDesc: PCallDesc; Params: Pointer);
+{$ELSE}
+procedure TPythonVariantType.DispInvoke(Dest: PVarData;
+ var Source: TVarData; CallDesc: PCallDesc; Params: Pointer);
+{$ENDIF}
+{$IFDEF PATCHEDSYSTEMDISPINVOKE}
+ // Modified to correct memory leak QC102387 / RSP-23093
+ procedure PatchedFinalizeDispatchInvokeArgs(CallDesc: PCallDesc; const Args: TVarDataArray; OrderLTR : Boolean);
+ const
+ atByRef = $80;
+ var
+ I: Integer;
+ ArgType: Byte;
+ PVarParm: PVarData;
+ VType: TVarType;
+ begin
+ for I := 0 to CallDesc^.ArgCount-1 do
+ begin
+ ArgType := CallDesc^.ArgTypes[I];
+
+ if OrderLTR then
+ PVarParm := @Args[I]
+ else
+ PVarParm := @Args[CallDesc^.ArgCount-I-1];
+
+ VType := PVarParm.VType;
+
+ // Only ByVal Variant or Array parameters have been copied and need to be released
+ // Strings have been released via the use of the TStringRefList parameter to GetDispatchInvokeArgs
+ // !!Modified to prevent memory leaks!! RSP-23093
+ if ((ArgType and atByRef) <> atByRef) and ((ArgType = varVariant) or ((VType and varArray) = varArray)) then
+ VarClear(PVariant(PVarParm)^);
+ end;
+ end;
+
+ procedure PatchedDispInvoke(Dest: PVarData;
+ const Source: TVarData; CallDesc: PCallDesc; Params: Pointer);
+ {$IFNDEF DELPHI10_4_OR_HIGHER}
+ type
+ PStringRefList = ^TStringRefList;
+ {$ENDIF}
+ const
+ CDoMethod = $01;
+ CPropertyGet = $02;
+ CPropertySet = $04;
+ var
+ I, LArgCount: Integer;
+ LIdent: string;
+ LTemp: TVarData;
+ VarParams : TVarDataArray;
+ {$IFNDEF DELPHI10_4_OR_HIGHER}
+ Strings: array of TStringRef;
+ {$ELSE}
+ Strings: TStringRefList;
+ {$ENDIF}
+ PIdent: PByte;
+ begin
+ // Grab the identifier
+ LArgCount := CallDesc^.ArgCount;
+ PIdent := @CallDesc^.ArgTypes[LArgCount];
+ LIdent := FixupIdent( UTF8ToString(MarshaledAString(PIdent)) );
+ if LArgCount > 0 then begin
+ SetLength(Strings, LArgCount);
+ {$IFNDEF DELPHI10_4_OR_HIGHER}
+ VarParams := GetDispatchInvokeArgs(CallDesc, Params, PStringRefList(Strings)^, true);
+ {$ELSE}
+ VarParams := GetDispatchInvokeArgs(CallDesc, Params, Strings, true);
+ {$ENDIF}
+ end;
+ try
+ // What type of invoke is this?
+ case CallDesc^.CallType of
+ CDoMethod:
+ // procedure with N arguments
+ if Dest = nil then
+ begin
+ if not DoProcedure(Source, LIdent, VarParams) then
+ begin
+
+ // ok maybe its a function but first we must make room for a result
+ VarDataInit(LTemp);
+ try
+
+ // notate that the destination shouldn't be bothered with
+ // functions can still return stuff, we just do this so they
+ // can tell that they don't need to if they don't want to
+ SetClearVarToEmptyParam(LTemp);
+
+ // ok lets try for that function
+ if not DoFunction(LTemp, Source, LIdent, VarParams) then
+ RaiseDispError;
+ finally
+ VarDataClear(LTemp);
+ end;
+ end
+ end
+
+ // property get or function with 0 argument
+ else if LArgCount = 0 then
+ begin
+ if not GetProperty(Dest^, Source, LIdent) and
+ not DoFunction(Dest^, Source, LIdent, VarParams) then
+ RaiseDispError;
+ end
+
+ // function with N arguments
+ else if not DoFunction(Dest^, Source, LIdent, VarParams) then
+ RaiseDispError;
+
+ CPropertyGet:
+ if not ((Dest <> nil) and // there must be a dest
+ (LArgCount = 0) and // only no args
+ GetProperty(Dest^, Source, LIdent)) then // get op be valid
+ RaiseDispError;
+
+ CPropertySet:
+ if not ((Dest = nil) and // there can't be a dest
+ (LArgCount = 1) and // can only be one arg
+ SetProperty(Source, LIdent, VarParams[0])) then // set op be valid
+ RaiseDispError;
+ else
+ RaiseDispError;
+ end;
+
+ finally
+ PatchedFinalizeDispatchInvokeArgs(CallDesc, VarParams, true);
+ end;
+
+ for I := 0 to Length(Strings) - 1 do
+ begin
+ if Pointer(Strings[I].Wide) = nil then
+ Break;
+ if Strings[I].Ansi <> nil then
+ Strings[I].Ansi^ := AnsiString(Strings[I].Wide)
+ else
+ if Strings[I].Unicode <> nil then
+ Strings[I].Unicode^ := UnicodeString(Strings[I].Wide)
+ end;
+ end;
+{$ENDIF PATCHEDSYSTEMDISPINVOKE}
+
+ procedure GetNamedParams;
+ var
+ LNamePtr: PAnsiChar;
+ LNamedArgStart : Integer; //arg position of 1st named argument (if any)
+ I : integer;
+ begin
+ LNamePtr := PAnsiChar(@CallDesc^.ArgTypes[CallDesc^.ArgCount]);
+ LNamedArgStart := CallDesc^.ArgCount - CallDesc^.NamedArgCount;
+ SetLength(fNamedParams, CallDesc^.NamedArgCount);
+ // Skip function Name
+ for I := 0 to CallDesc^.NamedArgCount - 1 do begin
+ LNamePtr := LNamePtr + Succ(Length(LNamePtr));
+ fNamedParams[I].Index := I+LNamedArgStart;
+ fNamedParams[I].Name := AnsiString(LNamePtr);
+ end;
+ end;
+
+Var
+ NewCallDesc : TCallDesc;
+begin
+ if CallDesc^.NamedArgCount > 0 then GetNamedParams;
+ try
+ if (CallDesc^.CallType = CPropertyGet) and (CallDesc^.ArgCount = 1) then begin
+ NewCallDesc := CallDesc^;
+ NewCallDesc.CallType := CDoMethod;
+ {$IFDEF PATCHEDSYSTEMDISPINVOKE}
+ PatchedDispInvoke(Dest, Source, @NewCallDesc, Params);
+ {$ELSE PATCHEDSYSTEMDISPINVOKE}
+ inherited DispInvoke(Dest, Source, @NewCallDesc, Params);
+ {$ENDIF PATCHEDSYSTEMDISPINVOKE}
+ end else
+ {$IFDEF PATCHEDSYSTEMDISPINVOKE}
+ PatchedDispInvoke(Dest, Source, CallDesc, Params);
+ {$ELSE PATCHEDSYSTEMDISPINVOKE}
+ inherited;
+ {$ENDIF PATCHEDSYSTEMDISPINVOKE}
+ finally
+ if CallDesc^.NamedArgCount > 0 then SetLength(fNamedParams, 0);
+ end;
+end;
+
+function TPythonVariantType.DoFunction(var Dest: TVarData;
+ const V: TVarData; const AName: string;
+ const Arguments: TVarDataArray): Boolean;
+var
+ _PyResult : PPyObject;
+begin
+ // eval the function call
+ _PyResult := EvalPython(V, AnsiString(AName), Arguments);
+ try
+ Result := Assigned(_PyResult);
+ // if the evaluation returned a result
+ if Result then
+ // convert it into a variant
+ PyhonVarDataCreate( Dest, _PyResult );
+ finally
+ GetPythonEngine.Py_XDecRef( _PyResult );
+ end; // of try
+end;
+
+function TPythonVariantType.DoProcedure(const V: TVarData;
+ const AName: string; const Arguments: TVarDataArray): Boolean;
+var
+ _PyResult : PPyObject;
+begin
+ _PyResult := EvalPython(V, AnsiString(AName), Arguments);
+ Result := Assigned(_PyResult);
+ GetPythonEngine.Py_XDecRef( _PyResult );
+end;
+
+function TPythonVariantType.EvalPython(const V: TVarData;
+ const AName: AnsiString; const Arguments: TVarDataArray): PPyObject;
+
+ function ArgAsPythonObject( AArgIndex : Integer ) : PPyObject;
+ begin
+ Result := VarDataToPythonObject(Arguments[AArgIndex]);
+ // if conversion failed, then too bad ;-)
+ if not Assigned(Result) then
+ raise Exception.CreateFmt(SCantConvertArg, [AArgIndex, AName]);
+ end; // of function
+
+ function GetObjectItem( AObject : PPyObject; const AKey : TVarData ) : PPyObject;
+ var
+ _key : PPyObject;
+ begin
+ _key := VarDataToPythonObject(AKey);
+ with GetPythonEngine do
+ begin
+ PyErr_Clear;
+ if not Assigned(_key) then
+ raise Exception.Create(SCantConvertKeyToPythonObject);
+ try
+ Result := PyObject_GetItem( AObject, _key );
+ CheckError;
+ finally
+ Py_XDecRef(_key);
+ end; // of try
+ end; // of with
+ end; // of function
+
+ function SetObjectItem( AObject : PPyObject; const AKey, AValue : TVarData ) : PPyObject;
+ var
+ _key, _value : PPyObject;
+ _result : Integer;
+ begin
+ with GetPythonEngine do
+ begin
+ PyErr_Clear;
+ _key := VarDataToPythonObject(AKey);
+ if not Assigned(_key) then
+ raise Exception.Create(SCantConvertKeyToPythonObject);
+ try
+ _value := VarDataToPythonObject(AValue);
+ if not Assigned(_value) then
+ raise Exception.Create(SCantConvertValueToPythonObject);
+ if PyList_Check(AObject) then
+ _result := PyList_SetItem( AObject,
+ {$IFDEF FPC}PtrInt(Variant(AKey)){$ELSE}Variant(AKey){$ENDIF}, _value )
+ else if PyTuple_Check(AObject) then
+ _result := PyTuple_SetItem( AObject,
+ {$IFDEF FPC}PtrInt(Variant(AKey)){$ELSE}Variant(AKey){$ENDIF}, _value )
+ else
+ try
+ if PySequence_Check(AObject) <> 0 then
+ _result := PySequence_SetItem(AObject,
+ {$IFDEF FPC}PtrInt(Variant(AKey)){$ELSE}Variant(AKey){$ENDIF}, _value)
+ else
+ _result := PyObject_SetItem( AObject, _key, _value );
+ finally
+ Py_XDecRef(_value);
+ end; // of try
+ CheckError;
+ Result := PyLong_FromLong(_result);
+ finally
+ Py_XDecRef(_key);
+ end; // of try
+ end; // of with
+ end; // of function
+
+ function DeleteObjectItem( AObject : PPyObject; const AKey : TVarData ) : PPyObject;
+ var
+ _key : PPyObject;
+ begin
+ _key := VarDataToPythonObject(AKey);
+ with GetPythonEngine do
+ begin
+ PyErr_Clear;
+ if not Assigned(_key) then
+ raise Exception.Create(SCantConvertKeyToPythonObject);
+ try
+ PyObject_DelItem( AObject, _key );
+ CheckError;
+ Result := ReturnNone;
+ finally
+ Py_XDecRef(_key);
+ end; // of try
+ end; // of with
+ end; // of function
+
+ procedure ExtractSliceIndexes(AObject : PPyObject; const AStart, AEnd: TVarData; out ASliceStart, ASliceEnd : Integer );
+ begin
+ with GetPythonEngine do
+ begin
+ if VarIsSame(Variant(AStart), Ellipsis) then
+ ASliceStart := 0
+ else
+ ASliceStart := Variant(AStart);
+ if VarIsSame(Variant(AEnd), Ellipsis) then
+ ASliceEnd := PySequence_Length(AObject)
+ else
+ ASliceEnd := Variant(AEnd);
+ CheckError;
+ end; // of with
+ end;
+
+ function GetSequenceSlice( AObject : PPyObject; const AStart, AEnd: TVarData ) : PPyObject;
+ var
+ _start, _end : Integer;
+ begin
+ with GetPythonEngine do
+ begin
+ PyErr_Clear;
+ ExtractSliceIndexes(AObject, AStart, AEnd, _start, _end);
+ Result := PySequence_GetSlice( AObject, _start, _end);
+ CheckError;
+ end; // of with
+ end; // of function
+
+ function SetSequenceSlice( AObject : PPyObject; const AStart, AEnd, AValue : TVarData ) : PPyObject;
+ var
+ _start, _end : Integer;
+ _value : PPyObject;
+ _result : Integer;
+ begin
+ with GetPythonEngine do
+ begin
+ PyErr_Clear;
+ ExtractSliceIndexes(AObject, AStart, AEnd, _start, _end);
+ _value := VarDataToPythonObject(AValue);
+ if not Assigned(_value) then
+ raise Exception.Create(SCantConvertValueToPythonObject);
+ try
+ _result := PySequence_SetSlice( AObject, _start, _end, _value);
+ CheckError;
+ Result := PyLong_FromLong(_result);
+ finally
+ Py_XDecRef(_value);
+ end; // of try
+ end; // of with
+ end; // of function
+
+ function DelSequenceSlice( AObject : PPyObject; const AStart, AEnd: TVarData ) : PPyObject;
+ var
+ _start, _end, _result : Integer;
+ begin
+ with GetPythonEngine do
+ begin
+ PyErr_Clear;
+ ExtractSliceIndexes(AObject, AStart, AEnd, _start, _end);
+ _result := PySequence_DelSlice( AObject, _start, _end);
+ CheckError;
+ Result := PyLong_FromLong(_result);
+ end; // of with
+ end; // of function
+
+ function SequenceContains( AObject : PPyObject; const AValue : TVarData ) : PPyObject;
+ var
+ _value : PPyObject;
+ _result : Integer;
+ begin
+ _value := VarDataToPythonObject(AValue);
+ with GetPythonEngine do
+ begin
+ PyErr_Clear;
+ if not Assigned(_value) then
+ raise Exception.Create(SCantConvertValueToPythonObject);
+ try
+ _result := PySequence_Contains( AObject, _value );
+ CheckError;
+ Result := PyLong_FromLong(_result);
+ finally
+ Py_XDecRef(_value);
+ end; // of try
+ end; // of with
+ end; // of function
+
+var
+ i : Integer;
+ _container : PPyObject;
+ _obj : PPyObject;
+ _Arg : PPyObject;
+ _Args : PPyObject;
+ _ArgLen : Integer;
+ _KW : PPyObject;
+begin
+ Result := nil;
+ with GetPythonEngine do
+ begin
+ // extract the associated Python object
+ _container := TPythonVarData(V).VPython.PyObject;
+
+ // extract the key from the container object
+ _obj := PyObject_GetAttrString(_container, PAnsiChar(AName));
+ try
+ try
+ // if the container object does not have the key AName
+ if PyErr_Occurred <> nil then
+ begin
+ // here we handle a special case: COM (or Delphi?) doesn't allow you to have index properties
+ // on a variant except from a true array variant! So if myVar is a Python variant that holds
+ // a Python list, I can't write something like: myVar[0]! But if the list is a member of a
+ // Python instance, it will work fine! Like: myInst.myList[0]
+ // So, to handle this problem we detect some special names: GetItem, SetItem and Length
+ // that will do the same as:
+ // myList[0] <-> myList.GetItem(0)
+ // myDict['Hello'] := 1 <-> myDict.SetItem('Hello', 1)
+ // len(myList) <-> myList.Length()
+ // we get some bonus with the slices and in operators also:
+ // myList = [0, 1, 2, 3]; myList.GetSlice(1, 2) --> [1, 2]
+ // myList.Contains(2) <-> 2 in myList
+
+ if (Length(Arguments) = 1) and SameText(string(AName), 'GetItem') then
+ Result := GetObjectItem(_container, Arguments[0])
+ else if (Length(Arguments) = 2) and SameText(string(AName), 'SetItem') then
+ Result := SetObjectItem(_container, Arguments[0], Arguments[1])
+ else if (Length(Arguments) = 1) and SameText(string(AName), 'DeleteItem') then
+ Result := DeleteObjectItem(_container, Arguments[0])
+ else if (Length(Arguments) = 2) and SameText(string(AName), 'GetSlice') then
+ Result := GetSequenceSlice(_container, Arguments[0], Arguments[1])
+ else if (Length(Arguments) = 3) and SameText(string(AName), 'SetSlice') then
+ Result := SetSequenceSlice(_container, Arguments[0], Arguments[1], Arguments[2])
+ else if (Length(Arguments) = 2) and SameText(string(AName), 'DelSlice') then
+ Result := DelSequenceSlice(_container, Arguments[0], Arguments[1])
+ else if (Length(Arguments) = 1) and SameText(string(AName), 'Contains') then
+ Result := SequenceContains(_container, Arguments[0])
+ else if SameText(string(AName), 'Length') then
+ Result := PyLong_FromLong( GetObjectLength(_container) );
+ end; // of if
+ finally
+ // if the key did not exist, Python generated an exception that we must propagate through CheckError
+ CheckError;
+ end; // of try
+ // exit now if our special functions could apply
+ if Assigned(Result) then
+ Exit;
+ // if we found the key
+ if Assigned(_obj) then
+ // if the associated object is callable (a method or a function)
+ if PyCallable_Check(_obj) <> 0 then
+ begin
+ // Prepare the Python arguments for calling the func or method.
+
+ // there's a special case: if we call a Python method without any argument (like myList.sort()),
+ // the arguments list contains a single error variant.
+ if (Length(Arguments) = 1) and VarDataIsEmptyParam(Arguments[0]) then
+ _ArgLen := 0
+ else
+ _ArgLen := Length(Arguments);
+ if Length(fNamedParams) > 0 then
+ begin
+ _KW := PyDict_New;
+ _ArgLen := fNamedParams[0].Index;
+ end
+ else
+ _KW := nil;
+ try
+ _Args := PyTuple_New(_ArgLen);
+ try
+ for i := 0 to _ArgLen-1 do
+ PyTuple_SetItem( _Args, i, ArgAsPythonObject(i) );
+ for i := 0 to Length(fNamedParams)-1 do
+ PyDict_SetItemString(_KW, PAnsiChar(fNamedParams[i].Name), ArgAsPythonObject(fNamedParams[i].Index));
+
+ // call the func or method, with or without named parameters (KW)
+ if Assigned(_KW) then
+ Result := PyEval_CallObjectWithKeywords(_obj, _Args, _KW)
+ else
+ Result := PyEval_CallObjectWithKeywords(_obj, _Args, nil);
+ CheckError(True);
+ finally
+ Py_XDecRef(_Args);
+ end; // of try
+ finally
+ Py_XDecRef(_KW);
+ end;
+ end // of if
+ // if we have one argument and our associated object is not callable
+ // it could mean that we're trying to access an item of a sequence or
+ // a mapping, like myInst.MyList(1)
+ else if Length(Arguments) = 1 then
+ begin
+ // if we have a sequence or a mapping object
+ if (PySequence_Check(_obj) <> 0) or (PyMapping_Check(_obj) <> 0) then
+ begin
+ // convert the variant argument into a Python object
+ _Arg := VarDataToPythonObject(Arguments[0]);
+ try
+ // get the item
+ Result := PyObject_GetItem(_obj, _Arg);
+ CheckError;
+ finally
+ Py_XDecRef(_Arg);
+ end; // of try
+ end; // of if
+ end // of else if
+ else
+ raise Exception.Create( SMultiDimensionalPropsNotSupported );
+ finally
+ Py_XDecRef(_obj);
+ end; // of try
+ end; // of with
+end;
+
+{$IFNDEF FPC}
+function TPythonVariantType.FixupIdent(const AText: string): string;
+begin
+ Result := AText;
+end;
+{$ENDIF FPC}
+
+function TPythonVariantType.GetInstance(const V: TVarData): TObject;
+begin
+ Result := TPythonVarData(V).VPython;
+end;
+
+function TPythonVariantType.GetProperty(var Dest: TVarData;
+ const V: TVarData; const AName: string): Boolean;
+var
+ _prop : PPyObject;
+ _len : Integer;
+begin
+ with GetPythonEngine do
+ begin
+ _prop := PyObject_GetAttrString(TPythonVarData(V).VPython.PyObject, PAnsiChar(AnsiString(AName)));
+ // if we could not find the property
+ if (PyErr_Occurred <> nil) or not Assigned(_prop) then
+ begin
+ // test a special property name for sequences only
+ if SameText(AName, 'Length') then
+ begin
+ // if it's a sequence or a mapping
+ if (PySequence_Check(TPythonVarData(V).VPython.PyObject) <> 0) or
+ (PyMapping_Check(TPythonVarData(V).VPython.PyObject) <> 0) then
+ begin
+ // clear the error state of Python
+ PyErr_Clear;
+ // get the length
+ _len := PyObject_Length(TPythonVarData(V).VPython.PyObject);
+ CheckError;
+ // convert the length into a Python integer
+ _prop := PyLong_FromLong( _len );
+ end; // of if
+ end;
+ end; // of if
+ CheckError;
+ Result := Assigned(_prop);
+ if Result then
+ try
+ PyhonVarDataCreate(Dest, _prop);
+ finally
+ Py_XDecRef(_prop);
+ end; // of try
+ end; // of with
+end;
+
+function TPythonVariantType.IsClear(const V: TVarData): Boolean;
+begin
+ Result := (TPythonVarData(V).VPython = nil) or
+ TPythonVarData(V).VPython.IsNone;
+end;
+
+function TPythonVariantType.LeftPromotion(const V: TVarData;
+ const AOperator: TVarOp; out RequiredVarType: TVarType): Boolean;
+begin
+ { TypeX Op Python }
+ if (AOperator = opAdd) and VarDataIsStr(V) then
+ RequiredVarType := varUString
+ else
+ RequiredVarType := VarType;
+
+ Result := True;
+end;
+
+// this method increases the ref count of AObject
+procedure TPythonVariantType.PyhonVarDataCreate(var Dest: TVarData;
+ AObject: PPyObject);
+begin
+ VarDataClear(Dest);
+ if Assigned(AObject) then
+ begin
+ TPythonVarData(Dest).VType := VarPython;
+ TPythonVarData(Dest).VPython := TPythonData.Create(AObject);
+ end;
+end;
+
+function TPythonVariantType.RightPromotion(const V: TVarData;
+ const AOperator: TVarOp; out RequiredVarType: TVarType): Boolean;
+begin
+ { Python Op TypeX }
+ // Note that the Int64 doesn't is an exception, because the expr Python op Int64,
+ // won't cast the Int64 to Python.
+ // See unit Variants, function VarCastRare.
+ if V.VType <> varInt64 then
+ begin
+ RequiredVarType := VarType;
+ Result := True;
+ end
+ else
+ Result := False;
+end;
+
+function TPythonVariantType.SetProperty({$IFDEF FPC}var{$ELSE}const{$ENDIF} V: TVarData;
+ const AName: string; const Value: TVarData): Boolean;
+var
+ _newValue : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _newValue := VarDataToPythonObject(Value);
+ try
+ PyObject_SetAttrString(TPythonVarData(V).VPython.PyObject, PAnsiChar(AnsiString(AName)), _newValue );
+ CheckError;
+ finally
+ Py_XDecRef(_newValue);
+ end; // of try
+ end; // of with
+ Result := True;
+end;
+
+procedure TPythonVariantType.UnaryOp(var Right: TVarData;
+ const AOperator: TVarOp);
+begin
+ if Right.VType = VarType then
+ case AOperator of
+ opNegate:
+ TPythonVarData(Right).VPython.DoNegate;
+ opNot:
+ TPythonVarData(Right).VPython.DoNot;
+ else
+ RaiseInvalidOp;
+ end // of case
+ else
+ RaiseInvalidOp;
+end;
+
+function TPythonVariantType.VarDataToPythonObject(AVarData: TVarData): PPyObject;
+var
+ _PVarData : PVarData;
+begin
+ Result := nil;
+ // first detect if we have a Python variant as argument and extract its associated Python object
+ if AVarData.VType = VarType then
+ begin
+ Result := TPythonVarData(AVarData).VPython.PyObject;
+ GetPythonEngine.Py_XINCREF(Result);
+ end // of if
+ else if VarDataIsByRef(AVarData) and
+ ((AVarData.VType and varTypeMask) = varVariant) then
+ begin
+ _PVarData := AVarData.VPointer;
+ if _PVarData^.VType = VarType then
+ begin
+ Result := TPythonVarData(_PVarData^).VPython.PyObject;
+ GetPythonEngine.Py_XINCREF(Result);
+ end; // of if
+ end // of if
+ else if (AVarData.VType and varTypeMask) = varNull then
+ Result := GetPythonEngine.ReturnNone
+ else if (AVarData.VType and varTypeMask) = varEmpty then
+ Result := GetPythonEngine.ReturnNone;
+ // else try to convert the variant into a Python object
+ if not Assigned(Result) then
+ Result := GetPythonEngine.VariantAsPyObject(Variant(AVarData));
+end;
+
+//------------------------------------------------------------------------------
+{ TPythonData }
+
+constructor TPythonData.Create(AObject: PPyObject);
+begin
+ PyObject := AObject;
+end;
+
+destructor TPythonData.Destroy;
+begin
+ if PythonOK then
+ PyObject := nil;
+ inherited;
+end;
+
+procedure TPythonData.DoAdd(const Right: TPythonData);
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_Add(PyObject, Right.PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoAnd(const Right: TPythonData);
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_And(PyObject, Right.PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoDivide(const Right: TPythonData);
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_TrueDivide(PyObject, Right.PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoIntDivide(const Right: TPythonData);
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_FloorDivide( PyObject, Right.PyObject );
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoModulus(const Right: TPythonData);
+var
+ _item, _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_Divmod(PyObject, Right.PyObject);
+ CheckError;
+ if Assigned(_result) and (PySequence_Check(_result) <> 0) and
+ (PySequence_Length(_result) >= 2) then
+ begin
+ _item := PySequence_GetItem(_result, 1);
+ PyObject := _item;
+ Py_XDecRef(_item);
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoMultiply(const Right: TPythonData);
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_Multiply(PyObject, Right.PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoNegate;
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_Negative(PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoNot;
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_Invert(PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoOr(const Right: TPythonData);
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_Or(PyObject, Right.PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoShiftLeft(const Right: TPythonData);
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_LShift(PyObject, Right.PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoShiftRight(const Right: TPythonData);
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_RShift(PyObject, Right.PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoSubtract(const Right: TPythonData);
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_Subtract(PyObject, Right.PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+procedure TPythonData.DoXor(const Right: TPythonData);
+var
+ _result : PPyObject;
+begin
+ with GetPythonEngine do
+ begin
+ _result := PyNumber_Xor(PyObject, Right.PyObject);
+ CheckError;
+ if Assigned(_result) then
+ begin
+ PyObject := _result;
+ Py_XDecRef(_result);
+ end; // of if
+ end; // of with
+end;
+
+function TPythonData.Equal(const Right: TPythonData): Boolean;
+begin
+ with GetPythonEngine do
+ begin
+ Result := PyObject_RichCompareBool(PyObject, Right.PyObject, Py_EQ) = 1;
+ CheckError;
+ end; // of with
+end;
+
+function TPythonData.GetAsAnsiString: AnsiString;
+begin
+ Result := AnsiString(GetAsString);
+end;
+
+function TPythonData.GetAsString: string;
+begin
+ if Assigned(PyObject) then
+ Result := GetPythonEngine.PyObjectAsString(PyObject)
+ else
+ result := '';
+end;
+
+function TPythonData.GetAsVariant: Variant;
+begin
+ if Assigned(PyObject) then
+ Result := GetPythonEngine.PyObjectAsVariant(PyObject)
+ else
+ Result := Null;
+end;
+
+function TPythonData.GetAsWideString: UnicodeString;
+begin
+ if Assigned(PyObject) and GetPythonEngine.PyUnicode_Check(PyObject) then
+ Result := GetPythonEngine.PyUnicodeAsString(PyObject)
+ else
+ Result := UnicodeString(GetAsString);
+end;
+
+function TPythonData.GreaterOrEqualThan(const Right: TPythonData): Boolean;
+begin
+ with GetPythonEngine do
+ Result := PyObject_RichCompareBool(PyObject, Right.PyObject, Py_GE) = 1
+end;
+
+function TPythonData.GreaterThan(const Right: TPythonData): Boolean;
+begin
+ with GetPythonEngine do
+ Result := PyObject_RichCompareBool(PyObject, Right.PyObject, Py_GT) = 1
+end;
+
+function TPythonData.IsNone: Boolean;
+begin
+ Result := PyObject = GetPythonEngine.Py_None;
+end;
+
+function TPythonData.LessOrEqualThan(const Right: TPythonData): Boolean;
+begin
+ with GetPythonEngine do
+ Result := PyObject_RichCompareBool(PyObject, Right.PyObject, Py_LE) = 1
+end;
+
+function TPythonData.LessThan(const Right: TPythonData): Boolean;
+begin
+ with GetPythonEngine do
+ Result := PyObject_RichCompareBool(PyObject, Right.PyObject, Py_LT) = 1
+end;
+
+procedure TPythonData.SetPyObject(const Value: PPyObject);
+begin
+ with GetPythonEngine do
+ begin
+ Py_XDecRef(fPyObject);
+ fPyObject := Value;
+ Py_XIncRef(fPyObject);
+ end;
+end;
+
+{ TVarPyEnumerator }
+
+constructor TVarPyEnumerator.Create(const AValue: Variant);
+begin
+ FIterator := iter(AValue);
+end;
+
+function TVarPyEnumerator.GetCurrent: Variant;
+begin
+ Result := FCurrent;
+end;
+
+function TVarPyEnumerator.MoveNext: Boolean;
+begin
+ Result := True;
+ try
+ FCurrent := BuiltinModule.next(FIterator);
+ except
+ on E: EPyStopIteration do
+ begin
+ Result := False;
+ end
+ else
+ raise;
+ end;
+end;
+
+function VarPyIterate(const AValue: Variant): TVarPyEnumerateHelper;
+begin
+ Result := TVarPyEnumerateHelper.Create(AValue);
+end;
+
+{ TVarPyEnumerateHelper }
+
+constructor TVarPyEnumerateHelper.Create(const AValue: Variant);
+begin
+ FIterable := AValue;
+end;
+
+function TVarPyEnumerateHelper.GetEnumerator: TVarPyEnumerator;
+begin
+ Result := TVarPyEnumerator.Create(FIterable);
+end;
+
+procedure VarPyToStrings(const AValue : Variant; const AStrings: TStrings);
+var
+ V: Variant;
+begin
+ for V in VarPyIterate(AValue) do
+ AStrings.Add(V)
+end;
+
+initialization
+ PythonVariantType := TPythonVariantType.Create;
+
+finalization
+ FreeAndNil(PythonVariantType);
+
+end.
diff --git a/python4lazarus/python4lazarus_package.lpk b/python4lazarus/python4lazarus_package.lpk
index f714e2e..8e0dd01 100644
--- a/python4lazarus/python4lazarus_package.lpk
+++ b/python4lazarus/python4lazarus_package.lpk
@@ -25,8 +25,8 @@
-
-
+
+
@@ -44,6 +44,10 @@
+
+
+
+
diff --git a/python4lazarus/python4lazarus_package.pas b/python4lazarus/python4lazarus_package.pas
index 1c05eca..c2a7864 100644
--- a/python4lazarus/python4lazarus_package.pas
+++ b/python4lazarus/python4lazarus_package.pas
@@ -9,7 +9,7 @@ interface
uses
Python4Lazarus_register, PythonEngine, PythonGUIInputOutput, MethodCallBack,
- LazarusPackageIntf;
+ VarPyth, LazarusPackageIntf;
implementation