339 lines
116 KiB
Plaintext
339 lines
116 KiB
Plaintext
|
|
#! /usr/bin/env python
|
||
|
|
# encoding: utf-8
|
||
|
|
# Thomas Nagy, 2005 (ita)
|
||
|
|
|
||
|
|
import os, sys
|
||
|
|
if 'PSYCOWAF' in os.environ:
|
||
|
|
try:
|
||
|
|
import psyco
|
||
|
|
psyco.full()
|
||
|
|
except:
|
||
|
|
pass
|
||
|
|
|
||
|
|
VERSION="1.1.1"
|
||
|
|
REVISION="1272724989"
|
||
|
|
INSTALL=sys.platform=='win32' and 'c:/temp' or '/usr/local'
|
||
|
|
cwd = os.getcwd()
|
||
|
|
|
||
|
|
def decodeAscii85(s):
|
||
|
|
out=[]
|
||
|
|
app=out.append
|
||
|
|
s=''.join(s.split()).replace('z','!!!!!')
|
||
|
|
p1,p2=divmod(len(s), 5)
|
||
|
|
stop=5*p1
|
||
|
|
p3,p4=s[0:stop],s[stop:]
|
||
|
|
for i in range(p1):
|
||
|
|
off=i*5
|
||
|
|
a=ord(p3[off])-33
|
||
|
|
b=ord(p3[off+1])-33
|
||
|
|
c=ord(p3[off+2])-33
|
||
|
|
d=ord(p3[off+3])-33
|
||
|
|
e=ord(p3[off+4])-33
|
||
|
|
num=(52200625L*a)+(614125*b)+(7225*c)+(85*d)+e
|
||
|
|
x,p=divmod(num,256)
|
||
|
|
x,o=divmod(x,256)
|
||
|
|
m,n=divmod(x,256)
|
||
|
|
app(chr(m)+chr(n)+chr(o)+chr(p))
|
||
|
|
if p2:
|
||
|
|
while len(p4)<5: p4=p4+'!'
|
||
|
|
a=ord(p4[0])-33
|
||
|
|
b=ord(p4[1])-33
|
||
|
|
c=ord(p4[2])-33
|
||
|
|
d=ord(p4[3])-33
|
||
|
|
e=ord(p4[4])-33
|
||
|
|
num=(52200625L*a)+(614125*b)+(7225*c)+(85*d)+e
|
||
|
|
x,p=divmod(num,256)
|
||
|
|
x,o=divmod(x,256)
|
||
|
|
m,n=divmod(x, 256)
|
||
|
|
if p2==2: app(chr(m))
|
||
|
|
elif p2==3: app(chr(m)+chr(n))
|
||
|
|
elif p2==4: app(chr(m)+chr(n)+chr(o))
|
||
|
|
return ''.join(out)
|
||
|
|
|
||
|
|
# wafdir is needed to parse the command-line arguments or print the version number
|
||
|
|
wafdir=None # SPECIAL LINE
|
||
|
|
|
||
|
|
def uncompress_wafdir(newdir):
|
||
|
|
file = open(sys.argv[0], 'rb')
|
||
|
|
while 1:
|
||
|
|
line = file.readline()
|
||
|
|
if not line:
|
||
|
|
print "This is a stripped-down waf, there is no wafadmin directory available"
|
||
|
|
print "Please set WAFDIR to a directory containing a directory named wafadmin"
|
||
|
|
print "Or use the full waf version available freely at http://freehackers.org/~tnagy/bksys.html"
|
||
|
|
print "\033[91mNo wafadmin: cannot execute anything (error)\033[0m"
|
||
|
|
sys.exit(1)
|
||
|
|
line=line.rstrip()
|
||
|
|
if line=='# ===>BEGIN WOOF<===':
|
||
|
|
cnt = file.readline()
|
||
|
|
if not cnt:
|
||
|
|
print "Corrupted waf (1)"
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
line = file.readline().rstrip()
|
||
|
|
if line!='# ===>END WOOF<===':
|
||
|
|
print "Corrupted waf (2)"
|
||
|
|
sys.exit(1)
|
||
|
|
break
|
||
|
|
if not cnt:
|
||
|
|
print "Corrupted waf (3)"
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
cnt = decodeAscii85(cnt[1:])
|
||
|
|
|
||
|
|
# create wafadmin
|
||
|
|
import shutil
|
||
|
|
try: shutil.rmtree(newdir)
|
||
|
|
except OSError: pass
|
||
|
|
try: os.makedirs(newdir)
|
||
|
|
except OSError:
|
||
|
|
print "Could uncompress waf-local into %s"%newdir
|
||
|
|
print "Please install waf system-wide or move waf in a writeable directory"
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
os.chdir(newdir)
|
||
|
|
file = open('wafadmin.tar.bz2', 'wb')
|
||
|
|
file.write(cnt)
|
||
|
|
file.close()
|
||
|
|
|
||
|
|
# now we have the tar file to open
|
||
|
|
import tarfile
|
||
|
|
tar = tarfile.open('wafadmin.tar.bz2')
|
||
|
|
for tarinfo in tar:
|
||
|
|
tar.extract(tarinfo)
|
||
|
|
tar.close()
|
||
|
|
|
||
|
|
# cleanup the tarfile and chdir to the previous directory
|
||
|
|
os.chmod('wafadmin', 0755)
|
||
|
|
os.chmod('wafadmin'+os.sep+'Tools', 0755)
|
||
|
|
os.unlink('wafadmin.tar.bz2')
|
||
|
|
os.chdir(cwd)
|
||
|
|
|
||
|
|
global wafdir
|
||
|
|
wafdir = newdir
|
||
|
|
|
||
|
|
def try_wafdir(dir):
|
||
|
|
global wafdir
|
||
|
|
if wafdir: return
|
||
|
|
try:
|
||
|
|
os.stat(os.path.join(dir, 'wafadmin'))
|
||
|
|
wafdir = os.path.abspath(dir)
|
||
|
|
except OSError:
|
||
|
|
pass
|
||
|
|
|
||
|
|
def find_wafadmin():
|
||
|
|
global wafdir
|
||
|
|
name = sys.argv[0]
|
||
|
|
|
||
|
|
# wafadmin may be in $WAFDIR (developers)
|
||
|
|
if 'WAFDIR' in os.environ:
|
||
|
|
try_wafdir(os.environ['WAFDIR'])
|
||
|
|
if wafdir: return
|
||
|
|
|
||
|
|
# waf-light is a special beast
|
||
|
|
if name[-5:] == 'light':
|
||
|
|
try_wafdir(os.path.dirname(os.path.abspath(name)))
|
||
|
|
if wafdir: return
|
||
|
|
print "\033[91mwaf-light in use, wafadmin not found -> export WAFDIR=/folder\033[0m"
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
if not wafdir:
|
||
|
|
dir = "/lib/waf-%s-%s/" % (VERSION, REVISION)
|
||
|
|
for i in [INSTALL, '/usr', '/usr/local', '/opt']:
|
||
|
|
try_wafdir(i+dir)
|
||
|
|
if wafdir: return
|
||
|
|
|
||
|
|
# remove $HOME/.waf-version if asked to
|
||
|
|
if wafdir:
|
||
|
|
if "--nocache" in sys.argv:
|
||
|
|
import shutil
|
||
|
|
print "removing the local wafdir", wafdir
|
||
|
|
try: shutil.rmtree(wafdir)
|
||
|
|
except OSError: pass
|
||
|
|
try: os.stat(wafdir)
|
||
|
|
except OSError: wafdir=None
|
||
|
|
|
||
|
|
if wafdir: return
|
||
|
|
|
||
|
|
# look in the directory containing waf
|
||
|
|
if sys.platform == 'win32': s='waf-%s-%s'
|
||
|
|
else: s='.waf-%s-%s'
|
||
|
|
dir = os.path.join(os.path.dirname(os.path.abspath(name)), s % (VERSION, REVISION))
|
||
|
|
try_wafdir(dir)
|
||
|
|
if wafdir: return
|
||
|
|
|
||
|
|
# not found, uncompress
|
||
|
|
wafdir = dir
|
||
|
|
uncompress_wafdir(dir)
|
||
|
|
|
||
|
|
# run the test
|
||
|
|
find_wafadmin()
|
||
|
|
if "-vv" in sys.argv: print "wafdir is ", wafdir
|
||
|
|
|
||
|
|
# Update sys.path and import our modules
|
||
|
|
wafadmindir = os.path.join(wafdir, 'wafadmin')
|
||
|
|
tooldir = os.path.join(wafadmindir, 'Tools')
|
||
|
|
sys.path = [wafadmindir, tooldir] + sys.path
|
||
|
|
|
||
|
|
import Options, Params, Utils
|
||
|
|
from Params import fatal, warning
|
||
|
|
|
||
|
|
# Set the directory containing the tools
|
||
|
|
Params.g_tooldir = [tooldir]
|
||
|
|
Params.g_cwd_launch = cwd
|
||
|
|
|
||
|
|
if Params.g_version != VERSION:
|
||
|
|
fatal('version mismatch waf %s <-> wafadmin %s (wafdir %s)' % (VERSION, Params.g_version, wafdir))
|
||
|
|
|
||
|
|
# some command-line options can be processed immediately
|
||
|
|
if '--version' in sys.argv:
|
||
|
|
opt_obj = Options.Handler()
|
||
|
|
opt_obj.parse_args()
|
||
|
|
sys.exit(0)
|
||
|
|
|
||
|
|
# now find the wscript file
|
||
|
|
msg1 = 'Waf: *** Nothing to do! Please run waf from a directory containing a file named "wscript"'
|
||
|
|
|
||
|
|
# Some people want to configure their projects gcc-style:
|
||
|
|
# mkdir build && cd build && ../waf configure && ../waf
|
||
|
|
# check that this is really what is wanted
|
||
|
|
build_dir_override = None
|
||
|
|
candidate = None
|
||
|
|
|
||
|
|
lst = os.listdir(cwd)
|
||
|
|
xml = 0
|
||
|
|
#check if a wscript or a wscript_xml file is in current directory
|
||
|
|
if (not 'wscript' in lst) and (not 'wscript_xml' in lst):
|
||
|
|
if 'configure' in sys.argv:
|
||
|
|
#set the build directory with the current directory
|
||
|
|
build_dir_override = cwd
|
||
|
|
if 'wscript_build' in lst:
|
||
|
|
#try to find the wscript root
|
||
|
|
candidate = cwd
|
||
|
|
else:
|
||
|
|
#wscript or wscript_xml is in current directory, use this directory as candidate
|
||
|
|
candidate = cwd
|
||
|
|
|
||
|
|
try:
|
||
|
|
#check the following dirs for wscript or wscript_xml
|
||
|
|
search_for_candidate = True
|
||
|
|
if not candidate:
|
||
|
|
#check first the calldir if there is wscript or wscript_xml
|
||
|
|
#for example: /usr/src/configure the calldir would be /usr/src
|
||
|
|
calldir = os.path.abspath(os.path.dirname(sys.argv[0]))
|
||
|
|
lst_calldir = os.listdir(calldir)
|
||
|
|
if 'wscript' in lst_calldir:
|
||
|
|
candidate = calldir
|
||
|
|
search_for_candidate = False
|
||
|
|
if 'wscript_xml' in lst_calldir:
|
||
|
|
candidate = calldir
|
||
|
|
xml = 1
|
||
|
|
search_for_candidate = False
|
||
|
|
if "--make-waf" in sys.argv and candidate:
|
||
|
|
search_for_candidate = False
|
||
|
|
|
||
|
|
#check all directories above current dir for wscript or wscript_xml if still not found
|
||
|
|
while search_for_candidate:
|
||
|
|
if len(cwd) <= 3:
|
||
|
|
break # stop at / or c:
|
||
|
|
dirlst = os.listdir(cwd)
|
||
|
|
if 'wscript' in dirlst:
|
||
|
|
candidate = cwd
|
||
|
|
xml = 0
|
||
|
|
if 'wscript_xml' in dirlst:
|
||
|
|
candidate = cwd
|
||
|
|
xml = 1
|
||
|
|
break
|
||
|
|
if 'configure' in sys.argv and candidate:
|
||
|
|
break
|
||
|
|
if Params.g_lockfile in dirlst:
|
||
|
|
break
|
||
|
|
cwd = cwd[:cwd.rfind(os.sep)] # climb up
|
||
|
|
except:
|
||
|
|
fatal(msg1)
|
||
|
|
|
||
|
|
if not candidate:
|
||
|
|
# check if the user only wanted to display the help
|
||
|
|
if '-h' in sys.argv or '--help' in sys.argv:
|
||
|
|
warning('No wscript file found: the help message may be incomplete')
|
||
|
|
opt_obj = Options.Handler()
|
||
|
|
opt_obj.parse_args()
|
||
|
|
sys.exit(0)
|
||
|
|
else:
|
||
|
|
fatal(msg1)
|
||
|
|
|
||
|
|
# We have found wscript, but there is no guarantee that it is valid
|
||
|
|
os.chdir(candidate)
|
||
|
|
|
||
|
|
# xml -> jump to the parser
|
||
|
|
if xml:
|
||
|
|
from XMLScripting import compile
|
||
|
|
compile(candidate+os.sep+'wscript_xml')
|
||
|
|
else:
|
||
|
|
# define the main module containing the functions init, shutdown, ..
|
||
|
|
Utils.set_main_module(os.path.join(candidate, 'wscript'))
|
||
|
|
|
||
|
|
if build_dir_override:
|
||
|
|
try:
|
||
|
|
# test if user has set the blddir in wscript.
|
||
|
|
blddir = Utils.g_module.blddir
|
||
|
|
msg = 'Overriding build directory %s with %s' % (blddir, build_dir_override)
|
||
|
|
Params.niceprint(msg, 'WARNING', 'waf')
|
||
|
|
except:
|
||
|
|
pass
|
||
|
|
Utils.g_module.blddir = build_dir_override
|
||
|
|
|
||
|
|
# fetch the custom command-line options recursively and in a procedural way
|
||
|
|
opt_obj = Options.Handler()
|
||
|
|
opt_obj.sub_options('') # will look in wscript
|
||
|
|
opt_obj.parse_args()
|
||
|
|
|
||
|
|
# use the parser results
|
||
|
|
if Params.g_commands['dist']:
|
||
|
|
# try to use the user-defined dist function first, fallback to the waf scheme
|
||
|
|
try:
|
||
|
|
Utils.g_module.dist()
|
||
|
|
sys.exit(0)
|
||
|
|
except AttributeError:
|
||
|
|
pass
|
||
|
|
try: appname = Utils.g_module.APPNAME
|
||
|
|
except: appname = 'noname'
|
||
|
|
|
||
|
|
try:
|
||
|
|
get_version = Utils.g_module.get_version
|
||
|
|
except AttributeError:
|
||
|
|
try:
|
||
|
|
version = Utils.g_module.VERSION
|
||
|
|
except AttributeError:
|
||
|
|
version = '1.0'
|
||
|
|
else:
|
||
|
|
version = get_version()
|
||
|
|
|
||
|
|
from Scripting import Dist
|
||
|
|
Dist(appname, version)
|
||
|
|
sys.exit(0)
|
||
|
|
elif Params.g_commands['distclean']:
|
||
|
|
# try to use the user-defined distclean first, fallback to the waf scheme
|
||
|
|
try:
|
||
|
|
Utils.g_module.distclean()
|
||
|
|
sys.exit(0)
|
||
|
|
except AttributeError:
|
||
|
|
pass
|
||
|
|
from Scripting import DistClean
|
||
|
|
DistClean()
|
||
|
|
sys.exit(0)
|
||
|
|
|
||
|
|
try: Utils.g_module.init()
|
||
|
|
except AttributeError: pass
|
||
|
|
|
||
|
|
import Scripting
|
||
|
|
try: Scripting.Main()
|
||
|
|
except KeyboardInterrupt: Params.fatal('build interrupted')
|
||
|
|
#import hotshot
|
||
|
|
#prof=hotshot.Profile("/tmp/proftest.txt")
|
||
|
|
#prof.runcall(Scripting.Main)
|
||
|
|
#prof.close()
|
||
|
|
# ===>BEGIN WOOF<===
|
||
|
|
#6<\%_0gSqh;d"&i4hUq"'EA+4s8;Tjs8W-!s8W-!s8W+l!!!?/+s8Ri#QQOmTF;*7jW*^\\1'ZCz!!!!q-n#&q!!"DJF2"&p-aW8SQY$K"!EWV\h!&gY=W_6RV_sr\722cZ@k5kdqqg'$4*["='$#2".3/jH9s\UR>BX?ohY0*=H[;!kmGlsVII%EnT7)!(/U>#5gO6P<#sP`m!Um]ST#;0S]:$Hk8J3V550%G+n!@)<f=ekG?(YIu83IB6do6RS4(+]aZkUp:6=%$bl&Ylc'WOP>?&(e/H?7rG4)HopHecsJV&*NLld/Hf'i_<Dq[OaILkdl17[*lSp,\f#T_!"RRl*#dq`D8j]/ebpTK:JEKAHS=8gj\L3j&RE:TZ,@W#kBbVK`(A4R9Pj5TYUZ,"8re>/tW]OXF=:('"e7,sVH,!!!'c"B6'9h=&$=^$;/b<7!LN[75n*Zqu06hetOCfNT/9Dgh)`hX<XO/(30pQ[A1Jc`>=R2Efmj*fjoK.pmJmh!ZlhGA_fKbKkV"UYb%$WeaM<&g4,qXHU?d8^JOF*%JYrh=IR.4^RKF+eA55]5<0hXk9hhme9(rh6nrgMn6Nkn!3?hPcO46ZarrBDYD60?/F#=^#"+FY%MhCpYKIuY'4`L\G(EBC%lKlo_[gcA*S!'f@;scf6;#ph"9uKijR_*<r8l-n9Xuli;9j_1fJb4j55:Zh`g5:m?Zql2neqFe":flD&T,>D0sg5$f:Wk<&O(2&%?WII<;NeC$o1g)ql6Ep?UE"Nr&N6G4/jfDnaO=GIt<\efO_Thd*tkIJ(4`B<C$rmPhlWlYj%Adn[V_Ge6,Ac`aJmXaqnpIIBVYpY4UeqiZ<_k.h"GNgf4adk8<B7mI12g]EoPB@-*JpLMiV3@h[Lmlg;>hH+Q#Q^mriANd<)9A\4n"42=kb]#^DkT=Q+gDA3H_e&T"!!)5_8bRSiDY<_tcb@q:I-rM#g:)F^8p<2]2gLe?Ch*\7]tNjs020r>=5RnDp%7PBoC![Th72o`a:#<,9:j0fl5oft]63B-8kZn]AU<ZqqX(nYl.\/RHg`ChZBO`_49rK6HQEGrpV-O^?Ti<(Y"uBOZ]ACScZd+sgU?C&d=YZ6HZtVh^@o;<ZZ]fI@8u]s*;@'cbMPCb#@+uf!)er-BN=Edku.8gS$mhW[d;i<^%K!tqk#&62T8Y[9s#(Oh0&eQYhc\Bgl7ks*So%*pUfh)^%K^]QerhWjh#VQD=hn:iukOLh]H2AMZj@=K<_l#g<SI-G38sN]:X:nnh$@!1UaP8N!1M2I.13Ld*qEu#GCXYZYmLg=1,0BftF>bg83'YpRHGrfg4g+/H\r+?>S>Dp@l24g/m%jC0ZVQ)bTehQ#4*Z0as)4J9k`J:5(m&jtEVkI2Cd(dA8ktHLJ>Oq"f]f[(A<E%.4>rhIYKc]5c[J4lPj>D'k5f4*NGO&PAu:]C+\N<df>PC%]toII(/+.rjfDHbJ5>YJ"KR9b7j=!Wi@V5S+A-^`Z.ASs`%sVkPt8ct"&3+92BEVEkcF#RCJ7dh#E,Ua`\jeFbS3IT5tX)L@B"cl+_GW#>Xm!!!'e,X>9.":V:+!hL&PR0f<V1t;.81oH`gWO2=o'R<Aa8ZCegSqK8,4X3ZB:dS#'&niRRWTH[%Stg%8H>"X"2lLC,L^ae2!71_m!MBDm!$Oo>7Ynt_-@c@Y'Z*!^lAs)Wb%=WB+[&Uq:JF)fo`,M!)?9a<-DDVJ5ThD;C,#pWnI_3hrA9lerC5<V;oI/r:t$TQ!!XRm!!%Ehs/Z-T!mW8>s2rjl;?[PrL=C^1!mZZe!*tIsVMZ(`(aR.`!.f;1JL3$GX5;7lqq$d-4`p%rY43r4;oek6HHf2F7+PXA[5XV*Bupng8)TXXs/-lT#^Lr&'K\Qer#dXd]Cp9.mP/tTC5VP&D[`VCFf?)?KI(kK#j'?aArSC"kcMIcb*fhrE/IY4>tHlu3H)Ah!H-i1UBF'l\7*5d+pSd1QOXU,!m6;[+S$'LH\EG3'I_C+N<iFA$5>!$1+S/Xm_TYp[$6OMM\6Lb6b*.a-p;-K&GIBY.2IRIl@iLl5p?i<ckFq2:^g0r'DFh%4O&BmT.T[Y-oU#Z#7_<&BiiA].d7bT+IlD!=5&2sJPd8G!%AUhog6/T,(ocd&_N0B:un9I.*+h5$VWtknN)saUIkK`@,qnC86#aZ;c#jj86%L2N<;fe8C7SP&HG6g,S7pMPQ=<3;C)<@"@1BDd59<0'bNk[<)f)N7$.o.'NEIO72-1Fbf#0iZEQ;;Pq!':$DEV2L4H'_k7^gR<('=j"VFTW8PCF06S24;0mfEYZEhC`1I=en/;+Zn:mFC:;@l0[5r->V9MI)>9,,>q<C0,07"[or,:,2j6H"utaTN=^&epS<%15pk6psI;N)68LZqWtebS6jO,YKC\`'Fr'&B[^&9JdCr,>BHsO9J<7OV9E@'%8]A1sm`T">r#7"I2AP!)c`-72/<j&OR*u5tY!0dSLY)&Hn72&L:>oZir6"9Mht@'bEYs>A0_+@O`e!+[VTQ,*mbQ@MkIV,ab5MJ;Rm1To+GYM@*`88=G8?VHB"STV@=D@OPt6W$J$fBOrV0-n:U?TqWGT)3R<'+G(dC#_jNq)Ib1,>+qU`+UFmB$"/oE,)@E]?m$q1UnJ'U.Z0+@Tr)7cTa@*BMCN#0R2R2uW%(AjLkp^6BkX<1+KC9kU5#VBVIGXKMJ/ENBh9S)#UtS0W!JK8Ob0EsOt%T2AdOWpL*EIOR"upf-A#uq,&+'S80FTSLkLp,)CV;9#(W'V-DcSHBLnA\MPLQHP"K1eAL_-r8j]2$VMZQGLhMrCWD*jo,`%84-5_l%R\YP4L4UiuKRtP68gn/"@=a;&Q6mHJMBWplV&>(7?mI-KAf;jaQ@pBZ,(`[L+fYkPMO&jYR"d$q#a,dfC8-<[TI;3\BHdMWBI6'7!2Z?]W$7BI?t"kI.&qkJ,"R<:+K-2M7Tro_AeJK$JqHOW+IZDhOb-D](mZ;<-<-ZfU4S,bUo&ho7ZjDj8qJI#TSaj!8<AF*MCO-jL^5,k@N$AX('pe%W0/GTVLejn+GabZ#cXPmJr0VkLaf'\MQ3PROJ.3!,_Dsm,(`[R!b*L>.L7A5OGNrUM3&urTn]Eg-)cPD@SiIqMNSm/Slm3`R%],3Jk.=W&djAM@L?:RLm4k_,c%/s-n,4lV'ZOA8=EFKWgWKh9Z06^$?/C!";NW7[_\dIUgcrPJ=%OS,a+k"J;Aek8n+6X.OgL7@UUO:!\.rR$;uD+TI(j`A;DM1.12K;Jf./f6>2T-$4;Alj9`\$MOGf"Ad#,I."R2?ROKF/Q)\:")AWV`Q=L>+&V64AJfnSL5&_'@ps7.?K-IZV'a579&5jd\,u[c/!<g?I%5^?RPX?']_Ee=@!A^H%JAF*78MnXG0N+Ga6VU7-5t+1-%+Ine9M.te_Ee2'8kB+>":Q"j'b"&p;H+ea78+=fPg%KR1ntUN6j/aV1a<WtP,09P14W:oci=a\5^[-^W$jn;#%E*s,,-HP_SIck'akWg[*Z*W!`C<F&OR0BaO&@k_R)^.9LTOZ8C4S4,fInq/KlmnU][;a%#kPrZlq2f^p4\Q71Ce76;p<-)H.=^78aV(1k?4d'*LQgP8#Q%<<Q/"7*ItR.72H=$BZi46H"FL1lFpt;DeUd6rPg/6o:.I6<+[E`(^tGP6DCQ<2@Gg0at!W7"mKt;)L1)%2D8W.83G^,pY/NX[9r=`5*QoONTp'%8/Di<C$a]PcPS9"URgg;&#im,XfSU;+)$1,o%'B&5t8+5nQck'+coA;ajS>;%"NZ<E):^;Gf!d'\!a-#W/2PJ3aPp1djbA.7lm$&QLC#_Sn4W79!1p)`fF(-<cdk.Y`L`@"M?%,T9-[#)X7PO@hcgJ;0pF-C/)7BS)OX@$lf_VN<6?&qXcji4q1+8OAZ+'N-^icq$Pm!DF%=&M,aR$C"B3&;),o9SEdA1f@=.1Gk>\#;YI8)[;g:(0\g+"[p4);+3hYV0!=_9X?R[7$95[9$sJT&HP3&O`LjtPbL`($qNep!s(e@ZS9oT&4EcH'b`9;!N7IPM5ckEL+%o_,%:ldL/=ONLl-_F&;C?3O['
|
||
|
|
# ===>END WOOF<===
|