diff --git a/.gitignore b/.gitignore index 65b90da54..78bbd3eb0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,10 @@ powder.def gmon.out *.*.orig -build/powder* build/stamps/* +*~ +*.pyc +utils/* +*.log +build/* +src/python/stdlib/* \ No newline at end of file diff --git a/Makefile b/Makefile index 29e1a324a..4f2c72e2c 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ SOURCES := src/*.c src/elements/*.c CFLAGS := -w -std=c99 -D_POSIX_C_SOURCE=200112L -Iincludes/ OFLAGS := -O3 -ffast-math -ftree-vectorize -funsafe-math-optimizations -LFLAGS := -lSDL -lm -lbz2 +LFLAGS := -lSDL -lm -lbz2 -lpython2.7 -L/usr/lib/python2.7/config -I/usr/include/python2.7 LFLAGS_X := -lm -lbz2 -lSDLmain MFLAGS_SSE3 := -march=native -DX86 -DX86_SSE3 -msse3 MFLAGS_SSE2 := -march=native -DX86 -DX86_SSE2 -msse2 @@ -11,37 +11,47 @@ FLAGS_DBUG := -Wall -std=c99 -D_POSIX_C_SOURCE=200112L -pg -DX86 -DX86_SSE3 -mss COMPILER := gcc LINUX_TARG := powder-64-sse2 powder-sse powder-sse2 WIN32_TARG := powder-sse.exe powder-sse2.exe +PYCOMMAND := python getheader.py powder: $(SOURCES) + $(PYCOMMAND) $(COMPILER) -DINTERNAL -o$@ $(CFLAGS) $(OFLAGS) $(LFLAGS) $(MFLAGS_SSE3) $(SOURCES) -DLIN64 mv $@ build powder-debug-64: $(SOURCES) + $(PYCOMMAND) --64bit $(COMPILER) -m64 -o$@ $(FLAGS_DBUG) -DLIN64 $(SOURCES) -Iincludes/ mv $@ build powder-debug: $(SOURCES) - $(COMPILER) -m32 -o$@ $(FLAGS_DBUG) -DLIN32 $(SOURCES) -Iincludes/ + $(PYCOMMAND) + $(COMPILER) -DINTERNAL -o$@ $(CFLAGS) $(OFLAGS) $(LFLAGS) $(MFLAGS_SSE3) $(SOURCES) -DLIN64 $(FLAGS_DBUG) mv $@ build powder-sse3: $(SOURCES) + $(PYCOMMAND) $(COMPILER) -m32 -o$@ $(CFLAGS) $(OFLAGS) $(LFLAGS) $(MFLAGS_SSE3) $(SOURCES) -DLIN32 strip $@ mv $@ build powder-sse2: $(SOURCES) + $(PYCOMMAND) $(COMPILER) -m32 -o$@ $(CFLAGS) $(OFLAGS) $(LFLAGS) $(MFLAGS_SSE2) $(SOURCES) -DLIN32 strip $@ mv $@ build powder-sse: $(SOURCES) + $(PYCOMMAND) $(COMPILER) -m32 -o$@ $(CFLAGS) $(OFLAGS) $(LFLAGS) $(MFLAGS_SSE) $(SOURCES) -DLIN32 strip $@ mv $@ build powder-64-sse3-opengl: $(SOURCES) + $(PYCOMMAND) --64bit $(COMPILER) -m64 -o$@ $(CFLAGS) $(OFLAGS) $(LFLAGS) $(MFLAGS_SSE3) $(SOURCES) -DLIN64 -lGL -lGLU -DOpenGL strip $@ mv $@ build powder-64-sse3: $(SOURCES) + $(PYCOMMAND) --64bit $(COMPILER) -m64 -o$@ $(CFLAGS) $(OFLAGS) $(LFLAGS) $(MFLAGS_SSE3) $(SOURCES) -DLIN64 strip $@ mv $@ build powder-64-sse2: $(SOURCES) + $(PYCOMMAND) --64bit $(COMPILER) -m64 -o$@ $(CFLAGS) $(OFLAGS) $(LFLAGS) $(MFLAGS_SSE2) $(SOURCES) -DLIN64 strip $@ mv $@ build @@ -53,25 +63,30 @@ powder-res.o: powder-res.rc powder.ico i586-mingw32msvc-windres powder-res.rc powder-res.o powder-sse3.exe: $(SOURCES) powder-res.o + $(PYCOMMAND) i586-mingw32msvc-gcc -o$@ $(CFLAGS) $(OFLAGS) $(MFLAGS_SSE3) $(SOURCES) powder-res.o -lmingw32 -llibregex -lws2_32 -lSDLmain $(LFLAGS) -mwindows -DWIN32 strip $@ chmod 0644 $@ mv $@ build powder-sse2.exe: $(SOURCES) powder-res.o + $(PYCOMMAND) i586-mingw32msvc-gcc -o$@ $(CFLAGS) $(OFLAGS) $(MFLAGS_SSE2) $(SOURCES) powder-res.o -lmingw32 -llibregex -lws2_32 -lSDLmain $(LFLAGS) -mwindows -DWIN32 strip $@ chmod 0644 $@ mv $@ build powder-sse.exe: $(SOURCES) powder-res.o + $(PYCOMMAND) i586-mingw32msvc-gcc -o$@ $(CFLAGS) $(OFLAGS) $(MFLAGS_SSE) $(SOURCES) powder-res.o -lmingw32 -llibregex -lws2_32 -lSDLmain $(LFLAGS) -mwindows -DWIN32 strip $@ chmod 0644 $@ mv $@ build powder-x: $(SOURCES) + $(PYCOMMAND) gcc -o $@ $(CFLAGS) $(OFLAGS) $(LFLAGS_X) $(MFLAGS) $(SOURCES) -DMACOSX -DPIX32BGRA -arch x86_64 -framework Cocoa -framework SDL -framework Python strip $@ mv $@ build/Powder.app/Contents/MacOS/ powder-x-ogl: $(SOURCES) + $(PYCOMMAND) gcc -o $@ $(CFLAGS) $(OFLAGS) $(LFLAGS_X) $(MFLAGS) $(SOURCES) -DOpenGL -DMACOSX -DPIX32BGRA -arch x86_64 -framework Cocoa -framework SDL -framework OpenGL -framework Python strip $@ mv $@ build diff --git a/addzip.py b/addzip.py new file mode 100644 index 000000000..b80d34670 --- /dev/null +++ b/addzip.py @@ -0,0 +1,49 @@ +import zipfile +import os +import os.path +import sys + +if(len(sys.argv)>1 and sys.argv[1]=="--clean"): + print "cleaning" + for dirpath,dirnames,filenames in os.walk("./src/python/stdlib"): + for fname in filenames: + if(fname.endswith(".pyc") or fname.endswith(".pyo")): + os.remove(os.path.join(dirpath,fname)) + raise SystemExit + +print "zipping stdlib" +fid=zipfile.ZipFile("./build/tptPython.zip","w",zipfile.ZIP_DEFLATED) + +#ZipFile.write(filename) +files=os.walk("./src/python/stdlib") +num=0 +pn=0 +for dirpath,dirnames,filenames in files: + for fname in filenames: + if(fname.endswith(".py")): + continue + fid.write(os.path.join(dirpath,fname)) + num+=1 + if(num-5>=pn): + pn=num + print "%d done."%num + +print "writing zipfile" +fid.close() + +raise SystemExit + +"""not needed.""" +print "generating pystdlib.h" +with open("stdlib.zip","r") as fid: + with open("./includes/pystdlib.h","w") as outfid: + outfid.write("unsigned char tpt_console_stdlib[] = {") + tmp=0 + for char in fid.read(): + outfid.write(hex(ord(char))) + outfid.write(",") + tmp+=1 + outfid.write("};\n") + outfid.write("size_t tpt_console_stdlibsize=%d;"%tmp) +print "done" + diff --git a/build/example.py b/build/example.py new file mode 100644 index 000000000..850d8ae12 --- /dev/null +++ b/build/example.py @@ -0,0 +1,21 @@ +import utils +# example script + +def noise(typ,amount=50): + for xx in range(4,612): + for yy in range(4,384): + if(random.randrange(0,100)>8 + t = tpt.get_prop(i,"type")+amount + if t>=148: + t=t-148 + if t==128: + t=129 + if t==55: + t=56 + tpt.set_type(i=i,settoint=t) \ No newline at end of file diff --git a/build/ext_chat.py b/build/ext_chat.py index 8daa7ca75..56a58e56b 100644 --- a/build/ext_chat.py +++ b/build/ext_chat.py @@ -28,7 +28,7 @@ def init(): NICK=name+"[tpt]" IDENT=name+"[tpt]" REALNAME=name - CHANNEL="#foobar7" + CHANNEL="#powder" readbuffer="" def exit(): @@ -57,7 +57,7 @@ def key(keyy) : except: key.pmod=(False,False,False) global typing,typed - print "got %s"%repr(keyy) + #print "got %s"%repr(keyy) ctrl1,ctrl2,alt1,alt2,shift1,shift2=tpt.get_modifier() mod=(ctrl1 or ctrl2,alt1 or alt2,shift1 or shift2) skip=False diff --git a/build/tpt_console.py b/build/tpt_console.py new file mode 100644 index 000000000..b26ecef00 --- /dev/null +++ b/build/tpt_console.py @@ -0,0 +1,116 @@ +import tpt +from tpt import * +import sys +import code +import ctypes +import traceback +DEBUG=False + +#print "console module loaded." +#redirect stdout like this: +class logger: + def write(self,txt): + txt=txt.strip().split("\n")[-1] + repr(txt) + tpt.log(txt) +if(DEBUG==False): + sys.stdout=logger() + sys.stderr=logger() + + +element={"none":0,"dust":1,"watr":2,"oil":3,"fire":4,"stne":5,"lava":6,"gunp":7, + "nitr":8,"clne":9,"gas":10,"plex":11,"goo":12,"icei":13,"metl":14,"sprk":15, + "snow":16,"wood":17,"neut":18,"plut":19,"plnt":20,"acid":21,"void":22, + "wtrv":23,"cnct":24,"dstw":25,"salt":26,"sltw":27,"dmnd":28,"bmtl":29, + "brmt":30,"phot":31,"uran":32,"wax":33,"mwax":34,"pscn":35,"nscn":36, + "lntg":37,"insl":38,"bhol":39,"whol":40,"rbdm":41,"lrbd":42,"ntct":43, + "sand":44,"glas":45,"ptct":46,"bgla":47,"thdr":48,"plsm":49,"etrd":50, + "nice":51,"nble":52,"btry":53,"lcry":54,"stkm":55,"swch":56,"smke":57, + "desl":58,"coal":59,"lo2":60,"o2":61,"inwr":62,"yest":63,"dyst":64, + "thrm":65,"glow":66,"brck":67,"hflm":68,"firw":69,"fuse":70,"fsep":71, + "amtr":72,"bcol":73,"pcln":74,"hswc":75,"iron":76,"mort":77,"gol":78, + "hlif":79,"asim":80,"2x2":81,"dani":82,"amoe":83,"move":84,"pgol":85, + "dmoe":86,"34":87,"llif":88,"stan":89,"spng":90,"rime":91,"fog":92, + "bcln":93,"love":94,"deut":95,"warp":96,"pump":97,"fwrk":98,"pipe":99, + "frzz":100,"frzw":101,"grav":102,"bizr":103,"bizrg":104,"bizrs":105, + "inst":106,"isoz":107,"iszs":108,"prti":109,"prto":110,"pste":111, + "psts":112,"anar":113,"vine":114,"invis":115,"equalvel":116,"spawn2":117, + "spawn":118,"shld1":119,"shld2":120,"shld3":121,"shld4":122,"lolz":123, + "wifi":124,"filt":125,"aray":126,"bray":127,"stkm2":128,"bomb":129, + "c5":130,"sing":131,"qrtz":132,"pqrt":133,"seed":134,"maze":135, + "coag":136,"wall":137,"gnar":138,"repl":139,"myst":140,"boyl":141, + "lote":142,"frg2":143,"star":144,"frog":145,"bran":146,"wind":147, + "num":148} + + +def fork_unblock(): + pass#i need to implement this some day. +def error(ex): + traceback.print_exc() + err=traceback.format_exc() + sys.stdout.write(err) + +def clean(): + #add any functions that must be reachable here. + """copy=["__builtins__","__name__","__doc__","__package__",'tpt','clean', + 'element','fork','_fork','fork_status','fork_unblock','sys'] + handle.glob={} + for item in copy: + handle.glob[item]=globals()[item]""" + handle.glob=globals() + handle.buf="" + +def handle(txt): + try: + a=handle.glob + except: + clean() + try: + _handle(txt) + except Exception as ex: + error(ex) + +def _handle(txt): + #print "handling '%s'"%txt + try: + sys.stdout.write(repr(eval(txt,handle.glob))) + except: + try: + exec txt in handle.glob + except Exception as ex: + error(ex) + + +_extensions=[] +def loadext(fname): + ext=__import__(fname) + ext.init() + _extensions.append(ext) + +def keypress(key): + unload=[] + for item in _extensions: + try: + item.key(key) + except Exception as ex: + error(ex) + unload.append(item) + for item in unload: + item.exit() + _extensions.remove(item) + + +def step(): + unload=[] + for item in _extensions: + try: + item.step() + except Exception as ex: + error(ex) + unload.append(item) + for item in unload: + try: + item.exit() + except Exception as ex: + error(ex) + _extensions.remove(item) diff --git a/console_README b/console_README index 0171b2a11..b94053e3d 100644 --- a/console_README +++ b/console_README @@ -10,10 +10,10 @@ currently implemented api functions: ### USING SET COMMANDS ### the console uses keywords to identify variables of what to set, you can specify x and y coords with x=100 y=100, ect. i is the particle number -setfrom will change all of setfrom's type to the setto variable. It needs to be a string "dust" ect, "all" for all. -the setto is what the particle(s) will be set to, it is a string for the type/ctype commands, and an int for the rest, there is a settoint for type and ctype command. +name will change all of name's type to the setto variable. It needs to be a string "dust" ect, "all" for all. +the setto is what the particle(s) will be set to, it is a string for the type/ctype commands, and an int for the rest. you need to set the to* variable and one location/name/coords for it to work. - set_type(x=,y=,i=,setfrom="",setto="") + set_type(x=,y=,i=,name="",setto="") set_life() set_temp() set_tmp() diff --git a/getheader.py b/getheader.py index 536915e27..6a131d71c 100644 --- a/getheader.py +++ b/getheader.py @@ -13,25 +13,59 @@ args="-lpython%s -lm -L%s"%(sys.version[:3],os.path.join(sys.exec_prefix,"lib"," print "\n windows args are" print args,"-I%s"%path -#unsigned char tpt_console_pyc[] = { 0x1B, 0x57}; -lst=[] -compileall.compile_dir("./src/python", force=1) +ext=False +"""#see if we're on 64bit. +with open("./includes/defines.h") as fid: + for line in fid: + if(line.startswith("#define") and line.count("PYEXT")>0): + print "using external console.py" + ext=True""" +#print sys.argv +if(len(sys.argv)>=2 and sys.argv[1]=="--64bit"): + ext=True + print "YEAHS" +#raw_input("") -print "generating pyconsole.h" +if(ext): + print "external" + #raw_input(sys.argv) + with open("./src/python/tpt_console.py") as fid: + consolepy=fid.read() + script=""" +import tempfile,os.path,sys +dir=tempfile.gettempdir() +sys.path.append(dir) +tmp=%s +print "making console.py @ %%s"%%os.path.join(dir,"tpt_console.py") +with open(os.path.join(dir,"tpt_console.py"),"w") as fid: + fid.write(tmp) + """%repr(consolepy) + tmp=[hex(ord(char)) for char in script] + out=["unsigned char tpt_console_py[] = {",','.join(tmp),"};"] + with open("./includes/pyconsole.h","w") as fid: + fid.write(''.join(out)) +else: + print "internal" + #raw_input(sys.argv) + #unsigned char tpt_console_pyc[] = { 0x1B, 0x57}; + lst=[] + compileall.compile_dir("./src/python", force=0) -fname="./src/python/tpt_console.pyc" -try: - fid=open(fname,"r") -except IOError: - fname="./src/python/tpt_console.pyo" -finally: - fid.close() + print "generating pyconsole.h" -with open(fname,"r") as fid: - for char in fid.read(): - lst.append(hex(ord(char))) -tmp=",".join(lst) -out=''.join(["#include \nunsigned char tpt_console_pyc[] = {",tmp,"};"]) -with open("./includes/pyconsole.h","w") as fid: - fid.write(out) + fname="./src/python/tpt_console.pyc" + try: + fid=open(fname,"r") + except IOError: + fname="./src/python/tpt_console.pyo" + finally: + fid.close() + + with open(fname,"r") as fid: + for char in fid.read(): + lst.append(hex(ord(char))) + tmp=",".join(lst) + out=''.join(["#include \nunsigned char tpt_console_pyc[] = {",tmp,"};"]) + with open("./includes/pyconsole.h","w") as fid: + fid.write(out) print "done" diff --git a/includes/defines.h b/includes/defines.h index 9ec6905a7..1af4d33c2 100644 --- a/includes/defines.h +++ b/includes/defines.h @@ -7,8 +7,8 @@ #define PATH_SEP "/" #endif -#define SAVE_VERSION 46 -#define MINOR_VERSION 4 +#define SAVE_VERSION 47 +#define MINOR_VERSION 0 #define IDENT_VERSION "G" //Change this if you're not Simon! It should be a single letter. #define BETA @@ -68,6 +68,9 @@ extern unsigned char ZSIZE; #define BRUSH_NUM 2 #define PYCONSOLE +//#define PYEXT +//WARNING pyext must be defined on 64bit! +//also, don't add a comment on that line, it breaks #ifdef PIX16 typedef unsigned short pixel; @@ -158,6 +161,8 @@ int player2spawn; int death2; int ISSPAWN1; int ISSPAWN2; +extern char pyready; +extern char pygood; extern sign signs[MAXSIGNS]; extern stamp stamps[STAMP_MAX]; extern int stamp_count; @@ -183,5 +188,5 @@ int parse_save(void *save, int size, int replace, int x0, int y0, unsigned char void clear_sim(void); void del_stamp(int d); void sdl_seticon(void); -int process_command(pixel *vid_buf, char *console, char *console_error); +//int process_command(pixel *vid_buf, char *console, char *console_error, PyObject *pfunc); #endif diff --git a/includes/pyconsole.h b/includes/pyconsole.h index 765e63dbf..f743cbeba 100644 --- a/includes/pyconsole.h +++ b/includes/pyconsole.h @@ -1,2 +1,2 @@ #include -unsigned char tpt_console_pyc[] = {0x3,0xf3,0xd,0xa,0xde,0x1,0x75,0x4d,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x73,0xf1,0x4,0x0,0x0,0x64,0x0,0x0,0x64,0x1,0x0,0x6c,0x0,0x0,0x5a,0x0,0x0,0x64,0x0,0x0,0x64,0x2,0x0,0x6c,0x0,0x0,0x54,0x64,0x0,0x0,0x64,0x1,0x0,0x6c,0x1,0x0,0x5a,0x1,0x0,0x64,0x0,0x0,0x64,0x1,0x0,0x6c,0x2,0x0,0x5a,0x2,0x0,0x64,0x0,0x0,0x64,0x1,0x0,0x6c,0x3,0x0,0x5a,0x3,0x0,0x64,0x0,0x0,0x64,0x1,0x0,0x6c,0x4,0x0,0x5a,0x4,0x0,0x65,0x5,0x0,0x5a,0x6,0x0,0x64,0x3,0x0,0x64,0x37,0x1,0x64,0x4,0x0,0x84,0x0,0x0,0x83,0x0,0x0,0x59,0x5a,0x7,0x0,0x65,0x6,0x0,0x65,0x5,0x0,0x6b,0x2,0x0,0x72,0x86,0x0,0x65,0x7,0x0,0x83,0x0,0x0,0x65,0x1,0x0,0x5f,0x8,0x0,0x65,0x7,0x0,0x83,0x0,0x0,0x65,0x1,0x0,0x5f,0x9,0x0,0x6e,0x0,0x0,0x69,0x95,0x0,0x64,0x5,0x0,0x64,0x6,0x0,0x36,0x64,0x7,0x0,0x64,0x8,0x0,0x36,0x64,0x9,0x0,0x64,0xa,0x0,0x36,0x64,0xb,0x0,0x64,0xc,0x0,0x36,0x64,0xd,0x0,0x64,0xe,0x0,0x36,0x64,0xf,0x0,0x64,0x10,0x0,0x36,0x64,0x11,0x0,0x64,0x12,0x0,0x36,0x64,0x13,0x0,0x64,0x14,0x0,0x36,0x64,0x15,0x0,0x64,0x16,0x0,0x36,0x64,0x17,0x0,0x64,0x18,0x0,0x36,0x64,0x19,0x0,0x64,0x1a,0x0,0x36,0x64,0x1b,0x0,0x64,0x1c,0x0,0x36,0x64,0x1d,0x0,0x64,0x1e,0x0,0x36,0x64,0x1f,0x0,0x64,0x20,0x0,0x36,0x64,0x21,0x0,0x64,0x22,0x0,0x36,0x64,0x23,0x0,0x64,0x24,0x0,0x36,0x64,0x25,0x0,0x64,0x26,0x0,0x36,0x64,0x27,0x0,0x64,0x28,0x0,0x36,0x64,0x29,0x0,0x64,0x2a,0x0,0x36,0x64,0x2b,0x0,0x64,0x2c,0x0,0x36,0x64,0x2d,0x0,0x64,0x2e,0x0,0x36,0x64,0x2f,0x0,0x64,0x30,0x0,0x36,0x64,0x31,0x0,0x64,0x32,0x0,0x36,0x64,0x33,0x0,0x64,0x34,0x0,0x36,0x64,0x35,0x0,0x64,0x36,0x0,0x36,0x64,0x37,0x0,0x64,0x38,0x0,0x36,0x64,0x39,0x0,0x64,0x3a,0x0,0x36,0x64,0x3b,0x0,0x64,0x3c,0x0,0x36,0x64,0x3d,0x0,0x64,0x3e,0x0,0x36,0x64,0x3f,0x0,0x64,0x40,0x0,0x36,0x64,0x41,0x0,0x64,0x42,0x0,0x36,0x64,0x43,0x0,0x64,0x44,0x0,0x36,0x64,0x45,0x0,0x64,0x46,0x0,0x36,0x64,0x47,0x0,0x64,0x48,0x0,0x36,0x64,0x49,0x0,0x64,0x4a,0x0,0x36,0x64,0x4b,0x0,0x64,0x4c,0x0,0x36,0x64,0x4d,0x0,0x64,0x4e,0x0,0x36,0x64,0x4f,0x0,0x64,0x50,0x0,0x36,0x64,0x51,0x0,0x64,0x52,0x0,0x36,0x64,0x53,0x0,0x64,0x54,0x0,0x36,0x64,0x55,0x0,0x64,0x56,0x0,0x36,0x64,0x57,0x0,0x64,0x58,0x0,0x36,0x64,0x59,0x0,0x64,0x5a,0x0,0x36,0x64,0x5b,0x0,0x64,0x5c,0x0,0x36,0x64,0x5d,0x0,0x64,0x5e,0x0,0x36,0x64,0x5f,0x0,0x64,0x60,0x0,0x36,0x64,0x61,0x0,0x64,0x62,0x0,0x36,0x64,0x63,0x0,0x64,0x64,0x0,0x36,0x64,0x65,0x0,0x64,0x66,0x0,0x36,0x64,0x67,0x0,0x64,0x68,0x0,0x36,0x64,0x69,0x0,0x64,0x6a,0x0,0x36,0x64,0x6b,0x0,0x64,0x6c,0x0,0x36,0x64,0x6d,0x0,0x64,0x6e,0x0,0x36,0x64,0x6f,0x0,0x64,0x70,0x0,0x36,0x64,0x71,0x0,0x64,0x72,0x0,0x36,0x64,0x73,0x0,0x64,0x74,0x0,0x36,0x64,0x75,0x0,0x64,0x76,0x0,0x36,0x64,0x77,0x0,0x64,0x78,0x0,0x36,0x64,0x79,0x0,0x64,0x7a,0x0,0x36,0x64,0x7b,0x0,0x64,0x7c,0x0,0x36,0x64,0x7d,0x0,0x64,0x7e,0x0,0x36,0x64,0x7f,0x0,0x64,0x80,0x0,0x36,0x64,0x81,0x0,0x64,0x82,0x0,0x36,0x64,0x83,0x0,0x64,0x84,0x0,0x36,0x64,0x85,0x0,0x64,0x86,0x0,0x36,0x64,0x87,0x0,0x64,0x88,0x0,0x36,0x64,0x89,0x0,0x64,0x8a,0x0,0x36,0x64,0x8b,0x0,0x64,0x8c,0x0,0x36,0x64,0x8d,0x0,0x64,0x8e,0x0,0x36,0x64,0x8f,0x0,0x64,0x90,0x0,0x36,0x64,0x91,0x0,0x64,0x92,0x0,0x36,0x64,0x93,0x0,0x64,0x94,0x0,0x36,0x64,0x95,0x0,0x64,0x96,0x0,0x36,0x64,0x97,0x0,0x64,0x98,0x0,0x36,0x64,0x99,0x0,0x64,0x9a,0x0,0x36,0x64,0x9b,0x0,0x64,0x9c,0x0,0x36,0x64,0x9d,0x0,0x64,0x9e,0x0,0x36,0x64,0x9f,0x0,0x64,0xa0,0x0,0x36,0x64,0xa1,0x0,0x64,0xa2,0x0,0x36,0x64,0xa3,0x0,0x64,0xa4,0x0,0x36,0x64,0xa5,0x0,0x64,0xa6,0x0,0x36,0x64,0xa7,0x0,0x64,0xa8,0x0,0x36,0x64,0xa9,0x0,0x64,0xaa,0x0,0x36,0x64,0xab,0x0,0x64,0xac,0x0,0x36,0x64,0xad,0x0,0x64,0xae,0x0,0x36,0x64,0xaf,0x0,0x64,0xb0,0x0,0x36,0x64,0xb1,0x0,0x64,0xb2,0x0,0x36,0x64,0xb3,0x0,0x64,0xb4,0x0,0x36,0x64,0xb5,0x0,0x64,0xb6,0x0,0x36,0x64,0xb7,0x0,0x64,0xb8,0x0,0x36,0x64,0xb9,0x0,0x64,0xba,0x0,0x36,0x64,0xbb,0x0,0x64,0xbc,0x0,0x36,0x64,0xbd,0x0,0x64,0xbe,0x0,0x36,0x64,0xbf,0x0,0x64,0xc0,0x0,0x36,0x64,0xc1,0x0,0x64,0xc2,0x0,0x36,0x64,0xc3,0x0,0x64,0xc4,0x0,0x36,0x64,0xc5,0x0,0x64,0xc6,0x0,0x36,0x64,0xc7,0x0,0x64,0xc8,0x0,0x36,0x64,0xc9,0x0,0x64,0xca,0x0,0x36,0x64,0xcb,0x0,0x64,0xcc,0x0,0x36,0x64,0xcd,0x0,0x64,0xce,0x0,0x36,0x64,0xcf,0x0,0x64,0xd0,0x0,0x36,0x64,0xd1,0x0,0x64,0xd2,0x0,0x36,0x64,0xd3,0x0,0x64,0xd4,0x0,0x36,0x64,0xd5,0x0,0x64,0xd6,0x0,0x36,0x64,0xd7,0x0,0x64,0xd8,0x0,0x36,0x64,0xd9,0x0,0x64,0xda,0x0,0x36,0x64,0xdb,0x0,0x64,0xdc,0x0,0x36,0x64,0xdd,0x0,0x64,0xde,0x0,0x36,0x64,0xdf,0x0,0x64,0xe0,0x0,0x36,0x64,0xe1,0x0,0x64,0xe2,0x0,0x36,0x64,0xe3,0x0,0x64,0xe4,0x0,0x36,0x64,0xe5,0x0,0x64,0xe6,0x0,0x36,0x64,0xe7,0x0,0x64,0xe8,0x0,0x36,0x64,0xe9,0x0,0x64,0xea,0x0,0x36,0x64,0xeb,0x0,0x64,0xec,0x0,0x36,0x64,0xed,0x0,0x64,0xee,0x0,0x36,0x64,0xef,0x0,0x64,0xf0,0x0,0x36,0x64,0xf1,0x0,0x64,0xf2,0x0,0x36,0x64,0xf3,0x0,0x64,0xf4,0x0,0x36,0x64,0xf5,0x0,0x64,0xf6,0x0,0x36,0x64,0xf7,0x0,0x64,0xf8,0x0,0x36,0x64,0xf9,0x0,0x64,0xfa,0x0,0x36,0x64,0xfb,0x0,0x64,0xfc,0x0,0x36,0x64,0xfd,0x0,0x64,0xfe,0x0,0x36,0x64,0xff,0x0,0x64,0x0,0x1,0x36,0x64,0x1,0x1,0x64,0x2,0x1,0x36,0x64,0x3,0x1,0x64,0x4,0x1,0x36,0x64,0x5,0x1,0x64,0x6,0x1,0x36,0x64,0x7,0x1,0x64,0x8,0x1,0x36,0x64,0x9,0x1,0x64,0xa,0x1,0x36,0x64,0xb,0x1,0x64,0xc,0x1,0x36,0x64,0xd,0x1,0x64,0xe,0x1,0x36,0x64,0xf,0x1,0x64,0x10,0x1,0x36,0x64,0x11,0x1,0x64,0x12,0x1,0x36,0x64,0x13,0x1,0x64,0x14,0x1,0x36,0x64,0x15,0x1,0x64,0x16,0x1,0x36,0x64,0x17,0x1,0x64,0x18,0x1,0x36,0x64,0x19,0x1,0x64,0x1a,0x1,0x36,0x64,0x1b,0x1,0x64,0x1c,0x1,0x36,0x64,0x1d,0x1,0x64,0x1e,0x1,0x36,0x64,0x1f,0x1,0x64,0x20,0x1,0x36,0x64,0x21,0x1,0x64,0x22,0x1,0x36,0x64,0x23,0x1,0x64,0x24,0x1,0x36,0x64,0x25,0x1,0x64,0x26,0x1,0x36,0x64,0x27,0x1,0x64,0x28,0x1,0x36,0x64,0x29,0x1,0x64,0x2a,0x1,0x36,0x64,0x2b,0x1,0x64,0x2c,0x1,0x36,0x64,0x2d,0x1,0x64,0x2e,0x1,0x36,0x5a,0xa,0x0,0x64,0x2f,0x1,0x84,0x0,0x0,0x5a,0xb,0x0,0x64,0x30,0x1,0x84,0x0,0x0,0x5a,0xc,0x0,0x64,0x31,0x1,0x84,0x0,0x0,0x5a,0xd,0x0,0x64,0x32,0x1,0x84,0x0,0x0,0x5a,0xe,0x0,0x64,0x33,0x1,0x84,0x0,0x0,0x5a,0xf,0x0,0x67,0x0,0x0,0x5a,0x10,0x0,0x64,0x34,0x1,0x84,0x0,0x0,0x5a,0x11,0x0,0x64,0x35,0x1,0x84,0x0,0x0,0x5a,0x12,0x0,0x64,0x36,0x1,0x84,0x0,0x0,0x5a,0x13,0x0,0x64,0x1,0x0,0x53,0x28,0x38,0x1,0x0,0x0,0x69,0xff,0xff,0xff,0xff,0x4e,0x28,0x1,0x0,0x0,0x0,0x74,0x1,0x0,0x0,0x0,0x2a,0x74,0x6,0x0,0x0,0x0,0x6c,0x6f,0x67,0x67,0x65,0x72,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x42,0x0,0x0,0x0,0x73,0x11,0x0,0x0,0x0,0x65,0x0,0x0,0x5a,0x1,0x0,0x64,0x0,0x0,0x84,0x0,0x0,0x5a,0x2,0x0,0x52,0x53,0x28,0x1,0x0,0x0,0x0,0x63,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x34,0x0,0x0,0x0,0x7c,0x1,0x0,0x6a,0x0,0x0,0x83,0x0,0x0,0x6a,0x1,0x0,0x64,0x1,0x0,0x83,0x1,0x0,0x64,0x2,0x0,0x19,0x7d,0x1,0x0,0x74,0x2,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x74,0x3,0x0,0x6a,0x4,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x64,0x0,0x0,0x53,0x28,0x3,0x0,0x0,0x0,0x4e,0x73,0x1,0x0,0x0,0x0,0xa,0x69,0xff,0xff,0xff,0xff,0x28,0x5,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x74,0x72,0x69,0x70,0x74,0x5,0x0,0x0,0x0,0x73,0x70,0x6c,0x69,0x74,0x74,0x4,0x0,0x0,0x0,0x72,0x65,0x70,0x72,0x74,0x3,0x0,0x0,0x0,0x74,0x70,0x74,0x74,0x3,0x0,0x0,0x0,0x6c,0x6f,0x67,0x28,0x2,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x65,0x6c,0x66,0x74,0x3,0x0,0x0,0x0,0x74,0x78,0x74,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x5,0x0,0x0,0x0,0x77,0x72,0x69,0x74,0x65,0xc,0x0,0x0,0x0,0x73,0x6,0x0,0x0,0x0,0x0,0x1,0x19,0x1,0xa,0x1,0x28,0x3,0x0,0x0,0x0,0x74,0x8,0x0,0x0,0x0,0x5f,0x5f,0x6e,0x61,0x6d,0x65,0x5f,0x5f,0x74,0xa,0x0,0x0,0x0,0x5f,0x5f,0x6d,0x6f,0x64,0x75,0x6c,0x65,0x5f,0x5f,0x52,0x9,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x52,0x1,0x0,0x0,0x0,0xb,0x0,0x0,0x0,0x73,0x2,0x0,0x0,0x0,0x6,0x1,0x69,0x0,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x6f,0x6e,0x65,0x69,0x1,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x75,0x73,0x74,0x69,0x2,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x61,0x74,0x72,0x69,0x3,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x6f,0x69,0x6c,0x69,0x4,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x69,0x72,0x65,0x69,0x5,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x74,0x6e,0x65,0x69,0x6,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x61,0x76,0x61,0x69,0x7,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x67,0x75,0x6e,0x70,0x69,0x8,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x69,0x74,0x72,0x69,0x9,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x63,0x6c,0x6e,0x65,0x69,0xa,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x67,0x61,0x73,0x69,0xb,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x6c,0x65,0x78,0x69,0xc,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x67,0x6f,0x6f,0x69,0xd,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x63,0x65,0x69,0x69,0xe,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x65,0x74,0x6c,0x69,0xf,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x70,0x72,0x6b,0x69,0x10,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x6e,0x6f,0x77,0x69,0x11,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x6f,0x6f,0x64,0x69,0x12,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x65,0x75,0x74,0x69,0x13,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x6c,0x75,0x74,0x69,0x14,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x6c,0x6e,0x74,0x69,0x15,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x63,0x69,0x64,0x69,0x16,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x76,0x6f,0x69,0x64,0x69,0x17,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x74,0x72,0x76,0x69,0x18,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x63,0x6e,0x63,0x74,0x69,0x19,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x73,0x74,0x77,0x69,0x1a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x61,0x6c,0x74,0x69,0x1b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x6c,0x74,0x77,0x69,0x1c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x6d,0x6e,0x64,0x69,0x1d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x6d,0x74,0x6c,0x69,0x1e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x72,0x6d,0x74,0x69,0x1f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x68,0x6f,0x74,0x69,0x20,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x75,0x72,0x61,0x6e,0x69,0x21,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x77,0x61,0x78,0x69,0x22,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x77,0x61,0x78,0x69,0x23,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x73,0x63,0x6e,0x69,0x24,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x73,0x63,0x6e,0x69,0x25,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x6e,0x74,0x67,0x69,0x26,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x6e,0x73,0x6c,0x69,0x27,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x68,0x6f,0x6c,0x69,0x28,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x68,0x6f,0x6c,0x69,0x29,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x72,0x62,0x64,0x6d,0x69,0x2a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x72,0x62,0x64,0x69,0x2b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x74,0x63,0x74,0x69,0x2c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x61,0x6e,0x64,0x69,0x2d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x67,0x6c,0x61,0x73,0x69,0x2e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x74,0x63,0x74,0x69,0x2f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x67,0x6c,0x61,0x69,0x30,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x74,0x68,0x64,0x72,0x69,0x31,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x6c,0x73,0x6d,0x69,0x32,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x65,0x74,0x72,0x64,0x69,0x33,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x69,0x63,0x65,0x69,0x34,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x62,0x6c,0x65,0x69,0x35,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x74,0x72,0x79,0x69,0x36,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x63,0x72,0x79,0x69,0x37,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x74,0x6b,0x6d,0x69,0x38,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x77,0x63,0x68,0x69,0x39,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x6d,0x6b,0x65,0x69,0x3a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x65,0x73,0x6c,0x69,0x3b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x63,0x6f,0x61,0x6c,0x69,0x3c,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x6c,0x6f,0x32,0x69,0x3d,0x0,0x0,0x0,0x74,0x2,0x0,0x0,0x0,0x6f,0x32,0x69,0x3e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x6e,0x77,0x72,0x69,0x3f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x79,0x65,0x73,0x74,0x69,0x40,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x79,0x73,0x74,0x69,0x41,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x74,0x68,0x72,0x6d,0x69,0x42,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x67,0x6c,0x6f,0x77,0x69,0x43,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x72,0x63,0x6b,0x69,0x44,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x68,0x66,0x6c,0x6d,0x69,0x45,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x69,0x72,0x77,0x69,0x46,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x75,0x73,0x65,0x69,0x47,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x73,0x65,0x70,0x69,0x48,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x6d,0x74,0x72,0x69,0x49,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x63,0x6f,0x6c,0x69,0x4a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x63,0x6c,0x6e,0x69,0x4b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x68,0x73,0x77,0x63,0x69,0x4c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x72,0x6f,0x6e,0x69,0x4d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x6f,0x72,0x74,0x69,0x4e,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x67,0x6f,0x6c,0x69,0x4f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x68,0x6c,0x69,0x66,0x69,0x50,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x73,0x69,0x6d,0x69,0x51,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x32,0x78,0x32,0x69,0x52,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x61,0x6e,0x69,0x69,0x53,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x6d,0x6f,0x65,0x69,0x54,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x6f,0x76,0x65,0x69,0x55,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x67,0x6f,0x6c,0x69,0x56,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x6d,0x6f,0x65,0x69,0x57,0x0,0x0,0x0,0x74,0x2,0x0,0x0,0x0,0x33,0x34,0x69,0x58,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x6c,0x69,0x66,0x69,0x59,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x74,0x61,0x6e,0x69,0x5a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x70,0x6e,0x67,0x69,0x5b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x72,0x69,0x6d,0x65,0x69,0x5c,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x66,0x6f,0x67,0x69,0x5d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x63,0x6c,0x6e,0x69,0x5e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x6f,0x76,0x65,0x69,0x5f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x65,0x75,0x74,0x69,0x60,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x61,0x72,0x70,0x69,0x61,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x75,0x6d,0x70,0x69,0x62,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x77,0x72,0x6b,0x69,0x63,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x69,0x70,0x65,0x69,0x64,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x72,0x7a,0x7a,0x69,0x65,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x72,0x7a,0x77,0x69,0x66,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x67,0x72,0x61,0x76,0x69,0x67,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x69,0x7a,0x72,0x69,0x68,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x62,0x69,0x7a,0x72,0x67,0x69,0x69,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x62,0x69,0x7a,0x72,0x73,0x69,0x6a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x6e,0x73,0x74,0x69,0x6b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x73,0x6f,0x7a,0x69,0x6c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x73,0x7a,0x73,0x69,0x6d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x72,0x74,0x69,0x69,0x6e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x72,0x74,0x6f,0x69,0x6f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x73,0x74,0x65,0x69,0x70,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x73,0x74,0x73,0x69,0x71,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x6e,0x61,0x72,0x69,0x72,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x76,0x69,0x6e,0x65,0x69,0x73,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x69,0x6e,0x76,0x69,0x73,0x69,0x74,0x0,0x0,0x0,0x74,0x8,0x0,0x0,0x0,0x65,0x71,0x75,0x61,0x6c,0x76,0x65,0x6c,0x69,0x75,0x0,0x0,0x0,0x74,0x6,0x0,0x0,0x0,0x73,0x70,0x61,0x77,0x6e,0x32,0x69,0x76,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x70,0x61,0x77,0x6e,0x69,0x77,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x68,0x6c,0x64,0x31,0x69,0x78,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x68,0x6c,0x64,0x32,0x69,0x79,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x68,0x6c,0x64,0x33,0x69,0x7a,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x68,0x6c,0x64,0x34,0x69,0x7b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x6f,0x6c,0x7a,0x69,0x7c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x69,0x66,0x69,0x69,0x7d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x69,0x6c,0x74,0x69,0x7e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x72,0x61,0x79,0x69,0x7f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x72,0x61,0x79,0x69,0x80,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x74,0x6b,0x6d,0x32,0x69,0x81,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x6f,0x6d,0x62,0x69,0x82,0x0,0x0,0x0,0x74,0x2,0x0,0x0,0x0,0x63,0x35,0x69,0x83,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x69,0x6e,0x67,0x69,0x84,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x71,0x72,0x74,0x7a,0x69,0x85,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x71,0x72,0x74,0x69,0x86,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x65,0x65,0x64,0x69,0x87,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x61,0x7a,0x65,0x69,0x88,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x63,0x6f,0x61,0x67,0x69,0x89,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x61,0x6c,0x6c,0x69,0x8a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x67,0x6e,0x61,0x72,0x69,0x8b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x72,0x65,0x70,0x6c,0x69,0x8c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x79,0x73,0x74,0x69,0x8d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x6f,0x79,0x6c,0x69,0x8e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x6f,0x74,0x65,0x69,0x8f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x72,0x67,0x32,0x69,0x90,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x74,0x61,0x72,0x69,0x91,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x72,0x6f,0x67,0x69,0x92,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x72,0x61,0x6e,0x69,0x93,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x69,0x6e,0x64,0x69,0x94,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x6e,0x75,0x6d,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x4,0x0,0x0,0x0,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0xc,0x0,0x0,0x0,0x66,0x6f,0x72,0x6b,0x5f,0x75,0x6e,0x62,0x6c,0x6f,0x63,0x6b,0x2e,0x0,0x0,0x0,0x73,0x2,0x0,0x0,0x0,0x0,0x1,0x63,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x2a,0x0,0x0,0x0,0x74,0x0,0x0,0x6a,0x1,0x0,0x83,0x0,0x0,0x1,0x74,0x0,0x0,0x6a,0x2,0x0,0x83,0x0,0x0,0x7d,0x1,0x0,0x74,0x3,0x0,0x6a,0x4,0x0,0x6a,0x5,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x6,0x0,0x0,0x0,0x74,0x9,0x0,0x0,0x0,0x74,0x72,0x61,0x63,0x65,0x62,0x61,0x63,0x6b,0x74,0x9,0x0,0x0,0x0,0x70,0x72,0x69,0x6e,0x74,0x5f,0x65,0x78,0x63,0x74,0xa,0x0,0x0,0x0,0x66,0x6f,0x72,0x6d,0x61,0x74,0x5f,0x65,0x78,0x63,0x74,0x3,0x0,0x0,0x0,0x73,0x79,0x73,0x74,0x6,0x0,0x0,0x0,0x73,0x74,0x64,0x6f,0x75,0x74,0x52,0x9,0x0,0x0,0x0,0x28,0x2,0x0,0x0,0x0,0x74,0x2,0x0,0x0,0x0,0x65,0x78,0x74,0x3,0x0,0x0,0x0,0x65,0x72,0x72,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x5,0x0,0x0,0x0,0x65,0x72,0x72,0x6f,0x72,0x30,0x0,0x0,0x0,0x73,0x6,0x0,0x0,0x0,0x0,0x1,0xa,0x1,0xc,0x1,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x19,0x0,0x0,0x0,0x74,0x0,0x0,0x83,0x0,0x0,0x74,0x1,0x0,0x5f,0x2,0x0,0x64,0x1,0x0,0x74,0x1,0x0,0x5f,0x3,0x0,0x64,0x2,0x0,0x53,0x28,0x3,0x0,0x0,0x0,0x73,0xde,0x0,0x0,0x0,0x63,0x6f,0x70,0x79,0x3d,0x5b,0x22,0x5f,0x5f,0x62,0x75,0x69,0x6c,0x74,0x69,0x6e,0x73,0x5f,0x5f,0x22,0x2c,0x22,0x5f,0x5f,0x6e,0x61,0x6d,0x65,0x5f,0x5f,0x22,0x2c,0x22,0x5f,0x5f,0x64,0x6f,0x63,0x5f,0x5f,0x22,0x2c,0x22,0x5f,0x5f,0x70,0x61,0x63,0x6b,0x61,0x67,0x65,0x5f,0x5f,0x22,0x2c,0x27,0x74,0x70,0x74,0x27,0x2c,0x27,0x63,0x6c,0x65,0x61,0x6e,0x27,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x27,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x27,0x2c,0x27,0x66,0x6f,0x72,0x6b,0x27,0x2c,0x27,0x5f,0x66,0x6f,0x72,0x6b,0x27,0x2c,0x27,0x66,0x6f,0x72,0x6b,0x5f,0x73,0x74,0x61,0x74,0x75,0x73,0x27,0x2c,0x27,0x66,0x6f,0x72,0x6b,0x5f,0x75,0x6e,0x62,0x6c,0x6f,0x63,0x6b,0x27,0x2c,0x27,0x73,0x79,0x73,0x27,0x5d,0xa,0x20,0x20,0x20,0x20,0x68,0x61,0x6e,0x64,0x6c,0x65,0x2e,0x67,0x6c,0x6f,0x62,0x3d,0x7b,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x69,0x74,0x65,0x6d,0x20,0x69,0x6e,0x20,0x63,0x6f,0x70,0x79,0x3a,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x68,0x61,0x6e,0x64,0x6c,0x65,0x2e,0x67,0x6c,0x6f,0x62,0x5b,0x69,0x74,0x65,0x6d,0x5d,0x3d,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x73,0x28,0x29,0x5b,0x69,0x74,0x65,0x6d,0x5d,0x74,0x0,0x0,0x0,0x0,0x4e,0x28,0x4,0x0,0x0,0x0,0x74,0x7,0x0,0x0,0x0,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x73,0x74,0x6,0x0,0x0,0x0,0x68,0x61,0x6e,0x64,0x6c,0x65,0x74,0x4,0x0,0x0,0x0,0x67,0x6c,0x6f,0x62,0x74,0x3,0x0,0x0,0x0,0x62,0x75,0x66,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x5,0x0,0x0,0x0,0x63,0x6c,0x65,0x61,0x6e,0x35,0x0,0x0,0x0,0x73,0x4,0x0,0x0,0x0,0x0,0x7,0xc,0x1,0x63,0x1,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x5,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x50,0x0,0x0,0x0,0x79,0xd,0x0,0x74,0x0,0x0,0x6a,0x1,0x0,0x7d,0x1,0x0,0x57,0x6e,0xe,0x0,0x1,0x1,0x1,0x74,0x2,0x0,0x83,0x0,0x0,0x1,0x6e,0x1,0x0,0x58,0x79,0xe,0x0,0x74,0x3,0x0,0x7c,0x0,0x0,0x83,0x1,0x0,0x1,0x57,0x6e,0x1d,0x0,0x4,0x74,0x4,0x0,0x6b,0xa,0x0,0x72,0x4b,0x0,0x1,0x7d,0x2,0x0,0x1,0x74,0x5,0x0,0x7c,0x2,0x0,0x83,0x1,0x0,0x1,0x6e,0x1,0x0,0x58,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x6,0x0,0x0,0x0,0x52,0xac,0x0,0x0,0x0,0x52,0xad,0x0,0x0,0x0,0x52,0xaf,0x0,0x0,0x0,0x74,0x7,0x0,0x0,0x0,0x5f,0x68,0x61,0x6e,0x64,0x6c,0x65,0x74,0x9,0x0,0x0,0x0,0x45,0x78,0x63,0x65,0x70,0x74,0x69,0x6f,0x6e,0x52,0xa9,0x0,0x0,0x0,0x28,0x3,0x0,0x0,0x0,0x52,0x8,0x0,0x0,0x0,0x74,0x1,0x0,0x0,0x0,0x61,0x52,0xa7,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x52,0xac,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x73,0x10,0x0,0x0,0x0,0x0,0x1,0x3,0x1,0xd,0x1,0x3,0x1,0xb,0x1,0x3,0x1,0xe,0x1,0xf,0x1,0x63,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x5,0x0,0x0,0x0,0x42,0x0,0x0,0x0,0x73,0x63,0x0,0x0,0x0,0x79,0x26,0x0,0x65,0x0,0x0,0x6a,0x1,0x0,0x6a,0x2,0x0,0x65,0x3,0x0,0x65,0x4,0x0,0x7c,0x0,0x0,0x65,0x5,0x0,0x6a,0x6,0x0,0x83,0x2,0x0,0x83,0x1,0x0,0x83,0x1,0x0,0x1,0x57,0x6e,0x36,0x0,0x1,0x1,0x1,0x79,0xf,0x0,0x7c,0x0,0x0,0x65,0x5,0x0,0x6a,0x6,0x0,0x4,0x55,0x57,0x71,0x5f,0x0,0x4,0x65,0x7,0x0,0x6b,0xa,0x0,0x72,0x5a,0x0,0x1,0x7d,0x1,0x0,0x1,0x65,0x8,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x71,0x5f,0x0,0x58,0x6e,0x1,0x0,0x58,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x9,0x0,0x0,0x0,0x52,0xa5,0x0,0x0,0x0,0x52,0xa6,0x0,0x0,0x0,0x52,0x9,0x0,0x0,0x0,0x52,0x4,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x65,0x76,0x61,0x6c,0x52,0xac,0x0,0x0,0x0,0x52,0xad,0x0,0x0,0x0,0x52,0xb1,0x0,0x0,0x0,0x52,0xa9,0x0,0x0,0x0,0x28,0x2,0x0,0x0,0x0,0x52,0x8,0x0,0x0,0x0,0x52,0xa7,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x52,0xb0,0x0,0x0,0x0,0x49,0x0,0x0,0x0,0x73,0xe,0x0,0x0,0x0,0x0,0x2,0x3,0x1,0x26,0x1,0x3,0x1,0x3,0x1,0xf,0x1,0xf,0x1,0x63,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x27,0x0,0x0,0x0,0x74,0x0,0x0,0x7c,0x0,0x0,0x83,0x1,0x0,0x7d,0x1,0x0,0x7c,0x1,0x0,0x6a,0x1,0x0,0x83,0x0,0x0,0x1,0x74,0x2,0x0,0x6a,0x3,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x4,0x0,0x0,0x0,0x74,0xa,0x0,0x0,0x0,0x5f,0x5f,0x69,0x6d,0x70,0x6f,0x72,0x74,0x5f,0x5f,0x74,0x4,0x0,0x0,0x0,0x69,0x6e,0x69,0x74,0x74,0xb,0x0,0x0,0x0,0x5f,0x65,0x78,0x74,0x65,0x6e,0x73,0x69,0x6f,0x6e,0x73,0x74,0x6,0x0,0x0,0x0,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x2,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x66,0x6e,0x61,0x6d,0x65,0x74,0x3,0x0,0x0,0x0,0x65,0x78,0x74,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x7,0x0,0x0,0x0,0x6c,0x6f,0x61,0x64,0x65,0x78,0x74,0x55,0x0,0x0,0x0,0x73,0x6,0x0,0x0,0x0,0x0,0x1,0xc,0x1,0xa,0x1,0x63,0x1,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x81,0x0,0x0,0x0,0x67,0x0,0x0,0x7d,0x1,0x0,0x78,0x4c,0x0,0x74,0x0,0x0,0x44,0x5d,0x44,0x0,0x7d,0x2,0x0,0x79,0x11,0x0,0x7c,0x2,0x0,0x6a,0x1,0x0,0x7c,0x0,0x0,0x83,0x1,0x0,0x1,0x57,0x71,0xd,0x0,0x4,0x74,0x2,0x0,0x6b,0xa,0x0,0x72,0x50,0x0,0x1,0x7d,0x3,0x0,0x1,0x74,0x3,0x0,0x7c,0x3,0x0,0x83,0x1,0x0,0x1,0x7c,0x1,0x0,0x6a,0x4,0x0,0x7c,0x2,0x0,0x83,0x1,0x0,0x1,0x71,0xd,0x0,0x58,0x71,0xd,0x0,0x57,0x78,0x25,0x0,0x7c,0x1,0x0,0x44,0x5d,0x1d,0x0,0x7d,0x2,0x0,0x7c,0x2,0x0,0x6a,0x5,0x0,0x83,0x0,0x0,0x1,0x74,0x0,0x0,0x6a,0x6,0x0,0x7c,0x2,0x0,0x83,0x1,0x0,0x1,0x71,0x5c,0x0,0x57,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x7,0x0,0x0,0x0,0x52,0xb6,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x6b,0x65,0x79,0x52,0xb1,0x0,0x0,0x0,0x52,0xa9,0x0,0x0,0x0,0x52,0xb7,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x65,0x78,0x69,0x74,0x74,0x6,0x0,0x0,0x0,0x72,0x65,0x6d,0x6f,0x76,0x65,0x28,0x4,0x0,0x0,0x0,0x52,0xbb,0x0,0x0,0x0,0x74,0x6,0x0,0x0,0x0,0x75,0x6e,0x6c,0x6f,0x61,0x64,0x74,0x4,0x0,0x0,0x0,0x69,0x74,0x65,0x6d,0x52,0xa7,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x8,0x0,0x0,0x0,0x6b,0x65,0x79,0x70,0x72,0x65,0x73,0x73,0x5a,0x0,0x0,0x0,0x73,0x14,0x0,0x0,0x0,0x0,0x1,0x6,0x1,0xd,0x1,0x3,0x1,0x11,0x1,0xf,0x1,0xa,0x1,0x15,0x1,0xd,0x1,0xa,0x1,0x63,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0xa2,0x0,0x0,0x0,0x67,0x0,0x0,0x7d,0x0,0x0,0x78,0x49,0x0,0x74,0x0,0x0,0x44,0x5d,0x41,0x0,0x7d,0x1,0x0,0x79,0xe,0x0,0x7c,0x1,0x0,0x6a,0x1,0x0,0x83,0x0,0x0,0x1,0x57,0x71,0xd,0x0,0x4,0x74,0x2,0x0,0x6b,0xa,0x0,0x72,0x4d,0x0,0x1,0x7d,0x2,0x0,0x1,0x74,0x3,0x0,0x7c,0x2,0x0,0x83,0x1,0x0,0x1,0x7c,0x0,0x0,0x6a,0x4,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x71,0xd,0x0,0x58,0x71,0xd,0x0,0x57,0x78,0x49,0x0,0x7c,0x0,0x0,0x44,0x5d,0x41,0x0,0x7d,0x1,0x0,0x79,0xe,0x0,0x7c,0x1,0x0,0x6a,0x5,0x0,0x83,0x0,0x0,0x1,0x57,0x6e,0x1d,0x0,0x4,0x74,0x2,0x0,0x6b,0xa,0x0,0x72,0x8c,0x0,0x1,0x7d,0x2,0x0,0x1,0x74,0x3,0x0,0x7c,0x2,0x0,0x83,0x1,0x0,0x1,0x6e,0x1,0x0,0x58,0x74,0x0,0x0,0x6a,0x6,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x71,0x59,0x0,0x57,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x7,0x0,0x0,0x0,0x52,0xb6,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x74,0x65,0x70,0x52,0xb1,0x0,0x0,0x0,0x52,0xa9,0x0,0x0,0x0,0x52,0xb7,0x0,0x0,0x0,0x52,0xbc,0x0,0x0,0x0,0x52,0xbd,0x0,0x0,0x0,0x28,0x3,0x0,0x0,0x0,0x52,0xbe,0x0,0x0,0x0,0x52,0xbf,0x0,0x0,0x0,0x52,0xa7,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x52,0xc1,0x0,0x0,0x0,0x67,0x0,0x0,0x0,0x73,0x1a,0x0,0x0,0x0,0x0,0x1,0x6,0x1,0xd,0x1,0x3,0x1,0xe,0x1,0xf,0x1,0xa,0x1,0x15,0x1,0xd,0x1,0x3,0x1,0xe,0x1,0xf,0x1,0xe,0x1,0x28,0x0,0x0,0x0,0x0,0x28,0x14,0x0,0x0,0x0,0x52,0x5,0x0,0x0,0x0,0x52,0xa5,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x63,0x6f,0x64,0x65,0x74,0x6,0x0,0x0,0x0,0x63,0x74,0x79,0x70,0x65,0x73,0x52,0xa2,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x46,0x61,0x6c,0x73,0x65,0x74,0x5,0x0,0x0,0x0,0x44,0x45,0x42,0x55,0x47,0x52,0x1,0x0,0x0,0x0,0x52,0xa6,0x0,0x0,0x0,0x74,0x6,0x0,0x0,0x0,0x73,0x74,0x64,0x65,0x72,0x72,0x74,0x7,0x0,0x0,0x0,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x52,0xa1,0x0,0x0,0x0,0x52,0xa9,0x0,0x0,0x0,0x52,0xaf,0x0,0x0,0x0,0x52,0xac,0x0,0x0,0x0,0x52,0xb0,0x0,0x0,0x0,0x52,0xb6,0x0,0x0,0x0,0x52,0xba,0x0,0x0,0x0,0x52,0xc0,0x0,0x0,0x0,0x52,0xc1,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x8,0x0,0x0,0x0,0x3c,0x6d,0x6f,0x64,0x75,0x6c,0x65,0x3e,0x1,0x0,0x0,0x0,0x73,0x54,0x0,0x0,0x0,0xc,0x1,0xa,0x1,0xc,0x1,0xc,0x1,0xc,0x1,0xc,0x1,0x6,0x4,0x13,0x5,0xc,0x1,0xc,0x1,0xf,0x3,0x3b,0x1,0x38,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0xa,0x3,0x9,0x2,0x9,0x5,0x9,0xa,0x9,0xa,0x9,0xb,0x6,0x1,0x9,0x5,0x9,0xd}; \ No newline at end of file +unsigned char tpt_console_pyc[] = {0x3,0xf3,0xd,0xa,0x6f,0xc4,0x84,0x4d,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x73,0xf1,0x4,0x0,0x0,0x64,0x0,0x0,0x64,0x1,0x0,0x6c,0x0,0x0,0x5a,0x0,0x0,0x64,0x0,0x0,0x64,0x2,0x0,0x6c,0x0,0x0,0x54,0x64,0x0,0x0,0x64,0x1,0x0,0x6c,0x1,0x0,0x5a,0x1,0x0,0x64,0x0,0x0,0x64,0x1,0x0,0x6c,0x2,0x0,0x5a,0x2,0x0,0x64,0x0,0x0,0x64,0x1,0x0,0x6c,0x3,0x0,0x5a,0x3,0x0,0x64,0x0,0x0,0x64,0x1,0x0,0x6c,0x4,0x0,0x5a,0x4,0x0,0x65,0x5,0x0,0x5a,0x6,0x0,0x64,0x3,0x0,0x64,0x37,0x1,0x64,0x4,0x0,0x84,0x0,0x0,0x83,0x0,0x0,0x59,0x5a,0x7,0x0,0x65,0x6,0x0,0x65,0x5,0x0,0x6b,0x2,0x0,0x72,0x86,0x0,0x65,0x7,0x0,0x83,0x0,0x0,0x65,0x1,0x0,0x5f,0x8,0x0,0x65,0x7,0x0,0x83,0x0,0x0,0x65,0x1,0x0,0x5f,0x9,0x0,0x6e,0x0,0x0,0x69,0x95,0x0,0x64,0x5,0x0,0x64,0x6,0x0,0x36,0x64,0x7,0x0,0x64,0x8,0x0,0x36,0x64,0x9,0x0,0x64,0xa,0x0,0x36,0x64,0xb,0x0,0x64,0xc,0x0,0x36,0x64,0xd,0x0,0x64,0xe,0x0,0x36,0x64,0xf,0x0,0x64,0x10,0x0,0x36,0x64,0x11,0x0,0x64,0x12,0x0,0x36,0x64,0x13,0x0,0x64,0x14,0x0,0x36,0x64,0x15,0x0,0x64,0x16,0x0,0x36,0x64,0x17,0x0,0x64,0x18,0x0,0x36,0x64,0x19,0x0,0x64,0x1a,0x0,0x36,0x64,0x1b,0x0,0x64,0x1c,0x0,0x36,0x64,0x1d,0x0,0x64,0x1e,0x0,0x36,0x64,0x1f,0x0,0x64,0x20,0x0,0x36,0x64,0x21,0x0,0x64,0x22,0x0,0x36,0x64,0x23,0x0,0x64,0x24,0x0,0x36,0x64,0x25,0x0,0x64,0x26,0x0,0x36,0x64,0x27,0x0,0x64,0x28,0x0,0x36,0x64,0x29,0x0,0x64,0x2a,0x0,0x36,0x64,0x2b,0x0,0x64,0x2c,0x0,0x36,0x64,0x2d,0x0,0x64,0x2e,0x0,0x36,0x64,0x2f,0x0,0x64,0x30,0x0,0x36,0x64,0x31,0x0,0x64,0x32,0x0,0x36,0x64,0x33,0x0,0x64,0x34,0x0,0x36,0x64,0x35,0x0,0x64,0x36,0x0,0x36,0x64,0x37,0x0,0x64,0x38,0x0,0x36,0x64,0x39,0x0,0x64,0x3a,0x0,0x36,0x64,0x3b,0x0,0x64,0x3c,0x0,0x36,0x64,0x3d,0x0,0x64,0x3e,0x0,0x36,0x64,0x3f,0x0,0x64,0x40,0x0,0x36,0x64,0x41,0x0,0x64,0x42,0x0,0x36,0x64,0x43,0x0,0x64,0x44,0x0,0x36,0x64,0x45,0x0,0x64,0x46,0x0,0x36,0x64,0x47,0x0,0x64,0x48,0x0,0x36,0x64,0x49,0x0,0x64,0x4a,0x0,0x36,0x64,0x4b,0x0,0x64,0x4c,0x0,0x36,0x64,0x4d,0x0,0x64,0x4e,0x0,0x36,0x64,0x4f,0x0,0x64,0x50,0x0,0x36,0x64,0x51,0x0,0x64,0x52,0x0,0x36,0x64,0x53,0x0,0x64,0x54,0x0,0x36,0x64,0x55,0x0,0x64,0x56,0x0,0x36,0x64,0x57,0x0,0x64,0x58,0x0,0x36,0x64,0x59,0x0,0x64,0x5a,0x0,0x36,0x64,0x5b,0x0,0x64,0x5c,0x0,0x36,0x64,0x5d,0x0,0x64,0x5e,0x0,0x36,0x64,0x5f,0x0,0x64,0x60,0x0,0x36,0x64,0x61,0x0,0x64,0x62,0x0,0x36,0x64,0x63,0x0,0x64,0x64,0x0,0x36,0x64,0x65,0x0,0x64,0x66,0x0,0x36,0x64,0x67,0x0,0x64,0x68,0x0,0x36,0x64,0x69,0x0,0x64,0x6a,0x0,0x36,0x64,0x6b,0x0,0x64,0x6c,0x0,0x36,0x64,0x6d,0x0,0x64,0x6e,0x0,0x36,0x64,0x6f,0x0,0x64,0x70,0x0,0x36,0x64,0x71,0x0,0x64,0x72,0x0,0x36,0x64,0x73,0x0,0x64,0x74,0x0,0x36,0x64,0x75,0x0,0x64,0x76,0x0,0x36,0x64,0x77,0x0,0x64,0x78,0x0,0x36,0x64,0x79,0x0,0x64,0x7a,0x0,0x36,0x64,0x7b,0x0,0x64,0x7c,0x0,0x36,0x64,0x7d,0x0,0x64,0x7e,0x0,0x36,0x64,0x7f,0x0,0x64,0x80,0x0,0x36,0x64,0x81,0x0,0x64,0x82,0x0,0x36,0x64,0x83,0x0,0x64,0x84,0x0,0x36,0x64,0x85,0x0,0x64,0x86,0x0,0x36,0x64,0x87,0x0,0x64,0x88,0x0,0x36,0x64,0x89,0x0,0x64,0x8a,0x0,0x36,0x64,0x8b,0x0,0x64,0x8c,0x0,0x36,0x64,0x8d,0x0,0x64,0x8e,0x0,0x36,0x64,0x8f,0x0,0x64,0x90,0x0,0x36,0x64,0x91,0x0,0x64,0x92,0x0,0x36,0x64,0x93,0x0,0x64,0x94,0x0,0x36,0x64,0x95,0x0,0x64,0x96,0x0,0x36,0x64,0x97,0x0,0x64,0x98,0x0,0x36,0x64,0x99,0x0,0x64,0x9a,0x0,0x36,0x64,0x9b,0x0,0x64,0x9c,0x0,0x36,0x64,0x9d,0x0,0x64,0x9e,0x0,0x36,0x64,0x9f,0x0,0x64,0xa0,0x0,0x36,0x64,0xa1,0x0,0x64,0xa2,0x0,0x36,0x64,0xa3,0x0,0x64,0xa4,0x0,0x36,0x64,0xa5,0x0,0x64,0xa6,0x0,0x36,0x64,0xa7,0x0,0x64,0xa8,0x0,0x36,0x64,0xa9,0x0,0x64,0xaa,0x0,0x36,0x64,0xab,0x0,0x64,0xac,0x0,0x36,0x64,0xad,0x0,0x64,0xae,0x0,0x36,0x64,0xaf,0x0,0x64,0xb0,0x0,0x36,0x64,0xb1,0x0,0x64,0xb2,0x0,0x36,0x64,0xb3,0x0,0x64,0xb4,0x0,0x36,0x64,0xb5,0x0,0x64,0xb6,0x0,0x36,0x64,0xb7,0x0,0x64,0xb8,0x0,0x36,0x64,0xb9,0x0,0x64,0xba,0x0,0x36,0x64,0xbb,0x0,0x64,0xbc,0x0,0x36,0x64,0xbd,0x0,0x64,0xbe,0x0,0x36,0x64,0xbf,0x0,0x64,0xc0,0x0,0x36,0x64,0xc1,0x0,0x64,0xc2,0x0,0x36,0x64,0xc3,0x0,0x64,0xc4,0x0,0x36,0x64,0xc5,0x0,0x64,0xc6,0x0,0x36,0x64,0xc7,0x0,0x64,0xc8,0x0,0x36,0x64,0xc9,0x0,0x64,0xca,0x0,0x36,0x64,0xcb,0x0,0x64,0xcc,0x0,0x36,0x64,0xcd,0x0,0x64,0xce,0x0,0x36,0x64,0xcf,0x0,0x64,0xd0,0x0,0x36,0x64,0xd1,0x0,0x64,0xd2,0x0,0x36,0x64,0xd3,0x0,0x64,0xd4,0x0,0x36,0x64,0xd5,0x0,0x64,0xd6,0x0,0x36,0x64,0xd7,0x0,0x64,0xd8,0x0,0x36,0x64,0xd9,0x0,0x64,0xda,0x0,0x36,0x64,0xdb,0x0,0x64,0xdc,0x0,0x36,0x64,0xdd,0x0,0x64,0xde,0x0,0x36,0x64,0xdf,0x0,0x64,0xe0,0x0,0x36,0x64,0xe1,0x0,0x64,0xe2,0x0,0x36,0x64,0xe3,0x0,0x64,0xe4,0x0,0x36,0x64,0xe5,0x0,0x64,0xe6,0x0,0x36,0x64,0xe7,0x0,0x64,0xe8,0x0,0x36,0x64,0xe9,0x0,0x64,0xea,0x0,0x36,0x64,0xeb,0x0,0x64,0xec,0x0,0x36,0x64,0xed,0x0,0x64,0xee,0x0,0x36,0x64,0xef,0x0,0x64,0xf0,0x0,0x36,0x64,0xf1,0x0,0x64,0xf2,0x0,0x36,0x64,0xf3,0x0,0x64,0xf4,0x0,0x36,0x64,0xf5,0x0,0x64,0xf6,0x0,0x36,0x64,0xf7,0x0,0x64,0xf8,0x0,0x36,0x64,0xf9,0x0,0x64,0xfa,0x0,0x36,0x64,0xfb,0x0,0x64,0xfc,0x0,0x36,0x64,0xfd,0x0,0x64,0xfe,0x0,0x36,0x64,0xff,0x0,0x64,0x0,0x1,0x36,0x64,0x1,0x1,0x64,0x2,0x1,0x36,0x64,0x3,0x1,0x64,0x4,0x1,0x36,0x64,0x5,0x1,0x64,0x6,0x1,0x36,0x64,0x7,0x1,0x64,0x8,0x1,0x36,0x64,0x9,0x1,0x64,0xa,0x1,0x36,0x64,0xb,0x1,0x64,0xc,0x1,0x36,0x64,0xd,0x1,0x64,0xe,0x1,0x36,0x64,0xf,0x1,0x64,0x10,0x1,0x36,0x64,0x11,0x1,0x64,0x12,0x1,0x36,0x64,0x13,0x1,0x64,0x14,0x1,0x36,0x64,0x15,0x1,0x64,0x16,0x1,0x36,0x64,0x17,0x1,0x64,0x18,0x1,0x36,0x64,0x19,0x1,0x64,0x1a,0x1,0x36,0x64,0x1b,0x1,0x64,0x1c,0x1,0x36,0x64,0x1d,0x1,0x64,0x1e,0x1,0x36,0x64,0x1f,0x1,0x64,0x20,0x1,0x36,0x64,0x21,0x1,0x64,0x22,0x1,0x36,0x64,0x23,0x1,0x64,0x24,0x1,0x36,0x64,0x25,0x1,0x64,0x26,0x1,0x36,0x64,0x27,0x1,0x64,0x28,0x1,0x36,0x64,0x29,0x1,0x64,0x2a,0x1,0x36,0x64,0x2b,0x1,0x64,0x2c,0x1,0x36,0x64,0x2d,0x1,0x64,0x2e,0x1,0x36,0x5a,0xa,0x0,0x64,0x2f,0x1,0x84,0x0,0x0,0x5a,0xb,0x0,0x64,0x30,0x1,0x84,0x0,0x0,0x5a,0xc,0x0,0x64,0x31,0x1,0x84,0x0,0x0,0x5a,0xd,0x0,0x64,0x32,0x1,0x84,0x0,0x0,0x5a,0xe,0x0,0x64,0x33,0x1,0x84,0x0,0x0,0x5a,0xf,0x0,0x67,0x0,0x0,0x5a,0x10,0x0,0x64,0x34,0x1,0x84,0x0,0x0,0x5a,0x11,0x0,0x64,0x35,0x1,0x84,0x0,0x0,0x5a,0x12,0x0,0x64,0x36,0x1,0x84,0x0,0x0,0x5a,0x13,0x0,0x64,0x1,0x0,0x53,0x28,0x38,0x1,0x0,0x0,0x69,0xff,0xff,0xff,0xff,0x4e,0x28,0x1,0x0,0x0,0x0,0x74,0x1,0x0,0x0,0x0,0x2a,0x74,0x6,0x0,0x0,0x0,0x6c,0x6f,0x67,0x67,0x65,0x72,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x42,0x0,0x0,0x0,0x73,0x11,0x0,0x0,0x0,0x65,0x0,0x0,0x5a,0x1,0x0,0x64,0x0,0x0,0x84,0x0,0x0,0x5a,0x2,0x0,0x52,0x53,0x28,0x1,0x0,0x0,0x0,0x63,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x34,0x0,0x0,0x0,0x7c,0x1,0x0,0x6a,0x0,0x0,0x83,0x0,0x0,0x6a,0x1,0x0,0x64,0x1,0x0,0x83,0x1,0x0,0x64,0x2,0x0,0x19,0x7d,0x1,0x0,0x74,0x2,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x74,0x3,0x0,0x6a,0x4,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x64,0x0,0x0,0x53,0x28,0x3,0x0,0x0,0x0,0x4e,0x73,0x1,0x0,0x0,0x0,0xa,0x69,0xff,0xff,0xff,0xff,0x28,0x5,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x74,0x72,0x69,0x70,0x74,0x5,0x0,0x0,0x0,0x73,0x70,0x6c,0x69,0x74,0x74,0x4,0x0,0x0,0x0,0x72,0x65,0x70,0x72,0x74,0x3,0x0,0x0,0x0,0x74,0x70,0x74,0x74,0x3,0x0,0x0,0x0,0x6c,0x6f,0x67,0x28,0x2,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x65,0x6c,0x66,0x74,0x3,0x0,0x0,0x0,0x74,0x78,0x74,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x5,0x0,0x0,0x0,0x77,0x72,0x69,0x74,0x65,0xc,0x0,0x0,0x0,0x73,0x6,0x0,0x0,0x0,0x0,0x1,0x19,0x1,0xa,0x1,0x28,0x3,0x0,0x0,0x0,0x74,0x8,0x0,0x0,0x0,0x5f,0x5f,0x6e,0x61,0x6d,0x65,0x5f,0x5f,0x74,0xa,0x0,0x0,0x0,0x5f,0x5f,0x6d,0x6f,0x64,0x75,0x6c,0x65,0x5f,0x5f,0x52,0x9,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x52,0x1,0x0,0x0,0x0,0xb,0x0,0x0,0x0,0x73,0x2,0x0,0x0,0x0,0x6,0x1,0x69,0x0,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x6f,0x6e,0x65,0x69,0x1,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x75,0x73,0x74,0x69,0x2,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x61,0x74,0x72,0x69,0x3,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x6f,0x69,0x6c,0x69,0x4,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x69,0x72,0x65,0x69,0x5,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x74,0x6e,0x65,0x69,0x6,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x61,0x76,0x61,0x69,0x7,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x67,0x75,0x6e,0x70,0x69,0x8,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x69,0x74,0x72,0x69,0x9,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x63,0x6c,0x6e,0x65,0x69,0xa,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x67,0x61,0x73,0x69,0xb,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x6c,0x65,0x78,0x69,0xc,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x67,0x6f,0x6f,0x69,0xd,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x63,0x65,0x69,0x69,0xe,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x65,0x74,0x6c,0x69,0xf,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x70,0x72,0x6b,0x69,0x10,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x6e,0x6f,0x77,0x69,0x11,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x6f,0x6f,0x64,0x69,0x12,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x65,0x75,0x74,0x69,0x13,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x6c,0x75,0x74,0x69,0x14,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x6c,0x6e,0x74,0x69,0x15,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x63,0x69,0x64,0x69,0x16,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x76,0x6f,0x69,0x64,0x69,0x17,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x74,0x72,0x76,0x69,0x18,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x63,0x6e,0x63,0x74,0x69,0x19,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x73,0x74,0x77,0x69,0x1a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x61,0x6c,0x74,0x69,0x1b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x6c,0x74,0x77,0x69,0x1c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x6d,0x6e,0x64,0x69,0x1d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x6d,0x74,0x6c,0x69,0x1e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x72,0x6d,0x74,0x69,0x1f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x68,0x6f,0x74,0x69,0x20,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x75,0x72,0x61,0x6e,0x69,0x21,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x77,0x61,0x78,0x69,0x22,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x77,0x61,0x78,0x69,0x23,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x73,0x63,0x6e,0x69,0x24,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x73,0x63,0x6e,0x69,0x25,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x6e,0x74,0x67,0x69,0x26,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x6e,0x73,0x6c,0x69,0x27,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x68,0x6f,0x6c,0x69,0x28,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x68,0x6f,0x6c,0x69,0x29,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x72,0x62,0x64,0x6d,0x69,0x2a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x72,0x62,0x64,0x69,0x2b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x74,0x63,0x74,0x69,0x2c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x61,0x6e,0x64,0x69,0x2d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x67,0x6c,0x61,0x73,0x69,0x2e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x74,0x63,0x74,0x69,0x2f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x67,0x6c,0x61,0x69,0x30,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x74,0x68,0x64,0x72,0x69,0x31,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x6c,0x73,0x6d,0x69,0x32,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x65,0x74,0x72,0x64,0x69,0x33,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x69,0x63,0x65,0x69,0x34,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6e,0x62,0x6c,0x65,0x69,0x35,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x74,0x72,0x79,0x69,0x36,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x63,0x72,0x79,0x69,0x37,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x74,0x6b,0x6d,0x69,0x38,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x77,0x63,0x68,0x69,0x39,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x6d,0x6b,0x65,0x69,0x3a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x65,0x73,0x6c,0x69,0x3b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x63,0x6f,0x61,0x6c,0x69,0x3c,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x6c,0x6f,0x32,0x69,0x3d,0x0,0x0,0x0,0x74,0x2,0x0,0x0,0x0,0x6f,0x32,0x69,0x3e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x6e,0x77,0x72,0x69,0x3f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x79,0x65,0x73,0x74,0x69,0x40,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x79,0x73,0x74,0x69,0x41,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x74,0x68,0x72,0x6d,0x69,0x42,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x67,0x6c,0x6f,0x77,0x69,0x43,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x72,0x63,0x6b,0x69,0x44,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x68,0x66,0x6c,0x6d,0x69,0x45,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x69,0x72,0x77,0x69,0x46,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x75,0x73,0x65,0x69,0x47,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x73,0x65,0x70,0x69,0x48,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x6d,0x74,0x72,0x69,0x49,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x63,0x6f,0x6c,0x69,0x4a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x63,0x6c,0x6e,0x69,0x4b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x68,0x73,0x77,0x63,0x69,0x4c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x72,0x6f,0x6e,0x69,0x4d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x6f,0x72,0x74,0x69,0x4e,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x67,0x6f,0x6c,0x69,0x4f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x68,0x6c,0x69,0x66,0x69,0x50,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x73,0x69,0x6d,0x69,0x51,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x32,0x78,0x32,0x69,0x52,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x61,0x6e,0x69,0x69,0x53,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x6d,0x6f,0x65,0x69,0x54,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x6f,0x76,0x65,0x69,0x55,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x67,0x6f,0x6c,0x69,0x56,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x6d,0x6f,0x65,0x69,0x57,0x0,0x0,0x0,0x74,0x2,0x0,0x0,0x0,0x33,0x34,0x69,0x58,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x6c,0x69,0x66,0x69,0x59,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x74,0x61,0x6e,0x69,0x5a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x70,0x6e,0x67,0x69,0x5b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x72,0x69,0x6d,0x65,0x69,0x5c,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x66,0x6f,0x67,0x69,0x5d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x63,0x6c,0x6e,0x69,0x5e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x6f,0x76,0x65,0x69,0x5f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x64,0x65,0x75,0x74,0x69,0x60,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x61,0x72,0x70,0x69,0x61,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x75,0x6d,0x70,0x69,0x62,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x77,0x72,0x6b,0x69,0x63,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x69,0x70,0x65,0x69,0x64,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x72,0x7a,0x7a,0x69,0x65,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x72,0x7a,0x77,0x69,0x66,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x67,0x72,0x61,0x76,0x69,0x67,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x69,0x7a,0x72,0x69,0x68,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x62,0x69,0x7a,0x72,0x67,0x69,0x69,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x62,0x69,0x7a,0x72,0x73,0x69,0x6a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x6e,0x73,0x74,0x69,0x6b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x73,0x6f,0x7a,0x69,0x6c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x69,0x73,0x7a,0x73,0x69,0x6d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x72,0x74,0x69,0x69,0x6e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x72,0x74,0x6f,0x69,0x6f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x73,0x74,0x65,0x69,0x70,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x73,0x74,0x73,0x69,0x71,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x6e,0x61,0x72,0x69,0x72,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x76,0x69,0x6e,0x65,0x69,0x73,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x69,0x6e,0x76,0x69,0x73,0x69,0x74,0x0,0x0,0x0,0x74,0x8,0x0,0x0,0x0,0x65,0x71,0x75,0x61,0x6c,0x76,0x65,0x6c,0x69,0x75,0x0,0x0,0x0,0x74,0x6,0x0,0x0,0x0,0x73,0x70,0x61,0x77,0x6e,0x32,0x69,0x76,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x70,0x61,0x77,0x6e,0x69,0x77,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x68,0x6c,0x64,0x31,0x69,0x78,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x68,0x6c,0x64,0x32,0x69,0x79,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x68,0x6c,0x64,0x33,0x69,0x7a,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x68,0x6c,0x64,0x34,0x69,0x7b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x6f,0x6c,0x7a,0x69,0x7c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x69,0x66,0x69,0x69,0x7d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x69,0x6c,0x74,0x69,0x7e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x61,0x72,0x61,0x79,0x69,0x7f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x72,0x61,0x79,0x69,0x80,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x73,0x74,0x6b,0x6d,0x32,0x69,0x81,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x6f,0x6d,0x62,0x69,0x82,0x0,0x0,0x0,0x74,0x2,0x0,0x0,0x0,0x63,0x35,0x69,0x83,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x69,0x6e,0x67,0x69,0x84,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x71,0x72,0x74,0x7a,0x69,0x85,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x70,0x71,0x72,0x74,0x69,0x86,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x65,0x65,0x64,0x69,0x87,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x61,0x7a,0x65,0x69,0x88,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x63,0x6f,0x61,0x67,0x69,0x89,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x61,0x6c,0x6c,0x69,0x8a,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x67,0x6e,0x61,0x72,0x69,0x8b,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x72,0x65,0x70,0x6c,0x69,0x8c,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6d,0x79,0x73,0x74,0x69,0x8d,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x6f,0x79,0x6c,0x69,0x8e,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x6c,0x6f,0x74,0x65,0x69,0x8f,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x72,0x67,0x32,0x69,0x90,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x74,0x61,0x72,0x69,0x91,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x66,0x72,0x6f,0x67,0x69,0x92,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x62,0x72,0x61,0x6e,0x69,0x93,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x77,0x69,0x6e,0x64,0x69,0x94,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x6e,0x75,0x6d,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x4,0x0,0x0,0x0,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0xc,0x0,0x0,0x0,0x66,0x6f,0x72,0x6b,0x5f,0x75,0x6e,0x62,0x6c,0x6f,0x63,0x6b,0x2f,0x0,0x0,0x0,0x73,0x2,0x0,0x0,0x0,0x0,0x1,0x63,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x2a,0x0,0x0,0x0,0x74,0x0,0x0,0x6a,0x1,0x0,0x83,0x0,0x0,0x1,0x74,0x0,0x0,0x6a,0x2,0x0,0x83,0x0,0x0,0x7d,0x1,0x0,0x74,0x3,0x0,0x6a,0x4,0x0,0x6a,0x5,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x6,0x0,0x0,0x0,0x74,0x9,0x0,0x0,0x0,0x74,0x72,0x61,0x63,0x65,0x62,0x61,0x63,0x6b,0x74,0x9,0x0,0x0,0x0,0x70,0x72,0x69,0x6e,0x74,0x5f,0x65,0x78,0x63,0x74,0xa,0x0,0x0,0x0,0x66,0x6f,0x72,0x6d,0x61,0x74,0x5f,0x65,0x78,0x63,0x74,0x3,0x0,0x0,0x0,0x73,0x79,0x73,0x74,0x6,0x0,0x0,0x0,0x73,0x74,0x64,0x6f,0x75,0x74,0x52,0x9,0x0,0x0,0x0,0x28,0x2,0x0,0x0,0x0,0x74,0x2,0x0,0x0,0x0,0x65,0x78,0x74,0x3,0x0,0x0,0x0,0x65,0x72,0x72,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x5,0x0,0x0,0x0,0x65,0x72,0x72,0x6f,0x72,0x31,0x0,0x0,0x0,0x73,0x6,0x0,0x0,0x0,0x0,0x1,0xa,0x1,0xc,0x1,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x19,0x0,0x0,0x0,0x74,0x0,0x0,0x83,0x0,0x0,0x74,0x1,0x0,0x5f,0x2,0x0,0x64,0x1,0x0,0x74,0x1,0x0,0x5f,0x3,0x0,0x64,0x2,0x0,0x53,0x28,0x3,0x0,0x0,0x0,0x73,0xde,0x0,0x0,0x0,0x63,0x6f,0x70,0x79,0x3d,0x5b,0x22,0x5f,0x5f,0x62,0x75,0x69,0x6c,0x74,0x69,0x6e,0x73,0x5f,0x5f,0x22,0x2c,0x22,0x5f,0x5f,0x6e,0x61,0x6d,0x65,0x5f,0x5f,0x22,0x2c,0x22,0x5f,0x5f,0x64,0x6f,0x63,0x5f,0x5f,0x22,0x2c,0x22,0x5f,0x5f,0x70,0x61,0x63,0x6b,0x61,0x67,0x65,0x5f,0x5f,0x22,0x2c,0x27,0x74,0x70,0x74,0x27,0x2c,0x27,0x63,0x6c,0x65,0x61,0x6e,0x27,0x2c,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x27,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x27,0x2c,0x27,0x66,0x6f,0x72,0x6b,0x27,0x2c,0x27,0x5f,0x66,0x6f,0x72,0x6b,0x27,0x2c,0x27,0x66,0x6f,0x72,0x6b,0x5f,0x73,0x74,0x61,0x74,0x75,0x73,0x27,0x2c,0x27,0x66,0x6f,0x72,0x6b,0x5f,0x75,0x6e,0x62,0x6c,0x6f,0x63,0x6b,0x27,0x2c,0x27,0x73,0x79,0x73,0x27,0x5d,0xa,0x20,0x20,0x20,0x20,0x68,0x61,0x6e,0x64,0x6c,0x65,0x2e,0x67,0x6c,0x6f,0x62,0x3d,0x7b,0x7d,0xa,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x69,0x74,0x65,0x6d,0x20,0x69,0x6e,0x20,0x63,0x6f,0x70,0x79,0x3a,0xa,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x68,0x61,0x6e,0x64,0x6c,0x65,0x2e,0x67,0x6c,0x6f,0x62,0x5b,0x69,0x74,0x65,0x6d,0x5d,0x3d,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x73,0x28,0x29,0x5b,0x69,0x74,0x65,0x6d,0x5d,0x74,0x0,0x0,0x0,0x0,0x4e,0x28,0x4,0x0,0x0,0x0,0x74,0x7,0x0,0x0,0x0,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x73,0x74,0x6,0x0,0x0,0x0,0x68,0x61,0x6e,0x64,0x6c,0x65,0x74,0x4,0x0,0x0,0x0,0x67,0x6c,0x6f,0x62,0x74,0x3,0x0,0x0,0x0,0x62,0x75,0x66,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x5,0x0,0x0,0x0,0x63,0x6c,0x65,0x61,0x6e,0x36,0x0,0x0,0x0,0x73,0x4,0x0,0x0,0x0,0x0,0x7,0xc,0x1,0x63,0x1,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x5,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x50,0x0,0x0,0x0,0x79,0xd,0x0,0x74,0x0,0x0,0x6a,0x1,0x0,0x7d,0x1,0x0,0x57,0x6e,0xe,0x0,0x1,0x1,0x1,0x74,0x2,0x0,0x83,0x0,0x0,0x1,0x6e,0x1,0x0,0x58,0x79,0xe,0x0,0x74,0x3,0x0,0x7c,0x0,0x0,0x83,0x1,0x0,0x1,0x57,0x6e,0x1d,0x0,0x4,0x74,0x4,0x0,0x6b,0xa,0x0,0x72,0x4b,0x0,0x1,0x7d,0x2,0x0,0x1,0x74,0x5,0x0,0x7c,0x2,0x0,0x83,0x1,0x0,0x1,0x6e,0x1,0x0,0x58,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x6,0x0,0x0,0x0,0x52,0xac,0x0,0x0,0x0,0x52,0xad,0x0,0x0,0x0,0x52,0xaf,0x0,0x0,0x0,0x74,0x7,0x0,0x0,0x0,0x5f,0x68,0x61,0x6e,0x64,0x6c,0x65,0x74,0x9,0x0,0x0,0x0,0x45,0x78,0x63,0x65,0x70,0x74,0x69,0x6f,0x6e,0x52,0xa9,0x0,0x0,0x0,0x28,0x3,0x0,0x0,0x0,0x52,0x8,0x0,0x0,0x0,0x74,0x1,0x0,0x0,0x0,0x61,0x52,0xa7,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x52,0xac,0x0,0x0,0x0,0x40,0x0,0x0,0x0,0x73,0x10,0x0,0x0,0x0,0x0,0x1,0x3,0x1,0xd,0x1,0x3,0x1,0xb,0x1,0x3,0x1,0xe,0x1,0xf,0x1,0x63,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x5,0x0,0x0,0x0,0x42,0x0,0x0,0x0,0x73,0x63,0x0,0x0,0x0,0x79,0x26,0x0,0x65,0x0,0x0,0x6a,0x1,0x0,0x6a,0x2,0x0,0x65,0x3,0x0,0x65,0x4,0x0,0x7c,0x0,0x0,0x65,0x5,0x0,0x6a,0x6,0x0,0x83,0x2,0x0,0x83,0x1,0x0,0x83,0x1,0x0,0x1,0x57,0x6e,0x36,0x0,0x1,0x1,0x1,0x79,0xf,0x0,0x7c,0x0,0x0,0x65,0x5,0x0,0x6a,0x6,0x0,0x4,0x55,0x57,0x71,0x5f,0x0,0x4,0x65,0x7,0x0,0x6b,0xa,0x0,0x72,0x5a,0x0,0x1,0x7d,0x1,0x0,0x1,0x65,0x8,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x71,0x5f,0x0,0x58,0x6e,0x1,0x0,0x58,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x9,0x0,0x0,0x0,0x52,0xa5,0x0,0x0,0x0,0x52,0xa6,0x0,0x0,0x0,0x52,0x9,0x0,0x0,0x0,0x52,0x4,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x65,0x76,0x61,0x6c,0x52,0xac,0x0,0x0,0x0,0x52,0xad,0x0,0x0,0x0,0x52,0xb1,0x0,0x0,0x0,0x52,0xa9,0x0,0x0,0x0,0x28,0x2,0x0,0x0,0x0,0x52,0x8,0x0,0x0,0x0,0x52,0xa7,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x52,0xb0,0x0,0x0,0x0,0x4a,0x0,0x0,0x0,0x73,0xe,0x0,0x0,0x0,0x0,0x2,0x3,0x1,0x26,0x1,0x3,0x1,0x3,0x1,0xf,0x1,0xf,0x1,0x63,0x1,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x27,0x0,0x0,0x0,0x74,0x0,0x0,0x7c,0x0,0x0,0x83,0x1,0x0,0x7d,0x1,0x0,0x7c,0x1,0x0,0x6a,0x1,0x0,0x83,0x0,0x0,0x1,0x74,0x2,0x0,0x6a,0x3,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x4,0x0,0x0,0x0,0x74,0xa,0x0,0x0,0x0,0x5f,0x5f,0x69,0x6d,0x70,0x6f,0x72,0x74,0x5f,0x5f,0x74,0x4,0x0,0x0,0x0,0x69,0x6e,0x69,0x74,0x74,0xb,0x0,0x0,0x0,0x5f,0x65,0x78,0x74,0x65,0x6e,0x73,0x69,0x6f,0x6e,0x73,0x74,0x6,0x0,0x0,0x0,0x61,0x70,0x70,0x65,0x6e,0x64,0x28,0x2,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x66,0x6e,0x61,0x6d,0x65,0x74,0x3,0x0,0x0,0x0,0x65,0x78,0x74,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x7,0x0,0x0,0x0,0x6c,0x6f,0x61,0x64,0x65,0x78,0x74,0x56,0x0,0x0,0x0,0x73,0x6,0x0,0x0,0x0,0x0,0x1,0xc,0x1,0xa,0x1,0x63,0x1,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0x81,0x0,0x0,0x0,0x67,0x0,0x0,0x7d,0x1,0x0,0x78,0x4c,0x0,0x74,0x0,0x0,0x44,0x5d,0x44,0x0,0x7d,0x2,0x0,0x79,0x11,0x0,0x7c,0x2,0x0,0x6a,0x1,0x0,0x7c,0x0,0x0,0x83,0x1,0x0,0x1,0x57,0x71,0xd,0x0,0x4,0x74,0x2,0x0,0x6b,0xa,0x0,0x72,0x50,0x0,0x1,0x7d,0x3,0x0,0x1,0x74,0x3,0x0,0x7c,0x3,0x0,0x83,0x1,0x0,0x1,0x7c,0x1,0x0,0x6a,0x4,0x0,0x7c,0x2,0x0,0x83,0x1,0x0,0x1,0x71,0xd,0x0,0x58,0x71,0xd,0x0,0x57,0x78,0x25,0x0,0x7c,0x1,0x0,0x44,0x5d,0x1d,0x0,0x7d,0x2,0x0,0x7c,0x2,0x0,0x6a,0x5,0x0,0x83,0x0,0x0,0x1,0x74,0x0,0x0,0x6a,0x6,0x0,0x7c,0x2,0x0,0x83,0x1,0x0,0x1,0x71,0x5c,0x0,0x57,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x7,0x0,0x0,0x0,0x52,0xb6,0x0,0x0,0x0,0x74,0x3,0x0,0x0,0x0,0x6b,0x65,0x79,0x52,0xb1,0x0,0x0,0x0,0x52,0xa9,0x0,0x0,0x0,0x52,0xb7,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x65,0x78,0x69,0x74,0x74,0x6,0x0,0x0,0x0,0x72,0x65,0x6d,0x6f,0x76,0x65,0x28,0x4,0x0,0x0,0x0,0x52,0xbb,0x0,0x0,0x0,0x74,0x6,0x0,0x0,0x0,0x75,0x6e,0x6c,0x6f,0x61,0x64,0x74,0x4,0x0,0x0,0x0,0x69,0x74,0x65,0x6d,0x52,0xa7,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x8,0x0,0x0,0x0,0x6b,0x65,0x79,0x70,0x72,0x65,0x73,0x73,0x5b,0x0,0x0,0x0,0x73,0x14,0x0,0x0,0x0,0x0,0x1,0x6,0x1,0xd,0x1,0x3,0x1,0x11,0x1,0xf,0x1,0xa,0x1,0x15,0x1,0xd,0x1,0xa,0x1,0x63,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x43,0x0,0x0,0x0,0x73,0xa2,0x0,0x0,0x0,0x67,0x0,0x0,0x7d,0x0,0x0,0x78,0x49,0x0,0x74,0x0,0x0,0x44,0x5d,0x41,0x0,0x7d,0x1,0x0,0x79,0xe,0x0,0x7c,0x1,0x0,0x6a,0x1,0x0,0x83,0x0,0x0,0x1,0x57,0x71,0xd,0x0,0x4,0x74,0x2,0x0,0x6b,0xa,0x0,0x72,0x4d,0x0,0x1,0x7d,0x2,0x0,0x1,0x74,0x3,0x0,0x7c,0x2,0x0,0x83,0x1,0x0,0x1,0x7c,0x0,0x0,0x6a,0x4,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x71,0xd,0x0,0x58,0x71,0xd,0x0,0x57,0x78,0x49,0x0,0x7c,0x0,0x0,0x44,0x5d,0x41,0x0,0x7d,0x1,0x0,0x79,0xe,0x0,0x7c,0x1,0x0,0x6a,0x5,0x0,0x83,0x0,0x0,0x1,0x57,0x6e,0x1d,0x0,0x4,0x74,0x2,0x0,0x6b,0xa,0x0,0x72,0x8c,0x0,0x1,0x7d,0x2,0x0,0x1,0x74,0x3,0x0,0x7c,0x2,0x0,0x83,0x1,0x0,0x1,0x6e,0x1,0x0,0x58,0x74,0x0,0x0,0x6a,0x6,0x0,0x7c,0x1,0x0,0x83,0x1,0x0,0x1,0x71,0x59,0x0,0x57,0x64,0x0,0x0,0x53,0x28,0x1,0x0,0x0,0x0,0x4e,0x28,0x7,0x0,0x0,0x0,0x52,0xb6,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x73,0x74,0x65,0x70,0x52,0xb1,0x0,0x0,0x0,0x52,0xa9,0x0,0x0,0x0,0x52,0xb7,0x0,0x0,0x0,0x52,0xbc,0x0,0x0,0x0,0x52,0xbd,0x0,0x0,0x0,0x28,0x3,0x0,0x0,0x0,0x52,0xbe,0x0,0x0,0x0,0x52,0xbf,0x0,0x0,0x0,0x52,0xa7,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x52,0xc1,0x0,0x0,0x0,0x68,0x0,0x0,0x0,0x73,0x1a,0x0,0x0,0x0,0x0,0x1,0x6,0x1,0xd,0x1,0x3,0x1,0xe,0x1,0xf,0x1,0xa,0x1,0x15,0x1,0xd,0x1,0x3,0x1,0xe,0x1,0xf,0x1,0xe,0x1,0x28,0x0,0x0,0x0,0x0,0x28,0x14,0x0,0x0,0x0,0x52,0x5,0x0,0x0,0x0,0x52,0xa5,0x0,0x0,0x0,0x74,0x4,0x0,0x0,0x0,0x63,0x6f,0x64,0x65,0x74,0x6,0x0,0x0,0x0,0x63,0x74,0x79,0x70,0x65,0x73,0x52,0xa2,0x0,0x0,0x0,0x74,0x5,0x0,0x0,0x0,0x46,0x61,0x6c,0x73,0x65,0x74,0x5,0x0,0x0,0x0,0x44,0x45,0x42,0x55,0x47,0x52,0x1,0x0,0x0,0x0,0x52,0xa6,0x0,0x0,0x0,0x74,0x6,0x0,0x0,0x0,0x73,0x74,0x64,0x65,0x72,0x72,0x74,0x7,0x0,0x0,0x0,0x65,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x52,0xa1,0x0,0x0,0x0,0x52,0xa9,0x0,0x0,0x0,0x52,0xaf,0x0,0x0,0x0,0x52,0xac,0x0,0x0,0x0,0x52,0xb0,0x0,0x0,0x0,0x52,0xb6,0x0,0x0,0x0,0x52,0xba,0x0,0x0,0x0,0x52,0xc0,0x0,0x0,0x0,0x52,0xc1,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x28,0x0,0x0,0x0,0x0,0x73,0x1b,0x0,0x0,0x0,0x2e,0x2f,0x73,0x72,0x63,0x2f,0x70,0x79,0x74,0x68,0x6f,0x6e,0x2f,0x74,0x70,0x74,0x5f,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x70,0x79,0x74,0x8,0x0,0x0,0x0,0x3c,0x6d,0x6f,0x64,0x75,0x6c,0x65,0x3e,0x1,0x0,0x0,0x0,0x73,0x54,0x0,0x0,0x0,0xc,0x1,0xa,0x1,0xc,0x1,0xc,0x1,0xc,0x1,0xc,0x1,0x6,0x4,0x13,0x5,0xc,0x1,0xc,0x1,0xf,0x4,0x3b,0x1,0x38,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x31,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0x2a,0x1,0xa,0x3,0x9,0x2,0x9,0x5,0x9,0xa,0x9,0xa,0x9,0xb,0x6,0x1,0x9,0x5,0x9,0xd}; diff --git a/src/interface.c b/src/interface.c index d23098042..680b6a908 100644 --- a/src/interface.c +++ b/src/interface.c @@ -15,6 +15,8 @@ #include #include + +//char pyready=1; SDLMod sdl_mod; int sdl_key, sdl_wheel, sdl_caps=0, sdl_ascii, sdl_zoom_trig=0; @@ -3839,21 +3841,16 @@ void open_link(char *uri) { #ifdef WIN32 ShellExecute(0, "OPEN", uri, NULL, NULL, 0); #elif MACOSX - //char *cmd[] = { "open", uri, (char *)0 }; - //execvp("open", cmd); - //LSOpenCFURLRef(CFURLCreateWithString(NULL, CFStringCreateWithCString(NULL, uri, 0) ,NULL), NULL); //TODO: Get this crap working char *cmd = malloc(7+strlen(uri)); strcpy(cmd, "open "); strappend(cmd, uri); system(cmd); #elif LIN32 - //execlp("xdg-open", "xdg-open", uri, (char *)0); char *cmd = malloc(11+strlen(uri)); strcpy(cmd, "xdg-open "); strappend(cmd, uri); system(cmd); #elif LIN64 - //execlp("xdg-open", "xdg-open", uri, (char *)0); char *cmd = malloc(11+strlen(uri)); strcpy(cmd, "xdg-open "); strappend(cmd, uri); @@ -3870,7 +3867,7 @@ typedef struct command_history command_history; command_history *last_command = NULL; command_history *last_command2 = NULL; char *console_ui(pixel *vid_buf,char error[255],char console_more) { - int mx,my,b,cc,ci = -1; + int mx,my,b,cc,ci = -1,i; pixel *old_buf=calloc((XRES+BARSIZE)*(YRES+MENUSIZE), PIXELSIZE); command_history *currentcommand; command_history *currentcommand2; @@ -3897,7 +3894,6 @@ char *console_ui(pixel *vid_buf,char error[255],char console_more) { last_command2 = currentcommand2; SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - cc = 0; while(cc < 80){ fillrect(old_buf, -1, -1+cc, XRES+BARSIZE, 2, 0, 0, 0, 160-(cc*2)); @@ -3912,8 +3908,14 @@ char *console_ui(pixel *vid_buf,char error[255],char console_more) { memcpy(vid_buf,old_buf,(XRES+BARSIZE)*YRES*PIXELSIZE); draw_line(vid_buf, 0, 219, XRES+BARSIZE-1, 219, 228, 228, 228, XRES+BARSIZE); - drawtext(vid_buf, 15, 15, "Welcome to The Powder Toy console v.3 (by cracker64, python by Doxin)" //TODO: help command - ,255, 255, 255, 255); + if(pygood) + i=255; + else + i=0; + if(pyready) + drawtext(vid_buf, 15, 15, "Welcome to The Powder Toy console v.3 (by cracker64, python by Doxin)",255,i,i, 255); + else + drawtext(vid_buf, 15, 15, "Welcome to The Powder Toy console v.3 (by cracker64, python disabled)",255,i,i, 255); cc = 0; currentcommand = last_command; diff --git a/src/main.c b/src/main.c index fe8496dee..8765642ce 100644 --- a/src/main.c +++ b/src/main.c @@ -29,6 +29,8 @@ #ifdef PYCONSOLE #include "Python.h" #include "pyconsole.h" +char pyready=1; +char pygood=1; #endif #include @@ -1212,8 +1214,7 @@ char console_error[255] = ""; //functions callable from python: -static PyObject* -emb_create(PyObject *self, PyObject *args, PyObject *keywds) +static PyObject* emb_create(PyObject *self, PyObject *args, PyObject *keywds) { int x,y,t; char *name = ""; @@ -1225,8 +1226,8 @@ emb_create(PyObject *self, PyObject *args, PyObject *keywds) console_parse_type(name, &t, console_error); return Py_BuildValue("i",create_part(-1,x,y,t)); } -//sys_pause = !sys_pause -emb_pause(PyObject *self, PyObject *args) + +static PyObject* emb_pause(PyObject *self, PyObject *args) { int x,y,t; if(!PyArg_ParseTuple(args, ":unpause")) @@ -1236,7 +1237,7 @@ emb_pause(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -emb_unpause(PyObject *self, PyObject *args) +static PyObject* emb_unpause(PyObject *self, PyObject *args) { int x,y,t; if(!PyArg_ParseTuple(args, ":pause")) @@ -1246,7 +1247,7 @@ emb_unpause(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -emb_toggle_pause(PyObject *self, PyObject *args) +static PyObject* emb_toggle_pause(PyObject *self, PyObject *args) { int x,y,t; if(!PyArg_ParseTuple(args, ":toggle_pause")) @@ -1257,8 +1258,7 @@ emb_toggle_pause(PyObject *self, PyObject *args) } //console_mode - -emb_toggle_console(PyObject *self, PyObject *args) +static PyObject* emb_toggle_console(PyObject *self, PyObject *args) { int x,y,t; if(!PyArg_ParseTuple(args, ":toggle_console")) @@ -1268,7 +1268,7 @@ emb_toggle_console(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -emb_open_console(PyObject *self, PyObject *args) +static PyObject* emb_open_console(PyObject *self, PyObject *args) { int x,y,t; if(!PyArg_ParseTuple(args, ":toggle_console")) @@ -1278,7 +1278,7 @@ emb_open_console(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -emb_close_console(PyObject *self, PyObject *args) +static PyObject* emb_close_console(PyObject *self, PyObject *args) { int x,y,t; if(!PyArg_ParseTuple(args, ":toggle_console")) @@ -1288,8 +1288,7 @@ emb_close_console(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } - -emb_log(PyObject *self, PyObject *args) +static PyObject* emb_log(PyObject *self, PyObject *args) { char *buffer; if(!PyArg_ParseTuple(args, "s:log",&buffer)) @@ -1302,7 +1301,7 @@ emb_log(PyObject *self, PyObject *args) char console_more=0; -emb_console_more(PyObject *self, PyObject *args) +static PyObject* emb_console_more(PyObject *self, PyObject *args) { if(!PyArg_ParseTuple(args, ":log")) return NULL; @@ -1311,7 +1310,7 @@ emb_console_more(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -emb_console_less(PyObject *self, PyObject *args) +static PyObject* emb_console_less(PyObject *self, PyObject *args) { if(!PyArg_ParseTuple(args, ":log")) return NULL; @@ -1320,10 +1319,7 @@ emb_console_less(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -//drawtext(vid_buf, 15, 175-(cc*12), currentcommand->command, 255, 255, 255, 255); - - -emb_reset_pressure(PyObject *self, PyObject *args) +static PyObject* emb_reset_pressure(PyObject *self, PyObject *args) { if(!PyArg_ParseTuple(args, ":reset_pressure")) return NULL; @@ -1336,7 +1332,7 @@ emb_reset_pressure(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -emb_reset_velocity(PyObject *self, PyObject *args) +static PyObject* emb_reset_velocity(PyObject *self, PyObject *args) { if(!PyArg_ParseTuple(args, ":reset_velocity")) return NULL; @@ -1350,7 +1346,7 @@ emb_reset_velocity(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -emb_reset_sparks(PyObject *self, PyObject *args) +static PyObject* emb_reset_sparks(PyObject *self, PyObject *args) { if(!PyArg_ParseTuple(args, ":reset_sparks")) return NULL; @@ -1366,11 +1362,11 @@ emb_reset_sparks(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -emb_set_life(PyObject *self, PyObject *args, PyObject *keywds) +static PyObject* emb_set_life(PyObject *self, PyObject *args, PyObject *keywds) { int i = -1,life,j,x=-1,y=-1; char *name = ""; - char *kwlist[] = {"setto", "setfrom", "i", "x", "y", NULL}; + char *kwlist[] = {"setto", "from", "i", "x", "y", NULL}; if(!PyArg_ParseTupleAndKeywords(args, keywds, "I|sIII:set_type",kwlist ,&life,&name,&i,&x,&y)) return NULL; // @@ -1406,12 +1402,12 @@ emb_set_life(PyObject *self, PyObject *args, PyObject *keywds) return Py_BuildValue("i",1); } -emb_set_type(PyObject *self, PyObject *args, PyObject *keywds) +static PyObject* emb_set_type(PyObject *self, PyObject *args, PyObject *keywds) { int i = -1,life,j=-1,x=-1,y=-1; char *name = ""; char *type = ""; - char *kwlist[] = {"setto", "settoint", "setfrom", "i", "x", "y", NULL}; + char *kwlist[] = {"setto", "settoint", "from", "i", "x", "y", NULL}; if(!PyArg_ParseTupleAndKeywords(args, keywds, "|sIsIII:set_type",kwlist ,&type,&life,&name,&i,&x,&y)) return NULL; // @@ -1448,11 +1444,11 @@ emb_set_type(PyObject *self, PyObject *args, PyObject *keywds) return Py_BuildValue("i",1); } -emb_set_temp(PyObject *self, PyObject *args, PyObject *keywds) +static PyObject* emb_set_temp(PyObject *self, PyObject *args, PyObject *keywds) { int i = -1,life,j,x=-1,y=-1; char *name = ""; - char *kwlist[] = {"setto", "setfrom", "i", "x", "y", NULL}; + char *kwlist[] = {"setto", "from", "i", "x", "y", NULL}; if(!PyArg_ParseTupleAndKeywords(args, keywds, "I|sIII:set_type",kwlist ,&life,&name,&i,&x,&y)) return NULL; // @@ -1488,11 +1484,11 @@ emb_set_temp(PyObject *self, PyObject *args, PyObject *keywds) return Py_BuildValue("i",1); } -emb_set_tmp(PyObject *self, PyObject *args, PyObject *keywds) +static PyObject* emb_set_tmp(PyObject *self, PyObject *args, PyObject *keywds) { int i = -1,life,j,x=-1,y=-1; char *name = ""; - char *kwlist[] = {"setto", "setfrom", "i", "x", "y", NULL}; + char *kwlist[] = {"setto", "from", "i", "x", "y", NULL}; if(!PyArg_ParseTupleAndKeywords(args, keywds, "I|sIII:set_type",kwlist ,&life,&name,&i,&x,&y)) return NULL; // @@ -1528,12 +1524,12 @@ emb_set_tmp(PyObject *self, PyObject *args, PyObject *keywds) return Py_BuildValue("i",1); } -emb_set_x(PyObject *self, PyObject *args, PyObject *keywds) +static PyObject* emb_set_x(PyObject *self, PyObject *args, PyObject *keywds) { int i = -1,life,j,x=-1,y=-1; char *name = ""; char *type = ""; - char *kwlist[] = {"setto", "setfrom", "i", "x", "y", NULL}; + char *kwlist[] = {"setto", "from", "i", "x", "y", NULL}; if(!PyArg_ParseTupleAndKeywords(args, keywds, "I|sIII:set_type",kwlist ,&life,&name,&i,&x,&y)) return NULL; // @@ -1569,11 +1565,11 @@ emb_set_x(PyObject *self, PyObject *args, PyObject *keywds) return Py_BuildValue("i",1); } -emb_set_y(PyObject *self, PyObject *args, PyObject *keywds) +static PyObject* emb_set_y(PyObject *self, PyObject *args, PyObject *keywds) { int i = -1,life,j,x=-1,y=-1; char *name = ""; - char *kwlist[] = {"setto", "setfrom", "i", "x", "y", NULL}; + char *kwlist[] = {"setto", "from", "i", "x", "y", NULL}; if(!PyArg_ParseTupleAndKeywords(args, keywds, "I|sIII:set_type",kwlist ,&life,&name,&i,&x,&y)) return NULL; // @@ -1609,12 +1605,12 @@ emb_set_y(PyObject *self, PyObject *args, PyObject *keywds) return Py_BuildValue("i",1); } -emb_set_ctype(PyObject *self, PyObject *args, PyObject *keywds) +static PyObject* emb_set_ctype(PyObject *self, PyObject *args, PyObject *keywds) { int i = -1,life,j,x=-1,y=-1; char *name = ""; char *type = ""; - char *kwlist[] = {"setto", "toctypeint", "setfrom", "i", "x", "y", NULL}; + char *kwlist[] = {"setto", "settoint", "from", "i", "x", "y", NULL}; if(!PyArg_ParseTupleAndKeywords(args, keywds, "s|IsIII:set_type",kwlist ,&type, &life, &name,&i,&x,&y)) return NULL; // @@ -1652,11 +1648,11 @@ emb_set_ctype(PyObject *self, PyObject *args, PyObject *keywds) return Py_BuildValue("i",1); } -emb_set_vx(PyObject *self, PyObject *args, PyObject *keywds) +static PyObject* emb_set_vx(PyObject *self, PyObject *args, PyObject *keywds) { int i = -1,life,j,x=-1,y=-1; char *name = ""; - char *kwlist[] = {"setto", "setfrom", "i", "x", "y", NULL}; + char *kwlist[] = {"setto", "from", "i", "x", "y", NULL}; if(!PyArg_ParseTupleAndKeywords(args, keywds, "I|sIII:set_type",kwlist ,&life,&name,&i,&x,&y)) return NULL; // @@ -1692,11 +1688,11 @@ emb_set_vx(PyObject *self, PyObject *args, PyObject *keywds) return Py_BuildValue("i",1); } -emb_set_vy(PyObject *self, PyObject *args, PyObject *keywds) +static PyObject* emb_set_vy(PyObject *self, PyObject *args, PyObject *keywds) { int i = -1,life,j,x=-1,y=-1; char *name = ""; - char *kwlist[] = {"setto", "setfrom", "i", "x", "y", NULL}; + char *kwlist[] = {"setto", "from", "i", "x", "y", NULL}; if(!PyArg_ParseTupleAndKeywords(args, keywds, "I|sIII:set_type",kwlist ,&life,&name,&i,&x,&y)) return NULL; // @@ -1731,7 +1727,8 @@ emb_set_vy(PyObject *self, PyObject *args, PyObject *keywds) } return Py_BuildValue("i",1); } -emb_get_pmap(PyObject *self, PyObject *args) + +static PyObject* emb_get_pmap(PyObject *self, PyObject *args) { int x,y; if(!PyArg_ParseTuple(args, "II:get_pmap",&x,&y)) @@ -1742,7 +1739,8 @@ emb_get_pmap(PyObject *self, PyObject *args) return Py_BuildValue("I",pmap[y][x]); } -emb_get_prop(PyObject *self, PyObject *args) + +static PyObject* emb_get_prop(PyObject *self, PyObject *args) { int i; char *prop = ""; @@ -1774,7 +1772,7 @@ emb_get_prop(PyObject *self, PyObject *args) return Py_BuildValue("i",-1); } -emb_draw_pixel(PyObject *self, PyObject *args) +static PyObject* emb_draw_pixel(PyObject *self, PyObject *args) { int x,y,r,g,b,a; a=255; @@ -1790,8 +1788,7 @@ emb_draw_pixel(PyObject *self, PyObject *args) } -//drawtext(pixel *vid, int x, int y, const char *s, int r, int g, int b, int a) -emb_draw_text(PyObject *self, PyObject *args) +static PyObject* emb_draw_text(PyObject *self, PyObject *args) { int x,y,r,g,b,a; char *txt; @@ -1806,8 +1803,7 @@ emb_draw_text(PyObject *self, PyObject *args) return Py_BuildValue("i",-1); } -//drawrect(pixel *vid, int x, int y, int w, int h, int r, int g, int b, int a) -emb_draw_rect(PyObject *self, PyObject *args) +static PyObject* emb_draw_rect(PyObject *self, PyObject *args) { int x,y,w,h,r,g,b,a; a=255; @@ -1822,7 +1818,7 @@ emb_draw_rect(PyObject *self, PyObject *args) return Py_BuildValue("i",-1); } -emb_draw_fillrect(PyObject *self, PyObject *args) +static PyObject* emb_draw_fillrect(PyObject *self, PyObject *args) { int x,y,w,h,r,g,b,a; a=255; @@ -1836,8 +1832,8 @@ emb_draw_fillrect(PyObject *self, PyObject *args) } return Py_BuildValue("i",-1); } -//int textwidth(char *s) -emb_get_width(PyObject *self, PyObject *args) + +static PyObject* emb_get_width(PyObject *self, PyObject *args) { char *txt; if(!PyArg_ParseTuple(args, "s:get_width",&txt)) @@ -1845,8 +1841,7 @@ emb_get_width(PyObject *self, PyObject *args) return Py_BuildValue("i",textwidth(txt)); } -//SDL_GetMouseState(&x, &y) -emb_get_mouse(PyObject *self, PyObject *args) +static PyObject* emb_get_mouse(PyObject *self, PyObject *args) { int x,y,mask,b1,b2,b3; if(!PyArg_ParseTuple(args, ":get_mouse")) @@ -1858,8 +1853,7 @@ emb_get_mouse(PyObject *self, PyObject *args) return Py_BuildValue("(ii(iii))",x,y,b1,b2,b3); } -//svf_name -emb_get_name(PyObject *self, PyObject *args) +static PyObject* emb_get_name(PyObject *self, PyObject *args) { if(!PyArg_ParseTuple(args, ":get_name")) return NULL; @@ -1869,7 +1863,7 @@ emb_get_name(PyObject *self, PyObject *args) return Py_BuildValue("s",""); } -emb_shortcuts_disable(PyObject *self, PyObject *args) +static PyObject* emb_shortcuts_disable(PyObject *self, PyObject *args) { if(!PyArg_ParseTuple(args, ":shortcuts_disable")) return NULL; @@ -1878,7 +1872,7 @@ emb_shortcuts_disable(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -emb_shortcuts_enable(PyObject *self, PyObject *args) +static PyObject* emb_shortcuts_enable(PyObject *self, PyObject *args) { if(!PyArg_ParseTuple(args, ":shortcuts_enable")) return NULL; @@ -1887,48 +1881,104 @@ emb_shortcuts_enable(PyObject *self, PyObject *args) return Py_BuildValue("i",1); } -emb_get_modifier(PyObject *self, PyObject *args) +static PyObject* emb_get_modifier(PyObject *self, PyObject *args) { if(!PyArg_ParseTuple(args, ":get_modifier")) return NULL; return Py_BuildValue("(iiiiii)",sdl_mod&KMOD_LCTRL,sdl_mod&KMOD_RCTRL,sdl_mod&KMOD_LALT,sdl_mod&KMOD_RALT,sdl_mod&KMOD_LSHIFT,sdl_mod&KMOD_RSHIFT); } +static PyObject* emb_set_keyrepeat(PyObject *self, PyObject *args) +{ + ////SDL_EnableKeyRepeat(delay,interval) + int keydelay,keyinterval; + keydelay=SDL_DEFAULT_REPEAT_DELAY; + keyinterval=SDL_DEFAULT_REPEAT_INTERVAL; + if(!PyArg_ParseTuple(args, "|ii:set_keyrepeat",&keydelay,&keyinterval)) + return NULL; + return Py_BuildValue("i",SDL_EnableKeyRepeat(keydelay,keyinterval)); +} + +//delete_part +static PyObject* emb_delete(PyObject *self, PyObject *args) +{ + ////SDL_EnableKeyRepeat(delay,interval) + int x,y; + if(!PyArg_ParseTuple(args, "ii:delete",&x,&y)) + return NULL; + delete_part(x,y); + return Py_BuildValue("i",1); +} + +static PyObject* emb_set_pressure(PyObject *self, PyObject *args) +{ + ////SDL_EnableKeyRepeat(delay,interval) + int x,y,press; + if(!PyArg_ParseTuple(args, "iii:set_pressure",&x,&y,&press)) + return NULL; + pv[y/CELL][x/CELL]=press; + return Py_BuildValue("i",1); +} + +static PyObject* emb_set_velocity(PyObject *self, PyObject *args) +{ + ////SDL_EnableKeyRepeat(delay,interval) + int x,y,xv,yv; + if(!PyArg_ParseTuple(args, "iiii:set_velocity",&x,&y,&xv,&yv)) + return NULL; + vx[y/CELL][x/CELL]=xv; + vy[y/CELL][x/CELL]=yv; + return Py_BuildValue("i",1); +} + +static PyObject* emb_disable_python(PyObject *self, PyObject *args) +{ + if(!PyArg_ParseTuple(args, ":disable_python")) + return NULL; + pyready=0; + return Py_BuildValue("i",1); +} + static PyMethodDef EmbMethods[] = { //WARNING! don't forget to register your function here! - {"create", emb_create, METH_VARARGS|METH_KEYWORDS, "create a particle."}, - {"log", emb_log, METH_VARARGS, "logs an error string to the console."}, - {"reset_pressure", emb_reset_pressure, METH_VARARGS, "resets all the pressure."}, - {"reset_velocity", emb_reset_velocity, METH_VARARGS, "resets all the velocity."}, - {"reset_sparks", emb_reset_sparks, METH_VARARGS, "resets all the sparks."}, - {"set_life", emb_set_life, METH_VARARGS|METH_KEYWORDS, "sets life of a specified particle."}, - {"set_type", emb_set_type, METH_VARARGS|METH_KEYWORDS, "sets type of a specified particle."}, - {"set_temp", emb_set_temp, METH_VARARGS|METH_KEYWORDS, "sets temp of a specified particle."}, - {"set_tmp", emb_set_tmp, METH_VARARGS|METH_KEYWORDS, "sets tmp of a specified particle."}, - {"set_x", emb_set_x, METH_VARARGS|METH_KEYWORDS, "sets x of a specified particle."}, - {"set_y", emb_set_y, METH_VARARGS|METH_KEYWORDS, "sets y of a specified particle."}, - {"set_ctype", emb_set_y, METH_VARARGS|METH_KEYWORDS, "sets ctype of a specified particle."}, - {"set_vx", emb_set_vx, METH_VARARGS|METH_KEYWORDS, "sets vx of a specified particle."}, - {"set_vy", emb_set_vy, METH_VARARGS|METH_KEYWORDS, "sets vy of a specified particle."}, - {"pause", emb_pause, METH_VARARGS, "pause the game."}, - {"unpause", emb_unpause, METH_VARARGS, "unpause the game."}, - {"pause_toggle", emb_toggle_pause, METH_VARARGS, "toggle game pause."}, - {"console_open", emb_open_console, METH_VARARGS, "open the game console."}, - {"console_close", emb_close_console, METH_VARARGS, "close the game console."}, - {"console_toggle", emb_toggle_console, METH_VARARGS, "toggle the game console."}, - {"console_more", emb_console_more, METH_VARARGS, "turns the more indicator on."}, - {"console_less", emb_console_less, METH_VARARGS, "turns the more indicator off."}, - {"get_pmap", emb_get_pmap, METH_VARARGS, "get the pmap value."}, - {"get_prop", emb_get_prop, METH_VARARGS, "get some properties."}, - {"draw_pixel", emb_draw_pixel, METH_VARARGS, "draw a pixel."}, - {"draw_text", emb_draw_text, METH_VARARGS, "draw some text."}, - {"draw_rect", emb_draw_rect, METH_VARARGS, "draw a rect."}, - {"draw_fillrect", emb_draw_fillrect, METH_VARARGS, "draw a rect."}, - {"get_width", emb_get_width, METH_VARARGS, "get string width."}, - {"get_mouse", emb_get_mouse, METH_VARARGS, "get mouse status."}, - {"get_name", emb_get_name, METH_VARARGS, "get name of logged in user"}, - {"shortcuts_disable", emb_shortcuts_disable, METH_VARARGS, "disable keyboard shortcuts"}, - {"shortcuts_enable", emb_shortcuts_enable, METH_VARARGS, "enable keyboard shortcuts"}, - {"get_modifier", emb_get_modifier, METH_VARARGS, "get pressed modifier keys"}, + {"create", (PyCFunction)emb_create, METH_VARARGS|METH_KEYWORDS, "create a particle."}, + {"log", (PyCFunction)emb_log, METH_VARARGS, "logs an error string to the console."}, + {"reset_pressure", (PyCFunction)emb_reset_pressure, METH_VARARGS, "resets all the pressure."}, + {"reset_velocity", (PyCFunction)emb_reset_velocity, METH_VARARGS, "resets all the velocity."}, + {"reset_sparks", (PyCFunction)emb_reset_sparks, METH_VARARGS, "resets all the sparks."}, + {"set_life", (PyCFunction)emb_set_life, METH_VARARGS|METH_KEYWORDS, "sets life of a specified particle."}, + {"set_type", (PyCFunction)emb_set_type, METH_VARARGS|METH_KEYWORDS, "sets type of a specified particle."}, + {"set_temp", (PyCFunction)emb_set_temp, METH_VARARGS|METH_KEYWORDS, "sets temp of a specified particle."}, + {"set_tmp", (PyCFunction)emb_set_tmp, METH_VARARGS|METH_KEYWORDS, "sets tmp of a specified particle."}, + {"set_x", (PyCFunction)emb_set_x, METH_VARARGS|METH_KEYWORDS, "sets x of a specified particle."}, + {"set_y", (PyCFunction)emb_set_y, METH_VARARGS|METH_KEYWORDS, "sets y of a specified particle."}, + {"set_ctype", (PyCFunction)emb_set_ctype, METH_VARARGS|METH_KEYWORDS, "sets ctype of a specified particle."}, + {"set_vx", (PyCFunction)emb_set_vx, METH_VARARGS|METH_KEYWORDS, "sets vx of a specified particle."}, + {"set_vy", (PyCFunction)emb_set_vy, METH_VARARGS|METH_KEYWORDS, "sets vy of a specified particle."}, + {"pause", (PyCFunction)emb_pause, METH_VARARGS, "pause the game."}, + {"unpause", (PyCFunction)emb_unpause, METH_VARARGS, "unpause the game."}, + {"pause_toggle", (PyCFunction)emb_toggle_pause, METH_VARARGS, "toggle game pause."}, + {"console_open", (PyCFunction)emb_open_console, METH_VARARGS, "open the game console."}, + {"console_close", (PyCFunction)emb_close_console, METH_VARARGS, "close the game console."}, + {"console_toggle", (PyCFunction)emb_toggle_console, METH_VARARGS, "toggle the game console."}, + {"console_more", (PyCFunction)emb_console_more, METH_VARARGS, "turns the more indicator on."}, + {"console_less", (PyCFunction)emb_console_less, METH_VARARGS, "turns the more indicator off."}, + {"get_pmap", (PyCFunction)emb_get_pmap, METH_VARARGS, "get the pmap value."}, + {"get_prop", (PyCFunction)emb_get_prop, METH_VARARGS, "get some properties."}, + {"draw_pixel", (PyCFunction)emb_draw_pixel, METH_VARARGS, "draw a pixel."}, + {"draw_text", (PyCFunction)emb_draw_text, METH_VARARGS, "draw some text."}, + {"draw_rect", (PyCFunction)emb_draw_rect, METH_VARARGS, "draw a rect."}, + {"draw_fillrect", (PyCFunction)emb_draw_fillrect, METH_VARARGS, "draw a rect."}, + {"get_width", (PyCFunction)emb_get_width, METH_VARARGS, "get string width."}, + {"get_mouse", (PyCFunction)emb_get_mouse, METH_VARARGS, "get mouse status."}, + {"get_name", (PyCFunction)emb_get_name, METH_VARARGS, "get name of logged in user"}, + {"shortcuts_disable", (PyCFunction)emb_shortcuts_disable, METH_VARARGS, "disable keyboard shortcuts"}, + {"shortcuts_enable", (PyCFunction)emb_shortcuts_enable, METH_VARARGS, "enable keyboard shortcuts"}, + {"get_modifier", (PyCFunction)emb_get_modifier, METH_VARARGS, "get pressed modifier keys"}, + {"set_keyrepeat", (PyCFunction)emb_set_keyrepeat, METH_VARARGS, "set key repeat rate."}, + {"delete", (PyCFunction)emb_delete, METH_VARARGS, "delete a particle"}, + {"set_pressure", (PyCFunction)emb_set_pressure, METH_VARARGS, "set pressure"}, + {"set_velocity", (PyCFunction)emb_set_velocity, METH_VARARGS, "set velocity"}, + {"disable_python", (PyCFunction)emb_disable_python, METH_VARARGS, "switch back to the old console."}, {NULL, NULL, 0, NULL} }; #endif @@ -1980,16 +2030,25 @@ int main(int argc, char *argv[]) fmt.callback = mixaudio; fmt.userdata = NULL; - #ifdef PYCONSOLE +#ifdef PYCONSOLE //initialise python console Py_Initialize(); - Py_InitModule("tpt", EmbMethods); - //change the path to find all the correct modules - PyRun_SimpleString("import sys\nsys.path.append('.')"); PyRun_SimpleString("print 'python present.'"); + Py_InitModule("tpt", EmbMethods); + + //change the path to find all the correct modules + PyRun_SimpleString("import sys\nsys.path.append('./tptPython.zip')\nsys.path.append('.')"); //load the console module and whatnot +#ifdef PYEXT + PyRun_SimpleString(tpt_console_py); + printf("using external python console file.\n"); + pname=PyString_FromString("tpt_console");//create string object + pmodule = PyImport_Import(pname);//import module + Py_DECREF(pname);//throw away string +#else PyObject *tpt_console_obj = PyMarshal_ReadObjectFromString(tpt_console_pyc+8, sizeof(tpt_console_pyc)-8); pmodule=PyImport_ExecCodeModule("tpt_console", tpt_console_obj); +#endif if(pmodule!=NULL) { pfunc=PyObject_GetAttrString(pmodule,"handle");//get the handler function @@ -2001,7 +2060,8 @@ int main(int argc, char *argv[]) { PyErr_Print(); printf("unable to find handle function, mangled console.py?\n"); - return -1; + pyready = 0; + pygood = 0; } pstep=PyObject_GetAttrString(pmodule,"step");//get the handler function @@ -2029,7 +2089,8 @@ int main(int argc, char *argv[]) //sys.stderr PyErr_Print(); printf("unable to find console module, missing file or mangled console.py?\n"); - return -1; + pyready = 0; + pygood = 0; } #else printf("python console disabled at compile time."); @@ -2658,378 +2719,18 @@ int main(int argc, char *argv[]) } } #ifdef PYCONSOLE - if(pkey!=NULL && sdl_key!=NULL) - { - pargs=Py_BuildValue("(c)",sdl_key); - pvalue = PyObject_CallObject(pkey, pargs); - Py_DECREF(pargs); - pargs=NULL; - if(pvalue==NULL) - strcpy(console_error,"failed to execute key code."); - //Py_DECREF(pvalue); - //puts("a"); - pvalue=NULL; - } + if(pyready==1 && pygood==1) + if(pkey!=NULL && sdl_key!=NULL) + { + pargs=Py_BuildValue("(c)",sdl_key); + pvalue = PyObject_CallObject(pkey, pargs); + Py_DECREF(pargs); + pargs=NULL; + if(pvalue==NULL) + strcpy(console_error,"failed to execute key code."); + pvalue=NULL; + } #endif -#ifdef INTERNAL - int counterthing; - if (sdl_key=='v'&&!(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL))) - { - if (sdl_mod & (KMOD_SHIFT)) { - if (vs>=1) - vs = 0; - else - vs = 3;//every other frame - } - else - { - if (vs>=1) - vs = 0; - else - vs = 1; - } - counterthing = 0; - } - if ((sdl_key=='s' && (sdl_mod & (KMOD_CTRL))) || (sdl_key=='s' && !isplayer2)) - { - if (it > 50) - it = 50; - save_mode = 1; - } - if (sdl_key=='1') - { - set_cmode(CM_VEL); - } - if (sdl_key=='2') - { - set_cmode(CM_PRESS); - } - if (sdl_key=='3') - { - set_cmode(CM_PERS); - } - if (sdl_key=='4') - { - set_cmode(CM_FIRE); - } - if (sdl_key=='5') - { - set_cmode(CM_BLOB); - } - if (sdl_key=='6') - { - set_cmode(CM_HEAT); - } - if (sdl_key=='7') - { - set_cmode(CM_FANCY); - } - if (sdl_key=='8') - { - set_cmode(CM_NOTHING); - } - if (sdl_key=='9') - { - set_cmode(CM_GRAD); - } - if (sdl_key=='0') - { - set_cmode(CM_CRACK); - } - if (sdl_key=='1'&& (sdl_mod & (KMOD_SHIFT)) && DEBUG_MODE) - { - if (counterthing+1>=vs) - { - dump_frame(vid_buf, XRES, YRES, XRES+BARSIZE); - counterthing = 0; - } - counterthing = (counterthing+1)%3; - } -#endif - - if (sdl_wheel) - { - if (sdl_zoom_trig==1) - { - ZSIZE += sdl_wheel; - if (ZSIZE>60) - ZSIZE = 60; - if (ZSIZE<2) - ZSIZE = 2; - ZFACTOR = 256/ZSIZE; - sdl_wheel = 0; - } - else - { - if (!(sdl_mod & (KMOD_SHIFT|KMOD_CTRL))) - { - bsx += sdl_wheel; - bsy += sdl_wheel; - } - else if (sdl_mod & (KMOD_SHIFT) && !(sdl_mod & (KMOD_CTRL))) - { - bsx += sdl_wheel; - } - else if (sdl_mod & (KMOD_CTRL) && !(sdl_mod & (KMOD_SHIFT))) - { - bsy += sdl_wheel; - } - if (bsx>1180) - bsx = 1180; - if (bsx<0) - bsx = 0; - if (bsy>1180) - bsy = 1180; - if (bsy<0) - bsy = 0; - sdl_wheel = 0; - /*if(su >= PT_NUM) { - if(sl < PT_NUM) - su = sl; - if(sr < PT_NUM) - su = sr; - }*/ - } - } - if (sdl_key==SDLK_RIGHTBRACKET) { - if (sdl_zoom_trig==1) - { - ZSIZE += 1; - if (ZSIZE>60) - ZSIZE = 60; - if (ZSIZE<2) - ZSIZE = 2; - ZFACTOR = 256/ZSIZE; - } - else - { - if (sdl_mod & (KMOD_LALT|KMOD_RALT) && !(sdl_mod & (KMOD_SHIFT|KMOD_CTRL))) - { - bsx += 1; - bsy += 1; - } - else if (sdl_mod & (KMOD_SHIFT) && !(sdl_mod & (KMOD_CTRL))) - { - bsx += 1; - } - else if (sdl_mod & (KMOD_CTRL) && !(sdl_mod & (KMOD_SHIFT))) - { - bsy += 1; - } - else - { - bsx += ceil((bsx/5)+0.5f); - bsy += ceil((bsy/5)+0.5f); - } - if (bsx>1180) - bsx = 1180; - if (bsy>1180) - bsy = 1180; - if (bsx<0) - bsx = 0; - if (bsy<0) - bsy = 0; - } - } - if ((sdl_key=='d'&&(sdl_mod & (KMOD_CTRL))) || (sdl_key=='d' && !isplayer2)) - DEBUG_MODE = !DEBUG_MODE; - if (sdl_key=='i') - { - int nx, ny; - for (nx = 0; nx 50) - it = 50; - } - if (sdl_key=='z'&&(sdl_mod & (KMOD_LCTRL|KMOD_RCTRL))) // Undo - { - int cbx, cby, cbi; - - for (cbi=0; cbi H. Frystyk Nielsen +# Expires September 8, 1995 March 8, 1995 +# +# URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt +# +# and +# +# Network Working Group R. Fielding +# Request for Comments: 2616 et al +# Obsoletes: 2068 June 1999 +# Category: Standards Track +# +# URL: http://www.faqs.org/rfcs/rfc2616.html + +# Log files +# --------- +# +# Here's a quote from the NCSA httpd docs about log file format. +# +# | The logfile format is as follows. Each line consists of: +# | +# | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb +# | +# | host: Either the DNS name or the IP number of the remote client +# | rfc931: Any information returned by identd for this person, +# | - otherwise. +# | authuser: If user sent a userid for authentication, the user name, +# | - otherwise. +# | DD: Day +# | Mon: Month (calendar name) +# | YYYY: Year +# | hh: hour (24-hour format, the machine's timezone) +# | mm: minutes +# | ss: seconds +# | request: The first line of the HTTP request as sent by the client. +# | ddd: the status code returned by the server, - if not available. +# | bbbb: the total number of bytes sent, +# | *not including the HTTP/1.0 header*, - if not available +# | +# | You can determine the name of the file accessed through request. +# +# (Actually, the latter is only true if you know the server configuration +# at the time the request was made!) + +__version__ = "0.3" + +__all__ = ["HTTPServer", "BaseHTTPRequestHandler"] + +import sys +import time +import socket # For gethostbyaddr() +from warnings import filterwarnings, catch_warnings +with catch_warnings(): + if sys.py3kwarning: + filterwarnings("ignore", ".*mimetools has been removed", + DeprecationWarning) + import mimetools +import SocketServer + +# Default error message template +DEFAULT_ERROR_MESSAGE = """\ + +Error response + + +

