diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.py
new file mode 100644
index 0000000..efeed79
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.py
@@ -0,0 +1,4 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.pyc
new file mode 100644
index 0000000..066aed3
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.py
new file mode 100644
index 0000000..7a16dfe
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.py
@@ -0,0 +1,11 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.Configure import conf
+@conf
+def find_ar(conf):
+	conf.load('ar')
+def configure(conf):
+	conf.find_program('ar',var='AR')
+	conf.env.ARFLAGS='rcs'
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.pyc
new file mode 100644
index 0000000..2c1968b
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/asm.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/asm.py
new file mode 100644
index 0000000..b9ed5f4
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/asm.py
@@ -0,0 +1,25 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Task,Utils
+import waflib.Task
+from waflib.Tools.ccroot import link_task,stlink_task
+from waflib.TaskGen import extension,feature
+class asm(Task.Task):
+	color='BLUE'
+	run_str='${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
+@extension('.s','.S','.asm','.ASM','.spp','.SPP')
+def asm_hook(self,node):
+	return self.create_compiled_task('asm',node)
+class asmprogram(link_task):
+	run_str='${ASLINK} ${ASLINKFLAGS} ${ASLNK_TGT_F}${TGT} ${ASLNK_SRC_F}${SRC}'
+	ext_out=['.bin']
+	inst_to='${BINDIR}'
+class asmshlib(asmprogram):
+	inst_to='${LIBDIR}'
+class asmstlib(stlink_task):
+	pass
+def configure(conf):
+	conf.env['ASMPATH_ST']='-I%s'
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/bison.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/bison.py
new file mode 100644
index 0000000..6ae7898
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/bison.py
@@ -0,0 +1,28 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Task
+from waflib.TaskGen import extension
+class bison(Task.Task):
+	color='BLUE'
+	run_str='${BISON} ${BISONFLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}'
+	ext_out=['.h']
+@extension('.y','.yc','.yy')
+def big_bison(self,node):
+	has_h='-d'in self.env['BISONFLAGS']
+	outs=[]
+	if node.name.endswith('.yc'):
+		outs.append(node.change_ext('.tab.cc'))
+		if has_h:
+			outs.append(node.change_ext('.tab.hh'))
+	else:
+		outs.append(node.change_ext('.tab.c'))
+		if has_h:
+			outs.append(node.change_ext('.tab.h'))
+	tsk=self.create_task('bison',node,outs)
+	tsk.cwd=node.parent.get_bld().abspath()
+	self.source.append(outs[0])
+def configure(conf):
+	conf.find_program('bison',var='BISON')
+	conf.env.BISONFLAGS=['-d']
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.py
new file mode 100644
index 0000000..4d8cbd5
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.py
@@ -0,0 +1,24 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import TaskGen,Task,Utils
+from waflib.Tools import c_preproc
+from waflib.Tools.ccroot import link_task,stlink_task
+@TaskGen.extension('.c')
+def c_hook(self,node):
+	return self.create_compiled_task('c',node)
+class c(Task.Task):
+	run_str='${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT}'
+	vars=['CCDEPS']
+	ext_in=['.h']
+	scan=c_preproc.scan
+class cprogram(link_task):
+	run_str='${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}'
+	ext_out=['.bin']
+	vars=['LINKDEPS']
+	inst_to='${BINDIR}'
+class cshlib(cprogram):
+	inst_to='${LIBDIR}'
+class cstlib(stlink_task):
+	pass
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.pyc
new file mode 100644
index 0000000..f40f66b
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.py
new file mode 100644
index 0000000..a3a2bb9
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.py
@@ -0,0 +1,55 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,re
+from waflib import Utils,Build
+from waflib.Configure import conf
+def get_extensions(lst):
+	ret=[]
+	for x in Utils.to_list(lst):
+		try:
+			if not isinstance(x,str):
+				x=x.name
+			ret.append(x[x.rfind('.')+1:])
+		except Exception:
+			pass
+	return ret
+def sniff_features(**kw):
+	exts=get_extensions(kw['source'])
+	type=kw['_type']
+	feats=[]
+	if'cxx'in exts or'cpp'in exts or'c++'in exts or'cc'in exts or'C'in exts:
+		feats.append('cxx')
+	if'c'in exts or'vala'in exts:
+		feats.append('c')
+	if'd'in exts:
+		feats.append('d')
+	if'java'in exts:
+		feats.append('java')
+	if'java'in exts:
+		return'java'
+	if type in['program','shlib','stlib']:
+		for x in feats:
+			if x in['cxx','d','c']:
+				feats.append(x+type)
+	return feats
+def set_features(kw,_type):
+	kw['_type']=_type
+	kw['features']=Utils.to_list(kw.get('features',[]))+Utils.to_list(sniff_features(**kw))
+@conf
+def program(bld,*k,**kw):
+	set_features(kw,'program')
+	return bld(*k,**kw)
+@conf
+def shlib(bld,*k,**kw):
+	set_features(kw,'shlib')
+	return bld(*k,**kw)
+@conf
+def stlib(bld,*k,**kw):
+	set_features(kw,'stlib')
+	return bld(*k,**kw)
+@conf
+def objects(bld,*k,**kw):
+	set_features(kw,'objects')
+	return bld(*k,**kw)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.pyc
new file mode 100644
index 0000000..8f3eb0c
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.py
new file mode 100755
index 0000000..690aa65
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.py
@@ -0,0 +1,729 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re,shlex,sys
+from waflib import Build,Utils,Task,Options,Logs,Errors,ConfigSet,Runner
+from waflib.TaskGen import after_method,feature
+from waflib.Configure import conf
+WAF_CONFIG_H='config.h'
+DEFKEYS='define_key'
+INCKEYS='include_key'
+cfg_ver={'atleast-version':'>=','exact-version':'==','max-version':'<=',}
+SNIP_FUNCTION='''
+int main(int argc, char **argv) {
+	void *p;
+	(void)argc; (void)argv;
+	p=(void*)(%s);
+	return 0;
+}
+'''
+SNIP_TYPE='''
+int main(int argc, char **argv) {
+	(void)argc; (void)argv;
+	if ((%(type_name)s *) 0) return 0;
+	if (sizeof (%(type_name)s)) return 0;
+	return 1;
+}
+'''
+SNIP_EMPTY_PROGRAM='''
+int main(int argc, char **argv) {
+	(void)argc; (void)argv;
+	return 0;
+}
+'''
+SNIP_FIELD='''
+int main(int argc, char **argv) {
+	char *off;
+	(void)argc; (void)argv;
+	off = (char*) &((%(type_name)s*)0)->%(field_name)s;
+	return (size_t) off < sizeof(%(type_name)s);
+}
+'''
+MACRO_TO_DESTOS={'__linux__':'linux','__GNU__':'gnu','__FreeBSD__':'freebsd','__NetBSD__':'netbsd','__OpenBSD__':'openbsd','__sun':'sunos','__hpux':'hpux','__sgi':'irix','_AIX':'aix','__CYGWIN__':'cygwin','__MSYS__':'msys','_UWIN':'uwin','_WIN64':'win32','_WIN32':'win32','__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__':'darwin','__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__':'darwin','__QNX__':'qnx','__native_client__':'nacl'}
+MACRO_TO_DEST_CPU={'__x86_64__':'x86_64','__amd64__':'x86_64','__i386__':'x86','__ia64__':'ia','__mips__':'mips','__sparc__':'sparc','__alpha__':'alpha','__aarch64__':'aarch64','__thumb__':'thumb','__arm__':'arm','__hppa__':'hppa','__powerpc__':'powerpc','__ppc__':'powerpc','__convex__':'convex','__m68k__':'m68k','__s390x__':'s390x','__s390__':'s390','__sh__':'sh',}
+@conf
+def parse_flags(self,line,uselib_store,env=None,force_static=False):
+	assert(isinstance(line,str))
+	env=env or self.env
+	app=env.append_value
+	appu=env.append_unique
+	lex=shlex.shlex(line,posix=False)
+	lex.whitespace_split=True
+	lex.commenters=''
+	lst=list(lex)
+	uselib=uselib_store
+	while lst:
+		x=lst.pop(0)
+		st=x[:2]
+		ot=x[2:]
+		if st=='-I'or st=='/I':
+			if not ot:ot=lst.pop(0)
+			appu('INCLUDES_'+uselib,[ot])
+		elif st=='-include':
+			tmp=[x,lst.pop(0)]
+			app('CFLAGS',tmp)
+			app('CXXFLAGS',tmp)
+		elif st=='-D'or(env.CXX_NAME=='msvc'and st=='/D'):
+			if not ot:ot=lst.pop(0)
+			app('DEFINES_'+uselib,[ot])
+		elif st=='-l':
+			if not ot:ot=lst.pop(0)
+			prefix=force_static and'STLIB_'or'LIB_'
+			appu(prefix+uselib,[ot])
+		elif st=='-L':
+			if not ot:ot=lst.pop(0)
+			appu('LIBPATH_'+uselib,[ot])
+		elif x.startswith('/LIBPATH:'):
+			appu('LIBPATH_'+uselib,[x.replace('/LIBPATH:','')])
+		elif x=='-pthread'or x.startswith('+')or x.startswith('-std'):
+			app('CFLAGS_'+uselib,[x])
+			app('CXXFLAGS_'+uselib,[x])
+			app('LINKFLAGS_'+uselib,[x])
+		elif x=='-framework':
+			appu('FRAMEWORK_'+uselib,[lst.pop(0)])
+		elif x.startswith('-F'):
+			appu('FRAMEWORKPATH_'+uselib,[x[2:]])
+		elif x.startswith('-Wl'):
+			app('LINKFLAGS_'+uselib,[x])
+		elif x.startswith('-m')or x.startswith('-f')or x.startswith('-dynamic'):
+			app('CFLAGS_'+uselib,[x])
+			app('CXXFLAGS_'+uselib,[x])
+		elif x.startswith('-bundle'):
+			app('LINKFLAGS_'+uselib,[x])
+		elif x.startswith('-undefined'):
+			arg=lst.pop(0)
+			app('LINKFLAGS_'+uselib,[x,arg])
+		elif x.startswith('-arch')or x.startswith('-isysroot'):
+			tmp=[x,lst.pop(0)]
+			app('CFLAGS_'+uselib,tmp)
+			app('CXXFLAGS_'+uselib,tmp)
+			app('LINKFLAGS_'+uselib,tmp)
+		elif x.endswith('.a')or x.endswith('.so')or x.endswith('.dylib')or x.endswith('.lib'):
+			appu('LINKFLAGS_'+uselib,[x])
+@conf
+def ret_msg(self,f,kw):
+	if isinstance(f,str):
+		return f
+	return f(kw)
+@conf
+def validate_cfg(self,kw):
+	if not'path'in kw:
+		if not self.env.PKGCONFIG:
+			self.find_program('pkg-config',var='PKGCONFIG')
+		kw['path']=self.env.PKGCONFIG
+	if'atleast_pkgconfig_version'in kw:
+		if not'msg'in kw:
+			kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version']
+		return
+	if not'okmsg'in kw:
+		kw['okmsg']='yes'
+	if not'errmsg'in kw:
+		kw['errmsg']='not found'
+	if'modversion'in kw:
+		if not'msg'in kw:
+			kw['msg']='Checking for %r version'%kw['modversion']
+		return
+	for x in cfg_ver.keys():
+		y=x.replace('-','_')
+		if y in kw:
+			if not'package'in kw:
+				raise ValueError('%s requires a package'%x)
+			if not'msg'in kw:
+				kw['msg']='Checking for %r %s %s'%(kw['package'],cfg_ver[x],kw[y])
+			return
+	if not'msg'in kw:
+		kw['msg']='Checking for %r'%(kw['package']or kw['path'])
+@conf
+def exec_cfg(self,kw):
+	def define_it():
+		self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0)
+	env=kw.get('env',self.env)
+	run_env=env.env or os.environ
+	if'atleast_pkgconfig_version'in kw:
+		cmd=[kw['path'],'--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
+		self.cmd_and_log(cmd,env=run_env)
+		if not'okmsg'in kw:
+			kw['okmsg']='yes'
+		return
+	for x in cfg_ver:
+		y=x.replace('-','_')
+		if y in kw:
+			self.cmd_and_log([kw['path'],'--%s=%s'%(x,kw[y]),kw['package']],env=run_env)
+			if not'okmsg'in kw:
+				kw['okmsg']='yes'
+			define_it()
+			break
+	if'modversion'in kw:
+		version=self.cmd_and_log([kw['path'],'--modversion',kw['modversion']],env=run_env).strip()
+		self.define('%s_VERSION'%Utils.quote_define_name(kw.get('uselib_store',kw['modversion'])),version)
+		return version
+	lst=[kw['path']]
+	defi=kw.get('define_variable',None)
+	if not defi:
+		defi=self.env.PKG_CONFIG_DEFINES or{}
+	for key,val in defi.items():
+		lst.append('--define-variable=%s=%s'%(key,val))
+	if'variables'in kw:
+		uselib=kw.get('uselib_store',kw['package'].upper())
+		vars=Utils.to_list(kw['variables'])
+		for v in vars:
+			val=self.cmd_and_log(lst+['--variable='+v],env=run_env).strip()
+			var='%s_%s'%(uselib,v)
+			env[var]=val
+		if not'okmsg'in kw:
+			kw['okmsg']='yes'
+		return
+	static=False
+	if'args'in kw:
+		args=Utils.to_list(kw['args'])
+		if'--static'in args or'--static-libs'in args:
+			static=True
+		lst+=args
+	lst.extend(Utils.to_list(kw['package']))
+	ret=self.cmd_and_log(lst,env=run_env)
+	if not'okmsg'in kw:
+		kw['okmsg']='yes'
+	define_it()
+	self.parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env),force_static=static)
+	return ret
+@conf
+def check_cfg(self,*k,**kw):
+	if k:
+		lst=k[0].split()
+		kw['package']=lst[0]
+		kw['args']=' '.join(lst[1:])
+	self.validate_cfg(kw)
+	if'msg'in kw:
+		self.start_msg(kw['msg'])
+	ret=None
+	try:
+		ret=self.exec_cfg(kw)
+	except self.errors.WafError:
+		if'errmsg'in kw:
+			self.end_msg(kw['errmsg'],'YELLOW')
+		if Logs.verbose>1:
+			raise
+		else:
+			self.fatal('The configuration failed')
+	else:
+		kw['success']=ret
+		if'okmsg'in kw:
+			self.end_msg(self.ret_msg(kw['okmsg'],kw))
+	return ret
+@conf
+def validate_c(self,kw):
+	if not'env'in kw:
+		kw['env']=self.env.derive()
+	env=kw['env']
+	if not'compiler'in kw and not'features'in kw:
+		kw['compiler']='c'
+		if env['CXX_NAME']and Task.classes.get('cxx',None):
+			kw['compiler']='cxx'
+			if not self.env['CXX']:
+				self.fatal('a c++ compiler is required')
+		else:
+			if not self.env['CC']:
+				self.fatal('a c compiler is required')
+	if not'compile_mode'in kw:
+		kw['compile_mode']='c'
+		if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler','')=='cxx':
+			kw['compile_mode']='cxx'
+	if not'type'in kw:
+		kw['type']='cprogram'
+	if not'features'in kw:
+		kw['features']=[kw['compile_mode'],kw['type']]
+	else:
+		kw['features']=Utils.to_list(kw['features'])
+	if not'compile_filename'in kw:
+		kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'')
+	def to_header(dct):
+		if'header_name'in dct:
+			dct=Utils.to_list(dct['header_name'])
+			return''.join(['#include <%s>\n'%x for x in dct])
+		return''
+	if'framework_name'in kw:
+		fwkname=kw['framework_name']
+		if not'uselib_store'in kw:
+			kw['uselib_store']=fwkname.upper()
+		if not kw.get('no_header',False):
+			if not'header_name'in kw:
+				kw['header_name']=[]
+			fwk='%s/%s.h'%(fwkname,fwkname)
+			if kw.get('remove_dot_h',None):
+				fwk=fwk[:-2]
+			kw['header_name']=Utils.to_list(kw['header_name'])+[fwk]
+		kw['msg']='Checking for framework %s'%fwkname
+		kw['framework']=fwkname
+	if'function_name'in kw:
+		fu=kw['function_name']
+		if not'msg'in kw:
+			kw['msg']='Checking for function %s'%fu
+		kw['code']=to_header(kw)+SNIP_FUNCTION%fu
+		if not'uselib_store'in kw:
+			kw['uselib_store']=fu.upper()
+		if not'define_name'in kw:
+			kw['define_name']=self.have_define(fu)
+	elif'type_name'in kw:
+		tu=kw['type_name']
+		if not'header_name'in kw:
+			kw['header_name']='stdint.h'
+		if'field_name'in kw:
+			field=kw['field_name']
+			kw['code']=to_header(kw)+SNIP_FIELD%{'type_name':tu,'field_name':field}
+			if not'msg'in kw:
+				kw['msg']='Checking for field %s in %s'%(field,tu)
+			if not'define_name'in kw:
+				kw['define_name']=self.have_define((tu+'_'+field).upper())
+		else:
+			kw['code']=to_header(kw)+SNIP_TYPE%{'type_name':tu}
+			if not'msg'in kw:
+				kw['msg']='Checking for type %s'%tu
+			if not'define_name'in kw:
+				kw['define_name']=self.have_define(tu.upper())
+	elif'header_name'in kw:
+		if not'msg'in kw:
+			kw['msg']='Checking for header %s'%kw['header_name']
+		l=Utils.to_list(kw['header_name'])
+		assert len(l)>0,'list of headers in header_name is empty'
+		kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM
+		if not'uselib_store'in kw:
+			kw['uselib_store']=l[0].upper()
+		if not'define_name'in kw:
+			kw['define_name']=self.have_define(l[0])
+	if'lib'in kw:
+		if not'msg'in kw:
+			kw['msg']='Checking for library %s'%kw['lib']
+		if not'uselib_store'in kw:
+			kw['uselib_store']=kw['lib'].upper()
+	if'stlib'in kw:
+		if not'msg'in kw:
+			kw['msg']='Checking for static library %s'%kw['stlib']
+		if not'uselib_store'in kw:
+			kw['uselib_store']=kw['stlib'].upper()
+	if'fragment'in kw:
+		kw['code']=kw['fragment']
+		if not'msg'in kw:
+			kw['msg']='Checking for code snippet'
+		if not'errmsg'in kw:
+			kw['errmsg']='no'
+	for(flagsname,flagstype)in[('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')]:
+		if flagsname in kw:
+			if not'msg'in kw:
+				kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
+			if not'errmsg'in kw:
+				kw['errmsg']='no'
+	if not'execute'in kw:
+		kw['execute']=False
+	if kw['execute']:
+		kw['features'].append('test_exec')
+	if not'errmsg'in kw:
+		kw['errmsg']='not found'
+	if not'okmsg'in kw:
+		kw['okmsg']='yes'
+	if not'code'in kw:
+		kw['code']=SNIP_EMPTY_PROGRAM
+	if self.env[INCKEYS]:
+		kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code']
+	if not kw.get('success'):kw['success']=None
+	if'define_name'in kw:
+		self.undefine(kw['define_name'])
+	assert'msg'in kw,'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c'
+@conf
+def post_check(self,*k,**kw):
+	is_success=0
+	if kw['execute']:
+		if kw['success']is not None:
+			if kw.get('define_ret',False):
+				is_success=kw['success']
+			else:
+				is_success=(kw['success']==0)
+	else:
+		is_success=(kw['success']==0)
+	if'define_name'in kw:
+		if'header_name'in kw or'function_name'in kw or'type_name'in kw or'fragment'in kw:
+			if kw['execute']and kw.get('define_ret',None)and isinstance(is_success,str):
+				self.define(kw['define_name'],is_success,quote=kw.get('quote',1))
+			else:
+				self.define_cond(kw['define_name'],is_success)
+		else:
+			self.define_cond(kw['define_name'],is_success)
+	if'header_name'in kw:
+		if kw.get('auto_add_header_name',False):
+			self.env.append_value(INCKEYS,Utils.to_list(kw['header_name']))
+	if is_success and'uselib_store'in kw:
+		from waflib.Tools import ccroot
+		_vars=set([])
+		for x in kw['features']:
+			if x in ccroot.USELIB_VARS:
+				_vars|=ccroot.USELIB_VARS[x]
+		for k in _vars:
+			lk=k.lower()
+			if k=='INCLUDES':lk='includes'
+			if k=='DEFINES':lk='defines'
+			if lk in kw:
+				val=kw[lk]
+				if isinstance(val,str):
+					val=val.rstrip(os.path.sep)
+				self.env.append_unique(k+'_'+kw['uselib_store'],val)
+	return is_success
+@conf
+def check(self,*k,**kw):
+	self.validate_c(kw)
+	self.start_msg(kw['msg'])
+	ret=None
+	try:
+		ret=self.run_c_code(*k,**kw)
+	except self.errors.ConfigurationError:
+		self.end_msg(kw['errmsg'],'YELLOW')
+		if Logs.verbose>1:
+			raise
+		else:
+			self.fatal('The configuration failed')
+	else:
+		kw['success']=ret
+	ret=self.post_check(*k,**kw)
+	if not ret:
+		self.end_msg(kw['errmsg'],'YELLOW')
+		self.fatal('The configuration failed %r'%ret)
+	else:
+		self.end_msg(self.ret_msg(kw['okmsg'],kw))
+	return ret
+class test_exec(Task.Task):
+	color='PINK'
+	def run(self):
+		if getattr(self.generator,'rpath',None):
+			if getattr(self.generator,'define_ret',False):
+				self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()])
+			else:
+				self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()])
+		else:
+			env=self.env.env or{}
+			env.update(dict(os.environ))
+			for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'):
+				env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'')
+			if getattr(self.generator,'define_ret',False):
+				self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()],env=env)
+			else:
+				self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()],env=env)
+@feature('test_exec')
+@after_method('apply_link')
+def test_exec_fun(self):
+	self.create_task('test_exec',self.link_task.outputs[0])
+CACHE_RESULTS=1
+COMPILE_ERRORS=2
+@conf
+def run_c_code(self,*k,**kw):
+	lst=[str(v)for(p,v)in kw.items()if p!='env']
+	h=Utils.h_list(lst)
+	dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
+	try:
+		os.makedirs(dir)
+	except OSError:
+		pass
+	try:
+		os.stat(dir)
+	except OSError:
+		self.fatal('cannot use the configuration test folder %r'%dir)
+	cachemode=getattr(Options.options,'confcache',None)
+	if cachemode==CACHE_RESULTS:
+		try:
+			proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_c_code'))
+		except OSError:
+			pass
+		else:
+			ret=proj['cache_run_c_code']
+			if isinstance(ret,str)and ret.startswith('Test does not build'):
+				self.fatal(ret)
+			return ret
+	bdir=os.path.join(dir,'testbuild')
+	if not os.path.exists(bdir):
+		os.makedirs(bdir)
+	self.test_bld=bld=Build.BuildContext(top_dir=dir,out_dir=bdir)
+	bld.init_dirs()
+	bld.progress_bar=0
+	bld.targets='*'
+	if kw['compile_filename']:
+		node=bld.srcnode.make_node(kw['compile_filename'])
+		node.write(kw['code'])
+	bld.logger=self.logger
+	bld.all_envs.update(self.all_envs)
+	bld.env=kw['env']
+	o=bld(features=kw['features'],source=kw['compile_filename'],target='testprog')
+	for k,v in kw.items():
+		setattr(o,k,v)
+	self.to_log("==>\n%s\n<=="%kw['code'])
+	bld.targets='*'
+	ret=-1
+	try:
+		try:
+			bld.compile()
+		except Errors.WafError:
+			ret='Test does not build: %s'%Utils.ex_stack()
+			self.fatal(ret)
+		else:
+			ret=getattr(bld,'retval',0)
+	finally:
+		proj=ConfigSet.ConfigSet()
+		proj['cache_run_c_code']=ret
+		proj.store(os.path.join(dir,'cache_run_c_code'))
+	return ret
+@conf
+def check_cxx(self,*k,**kw):
+	kw['compiler']='cxx'
+	return self.check(*k,**kw)
+@conf
+def check_cc(self,*k,**kw):
+	kw['compiler']='c'
+	return self.check(*k,**kw)
+@conf
+def define(self,key,val,quote=True):
+	assert key and isinstance(key,str)
+	if val is True:
+		val=1
+	elif val in(False,None):
+		val=0
+	if isinstance(val,int)or isinstance(val,float):
+		s='%s=%s'
+	else:
+		s=quote and'%s="%s"'or'%s=%s'
+	app=s%(key,str(val))
+	ban=key+'='
+	lst=self.env['DEFINES']
+	for x in lst:
+		if x.startswith(ban):
+			lst[lst.index(x)]=app
+			break
+	else:
+		self.env.append_value('DEFINES',app)
+	self.env.append_unique(DEFKEYS,key)
+@conf
+def undefine(self,key):
+	assert key and isinstance(key,str)
+	ban=key+'='
+	lst=[x for x in self.env['DEFINES']if not x.startswith(ban)]
+	self.env['DEFINES']=lst
+	self.env.append_unique(DEFKEYS,key)
+@conf
+def define_cond(self,key,val):
+	assert key and isinstance(key,str)
+	if val:
+		self.define(key,1)
+	else:
+		self.undefine(key)
+@conf
+def is_defined(self,key):
+	assert key and isinstance(key,str)
+	ban=key+'='
+	for x in self.env['DEFINES']:
+		if x.startswith(ban):
+			return True
+	return False
+@conf
+def get_define(self,key):
+	assert key and isinstance(key,str)
+	ban=key+'='
+	for x in self.env['DEFINES']:
+		if x.startswith(ban):
+			return x[len(ban):]
+	return None
+@conf
+def have_define(self,key):
+	return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key)
+@conf
+def write_config_header(self,configfile='',guard='',top=False,env=None,defines=True,headers=False,remove=True,define_prefix=''):
+	if env:
+		Logs.warn('Cannot pass env to write_config_header')
+	if not configfile:configfile=WAF_CONFIG_H
+	waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile)
+	node=top and self.bldnode or self.path.get_bld()
+	node=node.make_node(configfile)
+	node.parent.mkdir()
+	lst=['/* WARNING! All changes made to this file will be lost! */\n']
+	lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard))
+	lst.append(self.get_config_header(defines,headers,define_prefix=define_prefix))
+	lst.append('\n#endif /* %s */\n'%waf_guard)
+	node.write('\n'.join(lst))
+	self.env.append_unique(Build.CFG_FILES,[node.abspath()])
+	if remove:
+		for key in self.env[DEFKEYS]:
+			self.undefine(key)
+		self.env[DEFKEYS]=[]
+@conf
+def get_config_header(self,defines=True,headers=False,define_prefix=''):
+	lst=[]
+	if headers:
+		for x in self.env[INCKEYS]:
+			lst.append('#include <%s>'%x)
+	if defines:
+		for x in self.env[DEFKEYS]:
+			if self.is_defined(x):
+				val=self.get_define(x)
+				lst.append('#define %s %s'%(define_prefix+x,val))
+			else:
+				lst.append('/* #undef %s */'%(define_prefix+x))
+	return"\n".join(lst)
+@conf
+def cc_add_flags(conf):
+	conf.add_os_flags('CPPFLAGS','CFLAGS')
+	conf.add_os_flags('CFLAGS')
+@conf
+def cxx_add_flags(conf):
+	conf.add_os_flags('CPPFLAGS','CXXFLAGS')
+	conf.add_os_flags('CXXFLAGS')
+@conf
+def link_add_flags(conf):
+	conf.add_os_flags('LINKFLAGS')
+	conf.add_os_flags('LDFLAGS','LINKFLAGS')
+@conf
+def cc_load_tools(conf):
+	if not conf.env.DEST_OS:
+		conf.env.DEST_OS=Utils.unversioned_sys_platform()
+	conf.load('c')
+@conf
+def cxx_load_tools(conf):
+	if not conf.env.DEST_OS:
+		conf.env.DEST_OS=Utils.unversioned_sys_platform()
+	conf.load('cxx')
+@conf
+def get_cc_version(conf,cc,gcc=False,icc=False):
+	cmd=cc+['-dM','-E','-']
+	env=conf.env.env or None
+	try:
+		p=Utils.subprocess.Popen(cmd,stdin=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
+		p.stdin.write('\n')
+		out=p.communicate()[0]
+	except Exception:
+		conf.fatal('Could not determine the compiler version %r'%cmd)
+	if not isinstance(out,str):
+		out=out.decode(sys.stdout.encoding or'iso8859-1')
+	if gcc:
+		if out.find('__INTEL_COMPILER')>=0:
+			conf.fatal('The intel compiler pretends to be gcc')
+		if out.find('__GNUC__')<0 and out.find('__clang__')<0:
+			conf.fatal('Could not determine the compiler type')
+	if icc and out.find('__INTEL_COMPILER')<0:
+		conf.fatal('Not icc/icpc')
+	k={}
+	if icc or gcc:
+		out=out.splitlines()
+		for line in out:
+			lst=shlex.split(line)
+			if len(lst)>2:
+				key=lst[1]
+				val=lst[2]
+				k[key]=val
+		def isD(var):
+			return var in k
+		def isT(var):
+			return var in k and k[var]!='0'
+		if not conf.env.DEST_OS:
+			conf.env.DEST_OS=''
+		for i in MACRO_TO_DESTOS:
+			if isD(i):
+				conf.env.DEST_OS=MACRO_TO_DESTOS[i]
+				break
+		else:
+			if isD('__APPLE__')and isD('__MACH__'):
+				conf.env.DEST_OS='darwin'
+			elif isD('__unix__'):
+				conf.env.DEST_OS='generic'
+		if isD('__ELF__'):
+			conf.env.DEST_BINFMT='elf'
+		elif isD('__WINNT__')or isD('__CYGWIN__')or isD('_WIN32'):
+			conf.env.DEST_BINFMT='pe'
+			conf.env.LIBDIR=conf.env.BINDIR
+		elif isD('__APPLE__'):
+			conf.env.DEST_BINFMT='mac-o'
+		if not conf.env.DEST_BINFMT:
+			conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS)
+		for i in MACRO_TO_DEST_CPU:
+			if isD(i):
+				conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i]
+				break
+		Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')]))
+		if icc:
+			ver=k['__INTEL_COMPILER']
+			conf.env['CC_VERSION']=(ver[:-2],ver[-2],ver[-1])
+		else:
+			if isD('__clang__'):
+				conf.env['CC_VERSION']=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__'])
+			else:
+				conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
+	return k
+@conf
+def get_xlc_version(conf,cc):
+	cmd=cc+['-qversion']
+	try:
+		out,err=conf.cmd_and_log(cmd,output=0)
+	except Errors.WafError:
+		conf.fatal('Could not find xlc %r'%cmd)
+	for v in(r"IBM XL C/C\+\+.* V(?P<major>\d*)\.(?P<minor>\d*)",):
+		version_re=re.compile(v,re.I).search
+		match=version_re(out or err)
+		if match:
+			k=match.groupdict()
+			conf.env['CC_VERSION']=(k['major'],k['minor'])
+			break
+	else:
+		conf.fatal('Could not determine the XLC version.')
+@conf
+def add_as_needed(self):
+	if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
+		self.env.append_unique('LINKFLAGS','--as-needed')
+class cfgtask(Task.TaskBase):
+	def display(self):
+		return''
+	def runnable_status(self):
+		return Task.RUN_ME
+	def uid(self):
+		return Utils.SIG_NIL
+	def run(self):
+		conf=self.conf
+		bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath())
+		bld.env=conf.env
+		bld.init_dirs()
+		bld.in_msg=1
+		bld.logger=self.logger
+		try:
+			bld.check(**self.args)
+		except Exception:
+			return 1
+@conf
+def multicheck(self,*k,**kw):
+	self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)))
+	class par(object):
+		def __init__(self):
+			self.keep=False
+			self.cache_global=Options.cache_global
+			self.nocache=Options.options.nocache
+			self.returned_tasks=[]
+			self.task_sigs={}
+		def total(self):
+			return len(tasks)
+		def to_log(self,*k,**kw):
+			return
+	bld=par()
+	tasks=[]
+	for dct in k:
+		x=cfgtask(bld=bld)
+		tasks.append(x)
+		x.args=dct
+		x.bld=bld
+		x.conf=self
+		x.args=dct
+		x.logger=Logs.make_mem_logger(str(id(x)),self.logger)
+	def it():
+		yield tasks
+		while 1:
+			yield[]
+	p=Runner.Parallel(bld,Options.options.jobs)
+	p.biter=it()
+	p.start()
+	for x in tasks:
+		x.logger.memhandler.flush()
+	for x in tasks:
+		if x.hasrun!=Task.SUCCESS:
+			self.end_msg(kw.get('errmsg','no'),color='YELLOW')
+			self.fatal(kw.get('fatalmsg',None)or'One of the tests has failed, see the config.log for more information')
+	self.end_msg('ok')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.pyc
new file mode 100644
index 0000000..ff3de86
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.py
new file mode 100644
index 0000000..579b2a7
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.py
@@ -0,0 +1,120 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,shutil,sys,platform
+from waflib import TaskGen,Task,Build,Options,Utils,Errors
+from waflib.TaskGen import taskgen_method,feature,after_method,before_method
+app_info='''
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleGetInfoString</key>
+	<string>Created by Waf</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>NOTE</key>
+	<string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
+	<key>CFBundleExecutable</key>
+	<string>%s</string>
+</dict>
+</plist>
+'''
+@feature('c','cxx')
+def set_macosx_deployment_target(self):
+	if self.env['MACOSX_DEPLOYMENT_TARGET']:
+		os.environ['MACOSX_DEPLOYMENT_TARGET']=self.env['MACOSX_DEPLOYMENT_TARGET']
+	elif'MACOSX_DEPLOYMENT_TARGET'not in os.environ:
+		if Utils.unversioned_sys_platform()=='darwin':
+			os.environ['MACOSX_DEPLOYMENT_TARGET']='.'.join(platform.mac_ver()[0].split('.')[:2])
+@taskgen_method
+def create_bundle_dirs(self,name,out):
+	bld=self.bld
+	dir=out.parent.find_or_declare(name)
+	dir.mkdir()
+	macos=dir.find_or_declare(['Contents','MacOS'])
+	macos.mkdir()
+	return dir
+def bundle_name_for_output(out):
+	name=out.name
+	k=name.rfind('.')
+	if k>=0:
+		name=name[:k]+'.app'
+	else:
+		name=name+'.app'
+	return name
+@feature('cprogram','cxxprogram')
+@after_method('apply_link')
+def create_task_macapp(self):
+	if self.env['MACAPP']or getattr(self,'mac_app',False):
+		out=self.link_task.outputs[0]
+		name=bundle_name_for_output(out)
+		dir=self.create_bundle_dirs(name,out)
+		n1=dir.find_or_declare(['Contents','MacOS',out.name])
+		self.apptask=self.create_task('macapp',self.link_task.outputs,n1)
+		inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/MacOS/'%name
+		self.bld.install_files(inst_to,n1,chmod=Utils.O755)
+		if getattr(self,'mac_resources',None):
+			res_dir=n1.parent.parent.make_node('Resources')
+			inst_to=getattr(self,'install_path','/Applications')+'/%s/Resources'%name
+			for x in self.to_list(self.mac_resources):
+				node=self.path.find_node(x)
+				if not node:
+					raise Errors.WafError('Missing mac_resource %r in %r'%(x,self))
+				parent=node.parent
+				if os.path.isdir(node.abspath()):
+					nodes=node.ant_glob('**')
+				else:
+					nodes=[node]
+				for node in nodes:
+					rel=node.path_from(parent)
+					tsk=self.create_task('macapp',node,res_dir.make_node(rel))
+					self.bld.install_as(inst_to+'/%s'%rel,node)
+		if getattr(self.bld,'is_install',None):
+			self.install_task.hasrun=Task.SKIP_ME
+@feature('cprogram','cxxprogram')
+@after_method('apply_link')
+def create_task_macplist(self):
+	if self.env['MACAPP']or getattr(self,'mac_app',False):
+		out=self.link_task.outputs[0]
+		name=bundle_name_for_output(out)
+		dir=self.create_bundle_dirs(name,out)
+		n1=dir.find_or_declare(['Contents','Info.plist'])
+		self.plisttask=plisttask=self.create_task('macplist',[],n1)
+		if getattr(self,'mac_plist',False):
+			node=self.path.find_resource(self.mac_plist)
+			if node:
+				plisttask.inputs.append(node)
+			else:
+				plisttask.code=self.mac_plist
+		else:
+			plisttask.code=app_info%self.link_task.outputs[0].name
+		inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/'%name
+		self.bld.install_files(inst_to,n1)
+@feature('cshlib','cxxshlib')
+@before_method('apply_link','propagate_uselib_vars')
+def apply_bundle(self):
+	if self.env['MACBUNDLE']or getattr(self,'mac_bundle',False):
+		self.env['LINKFLAGS_cshlib']=self.env['LINKFLAGS_cxxshlib']=[]
+		self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['macbundle_PATTERN']
+		use=self.use=self.to_list(getattr(self,'use',[]))
+		if not'MACBUNDLE'in use:
+			use.append('MACBUNDLE')
+app_dirs=['Contents','Contents/MacOS','Contents/Resources']
+class macapp(Task.Task):
+	color='PINK'
+	def run(self):
+		self.outputs[0].parent.mkdir()
+		shutil.copy2(self.inputs[0].srcpath(),self.outputs[0].abspath())
+class macplist(Task.Task):
+	color='PINK'
+	ext_in=['.bin']
+	def run(self):
+		if getattr(self,'code',None):
+			txt=self.code
+		else:
+			txt=self.inputs[0].read()
+		self.outputs[0].write(txt)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.pyc
new file mode 100644
index 0000000..9684318
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.py
new file mode 100644
index 0000000..dc6453b
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.py
@@ -0,0 +1,604 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re,string,traceback
+from waflib import Logs,Utils,Errors
+from waflib.Logs import debug,error
+class PreprocError(Errors.WafError):
+	pass
+POPFILE='-'
+recursion_limit=150
+go_absolute=False
+standard_includes=['/usr/include']
+if Utils.is_win32:
+	standard_includes=[]
+use_trigraphs=0
+strict_quotes=0
+g_optrans={'not':'!','and':'&&','bitand':'&','and_eq':'&=','or':'||','bitor':'|','or_eq':'|=','xor':'^','xor_eq':'^=','compl':'~',}
+re_lines=re.compile('^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE)
+re_mac=re.compile("^[a-zA-Z_]\w*")
+re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]')
+re_pragma_once=re.compile('^\s*once\s*',re.IGNORECASE)
+re_nl=re.compile('\\\\\r*\n',re.MULTILINE)
+re_cpp=re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',re.DOTALL|re.MULTILINE)
+trig_def=[('??'+a,b)for a,b in zip("=-/!'()<>",r'#~\|^[]{}')]
+chr_esc={'0':0,'a':7,'b':8,'t':9,'n':10,'f':11,'v':12,'r':13,'\\':92,"'":39}
+NUM='i'
+OP='O'
+IDENT='T'
+STR='s'
+CHAR='c'
+tok_types=[NUM,STR,IDENT,OP]
+exp_types=[r"""0[xX](?P<hex>[a-fA-F0-9]+)(?P<qual1>[uUlL]*)|L*?'(?P<char>(\\.|[^\\'])+)'|(?P<n1>\d+)[Ee](?P<exp0>[+-]*?\d+)(?P<float0>[fFlL]*)|(?P<n2>\d*\.\d+)([Ee](?P<exp1>[+-]*?\d+))?(?P<float1>[fFlL]*)|(?P<n4>\d+\.\d*)([Ee](?P<exp2>[+-]*?\d+))?(?P<float2>[fFlL]*)|(?P<oct>0*)(?P<n0>\d+)(?P<qual2>[uUlL]*)""",r'L?"([^"\\]|\\.)*"',r'[a-zA-Z_]\w*',r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',]
+re_clexer=re.compile('|'.join(["(?P<%s>%s)"%(name,part)for name,part in zip(tok_types,exp_types)]),re.M)
+accepted='a'
+ignored='i'
+undefined='u'
+skipped='s'
+def repl(m):
+	s=m.group(0)
+	if s.startswith('/'):
+		return' '
+	return s
+def filter_comments(filename):
+	code=Utils.readf(filename)
+	if use_trigraphs:
+		for(a,b)in trig_def:code=code.split(a).join(b)
+	code=re_nl.sub('',code)
+	code=re_cpp.sub(repl,code)
+	return[(m.group(2),m.group(3))for m in re.finditer(re_lines,code)]
+prec={}
+ops=['* / %','+ -','<< >>','< <= >= >','== !=','& | ^','&& ||',',']
+for x in range(len(ops)):
+	syms=ops[x]
+	for u in syms.split():
+		prec[u]=x
+def trimquotes(s):
+	if not s:return''
+	s=s.rstrip()
+	if s[0]=="'"and s[-1]=="'":return s[1:-1]
+	return s
+def reduce_nums(val_1,val_2,val_op):
+	try:a=0+val_1
+	except TypeError:a=int(val_1)
+	try:b=0+val_2
+	except TypeError:b=int(val_2)
+	d=val_op
+	if d=='%':c=a%b
+	elif d=='+':c=a+b
+	elif d=='-':c=a-b
+	elif d=='*':c=a*b
+	elif d=='/':c=a/b
+	elif d=='^':c=a^b
+	elif d=='|':c=a|b
+	elif d=='||':c=int(a or b)
+	elif d=='&':c=a&b
+	elif d=='&&':c=int(a and b)
+	elif d=='==':c=int(a==b)
+	elif d=='!=':c=int(a!=b)
+	elif d=='<=':c=int(a<=b)
+	elif d=='<':c=int(a<b)
+	elif d=='>':c=int(a>b)
+	elif d=='>=':c=int(a>=b)
+	elif d=='^':c=int(a^b)
+	elif d=='<<':c=a<<b
+	elif d=='>>':c=a>>b
+	else:c=0
+	return c
+def get_num(lst):
+	if not lst:raise PreprocError("empty list for get_num")
+	(p,v)=lst[0]
+	if p==OP:
+		if v=='(':
+			count_par=1
+			i=1
+			while i<len(lst):
+				(p,v)=lst[i]
+				if p==OP:
+					if v==')':
+						count_par-=1
+						if count_par==0:
+							break
+					elif v=='(':
+						count_par+=1
+				i+=1
+			else:
+				raise PreprocError("rparen expected %r"%lst)
+			(num,_)=get_term(lst[1:i])
+			return(num,lst[i+1:])
+		elif v=='+':
+			return get_num(lst[1:])
+		elif v=='-':
+			num,lst=get_num(lst[1:])
+			return(reduce_nums('-1',num,'*'),lst)
+		elif v=='!':
+			num,lst=get_num(lst[1:])
+			return(int(not int(num)),lst)
+		elif v=='~':
+			num,lst=get_num(lst[1:])
+			return(~int(num),lst)
+		else:
+			raise PreprocError("Invalid op token %r for get_num"%lst)
+	elif p==NUM:
+		return v,lst[1:]
+	elif p==IDENT:
+		return 0,lst[1:]
+	else:
+		raise PreprocError("Invalid token %r for get_num"%lst)
+def get_term(lst):
+	if not lst:raise PreprocError("empty list for get_term")
+	num,lst=get_num(lst)
+	if not lst:
+		return(num,[])
+	(p,v)=lst[0]
+	if p==OP:
+		if v==',':
+			return get_term(lst[1:])
+		elif v=='?':
+			count_par=0
+			i=1
+			while i<len(lst):
+				(p,v)=lst[i]
+				if p==OP:
+					if v==')':
+						count_par-=1
+					elif v=='(':
+						count_par+=1
+					elif v==':':
+						if count_par==0:
+							break
+				i+=1
+			else:
+				raise PreprocError("rparen expected %r"%lst)
+			if int(num):
+				return get_term(lst[1:i])
+			else:
+				return get_term(lst[i+1:])
+		else:
+			num2,lst=get_num(lst[1:])
+			if not lst:
+				num2=reduce_nums(num,num2,v)
+				return get_term([(NUM,num2)]+lst)
+			p2,v2=lst[0]
+			if p2!=OP:
+				raise PreprocError("op expected %r"%lst)
+			if prec[v2]>=prec[v]:
+				num2=reduce_nums(num,num2,v)
+				return get_term([(NUM,num2)]+lst)
+			else:
+				num3,lst=get_num(lst[1:])
+				num3=reduce_nums(num2,num3,v2)
+				return get_term([(NUM,num),(p,v),(NUM,num3)]+lst)
+	raise PreprocError("cannot reduce %r"%lst)
+def reduce_eval(lst):
+	num,lst=get_term(lst)
+	return(NUM,num)
+def stringize(lst):
+	lst=[str(v2)for(p2,v2)in lst]
+	return"".join(lst)
+def paste_tokens(t1,t2):
+	p1=None
+	if t1[0]==OP and t2[0]==OP:
+		p1=OP
+	elif t1[0]==IDENT and(t2[0]==IDENT or t2[0]==NUM):
+		p1=IDENT
+	elif t1[0]==NUM and t2[0]==NUM:
+		p1=NUM
+	if not p1:
+		raise PreprocError('tokens do not make a valid paste %r and %r'%(t1,t2))
+	return(p1,t1[1]+t2[1])
+def reduce_tokens(lst,defs,ban=[]):
+	i=0
+	while i<len(lst):
+		(p,v)=lst[i]
+		if p==IDENT and v=="defined":
+			del lst[i]
+			if i<len(lst):
+				(p2,v2)=lst[i]
+				if p2==IDENT:
+					if v2 in defs:
+						lst[i]=(NUM,1)
+					else:
+						lst[i]=(NUM,0)
+				elif p2==OP and v2=='(':
+					del lst[i]
+					(p2,v2)=lst[i]
+					del lst[i]
+					if v2 in defs:
+						lst[i]=(NUM,1)
+					else:
+						lst[i]=(NUM,0)
+				else:
+					raise PreprocError("Invalid define expression %r"%lst)
+		elif p==IDENT and v in defs:
+			if isinstance(defs[v],str):
+				a,b=extract_macro(defs[v])
+				defs[v]=b
+			macro_def=defs[v]
+			to_add=macro_def[1]
+			if isinstance(macro_def[0],list):
+				del lst[i]
+				accu=to_add[:]
+				reduce_tokens(accu,defs,ban+[v])
+				for x in range(len(accu)):
+					lst.insert(i,accu[x])
+					i+=1
+			else:
+				args=[]
+				del lst[i]
+				if i>=len(lst):
+					raise PreprocError("expected '(' after %r (got nothing)"%v)
+				(p2,v2)=lst[i]
+				if p2!=OP or v2!='(':
+					raise PreprocError("expected '(' after %r"%v)
+				del lst[i]
+				one_param=[]
+				count_paren=0
+				while i<len(lst):
+					p2,v2=lst[i]
+					del lst[i]
+					if p2==OP and count_paren==0:
+						if v2=='(':
+							one_param.append((p2,v2))
+							count_paren+=1
+						elif v2==')':
+							if one_param:args.append(one_param)
+							break
+						elif v2==',':
+							if not one_param:raise PreprocError("empty param in funcall %s"%p)
+							args.append(one_param)
+							one_param=[]
+						else:
+							one_param.append((p2,v2))
+					else:
+						one_param.append((p2,v2))
+						if v2=='(':count_paren+=1
+						elif v2==')':count_paren-=1
+				else:
+					raise PreprocError('malformed macro')
+				accu=[]
+				arg_table=macro_def[0]
+				j=0
+				while j<len(to_add):
+					(p2,v2)=to_add[j]
+					if p2==OP and v2=='#':
+						if j+1<len(to_add)and to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
+							toks=args[arg_table[to_add[j+1][1]]]
+							accu.append((STR,stringize(toks)))
+							j+=1
+						else:
+							accu.append((p2,v2))
+					elif p2==OP and v2=='##':
+						if accu and j+1<len(to_add):
+							t1=accu[-1]
+							if to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
+								toks=args[arg_table[to_add[j+1][1]]]
+								if toks:
+									accu[-1]=paste_tokens(t1,toks[0])
+									accu.extend(toks[1:])
+								else:
+									accu.append((p2,v2))
+									accu.extend(toks)
+							elif to_add[j+1][0]==IDENT and to_add[j+1][1]=='__VA_ARGS__':
+								va_toks=[]
+								st=len(macro_def[0])
+								pt=len(args)
+								for x in args[pt-st+1:]:
+									va_toks.extend(x)
+									va_toks.append((OP,','))
+								if va_toks:va_toks.pop()
+								if len(accu)>1:
+									(p3,v3)=accu[-1]
+									(p4,v4)=accu[-2]
+									if v3=='##':
+										accu.pop()
+										if v4==','and pt<st:
+											accu.pop()
+								accu+=va_toks
+							else:
+								accu[-1]=paste_tokens(t1,to_add[j+1])
+							j+=1
+						else:
+							accu.append((p2,v2))
+					elif p2==IDENT and v2 in arg_table:
+						toks=args[arg_table[v2]]
+						reduce_tokens(toks,defs,ban+[v])
+						accu.extend(toks)
+					else:
+						accu.append((p2,v2))
+					j+=1
+				reduce_tokens(accu,defs,ban+[v])
+				for x in range(len(accu)-1,-1,-1):
+					lst.insert(i,accu[x])
+		i+=1
+def eval_macro(lst,defs):
+	reduce_tokens(lst,defs,[])
+	if not lst:raise PreprocError("missing tokens to evaluate")
+	(p,v)=reduce_eval(lst)
+	return int(v)!=0
+def extract_macro(txt):
+	t=tokenize(txt)
+	if re_fun.search(txt):
+		p,name=t[0]
+		p,v=t[1]
+		if p!=OP:raise PreprocError("expected open parenthesis")
+		i=1
+		pindex=0
+		params={}
+		prev='('
+		while 1:
+			i+=1
+			p,v=t[i]
+			if prev=='(':
+				if p==IDENT:
+					params[v]=pindex
+					pindex+=1
+					prev=p
+				elif p==OP and v==')':
+					break
+				else:
+					raise PreprocError("unexpected token (3)")
+			elif prev==IDENT:
+				if p==OP and v==',':
+					prev=v
+				elif p==OP and v==')':
+					break
+				else:
+					raise PreprocError("comma or ... expected")
+			elif prev==',':
+				if p==IDENT:
+					params[v]=pindex
+					pindex+=1
+					prev=p
+				elif p==OP and v=='...':
+					raise PreprocError("not implemented (1)")
+				else:
+					raise PreprocError("comma or ... expected (2)")
+			elif prev=='...':
+				raise PreprocError("not implemented (2)")
+			else:
+				raise PreprocError("unexpected else")
+		return(name,[params,t[i+1:]])
+	else:
+		(p,v)=t[0]
+		return(v,[[],t[1:]])
+re_include=re.compile('^\s*(<(?P<a>.*)>|"(?P<b>.*)")')
+def extract_include(txt,defs):
+	m=re_include.search(txt)
+	if m:
+		if m.group('a'):return'<',m.group('a')
+		if m.group('b'):return'"',m.group('b')
+	toks=tokenize(txt)
+	reduce_tokens(toks,defs,['waf_include'])
+	if not toks:
+		raise PreprocError("could not parse include %s"%txt)
+	if len(toks)==1:
+		if toks[0][0]==STR:
+			return'"',toks[0][1]
+	else:
+		if toks[0][1]=='<'and toks[-1][1]=='>':
+			return stringize(toks).lstrip('<').rstrip('>')
+	raise PreprocError("could not parse include %s."%txt)
+def parse_char(txt):
+	if not txt:raise PreprocError("attempted to parse a null char")
+	if txt[0]!='\\':
+		return ord(txt)
+	c=txt[1]
+	if c=='x':
+		if len(txt)==4 and txt[3]in string.hexdigits:return int(txt[2:],16)
+		return int(txt[2:],16)
+	elif c.isdigit():
+		if c=='0'and len(txt)==2:return 0
+		for i in 3,2,1:
+			if len(txt)>i and txt[1:1+i].isdigit():
+				return(1+i,int(txt[1:1+i],8))
+	else:
+		try:return chr_esc[c]
+		except KeyError:raise PreprocError("could not parse char literal '%s'"%txt)
+def tokenize(s):
+	return tokenize_private(s)[:]
+@Utils.run_once
+def tokenize_private(s):
+	ret=[]
+	for match in re_clexer.finditer(s):
+		m=match.group
+		for name in tok_types:
+			v=m(name)
+			if v:
+				if name==IDENT:
+					try:v=g_optrans[v];name=OP
+					except KeyError:
+						if v.lower()=="true":
+							v=1
+							name=NUM
+						elif v.lower()=="false":
+							v=0
+							name=NUM
+				elif name==NUM:
+					if m('oct'):v=int(v,8)
+					elif m('hex'):v=int(m('hex'),16)
+					elif m('n0'):v=m('n0')
+					else:
+						v=m('char')
+						if v:v=parse_char(v)
+						else:v=m('n2')or m('n4')
+				elif name==OP:
+					if v=='%:':v='#'
+					elif v=='%:%:':v='##'
+				elif name==STR:
+					v=v[1:-1]
+				ret.append((name,v))
+				break
+	return ret
+@Utils.run_once
+def define_name(line):
+	return re_mac.match(line).group(0)
+class c_parser(object):
+	def __init__(self,nodepaths=None,defines=None):
+		self.lines=[]
+		if defines is None:
+			self.defs={}
+		else:
+			self.defs=dict(defines)
+		self.state=[]
+		self.count_files=0
+		self.currentnode_stack=[]
+		self.nodepaths=nodepaths or[]
+		self.nodes=[]
+		self.names=[]
+		self.curfile=''
+		self.ban_includes=set([])
+	def cached_find_resource(self,node,filename):
+		try:
+			nd=node.ctx.cache_nd
+		except AttributeError:
+			nd=node.ctx.cache_nd={}
+		tup=(node,filename)
+		try:
+			return nd[tup]
+		except KeyError:
+			ret=node.find_resource(filename)
+			if ret:
+				if getattr(ret,'children',None):
+					ret=None
+				elif ret.is_child_of(node.ctx.bldnode):
+					tmp=node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode))
+					if tmp and getattr(tmp,'children',None):
+						ret=None
+			nd[tup]=ret
+			return ret
+	def tryfind(self,filename):
+		self.curfile=filename
+		found=self.cached_find_resource(self.currentnode_stack[-1],filename)
+		for n in self.nodepaths:
+			if found:
+				break
+			found=self.cached_find_resource(n,filename)
+		if found and not found in self.ban_includes:
+			self.nodes.append(found)
+			if filename[-4:]!='.moc':
+				self.addlines(found)
+		else:
+			if not filename in self.names:
+				self.names.append(filename)
+		return found
+	def addlines(self,node):
+		self.currentnode_stack.append(node.parent)
+		filepath=node.abspath()
+		self.count_files+=1
+		if self.count_files>recursion_limit:
+			raise PreprocError("recursion limit exceeded")
+		pc=self.parse_cache
+		debug('preproc: reading file %r',filepath)
+		try:
+			lns=pc[filepath]
+		except KeyError:
+			pass
+		else:
+			self.lines.extend(lns)
+			return
+		try:
+			lines=filter_comments(filepath)
+			lines.append((POPFILE,''))
+			lines.reverse()
+			pc[filepath]=lines
+			self.lines.extend(lines)
+		except IOError:
+			raise PreprocError("could not read the file %s"%filepath)
+		except Exception:
+			if Logs.verbose>0:
+				error("parsing %s failed"%filepath)
+				traceback.print_exc()
+	def start(self,node,env):
+		debug('preproc: scanning %s (in %s)',node.name,node.parent.name)
+		bld=node.ctx
+		try:
+			self.parse_cache=bld.parse_cache
+		except AttributeError:
+			bld.parse_cache={}
+			self.parse_cache=bld.parse_cache
+		self.current_file=node
+		self.addlines(node)
+		if env['DEFINES']:
+			try:
+				lst=['%s %s'%(x[0],trimquotes('='.join(x[1:])))for x in[y.split('=')for y in env['DEFINES']]]
+				lst.reverse()
+				self.lines.extend([('define',x)for x in lst])
+			except AttributeError:
+				pass
+		while self.lines:
+			(token,line)=self.lines.pop()
+			if token==POPFILE:
+				self.count_files-=1
+				self.currentnode_stack.pop()
+				continue
+			try:
+				ve=Logs.verbose
+				if ve:debug('preproc: line is %s - %s state is %s',token,line,self.state)
+				state=self.state
+				if token[:2]=='if':
+					state.append(undefined)
+				elif token=='endif':
+					state.pop()
+				if token[0]!='e':
+					if skipped in self.state or ignored in self.state:
+						continue
+				if token=='if':
+					ret=eval_macro(tokenize(line),self.defs)
+					if ret:state[-1]=accepted
+					else:state[-1]=ignored
+				elif token=='ifdef':
+					m=re_mac.match(line)
+					if m and m.group(0)in self.defs:state[-1]=accepted
+					else:state[-1]=ignored
+				elif token=='ifndef':
+					m=re_mac.match(line)
+					if m and m.group(0)in self.defs:state[-1]=ignored
+					else:state[-1]=accepted
+				elif token=='include'or token=='import':
+					(kind,inc)=extract_include(line,self.defs)
+					if ve:debug('preproc: include found %s    (%s) ',inc,kind)
+					if kind=='"'or not strict_quotes:
+						self.current_file=self.tryfind(inc)
+						if token=='import':
+							self.ban_includes.add(self.current_file)
+				elif token=='elif':
+					if state[-1]==accepted:
+						state[-1]=skipped
+					elif state[-1]==ignored:
+						if eval_macro(tokenize(line),self.defs):
+							state[-1]=accepted
+				elif token=='else':
+					if state[-1]==accepted:state[-1]=skipped
+					elif state[-1]==ignored:state[-1]=accepted
+				elif token=='define':
+					try:
+						self.defs[define_name(line)]=line
+					except Exception:
+						raise PreprocError("Invalid define line %s"%line)
+				elif token=='undef':
+					m=re_mac.match(line)
+					if m and m.group(0)in self.defs:
+						self.defs.__delitem__(m.group(0))
+				elif token=='pragma':
+					if re_pragma_once.match(line.lower()):
+						self.ban_includes.add(self.current_file)
+			except Exception ,e:
+				if Logs.verbose:
+					debug('preproc: line parsing failed (%s): %s %s',e,line,Utils.ex_stack())
+def scan(task):
+	global go_absolute
+	try:
+		incn=task.generator.includes_nodes
+	except AttributeError:
+		raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": '%task.generator)
+	if go_absolute:
+		nodepaths=incn+[task.generator.bld.root.find_dir(x)for x in standard_includes]
+	else:
+		nodepaths=[x for x in incn if x.is_child_of(x.ctx.srcnode)or x.is_child_of(x.ctx.bldnode)]
+	tmp=c_parser(nodepaths)
+	tmp.start(task.inputs[0],task.env)
+	if Logs.verbose:
+		debug('deps: deps for %r: %r; unresolved %r'%(task.inputs,tmp.nodes,tmp.names))
+	return(tmp.nodes,tmp.names)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.pyc
new file mode 100644
index 0000000..c375610
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.py
new file mode 100644
index 0000000..f275977
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.py
@@ -0,0 +1,153 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Task
+from waflib.Configure import conf
+from waflib.TaskGen import feature,before_method,after_method
+import sys
+LIB_CODE='''
+#ifdef _MSC_VER
+#define testEXPORT __declspec(dllexport)
+#else
+#define testEXPORT
+#endif
+testEXPORT int lib_func(void) { return 9; }
+'''
+MAIN_CODE='''
+#ifdef _MSC_VER
+#define testEXPORT __declspec(dllimport)
+#else
+#define testEXPORT
+#endif
+testEXPORT int lib_func(void);
+int main(int argc, char **argv) {
+	(void)argc; (void)argv;
+	return !(lib_func() == 9);
+}
+'''
+@feature('link_lib_test')
+@before_method('process_source')
+def link_lib_test_fun(self):
+	def write_test_file(task):
+		task.outputs[0].write(task.generator.code)
+	rpath=[]
+	if getattr(self,'add_rpath',False):
+		rpath=[self.bld.path.get_bld().abspath()]
+	mode=self.mode
+	m='%s %s'%(mode,mode)
+	ex=self.test_exec and'test_exec'or''
+	bld=self.bld
+	bld(rule=write_test_file,target='test.'+mode,code=LIB_CODE)
+	bld(rule=write_test_file,target='main.'+mode,code=MAIN_CODE)
+	bld(features='%sshlib'%m,source='test.'+mode,target='test')
+	bld(features='%sprogram %s'%(m,ex),source='main.'+mode,target='app',use='test',rpath=rpath)
+@conf
+def check_library(self,mode=None,test_exec=True):
+	if not mode:
+		mode='c'
+		if self.env.CXX:
+			mode='cxx'
+	self.check(compile_filename=[],features='link_lib_test',msg='Checking for libraries',mode=mode,test_exec=test_exec,)
+INLINE_CODE='''
+typedef int foo_t;
+static %s foo_t static_foo () {return 0; }
+%s foo_t foo () {
+	return 0;
+}
+'''
+INLINE_VALUES=['inline','__inline__','__inline']
+@conf
+def check_inline(self,**kw):
+	self.start_msg('Checking for inline')
+	if not'define_name'in kw:
+		kw['define_name']='INLINE_MACRO'
+	if not'features'in kw:
+		if self.env.CXX:
+			kw['features']=['cxx']
+		else:
+			kw['features']=['c']
+	for x in INLINE_VALUES:
+		kw['fragment']=INLINE_CODE%(x,x)
+		try:
+			self.check(**kw)
+		except self.errors.ConfigurationError:
+			continue
+		else:
+			self.end_msg(x)
+			if x!='inline':
+				self.define('inline',x,quote=False)
+			return x
+	self.fatal('could not use inline functions')
+LARGE_FRAGMENT='''#include <unistd.h>
+int main(int argc, char **argv) {
+	(void)argc; (void)argv;
+	return !(sizeof(off_t) >= 8);
+}
+'''
+@conf
+def check_large_file(self,**kw):
+	if not'define_name'in kw:
+		kw['define_name']='HAVE_LARGEFILE'
+	if not'execute'in kw:
+		kw['execute']=True
+	if not'features'in kw:
+		if self.env.CXX:
+			kw['features']=['cxx','cxxprogram']
+		else:
+			kw['features']=['c','cprogram']
+	kw['fragment']=LARGE_FRAGMENT
+	kw['msg']='Checking for large file support'
+	ret=True
+	try:
+		if self.env.DEST_BINFMT!='pe':
+			ret=self.check(**kw)
+	except self.errors.ConfigurationError:
+		pass
+	else:
+		if ret:
+			return True
+	kw['msg']='Checking for -D_FILE_OFFSET_BITS=64'
+	kw['defines']=['_FILE_OFFSET_BITS=64']
+	try:
+		ret=self.check(**kw)
+	except self.errors.ConfigurationError:
+		pass
+	else:
+		self.define('_FILE_OFFSET_BITS',64)
+		return ret
+	self.fatal('There is no support for large files')
+ENDIAN_FRAGMENT='''
+short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+int use_ascii (int i) {
+	return ascii_mm[i] + ascii_ii[i];
+}
+short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+int use_ebcdic (int i) {
+	return ebcdic_mm[i] + ebcdic_ii[i];
+}
+extern int foo;
+'''
+class grep_for_endianness(Task.Task):
+	color='PINK'
+	def run(self):
+		txt=self.inputs[0].read(flags='rb').decode('iso8859-1')
+		if txt.find('LiTTleEnDian')>-1:
+			self.generator.tmp.append('little')
+		elif txt.find('BIGenDianSyS')>-1:
+			self.generator.tmp.append('big')
+		else:
+			return-1
+@feature('grep_for_endianness')
+@after_method('process_source')
+def grep_for_endianness_fun(self):
+	self.create_task('grep_for_endianness',self.compiled_tasks[0].outputs[0])
+@conf
+def check_endianness(self):
+	tmp=[]
+	def check_msg(self):
+		return tmp[0]
+	self.check(fragment=ENDIAN_FRAGMENT,features='c grep_for_endianness',msg="Checking for endianness",define='ENDIANNESS',tmp=tmp,okmsg=check_msg)
+	return tmp[0]
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.pyc
new file mode 100644
index 0000000..ed42588
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.py
new file mode 100644
index 0000000..3fa7084
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.py
@@ -0,0 +1,396 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Task,Utils,Node,Errors
+from waflib.TaskGen import after_method,before_method,feature,taskgen_method,extension
+from waflib.Tools import c_aliases,c_preproc,c_config,c_osx,c_tests
+from waflib.Configure import conf
+SYSTEM_LIB_PATHS=['/usr/lib64','/usr/lib','/usr/local/lib64','/usr/local/lib']
+USELIB_VARS=Utils.defaultdict(set)
+USELIB_VARS['c']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CCDEPS','CFLAGS','ARCH'])
+USELIB_VARS['cxx']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CXXDEPS','CXXFLAGS','ARCH'])
+USELIB_VARS['d']=set(['INCLUDES','DFLAGS'])
+USELIB_VARS['includes']=set(['INCLUDES','FRAMEWORKPATH','ARCH'])
+USELIB_VARS['cprogram']=USELIB_VARS['cxxprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH'])
+USELIB_VARS['cshlib']=USELIB_VARS['cxxshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH'])
+USELIB_VARS['cstlib']=USELIB_VARS['cxxstlib']=set(['ARFLAGS','LINKDEPS'])
+USELIB_VARS['dprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+USELIB_VARS['dshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+USELIB_VARS['dstlib']=set(['ARFLAGS','LINKDEPS'])
+USELIB_VARS['asm']=set(['ASFLAGS'])
+@taskgen_method
+def create_compiled_task(self,name,node):
+	out='%s.%d.o'%(node.name,self.idx)
+	task=self.create_task(name,node,node.parent.find_or_declare(out))
+	try:
+		self.compiled_tasks.append(task)
+	except AttributeError:
+		self.compiled_tasks=[task]
+	return task
+@taskgen_method
+def to_incnodes(self,inlst):
+	lst=[]
+	seen=set([])
+	for x in self.to_list(inlst):
+		if x in seen or not x:
+			continue
+		seen.add(x)
+		if isinstance(x,Node.Node):
+			lst.append(x)
+		else:
+			if os.path.isabs(x):
+				lst.append(self.bld.root.make_node(x)or x)
+			else:
+				if x[0]=='#':
+					p=self.bld.bldnode.make_node(x[1:])
+					v=self.bld.srcnode.make_node(x[1:])
+				else:
+					p=self.path.get_bld().make_node(x)
+					v=self.path.make_node(x)
+				if p.is_child_of(self.bld.bldnode):
+					p.mkdir()
+				lst.append(p)
+				lst.append(v)
+	return lst
+@feature('c','cxx','d','asm','fc','includes')
+@after_method('propagate_uselib_vars','process_source')
+def apply_incpaths(self):
+	lst=self.to_incnodes(self.to_list(getattr(self,'includes',[]))+self.env['INCLUDES'])
+	self.includes_nodes=lst
+	self.env['INCPATHS']=[x.abspath()for x in lst]
+class link_task(Task.Task):
+	color='YELLOW'
+	inst_to=None
+	chmod=Utils.O755
+	def add_target(self,target):
+		if isinstance(target,str):
+			pattern=self.env[self.__class__.__name__+'_PATTERN']
+			if not pattern:
+				pattern='%s'
+			folder,name=os.path.split(target)
+			if self.__class__.__name__.find('shlib')>0:
+				if self.env.DEST_BINFMT=='pe'and getattr(self.generator,'vnum',None):
+					name=name+'-'+self.generator.vnum.split('.')[0]
+			tmp=folder+os.sep+pattern%name
+			target=self.generator.path.find_or_declare(tmp)
+		self.set_outputs(target)
+class stlink_task(link_task):
+	run_str='${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}'
+def rm_tgt(cls):
+	old=cls.run
+	def wrap(self):
+		try:os.remove(self.outputs[0].abspath())
+		except OSError:pass
+		return old(self)
+	setattr(cls,'run',wrap)
+rm_tgt(stlink_task)
+@feature('c','cxx','d','fc','asm')
+@after_method('process_source')
+def apply_link(self):
+	for x in self.features:
+		if x=='cprogram'and'cxx'in self.features:
+			x='cxxprogram'
+		elif x=='cshlib'and'cxx'in self.features:
+			x='cxxshlib'
+		if x in Task.classes:
+			if issubclass(Task.classes[x],link_task):
+				link=x
+				break
+	else:
+		return
+	objs=[t.outputs[0]for t in getattr(self,'compiled_tasks',[])]
+	self.link_task=self.create_task(link,objs)
+	self.link_task.add_target(self.target)
+	try:
+		inst_to=self.install_path
+	except AttributeError:
+		inst_to=self.link_task.__class__.inst_to
+	if inst_to:
+		self.install_task=self.bld.install_files(inst_to,self.link_task.outputs[:],env=self.env,chmod=self.link_task.chmod)
+@taskgen_method
+def use_rec(self,name,**kw):
+	if name in self.tmp_use_not or name in self.tmp_use_seen:
+		return
+	try:
+		y=self.bld.get_tgen_by_name(name)
+	except Errors.WafError:
+		self.uselib.append(name)
+		self.tmp_use_not.add(name)
+		return
+	self.tmp_use_seen.append(name)
+	y.post()
+	y.tmp_use_objects=objects=kw.get('objects',True)
+	y.tmp_use_stlib=stlib=kw.get('stlib',True)
+	try:
+		link_task=y.link_task
+	except AttributeError:
+		y.tmp_use_var=''
+	else:
+		objects=False
+		if not isinstance(link_task,stlink_task):
+			stlib=False
+			y.tmp_use_var='LIB'
+		else:
+			y.tmp_use_var='STLIB'
+	p=self.tmp_use_prec
+	for x in self.to_list(getattr(y,'use',[])):
+		try:
+			p[x].append(name)
+		except KeyError:
+			p[x]=[name]
+		self.use_rec(x,objects=objects,stlib=stlib)
+@feature('c','cxx','d','use','fc')
+@before_method('apply_incpaths','propagate_uselib_vars')
+@after_method('apply_link','process_source')
+def process_use(self):
+	use_not=self.tmp_use_not=set([])
+	self.tmp_use_seen=[]
+	use_prec=self.tmp_use_prec={}
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	self.includes=self.to_list(getattr(self,'includes',[]))
+	names=self.to_list(getattr(self,'use',[]))
+	for x in names:
+		self.use_rec(x)
+	for x in use_not:
+		if x in use_prec:
+			del use_prec[x]
+	out=[]
+	tmp=[]
+	for x in self.tmp_use_seen:
+		for k in use_prec.values():
+			if x in k:
+				break
+		else:
+			tmp.append(x)
+	while tmp:
+		e=tmp.pop()
+		out.append(e)
+		try:
+			nlst=use_prec[e]
+		except KeyError:
+			pass
+		else:
+			del use_prec[e]
+			for x in nlst:
+				for y in use_prec:
+					if x in use_prec[y]:
+						break
+				else:
+					tmp.append(x)
+	if use_prec:
+		raise Errors.WafError('Cycle detected in the use processing %r'%use_prec)
+	out.reverse()
+	link_task=getattr(self,'link_task',None)
+	for x in out:
+		y=self.bld.get_tgen_by_name(x)
+		var=y.tmp_use_var
+		if var and link_task:
+			if var=='LIB'or y.tmp_use_stlib:
+				self.env.append_value(var,[y.target[y.target.rfind(os.sep)+1:]])
+				self.link_task.dep_nodes.extend(y.link_task.outputs)
+				tmp_path=y.link_task.outputs[0].parent.path_from(self.bld.bldnode)
+				self.env.append_value(var+'PATH',[tmp_path])
+		else:
+			if y.tmp_use_objects:
+				self.add_objects_from_tgen(y)
+		if getattr(y,'export_includes',None):
+			self.includes.extend(y.to_incnodes(y.export_includes))
+		if getattr(y,'export_defines',None):
+			self.env.append_value('DEFINES',self.to_list(y.export_defines))
+	for x in names:
+		try:
+			y=self.bld.get_tgen_by_name(x)
+		except Exception:
+			if not self.env['STLIB_'+x]and not x in self.uselib:
+				self.uselib.append(x)
+		else:
+			for k in self.to_list(getattr(y,'uselib',[])):
+				if not self.env['STLIB_'+k]and not k in self.uselib:
+					self.uselib.append(k)
+@taskgen_method
+def accept_node_to_link(self,node):
+	return not node.name.endswith('.pdb')
+@taskgen_method
+def add_objects_from_tgen(self,tg):
+	try:
+		link_task=self.link_task
+	except AttributeError:
+		pass
+	else:
+		for tsk in getattr(tg,'compiled_tasks',[]):
+			for x in tsk.outputs:
+				if self.accept_node_to_link(x):
+					link_task.inputs.append(x)
+@taskgen_method
+def get_uselib_vars(self):
+	_vars=set([])
+	for x in self.features:
+		if x in USELIB_VARS:
+			_vars|=USELIB_VARS[x]
+	return _vars
+@feature('c','cxx','d','fc','javac','cs','uselib','asm')
+@after_method('process_use')
+def propagate_uselib_vars(self):
+	_vars=self.get_uselib_vars()
+	env=self.env
+	for x in _vars:
+		y=x.lower()
+		env.append_unique(x,self.to_list(getattr(self,y,[])))
+	for x in self.features:
+		for var in _vars:
+			compvar='%s_%s'%(var,x)
+			env.append_value(var,env[compvar])
+	for x in self.to_list(getattr(self,'uselib',[])):
+		for v in _vars:
+			env.append_value(v,env[v+'_'+x])
+@feature('cshlib','cxxshlib','fcshlib')
+@after_method('apply_link')
+def apply_implib(self):
+	if not self.env.DEST_BINFMT=='pe':
+		return
+	dll=self.link_task.outputs[0]
+	if isinstance(self.target,Node.Node):
+		name=self.target.name
+	else:
+		name=os.path.split(self.target)[1]
+	implib=self.env['implib_PATTERN']%name
+	implib=dll.parent.find_or_declare(implib)
+	self.env.append_value('LINKFLAGS',self.env['IMPLIB_ST']%implib.bldpath())
+	self.link_task.outputs.append(implib)
+	if getattr(self,'defs',None)and self.env.DEST_BINFMT=='pe':
+		node=self.path.find_resource(self.defs)
+		if not node:
+			raise Errors.WafError('invalid def file %r'%self.defs)
+		if'msvc'in(self.env.CC_NAME,self.env.CXX_NAME):
+			self.env.append_value('LINKFLAGS','/def:%s'%node.path_from(self.bld.bldnode))
+			self.link_task.dep_nodes.append(node)
+		else:
+			self.link_task.inputs.append(node)
+	try:
+		inst_to=self.install_path
+	except AttributeError:
+		inst_to=self.link_task.__class__.inst_to
+	if not inst_to:
+		return
+	self.implib_install_task=self.bld.install_as('${LIBDIR}/%s'%implib.name,implib,self.env)
+re_vnum=re.compile('^([1-9]\\d*|0)[.]([1-9]\\d*|0)[.]([1-9]\\d*|0)$')
+@feature('cshlib','cxxshlib','dshlib','fcshlib','vnum')
+@after_method('apply_link','propagate_uselib_vars')
+def apply_vnum(self):
+	if not getattr(self,'vnum','')or os.name!='posix'or self.env.DEST_BINFMT not in('elf','mac-o'):
+		return
+	link=self.link_task
+	if not re_vnum.match(self.vnum):
+		raise Errors.WafError('Invalid version %r for %r'%(self.vnum,self))
+	nums=self.vnum.split('.')
+	node=link.outputs[0]
+	libname=node.name
+	if libname.endswith('.dylib'):
+		name3=libname.replace('.dylib','.%s.dylib'%self.vnum)
+		name2=libname.replace('.dylib','.%s.dylib'%nums[0])
+	else:
+		name3=libname+'.'+self.vnum
+		name2=libname+'.'+nums[0]
+	if self.env.SONAME_ST:
+		v=self.env.SONAME_ST%name2
+		self.env.append_value('LINKFLAGS',v.split())
+	self.create_task('vnum',node,[node.parent.find_or_declare(name2),node.parent.find_or_declare(name3)])
+	if getattr(self,'install_task',None):
+		self.install_task.hasrun=Task.SKIP_ME
+		bld=self.bld
+		path=self.install_task.dest
+		t1=bld.install_as(path+os.sep+name3,node,env=self.env,chmod=self.link_task.chmod)
+		t2=bld.symlink_as(path+os.sep+name2,name3)
+		t3=bld.symlink_as(path+os.sep+libname,name3)
+		self.vnum_install_task=(t1,t2,t3)
+	if'-dynamiclib'in self.env['LINKFLAGS']:
+		try:
+			inst_to=self.install_path
+		except AttributeError:
+			inst_to=self.link_task.__class__.inst_to
+		if inst_to:
+			p=Utils.subst_vars(inst_to,self.env)
+			path=os.path.join(p,self.link_task.outputs[0].name)
+			self.env.append_value('LINKFLAGS',['-install_name',path])
+class vnum(Task.Task):
+	color='CYAN'
+	quient=True
+	ext_in=['.bin']
+	def run(self):
+		for x in self.outputs:
+			path=x.abspath()
+			try:
+				os.remove(path)
+			except OSError:
+				pass
+			try:
+				os.symlink(self.inputs[0].name,path)
+			except OSError:
+				return 1
+class fake_shlib(link_task):
+	def runnable_status(self):
+		for t in self.run_after:
+			if not t.hasrun:
+				return Task.ASK_LATER
+		for x in self.outputs:
+			x.sig=Utils.h_file(x.abspath())
+		return Task.SKIP_ME
+class fake_stlib(stlink_task):
+	def runnable_status(self):
+		for t in self.run_after:
+			if not t.hasrun:
+				return Task.ASK_LATER
+		for x in self.outputs:
+			x.sig=Utils.h_file(x.abspath())
+		return Task.SKIP_ME
+@conf
+def read_shlib(self,name,paths=[],export_includes=[],export_defines=[]):
+	return self(name=name,features='fake_lib',lib_paths=paths,lib_type='shlib',export_includes=export_includes,export_defines=export_defines)
+@conf
+def read_stlib(self,name,paths=[],export_includes=[],export_defines=[]):
+	return self(name=name,features='fake_lib',lib_paths=paths,lib_type='stlib',export_includes=export_includes,export_defines=export_defines)
+lib_patterns={'shlib':['lib%s.so','%s.so','lib%s.dylib','lib%s.dll','%s.dll'],'stlib':['lib%s.a','%s.a','lib%s.dll','%s.dll','lib%s.lib','%s.lib'],}
+@feature('fake_lib')
+def process_lib(self):
+	node=None
+	names=[x%self.name for x in lib_patterns[self.lib_type]]
+	for x in self.lib_paths+[self.path]+SYSTEM_LIB_PATHS:
+		if not isinstance(x,Node.Node):
+			x=self.bld.root.find_node(x)or self.path.find_node(x)
+			if not x:
+				continue
+		for y in names:
+			node=x.find_node(y)
+			if node:
+				node.sig=Utils.h_file(node.abspath())
+				break
+		else:
+			continue
+		break
+	else:
+		raise Errors.WafError('could not find library %r'%self.name)
+	self.link_task=self.create_task('fake_%s'%self.lib_type,[],[node])
+	self.target=self.name
+class fake_o(Task.Task):
+	def runnable_status(self):
+		return Task.SKIP_ME
+@extension('.o','.obj')
+def add_those_o_files(self,node):
+	tsk=self.create_task('fake_o',[],node)
+	try:
+		self.compiled_tasks.append(tsk)
+	except AttributeError:
+		self.compiled_tasks=[tsk]
+@feature('fake_obj')
+@before_method('process_source')
+def process_objs(self):
+	for node in self.to_nodes(self.source):
+		self.add_those_o_files(node)
+	self.source=[]
+@conf
+def read_object(self,obj):
+	if not isinstance(obj,self.path.__class__):
+		obj=self.path.find_resource(obj)
+	return self(features='fake_obj',source=obj,name=obj.name)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.pyc
new file mode 100644
index 0000000..e13e91d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.py
new file mode 100644
index 0000000..04504fa
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.py
@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib.Tools import ccroot
+from waflib import Utils,Configure
+from waflib.Logs import debug
+c_compiler={'win32':['msvc','gcc'],'cygwin':['gcc'],'darwin':['gcc'],'aix':['xlc','gcc'],'linux':['gcc','icc'],'sunos':['suncc','gcc'],'irix':['gcc','irixcc'],'hpux':['gcc'],'gnu':['gcc'],'java':['gcc','msvc','icc'],'default':['gcc'],}
+def configure(conf):
+	try:test_for_compiler=conf.options.check_c_compiler
+	except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_c')")
+	for compiler in test_for_compiler.split():
+		conf.env.stash()
+		conf.start_msg('Checking for %r (c compiler)'%compiler)
+		try:
+			conf.load(compiler)
+		except conf.errors.ConfigurationError ,e:
+			conf.env.revert()
+			conf.end_msg(False)
+			debug('compiler_c: %r'%e)
+		else:
+			if conf.env['CC']:
+				conf.end_msg(conf.env.get_flat('CC'))
+				conf.env['COMPILER_CC']=compiler
+				break
+			conf.end_msg(False)
+	else:
+		conf.fatal('could not configure a c compiler!')
+def options(opt):
+	opt.load_special_tools('c_*.py',ban=['c_dumbpreproc.py'])
+	global c_compiler
+	build_platform=Utils.unversioned_sys_platform()
+	possible_compiler_list=c_compiler[build_platform in c_compiler and build_platform or'default']
+	test_for_compiler=' '.join(possible_compiler_list)
+	cc_compiler_opts=opt.add_option_group("C Compiler Options")
+	cc_compiler_opts.add_option('--check-c-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following C-Compiler will be checked by default: "%s"'%(build_platform,test_for_compiler),dest="check_c_compiler")
+	for x in test_for_compiler.split():
+		opt.load('%s'%x)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.pyc
new file mode 100644
index 0000000..7b68f35
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.py
new file mode 100644
index 0000000..14b7c7d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.py
@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib.Tools import ccroot
+from waflib import Utils,Configure
+from waflib.Logs import debug
+cxx_compiler={'win32':['msvc','g++'],'cygwin':['g++'],'darwin':['g++'],'aix':['xlc++','g++'],'linux':['g++','icpc'],'sunos':['sunc++','g++'],'irix':['g++'],'hpux':['g++'],'gnu':['g++'],'java':['g++','msvc','icpc'],'default':['g++']}
+def configure(conf):
+	try:test_for_compiler=conf.options.check_cxx_compiler
+	except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_cxx')")
+	for compiler in test_for_compiler.split():
+		conf.env.stash()
+		conf.start_msg('Checking for %r (c++ compiler)'%compiler)
+		try:
+			conf.load(compiler)
+		except conf.errors.ConfigurationError ,e:
+			conf.env.revert()
+			conf.end_msg(False)
+			debug('compiler_cxx: %r'%e)
+		else:
+			if conf.env['CXX']:
+				conf.end_msg(conf.env.get_flat('CXX'))
+				conf.env['COMPILER_CXX']=compiler
+				break
+			conf.end_msg(False)
+	else:
+		conf.fatal('could not configure a c++ compiler!')
+def options(opt):
+	opt.load_special_tools('cxx_*.py')
+	global cxx_compiler
+	build_platform=Utils.unversioned_sys_platform()
+	possible_compiler_list=cxx_compiler[build_platform in cxx_compiler and build_platform or'default']
+	test_for_compiler=' '.join(possible_compiler_list)
+	cxx_compiler_opts=opt.add_option_group('C++ Compiler Options')
+	cxx_compiler_opts.add_option('--check-cxx-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following C++ Compiler will be checked by default: "%s"'%(build_platform,test_for_compiler),dest="check_cxx_compiler")
+	for x in test_for_compiler.split():
+		opt.load('%s'%x)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.pyc
new file mode 100644
index 0000000..ad9679e
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_d.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_d.py
new file mode 100644
index 0000000..ee173e1
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_d.py
@@ -0,0 +1,29 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib import Utils,Configure,Options,Logs
+def configure(conf):
+	for compiler in conf.options.dcheck.split(','):
+		conf.env.stash()
+		conf.start_msg('Checking for %r (d compiler)'%compiler)
+		try:
+			conf.load(compiler)
+		except conf.errors.ConfigurationError ,e:
+			conf.env.revert()
+			conf.end_msg(False)
+			Logs.debug('compiler_d: %r'%e)
+		else:
+			if conf.env.D:
+				conf.end_msg(conf.env.get_flat('D'))
+				conf.env['COMPILER_D']=compiler
+				break
+			conf.end_msg(False)
+	else:
+		conf.fatal('no suitable d compiler was found')
+def options(opt):
+	d_compiler_opts=opt.add_option_group('D Compiler Options')
+	d_compiler_opts.add_option('--check-d-compiler',default='gdc,dmd,ldc2',action='store',help='check for the compiler [Default:gdc,dmd,ldc2]',dest='dcheck')
+	for d_compiler in['gdc','dmd','ldc2']:
+		opt.load('%s'%d_compiler)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_fc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_fc.py
new file mode 100644
index 0000000..ec5d2ea
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_fc.py
@@ -0,0 +1,43 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib import Utils,Configure,Options,Logs,Errors
+from waflib.Tools import fc
+fc_compiler={'win32':['gfortran','ifort'],'darwin':['gfortran','g95','ifort'],'linux':['gfortran','g95','ifort'],'java':['gfortran','g95','ifort'],'default':['gfortran'],'aix':['gfortran']}
+def __list_possible_compiler(platform):
+	try:
+		return fc_compiler[platform]
+	except KeyError:
+		return fc_compiler["default"]
+def configure(conf):
+	try:test_for_compiler=conf.options.check_fc
+	except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_fc')")
+	for compiler in test_for_compiler.split():
+		conf.env.stash()
+		conf.start_msg('Checking for %r (fortran compiler)'%compiler)
+		try:
+			conf.load(compiler)
+		except conf.errors.ConfigurationError ,e:
+			conf.env.revert()
+			conf.end_msg(False)
+			Logs.debug('compiler_fortran: %r'%e)
+		else:
+			if conf.env['FC']:
+				conf.end_msg(conf.env.get_flat('FC'))
+				conf.env.COMPILER_FORTRAN=compiler
+				break
+			conf.end_msg(False)
+	else:
+		conf.fatal('could not configure a fortran compiler!')
+def options(opt):
+	opt.load_special_tools('fc_*.py')
+	build_platform=Utils.unversioned_sys_platform()
+	detected_platform=Options.platform
+	possible_compiler_list=__list_possible_compiler(detected_platform)
+	test_for_compiler=' '.join(possible_compiler_list)
+	fortran_compiler_opts=opt.add_option_group("Fortran Compiler Options")
+	fortran_compiler_opts.add_option('--check-fortran-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following Fortran Compiler will be checked by default: "%s"'%(detected_platform,test_for_compiler),dest="check_fc")
+	for compiler in test_for_compiler.split():
+		opt.load('%s'%compiler)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cs.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cs.py
new file mode 100644
index 0000000..ee4d319
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cs.py
@@ -0,0 +1,132 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Utils,Task,Options,Logs,Errors
+from waflib.TaskGen import before_method,after_method,feature
+from waflib.Tools import ccroot
+from waflib.Configure import conf
+import os,tempfile
+ccroot.USELIB_VARS['cs']=set(['CSFLAGS','ASSEMBLIES','RESOURCES'])
+ccroot.lib_patterns['csshlib']=['%s']
+@feature('cs')
+@before_method('process_source')
+def apply_cs(self):
+	cs_nodes=[]
+	no_nodes=[]
+	for x in self.to_nodes(self.source):
+		if x.name.endswith('.cs'):
+			cs_nodes.append(x)
+		else:
+			no_nodes.append(x)
+	self.source=no_nodes
+	bintype=getattr(self,'bintype',self.gen.endswith('.dll')and'library'or'exe')
+	self.cs_task=tsk=self.create_task('mcs',cs_nodes,self.path.find_or_declare(self.gen))
+	tsk.env.CSTYPE='/target:%s'%bintype
+	tsk.env.OUT='/out:%s'%tsk.outputs[0].abspath()
+	self.env.append_value('CSFLAGS','/platform:%s'%getattr(self,'platform','anycpu'))
+	inst_to=getattr(self,'install_path',bintype=='exe'and'${BINDIR}'or'${LIBDIR}')
+	if inst_to:
+		mod=getattr(self,'chmod',bintype=='exe'and Utils.O755 or Utils.O644)
+		self.install_task=self.bld.install_files(inst_to,self.cs_task.outputs[:],env=self.env,chmod=mod)
+@feature('cs')
+@after_method('apply_cs')
+def use_cs(self):
+	names=self.to_list(getattr(self,'use',[]))
+	get=self.bld.get_tgen_by_name
+	for x in names:
+		try:
+			y=get(x)
+		except Errors.WafError:
+			self.env.append_value('CSFLAGS','/reference:%s'%x)
+			continue
+		y.post()
+		tsk=getattr(y,'cs_task',None)or getattr(y,'link_task',None)
+		if not tsk:
+			self.bld.fatal('cs task has no link task for use %r'%self)
+		self.cs_task.dep_nodes.extend(tsk.outputs)
+		self.cs_task.set_run_after(tsk)
+		self.env.append_value('CSFLAGS','/reference:%s'%tsk.outputs[0].abspath())
+@feature('cs')
+@after_method('apply_cs','use_cs')
+def debug_cs(self):
+	csdebug=getattr(self,'csdebug',self.env.CSDEBUG)
+	if not csdebug:
+		return
+	node=self.cs_task.outputs[0]
+	if self.env.CS_NAME=='mono':
+		out=node.parent.find_or_declare(node.name+'.mdb')
+	else:
+		out=node.change_ext('.pdb')
+	self.cs_task.outputs.append(out)
+	try:
+		self.install_task.source.append(out)
+	except AttributeError:
+		pass
+	if csdebug=='pdbonly':
+		val=['/debug+','/debug:pdbonly']
+	elif csdebug=='full':
+		val=['/debug+','/debug:full']
+	else:
+		val=['/debug-']
+	self.env.append_value('CSFLAGS',val)
+class mcs(Task.Task):
+	color='YELLOW'
+	run_str='${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}'
+	def exec_command(self,cmd,**kw):
+		bld=self.generator.bld
+		try:
+			if not kw.get('cwd',None):
+				kw['cwd']=bld.cwd
+		except AttributeError:
+			bld.cwd=kw['cwd']=bld.variant_dir
+		try:
+			tmp=None
+			if isinstance(cmd,list)and len(' '.join(cmd))>=8192:
+				program=cmd[0]
+				cmd=[self.quote_response_command(x)for x in cmd]
+				(fd,tmp)=tempfile.mkstemp()
+				os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
+				os.close(fd)
+				cmd=[program,'@'+tmp]
+			ret=self.generator.bld.exec_command(cmd,**kw)
+		finally:
+			if tmp:
+				try:
+					os.remove(tmp)
+				except OSError:
+					pass
+		return ret
+	def quote_response_command(self,flag):
+		if flag.lower()=='/noconfig':
+			return''
+		if flag.find(' ')>-1:
+			for x in('/r:','/reference:','/resource:','/lib:','/out:'):
+				if flag.startswith(x):
+					flag='%s"%s"'%(x,flag[len(x):])
+					break
+			else:
+				flag='"%s"'%flag
+		return flag
+def configure(conf):
+	csc=getattr(Options.options,'cscbinary',None)
+	if csc:
+		conf.env.MCS=csc
+	conf.find_program(['csc','mcs','gmcs'],var='MCS')
+	conf.env.ASS_ST='/r:%s'
+	conf.env.RES_ST='/resource:%s'
+	conf.env.CS_NAME='csc'
+	if str(conf.env.MCS).lower().find('mcs')>-1:
+		conf.env.CS_NAME='mono'
+def options(opt):
+	opt.add_option('--with-csc-binary',type='string',dest='cscbinary')
+class fake_csshlib(Task.Task):
+	color='YELLOW'
+	inst_to=None
+	def runnable_status(self):
+		for x in self.outputs:
+			x.sig=Utils.h_file(x.abspath())
+		return Task.SKIP_ME
+@conf
+def read_csshlib(self,name,paths=[]):
+	return self(name=name,features='fake_lib',lib_paths=paths,lib_type='csshlib')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.py
new file mode 100644
index 0000000..b744a8d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.py
@@ -0,0 +1,26 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import TaskGen,Task,Utils
+from waflib.Tools import c_preproc
+from waflib.Tools.ccroot import link_task,stlink_task
+@TaskGen.extension('.cpp','.cc','.cxx','.C','.c++')
+def cxx_hook(self,node):
+	return self.create_compiled_task('cxx',node)
+if not'.c'in TaskGen.task_gen.mappings:
+	TaskGen.task_gen.mappings['.c']=TaskGen.task_gen.mappings['.cpp']
+class cxx(Task.Task):
+	run_str='${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT}'
+	vars=['CXXDEPS']
+	ext_in=['.h']
+	scan=c_preproc.scan
+class cxxprogram(link_task):
+	run_str='${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}'
+	vars=['LINKDEPS']
+	ext_out=['.bin']
+	inst_to='${BINDIR}'
+class cxxshlib(cxxprogram):
+	inst_to='${LIBDIR}'
+class cxxstlib(stlink_task):
+	pass
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.pyc
new file mode 100644
index 0000000..3edb2e0
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d.py
new file mode 100644
index 0000000..1838740
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d.py
@@ -0,0 +1,54 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Utils,Task,Errors
+from waflib.TaskGen import taskgen_method,feature,extension
+from waflib.Tools import d_scan,d_config
+from waflib.Tools.ccroot import link_task,stlink_task
+class d(Task.Task):
+	color='GREEN'
+	run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}'
+	scan=d_scan.scan
+class d_with_header(d):
+	run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_HDR_F:tgt.outputs[1].bldpath()} ${D_SRC_F:SRC} ${D_TGT_F:tgt.outputs[0].bldpath()}'
+class d_header(Task.Task):
+	color='BLUE'
+	run_str='${D} ${D_HEADER} ${SRC}'
+class dprogram(link_task):
+	run_str='${D_LINKER} ${LINKFLAGS} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F:TGT} ${RPATH_ST:RPATH} ${DSTLIB_MARKER} ${DSTLIBPATH_ST:STLIBPATH} ${DSTLIB_ST:STLIB} ${DSHLIB_MARKER} ${DLIBPATH_ST:LIBPATH} ${DSHLIB_ST:LIB}'
+	inst_to='${BINDIR}'
+class dshlib(dprogram):
+	inst_to='${LIBDIR}'
+class dstlib(stlink_task):
+	pass
+@extension('.d','.di','.D')
+def d_hook(self,node):
+	ext=Utils.destos_to_binfmt(self.env.DEST_OS)=='pe'and'obj'or'o'
+	out='%s.%d.%s'%(node.name,self.idx,ext)
+	def create_compiled_task(self,name,node):
+		task=self.create_task(name,node,node.parent.find_or_declare(out))
+		try:
+			self.compiled_tasks.append(task)
+		except AttributeError:
+			self.compiled_tasks=[task]
+		return task
+	if getattr(self,'generate_headers',None):
+		tsk=create_compiled_task(self,'d_with_header',node)
+		tsk.outputs.append(node.change_ext(self.env['DHEADER_ext']))
+	else:
+		tsk=create_compiled_task(self,'d',node)
+	return tsk
+@taskgen_method
+def generate_header(self,filename):
+	try:
+		self.header_lst.append([filename,self.install_path])
+	except AttributeError:
+		self.header_lst=[[filename,self.install_path]]
+@feature('d')
+def process_header(self):
+	for i in getattr(self,'header_lst',[]):
+		node=self.path.find_resource(i[0])
+		if not node:
+			raise Errors.WafError('file %r not found on d obj'%i[0])
+		self.create_task('d_header',node,node.change_ext('.di'))
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_config.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_config.py
new file mode 100644
index 0000000..50660ea
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_config.py
@@ -0,0 +1,52 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Utils
+from waflib.Configure import conf
+@conf
+def d_platform_flags(self):
+	v=self.env
+	if not v.DEST_OS:
+		v.DEST_OS=Utils.unversioned_sys_platform()
+	binfmt=Utils.destos_to_binfmt(self.env.DEST_OS)
+	if binfmt=='pe':
+		v['dprogram_PATTERN']='%s.exe'
+		v['dshlib_PATTERN']='lib%s.dll'
+		v['dstlib_PATTERN']='lib%s.a'
+	elif binfmt=='mac-o':
+		v['dprogram_PATTERN']='%s'
+		v['dshlib_PATTERN']='lib%s.dylib'
+		v['dstlib_PATTERN']='lib%s.a'
+	else:
+		v['dprogram_PATTERN']='%s'
+		v['dshlib_PATTERN']='lib%s.so'
+		v['dstlib_PATTERN']='lib%s.a'
+DLIB='''
+version(D_Version2) {
+	import std.stdio;
+	int main() {
+		writefln("phobos2");
+		return 0;
+	}
+} else {
+	version(Tango) {
+		import tango.stdc.stdio;
+		int main() {
+			printf("tango");
+			return 0;
+		}
+	} else {
+		import std.stdio;
+		int main() {
+			writefln("phobos1");
+			return 0;
+		}
+	}
+}
+'''
+@conf
+def check_dlibrary(self,execute=True):
+	ret=self.check_cc(features='d dprogram',fragment=DLIB,compile_filename='test.d',execute=execute,define_ret=True)
+	if execute:
+		self.env.DLIBRARY=ret.strip()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_scan.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_scan.py
new file mode 100644
index 0000000..ee80c5f
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_scan.py
@@ -0,0 +1,133 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Logs
+def filter_comments(filename):
+	txt=Utils.readf(filename)
+	i=0
+	buf=[]
+	max=len(txt)
+	begin=0
+	while i<max:
+		c=txt[i]
+		if c=='"'or c=="'":
+			buf.append(txt[begin:i])
+			delim=c
+			i+=1
+			while i<max:
+				c=txt[i]
+				if c==delim:break
+				elif c=='\\':
+					i+=1
+				i+=1
+			i+=1
+			begin=i
+		elif c=='/':
+			buf.append(txt[begin:i])
+			i+=1
+			if i==max:break
+			c=txt[i]
+			if c=='+':
+				i+=1
+				nesting=1
+				c=None
+				while i<max:
+					prev=c
+					c=txt[i]
+					if prev=='/'and c=='+':
+						nesting+=1
+						c=None
+					elif prev=='+'and c=='/':
+						nesting-=1
+						if nesting==0:break
+						c=None
+					i+=1
+			elif c=='*':
+				i+=1
+				c=None
+				while i<max:
+					prev=c
+					c=txt[i]
+					if prev=='*'and c=='/':break
+					i+=1
+			elif c=='/':
+				i+=1
+				while i<max and txt[i]!='\n':
+					i+=1
+			else:
+				begin=i-1
+				continue
+			i+=1
+			begin=i
+			buf.append(' ')
+		else:
+			i+=1
+	buf.append(txt[begin:])
+	return buf
+class d_parser(object):
+	def __init__(self,env,incpaths):
+		self.allnames=[]
+		self.re_module=re.compile("module\s+([^;]+)")
+		self.re_import=re.compile("import\s+([^;]+)")
+		self.re_import_bindings=re.compile("([^:]+):(.*)")
+		self.re_import_alias=re.compile("[^=]+=(.+)")
+		self.env=env
+		self.nodes=[]
+		self.names=[]
+		self.incpaths=incpaths
+	def tryfind(self,filename):
+		found=0
+		for n in self.incpaths:
+			found=n.find_resource(filename.replace('.','/')+'.d')
+			if found:
+				self.nodes.append(found)
+				self.waiting.append(found)
+				break
+		if not found:
+			if not filename in self.names:
+				self.names.append(filename)
+	def get_strings(self,code):
+		self.module=''
+		lst=[]
+		mod_name=self.re_module.search(code)
+		if mod_name:
+			self.module=re.sub('\s+','',mod_name.group(1))
+		import_iterator=self.re_import.finditer(code)
+		if import_iterator:
+			for import_match in import_iterator:
+				import_match_str=re.sub('\s+','',import_match.group(1))
+				bindings_match=self.re_import_bindings.match(import_match_str)
+				if bindings_match:
+					import_match_str=bindings_match.group(1)
+				matches=import_match_str.split(',')
+				for match in matches:
+					alias_match=self.re_import_alias.match(match)
+					if alias_match:
+						match=alias_match.group(1)
+					lst.append(match)
+		return lst
+	def start(self,node):
+		self.waiting=[node]
+		while self.waiting:
+			nd=self.waiting.pop(0)
+			self.iter(nd)
+	def iter(self,node):
+		path=node.abspath()
+		code="".join(filter_comments(path))
+		names=self.get_strings(code)
+		for x in names:
+			if x in self.allnames:continue
+			self.allnames.append(x)
+			self.tryfind(x)
+def scan(self):
+	env=self.env
+	gruik=d_parser(env,self.generator.includes_nodes)
+	node=self.inputs[0]
+	gruik.start(node)
+	nodes=gruik.nodes
+	names=gruik.names
+	if Logs.verbose:
+		Logs.debug('deps: deps for %s: %r; unresolved %r'%(str(node),nodes,names))
+	return(nodes,names)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dbus.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dbus.py
new file mode 100644
index 0000000..ccea278
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dbus.py
@@ -0,0 +1,29 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Task,Errors
+from waflib.TaskGen import taskgen_method,before_method
+@taskgen_method
+def add_dbus_file(self,filename,prefix,mode):
+	if not hasattr(self,'dbus_lst'):
+		self.dbus_lst=[]
+	if not'process_dbus'in self.meths:
+		self.meths.append('process_dbus')
+	self.dbus_lst.append([filename,prefix,mode])
+@before_method('apply_core')
+def process_dbus(self):
+	for filename,prefix,mode in getattr(self,'dbus_lst',[]):
+		node=self.path.find_resource(filename)
+		if not node:
+			raise Errors.WafError('file not found '+filename)
+		tsk=self.create_task('dbus_binding_tool',node,node.change_ext('.h'))
+		tsk.env.DBUS_BINDING_TOOL_PREFIX=prefix
+		tsk.env.DBUS_BINDING_TOOL_MODE=mode
+class dbus_binding_tool(Task.Task):
+	color='BLUE'
+	ext_out=['.h']
+	run_str='${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}'
+	shell=True
+def configure(conf):
+	dbus_binding_tool=conf.find_program('dbus-binding-tool',var='DBUS_BINDING_TOOL')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dmd.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dmd.py
new file mode 100644
index 0000000..b6e3303
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dmd.py
@@ -0,0 +1,51 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+@conf
+def find_dmd(conf):
+	conf.find_program(['dmd','dmd2','ldc'],var='D')
+	out=conf.cmd_and_log([conf.env.D,'--help'])
+	if out.find("D Compiler v")==-1:
+		out=conf.cmd_and_log([conf.env.D,'-version'])
+		if out.find("based on DMD v1.")==-1:
+			conf.fatal("detected compiler is not dmd/ldc")
+@conf
+def common_flags_ldc(conf):
+	v=conf.env
+	v['DFLAGS']=['-d-version=Posix']
+	v['LINKFLAGS']=[]
+	v['DFLAGS_dshlib']=['-relocation-model=pic']
+@conf
+def common_flags_dmd(conf):
+	v=conf.env
+	v['D_SRC_F']=['-c']
+	v['D_TGT_F']='-of%s'
+	v['D_LINKER']=v['D']
+	v['DLNK_SRC_F']=''
+	v['DLNK_TGT_F']='-of%s'
+	v['DINC_ST']='-I%s'
+	v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+	v['DSTLIB_ST']=v['DSHLIB_ST']='-L-l%s'
+	v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L-L%s'
+	v['LINKFLAGS_dprogram']=['-quiet']
+	v['DFLAGS_dshlib']=['-fPIC']
+	v['LINKFLAGS_dshlib']=['-L-shared']
+	v['DHEADER_ext']='.di'
+	v.DFLAGS_d_with_header=['-H','-Hf']
+	v['D_HDR_F']='%s'
+def configure(conf):
+	conf.find_dmd()
+	if sys.platform=='win32':
+		out=conf.cmd_and_log([conf.env.D,'--help'])
+		if out.find("D Compiler v2.")>-1:
+			conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead')
+	conf.load('ar')
+	conf.load('d')
+	conf.common_flags_dmd()
+	conf.d_platform_flags()
+	if str(conf.env.D).find('ldc')>-1:
+		conf.common_flags_ldc()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/errcheck.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/errcheck.py
new file mode 100644
index 0000000..3b06493
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/errcheck.py
@@ -0,0 +1,161 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path','iscopy':'is_copy',}
+meths_typos=['__call__','program','shlib','stlib','objects']
+from waflib import Logs,Build,Node,Task,TaskGen,ConfigSet,Errors,Utils
+import waflib.Tools.ccroot
+def check_same_targets(self):
+	mp=Utils.defaultdict(list)
+	uids={}
+	def check_task(tsk):
+		if not isinstance(tsk,Task.Task):
+			return
+		for node in tsk.outputs:
+			mp[node].append(tsk)
+		try:
+			uids[tsk.uid()].append(tsk)
+		except KeyError:
+			uids[tsk.uid()]=[tsk]
+	for g in self.groups:
+		for tg in g:
+			try:
+				for tsk in tg.tasks:
+					check_task(tsk)
+			except AttributeError:
+				check_task(tg)
+	dupe=False
+	for(k,v)in mp.items():
+		if len(v)>1:
+			dupe=True
+			msg='* Node %r is created more than once%s. The task generators are:'%(k,Logs.verbose==1 and" (full message on 'waf -v -v')"or"")
+			Logs.error(msg)
+			for x in v:
+				if Logs.verbose>1:
+					Logs.error('  %d. %r'%(1+v.index(x),x.generator))
+				else:
+					Logs.error('  %d. %r in %r'%(1+v.index(x),x.generator.name,getattr(x.generator,'path',None)))
+	if not dupe:
+		for(k,v)in uids.items():
+			if len(v)>1:
+				Logs.error('* Several tasks use the same identifier. Please check the information on\n   http://docs.waf.googlecode.com/git/apidocs_16/Task.html#waflib.Task.Task.uid')
+				for tsk in v:
+					Logs.error('  - object %r (%r) defined in %r'%(tsk.__class__.__name__,tsk,tsk.generator))
+def check_invalid_constraints(self):
+	feat=set([])
+	for x in list(TaskGen.feats.values()):
+		feat.union(set(x))
+	for(x,y)in TaskGen.task_gen.prec.items():
+		feat.add(x)
+		feat.union(set(y))
+	ext=set([])
+	for x in TaskGen.task_gen.mappings.values():
+		ext.add(x.__name__)
+	invalid=ext&feat
+	if invalid:
+		Logs.error('The methods %r have invalid annotations:  @extension <-> @feature/@before_method/@after_method'%list(invalid))
+	for cls in list(Task.classes.values()):
+		for x in('before','after'):
+			for y in Utils.to_list(getattr(cls,x,[])):
+				if not Task.classes.get(y,None):
+					Logs.error('Erroneous order constraint %r=%r on task class %r'%(x,y,cls.__name__))
+		if getattr(cls,'rule',None):
+			Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")'%cls.__name__)
+def replace(m):
+	oldcall=getattr(Build.BuildContext,m)
+	def call(self,*k,**kw):
+		ret=oldcall(self,*k,**kw)
+		for x in typos:
+			if x in kw:
+				if x=='iscopy'and'subst'in getattr(self,'features',''):
+					continue
+				err=True
+				Logs.error('Fix the typo %r -> %r on %r'%(x,typos[x],ret))
+		return ret
+	setattr(Build.BuildContext,m,call)
+def enhance_lib():
+	for m in meths_typos:
+		replace(m)
+	def ant_glob(self,*k,**kw):
+		if k:
+			lst=Utils.to_list(k[0])
+			for pat in lst:
+				if'..'in pat.split('/'):
+					Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'"%k[0])
+		if kw.get('remove',True):
+			try:
+				if self.is_child_of(self.ctx.bldnode)and not kw.get('quiet',False):
+					Logs.error('Using ant_glob on the build folder (%r) is dangerous (quiet=True to disable this warning)'%self)
+			except AttributeError:
+				pass
+		return self.old_ant_glob(*k,**kw)
+	Node.Node.old_ant_glob=Node.Node.ant_glob
+	Node.Node.ant_glob=ant_glob
+	old=Task.is_before
+	def is_before(t1,t2):
+		ret=old(t1,t2)
+		if ret and old(t2,t1):
+			Logs.error('Contradictory order constraints in classes %r %r'%(t1,t2))
+		return ret
+	Task.is_before=is_before
+	def check_err_features(self):
+		lst=self.to_list(self.features)
+		if'shlib'in lst:
+			Logs.error('feature shlib -> cshlib, dshlib or cxxshlib')
+		for x in('c','cxx','d','fc'):
+			if not x in lst and lst and lst[0]in[x+y for y in('program','shlib','stlib')]:
+				Logs.error('%r features is probably missing %r'%(self,x))
+	TaskGen.feature('*')(check_err_features)
+	def check_err_order(self):
+		if not hasattr(self,'rule')and not'subst'in Utils.to_list(self.features):
+			for x in('before','after','ext_in','ext_out'):
+				if hasattr(self,x):
+					Logs.warn('Erroneous order constraint %r on non-rule based task generator %r'%(x,self))
+		else:
+			for x in('before','after'):
+				for y in self.to_list(getattr(self,x,[])):
+					if not Task.classes.get(y,None):
+						Logs.error('Erroneous order constraint %s=%r on %r (no such class)'%(x,y,self))
+	TaskGen.feature('*')(check_err_order)
+	def check_compile(self):
+		check_invalid_constraints(self)
+		try:
+			ret=self.orig_compile()
+		finally:
+			check_same_targets(self)
+		return ret
+	Build.BuildContext.orig_compile=Build.BuildContext.compile
+	Build.BuildContext.compile=check_compile
+	def use_rec(self,name,**kw):
+		try:
+			y=self.bld.get_tgen_by_name(name)
+		except Errors.WafError:
+			pass
+		else:
+			idx=self.bld.get_group_idx(self)
+			odx=self.bld.get_group_idx(y)
+			if odx>idx:
+				msg="Invalid 'use' across build groups:"
+				if Logs.verbose>1:
+					msg+='\n  target %r\n  uses:\n  %r'%(self,y)
+				else:
+					msg+=" %r uses %r (try 'waf -v -v' for the full error)"%(self.name,name)
+				raise Errors.WafError(msg)
+		self.orig_use_rec(name,**kw)
+	TaskGen.task_gen.orig_use_rec=TaskGen.task_gen.use_rec
+	TaskGen.task_gen.use_rec=use_rec
+	def getattri(self,name,default=None):
+		if name=='append'or name=='add':
+			raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique')
+		elif name=='prepend':
+			raise Errors.WafError('env.prepend does not exist: use env.prepend_value')
+		if name in self.__slots__:
+			return object.__getattr__(self,name,default)
+		else:
+			return self[name]
+	ConfigSet.ConfigSet.__getattr__=getattri
+def options(opt):
+	enhance_lib()
+def configure(conf):
+	pass
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc.py
new file mode 100644
index 0000000..3589799
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc.py
@@ -0,0 +1,116 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Task,TaskGen,Logs
+from waflib.Tools import ccroot,fc_config,fc_scan
+from waflib.TaskGen import feature,before_method,after_method,extension
+from waflib.Configure import conf
+ccroot.USELIB_VARS['fc']=set(['FCFLAGS','DEFINES','INCLUDES'])
+ccroot.USELIB_VARS['fcprogram_test']=ccroot.USELIB_VARS['fcprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+ccroot.USELIB_VARS['fcshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+ccroot.USELIB_VARS['fcstlib']=set(['ARFLAGS','LINKDEPS'])
+@feature('fcprogram','fcshlib','fcstlib','fcprogram_test')
+def dummy(self):
+	pass
+@extension('.f','.f90','.F','.F90','.for','.FOR')
+def fc_hook(self,node):
+	return self.create_compiled_task('fc',node)
+@conf
+def modfile(conf,name):
+	return{'lower':name.lower()+'.mod','lower.MOD':name.upper()+'.MOD','UPPER.mod':name.upper()+'.mod','UPPER':name.upper()+'.MOD'}[conf.env.FC_MOD_CAPITALIZATION or'lower']
+def get_fortran_tasks(tsk):
+	bld=tsk.generator.bld
+	tasks=bld.get_tasks_group(bld.get_group_idx(tsk.generator))
+	return[x for x in tasks if isinstance(x,fc)and not getattr(x,'nomod',None)and not getattr(x,'mod_fortran_done',None)]
+class fc(Task.Task):
+	color='GREEN'
+	run_str='${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()}'
+	vars=["FORTRANMODPATHFLAG"]
+	def scan(self):
+		tmp=fc_scan.fortran_parser(self.generator.includes_nodes)
+		tmp.task=self
+		tmp.start(self.inputs[0])
+		if Logs.verbose:
+			Logs.debug('deps: deps for %r: %r; unresolved %r'%(self.inputs,tmp.nodes,tmp.names))
+		return(tmp.nodes,tmp.names)
+	def runnable_status(self):
+		if getattr(self,'mod_fortran_done',None):
+			return super(fc,self).runnable_status()
+		bld=self.generator.bld
+		lst=get_fortran_tasks(self)
+		for tsk in lst:
+			tsk.mod_fortran_done=True
+		for tsk in lst:
+			ret=tsk.runnable_status()
+			if ret==Task.ASK_LATER:
+				for x in lst:
+					x.mod_fortran_done=None
+				return Task.ASK_LATER
+		ins=Utils.defaultdict(set)
+		outs=Utils.defaultdict(set)
+		for tsk in lst:
+			key=tsk.uid()
+			for x in bld.raw_deps[key]:
+				if x.startswith('MOD@'):
+					name=bld.modfile(x.replace('MOD@',''))
+					node=bld.srcnode.find_or_declare(name)
+					tsk.set_outputs(node)
+					outs[id(node)].add(tsk)
+		for tsk in lst:
+			key=tsk.uid()
+			for x in bld.raw_deps[key]:
+				if x.startswith('USE@'):
+					name=bld.modfile(x.replace('USE@',''))
+					node=bld.srcnode.find_resource(name)
+					if node and node not in tsk.outputs:
+						if not node in bld.node_deps[key]:
+							bld.node_deps[key].append(node)
+						ins[id(node)].add(tsk)
+		for k in ins.keys():
+			for a in ins[k]:
+				a.run_after.update(outs[k])
+				tmp=[]
+				for t in outs[k]:
+					tmp.extend(t.outputs)
+				a.dep_nodes.extend(tmp)
+				a.dep_nodes.sort(key=lambda x:x.abspath())
+		for tsk in lst:
+			try:
+				delattr(tsk,'cache_sig')
+			except AttributeError:
+				pass
+		return super(fc,self).runnable_status()
+class fcprogram(ccroot.link_task):
+	color='YELLOW'
+	run_str='${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB}'
+	inst_to='${BINDIR}'
+class fcshlib(fcprogram):
+	inst_to='${LIBDIR}'
+class fcprogram_test(fcprogram):
+	def can_retrieve_cache(self):
+		return False
+	def runnable_status(self):
+		ret=super(fcprogram_test,self).runnable_status()
+		if ret==Task.SKIP_ME:
+			ret=Task.RUN_ME
+		return ret
+	def exec_command(self,cmd,**kw):
+		bld=self.generator.bld
+		kw['shell']=isinstance(cmd,str)
+		kw['stdout']=kw['stderr']=Utils.subprocess.PIPE
+		kw['cwd']=bld.variant_dir
+		bld.out=bld.err=''
+		bld.to_log('command: %s\n'%cmd)
+		kw['output']=0
+		try:
+			(bld.out,bld.err)=bld.cmd_and_log(cmd,**kw)
+		except Exception ,e:
+			return-1
+		if bld.out:
+			bld.to_log("out: %s\n"%bld.out)
+		if bld.err:
+			bld.to_log("err: %s\n"%bld.err)
+class fcstlib(ccroot.stlink_task):
+	pass
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_config.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_config.py
new file mode 100644
index 0000000..580eac7
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_config.py
@@ -0,0 +1,285 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re,shutil,os,sys,string,shlex
+from waflib.Configure import conf
+from waflib.TaskGen import feature,after_method,before_method
+from waflib import Build,Utils
+FC_FRAGMENT='        program main\n        end     program main\n'
+FC_FRAGMENT2='        PROGRAM MAIN\n        END\n'
+@conf
+def fc_flags(conf):
+	v=conf.env
+	v['FC_SRC_F']=[]
+	v['FC_TGT_F']=['-c','-o']
+	v['FCINCPATH_ST']='-I%s'
+	v['FCDEFINES_ST']='-D%s'
+	if not v['LINK_FC']:v['LINK_FC']=v['FC']
+	v['FCLNK_SRC_F']=[]
+	v['FCLNK_TGT_F']=['-o']
+	v['FCFLAGS_fcshlib']=['-fpic']
+	v['LINKFLAGS_fcshlib']=['-shared']
+	v['fcshlib_PATTERN']='lib%s.so'
+	v['fcstlib_PATTERN']='lib%s.a'
+	v['FCLIB_ST']='-l%s'
+	v['FCLIBPATH_ST']='-L%s'
+	v['FCSTLIB_ST']='-l%s'
+	v['FCSTLIBPATH_ST']='-L%s'
+	v['FCSTLIB_MARKER']='-Wl,-Bstatic'
+	v['FCSHLIB_MARKER']='-Wl,-Bdynamic'
+	v['SONAME_ST']='-Wl,-h,%s'
+@conf
+def fc_add_flags(conf):
+	conf.add_os_flags('FCFLAGS')
+	conf.add_os_flags('LDFLAGS','LINKFLAGS')
+@conf
+def check_fortran(self,*k,**kw):
+	self.check_cc(fragment=FC_FRAGMENT,compile_filename='test.f',features='fc fcprogram',msg='Compiling a simple fortran app')
+@conf
+def check_fc(self,*k,**kw):
+	kw['compiler']='fc'
+	if not'compile_mode'in kw:
+		kw['compile_mode']='fc'
+	if not'type'in kw:
+		kw['type']='fcprogram'
+	if not'compile_filename'in kw:
+		kw['compile_filename']='test.f90'
+	if not'code'in kw:
+		kw['code']=FC_FRAGMENT
+	return self.check(*k,**kw)
+@conf
+def fortran_modifier_darwin(conf):
+	v=conf.env
+	v['FCFLAGS_fcshlib']=['-fPIC']
+	v['LINKFLAGS_fcshlib']=['-dynamiclib','-Wl,-compatibility_version,1','-Wl,-current_version,1']
+	v['fcshlib_PATTERN']='lib%s.dylib'
+	v['FRAMEWORKPATH_ST']='-F%s'
+	v['FRAMEWORK_ST']='-framework %s'
+	v['LINKFLAGS_fcstlib']=[]
+	v['FCSHLIB_MARKER']=''
+	v['FCSTLIB_MARKER']=''
+	v['SONAME_ST']=''
+@conf
+def fortran_modifier_win32(conf):
+	v=conf.env
+	v['fcprogram_PATTERN']=v['fcprogram_test_PATTERN']='%s.exe'
+	v['fcshlib_PATTERN']='%s.dll'
+	v['implib_PATTERN']='lib%s.dll.a'
+	v['IMPLIB_ST']='-Wl,--out-implib,%s'
+	v['FCFLAGS_fcshlib']=[]
+	v.append_value('FCFLAGS_fcshlib',['-DDLL_EXPORT'])
+	v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+@conf
+def fortran_modifier_cygwin(conf):
+	fortran_modifier_win32(conf)
+	v=conf.env
+	v['fcshlib_PATTERN']='cyg%s.dll'
+	v.append_value('LINKFLAGS_fcshlib',['-Wl,--enable-auto-image-base'])
+	v['FCFLAGS_fcshlib']=[]
+@conf
+def check_fortran_dummy_main(self,*k,**kw):
+	if not self.env.CC:
+		self.fatal('A c compiler is required for check_fortran_dummy_main')
+	lst=['MAIN__','__MAIN','_MAIN','MAIN_','MAIN']
+	lst.extend([m.lower()for m in lst])
+	lst.append('')
+	self.start_msg('Detecting whether we need a dummy main')
+	for main in lst:
+		kw['fortran_main']=main
+		try:
+			self.check_cc(fragment='int %s() { return 0; }\n'%(main or'test'),features='c fcprogram',mandatory=True)
+			if not main:
+				self.env.FC_MAIN=-1
+				self.end_msg('no')
+			else:
+				self.env.FC_MAIN=main
+				self.end_msg('yes %s'%main)
+			break
+		except self.errors.ConfigurationError:
+			pass
+	else:
+		self.end_msg('not found')
+		self.fatal('could not detect whether fortran requires a dummy main, see the config.log')
+GCC_DRIVER_LINE=re.compile('^Driving:')
+POSIX_STATIC_EXT=re.compile('\S+\.a')
+POSIX_LIB_FLAGS=re.compile('-l\S+')
+@conf
+def is_link_verbose(self,txt):
+	assert isinstance(txt,str)
+	for line in txt.splitlines():
+		if not GCC_DRIVER_LINE.search(line):
+			if POSIX_STATIC_EXT.search(line)or POSIX_LIB_FLAGS.search(line):
+				return True
+	return False
+@conf
+def check_fortran_verbose_flag(self,*k,**kw):
+	self.start_msg('fortran link verbose flag')
+	for x in['-v','--verbose','-verbose','-V']:
+		try:
+			self.check_cc(features='fc fcprogram_test',fragment=FC_FRAGMENT2,compile_filename='test.f',linkflags=[x],mandatory=True)
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			if self.is_link_verbose(self.test_bld.err)or self.is_link_verbose(self.test_bld.out):
+				self.end_msg(x)
+				break
+	else:
+		self.end_msg('failure')
+		self.fatal('Could not obtain the fortran link verbose flag (see config.log)')
+	self.env.FC_VERBOSE_FLAG=x
+	return x
+LINKFLAGS_IGNORED=[r'-lang*',r'-lcrt[a-zA-Z0-9\.]*\.o',r'-lc$',r'-lSystem',r'-libmil',r'-LIST:*',r'-LNO:*']
+if os.name=='nt':
+	LINKFLAGS_IGNORED.extend([r'-lfrt*',r'-luser32',r'-lkernel32',r'-ladvapi32',r'-lmsvcrt',r'-lshell32',r'-lmingw',r'-lmoldname'])
+else:
+	LINKFLAGS_IGNORED.append(r'-lgcc*')
+RLINKFLAGS_IGNORED=[re.compile(f)for f in LINKFLAGS_IGNORED]
+def _match_ignore(line):
+	for i in RLINKFLAGS_IGNORED:
+		if i.match(line):
+			return True
+	return False
+def parse_fortran_link(lines):
+	final_flags=[]
+	for line in lines:
+		if not GCC_DRIVER_LINE.match(line):
+			_parse_flink_line(line,final_flags)
+	return final_flags
+SPACE_OPTS=re.compile('^-[LRuYz]$')
+NOSPACE_OPTS=re.compile('^-[RL]')
+def _parse_flink_line(line,final_flags):
+	lexer=shlex.shlex(line,posix=True)
+	lexer.whitespace_split=True
+	t=lexer.get_token()
+	tmp_flags=[]
+	while t:
+		def parse(token):
+			if _match_ignore(token):
+				pass
+			elif token.startswith('-lkernel32')and sys.platform=='cygwin':
+				tmp_flags.append(token)
+			elif SPACE_OPTS.match(token):
+				t=lexer.get_token()
+				if t.startswith('P,'):
+					t=t[2:]
+				for opt in t.split(os.pathsep):
+					tmp_flags.append('-L%s'%opt)
+			elif NOSPACE_OPTS.match(token):
+				tmp_flags.append(token)
+			elif POSIX_LIB_FLAGS.match(token):
+				tmp_flags.append(token)
+			else:
+				pass
+			t=lexer.get_token()
+			return t
+		t=parse(t)
+	final_flags.extend(tmp_flags)
+	return final_flags
+@conf
+def check_fortran_clib(self,autoadd=True,*k,**kw):
+	if not self.env.FC_VERBOSE_FLAG:
+		self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?')
+	self.start_msg('Getting fortran runtime link flags')
+	try:
+		self.check_cc(fragment=FC_FRAGMENT2,compile_filename='test.f',features='fc fcprogram_test',linkflags=[self.env.FC_VERBOSE_FLAG])
+	except Exception:
+		self.end_msg(False)
+		if kw.get('mandatory',True):
+			conf.fatal('Could not find the c library flags')
+	else:
+		out=self.test_bld.err
+		flags=parse_fortran_link(out.splitlines())
+		self.end_msg('ok (%s)'%' '.join(flags))
+		self.env.LINKFLAGS_CLIB=flags
+		return flags
+	return[]
+def getoutput(conf,cmd,stdin=False):
+	if stdin:
+		stdin=Utils.subprocess.PIPE
+	else:
+		stdin=None
+	env=conf.env.env or None
+	try:
+		p=Utils.subprocess.Popen(cmd,stdin=stdin,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
+		if stdin:
+			p.stdin.write('\n')
+		out,err=p.communicate()
+	except Exception:
+		conf.fatal('could not determine the compiler version %r'%cmd)
+	if not isinstance(out,str):
+		out=out.decode(sys.stdout.encoding or'iso8859-1')
+	if not isinstance(err,str):
+		err=err.decode(sys.stdout.encoding or'iso8859-1')
+	return(out,err)
+ROUTINES_CODE="""\
+      subroutine foobar()
+      return
+      end
+      subroutine foo_bar()
+      return
+      end
+"""
+MAIN_CODE="""
+void %(dummy_func_nounder)s(void);
+void %(dummy_func_under)s(void);
+int %(main_func_name)s() {
+  %(dummy_func_nounder)s();
+  %(dummy_func_under)s();
+  return 0;
+}
+"""
+@feature('link_main_routines_func')
+@before_method('process_source')
+def link_main_routines_tg_method(self):
+	def write_test_file(task):
+		task.outputs[0].write(task.generator.code)
+	bld=self.bld
+	bld(rule=write_test_file,target='main.c',code=MAIN_CODE%self.__dict__)
+	bld(rule=write_test_file,target='test.f',code=ROUTINES_CODE)
+	bld(features='fc fcstlib',source='test.f',target='test')
+	bld(features='c fcprogram',source='main.c',target='app',use='test')
+def mangling_schemes():
+	for u in['_','']:
+		for du in['','_']:
+			for c in["lower","upper"]:
+				yield(u,du,c)
+def mangle_name(u,du,c,name):
+	return getattr(name,c)()+u+(name.find('_')!=-1 and du or'')
+@conf
+def check_fortran_mangling(self,*k,**kw):
+	if not self.env.CC:
+		self.fatal('A c compiler is required for link_main_routines')
+	if not self.env.FC:
+		self.fatal('A fortran compiler is required for link_main_routines')
+	if not self.env.FC_MAIN:
+		self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)')
+	self.start_msg('Getting fortran mangling scheme')
+	for(u,du,c)in mangling_schemes():
+		try:
+			self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',mandatory=True,dummy_func_nounder=mangle_name(u,du,c,"foobar"),dummy_func_under=mangle_name(u,du,c,"foo_bar"),main_func_name=self.env.FC_MAIN)
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			self.end_msg("ok ('%s', '%s', '%s-case')"%(u,du,c))
+			self.env.FORTRAN_MANGLING=(u,du,c)
+			break
+	else:
+		self.end_msg(False)
+		self.fatal('mangler not found')
+	return(u,du,c)
+@feature('pyext')
+@before_method('propagate_uselib_vars','apply_link')
+def set_lib_pat(self):
+	self.env['fcshlib_PATTERN']=self.env['pyext_PATTERN']
+@conf
+def detect_openmp(self):
+	for x in['-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp']:
+		try:
+			self.check_fc(msg='Checking for OpenMP flag %s'%x,fragment='program main\n  call omp_get_num_threads()\nend program main',fcflags=x,linkflags=x,uselib_store='OPENMP')
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			break
+	else:
+		self.fatal('Could not find OpenMP')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_scan.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_scan.py
new file mode 100644
index 0000000..48e06b5
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_scan.py
@@ -0,0 +1,68 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Task,TaskGen,Logs
+from waflib.TaskGen import feature,before_method,after_method,extension
+from waflib.Configure import conf
+INC_REGEX="""(?:^|['">]\s*;)\s*INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
+USE_REGEX="""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
+MOD_REGEX="""(?:^|;)\s*MODULE(?!\s*PROCEDURE)(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
+re_inc=re.compile(INC_REGEX,re.I)
+re_use=re.compile(USE_REGEX,re.I)
+re_mod=re.compile(MOD_REGEX,re.I)
+class fortran_parser(object):
+	def __init__(self,incpaths):
+		self.seen=[]
+		self.nodes=[]
+		self.names=[]
+		self.incpaths=incpaths
+	def find_deps(self,node):
+		txt=node.read()
+		incs=[]
+		uses=[]
+		mods=[]
+		for line in txt.splitlines():
+			m=re_inc.search(line)
+			if m:
+				incs.append(m.group(1))
+			m=re_use.search(line)
+			if m:
+				uses.append(m.group(1))
+			m=re_mod.search(line)
+			if m:
+				mods.append(m.group(1))
+		return(incs,uses,mods)
+	def start(self,node):
+		self.waiting=[node]
+		while self.waiting:
+			nd=self.waiting.pop(0)
+			self.iter(nd)
+	def iter(self,node):
+		path=node.abspath()
+		incs,uses,mods=self.find_deps(node)
+		for x in incs:
+			if x in self.seen:
+				continue
+			self.seen.append(x)
+			self.tryfind_header(x)
+		for x in uses:
+			name="USE@%s"%x
+			if not name in self.names:
+				self.names.append(name)
+		for x in mods:
+			name="MOD@%s"%x
+			if not name in self.names:
+				self.names.append(name)
+	def tryfind_header(self,filename):
+		found=None
+		for n in self.incpaths:
+			found=n.find_resource(filename)
+			if found:
+				self.nodes.append(found)
+				self.waiting.append(found)
+				break
+		if not found:
+			if not filename in self.names:
+				self.names.append(filename)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/flex.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/flex.py
new file mode 100644
index 0000000..13f6207
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/flex.py
@@ -0,0 +1,32 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import waflib.TaskGen,os,re
+def decide_ext(self,node):
+	if'cxx'in self.features:
+		return['.lex.cc']
+	return['.lex.c']
+def flexfun(tsk):
+	env=tsk.env
+	bld=tsk.generator.bld
+	wd=bld.variant_dir
+	def to_list(xx):
+		if isinstance(xx,str):return[xx]
+		return xx
+	tsk.last_cmd=lst=[]
+	lst.extend(to_list(env['FLEX']))
+	lst.extend(to_list(env['FLEXFLAGS']))
+	inputs=[a.path_from(bld.bldnode)for a in tsk.inputs]
+	if env.FLEX_MSYS:
+		inputs=[x.replace(os.sep,'/')for x in inputs]
+	lst.extend(inputs)
+	lst=[x for x in lst if x]
+	txt=bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
+	tsk.outputs[0].write(txt.replace('\r\n','\n').replace('\r','\n'))
+waflib.TaskGen.declare_chain(name='flex',rule=flexfun,ext_in='.l',decider=decide_ext,)
+def configure(conf):
+	conf.find_program('flex',var='FLEX')
+	conf.env.FLEXFLAGS=['-t']
+	if re.search(r"\\msys\\[0-9.]+\\bin\\flex.exe$",conf.env.FLEX):
+		conf.env.FLEX_MSYS=True
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/g95.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/g95.py
new file mode 100644
index 0000000..9bc331a
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/g95.py
@@ -0,0 +1,55 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan,ar
+from waflib.Configure import conf
+@conf
+def find_g95(conf):
+	fc=conf.find_program('g95',var='FC')
+	fc=conf.cmd_to_list(fc)
+	conf.get_g95_version(fc)
+	conf.env.FC_NAME='G95'
+@conf
+def g95_flags(conf):
+	v=conf.env
+	v['FCFLAGS_fcshlib']=['-fPIC']
+	v['FORTRANMODFLAG']=['-fmod=','']
+	v['FCFLAGS_DEBUG']=['-Werror']
+@conf
+def g95_modifier_win32(conf):
+	fc_config.fortran_modifier_win32(conf)
+@conf
+def g95_modifier_cygwin(conf):
+	fc_config.fortran_modifier_cygwin(conf)
+@conf
+def g95_modifier_darwin(conf):
+	fc_config.fortran_modifier_darwin(conf)
+@conf
+def g95_modifier_platform(conf):
+	dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+	g95_modifier_func=getattr(conf,'g95_modifier_'+dest_os,None)
+	if g95_modifier_func:
+		g95_modifier_func()
+@conf
+def get_g95_version(conf,fc):
+	version_re=re.compile(r"g95\s*(?P<major>\d*)\.(?P<minor>\d*)").search
+	cmd=fc+['--version']
+	out,err=fc_config.getoutput(conf,cmd,stdin=False)
+	if out:
+		match=version_re(out)
+	else:
+		match=version_re(err)
+	if not match:
+		conf.fatal('cannot determine g95 version')
+	k=match.groupdict()
+	conf.env['FC_VERSION']=(k['major'],k['minor'])
+def configure(conf):
+	conf.find_g95()
+	conf.find_ar()
+	conf.fc_flags()
+	conf.fc_add_flags()
+	conf.g95_flags()
+	conf.g95_modifier_platform()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gas.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gas.py
new file mode 100644
index 0000000..b714ca1
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gas.py
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import waflib.Tools.asm
+from waflib.Tools import ar
+def configure(conf):
+	conf.find_program(['gas','gcc'],var='AS')
+	conf.env.AS_TGT_F=['-c','-o']
+	conf.env.ASLNK_TGT_F=['-o']
+	conf.find_ar()
+	conf.load('asm')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.py
new file mode 100644
index 0000000..da68d94
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.py
@@ -0,0 +1,97 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Configure,Options,Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_gcc(conf):
+	cc=conf.find_program(['gcc','cc'],var='CC')
+	cc=conf.cmd_to_list(cc)
+	conf.get_cc_version(cc,gcc=True)
+	conf.env.CC_NAME='gcc'
+	conf.env.CC=cc
+@conf
+def gcc_common_flags(conf):
+	v=conf.env
+	v['CC_SRC_F']=[]
+	v['CC_TGT_F']=['-c','-o']
+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
+	v['CCLNK_SRC_F']=[]
+	v['CCLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['RPATH_ST']='-Wl,-rpath,%s'
+	v['SONAME_ST']='-Wl,-h,%s'
+	v['SHLIB_MARKER']='-Wl,-Bdynamic'
+	v['STLIB_MARKER']='-Wl,-Bstatic'
+	v['cprogram_PATTERN']='%s'
+	v['CFLAGS_cshlib']=['-fPIC']
+	v['LINKFLAGS_cshlib']=['-shared']
+	v['cshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cstlib']=['-Wl,-Bstatic']
+	v['cstlib_PATTERN']='lib%s.a'
+	v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup']
+	v['CFLAGS_MACBUNDLE']=['-fPIC']
+	v['macbundle_PATTERN']='%s.bundle'
+@conf
+def gcc_modifier_win32(conf):
+	v=conf.env
+	v['cprogram_PATTERN']='%s.exe'
+	v['cshlib_PATTERN']='%s.dll'
+	v['implib_PATTERN']='lib%s.dll.a'
+	v['IMPLIB_ST']='-Wl,--out-implib,%s'
+	v['CFLAGS_cshlib']=[]
+	v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+@conf
+def gcc_modifier_cygwin(conf):
+	gcc_modifier_win32(conf)
+	v=conf.env
+	v['cshlib_PATTERN']='cyg%s.dll'
+	v.append_value('LINKFLAGS_cshlib',['-Wl,--enable-auto-image-base'])
+	v['CFLAGS_cshlib']=[]
+@conf
+def gcc_modifier_darwin(conf):
+	v=conf.env
+	v['CFLAGS_cshlib']=['-fPIC']
+	v['LINKFLAGS_cshlib']=['-dynamiclib','-Wl,-compatibility_version,1','-Wl,-current_version,1']
+	v['cshlib_PATTERN']='lib%s.dylib'
+	v['FRAMEWORKPATH_ST']='-F%s'
+	v['FRAMEWORK_ST']=['-framework']
+	v['ARCH_ST']=['-arch']
+	v['LINKFLAGS_cstlib']=[]
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']=[]
+	v['SONAME_ST']=[]
+@conf
+def gcc_modifier_aix(conf):
+	v=conf.env
+	v['LINKFLAGS_cprogram']=['-Wl,-brtl']
+	v['LINKFLAGS_cshlib']=['-shared','-Wl,-brtl,-bexpfull']
+	v['SHLIB_MARKER']=[]
+@conf
+def gcc_modifier_hpux(conf):
+	v=conf.env
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']='-Bstatic'
+	v['CFLAGS_cshlib']=['-fPIC','-DPIC']
+	v['cshlib_PATTERN']='lib%s.sl'
+@conf
+def gcc_modifier_platform(conf):
+	gcc_modifier_func=getattr(conf,'gcc_modifier_'+conf.env.DEST_OS,None)
+	if gcc_modifier_func:
+		gcc_modifier_func()
+def configure(conf):
+	conf.find_gcc()
+	conf.find_ar()
+	conf.gcc_common_flags()
+	conf.gcc_modifier_platform()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.pyc
new file mode 100644
index 0000000..2d7303f
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gdc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gdc.py
new file mode 100644
index 0000000..da966ec
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gdc.py
@@ -0,0 +1,36 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+@conf
+def find_gdc(conf):
+	conf.find_program('gdc',var='D')
+	out=conf.cmd_and_log([conf.env.D,'--version'])
+	if out.find("gdc ")==-1:
+		conf.fatal("detected compiler is not gdc")
+@conf
+def common_flags_gdc(conf):
+	v=conf.env
+	v['DFLAGS']=[]
+	v['D_SRC_F']=['-c']
+	v['D_TGT_F']='-o%s'
+	v['D_LINKER']=v['D']
+	v['DLNK_SRC_F']=''
+	v['DLNK_TGT_F']='-o%s'
+	v['DINC_ST']='-I%s'
+	v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+	v['DSTLIB_ST']=v['DSHLIB_ST']='-l%s'
+	v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L%s'
+	v['LINKFLAGS_dshlib']=['-shared']
+	v['DHEADER_ext']='.di'
+	v.DFLAGS_d_with_header='-fintfc'
+	v['D_HDR_F']='-fintfc-file=%s'
+def configure(conf):
+	conf.find_gdc()
+	conf.load('ar')
+	conf.load('d')
+	conf.common_flags_gdc()
+	conf.d_platform_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gfortran.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gfortran.py
new file mode 100644
index 0000000..854a93d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gfortran.py
@@ -0,0 +1,69 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan,ar
+from waflib.Configure import conf
+@conf
+def find_gfortran(conf):
+	fc=conf.find_program(['gfortran','g77'],var='FC')
+	fc=conf.cmd_to_list(fc)
+	conf.get_gfortran_version(fc)
+	conf.env.FC_NAME='GFORTRAN'
+@conf
+def gfortran_flags(conf):
+	v=conf.env
+	v['FCFLAGS_fcshlib']=['-fPIC']
+	v['FORTRANMODFLAG']=['-J','']
+	v['FCFLAGS_DEBUG']=['-Werror']
+@conf
+def gfortran_modifier_win32(conf):
+	fc_config.fortran_modifier_win32(conf)
+@conf
+def gfortran_modifier_cygwin(conf):
+	fc_config.fortran_modifier_cygwin(conf)
+@conf
+def gfortran_modifier_darwin(conf):
+	fc_config.fortran_modifier_darwin(conf)
+@conf
+def gfortran_modifier_platform(conf):
+	dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+	gfortran_modifier_func=getattr(conf,'gfortran_modifier_'+dest_os,None)
+	if gfortran_modifier_func:
+		gfortran_modifier_func()
+@conf
+def get_gfortran_version(conf,fc):
+	version_re=re.compile(r"GNU\s*Fortran",re.I).search
+	cmd=fc+['--version']
+	out,err=fc_config.getoutput(conf,cmd,stdin=False)
+	if out:match=version_re(out)
+	else:match=version_re(err)
+	if not match:
+		conf.fatal('Could not determine the compiler type')
+	cmd=fc+['-dM','-E','-']
+	out,err=fc_config.getoutput(conf,cmd,stdin=True)
+	if out.find('__GNUC__')<0:
+		conf.fatal('Could not determine the compiler type')
+	k={}
+	out=out.split('\n')
+	import shlex
+	for line in out:
+		lst=shlex.split(line)
+		if len(lst)>2:
+			key=lst[1]
+			val=lst[2]
+			k[key]=val
+	def isD(var):
+		return var in k
+	def isT(var):
+		return var in k and k[var]!='0'
+	conf.env['FC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
+def configure(conf):
+	conf.find_gfortran()
+	conf.find_ar()
+	conf.fc_flags()
+	conf.fc_add_flags()
+	conf.gfortran_flags()
+	conf.gfortran_modifier_platform()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/glib2.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/glib2.py
new file mode 100644
index 0000000..1d75510
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/glib2.py
@@ -0,0 +1,173 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Task,Utils,Options,Errors,Logs
+from waflib.TaskGen import taskgen_method,before_method,after_method,feature
+@taskgen_method
+def add_marshal_file(self,filename,prefix):
+	if not hasattr(self,'marshal_list'):
+		self.marshal_list=[]
+	self.meths.append('process_marshal')
+	self.marshal_list.append((filename,prefix))
+@before_method('process_source')
+def process_marshal(self):
+	for f,prefix in getattr(self,'marshal_list',[]):
+		node=self.path.find_resource(f)
+		if not node:
+			raise Errors.WafError('file not found %r'%f)
+		h_node=node.change_ext('.h')
+		c_node=node.change_ext('.c')
+		task=self.create_task('glib_genmarshal',node,[h_node,c_node])
+		task.env.GLIB_GENMARSHAL_PREFIX=prefix
+	self.source=self.to_nodes(getattr(self,'source',[]))
+	self.source.append(c_node)
+class glib_genmarshal(Task.Task):
+	def run(self):
+		bld=self.inputs[0].__class__.ctx
+		get=self.env.get_flat
+		cmd1="%s %s --prefix=%s --header > %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[0].abspath())
+		ret=bld.exec_command(cmd1)
+		if ret:return ret
+		c='''#include "%s"\n'''%self.outputs[0].name
+		self.outputs[1].write(c)
+		cmd2="%s %s --prefix=%s --body >> %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[1].abspath())
+		return bld.exec_command(cmd2)
+	vars=['GLIB_GENMARSHAL_PREFIX','GLIB_GENMARSHAL']
+	color='BLUE'
+	ext_out=['.h']
+@taskgen_method
+def add_enums_from_template(self,source='',target='',template='',comments=''):
+	if not hasattr(self,'enums_list'):
+		self.enums_list=[]
+	self.meths.append('process_enums')
+	self.enums_list.append({'source':source,'target':target,'template':template,'file-head':'','file-prod':'','file-tail':'','enum-prod':'','value-head':'','value-prod':'','value-tail':'','comments':comments})
+@taskgen_method
+def add_enums(self,source='',target='',file_head='',file_prod='',file_tail='',enum_prod='',value_head='',value_prod='',value_tail='',comments=''):
+	if not hasattr(self,'enums_list'):
+		self.enums_list=[]
+	self.meths.append('process_enums')
+	self.enums_list.append({'source':source,'template':'','target':target,'file-head':file_head,'file-prod':file_prod,'file-tail':file_tail,'enum-prod':enum_prod,'value-head':value_head,'value-prod':value_prod,'value-tail':value_tail,'comments':comments})
+@before_method('process_source')
+def process_enums(self):
+	for enum in getattr(self,'enums_list',[]):
+		task=self.create_task('glib_mkenums')
+		env=task.env
+		inputs=[]
+		source_list=self.to_list(enum['source'])
+		if not source_list:
+			raise Errors.WafError('missing source '+str(enum))
+		source_list=[self.path.find_resource(k)for k in source_list]
+		inputs+=source_list
+		env['GLIB_MKENUMS_SOURCE']=[k.abspath()for k in source_list]
+		if not enum['target']:
+			raise Errors.WafError('missing target '+str(enum))
+		tgt_node=self.path.find_or_declare(enum['target'])
+		if tgt_node.name.endswith('.c'):
+			self.source.append(tgt_node)
+		env['GLIB_MKENUMS_TARGET']=tgt_node.abspath()
+		options=[]
+		if enum['template']:
+			template_node=self.path.find_resource(enum['template'])
+			options.append('--template %s'%(template_node.abspath()))
+			inputs.append(template_node)
+		params={'file-head':'--fhead','file-prod':'--fprod','file-tail':'--ftail','enum-prod':'--eprod','value-head':'--vhead','value-prod':'--vprod','value-tail':'--vtail','comments':'--comments'}
+		for param,option in params.items():
+			if enum[param]:
+				options.append('%s %r'%(option,enum[param]))
+		env['GLIB_MKENUMS_OPTIONS']=' '.join(options)
+		task.set_inputs(inputs)
+		task.set_outputs(tgt_node)
+class glib_mkenums(Task.Task):
+	run_str='${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}'
+	color='PINK'
+	ext_out=['.h']
+@taskgen_method
+def add_settings_schemas(self,filename_list):
+	if not hasattr(self,'settings_schema_files'):
+		self.settings_schema_files=[]
+	if not isinstance(filename_list,list):
+		filename_list=[filename_list]
+	self.settings_schema_files.extend(filename_list)
+@taskgen_method
+def add_settings_enums(self,namespace,filename_list):
+	if hasattr(self,'settings_enum_namespace'):
+		raise Errors.WafError("Tried to add gsettings enums to '%s' more than once"%self.name)
+	self.settings_enum_namespace=namespace
+	if type(filename_list)!='list':
+		filename_list=[filename_list]
+	self.settings_enum_files=filename_list
+def r_change_ext(self,ext):
+	name=self.name
+	k=name.rfind('.')
+	if k>=0:
+		name=name[:k]+ext
+	else:
+		name=name+ext
+	return self.parent.find_or_declare([name])
+@feature('glib2')
+def process_settings(self):
+	enums_tgt_node=[]
+	install_files=[]
+	settings_schema_files=getattr(self,'settings_schema_files',[])
+	if settings_schema_files and not self.env['GLIB_COMPILE_SCHEMAS']:
+		raise Errors.WafError("Unable to process GSettings schemas - glib-compile-schemas was not found during configure")
+	if hasattr(self,'settings_enum_files'):
+		enums_task=self.create_task('glib_mkenums')
+		source_list=self.settings_enum_files
+		source_list=[self.path.find_resource(k)for k in source_list]
+		enums_task.set_inputs(source_list)
+		enums_task.env['GLIB_MKENUMS_SOURCE']=[k.abspath()for k in source_list]
+		target=self.settings_enum_namespace+'.enums.xml'
+		tgt_node=self.path.find_or_declare(target)
+		enums_task.set_outputs(tgt_node)
+		enums_task.env['GLIB_MKENUMS_TARGET']=tgt_node.abspath()
+		enums_tgt_node=[tgt_node]
+		install_files.append(tgt_node)
+		options='--comments "<!-- @comment@ -->" --fhead "<schemalist>" --vhead "  <@type@ id=\\"%s.@EnumName@\\">" --vprod "    <value nick=\\"@valuenick@\\" value=\\"@valuenum@\\"/>" --vtail "  </@type@>" --ftail "</schemalist>" '%(self.settings_enum_namespace)
+		enums_task.env['GLIB_MKENUMS_OPTIONS']=options
+	for schema in settings_schema_files:
+		schema_task=self.create_task('glib_validate_schema')
+		schema_node=self.path.find_resource(schema)
+		if not schema_node:
+			raise Errors.WafError("Cannot find the schema file '%s'"%schema)
+		install_files.append(schema_node)
+		source_list=enums_tgt_node+[schema_node]
+		schema_task.set_inputs(source_list)
+		schema_task.env['GLIB_COMPILE_SCHEMAS_OPTIONS']=[("--schema-file="+k.abspath())for k in source_list]
+		target_node=r_change_ext(schema_node,'.xml.valid')
+		schema_task.set_outputs(target_node)
+		schema_task.env['GLIB_VALIDATE_SCHEMA_OUTPUT']=target_node.abspath()
+	def compile_schemas_callback(bld):
+		if not bld.is_install:return
+		Logs.pprint('YELLOW','Updating GSettings schema cache')
+		command=Utils.subst_vars("${GLIB_COMPILE_SCHEMAS} ${GSETTINGSSCHEMADIR}",bld.env)
+		ret=self.bld.exec_command(command)
+	if self.bld.is_install:
+		if not self.env['GSETTINGSSCHEMADIR']:
+			raise Errors.WafError('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)')
+		if install_files:
+			self.bld.install_files(self.env['GSETTINGSSCHEMADIR'],install_files)
+			if not hasattr(self.bld,'_compile_schemas_registered'):
+				self.bld.add_post_fun(compile_schemas_callback)
+				self.bld._compile_schemas_registered=True
+class glib_validate_schema(Task.Task):
+	run_str='rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}'
+	color='PINK'
+def configure(conf):
+	conf.find_program('glib-genmarshal',var='GLIB_GENMARSHAL')
+	conf.find_perl_program('glib-mkenums',var='GLIB_MKENUMS')
+	conf.find_program('glib-compile-schemas',var='GLIB_COMPILE_SCHEMAS',mandatory=False)
+	def getstr(varname):
+		return getattr(Options.options,varname,getattr(conf.env,varname,''))
+	gsettingsschemadir=getstr('GSETTINGSSCHEMADIR')
+	if not gsettingsschemadir:
+		datadir=getstr('DATADIR')
+		if not datadir:
+			prefix=conf.env['PREFIX']
+			datadir=os.path.join(prefix,'share')
+		gsettingsschemadir=os.path.join(datadir,'glib-2.0','schemas')
+	conf.env['GSETTINGSSCHEMADIR']=gsettingsschemadir
+def options(opt):
+	opt.add_option('--gsettingsschemadir',help='GSettings schema location [Default: ${datadir}/glib-2.0/schemas]',default='',dest='GSETTINGSSCHEMADIR')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.py
new file mode 100644
index 0000000..9c8a304
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.py
@@ -0,0 +1,65 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils,Options,Context
+_options=[x.split(', ')for x in'''
+bindir, user executables, ${EXEC_PREFIX}/bin
+sbindir, system admin executables, ${EXEC_PREFIX}/sbin
+libexecdir, program executables, ${EXEC_PREFIX}/libexec
+sysconfdir, read-only single-machine data, ${PREFIX}/etc
+sharedstatedir, modifiable architecture-independent data, ${PREFIX}/com
+localstatedir, modifiable single-machine data, ${PREFIX}/var
+libdir, object code libraries, ${EXEC_PREFIX}/lib
+includedir, C header files, ${PREFIX}/include
+oldincludedir, C header files for non-gcc, /usr/include
+datarootdir, read-only arch.-independent data root, ${PREFIX}/share
+datadir, read-only architecture-independent data, ${DATAROOTDIR}
+infodir, info documentation, ${DATAROOTDIR}/info
+localedir, locale-dependent data, ${DATAROOTDIR}/locale
+mandir, man documentation, ${DATAROOTDIR}/man
+docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE}
+htmldir, html documentation, ${DOCDIR}
+dvidir, dvi documentation, ${DOCDIR}
+pdfdir, pdf documentation, ${DOCDIR}
+psdir, ps documentation, ${DOCDIR}
+'''.split('\n')if x]
+def configure(conf):
+	def get_param(varname,default):
+		return getattr(Options.options,varname,'')or default
+	env=conf.env
+	env.LIBDIR=env.BINDIR=[]
+	env.EXEC_PREFIX=get_param('EXEC_PREFIX',env.PREFIX)
+	env.PACKAGE=getattr(Context.g_module,'APPNAME',None)or env.PACKAGE
+	complete=False
+	iter=0
+	while not complete and iter<len(_options)+1:
+		iter+=1
+		complete=True
+		for name,help,default in _options:
+			name=name.upper()
+			if not env[name]:
+				try:
+					env[name]=Utils.subst_vars(get_param(name,default).replace('/',os.sep),env)
+				except TypeError:
+					complete=False
+	if not complete:
+		lst=[name for name,_,_ in _options if not env[name.upper()]]
+		raise conf.errors.WafError('Variable substitution failure %r'%lst)
+def options(opt):
+	inst_dir=opt.add_option_group('Installation directories','By default, "waf install" will put the files in\
+ "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\
+ than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"')
+	for k in('--prefix','--destdir'):
+		option=opt.parser.get_option(k)
+		if option:
+			opt.parser.remove_option(k)
+			inst_dir.add_option(option)
+	inst_dir.add_option('--exec-prefix',help='installation prefix [Default: ${PREFIX}]',default='',dest='EXEC_PREFIX')
+	dirs_options=opt.add_option_group('Pre-defined installation directories','')
+	for name,help,default in _options:
+		option_name='--'+name
+		str_default=default
+		str_help='%s [Default: %s]'%(help,str_default)
+		dirs_options.add_option(option_name,help=str_help,default='',dest=name.upper())
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.pyc
new file mode 100644
index 0000000..09c626d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.py
new file mode 100644
index 0000000..553e5ba
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.py
@@ -0,0 +1,97 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Configure,Options,Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_gxx(conf):
+	cxx=conf.find_program(['g++','c++'],var='CXX')
+	cxx=conf.cmd_to_list(cxx)
+	conf.get_cc_version(cxx,gcc=True)
+	conf.env.CXX_NAME='gcc'
+	conf.env.CXX=cxx
+@conf
+def gxx_common_flags(conf):
+	v=conf.env
+	v['CXX_SRC_F']=[]
+	v['CXX_TGT_F']=['-c','-o']
+	if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+	v['CXXLNK_SRC_F']=[]
+	v['CXXLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['RPATH_ST']='-Wl,-rpath,%s'
+	v['SONAME_ST']='-Wl,-h,%s'
+	v['SHLIB_MARKER']='-Wl,-Bdynamic'
+	v['STLIB_MARKER']='-Wl,-Bstatic'
+	v['cxxprogram_PATTERN']='%s'
+	v['CXXFLAGS_cxxshlib']=['-fPIC']
+	v['LINKFLAGS_cxxshlib']=['-shared']
+	v['cxxshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cxxstlib']=['-Wl,-Bstatic']
+	v['cxxstlib_PATTERN']='lib%s.a'
+	v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup']
+	v['CXXFLAGS_MACBUNDLE']=['-fPIC']
+	v['macbundle_PATTERN']='%s.bundle'
+@conf
+def gxx_modifier_win32(conf):
+	v=conf.env
+	v['cxxprogram_PATTERN']='%s.exe'
+	v['cxxshlib_PATTERN']='%s.dll'
+	v['implib_PATTERN']='lib%s.dll.a'
+	v['IMPLIB_ST']='-Wl,--out-implib,%s'
+	v['CXXFLAGS_cxxshlib']=[]
+	v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+@conf
+def gxx_modifier_cygwin(conf):
+	gxx_modifier_win32(conf)
+	v=conf.env
+	v['cxxshlib_PATTERN']='cyg%s.dll'
+	v.append_value('LINKFLAGS_cxxshlib',['-Wl,--enable-auto-image-base'])
+	v['CXXFLAGS_cxxshlib']=[]
+@conf
+def gxx_modifier_darwin(conf):
+	v=conf.env
+	v['CXXFLAGS_cxxshlib']=['-fPIC']
+	v['LINKFLAGS_cxxshlib']=['-dynamiclib','-Wl,-compatibility_version,1','-Wl,-current_version,1']
+	v['cxxshlib_PATTERN']='lib%s.dylib'
+	v['FRAMEWORKPATH_ST']='-F%s'
+	v['FRAMEWORK_ST']=['-framework']
+	v['ARCH_ST']=['-arch']
+	v['LINKFLAGS_cxxstlib']=[]
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']=[]
+	v['SONAME_ST']=[]
+@conf
+def gxx_modifier_aix(conf):
+	v=conf.env
+	v['LINKFLAGS_cxxprogram']=['-Wl,-brtl']
+	v['LINKFLAGS_cxxshlib']=['-shared','-Wl,-brtl,-bexpfull']
+	v['SHLIB_MARKER']=[]
+@conf
+def gxx_modifier_hpux(conf):
+	v=conf.env
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']='-Bstatic'
+	v['CFLAGS_cxxshlib']=['-fPIC','-DPIC']
+	v['cxxshlib_PATTERN']='lib%s.sl'
+@conf
+def gxx_modifier_platform(conf):
+	gxx_modifier_func=getattr(conf,'gxx_modifier_'+conf.env.DEST_OS,None)
+	if gxx_modifier_func:
+		gxx_modifier_func()
+def configure(conf):
+	conf.find_gxx()
+	conf.find_ar()
+	conf.gxx_common_flags()
+	conf.gxx_modifier_platform()
+	conf.cxx_load_tools()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.pyc
new file mode 100644
index 0000000..dd856a5
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icc.py
new file mode 100644
index 0000000..7c75e18
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icc.py
@@ -0,0 +1,30 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.Tools import ccroot,ar,gcc
+from waflib.Configure import conf
+@conf
+def find_icc(conf):
+	if sys.platform=='cygwin':
+		conf.fatal('The Intel compiler does not work on Cygwin')
+	v=conf.env
+	cc=None
+	if v['CC']:cc=v['CC']
+	elif'CC'in conf.environ:cc=conf.environ['CC']
+	if not cc:cc=conf.find_program('icc',var='CC')
+	if not cc:cc=conf.find_program('ICL',var='CC')
+	if not cc:conf.fatal('Intel C Compiler (icc) was not found')
+	cc=conf.cmd_to_list(cc)
+	conf.get_cc_version(cc,icc=True)
+	v['CC']=cc
+	v['CC_NAME']='icc'
+def configure(conf):
+	conf.find_icc()
+	conf.find_ar()
+	conf.gcc_common_flags()
+	conf.gcc_modifier_platform()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icpc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icpc.py
new file mode 100644
index 0000000..14a5325
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icpc.py
@@ -0,0 +1,29 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.Tools import ccroot,ar,gxx
+from waflib.Configure import conf
+@conf
+def find_icpc(conf):
+	if sys.platform=='cygwin':
+		conf.fatal('The Intel compiler does not work on Cygwin')
+	v=conf.env
+	cxx=None
+	if v['CXX']:cxx=v['CXX']
+	elif'CXX'in conf.environ:cxx=conf.environ['CXX']
+	if not cxx:cxx=conf.find_program('icpc',var='CXX')
+	if not cxx:conf.fatal('Intel C++ Compiler (icpc) was not found')
+	cxx=conf.cmd_to_list(cxx)
+	conf.get_cc_version(cxx,icc=True)
+	v['CXX']=cxx
+	v['CXX_NAME']='icc'
+def configure(conf):
+	conf.find_icpc()
+	conf.find_ar()
+	conf.gxx_common_flags()
+	conf.gxx_modifier_platform()
+	conf.cxx_load_tools()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ifort.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ifort.py
new file mode 100644
index 0000000..a9f2528
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ifort.py
@@ -0,0 +1,49 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan,ar
+from waflib.Configure import conf
+@conf
+def find_ifort(conf):
+	fc=conf.find_program('ifort',var='FC')
+	fc=conf.cmd_to_list(fc)
+	conf.get_ifort_version(fc)
+	conf.env.FC_NAME='IFORT'
+@conf
+def ifort_modifier_cygwin(conf):
+	raise NotImplementedError("Ifort on cygwin not yet implemented")
+@conf
+def ifort_modifier_win32(conf):
+	fc_config.fortran_modifier_win32(conf)
+@conf
+def ifort_modifier_darwin(conf):
+	fc_config.fortran_modifier_darwin(conf)
+@conf
+def ifort_modifier_platform(conf):
+	dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+	ifort_modifier_func=getattr(conf,'ifort_modifier_'+dest_os,None)
+	if ifort_modifier_func:
+		ifort_modifier_func()
+@conf
+def get_ifort_version(conf,fc):
+	version_re=re.compile(r"ifort\s*\(IFORT\)\s*(?P<major>\d*)\.(?P<minor>\d*)",re.I).search
+	cmd=fc+['--version']
+	out,err=fc_config.getoutput(conf,cmd,stdin=False)
+	if out:
+		match=version_re(out)
+	else:
+		match=version_re(err)
+	if not match:
+		conf.fatal('cannot determine ifort version.')
+	k=match.groupdict()
+	conf.env['FC_VERSION']=(k['major'],k['minor'])
+def configure(conf):
+	conf.find_ifort()
+	conf.find_program('xiar',var='AR')
+	conf.env.ARFLAGS='rcs'
+	conf.fc_flags()
+	conf.fc_add_flags()
+	conf.ifort_modifier_platform()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/intltool.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/intltool.py
new file mode 100644
index 0000000..d558674
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/intltool.py
@@ -0,0 +1,77 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Configure,TaskGen,Task,Utils,Runner,Options,Build,Logs
+import waflib.Tools.ccroot
+from waflib.TaskGen import feature,before_method
+from waflib.Logs import error
+@before_method('process_source')
+@feature('intltool_in')
+def apply_intltool_in_f(self):
+	try:self.meths.remove('process_source')
+	except ValueError:pass
+	if not self.env.LOCALEDIR:
+		self.env.LOCALEDIR=self.env.PREFIX+'/share/locale'
+	for i in self.to_list(self.source):
+		node=self.path.find_resource(i)
+		podir=getattr(self,'podir','po')
+		podirnode=self.path.find_dir(podir)
+		if not podirnode:
+			error("could not find the podir %r"%podir)
+			continue
+		cache=getattr(self,'intlcache','.intlcache')
+		self.env['INTLCACHE']=os.path.join(self.path.bldpath(),podir,cache)
+		self.env['INTLPODIR']=podirnode.bldpath()
+		self.env['INTLFLAGS']=getattr(self,'flags',['-q','-u','-c'])
+		task=self.create_task('intltool',node,node.change_ext(''))
+		inst=getattr(self,'install_path','${LOCALEDIR}')
+		if inst:
+			self.bld.install_files(inst,task.outputs)
+@feature('intltool_po')
+def apply_intltool_po(self):
+	try:self.meths.remove('process_source')
+	except ValueError:pass
+	if not self.env.LOCALEDIR:
+		self.env.LOCALEDIR=self.env.PREFIX+'/share/locale'
+	appname=getattr(self,'appname','set_your_app_name')
+	podir=getattr(self,'podir','')
+	inst=getattr(self,'install_path','${LOCALEDIR}')
+	linguas=self.path.find_node(os.path.join(podir,'LINGUAS'))
+	if linguas:
+		file=open(linguas.abspath())
+		langs=[]
+		for line in file.readlines():
+			if not line.startswith('#'):
+				langs+=line.split()
+		file.close()
+		re_linguas=re.compile('[-a-zA-Z_@.]+')
+		for lang in langs:
+			if re_linguas.match(lang):
+				node=self.path.find_resource(os.path.join(podir,re_linguas.match(lang).group()+'.po'))
+				task=self.create_task('po',node,node.change_ext('.mo'))
+				if inst:
+					filename=task.outputs[0].name
+					(langname,ext)=os.path.splitext(filename)
+					inst_file=inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+appname+'.mo'
+					self.bld.install_as(inst_file,task.outputs[0],chmod=getattr(self,'chmod',Utils.O644),env=task.env)
+	else:
+		Logs.pprint('RED',"Error no LINGUAS file found in po directory")
+class po(Task.Task):
+	run_str='${MSGFMT} -o ${TGT} ${SRC}'
+	color='BLUE'
+class intltool(Task.Task):
+	run_str='${INTLTOOL} ${INTLFLAGS} ${INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}'
+	color='BLUE'
+def configure(conf):
+	conf.find_program('msgfmt',var='MSGFMT')
+	conf.find_perl_program('intltool-merge',var='INTLTOOL')
+	prefix=conf.env.PREFIX
+	datadir=conf.env.DATADIR
+	if not datadir:
+		datadir=os.path.join(prefix,'share')
+	conf.define('LOCALEDIR',os.path.join(datadir,'locale').replace('\\','\\\\'))
+	conf.define('DATADIR',datadir.replace('\\','\\\\'))
+	if conf.env.CC or conf.env.CXX:
+		conf.check(header_name='locale.h')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/irixcc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/irixcc.py
new file mode 100644
index 0000000..8dbdfca
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/irixcc.py
@@ -0,0 +1,48 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_irixcc(conf):
+	v=conf.env
+	cc=None
+	if v['CC']:cc=v['CC']
+	elif'CC'in conf.environ:cc=conf.environ['CC']
+	if not cc:cc=conf.find_program('cc',var='CC')
+	if not cc:conf.fatal('irixcc was not found')
+	cc=conf.cmd_to_list(cc)
+	try:
+		conf.cmd_and_log(cc+['-version'])
+	except Exception:
+		conf.fatal('%r -version could not be executed'%cc)
+	v['CC']=cc
+	v['CC_NAME']='irix'
+@conf
+def irixcc_common_flags(conf):
+	v=conf.env
+	v['CC_SRC_F']=''
+	v['CC_TGT_F']=['-c','-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
+	v['CCLNK_SRC_F']=''
+	v['CCLNK_TGT_F']=['-o']
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['cprogram_PATTERN']='%s'
+	v['cshlib_PATTERN']='lib%s.so'
+	v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+	conf.find_irixcc()
+	conf.find_cpp()
+	conf.find_ar()
+	conf.irixcc_common_flags()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/javaw.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/javaw.py
new file mode 100644
index 0000000..15f128c
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/javaw.py
@@ -0,0 +1,309 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re,tempfile,shutil
+from waflib import TaskGen,Task,Utils,Options,Build,Errors,Node,Logs
+from waflib.Configure import conf
+from waflib.TaskGen import feature,before_method,after_method
+from waflib.Tools import ccroot
+ccroot.USELIB_VARS['javac']=set(['CLASSPATH','JAVACFLAGS'])
+SOURCE_RE='**/*.java'
+JAR_RE='**/*'
+class_check_source='''
+public class Test {
+	public static void main(String[] argv) {
+		Class lib;
+		if (argv.length < 1) {
+			System.err.println("Missing argument");
+			System.exit(77);
+		}
+		try {
+			lib = Class.forName(argv[0]);
+		} catch (ClassNotFoundException e) {
+			System.err.println("ClassNotFoundException");
+			System.exit(1);
+		}
+		lib = null;
+		System.exit(0);
+	}
+}
+'''
+@feature('javac')
+@before_method('process_source')
+def apply_java(self):
+	Utils.def_attrs(self,jarname='',classpath='',sourcepath='.',srcdir='.',jar_mf_attributes={},jar_mf_classpath=[])
+	nodes_lst=[]
+	outdir=getattr(self,'outdir',None)
+	if outdir:
+		if not isinstance(outdir,Node.Node):
+			outdir=self.path.get_bld().make_node(self.outdir)
+	else:
+		outdir=self.path.get_bld()
+	outdir.mkdir()
+	self.outdir=outdir
+	self.env['OUTDIR']=outdir.abspath()
+	self.javac_task=tsk=self.create_task('javac')
+	tmp=[]
+	srcdir=getattr(self,'srcdir','')
+	if isinstance(srcdir,Node.Node):
+		srcdir=[srcdir]
+	for x in Utils.to_list(srcdir):
+		if isinstance(x,Node.Node):
+			y=x
+		else:
+			y=self.path.find_dir(x)
+			if not y:
+				self.bld.fatal('Could not find the folder %s from %s'%(x,self.path))
+		tmp.append(y)
+	tsk.srcdir=tmp
+	if getattr(self,'compat',None):
+		tsk.env.append_value('JAVACFLAGS',['-source',self.compat])
+	if hasattr(self,'sourcepath'):
+		fold=[isinstance(x,Node.Node)and x or self.path.find_dir(x)for x in self.to_list(self.sourcepath)]
+		names=os.pathsep.join([x.srcpath()for x in fold])
+	else:
+		names=[x.srcpath()for x in tsk.srcdir]
+	if names:
+		tsk.env.append_value('JAVACFLAGS',['-sourcepath',names])
+@feature('javac')
+@after_method('apply_java')
+def use_javac_files(self):
+	lst=[]
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	names=self.to_list(getattr(self,'use',[]))
+	get=self.bld.get_tgen_by_name
+	for x in names:
+		try:
+			y=get(x)
+		except Exception:
+			self.uselib.append(x)
+		else:
+			y.post()
+			lst.append(y.jar_task.outputs[0].abspath())
+			self.javac_task.set_run_after(y.jar_task)
+	if lst:
+		self.env.append_value('CLASSPATH',lst)
+@feature('javac')
+@after_method('apply_java','propagate_uselib_vars','use_javac_files')
+def set_classpath(self):
+	self.env.append_value('CLASSPATH',getattr(self,'classpath',[]))
+	for x in self.tasks:
+		x.env.CLASSPATH=os.pathsep.join(self.env.CLASSPATH)+os.pathsep
+@feature('jar')
+@after_method('apply_java','use_javac_files')
+@before_method('process_source')
+def jar_files(self):
+	destfile=getattr(self,'destfile','test.jar')
+	jaropts=getattr(self,'jaropts',[])
+	manifest=getattr(self,'manifest',None)
+	basedir=getattr(self,'basedir',None)
+	if basedir:
+		if not isinstance(self.basedir,Node.Node):
+			basedir=self.path.get_bld().make_node(basedir)
+	else:
+		basedir=self.path.get_bld()
+	if not basedir:
+		self.bld.fatal('Could not find the basedir %r for %r'%(self.basedir,self))
+	self.jar_task=tsk=self.create_task('jar_create')
+	if manifest:
+		jarcreate=getattr(self,'jarcreate','cfm')
+		node=self.path.find_node(manifest)
+		tsk.dep_nodes.append(node)
+		jaropts.insert(0,node.abspath())
+	else:
+		jarcreate=getattr(self,'jarcreate','cf')
+	if not isinstance(destfile,Node.Node):
+		destfile=self.path.find_or_declare(destfile)
+	if not destfile:
+		self.bld.fatal('invalid destfile %r for %r'%(destfile,self))
+	tsk.set_outputs(destfile)
+	tsk.basedir=basedir
+	jaropts.append('-C')
+	jaropts.append(basedir.bldpath())
+	jaropts.append('.')
+	tsk.env['JAROPTS']=jaropts
+	tsk.env['JARCREATE']=jarcreate
+	if getattr(self,'javac_task',None):
+		tsk.set_run_after(self.javac_task)
+@feature('jar')
+@after_method('jar_files')
+def use_jar_files(self):
+	lst=[]
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	names=self.to_list(getattr(self,'use',[]))
+	get=self.bld.get_tgen_by_name
+	for x in names:
+		try:
+			y=get(x)
+		except Exception:
+			self.uselib.append(x)
+		else:
+			y.post()
+			self.jar_task.run_after.update(y.tasks)
+class jar_create(Task.Task):
+	color='GREEN'
+	run_str='${JAR} ${JARCREATE} ${TGT} ${JAROPTS}'
+	def runnable_status(self):
+		for t in self.run_after:
+			if not t.hasrun:
+				return Task.ASK_LATER
+		if not self.inputs:
+			global JAR_RE
+			try:
+				self.inputs=[x for x in self.basedir.ant_glob(JAR_RE,remove=False)if id(x)!=id(self.outputs[0])]
+			except Exception:
+				raise Errors.WafError('Could not find the basedir %r for %r'%(self.basedir,self))
+		return super(jar_create,self).runnable_status()
+class javac(Task.Task):
+	color='BLUE'
+	nocache=True
+	vars=['CLASSPATH','JAVACFLAGS','JAVAC','OUTDIR']
+	def runnable_status(self):
+		for t in self.run_after:
+			if not t.hasrun:
+				return Task.ASK_LATER
+		if not self.inputs:
+			global SOURCE_RE
+			self.inputs=[]
+			for x in self.srcdir:
+				self.inputs.extend(x.ant_glob(SOURCE_RE,remove=False))
+		return super(javac,self).runnable_status()
+	def run(self):
+		env=self.env
+		gen=self.generator
+		bld=gen.bld
+		wd=bld.bldnode.abspath()
+		def to_list(xx):
+			if isinstance(xx,str):return[xx]
+			return xx
+		cmd=[]
+		cmd.extend(to_list(env['JAVAC']))
+		cmd.extend(['-classpath'])
+		cmd.extend(to_list(env['CLASSPATH']))
+		cmd.extend(['-d'])
+		cmd.extend(to_list(env['OUTDIR']))
+		cmd.extend(to_list(env['JAVACFLAGS']))
+		files=[a.path_from(bld.bldnode)for a in self.inputs]
+		tmp=None
+		try:
+			if len(str(files))+len(str(cmd))>8192:
+				(fd,tmp)=tempfile.mkstemp(dir=bld.bldnode.abspath())
+				try:
+					os.write(fd,'\n'.join(files))
+				finally:
+					if tmp:
+						os.close(fd)
+				if Logs.verbose:
+					Logs.debug('runner: %r'%(cmd+files))
+				cmd.append('@'+tmp)
+			else:
+				cmd+=files
+			ret=self.exec_command(cmd,cwd=wd,env=env.env or None)
+		finally:
+			if tmp:
+				os.remove(tmp)
+		return ret
+	def post_run(self):
+		for n in self.generator.outdir.ant_glob('**/*.class'):
+			n.sig=Utils.h_file(n.abspath())
+		self.generator.bld.task_sigs[self.uid()]=self.cache_sig
+@feature('javadoc')
+@after_method('process_rule')
+def create_javadoc(self):
+	tsk=self.create_task('javadoc')
+	tsk.classpath=getattr(self,'classpath',[])
+	self.javadoc_package=Utils.to_list(self.javadoc_package)
+	if not isinstance(self.javadoc_output,Node.Node):
+		self.javadoc_output=self.bld.path.find_or_declare(self.javadoc_output)
+class javadoc(Task.Task):
+	color='BLUE'
+	def __str__(self):
+		return'%s: %s -> %s\n'%(self.__class__.__name__,self.generator.srcdir,self.generator.javadoc_output)
+	def run(self):
+		env=self.env
+		bld=self.generator.bld
+		wd=bld.bldnode.abspath()
+		srcpath=self.generator.path.abspath()+os.sep+self.generator.srcdir
+		srcpath+=os.pathsep
+		srcpath+=self.generator.path.get_bld().abspath()+os.sep+self.generator.srcdir
+		classpath=env.CLASSPATH
+		classpath+=os.pathsep
+		classpath+=os.pathsep.join(self.classpath)
+		classpath="".join(classpath)
+		self.last_cmd=lst=[]
+		lst.extend(Utils.to_list(env['JAVADOC']))
+		lst.extend(['-d',self.generator.javadoc_output.abspath()])
+		lst.extend(['-sourcepath',srcpath])
+		lst.extend(['-classpath',classpath])
+		lst.extend(['-subpackages'])
+		lst.extend(self.generator.javadoc_package)
+		lst=[x for x in lst if x]
+		self.generator.bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
+	def post_run(self):
+		nodes=self.generator.javadoc_output.ant_glob('**')
+		for x in nodes:
+			x.sig=Utils.h_file(x.abspath())
+		self.generator.bld.task_sigs[self.uid()]=self.cache_sig
+def configure(self):
+	java_path=self.environ['PATH'].split(os.pathsep)
+	v=self.env
+	if'JAVA_HOME'in self.environ:
+		java_path=[os.path.join(self.environ['JAVA_HOME'],'bin')]+java_path
+		self.env['JAVA_HOME']=[self.environ['JAVA_HOME']]
+	for x in'javac java jar javadoc'.split():
+		self.find_program(x,var=x.upper(),path_list=java_path)
+		self.env[x.upper()]=self.cmd_to_list(self.env[x.upper()])
+	if'CLASSPATH'in self.environ:
+		v['CLASSPATH']=self.environ['CLASSPATH']
+	if not v['JAR']:self.fatal('jar is required for making java packages')
+	if not v['JAVAC']:self.fatal('javac is required for compiling java classes')
+	v['JARCREATE']='cf'
+	v['JAVACFLAGS']=[]
+@conf
+def check_java_class(self,classname,with_classpath=None):
+	javatestdir='.waf-javatest'
+	classpath=javatestdir
+	if self.env['CLASSPATH']:
+		classpath+=os.pathsep+self.env['CLASSPATH']
+	if isinstance(with_classpath,str):
+		classpath+=os.pathsep+with_classpath
+	shutil.rmtree(javatestdir,True)
+	os.mkdir(javatestdir)
+	Utils.writef(os.path.join(javatestdir,'Test.java'),class_check_source)
+	self.exec_command(self.env['JAVAC']+[os.path.join(javatestdir,'Test.java')],shell=False)
+	cmd=self.env['JAVA']+['-cp',classpath,'Test',classname]
+	self.to_log("%s\n"%str(cmd))
+	found=self.exec_command(cmd,shell=False)
+	self.msg('Checking for java class %s'%classname,not found)
+	shutil.rmtree(javatestdir,True)
+	return found
+@conf
+def check_jni_headers(conf):
+	if not conf.env.CC_NAME and not conf.env.CXX_NAME:
+		conf.fatal('load a compiler first (gcc, g++, ..)')
+	if not conf.env.JAVA_HOME:
+		conf.fatal('set JAVA_HOME in the system environment')
+	javaHome=conf.env['JAVA_HOME'][0]
+	dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/include')
+	if dir is None:
+		dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/../Headers')
+	if dir is None:
+		conf.fatal('JAVA_HOME does not seem to be set properly')
+	f=dir.ant_glob('**/(jni|jni_md).h')
+	incDirs=[x.parent.abspath()for x in f]
+	dir=conf.root.find_dir(conf.env.JAVA_HOME[0])
+	f=dir.ant_glob('**/*jvm.(so|dll|dylib)')
+	libDirs=[x.parent.abspath()for x in f]or[javaHome]
+	f=dir.ant_glob('**/*jvm.(lib)')
+	if f:
+		libDirs=[[x,y.parent.abspath()]for x in libDirs for y in f]
+	for d in libDirs:
+		try:
+			conf.check(header_name='jni.h',define_name='HAVE_JNI_H',lib='jvm',libpath=d,includes=incDirs,uselib_store='JAVA',uselib='JAVA')
+		except Exception:
+			pass
+		else:
+			break
+	else:
+		conf.fatal('could not find lib jvm in %r (see config.log)'%libDirs)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/kde4.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/kde4.py
new file mode 100644
index 0000000..cd51f5f
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/kde4.py
@@ -0,0 +1,48 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,re
+from waflib import Options,TaskGen,Task,Utils
+from waflib.TaskGen import feature,after_method
+@feature('msgfmt')
+def apply_msgfmt(self):
+	for lang in self.to_list(self.langs):
+		node=self.path.find_resource(lang+'.po')
+		task=self.create_task('msgfmt',node,node.change_ext('.mo'))
+		langname=lang.split('/')
+		langname=langname[-1]
+		inst=getattr(self,'install_path','${KDE4_LOCALE_INSTALL_DIR}')
+		self.bld.install_as(inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+getattr(self,'appname','set_your_appname')+'.mo',task.outputs[0],chmod=getattr(self,'chmod',Utils.O644))
+class msgfmt(Task.Task):
+	color='BLUE'
+	run_str='${MSGFMT} ${SRC} -o ${TGT}'
+def configure(self):
+	kdeconfig=self.find_program('kde4-config')
+	prefix=self.cmd_and_log('%s --prefix'%kdeconfig).strip()
+	fname='%s/share/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
+	try:os.stat(fname)
+	except OSError:
+		fname='%s/share/kde4/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
+		try:os.stat(fname)
+		except OSError:self.fatal('could not open %s'%fname)
+	try:
+		txt=Utils.readf(fname)
+	except(OSError,IOError):
+		self.fatal('could not read %s'%fname)
+	txt=txt.replace('\\\n','\n')
+	fu=re.compile('#(.*)\n')
+	txt=fu.sub('',txt)
+	setregexp=re.compile('([sS][eE][tT]\s*\()\s*([^\s]+)\s+\"([^"]+)\"\)')
+	found=setregexp.findall(txt)
+	for(_,key,val)in found:
+		self.env[key]=val
+	self.env['LIB_KDECORE']=['kdecore']
+	self.env['LIB_KDEUI']=['kdeui']
+	self.env['LIB_KIO']=['kio']
+	self.env['LIB_KHTML']=['khtml']
+	self.env['LIB_KPARTS']=['kparts']
+	self.env['LIBPATH_KDECORE']=[os.path.join(self.env.KDE4_LIB_INSTALL_DIR,'kde4','devel'),self.env.KDE4_LIB_INSTALL_DIR]
+	self.env['INCLUDES_KDECORE']=[self.env['KDE4_INCLUDE_INSTALL_DIR']]
+	self.env.append_value('INCLUDES_KDECORE',[self.env['KDE4_INCLUDE_INSTALL_DIR']+os.sep+'KDE'])
+	self.find_program('msgfmt',var='MSGFMT')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ldc2.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ldc2.py
new file mode 100644
index 0000000..25b99e5
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ldc2.py
@@ -0,0 +1,37 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+@conf
+def find_ldc2(conf):
+	conf.find_program(['ldc2'],var='D')
+	out=conf.cmd_and_log([conf.env.D,'-version'])
+	if out.find("based on DMD v2.")==-1:
+		conf.fatal("detected compiler is not ldc2")
+@conf
+def common_flags_ldc2(conf):
+	v=conf.env
+	v['D_SRC_F']=['-c']
+	v['D_TGT_F']='-of%s'
+	v['D_LINKER']=v['D']
+	v['DLNK_SRC_F']=''
+	v['DLNK_TGT_F']='-of%s'
+	v['DINC_ST']='-I%s'
+	v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+	v['DSTLIB_ST']=v['DSHLIB_ST']='-L-l%s'
+	v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L-L%s'
+	v['LINKFLAGS_dshlib']=['-L-shared']
+	v['DHEADER_ext']='.di'
+	v['DFLAGS_d_with_header']=['-H','-Hf']
+	v['D_HDR_F']='%s'
+	v['LINKFLAGS']=[]
+	v['DFLAGS_dshlib']=['-relocation-model=pic']
+def configure(conf):
+	conf.find_ldc2()
+	conf.load('ar')
+	conf.load('d')
+	conf.common_flags_ldc2()
+	conf.d_platform_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/lua.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/lua.py
new file mode 100644
index 0000000..a0a35fc
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/lua.py
@@ -0,0 +1,18 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.TaskGen import extension
+from waflib import Task,Utils
+@extension('.lua')
+def add_lua(self,node):
+	tsk=self.create_task('luac',node,node.change_ext('.luac'))
+	inst_to=getattr(self,'install_path',self.env.LUADIR and'${LUADIR}'or None)
+	if inst_to:
+		self.bld.install_files(inst_to,tsk.outputs)
+	return tsk
+class luac(Task.Task):
+	run_str='${LUAC} -s -o ${TGT} ${SRC}'
+	color='PINK'
+def configure(conf):
+	conf.find_program('luac',var='LUAC')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/msvc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/msvc.py
new file mode 100644
index 0000000..9ac0a59
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/msvc.py
@@ -0,0 +1,750 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,re,tempfile
+from waflib import Utils,Task,Logs,Options,Errors
+from waflib.Logs import debug,warn
+from waflib.TaskGen import after_method,feature
+from waflib.Configure import conf
+from waflib.Tools import ccroot,c,cxx,ar,winres
+g_msvc_systemlibs='''
+aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet
+cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs
+credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d
+ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp
+faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid
+gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop
+kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi
+mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree
+msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm
+netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp
+odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32
+osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu
+ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm
+rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32
+shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32
+traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg
+version vfw32 wbemuuid  webpost wiaguid wininet winmm winscard winspool winstrm
+wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp
+'''.split()
+all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64'),('x86_arm','arm')]
+all_wince_platforms=[('armv4','arm'),('armv4i','arm'),('mipsii','mips'),('mipsii_fp','mips'),('mipsiv','mips'),('mipsiv_fp','mips'),('sh4','sh'),('x86','cex86')]
+all_icl_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
+def options(opt):
+	opt.add_option('--msvc_version',type='string',help='msvc version, eg: "msvc 10.0,msvc 9.0"',default='')
+	opt.add_option('--msvc_targets',type='string',help='msvc targets, eg: "x64,arm"',default='')
+def setup_msvc(conf,versions,arch=False):
+	platforms=getattr(Options.options,'msvc_targets','').split(',')
+	if platforms==['']:
+		platforms=Utils.to_list(conf.env['MSVC_TARGETS'])or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms]
+	desired_versions=getattr(Options.options,'msvc_version','').split(',')
+	if desired_versions==['']:
+		desired_versions=conf.env['MSVC_VERSIONS']or[v for v,_ in versions][::-1]
+	versiondict=dict(versions)
+	for version in desired_versions:
+		try:
+			targets=dict(versiondict[version])
+			for target in platforms:
+				try:
+					arch,(p1,p2,p3)=targets[target]
+					compiler,revision=version.rsplit(' ',1)
+					if arch:
+						return compiler,revision,p1,p2,p3,arch
+					else:
+						return compiler,revision,p1,p2,p3
+				except KeyError:continue
+		except KeyError:continue
+	conf.fatal('msvc: Impossible to find a valid architecture for building (in setup_msvc)')
+@conf
+def get_msvc_version(conf,compiler,version,target,vcvars):
+	debug('msvc: get_msvc_version: %r %r %r',compiler,version,target)
+	batfile=conf.bldnode.make_node('waf-print-msvc.bat')
+	batfile.write("""@echo off
+set INCLUDE=
+set LIB=
+call "%s" %s
+echo PATH=%%PATH%%
+echo INCLUDE=%%INCLUDE%%
+echo LIB=%%LIB%%;%%LIBPATH%%
+"""%(vcvars,target))
+	sout=conf.cmd_and_log(['cmd','/E:on','/V:on','/C',batfile.abspath()])
+	lines=sout.splitlines()
+	if not lines[0]:
+		lines.pop(0)
+	MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None
+	for line in lines:
+		if line.startswith('PATH='):
+			path=line[5:]
+			MSVC_PATH=path.split(';')
+		elif line.startswith('INCLUDE='):
+			MSVC_INCDIR=[i for i in line[8:].split(';')if i]
+		elif line.startswith('LIB='):
+			MSVC_LIBDIR=[i for i in line[4:].split(';')if i]
+	if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR):
+		conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)')
+	env=dict(os.environ)
+	env.update(PATH=path)
+	compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
+	cxx=conf.find_program(compiler_name,path_list=MSVC_PATH)
+	cxx=conf.cmd_to_list(cxx)
+	if'CL'in env:
+		del(env['CL'])
+	try:
+		try:
+			conf.cmd_and_log(cxx+['/help'],env=env)
+		except Exception ,e:
+			debug('msvc: get_msvc_version: %r %r %r -> failure'%(compiler,version,target))
+			debug(str(e))
+			conf.fatal('msvc: cannot run the compiler (in get_msvc_version)')
+		else:
+			debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target)
+	finally:
+		conf.env[compiler_name]=''
+	return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
+@conf
+def gather_wsdk_versions(conf,versions):
+	version_pattern=re.compile('^v..?.?\...?.?')
+	try:
+		all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows')
+	except WindowsError:
+		try:
+			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows')
+		except WindowsError:
+			return
+	index=0
+	while 1:
+		try:
+			version=Utils.winreg.EnumKey(all_versions,index)
+		except WindowsError:
+			break
+		index=index+1
+		if not version_pattern.match(version):
+			continue
+		try:
+			msvc_version=Utils.winreg.OpenKey(all_versions,version)
+			path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder')
+		except WindowsError:
+			continue
+		if os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
+			targets=[]
+			for target,arch in all_msvc_platforms:
+				try:
+					targets.append((target,(arch,conf.get_msvc_version('wsdk',version,'/'+target,os.path.join(path,'bin','SetEnv.cmd')))))
+				except conf.errors.ConfigurationError:
+					pass
+			versions.append(('wsdk '+version[1:],targets))
+def gather_wince_supported_platforms():
+	supported_wince_platforms=[]
+	try:
+		ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs')
+	except WindowsError:
+		try:
+			ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs')
+		except WindowsError:
+			ce_sdk=''
+	if not ce_sdk:
+		return supported_wince_platforms
+	ce_index=0
+	while 1:
+		try:
+			sdk_device=Utils.winreg.EnumKey(ce_sdk,ce_index)
+		except WindowsError:
+			break
+		ce_index=ce_index+1
+		sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device)
+		try:
+			path,type=Utils.winreg.QueryValueEx(sdk,'SDKRootDir')
+		except WindowsError:
+			try:
+				path,type=Utils.winreg.QueryValueEx(sdk,'SDKInformation')
+				path,xml=os.path.split(path)
+			except WindowsError:
+				continue
+		path=str(path)
+		path,device=os.path.split(path)
+		if not device:
+			path,device=os.path.split(path)
+		for arch,compiler in all_wince_platforms:
+			platforms=[]
+			if os.path.isdir(os.path.join(path,device,'Lib',arch)):
+				platforms.append((arch,compiler,os.path.join(path,device,'Include',arch),os.path.join(path,device,'Lib',arch)))
+			if platforms:
+				supported_wince_platforms.append((device,platforms))
+	return supported_wince_platforms
+def gather_msvc_detected_versions():
+	version_pattern=re.compile('^(\d\d?\.\d\d?)(Exp)?$')
+	detected_versions=[]
+	for vcver,vcvar in[('VCExpress','Exp'),('VisualStudio','')]:
+		try:
+			prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
+			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
+		except WindowsError:
+			try:
+				prefix='SOFTWARE\\Microsoft\\'+vcver
+				all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
+			except WindowsError:
+				continue
+		index=0
+		while 1:
+			try:
+				version=Utils.winreg.EnumKey(all_versions,index)
+			except WindowsError:
+				break
+			index=index+1
+			match=version_pattern.match(version)
+			if not match:
+				continue
+			else:
+				versionnumber=float(match.group(1))
+			detected_versions.append((versionnumber,version+vcvar,prefix+"\\"+version))
+	def fun(tup):
+		return tup[0]
+	detected_versions.sort(key=fun)
+	return detected_versions
+@conf
+def gather_msvc_targets(conf,versions,version,vc_path):
+	targets=[]
+	if os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')):
+		for target,realtarget in all_msvc_platforms[::-1]:
+			try:
+				targets.append((target,(realtarget,conf.get_msvc_version('msvc',version,target,os.path.join(vc_path,'vcvarsall.bat')))))
+			except conf.errors.ConfigurationError:
+				pass
+	elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')):
+		try:
+			targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat')))))
+		except conf.errors.ConfigurationError:
+			pass
+	elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')):
+		try:
+			targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'',os.path.join(vc_path,'Bin','vcvars32.bat')))))
+		except conf.errors.ConfigurationError:
+			pass
+	if targets:
+		versions.append(('msvc '+version,targets))
+@conf
+def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms):
+	for device,platforms in supported_platforms:
+		cetargets=[]
+		for platform,compiler,include,lib in platforms:
+			winCEpath=os.path.join(vc_path,'ce')
+			if not os.path.isdir(winCEpath):
+				continue
+			try:
+				common_bindirs,_1,_2=conf.get_msvc_version('msvc',version,'x86',vsvars)
+			except conf.errors.ConfigurationError:
+				continue
+			if os.path.isdir(os.path.join(winCEpath,'lib',platform)):
+				bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)]+common_bindirs
+				incdirs=[os.path.join(winCEpath,'include'),os.path.join(winCEpath,'atlmfc','include'),include]
+				libdirs=[os.path.join(winCEpath,'lib',platform),os.path.join(winCEpath,'atlmfc','lib',platform),lib]
+				cetargets.append((platform,(platform,(bindirs,incdirs,libdirs))))
+		if cetargets:
+			versions.append((device+' '+version,cetargets))
+@conf
+def gather_winphone_targets(conf,versions,version,vc_path,vsvars):
+	targets=[]
+	for target,realtarget in all_msvc_platforms[::-1]:
+		try:
+			targets.append((target,(realtarget,conf.get_msvc_version('winphone',version,target,vsvars))))
+		except conf.errors.ConfigurationError ,e:
+			pass
+	if targets:
+		versions.append(('winphone '+version,targets))
+@conf
+def gather_msvc_versions(conf,versions):
+	vc_paths=[]
+	for(v,version,reg)in gather_msvc_detected_versions():
+		try:
+			try:
+				msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\VC")
+			except WindowsError:
+				msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\Microsoft Visual C++")
+			path,type=Utils.winreg.QueryValueEx(msvc_version,'ProductDir')
+			vc_paths.append((version,os.path.abspath(str(path))))
+		except WindowsError:
+			continue
+	wince_supported_platforms=gather_wince_supported_platforms()
+	for version,vc_path in vc_paths:
+		vs_path=os.path.dirname(vc_path)
+		vsvars=os.path.join(vs_path,'Common7','Tools','vsvars32.bat')
+		if wince_supported_platforms and os.path.isfile(vsvars):
+			conf.gather_wince_targets(versions,version,vc_path,vsvars,wince_supported_platforms)
+		vsvars=os.path.join(vs_path,'VC','WPSDK','WP80','vcvarsphoneall.bat')
+		if os.path.isfile(vsvars):
+			conf.gather_winphone_targets(versions,'8.0',vc_path,vsvars)
+	for version,vc_path in vc_paths:
+		vs_path=os.path.dirname(vc_path)
+		conf.gather_msvc_targets(versions,version,vc_path)
+@conf
+def gather_icl_versions(conf,versions):
+	version_pattern=re.compile('^...?.?\....?.?')
+	try:
+		all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++')
+	except WindowsError:
+		try:
+			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++')
+		except WindowsError:
+			return
+	index=0
+	while 1:
+		try:
+			version=Utils.winreg.EnumKey(all_versions,index)
+		except WindowsError:
+			break
+		index=index+1
+		if not version_pattern.match(version):
+			continue
+		targets=[]
+		for target,arch in all_icl_platforms:
+			try:
+				if target=='intel64':targetDir='EM64T_NATIVE'
+				else:targetDir=target
+				Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
+				icl_version=Utils.winreg.OpenKey(all_versions,version)
+				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+				batch_file=os.path.join(path,'bin','iclvars.bat')
+				if os.path.isfile(batch_file):
+					try:
+						targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
+					except conf.errors.ConfigurationError:
+						pass
+			except WindowsError:
+				pass
+		for target,arch in all_icl_platforms:
+			try:
+				icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
+				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+				batch_file=os.path.join(path,'bin','iclvars.bat')
+				if os.path.isfile(batch_file):
+					try:
+						targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
+					except conf.errors.ConfigurationError:
+						pass
+			except WindowsError:
+				continue
+		major=version[0:2]
+		versions.append(('intel '+major,targets))
+@conf
+def gather_intel_composer_versions(conf,versions):
+	version_pattern=re.compile('^...?.?\...?.?.?')
+	try:
+		all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Suites')
+	except WindowsError:
+		try:
+			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Suites')
+		except WindowsError:
+			return
+	index=0
+	while 1:
+		try:
+			version=Utils.winreg.EnumKey(all_versions,index)
+		except WindowsError:
+			break
+		index=index+1
+		if not version_pattern.match(version):
+			continue
+		targets=[]
+		for target,arch in all_icl_platforms:
+			try:
+				if target=='intel64':targetDir='EM64T_NATIVE'
+				else:targetDir=target
+				try:
+					defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir)
+				except WindowsError:
+					if targetDir=='EM64T_NATIVE':
+						defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T')
+					else:
+						raise WindowsError
+				uid,type=Utils.winreg.QueryValueEx(defaults,'SubKey')
+				Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir)
+				icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++')
+				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+				batch_file=os.path.join(path,'bin','iclvars.bat')
+				if os.path.isfile(batch_file):
+					try:
+						targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
+					except conf.errors.ConfigurationError ,e:
+						pass
+				compilervars_warning_attr='_compilervars_warning_key'
+				if version[0:2]=='13'and getattr(conf,compilervars_warning_attr,True):
+					setattr(conf,compilervars_warning_attr,False)
+					patch_url='http://software.intel.com/en-us/forums/topic/328487'
+					compilervars_arch=os.path.join(path,'bin','compilervars_arch.bat')
+					for vscomntools in['VS110COMNTOOLS','VS100COMNTOOLS']:
+						if os.environ.has_key(vscomntools):
+							vs_express_path=os.environ[vscomntools]+r'..\IDE\VSWinExpress.exe'
+							dev_env_path=os.environ[vscomntools]+r'..\IDE\devenv.exe'
+							if(r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"'in Utils.readf(compilervars_arch)and not os.path.exists(vs_express_path)and not os.path.exists(dev_env_path)):
+								Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ''(VSWinExpress.exe) but it does not seem to be installed at %r. ''The intel command line set up will fail to configure unless the file %r''is patched. See: %s')%(vs_express_path,compilervars_arch,patch_url))
+			except WindowsError:
+				pass
+		major=version[0:2]
+		versions.append(('intel '+major,targets))
+@conf
+def get_msvc_versions(conf):
+	if not conf.env['MSVC_INSTALLED_VERSIONS']:
+		lst=[]
+		conf.gather_icl_versions(lst)
+		conf.gather_intel_composer_versions(lst)
+		conf.gather_wsdk_versions(lst)
+		conf.gather_msvc_versions(lst)
+		conf.env['MSVC_INSTALLED_VERSIONS']=lst
+	return conf.env['MSVC_INSTALLED_VERSIONS']
+@conf
+def print_all_msvc_detected(conf):
+	for version,targets in conf.env['MSVC_INSTALLED_VERSIONS']:
+		Logs.info(version)
+		for target,l in targets:
+			Logs.info("\t"+target)
+@conf
+def detect_msvc(conf,arch=False):
+	versions=get_msvc_versions(conf)
+	return setup_msvc(conf,versions,arch)
+@conf
+def find_lt_names_msvc(self,libname,is_static=False):
+	lt_names=['lib%s.la'%libname,'%s.la'%libname,]
+	for path in self.env['LIBPATH']:
+		for la in lt_names:
+			laf=os.path.join(path,la)
+			dll=None
+			if os.path.exists(laf):
+				ltdict=Utils.read_la_file(laf)
+				lt_libdir=None
+				if ltdict.get('libdir',''):
+					lt_libdir=ltdict['libdir']
+				if not is_static and ltdict.get('library_names',''):
+					dllnames=ltdict['library_names'].split()
+					dll=dllnames[0].lower()
+					dll=re.sub('\.dll$','',dll)
+					return(lt_libdir,dll,False)
+				elif ltdict.get('old_library',''):
+					olib=ltdict['old_library']
+					if os.path.exists(os.path.join(path,olib)):
+						return(path,olib,True)
+					elif lt_libdir!=''and os.path.exists(os.path.join(lt_libdir,olib)):
+						return(lt_libdir,olib,True)
+					else:
+						return(None,olib,True)
+				else:
+					raise self.errors.WafError('invalid libtool object file: %s'%laf)
+	return(None,None,None)
+@conf
+def libname_msvc(self,libname,is_static=False):
+	lib=libname.lower()
+	lib=re.sub('\.lib$','',lib)
+	if lib in g_msvc_systemlibs:
+		return lib
+	lib=re.sub('^lib','',lib)
+	if lib=='m':
+		return None
+	(lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static)
+	if lt_path!=None and lt_libname!=None:
+		if lt_static==True:
+			return os.path.join(lt_path,lt_libname)
+	if lt_path!=None:
+		_libpaths=[lt_path]+self.env['LIBPATH']
+	else:
+		_libpaths=self.env['LIBPATH']
+	static_libs=['lib%ss.lib'%lib,'lib%s.lib'%lib,'%ss.lib'%lib,'%s.lib'%lib,]
+	dynamic_libs=['lib%s.dll.lib'%lib,'lib%s.dll.a'%lib,'%s.dll.lib'%lib,'%s.dll.a'%lib,'lib%s_d.lib'%lib,'%s_d.lib'%lib,'%s.lib'%lib,]
+	libnames=static_libs
+	if not is_static:
+		libnames=dynamic_libs+static_libs
+	for path in _libpaths:
+		for libn in libnames:
+			if os.path.exists(os.path.join(path,libn)):
+				debug('msvc: lib found: %s'%os.path.join(path,libn))
+				return re.sub('\.lib$','',libn)
+	self.fatal("The library %r could not be found"%libname)
+	return re.sub('\.lib$','',libname)
+@conf
+def check_lib_msvc(self,libname,is_static=False,uselib_store=None):
+	libn=self.libname_msvc(libname,is_static)
+	if not uselib_store:
+		uselib_store=libname.upper()
+	if False and is_static:
+		self.env['STLIB_'+uselib_store]=[libn]
+	else:
+		self.env['LIB_'+uselib_store]=[libn]
+@conf
+def check_libs_msvc(self,libnames,is_static=False):
+	for libname in Utils.to_list(libnames):
+		self.check_lib_msvc(libname,is_static)
+def configure(conf):
+	conf.autodetect(True)
+	conf.find_msvc()
+	conf.msvc_common_flags()
+	conf.cc_load_tools()
+	conf.cxx_load_tools()
+	conf.cc_add_flags()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
+	conf.visual_studio_add_flags()
+@conf
+def no_autodetect(conf):
+	conf.env.NO_MSVC_DETECT=1
+	configure(conf)
+@conf
+def autodetect(conf,arch=False):
+	v=conf.env
+	if v.NO_MSVC_DETECT:
+		return
+	if arch:
+		compiler,version,path,includes,libdirs,arch=conf.detect_msvc(True)
+		v['DEST_CPU']=arch
+	else:
+		compiler,version,path,includes,libdirs=conf.detect_msvc()
+	v['PATH']=path
+	v['INCLUDES']=includes
+	v['LIBPATH']=libdirs
+	v['MSVC_COMPILER']=compiler
+	try:
+		v['MSVC_VERSION']=float(version)
+	except Exception:
+		v['MSVC_VERSION']=float(version[:-3])
+def _get_prog_names(conf,compiler):
+	if compiler=='intel':
+		compiler_name='ICL'
+		linker_name='XILINK'
+		lib_name='XILIB'
+	else:
+		compiler_name='CL'
+		linker_name='LINK'
+		lib_name='LIB'
+	return compiler_name,linker_name,lib_name
+@conf
+def find_msvc(conf):
+	if sys.platform=='cygwin':
+		conf.fatal('MSVC module does not work under cygwin Python!')
+	v=conf.env
+	path=v['PATH']
+	compiler=v['MSVC_COMPILER']
+	version=v['MSVC_VERSION']
+	compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
+	v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11)
+	cxx=None
+	if v['CXX']:cxx=v['CXX']
+	elif'CXX'in conf.environ:cxx=conf.environ['CXX']
+	cxx=conf.find_program(compiler_name,var='CXX',path_list=path)
+	cxx=conf.cmd_to_list(cxx)
+	env=dict(conf.environ)
+	if path:env.update(PATH=';'.join(path))
+	if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env):
+		conf.fatal('the msvc compiler could not be identified')
+	v['CC']=v['CXX']=cxx
+	v['CC_NAME']=v['CXX_NAME']='msvc'
+	if not v['LINK_CXX']:
+		link=conf.find_program(linker_name,path_list=path)
+		if link:v['LINK_CXX']=link
+		else:conf.fatal('%s was not found (linker)'%linker_name)
+		v['LINK']=link
+	if not v['LINK_CC']:
+		v['LINK_CC']=v['LINK_CXX']
+	if not v['AR']:
+		stliblink=conf.find_program(lib_name,path_list=path,var='AR')
+		if not stliblink:return
+		v['ARFLAGS']=['/NOLOGO']
+	if v.MSVC_MANIFEST:
+		conf.find_program('MT',path_list=path,var='MT')
+		v['MTFLAGS']=['/NOLOGO']
+	try:
+		conf.load('winres')
+	except Errors.WafError:
+		warn('Resource compiler not found. Compiling resource file is disabled')
+@conf
+def visual_studio_add_flags(self):
+	v=self.env
+	try:v.prepend_value('INCLUDES',[x for x in self.environ['INCLUDE'].split(';')if x])
+	except Exception:pass
+	try:v.prepend_value('LIBPATH',[x for x in self.environ['LIB'].split(';')if x])
+	except Exception:pass
+@conf
+def msvc_common_flags(conf):
+	v=conf.env
+	v['DEST_BINFMT']='pe'
+	v.append_value('CFLAGS',['/nologo'])
+	v.append_value('CXXFLAGS',['/nologo'])
+	v['DEFINES_ST']='/D%s'
+	v['CC_SRC_F']=''
+	v['CC_TGT_F']=['/c','/Fo']
+	if v['MSVC_VERSION']>=8:
+		v['CC_TGT_F']=['/FC']+v['CC_TGT_F']
+	v['CXX_SRC_F']=''
+	v['CXX_TGT_F']=['/c','/Fo']
+	if v['MSVC_VERSION']>=8:
+		v['CXX_TGT_F']=['/FC']+v['CXX_TGT_F']
+	v['CPPPATH_ST']='/I%s'
+	v['AR_TGT_F']=v['CCLNK_TGT_F']=v['CXXLNK_TGT_F']='/OUT:'
+	v['CFLAGS_CONSOLE']=v['CXXFLAGS_CONSOLE']=['/SUBSYSTEM:CONSOLE']
+	v['CFLAGS_NATIVE']=v['CXXFLAGS_NATIVE']=['/SUBSYSTEM:NATIVE']
+	v['CFLAGS_POSIX']=v['CXXFLAGS_POSIX']=['/SUBSYSTEM:POSIX']
+	v['CFLAGS_WINDOWS']=v['CXXFLAGS_WINDOWS']=['/SUBSYSTEM:WINDOWS']
+	v['CFLAGS_WINDOWSCE']=v['CXXFLAGS_WINDOWSCE']=['/SUBSYSTEM:WINDOWSCE']
+	v['CFLAGS_CRT_MULTITHREADED']=v['CXXFLAGS_CRT_MULTITHREADED']=['/MT']
+	v['CFLAGS_CRT_MULTITHREADED_DLL']=v['CXXFLAGS_CRT_MULTITHREADED_DLL']=['/MD']
+	v['CFLAGS_CRT_MULTITHREADED_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DBG']=['/MTd']
+	v['CFLAGS_CRT_MULTITHREADED_DLL_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DLL_DBG']=['/MDd']
+	v['LIB_ST']='%s.lib'
+	v['LIBPATH_ST']='/LIBPATH:%s'
+	v['STLIB_ST']='%s.lib'
+	v['STLIBPATH_ST']='/LIBPATH:%s'
+	v.append_value('LINKFLAGS',['/NOLOGO'])
+	if v['MSVC_MANIFEST']:
+		v.append_value('LINKFLAGS',['/MANIFEST'])
+	v['CFLAGS_cshlib']=[]
+	v['CXXFLAGS_cxxshlib']=[]
+	v['LINKFLAGS_cshlib']=v['LINKFLAGS_cxxshlib']=['/DLL']
+	v['cshlib_PATTERN']=v['cxxshlib_PATTERN']='%s.dll'
+	v['implib_PATTERN']='%s.lib'
+	v['IMPLIB_ST']='/IMPLIB:%s'
+	v['LINKFLAGS_cstlib']=[]
+	v['cstlib_PATTERN']=v['cxxstlib_PATTERN']='%s.lib'
+	v['cprogram_PATTERN']=v['cxxprogram_PATTERN']='%s.exe'
+@after_method('apply_link')
+@feature('c','cxx')
+def apply_flags_msvc(self):
+	if self.env.CC_NAME!='msvc'or not getattr(self,'link_task',None):
+		return
+	is_static=isinstance(self.link_task,ccroot.stlink_task)
+	subsystem=getattr(self,'subsystem','')
+	if subsystem:
+		subsystem='/subsystem:%s'%subsystem
+		flags=is_static and'ARFLAGS'or'LINKFLAGS'
+		self.env.append_value(flags,subsystem)
+	if not is_static:
+		for f in self.env.LINKFLAGS:
+			d=f.lower()
+			if d[1:]=='debug':
+				pdbnode=self.link_task.outputs[0].change_ext('.pdb')
+				self.link_task.outputs.append(pdbnode)
+				try:
+					self.install_task.source.append(pdbnode)
+				except AttributeError:
+					pass
+				break
+@feature('cprogram','cshlib','cxxprogram','cxxshlib')
+@after_method('apply_link')
+def apply_manifest(self):
+	if self.env.CC_NAME=='msvc'and self.env.MSVC_MANIFEST and getattr(self,'link_task',None):
+		out_node=self.link_task.outputs[0]
+		man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
+		self.link_task.outputs.append(man_node)
+		self.link_task.do_manifest=True
+def exec_mf(self):
+	env=self.env
+	mtool=env['MT']
+	if not mtool:
+		return 0
+	self.do_manifest=False
+	outfile=self.outputs[0].abspath()
+	manifest=None
+	for out_node in self.outputs:
+		if out_node.name.endswith('.manifest'):
+			manifest=out_node.abspath()
+			break
+	if manifest is None:
+		return 0
+	mode=''
+	if'cprogram'in self.generator.features or'cxxprogram'in self.generator.features:
+		mode='1'
+	elif'cshlib'in self.generator.features or'cxxshlib'in self.generator.features:
+		mode='2'
+	debug('msvc: embedding manifest in mode %r'%mode)
+	lst=[]
+	lst.append(env['MT'])
+	lst.extend(Utils.to_list(env['MTFLAGS']))
+	lst.extend(['-manifest',manifest])
+	lst.append('-outputresource:%s;%s'%(outfile,mode))
+	lst=[lst]
+	return self.exec_command(*lst)
+def quote_response_command(self,flag):
+	if flag.find(' ')>-1:
+		for x in('/LIBPATH:','/IMPLIB:','/OUT:','/I'):
+			if flag.startswith(x):
+				flag='%s"%s"'%(x,flag[len(x):])
+				break
+		else:
+			flag='"%s"'%flag
+	return flag
+def exec_response_command(self,cmd,**kw):
+	try:
+		tmp=None
+		if sys.platform.startswith('win')and isinstance(cmd,list)and len(' '.join(cmd))>=8192:
+			program=cmd[0]
+			cmd=[self.quote_response_command(x)for x in cmd]
+			(fd,tmp)=tempfile.mkstemp()
+			os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
+			os.close(fd)
+			cmd=[program,'@'+tmp]
+		ret=self.generator.bld.exec_command(cmd,**kw)
+	finally:
+		if tmp:
+			try:
+				os.remove(tmp)
+			except OSError:
+				pass
+	return ret
+def exec_command_msvc(self,*k,**kw):
+	if isinstance(k[0],list):
+		lst=[]
+		carry=''
+		for a in k[0]:
+			if a=='/Fo'or a=='/doc'or a[-1]==':':
+				carry=a
+			else:
+				lst.append(carry+a)
+				carry=''
+		k=[lst]
+	if self.env['PATH']:
+		env=dict(self.env.env or os.environ)
+		env.update(PATH=';'.join(self.env['PATH']))
+		kw['env']=env
+	bld=self.generator.bld
+	try:
+		if not kw.get('cwd',None):
+			kw['cwd']=bld.cwd
+	except AttributeError:
+		bld.cwd=kw['cwd']=bld.variant_dir
+	ret=self.exec_response_command(k[0],**kw)
+	if not ret and getattr(self,'do_manifest',None):
+		ret=self.exec_mf()
+	return ret
+def wrap_class(class_name):
+	cls=Task.classes.get(class_name,None)
+	if not cls:
+		return None
+	derived_class=type(class_name,(cls,),{})
+	def exec_command(self,*k,**kw):
+		if self.env['CC_NAME']=='msvc':
+			return self.exec_command_msvc(*k,**kw)
+		else:
+			return super(derived_class,self).exec_command(*k,**kw)
+	derived_class.exec_command=exec_command
+	derived_class.exec_response_command=exec_response_command
+	derived_class.quote_response_command=quote_response_command
+	derived_class.exec_command_msvc=exec_command_msvc
+	derived_class.exec_mf=exec_mf
+	return derived_class
+for k in'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split():
+	wrap_class(k)
+def make_winapp(self,family):
+	append=self.env.append_unique
+	append('DEFINES','WINAPI_FAMILY=%s'%family)
+	append('CXXFLAGS','/ZW')
+	append('CXXFLAGS','/TP')
+	for lib_path in self.env.LIBPATH:
+		append('CXXFLAGS','/AI%s'%lib_path)
+@feature('winphoneapp')
+@after_method('process_use')
+@after_method('propagate_uselib_vars')
+def make_winphone_app(self):
+	make_winapp(self,'WINAPI_FAMILY_PHONE_APP')
+	conf.env.append_unique('LINKFLAGS','/NODEFAULTLIB:ole32.lib')
+	conf.env.append_unique('LINKFLAGS','PhoneAppModelHost.lib')
+@feature('winapp')
+@after_method('process_use')
+@after_method('propagate_uselib_vars')
+def make_windows_app(self):
+	make_winapp(self,'WINAPI_FAMILY_DESKTOP_APP')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/nasm.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/nasm.py
new file mode 100644
index 0000000..e3126dd
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/nasm.py
@@ -0,0 +1,14 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import waflib.Tools.asm
+from waflib.TaskGen import feature
+@feature('asm')
+def apply_nasm_vars(self):
+	self.env.append_value('ASFLAGS',self.to_list(getattr(self,'nasm_flags',[])))
+def configure(conf):
+	nasm=conf.find_program(['nasm','yasm'],var='AS')
+	conf.env.AS_TGT_F=['-o']
+	conf.env.ASLNK_TGT_F=['-o']
+	conf.load('asm')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/perl.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/perl.py
new file mode 100644
index 0000000..8b6c2f8
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/perl.py
@@ -0,0 +1,80 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Task,Options,Utils
+from waflib.Configure import conf
+from waflib.TaskGen import extension,feature,before_method
+@before_method('apply_incpaths','apply_link','propagate_uselib_vars')
+@feature('perlext')
+def init_perlext(self):
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	if not'PERLEXT'in self.uselib:self.uselib.append('PERLEXT')
+	self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['perlext_PATTERN']
+@extension('.xs')
+def xsubpp_file(self,node):
+	outnode=node.change_ext('.c')
+	self.create_task('xsubpp',node,outnode)
+	self.source.append(outnode)
+class xsubpp(Task.Task):
+	run_str='${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}'
+	color='BLUE'
+	ext_out=['.h']
+@conf
+def check_perl_version(self,minver=None):
+	res=True
+	if minver:
+		cver='.'.join(map(str,minver))
+	else:
+		cver=''
+	self.start_msg('Checking for minimum perl version %s'%cver)
+	perl=getattr(Options.options,'perlbinary',None)
+	if not perl:
+		perl=self.find_program('perl',var='PERL')
+	if not perl:
+		self.end_msg("Perl not found",color="YELLOW")
+		return False
+	self.env['PERL']=perl
+	version=self.cmd_and_log([perl,"-e",'printf \"%vd\", $^V'])
+	if not version:
+		res=False
+		version="Unknown"
+	elif not minver is None:
+		ver=tuple(map(int,version.split(".")))
+		if ver<minver:
+			res=False
+	self.end_msg(version,color=res and"GREEN"or"YELLOW")
+	return res
+@conf
+def check_perl_module(self,module):
+	cmd=[self.env['PERL'],'-e','use %s'%module]
+	self.start_msg('perl module %s'%module)
+	try:
+		r=self.cmd_and_log(cmd)
+	except Exception:
+		self.end_msg(False)
+		return None
+	self.end_msg(r or True)
+	return r
+@conf
+def check_perl_ext_devel(self):
+	env=self.env
+	perl=env.PERL
+	if not perl:
+		self.fatal('find perl first')
+	def read_out(cmd):
+		return Utils.to_list(self.cmd_and_log(perl+cmd))
+	env['LINKFLAGS_PERLEXT']=read_out(" -MConfig -e'print $Config{lddlflags}'")
+	env['INCLUDES_PERLEXT']=read_out(" -MConfig -e'print \"$Config{archlib}/CORE\"'")
+	env['CFLAGS_PERLEXT']=read_out(" -MConfig -e'print \"$Config{ccflags} $Config{cccdlflags}\"'")
+	env['XSUBPP']=read_out(" -MConfig -e'print \"$Config{privlib}/ExtUtils/xsubpp$Config{exe_ext}\"'")
+	env['EXTUTILS_TYPEMAP']=read_out(" -MConfig -e'print \"$Config{privlib}/ExtUtils/typemap\"'")
+	if not getattr(Options.options,'perlarchdir',None):
+		env['ARCHDIR_PERL']=self.cmd_and_log(perl+" -MConfig -e'print $Config{sitearch}'")
+	else:
+		env['ARCHDIR_PERL']=getattr(Options.options,'perlarchdir')
+	env['perlext_PATTERN']='%s.'+self.cmd_and_log(perl+" -MConfig -e'print $Config{dlext}'")
+def options(opt):
+	opt.add_option('--with-perl-binary',type='string',dest='perlbinary',help='Specify alternate perl binary',default=None)
+	opt.add_option('--with-perl-archdir',type='string',dest='perlarchdir',help='Specify directory where to install arch specific files',default=None)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/python.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/python.py
new file mode 100644
index 0000000..da5f982
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/python.py
@@ -0,0 +1,351 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Utils,Options,Errors,Logs
+from waflib.TaskGen import extension,before_method,after_method,feature
+from waflib.Configure import conf
+FRAG='''
+#include <Python.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+	void Py_Initialize(void);
+	void Py_Finalize(void);
+#ifdef __cplusplus
+}
+#endif
+int main(int argc, char **argv)
+{
+   (void)argc; (void)argv;
+   Py_Initialize();
+   Py_Finalize();
+   return 0;
+}
+'''
+INST='''
+import sys, py_compile
+py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3])
+'''
+DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib']
+@extension('.py')
+def process_py(self,node):
+	try:
+		if not self.bld.is_install:
+			return
+	except AttributeError:
+		return
+	try:
+		if not self.install_path:
+			return
+	except AttributeError:
+		self.install_path='${PYTHONDIR}'
+	def inst_py(ctx):
+		install_from=getattr(self,'install_from',None)
+		if install_from:
+			install_from=self.path.find_dir(install_from)
+		install_pyfile(self,node,install_from)
+	self.bld.add_post_fun(inst_py)
+def install_pyfile(self,node,install_from=None):
+	from_node=install_from or node.parent
+	tsk=self.bld.install_as(self.install_path+'/'+node.path_from(from_node),node,postpone=False)
+	path=tsk.get_install_path()
+	if self.bld.is_install<0:
+		Logs.info("+ removing byte compiled python files")
+		for x in'co':
+			try:
+				os.remove(path+x)
+			except OSError:
+				pass
+	if self.bld.is_install>0:
+		try:
+			st1=os.stat(path)
+		except OSError:
+			Logs.error('The python file is missing, this should not happen')
+		for x in['c','o']:
+			do_inst=self.env['PY'+x.upper()]
+			try:
+				st2=os.stat(path+x)
+			except OSError:
+				pass
+			else:
+				if st1.st_mtime<=st2.st_mtime:
+					do_inst=False
+			if do_inst:
+				lst=(x=='o')and[self.env['PYFLAGS_OPT']]or[]
+				(a,b,c)=(path,path+x,tsk.get_install_path(destdir=False)+x)
+				argv=self.env['PYTHON']+lst+['-c',INST,a,b,c]
+				Logs.info('+ byte compiling %r'%(path+x))
+				env=self.env.env or None
+				ret=Utils.subprocess.Popen(argv,env=env).wait()
+				if ret:
+					raise Errors.WafError('py%s compilation failed %r'%(x,path))
+@feature('py')
+def feature_py(self):
+	pass
+@feature('pyext')
+@before_method('propagate_uselib_vars','apply_link')
+@after_method('apply_bundle')
+def init_pyext(self):
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	if not'PYEXT'in self.uselib:
+		self.uselib.append('PYEXT')
+	self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN=self.env.pyext_PATTERN
+	self.env.fcshlib_PATTERN=self.env.dshlib_PATTERN=self.env.pyext_PATTERN
+	try:
+		if not self.install_path:
+			return
+	except AttributeError:
+		self.install_path='${PYTHONARCHDIR}'
+@feature('pyext')
+@before_method('apply_link','apply_bundle')
+def set_bundle(self):
+	if Utils.unversioned_sys_platform()=='darwin':
+		self.mac_bundle=True
+@before_method('propagate_uselib_vars')
+@feature('pyembed')
+def init_pyembed(self):
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	if not'PYEMBED'in self.uselib:
+		self.uselib.append('PYEMBED')
+@conf
+def get_python_variables(self,variables,imports=None):
+	if not imports:
+		try:
+			imports=self.python_imports
+		except AttributeError:
+			imports=DISTUTILS_IMP
+	program=list(imports)
+	program.append('')
+	for v in variables:
+		program.append("print(repr(%s))"%v)
+	os_env=dict(os.environ)
+	try:
+		del os_env['MACOSX_DEPLOYMENT_TARGET']
+	except KeyError:
+		pass
+	try:
+		out=self.cmd_and_log(self.env.PYTHON+['-c','\n'.join(program)],env=os_env)
+	except Errors.WafError:
+		self.fatal('The distutils module is unusable: install "python-devel"?')
+	self.to_log(out)
+	return_values=[]
+	for s in out.split('\n'):
+		s=s.strip()
+		if not s:
+			continue
+		if s=='None':
+			return_values.append(None)
+		elif(s[0]=="'"and s[-1]=="'")or(s[0]=='"'and s[-1]=='"'):
+			return_values.append(eval(s))
+		elif s[0].isdigit():
+			return_values.append(int(s))
+		else:break
+	return return_values
+@conf
+def check_python_headers(conf):
+	env=conf.env
+	if not env['CC_NAME']and not env['CXX_NAME']:
+		conf.fatal('load a compiler first (gcc, g++, ..)')
+	if not env['PYTHON_VERSION']:
+		conf.check_python_version()
+	pybin=conf.env.PYTHON
+	if not pybin:
+		conf.fatal('Could not find the python executable')
+	v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS'.split()
+	try:
+		lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v])
+	except RuntimeError:
+		conf.fatal("Python development headers not found (-v for details).")
+	vals=['%s = %r'%(x,y)for(x,y)in zip(v,lst)]
+	conf.to_log("Configuration returned from %r:\n%r\n"%(pybin,'\n'.join(vals)))
+	dct=dict(zip(v,lst))
+	x='MACOSX_DEPLOYMENT_TARGET'
+	if dct[x]:
+		conf.env[x]=conf.environ[x]=dct[x]
+	env['pyext_PATTERN']='%s'+dct['SO']
+	all_flags=dct['LDFLAGS']+' '+dct['CFLAGS']
+	conf.parse_flags(all_flags,'PYEMBED')
+	all_flags=dct['LDFLAGS']+' '+dct['LDSHARED']+' '+dct['CFLAGS']
+	conf.parse_flags(all_flags,'PYEXT')
+	result=None
+	for name in('python'+env['PYTHON_VERSION'],'python'+env['PYTHON_VERSION']+'m','python'+env['PYTHON_VERSION'].replace('.','')):
+		if not result and env['LIBPATH_PYEMBED']:
+			path=env['LIBPATH_PYEMBED']
+			conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path)
+			result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBPATH_PYEMBED'%name)
+		if not result and dct['LIBDIR']:
+			path=[dct['LIBDIR']]
+			conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n"%path)
+			result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBDIR'%name)
+		if not result and dct['LIBPL']:
+			path=[dct['LIBPL']]
+			conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
+			result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in python_LIBPL'%name)
+		if not result:
+			path=[os.path.join(dct['prefix'],"libs")]
+			conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
+			result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in $prefix/libs'%name)
+		if result:
+			break
+	if result:
+		env['LIBPATH_PYEMBED']=path
+		env.append_value('LIB_PYEMBED',[name])
+	else:
+		conf.to_log("\n\n### LIB NOT FOUND\n")
+	if(Utils.is_win32 or sys.platform.startswith('os2')or dct['Py_ENABLE_SHARED']):
+		env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED']
+		env['LIB_PYEXT']=env['LIB_PYEMBED']
+	num='.'.join(env['PYTHON_VERSION'].split('.')[:2])
+	conf.find_program([''.join(pybin)+'-config','python%s-config'%num,'python-config-%s'%num,'python%sm-config'%num],var='PYTHON_CONFIG',display_name="python-config",mandatory=False)
+	includes=[]
+	if conf.env.PYTHON_CONFIG:
+		for incstr in conf.cmd_and_log([conf.env.PYTHON_CONFIG,'--includes']).strip().split():
+			if(incstr.startswith('-I')or incstr.startswith('/I')):
+				incstr=incstr[2:]
+			if incstr not in includes:
+				includes.append(incstr)
+		conf.to_log("Include path for Python extensions (found via python-config --includes): %r\n"%(includes,))
+		env['INCLUDES_PYEXT']=includes
+		env['INCLUDES_PYEMBED']=includes
+	else:
+		conf.to_log("Include path for Python extensions ""(found via distutils module): %r\n"%(dct['INCLUDEPY'],))
+		env['INCLUDES_PYEXT']=[dct['INCLUDEPY']]
+		env['INCLUDES_PYEMBED']=[dct['INCLUDEPY']]
+	if env['CC_NAME']=='gcc':
+		env.append_value('CFLAGS_PYEMBED',['-fno-strict-aliasing'])
+		env.append_value('CFLAGS_PYEXT',['-fno-strict-aliasing'])
+	if env['CXX_NAME']=='gcc':
+		env.append_value('CXXFLAGS_PYEMBED',['-fno-strict-aliasing'])
+		env.append_value('CXXFLAGS_PYEXT',['-fno-strict-aliasing'])
+	if env.CC_NAME=="msvc":
+		from distutils.msvccompiler import MSVCCompiler
+		dist_compiler=MSVCCompiler()
+		dist_compiler.initialize()
+		env.append_value('CFLAGS_PYEXT',dist_compiler.compile_options)
+		env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options)
+		env.append_value('LINKFLAGS_PYEXT',dist_compiler.ldflags_shared)
+	try:
+		conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',uselib='PYEMBED',fragment=FRAG,errmsg=':-(')
+	except conf.errors.ConfigurationError:
+		xx=conf.env.CXX_NAME and'cxx'or'c'
+		flags=['--cflags','--libs','--ldflags']
+		for f in flags:
+			conf.check_cfg(msg='Asking python-config for pyembed %s flags'%f,path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=[f])
+		conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',msg='Getting pyembed flags from python-config',fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(xx,xx))
+		for f in flags:
+			conf.check_cfg(msg='Asking python-config for pyext %s flags'%f,path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=[f])
+		conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',msg='Getting pyext flags from python-config',features='%s %sshlib pyext'%(xx,xx),fragment=FRAG,errmsg='Could not build python extensions')
+@conf
+def check_python_version(conf,minver=None):
+	assert minver is None or isinstance(minver,tuple)
+	pybin=conf.env['PYTHON']
+	if not pybin:
+		conf.fatal('could not find the python executable')
+	cmd=pybin+['-c','import sys\nfor x in sys.version_info: print(str(x))']
+	Logs.debug('python: Running python command %r'%cmd)
+	lines=conf.cmd_and_log(cmd).split()
+	assert len(lines)==5,"found %i lines, expected 5: %r"%(len(lines),lines)
+	pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4]))
+	result=(minver is None)or(pyver_tuple>=minver)
+	if result:
+		pyver='.'.join([str(x)for x in pyver_tuple[:2]])
+		conf.env['PYTHON_VERSION']=pyver
+		if'PYTHONDIR'in conf.environ:
+			pydir=conf.environ['PYTHONDIR']
+		else:
+			if Utils.is_win32:
+				(python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0) or ''"])
+			else:
+				python_LIBDEST=None
+				(pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0) or ''"])
+			if python_LIBDEST is None:
+				if conf.env['LIBDIR']:
+					python_LIBDEST=os.path.join(conf.env['LIBDIR'],"python"+pyver)
+				else:
+					python_LIBDEST=os.path.join(conf.env['PREFIX'],"lib","python"+pyver)
+		if'PYTHONARCHDIR'in conf.environ:
+			pyarchdir=conf.environ['PYTHONARCHDIR']
+		else:
+			(pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0) or ''"])
+			if not pyarchdir:
+				pyarchdir=pydir
+		if hasattr(conf,'define'):
+			conf.define('PYTHONDIR',pydir)
+			conf.define('PYTHONARCHDIR',pyarchdir)
+		conf.env['PYTHONDIR']=pydir
+		conf.env['PYTHONARCHDIR']=pyarchdir
+	pyver_full='.'.join(map(str,pyver_tuple[:3]))
+	if minver is None:
+		conf.msg('Checking for python version',pyver_full)
+	else:
+		minver_str='.'.join(map(str,minver))
+		conf.msg('Checking for python version',pyver_tuple,">= %s"%(minver_str,)and'GREEN'or'YELLOW')
+	if not result:
+		conf.fatal('The python version is too old, expecting %r'%(minver,))
+PYTHON_MODULE_TEMPLATE='''
+import %s as current_module
+version = getattr(current_module, '__version__', None)
+if version is not None:
+    print(str(version))
+else:
+    print('unknown version')
+'''
+@conf
+def check_python_module(conf,module_name,condition=''):
+	msg="Checking for python module '%s'"%module_name
+	if condition:
+		msg='%s (%s)'%(msg,condition)
+	conf.start_msg(msg)
+	try:
+		ret=conf.cmd_and_log(conf.env['PYTHON']+['-c',PYTHON_MODULE_TEMPLATE%module_name])
+	except Exception:
+		conf.end_msg(False)
+		conf.fatal('Could not find the python module %r'%module_name)
+	ret=ret.strip()
+	if condition:
+		conf.end_msg(ret)
+		if ret=='unknown version':
+			conf.fatal('Could not check the %s version'%module_name)
+		from distutils.version import LooseVersion
+		def num(*k):
+			if isinstance(k[0],int):
+				return LooseVersion('.'.join([str(x)for x in k]))
+			else:
+				return LooseVersion(k[0])
+		d={'num':num,'ver':LooseVersion(ret)}
+		ev=eval(condition,{},d)
+		if not ev:
+			conf.fatal('The %s version does not satisfy the requirements'%module_name)
+	else:
+		if ret=='unknown version':
+			conf.end_msg(True)
+		else:
+			conf.end_msg(ret)
+def configure(conf):
+	v=conf.env
+	if not v['PYTHON']:
+		v['PYTHON']=getattr(Options.options,'python',None)or sys.executable
+	if not v['PYTHONDIR']and Options.options.pythondir:
+		v['PYTHONDIR']=Options.options.pythondir
+	if not v['PYTHONARCHDIR']and Options.options.pythonarchdir:
+		v['PYTHONARCHDIR']=Options.options.pythonarchdir
+	try:
+		conf.find_program('python',var='PYTHON')
+	except conf.errors.ConfigurationError:
+		Logs.warn("could not find a python executable, setting to sys.executable '%s'"%sys.executable)
+		conf.env.PYTHON=sys.executable
+	conf.env.PYTHON=conf.cmd_to_list(conf.env.PYTHON)
+	v['PYCMD']='"import sys, py_compile;py_compile.compile(sys.argv[1], sys.argv[2])"'
+	v['PYFLAGS']=''
+	v['PYFLAGS_OPT']='-O'
+	v['PYC']=getattr(Options.options,'pyc',1)
+	v['PYO']=getattr(Options.options,'pyo',1)
+def options(opt):
+	pyopt=opt.add_option_group("Python Options")
+	pyopt.add_option('--nopyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]',dest='pyc')
+	pyopt.add_option('--nopyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]',dest='pyo')
+	pyopt.add_option('--python',help='python binary to be used [Default: %s]'%sys.executable,dest="python")
+	pyopt.add_option('--pythondir',help='Installation path for python modules (py, platform-independent .py and .pyc files)',dest='pythondir')
+	pyopt.add_option('--pythonarchdir',help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)',dest='pythonarchdir')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/qt4.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/qt4.py
new file mode 100644
index 0000000..b4328e7
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/qt4.py
@@ -0,0 +1,455 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+try:
+	from xml.sax import make_parser
+	from xml.sax.handler import ContentHandler
+except ImportError:
+	has_xml=False
+	ContentHandler=object
+else:
+	has_xml=True
+import os,sys
+from waflib.Tools import c_preproc,cxx
+from waflib import Task,Utils,Options,Errors
+from waflib.TaskGen import feature,after_method,extension
+from waflib.Configure import conf
+from waflib import Logs
+MOC_H=['.h','.hpp','.hxx','.hh']
+EXT_RCC=['.qrc']
+EXT_UI=['.ui']
+EXT_QT4=['.cpp','.cc','.cxx','.C']
+QT4_LIBS="QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtXmlPatterns QtWebKit Qt3Support QtHelp QtScript QtDeclarative QtDesigner"
+class qxx(Task.classes['cxx']):
+	def __init__(self,*k,**kw):
+		Task.Task.__init__(self,*k,**kw)
+		self.moc_done=0
+	def scan(self):
+		(nodes,names)=c_preproc.scan(self)
+		lst=[]
+		for x in nodes:
+			if x.name.endswith('.moc'):
+				s=x.path_from(self.inputs[0].parent.get_bld())
+				if s not in names:
+					names.append(s)
+			else:
+				lst.append(x)
+		return(lst,names)
+	def runnable_status(self):
+		if self.moc_done:
+			return Task.Task.runnable_status(self)
+		else:
+			for t in self.run_after:
+				if not t.hasrun:
+					return Task.ASK_LATER
+			self.add_moc_tasks()
+			return Task.Task.runnable_status(self)
+	def create_moc_task(self,h_node,m_node):
+		try:
+			moc_cache=self.generator.bld.moc_cache
+		except AttributeError:
+			moc_cache=self.generator.bld.moc_cache={}
+		try:
+			return moc_cache[h_node]
+		except KeyError:
+			tsk=moc_cache[h_node]=Task.classes['moc'](env=self.env,generator=self.generator)
+			tsk.set_inputs(h_node)
+			tsk.set_outputs(m_node)
+			gen=self.generator.bld.producer
+			gen.outstanding.insert(0,tsk)
+			gen.total+=1
+			return tsk
+	def add_moc_tasks(self):
+		node=self.inputs[0]
+		bld=self.generator.bld
+		try:
+			self.signature()
+		except KeyError:
+			pass
+		else:
+			delattr(self,'cache_sig')
+		moctasks=[]
+		mocfiles=[]
+		try:
+			tmp_lst=bld.raw_deps[self.uid()]
+			bld.raw_deps[self.uid()]=[]
+		except KeyError:
+			tmp_lst=[]
+		for d in tmp_lst:
+			if not d.endswith('.moc'):
+				continue
+			if d in mocfiles:
+				Logs.error("paranoia owns")
+				continue
+			mocfiles.append(d)
+			h_node=None
+			try:ext=Options.options.qt_header_ext.split()
+			except AttributeError:pass
+			if not ext:ext=MOC_H
+			base2=d[:-4]
+			for x in[node.parent]+self.generator.includes_nodes:
+				for e in ext:
+					h_node=x.find_node(base2+e)
+					if h_node:
+						break
+				if h_node:
+					m_node=h_node.change_ext('.moc')
+					break
+			else:
+				for k in EXT_QT4:
+					if base2.endswith(k):
+						for x in[node.parent]+self.generator.includes_nodes:
+							h_node=x.find_node(base2)
+							if h_node:
+								break
+					if h_node:
+						m_node=h_node.change_ext(k+'.moc')
+						break
+			if not h_node:
+				raise Errors.WafError('no header found for %r which is a moc file'%d)
+			bld.node_deps[(self.inputs[0].parent.abspath(),m_node.name)]=h_node
+			task=self.create_moc_task(h_node,m_node)
+			moctasks.append(task)
+		tmp_lst=bld.raw_deps[self.uid()]=mocfiles
+		lst=bld.node_deps.get(self.uid(),())
+		for d in lst:
+			name=d.name
+			if name.endswith('.moc'):
+				task=self.create_moc_task(bld.node_deps[(self.inputs[0].parent.abspath(),name)],d)
+				moctasks.append(task)
+		self.run_after.update(set(moctasks))
+		self.moc_done=1
+	run=Task.classes['cxx'].__dict__['run']
+class trans_update(Task.Task):
+	run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
+	color='BLUE'
+Task.update_outputs(trans_update)
+class XMLHandler(ContentHandler):
+	def __init__(self):
+		self.buf=[]
+		self.files=[]
+	def startElement(self,name,attrs):
+		if name=='file':
+			self.buf=[]
+	def endElement(self,name):
+		if name=='file':
+			self.files.append(str(''.join(self.buf)))
+	def characters(self,cars):
+		self.buf.append(cars)
+@extension(*EXT_RCC)
+def create_rcc_task(self,node):
+	rcnode=node.change_ext('_rc.cpp')
+	rcctask=self.create_task('rcc',node,rcnode)
+	cpptask=self.create_task('cxx',rcnode,rcnode.change_ext('.o'))
+	try:
+		self.compiled_tasks.append(cpptask)
+	except AttributeError:
+		self.compiled_tasks=[cpptask]
+	return cpptask
+@extension(*EXT_UI)
+def create_uic_task(self,node):
+	uictask=self.create_task('ui4',node)
+	uictask.outputs=[self.path.find_or_declare(self.env['ui_PATTERN']%node.name[:-3])]
+@extension('.ts')
+def add_lang(self,node):
+	self.lang=self.to_list(getattr(self,'lang',[]))+[node]
+@feature('qt4')
+@after_method('apply_link')
+def apply_qt4(self):
+	if getattr(self,'lang',None):
+		qmtasks=[]
+		for x in self.to_list(self.lang):
+			if isinstance(x,str):
+				x=self.path.find_resource(x+'.ts')
+			qmtasks.append(self.create_task('ts2qm',x,x.change_ext('.qm')))
+		if getattr(self,'update',None)and Options.options.trans_qt4:
+			cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if getattr(a,'inputs',None)and a.inputs[0].name.endswith('.ui')]
+			for x in qmtasks:
+				self.create_task('trans_update',cxxnodes,x.inputs)
+		if getattr(self,'langname',None):
+			qmnodes=[x.outputs[0]for x in qmtasks]
+			rcnode=self.langname
+			if isinstance(rcnode,str):
+				rcnode=self.path.find_or_declare(rcnode+'.qrc')
+			t=self.create_task('qm2rcc',qmnodes,rcnode)
+			k=create_rcc_task(self,t.outputs[0])
+			self.link_task.inputs.append(k.outputs[0])
+	lst=[]
+	for flag in self.to_list(self.env['CXXFLAGS']):
+		if len(flag)<2:continue
+		f=flag[0:2]
+		if f in['-D','-I','/D','/I']:
+			if(f[0]=='/'):
+				lst.append('-'+flag[1:])
+			else:
+				lst.append(flag)
+	self.env.append_value('MOC_FLAGS',lst)
+@extension(*EXT_QT4)
+def cxx_hook(self,node):
+	return self.create_compiled_task('qxx',node)
+class rcc(Task.Task):
+	color='BLUE'
+	run_str='${QT_RCC} -name ${SRC[0].name} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
+	ext_out=['.h']
+	def scan(self):
+		node=self.inputs[0]
+		if not has_xml:
+			Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
+			return([],[])
+		parser=make_parser()
+		curHandler=XMLHandler()
+		parser.setContentHandler(curHandler)
+		fi=open(self.inputs[0].abspath(),'r')
+		try:
+			parser.parse(fi)
+		finally:
+			fi.close()
+		nodes=[]
+		names=[]
+		root=self.inputs[0].parent
+		for x in curHandler.files:
+			nd=root.find_resource(x)
+			if nd:nodes.append(nd)
+			else:names.append(x)
+		return(nodes,names)
+class moc(Task.Task):
+	color='BLUE'
+	run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
+class ui4(Task.Task):
+	color='BLUE'
+	run_str='${QT_UIC} ${SRC} -o ${TGT}'
+	ext_out=['.h']
+class ts2qm(Task.Task):
+	color='BLUE'
+	run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
+class qm2rcc(Task.Task):
+	color='BLUE'
+	after='ts2qm'
+	def run(self):
+		txt='\n'.join(['<file>%s</file>'%k.path_from(self.outputs[0].parent)for k in self.inputs])
+		code='<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>'%txt
+		self.outputs[0].write(code)
+def configure(self):
+	self.find_qt4_binaries()
+	self.set_qt4_libs_to_check()
+	self.set_qt4_defines()
+	self.find_qt4_libraries()
+	self.add_qt4_rpath()
+	self.simplify_qt4_libs()
+@conf
+def find_qt4_binaries(self):
+	env=self.env
+	opt=Options.options
+	qtdir=getattr(opt,'qtdir','')
+	qtbin=getattr(opt,'qtbin','')
+	paths=[]
+	if qtdir:
+		qtbin=os.path.join(qtdir,'bin')
+	if not qtdir:
+		qtdir=os.environ.get('QT4_ROOT','')
+		qtbin=os.environ.get('QT4_BIN',None)or os.path.join(qtdir,'bin')
+	if qtbin:
+		paths=[qtbin]
+	if not qtdir:
+		paths=os.environ.get('PATH','').split(os.pathsep)
+		paths.append('/usr/share/qt4/bin/')
+		try:
+			lst=Utils.listdir('/usr/local/Trolltech/')
+		except OSError:
+			pass
+		else:
+			if lst:
+				lst.sort()
+				lst.reverse()
+				qtdir='/usr/local/Trolltech/%s/'%lst[0]
+				qtbin=os.path.join(qtdir,'bin')
+				paths.append(qtbin)
+	cand=None
+	prev_ver=['4','0','0']
+	for qmk in['qmake-qt4','qmake4','qmake']:
+		try:
+			qmake=self.find_program(qmk,path_list=paths)
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			try:
+				version=self.cmd_and_log([qmake,'-query','QT_VERSION']).strip()
+			except self.errors.WafError:
+				pass
+			else:
+				if version:
+					new_ver=version.split('.')
+					if new_ver>prev_ver:
+						cand=qmake
+						prev_ver=new_ver
+	if cand:
+		self.env.QMAKE=cand
+	else:
+		self.fatal('Could not find qmake for qt4')
+	qtbin=self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_BINS']).strip()+os.sep
+	def find_bin(lst,var):
+		if var in env:
+			return
+		for f in lst:
+			try:
+				ret=self.find_program(f,path_list=paths)
+			except self.errors.ConfigurationError:
+				pass
+			else:
+				env[var]=ret
+				break
+	find_bin(['uic-qt3','uic3'],'QT_UIC3')
+	find_bin(['uic-qt4','uic'],'QT_UIC')
+	if not env['QT_UIC']:
+		self.fatal('cannot find the uic compiler for qt4')
+	try:
+		uicver=self.cmd_and_log(env['QT_UIC']+" -version 2>&1").strip()
+	except self.errors.ConfigurationError:
+		self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
+	uicver=uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt','')
+	self.msg('Checking for uic version','%s'%uicver)
+	if uicver.find(' 3.')!=-1:
+		self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
+	find_bin(['moc-qt4','moc'],'QT_MOC')
+	find_bin(['rcc'],'QT_RCC')
+	find_bin(['lrelease-qt4','lrelease'],'QT_LRELEASE')
+	find_bin(['lupdate-qt4','lupdate'],'QT_LUPDATE')
+	env['UIC3_ST']='%s -o %s'
+	env['UIC_ST']='%s -o %s'
+	env['MOC_ST']='-o'
+	env['ui_PATTERN']='ui_%s.h'
+	env['QT_LRELEASE_FLAGS']=['-silent']
+	env.MOCCPPPATH_ST='-I%s'
+	env.MOCDEFINES_ST='-D%s'
+@conf
+def find_qt4_libraries(self):
+	qtlibs=getattr(Options.options,'qtlibs',None)or os.environ.get("QT4_LIBDIR",None)
+	if not qtlibs:
+		try:
+			qtlibs=self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_LIBS']).strip()
+		except Errors.WafError:
+			qtdir=self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_PREFIX']).strip()+os.sep
+			qtlibs=os.path.join(qtdir,'lib')
+	self.msg('Found the Qt4 libraries in',qtlibs)
+	qtincludes=os.environ.get("QT4_INCLUDES",None)or self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_HEADERS']).strip()
+	env=self.env
+	if not'PKG_CONFIG_PATH'in os.environ:
+		os.environ['PKG_CONFIG_PATH']='%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib'%(qtlibs,qtlibs)
+	try:
+		if os.environ.get("QT4_XCOMPILE",None):
+			raise self.errors.ConfigurationError()
+		self.check_cfg(atleast_pkgconfig_version='0.1')
+	except self.errors.ConfigurationError:
+		for i in self.qt4_vars:
+			uselib=i.upper()
+			if Utils.unversioned_sys_platform()=="darwin":
+				frameworkName=i+".framework"
+				qtDynamicLib=os.path.join(qtlibs,frameworkName,i)
+				if os.path.exists(qtDynamicLib):
+					env.append_unique('FRAMEWORK_'+uselib,i)
+					self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
+				else:
+					self.msg('Checking for %s'%i,False,'YELLOW')
+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtlibs,frameworkName,'Headers'))
+			elif env.DEST_OS!="win32":
+				qtDynamicLib=os.path.join(qtlibs,"lib"+i+".so")
+				qtStaticLib=os.path.join(qtlibs,"lib"+i+".a")
+				if os.path.exists(qtDynamicLib):
+					env.append_unique('LIB_'+uselib,i)
+					self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
+				elif os.path.exists(qtStaticLib):
+					env.append_unique('LIB_'+uselib,i)
+					self.msg('Checking for %s'%i,qtStaticLib,'GREEN')
+				else:
+					self.msg('Checking for %s'%i,False,'YELLOW')
+				env.append_unique('LIBPATH_'+uselib,qtlibs)
+				env.append_unique('INCLUDES_'+uselib,qtincludes)
+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+			else:
+				for k in("lib%s.a","lib%s4.a","%s.lib","%s4.lib"):
+					lib=os.path.join(qtlibs,k%i)
+					if os.path.exists(lib):
+						env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
+						self.msg('Checking for %s'%i,lib,'GREEN')
+						break
+				else:
+					self.msg('Checking for %s'%i,False,'YELLOW')
+				env.append_unique('LIBPATH_'+uselib,qtlibs)
+				env.append_unique('INCLUDES_'+uselib,qtincludes)
+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+				uselib=i.upper()+"_debug"
+				for k in("lib%sd.a","lib%sd4.a","%sd.lib","%sd4.lib"):
+					lib=os.path.join(qtlibs,k%i)
+					if os.path.exists(lib):
+						env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
+						self.msg('Checking for %s'%i,lib,'GREEN')
+						break
+				else:
+					self.msg('Checking for %s'%i,False,'YELLOW')
+				env.append_unique('LIBPATH_'+uselib,qtlibs)
+				env.append_unique('INCLUDES_'+uselib,qtincludes)
+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+	else:
+		for i in self.qt4_vars_debug+self.qt4_vars:
+			self.check_cfg(package=i,args='--cflags --libs',mandatory=False)
+@conf
+def simplify_qt4_libs(self):
+	env=self.env
+	def process_lib(vars_,coreval):
+		for d in vars_:
+			var=d.upper()
+			if var=='QTCORE':
+				continue
+			value=env['LIBPATH_'+var]
+			if value:
+				core=env[coreval]
+				accu=[]
+				for lib in value:
+					if lib in core:
+						continue
+					accu.append(lib)
+				env['LIBPATH_'+var]=accu
+	process_lib(self.qt4_vars,'LIBPATH_QTCORE')
+	process_lib(self.qt4_vars_debug,'LIBPATH_QTCORE_DEBUG')
+@conf
+def add_qt4_rpath(self):
+	env=self.env
+	if getattr(Options.options,'want_rpath',False):
+		def process_rpath(vars_,coreval):
+			for d in vars_:
+				var=d.upper()
+				value=env['LIBPATH_'+var]
+				if value:
+					core=env[coreval]
+					accu=[]
+					for lib in value:
+						if var!='QTCORE':
+							if lib in core:
+								continue
+						accu.append('-Wl,--rpath='+lib)
+					env['RPATH_'+var]=accu
+		process_rpath(self.qt4_vars,'LIBPATH_QTCORE')
+		process_rpath(self.qt4_vars_debug,'LIBPATH_QTCORE_DEBUG')
+@conf
+def set_qt4_libs_to_check(self):
+	if not hasattr(self,'qt4_vars'):
+		self.qt4_vars=QT4_LIBS
+	self.qt4_vars=Utils.to_list(self.qt4_vars)
+	if not hasattr(self,'qt4_vars_debug'):
+		self.qt4_vars_debug=[a+'_debug'for a in self.qt4_vars]
+	self.qt4_vars_debug=Utils.to_list(self.qt4_vars_debug)
+@conf
+def set_qt4_defines(self):
+	if sys.platform!='win32':
+		return
+	for x in self.qt4_vars:
+		y=x[2:].upper()
+		self.env.append_unique('DEFINES_%s'%x.upper(),'QT_%s_LIB'%y)
+		self.env.append_unique('DEFINES_%s_DEBUG'%x.upper(),'QT_%s_LIB'%y)
+def options(opt):
+	opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries')
+	opt.add_option('--header-ext',type='string',default='',help='header extension for moc files',dest='qt_header_ext')
+	for i in'qtdir qtbin qtlibs'.split():
+		opt.add_option('--'+i,type='string',default='',dest=i)
+	opt.add_option('--translate',action="store_true",help="collect translation strings",dest="trans_qt4",default=False)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ruby.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ruby.py
new file mode 100644
index 0000000..04cddfb
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ruby.py
@@ -0,0 +1,103 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Task,Options,Utils
+from waflib.TaskGen import before_method,feature,after_method,Task,extension
+from waflib.Configure import conf
+@feature('rubyext')
+@before_method('apply_incpaths','apply_lib_vars','apply_bundle','apply_link')
+def init_rubyext(self):
+	self.install_path='${ARCHDIR_RUBY}'
+	self.uselib=self.to_list(getattr(self,'uselib',''))
+	if not'RUBY'in self.uselib:
+		self.uselib.append('RUBY')
+	if not'RUBYEXT'in self.uselib:
+		self.uselib.append('RUBYEXT')
+@feature('rubyext')
+@before_method('apply_link','propagate_uselib')
+def apply_ruby_so_name(self):
+	self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['rubyext_PATTERN']
+@conf
+def check_ruby_version(self,minver=()):
+	if Options.options.rubybinary:
+		self.env.RUBY=Options.options.rubybinary
+	else:
+		self.find_program('ruby',var='RUBY')
+	ruby=self.env.RUBY
+	try:
+		version=self.cmd_and_log([ruby,'-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
+	except Exception:
+		self.fatal('could not determine ruby version')
+	self.env.RUBY_VERSION=version
+	try:
+		ver=tuple(map(int,version.split(".")))
+	except Exception:
+		self.fatal('unsupported ruby version %r'%version)
+	cver=''
+	if minver:
+		if ver<minver:
+			self.fatal('ruby is too old %r'%ver)
+		cver='.'.join([str(x)for x in minver])
+	else:
+		cver=ver
+	self.msg('Checking for ruby version %s'%str(minver or''),cver)
+@conf
+def check_ruby_ext_devel(self):
+	if not self.env.RUBY:
+		self.fatal('ruby detection is required first')
+	if not self.env.CC_NAME and not self.env.CXX_NAME:
+		self.fatal('load a c/c++ compiler first')
+	version=tuple(map(int,self.env.RUBY_VERSION.split(".")))
+	def read_out(cmd):
+		return Utils.to_list(self.cmd_and_log([self.env.RUBY,'-rrbconfig','-e',cmd]))
+	def read_config(key):
+		return read_out('puts Config::CONFIG[%r]'%key)
+	ruby=self.env['RUBY']
+	archdir=read_config('archdir')
+	cpppath=archdir
+	if version>=(1,9,0):
+		ruby_hdrdir=read_config('rubyhdrdir')
+		cpppath+=ruby_hdrdir
+		cpppath+=[os.path.join(ruby_hdrdir[0],read_config('arch')[0])]
+	self.check(header_name='ruby.h',includes=cpppath,errmsg='could not find ruby header file')
+	self.env.LIBPATH_RUBYEXT=read_config('libdir')
+	self.env.LIBPATH_RUBYEXT+=archdir
+	self.env.INCLUDES_RUBYEXT=cpppath
+	self.env.CFLAGS_RUBYEXT=read_config('CCDLFLAGS')
+	self.env.rubyext_PATTERN='%s.'+read_config('DLEXT')[0]
+	flags=read_config('LDSHARED')
+	while flags and flags[0][0]!='-':
+		flags=flags[1:]
+	if len(flags)>1 and flags[1]=="ppc":
+		flags=flags[2:]
+	self.env.LINKFLAGS_RUBYEXT=flags
+	self.env.LINKFLAGS_RUBYEXT+=read_config('LIBS')
+	self.env.LINKFLAGS_RUBYEXT+=read_config('LIBRUBYARG_SHARED')
+	if Options.options.rubyarchdir:
+		self.env.ARCHDIR_RUBY=Options.options.rubyarchdir
+	else:
+		self.env.ARCHDIR_RUBY=read_config('sitearchdir')[0]
+	if Options.options.rubylibdir:
+		self.env.LIBDIR_RUBY=Options.options.rubylibdir
+	else:
+		self.env.LIBDIR_RUBY=read_config('sitelibdir')[0]
+@conf
+def check_ruby_module(self,module_name):
+	self.start_msg('Ruby module %s'%module_name)
+	try:
+		self.cmd_and_log([self.env['RUBY'],'-e','require \'%s\';puts 1'%module_name])
+	except Exception:
+		self.end_msg(False)
+		self.fatal('Could not find the ruby module %r'%module_name)
+	self.end_msg(True)
+@extension('.rb')
+def process(self,node):
+	tsk=self.create_task('run_ruby',node)
+class run_ruby(Task.Task):
+	run_str='${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}'
+def options(opt):
+	opt.add_option('--with-ruby-archdir',type='string',dest='rubyarchdir',help='Specify directory where to install arch specific files')
+	opt.add_option('--with-ruby-libdir',type='string',dest='rubylibdir',help='Specify alternate ruby library path')
+	opt.add_option('--with-ruby-binary',type='string',dest='rubybinary',help='Specify alternate ruby binary')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncc.py
new file mode 100644
index 0000000..edd24cd
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncc.py
@@ -0,0 +1,53 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_scc(conf):
+	v=conf.env
+	cc=None
+	if v['CC']:cc=v['CC']
+	elif'CC'in conf.environ:cc=conf.environ['CC']
+	if not cc:cc=conf.find_program('cc',var='CC')
+	if not cc:conf.fatal('Could not find a Sun C compiler')
+	cc=conf.cmd_to_list(cc)
+	try:
+		conf.cmd_and_log(cc+['-flags'])
+	except Exception:
+		conf.fatal('%r is not a Sun compiler'%cc)
+	v['CC']=cc
+	v['CC_NAME']='sun'
+@conf
+def scc_common_flags(conf):
+	v=conf.env
+	v['CC_SRC_F']=[]
+	v['CC_TGT_F']=['-c','-o']
+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
+	v['CCLNK_SRC_F']=''
+	v['CCLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['SONAME_ST']='-Wl,-h,%s'
+	v['SHLIB_MARKER']='-Bdynamic'
+	v['STLIB_MARKER']='-Bstatic'
+	v['cprogram_PATTERN']='%s'
+	v['CFLAGS_cshlib']=['-Kpic','-DPIC']
+	v['LINKFLAGS_cshlib']=['-G']
+	v['cshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cstlib']=['-Bstatic']
+	v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+	conf.find_scc()
+	conf.find_ar()
+	conf.scc_common_flags()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncxx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncxx.py
new file mode 100644
index 0000000..4b8b931
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncxx.py
@@ -0,0 +1,54 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_sxx(conf):
+	v=conf.env
+	cc=None
+	if v['CXX']:cc=v['CXX']
+	elif'CXX'in conf.environ:cc=conf.environ['CXX']
+	if not cc:cc=conf.find_program('CC',var='CXX')
+	if not cc:cc=conf.find_program('c++',var='CXX')
+	if not cc:conf.fatal('Could not find a Sun C++ compiler')
+	cc=conf.cmd_to_list(cc)
+	try:
+		conf.cmd_and_log(cc+['-flags'])
+	except Exception:
+		conf.fatal('%r is not a Sun compiler'%cc)
+	v['CXX']=cc
+	v['CXX_NAME']='sun'
+@conf
+def sxx_common_flags(conf):
+	v=conf.env
+	v['CXX_SRC_F']=[]
+	v['CXX_TGT_F']=['-c','-o']
+	if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+	v['CXXLNK_SRC_F']=[]
+	v['CXXLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['SONAME_ST']='-Wl,-h,%s'
+	v['SHLIB_MARKER']='-Bdynamic'
+	v['STLIB_MARKER']='-Bstatic'
+	v['cxxprogram_PATTERN']='%s'
+	v['CXXFLAGS_cxxshlib']=['-Kpic','-DPIC']
+	v['LINKFLAGS_cxxshlib']=['-G']
+	v['cxxshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cxxstlib']=['-Bstatic']
+	v['cxxstlib_PATTERN']='lib%s.a'
+def configure(conf):
+	conf.find_sxx()
+	conf.find_ar()
+	conf.sxx_common_flags()
+	conf.cxx_load_tools()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/tex.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/tex.py
new file mode 100644
index 0000000..6813022
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/tex.py
@@ -0,0 +1,257 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Utils,Task,Errors,Logs
+from waflib.TaskGen import feature,before_method
+re_bibunit=re.compile(r'\\(?P<type>putbib)\[(?P<file>[^\[\]]*)\]',re.M)
+def bibunitscan(self):
+	node=self.inputs[0]
+	nodes=[]
+	if not node:return nodes
+	code=node.read()
+	for match in re_bibunit.finditer(code):
+		path=match.group('file')
+		if path:
+			for k in['','.bib']:
+				Logs.debug('tex: trying %s%s'%(path,k))
+				fi=node.parent.find_resource(path+k)
+				if fi:
+					nodes.append(fi)
+			else:
+				Logs.debug('tex: could not find %s'%path)
+	Logs.debug("tex: found the following bibunit files: %s"%nodes)
+	return nodes
+exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps']
+exts_tex=['.ltx','.tex']
+re_tex=re.compile(r'\\(?P<type>include|bibliography|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
+g_bibtex_re=re.compile('bibdata',re.M)
+class tex(Task.Task):
+	bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False)
+	bibtex_fun.__doc__="""
+	Execute the program **bibtex**
+	"""
+	makeindex_fun,_=Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}',shell=False)
+	makeindex_fun.__doc__="""
+	Execute the program **makeindex**
+	"""
+	def exec_command(self,cmd,**kw):
+		bld=self.generator.bld
+		try:
+			if not kw.get('cwd',None):
+				kw['cwd']=bld.cwd
+		except AttributeError:
+			bld.cwd=kw['cwd']=bld.variant_dir
+		return Utils.subprocess.Popen(cmd,**kw).wait()
+	def scan_aux(self,node):
+		nodes=[node]
+		re_aux=re.compile(r'\\@input{(?P<file>[^{}]*)}',re.M)
+		def parse_node(node):
+			code=node.read()
+			for match in re_aux.finditer(code):
+				path=match.group('file')
+				found=node.parent.find_or_declare(path)
+				if found and found not in nodes:
+					Logs.debug('tex: found aux node '+found.abspath())
+					nodes.append(found)
+					parse_node(found)
+		parse_node(node)
+		return nodes
+	def scan(self):
+		node=self.inputs[0]
+		nodes=[]
+		names=[]
+		seen=[]
+		if not node:return(nodes,names)
+		def parse_node(node):
+			if node in seen:
+				return
+			seen.append(node)
+			code=node.read()
+			global re_tex
+			for match in re_tex.finditer(code):
+				for path in match.group('file').split(','):
+					if path:
+						add_name=True
+						found=None
+						for k in exts_deps_tex:
+							Logs.debug('tex: trying %s%s'%(path,k))
+							found=node.parent.find_resource(path+k)
+							for tsk in self.generator.tasks:
+								if not found or found in tsk.outputs:
+									break
+							else:
+								nodes.append(found)
+								add_name=False
+								for ext in exts_tex:
+									if found.name.endswith(ext):
+										parse_node(found)
+										break
+						if add_name:
+							names.append(path)
+		parse_node(node)
+		for x in nodes:
+			x.parent.get_bld().mkdir()
+		Logs.debug("tex: found the following : %s and names %s"%(nodes,names))
+		return(nodes,names)
+	def check_status(self,msg,retcode):
+		if retcode!=0:
+			raise Errors.WafError("%r command exit status %r"%(msg,retcode))
+	def bibfile(self):
+		for aux_node in self.aux_nodes:
+			try:
+				ct=aux_node.read()
+			except(OSError,IOError):
+				Logs.error('Error reading %s: %r'%aux_node.abspath())
+				continue
+			if g_bibtex_re.findall(ct):
+				Logs.warn('calling bibtex')
+				self.env.env={}
+				self.env.env.update(os.environ)
+				self.env.env.update({'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS})
+				self.env.SRCFILE=aux_node.name[:-4]
+				self.check_status('error when calling bibtex',self.bibtex_fun())
+	def bibunits(self):
+		try:
+			bibunits=bibunitscan(self)
+		except OSError:
+			Logs.error('error bibunitscan')
+		else:
+			if bibunits:
+				fn=['bu'+str(i)for i in xrange(1,len(bibunits)+1)]
+				if fn:
+					Logs.warn('calling bibtex on bibunits')
+				for f in fn:
+					self.env.env={'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS}
+					self.env.SRCFILE=f
+					self.check_status('error when calling bibtex',self.bibtex_fun())
+	def makeindex(self):
+		try:
+			idx_path=self.idx_node.abspath()
+			os.stat(idx_path)
+		except OSError:
+			Logs.warn('index file %s absent, not calling makeindex'%idx_path)
+		else:
+			Logs.warn('calling makeindex')
+			self.env.SRCFILE=self.idx_node.name
+			self.env.env={}
+			self.check_status('error when calling makeindex %s'%idx_path,self.makeindex_fun())
+	def bibtopic(self):
+		p=self.inputs[0].parent.get_bld()
+		if os.path.exists(os.path.join(p.abspath(),'btaux.aux')):
+			self.aux_nodes+=p.ant_glob('*[0-9].aux')
+	def run(self):
+		env=self.env
+		if not env['PROMPT_LATEX']:
+			env.append_value('LATEXFLAGS','-interaction=batchmode')
+			env.append_value('PDFLATEXFLAGS','-interaction=batchmode')
+			env.append_value('XELATEXFLAGS','-interaction=batchmode')
+		fun=self.texfun
+		node=self.inputs[0]
+		srcfile=node.abspath()
+		texinputs=self.env.TEXINPUTS or''
+		self.TEXINPUTS=node.parent.get_bld().abspath()+os.pathsep+node.parent.get_src().abspath()+os.pathsep+texinputs+os.pathsep
+		self.cwd=self.inputs[0].parent.get_bld().abspath()
+		Logs.warn('first pass on %s'%self.__class__.__name__)
+		self.env.env={}
+		self.env.env.update(os.environ)
+		self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
+		self.env.SRCFILE=srcfile
+		self.check_status('error when calling latex',fun())
+		self.aux_nodes=self.scan_aux(node.change_ext('.aux'))
+		self.idx_node=node.change_ext('.idx')
+		self.bibtopic()
+		self.bibfile()
+		self.bibunits()
+		self.makeindex()
+		hash=''
+		for i in range(10):
+			prev_hash=hash
+			try:
+				hashes=[Utils.h_file(x.abspath())for x in self.aux_nodes]
+				hash=Utils.h_list(hashes)
+			except(OSError,IOError):
+				Logs.error('could not read aux.h')
+				pass
+			if hash and hash==prev_hash:
+				break
+			Logs.warn('calling %s'%self.__class__.__name__)
+			self.env.env={}
+			self.env.env.update(os.environ)
+			self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
+			self.env.SRCFILE=srcfile
+			self.check_status('error when calling %s'%self.__class__.__name__,fun())
+class latex(tex):
+	texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False)
+class pdflatex(tex):
+	texfun,vars=Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}',shell=False)
+class xelatex(tex):
+	texfun,vars=Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}',shell=False)
+class dvips(Task.Task):
+	run_str='${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}'
+	color='BLUE'
+	after=['latex','pdflatex','xelatex']
+class dvipdf(Task.Task):
+	run_str='${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}'
+	color='BLUE'
+	after=['latex','pdflatex','xelatex']
+class pdf2ps(Task.Task):
+	run_str='${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}'
+	color='BLUE'
+	after=['latex','pdflatex','xelatex']
+@feature('tex')
+@before_method('process_source')
+def apply_tex(self):
+	if not getattr(self,'type',None)in['latex','pdflatex','xelatex']:
+		self.type='pdflatex'
+	tree=self.bld
+	outs=Utils.to_list(getattr(self,'outs',[]))
+	self.env['PROMPT_LATEX']=getattr(self,'prompt',1)
+	deps_lst=[]
+	if getattr(self,'deps',None):
+		deps=self.to_list(self.deps)
+		for filename in deps:
+			n=self.path.find_resource(filename)
+			if not n:
+				self.bld.fatal('Could not find %r for %r'%(filename,self))
+			if not n in deps_lst:
+				deps_lst.append(n)
+	for node in self.to_nodes(self.source):
+		if self.type=='latex':
+			task=self.create_task('latex',node,node.change_ext('.dvi'))
+		elif self.type=='pdflatex':
+			task=self.create_task('pdflatex',node,node.change_ext('.pdf'))
+		elif self.type=='xelatex':
+			task=self.create_task('xelatex',node,node.change_ext('.pdf'))
+		task.env=self.env
+		if deps_lst:
+			try:
+				lst=tree.node_deps[task.uid()]
+				for n in deps_lst:
+					if not n in lst:
+						lst.append(n)
+			except KeyError:
+				tree.node_deps[task.uid()]=deps_lst
+		v=dict(os.environ)
+		p=node.parent.abspath()+os.pathsep+self.path.abspath()+os.pathsep+self.path.get_bld().abspath()+os.pathsep+v.get('TEXINPUTS','')+os.pathsep
+		v['TEXINPUTS']=p
+		if self.type=='latex':
+			if'ps'in outs:
+				tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps'))
+				tsk.env.env=dict(v)
+			if'pdf'in outs:
+				tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf'))
+				tsk.env.env=dict(v)
+		elif self.type=='pdflatex':
+			if'ps'in outs:
+				self.create_task('pdf2ps',task.outputs,node.change_ext('.ps'))
+	self.source=[]
+def configure(self):
+	v=self.env
+	for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split():
+		try:
+			self.find_program(p,var=p.upper())
+		except self.errors.ConfigurationError:
+			pass
+	v['DVIPSFLAGS']='-Ppdf'
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/vala.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/vala.py
new file mode 100644
index 0000000..96248c1
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/vala.py
@@ -0,0 +1,201 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os.path,shutil,re
+from waflib import Context,Task,Utils,Logs,Options,Errors
+from waflib.TaskGen import extension,taskgen_method
+from waflib.Configure import conf
+class valac(Task.Task):
+	vars=["VALAC","VALAC_VERSION","VALAFLAGS"]
+	ext_out=['.h']
+	def run(self):
+		cmd=[self.env['VALAC']]+self.env['VALAFLAGS']
+		cmd.extend([a.abspath()for a in self.inputs])
+		ret=self.exec_command(cmd,cwd=self.outputs[0].parent.abspath())
+		if ret:
+			return ret
+		for x in self.outputs:
+			if id(x.parent)!=id(self.outputs[0].parent):
+				shutil.move(self.outputs[0].parent.abspath()+os.sep+x.name,x.abspath())
+		if self.generator.dump_deps_node:
+			self.generator.dump_deps_node.write('\n'.join(self.generator.packages))
+		return ret
+valac=Task.update_outputs(valac)
+@taskgen_method
+def init_vala_task(self):
+	self.profile=getattr(self,'profile','gobject')
+	if self.profile=='gobject':
+		self.uselib=Utils.to_list(getattr(self,'uselib',[]))
+		if not'GOBJECT'in self.uselib:
+			self.uselib.append('GOBJECT')
+	def addflags(flags):
+		self.env.append_value('VALAFLAGS',flags)
+	if self.profile:
+		addflags('--profile=%s'%self.profile)
+	if hasattr(self,'threading'):
+		if self.profile=='gobject':
+			if not'GTHREAD'in self.uselib:
+				self.uselib.append('GTHREAD')
+		else:
+			Logs.warn("Profile %s means no threading support"%self.profile)
+			self.threading=False
+		if self.threading:
+			addflags('--threading')
+	valatask=self.valatask
+	self.is_lib='cprogram'not in self.features
+	if self.is_lib:
+		addflags('--library=%s'%self.target)
+		h_node=self.path.find_or_declare('%s.h'%self.target)
+		valatask.outputs.append(h_node)
+		addflags('--header=%s'%h_node.name)
+		valatask.outputs.append(self.path.find_or_declare('%s.vapi'%self.target))
+		if getattr(self,'gir',None):
+			gir_node=self.path.find_or_declare('%s.gir'%self.gir)
+			addflags('--gir=%s'%gir_node.name)
+			valatask.outputs.append(gir_node)
+	self.vala_target_glib=getattr(self,'vala_target_glib',getattr(Options.options,'vala_target_glib',None))
+	if self.vala_target_glib:
+		addflags('--target-glib=%s'%self.vala_target_glib)
+	addflags(['--define=%s'%x for x in getattr(self,'vala_defines',[])])
+	packages_private=Utils.to_list(getattr(self,'packages_private',[]))
+	addflags(['--pkg=%s'%x for x in packages_private])
+	def _get_api_version():
+		api_version='1.0'
+		if hasattr(Context.g_module,'API_VERSION'):
+			version=Context.g_module.API_VERSION.split(".")
+			if version[0]=="0":
+				api_version="0."+version[1]
+			else:
+				api_version=version[0]+".0"
+		return api_version
+	self.includes=Utils.to_list(getattr(self,'includes',[]))
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	valatask.install_path=getattr(self,'install_path','')
+	valatask.vapi_path=getattr(self,'vapi_path','${DATAROOTDIR}/vala/vapi')
+	valatask.pkg_name=getattr(self,'pkg_name',self.env['PACKAGE'])
+	valatask.header_path=getattr(self,'header_path','${INCLUDEDIR}/%s-%s'%(valatask.pkg_name,_get_api_version()))
+	valatask.install_binding=getattr(self,'install_binding',True)
+	self.packages=packages=Utils.to_list(getattr(self,'packages',[]))
+	self.vapi_dirs=vapi_dirs=Utils.to_list(getattr(self,'vapi_dirs',[]))
+	includes=[]
+	if hasattr(self,'use'):
+		local_packages=Utils.to_list(self.use)[:]
+		seen=[]
+		while len(local_packages)>0:
+			package=local_packages.pop()
+			if package in seen:
+				continue
+			seen.append(package)
+			try:
+				package_obj=self.bld.get_tgen_by_name(package)
+			except Errors.WafError:
+				continue
+			package_name=package_obj.target
+			package_node=package_obj.path
+			package_dir=package_node.path_from(self.path)
+			for task in package_obj.tasks:
+				for output in task.outputs:
+					if output.name==package_name+".vapi":
+						valatask.set_run_after(task)
+						if package_name not in packages:
+							packages.append(package_name)
+						if package_dir not in vapi_dirs:
+							vapi_dirs.append(package_dir)
+						if package_dir not in includes:
+							includes.append(package_dir)
+			if hasattr(package_obj,'use'):
+				lst=self.to_list(package_obj.use)
+				lst.reverse()
+				local_packages=[pkg for pkg in lst if pkg not in seen]+local_packages
+	addflags(['--pkg=%s'%p for p in packages])
+	for vapi_dir in vapi_dirs:
+		v_node=self.path.find_dir(vapi_dir)
+		if not v_node:
+			Logs.warn('Unable to locate Vala API directory: %r'%vapi_dir)
+		else:
+			addflags('--vapidir=%s'%v_node.abspath())
+			addflags('--vapidir=%s'%v_node.get_bld().abspath())
+	self.dump_deps_node=None
+	if self.is_lib and self.packages:
+		self.dump_deps_node=self.path.find_or_declare('%s.deps'%self.target)
+		valatask.outputs.append(self.dump_deps_node)
+	self.includes.append(self.bld.srcnode.abspath())
+	self.includes.append(self.bld.bldnode.abspath())
+	for include in includes:
+		try:
+			self.includes.append(self.path.find_dir(include).abspath())
+			self.includes.append(self.path.find_dir(include).get_bld().abspath())
+		except AttributeError:
+			Logs.warn("Unable to locate include directory: '%s'"%include)
+	if self.is_lib and valatask.install_binding:
+		headers_list=[o for o in valatask.outputs if o.suffix()==".h"]
+		try:
+			self.install_vheader.source=headers_list
+		except AttributeError:
+			self.install_vheader=self.bld.install_files(valatask.header_path,headers_list,self.env)
+		vapi_list=[o for o in valatask.outputs if(o.suffix()in(".vapi",".deps"))]
+		try:
+			self.install_vapi.source=vapi_list
+		except AttributeError:
+			self.install_vapi=self.bld.install_files(valatask.vapi_path,vapi_list,self.env)
+		gir_list=[o for o in valatask.outputs if o.suffix()=='.gir']
+		try:
+			self.install_gir.source=gir_list
+		except AttributeError:
+			self.install_gir=self.bld.install_files(getattr(self,'gir_path','${DATAROOTDIR}/gir-1.0'),gir_list,self.env)
+@extension('.vala','.gs')
+def vala_file(self,node):
+	try:
+		valatask=self.valatask
+	except AttributeError:
+		valatask=self.valatask=self.create_task('valac')
+		self.init_vala_task()
+	valatask.inputs.append(node)
+	c_node=node.change_ext('.c')
+	valatask.outputs.append(c_node)
+	self.source.append(c_node)
+@conf
+def find_valac(self,valac_name,min_version):
+	valac=self.find_program(valac_name,var='VALAC')
+	try:
+		output=self.cmd_and_log(valac+' --version')
+	except Exception:
+		valac_version=None
+	else:
+		ver=re.search(r'\d+.\d+.\d+',output).group(0).split('.')
+		valac_version=tuple([int(x)for x in ver])
+	self.msg('Checking for %s version >= %r'%(valac_name,min_version),valac_version,valac_version and valac_version>=min_version)
+	if valac and valac_version<min_version:
+		self.fatal("%s version %r is too old, need >= %r"%(valac_name,valac_version,min_version))
+	self.env['VALAC_VERSION']=valac_version
+	return valac
+@conf
+def check_vala(self,min_version=(0,8,0),branch=None):
+	if not branch:
+		branch=min_version[:2]
+	try:
+		find_valac(self,'valac-%d.%d'%(branch[0],branch[1]),min_version)
+	except self.errors.ConfigurationError:
+		find_valac(self,'valac',min_version)
+@conf
+def check_vala_deps(self):
+	if not self.env['HAVE_GOBJECT']:
+		pkg_args={'package':'gobject-2.0','uselib_store':'GOBJECT','args':'--cflags --libs'}
+		if getattr(Options.options,'vala_target_glib',None):
+			pkg_args['atleast_version']=Options.options.vala_target_glib
+		self.check_cfg(**pkg_args)
+	if not self.env['HAVE_GTHREAD']:
+		pkg_args={'package':'gthread-2.0','uselib_store':'GTHREAD','args':'--cflags --libs'}
+		if getattr(Options.options,'vala_target_glib',None):
+			pkg_args['atleast_version']=Options.options.vala_target_glib
+		self.check_cfg(**pkg_args)
+def configure(self):
+	self.load('gnu_dirs')
+	self.check_vala_deps()
+	self.check_vala()
+	self.env.VALAFLAGS=['-C','--quiet']
+def options(opt):
+	opt.load('gnu_dirs')
+	valaopts=opt.add_option_group('Vala Compiler Options')
+	valaopts.add_option('--vala-target-glib',default=None,dest='vala_target_glib',metavar='MAJOR.MINOR',help='Target version of glib for Vala GObject code generation')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/waf_unit_test.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/waf_unit_test.py
new file mode 100644
index 0000000..3363172
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/waf_unit_test.py
@@ -0,0 +1,97 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.TaskGen import feature,after_method
+from waflib import Utils,Task,Logs,Options
+testlock=Utils.threading.Lock()
+@feature('test')
+@after_method('apply_link')
+def make_test(self):
+	if getattr(self,'link_task',None):
+		self.create_task('utest',self.link_task.outputs)
+class utest(Task.Task):
+	color='PINK'
+	after=['vnum','inst']
+	vars=[]
+	def runnable_status(self):
+		if getattr(Options.options,'no_tests',False):
+			return Task.SKIP_ME
+		ret=super(utest,self).runnable_status()
+		if ret==Task.SKIP_ME:
+			if getattr(Options.options,'all_tests',False):
+				return Task.RUN_ME
+		return ret
+	def run(self):
+		filename=self.inputs[0].abspath()
+		self.ut_exec=getattr(self.generator,'ut_exec',[filename])
+		if getattr(self.generator,'ut_fun',None):
+			self.generator.ut_fun(self)
+		try:
+			fu=getattr(self.generator.bld,'all_test_paths')
+		except AttributeError:
+			fu=os.environ.copy()
+			lst=[]
+			for g in self.generator.bld.groups:
+				for tg in g:
+					if getattr(tg,'link_task',None):
+						s=tg.link_task.outputs[0].parent.abspath()
+						if s not in lst:
+							lst.append(s)
+			def add_path(dct,path,var):
+				dct[var]=os.pathsep.join(Utils.to_list(path)+[os.environ.get(var,'')])
+			if Utils.is_win32:
+				add_path(fu,lst,'PATH')
+			elif Utils.unversioned_sys_platform()=='darwin':
+				add_path(fu,lst,'DYLD_LIBRARY_PATH')
+				add_path(fu,lst,'LD_LIBRARY_PATH')
+			else:
+				add_path(fu,lst,'LD_LIBRARY_PATH')
+			self.generator.bld.all_test_paths=fu
+		cwd=getattr(self.generator,'ut_cwd','')or self.inputs[0].parent.abspath()
+		testcmd=getattr(Options.options,'testcmd',False)
+		if testcmd:
+			self.ut_exec=(testcmd%self.ut_exec[0]).split(' ')
+		proc=Utils.subprocess.Popen(self.ut_exec,cwd=cwd,env=fu,stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE)
+		(stdout,stderr)=proc.communicate()
+		tup=(filename,proc.returncode,stdout,stderr)
+		self.generator.utest_result=tup
+		testlock.acquire()
+		try:
+			bld=self.generator.bld
+			Logs.debug("ut: %r",tup)
+			try:
+				bld.utest_results.append(tup)
+			except AttributeError:
+				bld.utest_results=[tup]
+		finally:
+			testlock.release()
+def summary(bld):
+	lst=getattr(bld,'utest_results',[])
+	if lst:
+		Logs.pprint('CYAN','execution summary')
+		total=len(lst)
+		tfail=len([x for x in lst if x[1]])
+		Logs.pprint('CYAN','  tests that pass %d/%d'%(total-tfail,total))
+		for(f,code,out,err)in lst:
+			if not code:
+				Logs.pprint('CYAN','    %s'%f)
+		Logs.pprint('CYAN','  tests that fail %d/%d'%(tfail,total))
+		for(f,code,out,err)in lst:
+			if code:
+				Logs.pprint('CYAN','    %s'%f)
+def set_exit_code(bld):
+	lst=getattr(bld,'utest_results',[])
+	for(f,code,out,err)in lst:
+		if code:
+			msg=[]
+			if out:
+				msg.append('stdout:%s%s'%(os.linesep,out.decode('utf-8')))
+			if err:
+				msg.append('stderr:%s%s'%(os.linesep,err.decode('utf-8')))
+			bld.fatal(os.linesep.join(msg))
+def options(opt):
+	opt.add_option('--notests',action='store_true',default=False,help='Exec no unit tests',dest='no_tests')
+	opt.add_option('--alltests',action='store_true',default=False,help='Exec all unit tests',dest='all_tests')
+	opt.add_option('--testcmd',action='store',default=False,help='Run the unit tests using the test-cmd string'' example "--test-cmd="valgrind --error-exitcode=1'' %s" to run under valgrind',dest='testcmd')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/winres.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/winres.py
new file mode 100644
index 0000000..88904af
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/winres.py
@@ -0,0 +1,85 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re,traceback
+from waflib import Task,Logs,Utils
+from waflib.TaskGen import extension
+from waflib.Tools import c_preproc
+@extension('.rc')
+def rc_file(self,node):
+	obj_ext='.rc.o'
+	if self.env['WINRC_TGT_F']=='/fo':
+		obj_ext='.res'
+	rctask=self.create_task('winrc',node,node.change_ext(obj_ext))
+	try:
+		self.compiled_tasks.append(rctask)
+	except AttributeError:
+		self.compiled_tasks=[rctask]
+re_lines=re.compile('(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|''(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)',re.IGNORECASE|re.MULTILINE)
+class rc_parser(c_preproc.c_parser):
+	def filter_comments(self,filepath):
+		code=Utils.readf(filepath)
+		if c_preproc.use_trigraphs:
+			for(a,b)in c_preproc.trig_def:code=code.split(a).join(b)
+		code=c_preproc.re_nl.sub('',code)
+		code=c_preproc.re_cpp.sub(c_preproc.repl,code)
+		ret=[]
+		for m in re.finditer(re_lines,code):
+			if m.group(2):
+				ret.append((m.group(2),m.group(3)))
+			else:
+				ret.append(('include',m.group(5)))
+		return ret
+	def addlines(self,node):
+		self.currentnode_stack.append(node.parent)
+		filepath=node.abspath()
+		self.count_files+=1
+		if self.count_files>c_preproc.recursion_limit:
+			raise c_preproc.PreprocError("recursion limit exceeded")
+		pc=self.parse_cache
+		Logs.debug('preproc: reading file %r',filepath)
+		try:
+			lns=pc[filepath]
+		except KeyError:
+			pass
+		else:
+			self.lines.extend(lns)
+			return
+		try:
+			lines=self.filter_comments(filepath)
+			lines.append((c_preproc.POPFILE,''))
+			lines.reverse()
+			pc[filepath]=lines
+			self.lines.extend(lines)
+		except IOError:
+			raise c_preproc.PreprocError("could not read the file %s"%filepath)
+		except Exception:
+			if Logs.verbose>0:
+				Logs.error("parsing %s failed"%filepath)
+				traceback.print_exc()
+class winrc(Task.Task):
+	run_str='${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}'
+	color='BLUE'
+	def scan(self):
+		tmp=rc_parser(self.generator.includes_nodes)
+		tmp.start(self.inputs[0],self.env)
+		nodes=tmp.nodes
+		names=tmp.names
+		if Logs.verbose:
+			Logs.debug('deps: deps for %s: %r; unresolved %r'%(str(self),nodes,names))
+		return(nodes,names)
+def configure(conf):
+	v=conf.env
+	v['WINRC_TGT_F']='-o'
+	v['WINRC_SRC_F']='-i'
+	if not conf.env.WINRC:
+		if v.CC_NAME=='msvc':
+			conf.find_program('RC',var='WINRC',path_list=v['PATH'])
+			v['WINRC_TGT_F']='/fo'
+			v['WINRC_SRC_F']=''
+		else:
+			conf.find_program('windres',var='WINRC',path_list=v['PATH'])
+	if not conf.env.WINRC:
+		conf.fatal('winrc was not found!')
+	v['WINRCFLAGS']=[]
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlc.py
new file mode 100644
index 0000000..fbf0fcf
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlc.py
@@ -0,0 +1,45 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_xlc(conf):
+	cc=conf.find_program(['xlc_r','xlc'],var='CC')
+	cc=conf.cmd_to_list(cc)
+	conf.get_xlc_version(cc)
+	conf.env.CC_NAME='xlc'
+	conf.env.CC=cc
+@conf
+def xlc_common_flags(conf):
+	v=conf.env
+	v['CC_SRC_F']=[]
+	v['CC_TGT_F']=['-c','-o']
+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
+	v['CCLNK_SRC_F']=[]
+	v['CCLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['RPATH_ST']='-Wl,-rpath,%s'
+	v['SONAME_ST']=[]
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']=[]
+	v['LINKFLAGS_cprogram']=['-Wl,-brtl']
+	v['cprogram_PATTERN']='%s'
+	v['CFLAGS_cshlib']=['-fPIC']
+	v['LINKFLAGS_cshlib']=['-G','-Wl,-brtl,-bexpfull']
+	v['cshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cstlib']=[]
+	v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+	conf.find_xlc()
+	conf.find_ar()
+	conf.xlc_common_flags()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlcxx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlcxx.py
new file mode 100644
index 0000000..b7efb23
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlcxx.py
@@ -0,0 +1,45 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_xlcxx(conf):
+	cxx=conf.find_program(['xlc++_r','xlc++'],var='CXX')
+	cxx=conf.cmd_to_list(cxx)
+	conf.get_xlc_version(cxx)
+	conf.env.CXX_NAME='xlc++'
+	conf.env.CXX=cxx
+@conf
+def xlcxx_common_flags(conf):
+	v=conf.env
+	v['CXX_SRC_F']=[]
+	v['CXX_TGT_F']=['-c','-o']
+	if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+	v['CXXLNK_SRC_F']=[]
+	v['CXXLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['RPATH_ST']='-Wl,-rpath,%s'
+	v['SONAME_ST']=[]
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']=[]
+	v['LINKFLAGS_cxxprogram']=['-Wl,-brtl']
+	v['cxxprogram_PATTERN']='%s'
+	v['CXXFLAGS_cxxshlib']=['-fPIC']
+	v['LINKFLAGS_cxxshlib']=['-G','-Wl,-brtl,-bexpfull']
+	v['cxxshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cxxstlib']=[]
+	v['cxxstlib_PATTERN']='lib%s.a'
+def configure(conf):
+	conf.find_xlcxx()
+	conf.find_ar()
+	conf.xlcxx_common_flags()
+	conf.cxx_load_tools()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