Error response

+

Error code %(code)d. +

Message: %(message)s. +

Error code explanation: %(code)s = %(explain)s. + +""" + +DEFAULT_ERROR_CONTENT_TYPE = "text/html" + +def _quote_html(html): + return html.replace("&", "&").replace("<", "<").replace(">", ">") + +class HTTPServer(SocketServer.TCPServer): + + allow_reuse_address = 1 # Seems to make sense in testing environment + + def server_bind(self): + """Override server_bind to store the server name.""" + SocketServer.TCPServer.server_bind(self) + host, port = self.socket.getsockname()[:2] + self.server_name = socket.getfqdn(host) + self.server_port = port + + +class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler): + + """HTTP request handler base class. + + The following explanation of HTTP serves to guide you through the + code as well as to expose any misunderstandings I may have about + HTTP (so you don't need to read the code to figure out I'm wrong + :-). + + HTTP (HyperText Transfer Protocol) is an extensible protocol on + top of a reliable stream transport (e.g. TCP/IP). The protocol + recognizes three parts to a request: + + 1. One line identifying the request type and path + 2. An optional set of RFC-822-style headers + 3. An optional data part + + The headers and data are separated by a blank line. + + The first line of the request has the form + + + + where is a (case-sensitive) keyword such as GET or POST, + is a string containing path information for the request, + and should be the string "HTTP/1.0" or "HTTP/1.1". + is encoded using the URL encoding scheme (using %xx to signify + the ASCII character with hex code xx). + + The specification specifies that lines are separated by CRLF but + for compatibility with the widest range of clients recommends + servers also handle LF. Similarly, whitespace in the request line + is treated sensibly (allowing multiple spaces between components + and allowing trailing whitespace). + + Similarly, for output, lines ought to be separated by CRLF pairs + but most clients grok LF characters just fine. + + If the first line of the request has the form + + + + (i.e. is left out) then this is assumed to be an HTTP + 0.9 request; this form has no optional headers and data part and + the reply consists of just the data. + + The reply form of the HTTP 1.x protocol again has three parts: + + 1. One line giving the response code + 2. An optional set of RFC-822-style headers + 3. The data + + Again, the headers and data are separated by a blank line. + + The response code line has the form + + + + where is the protocol version ("HTTP/1.0" or "HTTP/1.1"), + is a 3-digit response code indicating success or + failure of the request, and is an optional + human-readable string explaining what the response code means. + + This server parses the request and the headers, and then calls a + function specific to the request type (). Specifically, + a request SPAM will be handled by a method do_SPAM(). If no + such method exists the server sends an error response to the + client. If it exists, it is called with no arguments: + + do_SPAM() + + Note that the request name is case sensitive (i.e. SPAM and spam + are different requests). + + The various request details are stored in instance variables: + + - client_address is the client IP address in the form (host, + port); + + - command, path and version are the broken-down request line; + + - headers is an instance of mimetools.Message (or a derived + class) containing the header information; + + - rfile is a file object open for reading positioned at the + start of the optional input data part; + + - wfile is a file object open for writing. + + IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING! + + The first thing to be written must be the response line. Then + follow 0 or more header lines, then a blank line, and then the + actual data (if any). The meaning of the header lines depends on + the command executed by the server; in most cases, when data is + returned, there should be at least one header line of the form + + Content-type: / + + where and should be registered MIME types, + e.g. "text/html" or "text/plain". + + """ + + # The Python system version, truncated to its first component. + sys_version = "Python/" + sys.version.split()[0] + + # The server software version. You may want to override this. + # The format is multiple whitespace-separated strings, + # where each string is of the form name[/version]. + server_version = "BaseHTTP/" + __version__ + + # The default request version. This only affects responses up until + # the point where the request line is parsed, so it mainly decides what + # the client gets back when sending a malformed request line. + # Most web servers default to HTTP 0.9, i.e. don't send a status line. + default_request_version = "HTTP/0.9" + + def parse_request(self): + """Parse a request (internal). + + The request should be stored in self.raw_requestline; the results + are in self.command, self.path, self.request_version and + self.headers. + + Return True for success, False for failure; on failure, an + error is sent back. + + """ + self.command = None # set in case of error on the first line + self.request_version = version = self.default_request_version + self.close_connection = 1 + requestline = self.raw_requestline + if requestline[-2:] == '\r\n': + requestline = requestline[:-2] + elif requestline[-1:] == '\n': + requestline = requestline[:-1] + self.requestline = requestline + words = requestline.split() + if len(words) == 3: + [command, path, version] = words + if version[:5] != 'HTTP/': + self.send_error(400, "Bad request version (%r)" % version) + return False + try: + base_version_number = version.split('/', 1)[1] + version_number = base_version_number.split(".") + # RFC 2145 section 3.1 says there can be only one "." and + # - major and minor numbers MUST be treated as + # separate integers; + # - HTTP/2.4 is a lower version than HTTP/2.13, which in + # turn is lower than HTTP/12.3; + # - Leading zeros MUST be ignored by recipients. + if len(version_number) != 2: + raise ValueError + version_number = int(version_number[0]), int(version_number[1]) + except (ValueError, IndexError): + self.send_error(400, "Bad request version (%r)" % version) + return False + if version_number >= (1, 1) and self.protocol_version >= "HTTP/1.1": + self.close_connection = 0 + if version_number >= (2, 0): + self.send_error(505, + "Invalid HTTP Version (%s)" % base_version_number) + return False + elif len(words) == 2: + [command, path] = words + self.close_connection = 1 + if command != 'GET': + self.send_error(400, + "Bad HTTP/0.9 request type (%r)" % command) + return False + elif not words: + return False + else: + self.send_error(400, "Bad request syntax (%r)" % requestline) + return False + self.command, self.path, self.request_version = command, path, version + + # Examine the headers and look for a Connection directive + self.headers = self.MessageClass(self.rfile, 0) + + conntype = self.headers.get('Connection', "") + if conntype.lower() == 'close': + self.close_connection = 1 + elif (conntype.lower() == 'keep-alive' and + self.protocol_version >= "HTTP/1.1"): + self.close_connection = 0 + return True + + def handle_one_request(self): + """Handle a single HTTP request. + + You normally don't need to override this method; see the class + __doc__ string for information on how to handle specific HTTP + commands such as GET and POST. + + """ + try: + self.raw_requestline = self.rfile.readline() + if not self.raw_requestline: + self.close_connection = 1 + return + if not self.parse_request(): + # An error code has been sent, just exit + return + mname = 'do_' + self.command + if not hasattr(self, mname): + self.send_error(501, "Unsupported method (%r)" % self.command) + return + method = getattr(self, mname) + method() + self.wfile.flush() #actually send the response if not already done. + except socket.timeout, e: + #a read or a write timed out. Discard this connection + self.log_error("Request timed out: %r", e) + self.close_connection = 1 + return + + def handle(self): + """Handle multiple requests if necessary.""" + self.close_connection = 1 + + self.handle_one_request() + while not self.close_connection: + self.handle_one_request() + + def send_error(self, code, message=None): + """Send and log an error reply. + + Arguments are the error code, and a detailed message. + The detailed message defaults to the short entry matching the + response code. + + This sends an error response (so it must be called before any + output has been generated), logs the error, and finally sends + a piece of HTML explaining the error to the user. + + """ + + try: + short, long = self.responses[code] + except KeyError: + short, long = '???', '???' + if message is None: + message = short + explain = long + self.log_error("code %d, message %s", code, message) + # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201) + content = (self.error_message_format % + {'code': code, 'message': _quote_html(message), 'explain': explain}) + self.send_response(code, message) + self.send_header("Content-Type", self.error_content_type) + self.send_header('Connection', 'close') + self.end_headers() + if self.command != 'HEAD' and code >= 200 and code not in (204, 304): + self.wfile.write(content) + + error_message_format = DEFAULT_ERROR_MESSAGE + error_content_type = DEFAULT_ERROR_CONTENT_TYPE + + def send_response(self, code, message=None): + """Send the response header and log the response code. + + Also send two standard headers with the server software + version and the current date. + + """ + self.log_request(code) + if message is None: + if code in self.responses: + message = self.responses[code][0] + else: + message = '' + if self.request_version != 'HTTP/0.9': + self.wfile.write("%s %d %s\r\n" % + (self.protocol_version, code, message)) + # print (self.protocol_version, code, message) + self.send_header('Server', self.version_string()) + self.send_header('Date', self.date_time_string()) + + def send_header(self, keyword, value): + """Send a MIME header.""" + if self.request_version != 'HTTP/0.9': + self.wfile.write("%s: %s\r\n" % (keyword, value)) + + if keyword.lower() == 'connection': + if value.lower() == 'close': + self.close_connection = 1 + elif value.lower() == 'keep-alive': + self.close_connection = 0 + + def end_headers(self): + """Send the blank line ending the MIME headers.""" + if self.request_version != 'HTTP/0.9': + self.wfile.write("\r\n") + + def log_request(self, code='-', size='-'): + """Log an accepted request. + + This is called by send_response(). + + """ + + self.log_message('"%s" %s %s', + self.requestline, str(code), str(size)) + + def log_error(self, format, *args): + """Log an error. + + This is called when a request cannot be fulfilled. By + default it passes the message on to log_message(). + + Arguments are the same as for log_message(). + + XXX This should go to the separate error log. + + """ + + self.log_message(format, *args) + + def log_message(self, format, *args): + """Log an arbitrary message. + + This is used by all other logging functions. Override + it if you have specific logging wishes. + + The first argument, FORMAT, is a format string for the + message to be logged. If the format string contains + any % escapes requiring parameters, they should be + specified as subsequent arguments (it's just like + printf!). + + The client host and current date/time are prefixed to + every message. + + """ + + sys.stderr.write("%s - - [%s] %s\n" % + (self.address_string(), + self.log_date_time_string(), + format%args)) + + def version_string(self): + """Return the server software version string.""" + return self.server_version + ' ' + self.sys_version + + def date_time_string(self, timestamp=None): + """Return the current date and time formatted for a message header.""" + if timestamp is None: + timestamp = time.time() + year, month, day, hh, mm, ss, wd, y, z = time.gmtime(timestamp) + s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % ( + self.weekdayname[wd], + day, self.monthname[month], year, + hh, mm, ss) + return s + + def log_date_time_string(self): + """Return the current time formatted for logging.""" + now = time.time() + year, month, day, hh, mm, ss, x, y, z = time.localtime(now) + s = "%02d/%3s/%04d %02d:%02d:%02d" % ( + day, self.monthname[month], year, hh, mm, ss) + return s + + weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + + monthname = [None, + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + + def address_string(self): + """Return the client address formatted for logging. + + This version looks up the full hostname using gethostbyaddr(), + and tries to find a name that contains at least one dot. + + """ + + host, port = self.client_address[:2] + return socket.getfqdn(host) + + # Essentially static class variables + + # The version of the HTTP protocol we support. + # Set this to HTTP/1.1 to enable automatic keepalive + protocol_version = "HTTP/1.0" + + # The Message-like class used to parse headers + MessageClass = mimetools.Message + + # Table mapping response codes to messages; entries have the + # form {code: (shortmessage, longmessage)}. + # See RFC 2616. + responses = { + 100: ('Continue', 'Request received, please continue'), + 101: ('Switching Protocols', + 'Switching to new protocol; obey Upgrade header'), + + 200: ('OK', 'Request fulfilled, document follows'), + 201: ('Created', 'Document created, URL follows'), + 202: ('Accepted', + 'Request accepted, processing continues off-line'), + 203: ('Non-Authoritative Information', 'Request fulfilled from cache'), + 204: ('No Content', 'Request fulfilled, nothing follows'), + 205: ('Reset Content', 'Clear input form for further input.'), + 206: ('Partial Content', 'Partial content follows.'), + + 300: ('Multiple Choices', + 'Object has several resources -- see URI list'), + 301: ('Moved Permanently', 'Object moved permanently -- see URI list'), + 302: ('Found', 'Object moved temporarily -- see URI list'), + 303: ('See Other', 'Object moved -- see Method and URL list'), + 304: ('Not Modified', + 'Document has not changed since given time'), + 305: ('Use Proxy', + 'You must use proxy specified in Location to access this ' + 'resource.'), + 307: ('Temporary Redirect', + 'Object moved temporarily -- see URI list'), + + 400: ('Bad Request', + 'Bad request syntax or unsupported method'), + 401: ('Unauthorized', + 'No permission -- see authorization schemes'), + 402: ('Payment Required', + 'No payment -- see charging schemes'), + 403: ('Forbidden', + 'Request forbidden -- authorization will not help'), + 404: ('Not Found', 'Nothing matches the given URI'), + 405: ('Method Not Allowed', + 'Specified method is invalid for this resource.'), + 406: ('Not Acceptable', 'URI not available in preferred format.'), + 407: ('Proxy Authentication Required', 'You must authenticate with ' + 'this proxy before proceeding.'), + 408: ('Request Timeout', 'Request timed out; try again later.'), + 409: ('Conflict', 'Request conflict.'), + 410: ('Gone', + 'URI no longer exists and has been permanently removed.'), + 411: ('Length Required', 'Client must specify Content-Length.'), + 412: ('Precondition Failed', 'Precondition in headers is false.'), + 413: ('Request Entity Too Large', 'Entity is too large.'), + 414: ('Request-URI Too Long', 'URI is too long.'), + 415: ('Unsupported Media Type', 'Entity body in unsupported format.'), + 416: ('Requested Range Not Satisfiable', + 'Cannot satisfy request range.'), + 417: ('Expectation Failed', + 'Expect condition could not be satisfied.'), + + 500: ('Internal Server Error', 'Server got itself in trouble'), + 501: ('Not Implemented', + 'Server does not support this operation'), + 502: ('Bad Gateway', 'Invalid responses from another server/proxy.'), + 503: ('Service Unavailable', + 'The server cannot process the request due to a high load'), + 504: ('Gateway Timeout', + 'The gateway server did not receive a timely response'), + 505: ('HTTP Version Not Supported', 'Cannot fulfill request.'), + } + + +def test(HandlerClass = BaseHTTPRequestHandler, + ServerClass = HTTPServer, protocol="HTTP/1.0"): + """Test the HTTP request handler class. + + This runs an HTTP server on port 8000 (or the first command line + argument). + + """ + + if sys.argv[1:]: + port = int(sys.argv[1]) + else: + port = 8000 + server_address = ('', port) + + HandlerClass.protocol_version = protocol + httpd = ServerClass(server_address, HandlerClass) + + sa = httpd.socket.getsockname() + print "Serving HTTP on", sa[0], "port", sa[1], "..." + httpd.serve_forever() + + +if __name__ == '__main__': + test() diff --git a/src/python/stdlib/Bastion.py b/src/python/stdlib/Bastion.py new file mode 100644 index 000000000..d0dddbfde --- /dev/null +++ b/src/python/stdlib/Bastion.py @@ -0,0 +1,180 @@ +"""Bastionification utility. + +A bastion (for another object -- the 'original') is an object that has +the same methods as the original but does not give access to its +instance variables. Bastions have a number of uses, but the most +obvious one is to provide code executing in restricted mode with a +safe interface to an object implemented in unrestricted mode. + +The bastionification routine has an optional second argument which is +a filter function. Only those methods for which the filter method +(called with the method name as argument) returns true are accessible. +The default filter method returns true unless the method name begins +with an underscore. + +There are a number of possible implementations of bastions. We use a +'lazy' approach where the bastion's __getattr__() discipline does all +the work for a particular method the first time it is used. This is +usually fastest, especially if the user doesn't call all available +methods. The retrieved methods are stored as instance variables of +the bastion, so the overhead is only occurred on the first use of each +method. + +Detail: the bastion class has a __repr__() discipline which includes +the repr() of the original object. This is precomputed when the +bastion is created. + +""" +from warnings import warnpy3k +warnpy3k("the Bastion module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + +__all__ = ["BastionClass", "Bastion"] + +from types import MethodType + + +class BastionClass: + + """Helper class used by the Bastion() function. + + You could subclass this and pass the subclass as the bastionclass + argument to the Bastion() function, as long as the constructor has + the same signature (a get() function and a name for the object). + + """ + + def __init__(self, get, name): + """Constructor. + + Arguments: + + get - a function that gets the attribute value (by name) + name - a human-readable name for the original object + (suggestion: use repr(object)) + + """ + self._get_ = get + self._name_ = name + + def __repr__(self): + """Return a representation string. + + This includes the name passed in to the constructor, so that + if you print the bastion during debugging, at least you have + some idea of what it is. + + """ + return "" % self._name_ + + def __getattr__(self, name): + """Get an as-yet undefined attribute value. + + This calls the get() function that was passed to the + constructor. The result is stored as an instance variable so + that the next time the same attribute is requested, + __getattr__() won't be invoked. + + If the get() function raises an exception, this is simply + passed on -- exceptions are not cached. + + """ + attribute = self._get_(name) + self.__dict__[name] = attribute + return attribute + + +def Bastion(object, filter = lambda name: name[:1] != '_', + name=None, bastionclass=BastionClass): + """Create a bastion for an object, using an optional filter. + + See the Bastion module's documentation for background. + + Arguments: + + object - the original object + filter - a predicate that decides whether a function name is OK; + by default all names are OK that don't start with '_' + name - the name of the object; default repr(object) + bastionclass - class used to create the bastion; default BastionClass + + """ + + raise RuntimeError, "This code is not secure in Python 2.2 and later" + + # Note: we define *two* ad-hoc functions here, get1 and get2. + # Both are intended to be called in the same way: get(name). + # It is clear that the real work (getting the attribute + # from the object and calling the filter) is done in get1. + # Why can't we pass get1 to the bastion? Because the user + # would be able to override the filter argument! With get2, + # overriding the default argument is no security loophole: + # all it does is call it. + # Also notice that we can't place the object and filter as + # instance variables on the bastion object itself, since + # the user has full access to all instance variables! + + def get1(name, object=object, filter=filter): + """Internal function for Bastion(). See source comments.""" + if filter(name): + attribute = getattr(object, name) + if type(attribute) == MethodType: + return attribute + raise AttributeError, name + + def get2(name, get1=get1): + """Internal function for Bastion(). See source comments.""" + return get1(name) + + if name is None: + name = repr(object) + return bastionclass(get2, name) + + +def _test(): + """Test the Bastion() function.""" + class Original: + def __init__(self): + self.sum = 0 + def add(self, n): + self._add(n) + def _add(self, n): + self.sum = self.sum + n + def total(self): + return self.sum + o = Original() + b = Bastion(o) + testcode = """if 1: + b.add(81) + b.add(18) + print "b.total() =", b.total() + try: + print "b.sum =", b.sum, + except: + print "inaccessible" + else: + print "accessible" + try: + print "b._add =", b._add, + except: + print "inaccessible" + else: + print "accessible" + try: + print "b._get_.func_defaults =", map(type, b._get_.func_defaults), + except: + print "inaccessible" + else: + print "accessible" + \n""" + exec testcode + print '='*20, "Using rexec:", '='*20 + import rexec + r = rexec.RExec() + m = r.add_module('__main__') + m.b = b + r.r_exec(testcode) + + +if __name__ == '__main__': + _test() diff --git a/src/python/stdlib/CGIHTTPServer.py b/src/python/stdlib/CGIHTTPServer.py new file mode 100644 index 000000000..13ca0b514 --- /dev/null +++ b/src/python/stdlib/CGIHTTPServer.py @@ -0,0 +1,374 @@ +"""CGI-savvy HTTP Server. + +This module builds on SimpleHTTPServer by implementing GET and POST +requests to cgi-bin scripts. + +If the os.fork() function is not present (e.g. on Windows), +os.popen2() is used as a fallback, with slightly altered semantics; if +that function is not present either (e.g. on Macintosh), only Python +scripts are supported, and they are executed by the current process. + +In all cases, the implementation is intentionally naive -- all +requests are executed sychronously. + +SECURITY WARNING: DON'T USE THIS CODE UNLESS YOU ARE INSIDE A FIREWALL +-- it may execute arbitrary Python code or external programs. + +Note that status code 200 is sent prior to execution of a CGI script, so +scripts cannot send other status codes such as 302 (redirect). +""" + + +__version__ = "0.4" + +__all__ = ["CGIHTTPRequestHandler"] + +import os +import sys +import urllib +import BaseHTTPServer +import SimpleHTTPServer +import select +import copy + + +class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): + + """Complete HTTP server with GET, HEAD and POST commands. + + GET and HEAD also support running CGI scripts. + + The POST command is *only* implemented for CGI scripts. + + """ + + # Determine platform specifics + have_fork = hasattr(os, 'fork') + have_popen2 = hasattr(os, 'popen2') + have_popen3 = hasattr(os, 'popen3') + + # Make rfile unbuffered -- we need to read one line and then pass + # the rest to a subprocess, so we can't use buffered input. + rbufsize = 0 + + def do_POST(self): + """Serve a POST request. + + This is only implemented for CGI scripts. + + """ + + if self.is_cgi(): + self.run_cgi() + else: + self.send_error(501, "Can only POST to CGI scripts") + + def send_head(self): + """Version of send_head that support CGI scripts""" + if self.is_cgi(): + return self.run_cgi() + else: + return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self) + + def is_cgi(self): + """Test whether self.path corresponds to a CGI script. + + Returns True and updates the cgi_info attribute to the tuple + (dir, rest) if self.path requires running a CGI script. + Returns False otherwise. + + If any exception is raised, the caller should assume that + self.path was rejected as invalid and act accordingly. + + The default implementation tests whether the normalized url + path begins with one of the strings in self.cgi_directories + (and the next character is a '/' or the end of the string). + """ + splitpath = _url_collapse_path_split(self.path) + if splitpath[0] in self.cgi_directories: + self.cgi_info = splitpath + return True + return False + + cgi_directories = ['/cgi-bin', '/htbin'] + + def is_executable(self, path): + """Test whether argument path is an executable file.""" + return executable(path) + + def is_python(self, path): + """Test whether argument path is a Python script.""" + head, tail = os.path.splitext(path) + return tail.lower() in (".py", ".pyw") + + def run_cgi(self): + """Execute a CGI script.""" + path = self.path + dir, rest = self.cgi_info + + i = path.find('/', len(dir) + 1) + while i >= 0: + nextdir = path[:i] + nextrest = path[i+1:] + + scriptdir = self.translate_path(nextdir) + if os.path.isdir(scriptdir): + dir, rest = nextdir, nextrest + i = path.find('/', len(dir) + 1) + else: + break + + # find an explicit query string, if present. + i = rest.rfind('?') + if i >= 0: + rest, query = rest[:i], rest[i+1:] + else: + query = '' + + # dissect the part after the directory name into a script name & + # a possible additional path, to be stored in PATH_INFO. + i = rest.find('/') + if i >= 0: + script, rest = rest[:i], rest[i:] + else: + script, rest = rest, '' + + scriptname = dir + '/' + script + scriptfile = self.translate_path(scriptname) + if not os.path.exists(scriptfile): + self.send_error(404, "No such CGI script (%r)" % scriptname) + return + if not os.path.isfile(scriptfile): + self.send_error(403, "CGI script is not a plain file (%r)" % + scriptname) + return + ispy = self.is_python(scriptname) + if not ispy: + if not (self.have_fork or self.have_popen2 or self.have_popen3): + self.send_error(403, "CGI script is not a Python script (%r)" % + scriptname) + return + if not self.is_executable(scriptfile): + self.send_error(403, "CGI script is not executable (%r)" % + scriptname) + return + + # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html + # XXX Much of the following could be prepared ahead of time! + env = copy.deepcopy(os.environ) + env['SERVER_SOFTWARE'] = self.version_string() + env['SERVER_NAME'] = self.server.server_name + env['GATEWAY_INTERFACE'] = 'CGI/1.1' + env['SERVER_PROTOCOL'] = self.protocol_version + env['SERVER_PORT'] = str(self.server.server_port) + env['REQUEST_METHOD'] = self.command + uqrest = urllib.unquote(rest) + env['PATH_INFO'] = uqrest + env['PATH_TRANSLATED'] = self.translate_path(uqrest) + env['SCRIPT_NAME'] = scriptname + if query: + env['QUERY_STRING'] = query + host = self.address_string() + if host != self.client_address[0]: + env['REMOTE_HOST'] = host + env['REMOTE_ADDR'] = self.client_address[0] + authorization = self.headers.getheader("authorization") + if authorization: + authorization = authorization.split() + if len(authorization) == 2: + import base64, binascii + env['AUTH_TYPE'] = authorization[0] + if authorization[0].lower() == "basic": + try: + authorization = base64.decodestring(authorization[1]) + except binascii.Error: + pass + else: + authorization = authorization.split(':') + if len(authorization) == 2: + env['REMOTE_USER'] = authorization[0] + # XXX REMOTE_IDENT + if self.headers.typeheader is None: + env['CONTENT_TYPE'] = self.headers.type + else: + env['CONTENT_TYPE'] = self.headers.typeheader + length = self.headers.getheader('content-length') + if length: + env['CONTENT_LENGTH'] = length + referer = self.headers.getheader('referer') + if referer: + env['HTTP_REFERER'] = referer + accept = [] + for line in self.headers.getallmatchingheaders('accept'): + if line[:1] in "\t\n\r ": + accept.append(line.strip()) + else: + accept = accept + line[7:].split(',') + env['HTTP_ACCEPT'] = ','.join(accept) + ua = self.headers.getheader('user-agent') + if ua: + env['HTTP_USER_AGENT'] = ua + co = filter(None, self.headers.getheaders('cookie')) + if co: + env['HTTP_COOKIE'] = ', '.join(co) + # XXX Other HTTP_* headers + # Since we're setting the env in the parent, provide empty + # values to override previously set values + for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH', + 'HTTP_USER_AGENT', 'HTTP_COOKIE', 'HTTP_REFERER'): + env.setdefault(k, "") + + self.send_response(200, "Script output follows") + + decoded_query = query.replace('+', ' ') + + if self.have_fork: + # Unix -- fork as we should + args = [script] + if '=' not in decoded_query: + args.append(decoded_query) + nobody = nobody_uid() + self.wfile.flush() # Always flush before forking + pid = os.fork() + if pid != 0: + # Parent + pid, sts = os.waitpid(pid, 0) + # throw away additional data [see bug #427345] + while select.select([self.rfile], [], [], 0)[0]: + if not self.rfile.read(1): + break + if sts: + self.log_error("CGI script exit status %#x", sts) + return + # Child + try: + try: + os.setuid(nobody) + except os.error: + pass + os.dup2(self.rfile.fileno(), 0) + os.dup2(self.wfile.fileno(), 1) + os.execve(scriptfile, args, env) + except: + self.server.handle_error(self.request, self.client_address) + os._exit(127) + + else: + # Non Unix - use subprocess + import subprocess + cmdline = [scriptfile] + if self.is_python(scriptfile): + interp = sys.executable + if interp.lower().endswith("w.exe"): + # On Windows, use python.exe, not pythonw.exe + interp = interp[:-5] + interp[-4:] + cmdline = [interp, '-u'] + cmdline + if '=' not in query: + cmdline.append(query) + + self.log_message("command: %s", subprocess.list2cmdline(cmdline)) + try: + nbytes = int(length) + except (TypeError, ValueError): + nbytes = 0 + p = subprocess.Popen(cmdline, + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + env = env + ) + if self.command.lower() == "post" and nbytes > 0: + data = self.rfile.read(nbytes) + else: + data = None + # throw away additional data [see bug #427345] + while select.select([self.rfile._sock], [], [], 0)[0]: + if not self.rfile._sock.recv(1): + break + stdout, stderr = p.communicate(data) + self.wfile.write(stdout) + if stderr: + self.log_error('%s', stderr) + p.stderr.close() + p.stdout.close() + status = p.returncode + if status: + self.log_error("CGI script exit status %#x", status) + else: + self.log_message("CGI script exited OK") + + +# TODO(gregory.p.smith): Move this into an appropriate library. +def _url_collapse_path_split(path): + """ + Given a URL path, remove extra '/'s and '.' path elements and collapse + any '..' references. + + Implements something akin to RFC-2396 5.2 step 6 to parse relative paths. + + Returns: A tuple of (head, tail) where tail is everything after the final / + and head is everything before it. Head will always start with a '/' and, + if it contains anything else, never have a trailing '/'. + + Raises: IndexError if too many '..' occur within the path. + """ + # Similar to os.path.split(os.path.normpath(path)) but specific to URL + # path semantics rather than local operating system semantics. + path_parts = [] + for part in path.split('/'): + if part == '.': + path_parts.append('') + else: + path_parts.append(part) + # Filter out blank non trailing parts before consuming the '..'. + path_parts = [part for part in path_parts[:-1] if part] + path_parts[-1:] + if path_parts: + tail_part = path_parts.pop() + else: + tail_part = '' + head_parts = [] + for part in path_parts: + if part == '..': + head_parts.pop() + else: + head_parts.append(part) + if tail_part and tail_part == '..': + head_parts.pop() + tail_part = '' + return ('/' + '/'.join(head_parts), tail_part) + + +nobody = None + +def nobody_uid(): + """Internal routine to get nobody's uid""" + global nobody + if nobody: + return nobody + try: + import pwd + except ImportError: + return -1 + try: + nobody = pwd.getpwnam('nobody')[2] + except KeyError: + nobody = 1 + max(map(lambda x: x[2], pwd.getpwall())) + return nobody + + +def executable(path): + """Test for executable file.""" + try: + st = os.stat(path) + except os.error: + return False + return st.st_mode & 0111 != 0 + + +def test(HandlerClass = CGIHTTPRequestHandler, + ServerClass = BaseHTTPServer.HTTPServer): + SimpleHTTPServer.test(HandlerClass, ServerClass) + + +if __name__ == '__main__': + test() diff --git a/src/python/stdlib/ConfigParser.py b/src/python/stdlib/ConfigParser.py new file mode 100644 index 000000000..dc7398841 --- /dev/null +++ b/src/python/stdlib/ConfigParser.py @@ -0,0 +1,711 @@ +"""Configuration file parser. + +A setup file consists of sections, lead by a "[section]" header, +and followed by "name: value" entries, with continuations and such in +the style of RFC 822. + +The option values can contain format strings which refer to other values in +the same section, or values in a special [DEFAULT] section. + +For example: + + something: %(dir)s/whatever + +would resolve the "%(dir)s" to the value of dir. All reference +expansions are done late, on demand. + +Intrinsic defaults can be specified by passing them into the +ConfigParser constructor as a dictionary. + +class: + +ConfigParser -- responsible for parsing a list of + configuration files, and managing the parsed database. + + methods: + + __init__(defaults=None) + create the parser and specify a dictionary of intrinsic defaults. The + keys must be strings, the values must be appropriate for %()s string + interpolation. Note that `__name__' is always an intrinsic default; + its value is the section's name. + + sections() + return all the configuration section names, sans DEFAULT + + has_section(section) + return whether the given section exists + + has_option(section, option) + return whether the given option exists in the given section + + options(section) + return list of configuration options for the named section + + read(filenames) + read and parse the list of named configuration files, given by + name. A single filename is also allowed. Non-existing files + are ignored. Return list of successfully read files. + + readfp(fp, filename=None) + read and parse one configuration file, given as a file object. + The filename defaults to fp.name; it is only used in error + messages (if fp has no `name' attribute, the string `' is used). + + get(section, option, raw=False, vars=None) + return a string value for the named option. All % interpolations are + expanded in the return values, based on the defaults passed into the + constructor and the DEFAULT section. Additional substitutions may be + provided using the `vars' argument, which must be a dictionary whose + contents override any pre-existing defaults. + + getint(section, options) + like get(), but convert value to an integer + + getfloat(section, options) + like get(), but convert value to a float + + getboolean(section, options) + like get(), but convert value to a boolean (currently case + insensitively defined as 0, false, no, off for False, and 1, true, + yes, on for True). Returns False or True. + + items(section, raw=False, vars=None) + return a list of tuples with (name, value) for each option + in the section. + + remove_section(section) + remove the given file section and all its options + + remove_option(section, option) + remove the given option from the given section + + set(section, option, value) + set the given option + + write(fp) + write the configuration state in .ini format +""" + +try: + from collections import OrderedDict as _default_dict +except ImportError: + # fallback for setup.py which hasn't yet built _collections + _default_dict = dict + +import re + +__all__ = ["NoSectionError", "DuplicateSectionError", "NoOptionError", + "InterpolationError", "InterpolationDepthError", + "InterpolationSyntaxError", "ParsingError", + "MissingSectionHeaderError", + "ConfigParser", "SafeConfigParser", "RawConfigParser", + "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] + +DEFAULTSECT = "DEFAULT" + +MAX_INTERPOLATION_DEPTH = 10 + + + +# exception classes +class Error(Exception): + """Base class for ConfigParser exceptions.""" + + def _get_message(self): + """Getter for 'message'; needed only to override deprecation in + BaseException.""" + return self.__message + + def _set_message(self, value): + """Setter for 'message'; needed only to override deprecation in + BaseException.""" + self.__message = value + + # BaseException.message has been deprecated since Python 2.6. To prevent + # DeprecationWarning from popping up over this pre-existing attribute, use + # a new property that takes lookup precedence. + message = property(_get_message, _set_message) + + def __init__(self, msg=''): + self.message = msg + Exception.__init__(self, msg) + + def __repr__(self): + return self.message + + __str__ = __repr__ + +class NoSectionError(Error): + """Raised when no section matches a requested option.""" + + def __init__(self, section): + Error.__init__(self, 'No section: %r' % (section,)) + self.section = section + +class DuplicateSectionError(Error): + """Raised when a section is multiply-created.""" + + def __init__(self, section): + Error.__init__(self, "Section %r already exists" % section) + self.section = section + +class NoOptionError(Error): + """A requested option was not found.""" + + def __init__(self, option, section): + Error.__init__(self, "No option %r in section: %r" % + (option, section)) + self.option = option + self.section = section + +class InterpolationError(Error): + """Base class for interpolation-related exceptions.""" + + def __init__(self, option, section, msg): + Error.__init__(self, msg) + self.option = option + self.section = section + +class InterpolationMissingOptionError(InterpolationError): + """A string substitution required a setting which was not available.""" + + def __init__(self, option, section, rawval, reference): + msg = ("Bad value substitution:\n" + "\tsection: [%s]\n" + "\toption : %s\n" + "\tkey : %s\n" + "\trawval : %s\n" + % (section, option, reference, rawval)) + InterpolationError.__init__(self, option, section, msg) + self.reference = reference + +class InterpolationSyntaxError(InterpolationError): + """Raised when the source text into which substitutions are made + does not conform to the required syntax.""" + +class InterpolationDepthError(InterpolationError): + """Raised when substitutions are nested too deeply.""" + + def __init__(self, option, section, rawval): + msg = ("Value interpolation too deeply recursive:\n" + "\tsection: [%s]\n" + "\toption : %s\n" + "\trawval : %s\n" + % (section, option, rawval)) + InterpolationError.__init__(self, option, section, msg) + +class ParsingError(Error): + """Raised when a configuration file does not follow legal syntax.""" + + def __init__(self, filename): + Error.__init__(self, 'File contains parsing errors: %s' % filename) + self.filename = filename + self.errors = [] + + def append(self, lineno, line): + self.errors.append((lineno, line)) + self.message += '\n\t[line %2d]: %s' % (lineno, line) + +class MissingSectionHeaderError(ParsingError): + """Raised when a key-value pair is found before any section header.""" + + def __init__(self, filename, lineno, line): + Error.__init__( + self, + 'File contains no section headers.\nfile: %s, line: %d\n%r' % + (filename, lineno, line)) + self.filename = filename + self.lineno = lineno + self.line = line + + +class RawConfigParser: + def __init__(self, defaults=None, dict_type=_default_dict, + allow_no_value=False): + self._dict = dict_type + self._sections = self._dict() + self._defaults = self._dict() + if allow_no_value: + self._optcre = self.OPTCRE_NV + else: + self._optcre = self.OPTCRE + if defaults: + for key, value in defaults.items(): + self._defaults[self.optionxform(key)] = value + + def defaults(self): + return self._defaults + + def sections(self): + """Return a list of section names, excluding [DEFAULT]""" + # self._sections will never have [DEFAULT] in it + return self._sections.keys() + + def add_section(self, section): + """Create a new section in the configuration. + + Raise DuplicateSectionError if a section by the specified name + already exists. Raise ValueError if name is DEFAULT or any of it's + case-insensitive variants. + """ + if section.lower() == "default": + raise ValueError, 'Invalid section name: %s' % section + + if section in self._sections: + raise DuplicateSectionError(section) + self._sections[section] = self._dict() + + def has_section(self, section): + """Indicate whether the named section is present in the configuration. + + The DEFAULT section is not acknowledged. + """ + return section in self._sections + + def options(self, section): + """Return a list of option names for the given section name.""" + try: + opts = self._sections[section].copy() + except KeyError: + raise NoSectionError(section) + opts.update(self._defaults) + if '__name__' in opts: + del opts['__name__'] + return opts.keys() + + def read(self, filenames): + """Read and parse a filename or a list of filenames. + + Files that cannot be opened are silently ignored; this is + designed so that you can specify a list of potential + configuration file locations (e.g. current directory, user's + home directory, systemwide directory), and all existing + configuration files in the list will be read. A single + filename may also be given. + + Return list of successfully read files. + """ + if isinstance(filenames, basestring): + filenames = [filenames] + read_ok = [] + for filename in filenames: + try: + fp = open(filename) + except IOError: + continue + self._read(fp, filename) + fp.close() + read_ok.append(filename) + return read_ok + + def readfp(self, fp, filename=None): + """Like read() but the argument must be a file-like object. + + The `fp' argument must have a `readline' method. Optional + second argument is the `filename', which if not given, is + taken from fp.name. If fp has no `name' attribute, `' is + used. + + """ + if filename is None: + try: + filename = fp.name + except AttributeError: + filename = '' + self._read(fp, filename) + + def get(self, section, option): + opt = self.optionxform(option) + if section not in self._sections: + if section != DEFAULTSECT: + raise NoSectionError(section) + if opt in self._defaults: + return self._defaults[opt] + else: + raise NoOptionError(option, section) + elif opt in self._sections[section]: + return self._sections[section][opt] + elif opt in self._defaults: + return self._defaults[opt] + else: + raise NoOptionError(option, section) + + def items(self, section): + try: + d2 = self._sections[section] + except KeyError: + if section != DEFAULTSECT: + raise NoSectionError(section) + d2 = self._dict() + d = self._defaults.copy() + d.update(d2) + if "__name__" in d: + del d["__name__"] + return d.items() + + def _get(self, section, conv, option): + return conv(self.get(section, option)) + + def getint(self, section, option): + return self._get(section, int, option) + + def getfloat(self, section, option): + return self._get(section, float, option) + + _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True, + '0': False, 'no': False, 'false': False, 'off': False} + + def getboolean(self, section, option): + v = self.get(section, option) + if v.lower() not in self._boolean_states: + raise ValueError, 'Not a boolean: %s' % v + return self._boolean_states[v.lower()] + + def optionxform(self, optionstr): + return optionstr.lower() + + def has_option(self, section, option): + """Check for the existence of a given option in a given section.""" + if not section or section == DEFAULTSECT: + option = self.optionxform(option) + return option in self._defaults + elif section not in self._sections: + return False + else: + option = self.optionxform(option) + return (option in self._sections[section] + or option in self._defaults) + + def set(self, section, option, value=None): + """Set an option.""" + if not section or section == DEFAULTSECT: + sectdict = self._defaults + else: + try: + sectdict = self._sections[section] + except KeyError: + raise NoSectionError(section) + sectdict[self.optionxform(option)] = value + + def write(self, fp): + """Write an .ini-format representation of the configuration state.""" + if self._defaults: + fp.write("[%s]\n" % DEFAULTSECT) + for (key, value) in self._defaults.items(): + fp.write("%s = %s\n" % (key, str(value).replace('\n', '\n\t'))) + fp.write("\n") + for section in self._sections: + fp.write("[%s]\n" % section) + for (key, value) in self._sections[section].items(): + if key == "__name__": + continue + if (value is not None) or (self._optcre == self.OPTCRE): + key = " = ".join((key, str(value).replace('\n', '\n\t'))) + fp.write("%s\n" % (key)) + fp.write("\n") + + def remove_option(self, section, option): + """Remove an option.""" + if not section or section == DEFAULTSECT: + sectdict = self._defaults + else: + try: + sectdict = self._sections[section] + except KeyError: + raise NoSectionError(section) + option = self.optionxform(option) + existed = option in sectdict + if existed: + del sectdict[option] + return existed + + def remove_section(self, section): + """Remove a file section.""" + existed = section in self._sections + if existed: + del self._sections[section] + return existed + + # + # Regular expressions for parsing section headers and options. + # + SECTCRE = re.compile( + r'\[' # [ + r'(?P

[^]]+)' # very permissive! + r'\]' # ] + ) + OPTCRE = re.compile( + r'(?P