.lpbuild2: packaging improvements (RM #244)

git-svn-id: svn://ultimatepp.org/upp/trunk@4581 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
dolik 2012-02-13 08:08:55 +00:00
parent c1c3616cbd
commit cf2218127a
7 changed files with 836 additions and 834 deletions

View file

@ -1,251 +1,250 @@
#include <time.h>
String ParseCustomStep(const String& s){
String cmd;
for(const char* c=~s;*c;c++){
if(c[0]=='\\' && c[1]=='\"') continue;
if(strncmp(c,"$(PATH)",7)==0){
cmd+="$$f";
c+=6;
} else if(strncmp(c,"$(DIR)",6)==0){
cmd+="`dirname $$f`";
c+=5;
} else if(strncmp(c,"$(FILE)",7)==0){
cmd+="`basename $$f`";
c+=6;
} else if(strncmp(c,"$(TITLE)",8)==0){
cmd+="`basename $$f | sed 's/[.][^.]*$//'`";
c+=7;
} else if(strncmp(c,"$(OUTDIR)",9)==0){
cmd+="$(BIN)/";
c+=8;
} else
cmd+=*c;
// $(INCLUDE),$(!) etc. not implemented yet
}
return cmd;
}
String CustomRule(String rule, const String& pkg){
String ext=ReadValue(rule);
String cmd=ParseCustomStep(ReadValue(rule));
//ignore last part for simplicity
if (cmd.IsEmpty() || ext.IsEmpty())
return "";
if (ext=="pre-link")
return " $E cd $("+pkg+"_src) &&"
"echo \" Applying custom build pre-link step "
"(warning: this is an experimental feature)\"; "
+cmd+";\n";
if (ext=="post-link")
return " $E cd $("+pkg+"_src) &&"
"echo \" Applying custom build post-link step "
"(warning: this is an experimental feature)\"; "
+cmd+";\n";
return " $E cd $("+pkg+"_src) && for f in *"+ext+"; "
"do echo \" Applying custom build step on $$f "
"(warning: this is an experimental feature)\"; "
+cmd+"; done;\n";
}
void Parser::Process(){
String uppout=GetEnv("OUT","/tmp/_out");
String makefile=uppout+"/Makefile";
FILE* mf=fopen(makefile,"w");
if(!mf){
printf("Failed to open file %s\n", ~makefile);
exit(1);
}
fprintf(mf, "# This is an automatically generated makefile for %s package\n"
"# You should never need to modify it...\n", ~main);
bool dep = GetEnv("DEPS","0")=="1";
bool color = GetEnv("COLOR","0")=="1";
String includes;
Vector<String> inc;
Split(GetEnv("INCPATHS"),inc);
for(int i=0; i<nests.GetCount(); i++)
includes+=" -I"+nests[i];
for(int i=0; i<inc.GetCount(); i++)
includes+=" -I"+inc[i];
String libpaths;
Vector<String> lpaths;
Split(GetEnv("LIBPATHS"),lpaths);
for(int i=0; i<lpaths.GetCount(); i++)
libpaths+=" -L"+lpaths[i];
time_t rawtime;
time(&rawtime);
char date[90];
struct tm* t = localtime(&rawtime);
sprintf(date," -DbmYEAR=%i -DbmMONTH=%i -DbmDAY=%i -DbmHOUR=%i -DbmMINUTE=%i -DbmSECOND=%i",
t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
fprintf(mf, "OUT:=%s\n"
"BIN:=%s\n"
"CFLAGS:=%s\n"
"CXXFLAGS:=%s\n"
"SPEEDFLAGS:=%s\n"
"SIZEFLAGS:=%s\n"
"LDFLAGS:=%s\n"
"CC:=%s\n"
"CXX:=%s\n"
"AR:=%s\n"
"MKDIRP:=%s\n"
"E:=%s\n"
"M:=%s\n"
"C:=%s\n"
"B:=%s\n"
"N:=%s\n"
"mc=$M \" Compiling $C$<$N\"\n"
"ma=$M \"=> $BCreating archive$N $C$@$N\"\n"
"cc=$E $(CC) -c -x c %s $< -o $@ $(CPPFLAGS) %s\n"
"cxx=$E $(CXX) -c -x c++ %s $< -o $@ $(CPPFLAGS) %s\n"
"includes:=%s\n"
"LIBPATHS:=%s\n"
"default: build\n"
".PHONY:build clean createdirs custom default\n\n",
~uppout, ~GetEnv("BIN","$(OUT)/bin"),
~GetEnv("CFLAGS","-O2"),
~GetEnv("CXXFLAGS","$(CFLAGS)"),
~GetEnv("SPEEDFLAGS","-O3 -ffunction-sections -fdata-sections"),
~GetEnv("SIZEFLAGS","-Os -finline-limit=20 -ffunction-sections -fdata-sections"),
~GetEnv("LDFLAGS","-Wl,--gc-sections -Wl,-s -Wl,-O,2"),
~GetEnv("CC","$(CC)"), ~GetEnv("CXX","$(CXX)"),
~GetEnv("AR","ar -src"), ~GetEnv("MKDIRP","mkdir -p"),
GetEnv("ECHO","0")=="1"?"":"@",
GetEnv("SILENT","0")=="1"?"@true":(color?"@echo -e":"@echo"),
color?(const char*)("\\e[3"+GetEnv("HIGHLIGHT","4")+"m"):"",
color?"\\e[1m":"", color?"\\e[0m":"",
dep?"-MMD":"", date, dep?"-MMD":"",
date, ~includes, ~libpaths);
String icpps, archives, prelink, postlink, custom;
Vector<String> dirs;
dirs.Add("$(BIN)");
for(int i=0;i<pkgs.GetCount();i++){
const String& pkg=pkgs[i].name;
String base=BaseName(pkg);
String objlist;
Vector<String> pflags;
String opt;
//we add the internal includes twice, to fix the case with relative paths... isn't there a better solution?
opt=EvalVector(pkgs[i].include,i,"-I");
opt+=EvalVector(pkgs[i].include,i,"-I$("+pkg+"_src)/");
opt+=EvalVector(pkgs[i].option,i,"");
for(int j=0;j<pkgs[i].flags.GetCount();j++)
opt+=" -Dflag"+pkgs[i].flags[j];
String fdir=pkg+"/"+FlagDir(pkgs[i].flags);
fprintf(mf, "%s", ~(pkg+"_src="+pkgs[i].dir+"\n"+
pkg+"_out=$(OUT)/"+fdir+"\n"+
pkg+"_opt=$(includes) "+opt+"\n"));
for(int j=0; j<pkgs[i].files.GetCount(); j++){
const File& f=pkgs[i].files[j];
dirs.AddUnique(DirName("$("+pkg+"_out)/"+f.name));
if(f.lang == "brc"){
fprintf(mf, "$(%s_out)/%s.o: $(%s_src)/%s\n"
" $(mc)\n"
" $E sh $(OUT)/brc.sh $< > $(%s_out)/%s.cpp\n"
" $E $(CXX) -c -x c++ $(%s_out)/%s.cpp -o $@ $(CPPFLAGS) $(CXXFLAGS)\n",
~pkg, ~f.name, ~pkg, ~f.name, ~pkg, ~f.name, ~pkg, ~f.name);
objlist+=" $("+pkg+"_out)/"+f.name+".o";
continue;
}
String ext,fopt;
if(f.lang=="c++")
opt="$(CXXFLAGS) ";
else if(f.lang=="c")
opt="$(CFLAGS) ";
if(pkgs[i].opt==SPEED) ext=".speed.o";
else if(pkgs[i].opt==SIZE) ext=".size.o";
else{
if(f.opt==SPEED) ext=".speed.o";
if(f.opt==SIZE) ext=".size.o";
else ext=".o";
}
if(ext==".speed.o")
fopt+="$(SPEEDFLAGS)";
else if(ext==".size.o")
fopt+="$(SIZEFLAGS)";
String fn="$("+pkg+"_out)/" + f.name + ext;
if(dep){
String dep = uppout + "/" + fdir + "/" + f.name + ext;
dep[dep.GetCount()-1]='d';
dep=LoadFile(dep);
if(dep.GetCount())
fprintf(mf, "%s", ~dep);
else
fprintf(mf, "%s: $("+pkg+"_src)/%s\n", ~fn, ~f.name);
} else {
fprintf(mf, "%s: $("+pkg+"_src)/%s\n", ~fn, ~f.name);
}
fprintf(mf," $(mc)\n"
" $(%s) %s $(%s_opt)\n",
~f.lang, ~fopt, ~pkg);
if(f.name.Mid(f.name.GetCount()-4)=="icpp")
icpps+=" "+fn;
else
objlist+=" "+fn;
}
fprintf(mf,"%s_custom:\n", ~pkgs[i].name);
for(int j=0;j<pkgs[i].custom.GetCount();j++){
if(EvalOpt(pkgs[i].custom[j],i)){
if(pkgs[i].custom[j].item.Compare("\"pre-link\"",10)==0)
prelink+=CustomRule(pkgs[i].custom[j].item, pkgs[i].name);
else if(pkgs[i].custom[j].item.Compare("\"post-link\"",11)==0)
postlink+=CustomRule(pkgs[i].custom[j].item, pkgs[i].name);
else{
String rule = CustomRule(pkgs[i].custom[j].item, pkgs[i].name);
if(rule=="") continue;
fprintf(mf,"%s",~rule);
custom+=" "+pkgs[i].name+"_custom";
}
}
}
fprintf(mf,"$(%s_out)/%s.a:%s\n"
" $(ma)\n"
" $E $(AR) $@ $^\n\n",
~pkg, ~base, ~objlist);
archives="$("+pkg+"_out)/"+base+".a "+archives;
}
String liblist,optlist,dirlist;
for(int i=0;i<libs.GetCount();i++)
liblist+=" -l"+libs[i];
for(int i=0;i<linkopts.GetCount();i++)
optlist+=" "+linkopts[i];
for(int i=0;i<dirs.GetCount();i++)
dirlist+=" "+dirs[i];
String target = GetEnv("TARGET");
if(target.IsEmpty()){
target=BaseName(main);
for(int i=0;i<pkgs[0].target.GetCount();i++){
if(EvalOpt(pkgs[0].target[i],0)){
target = pkgs[0].target[i].item;
break;
}
}
}
if(target[0]!='/')
target="$(BIN)/"+target;
dirs.AddUnique(DirName(target));
fprintf(mf, "build: createdirs %s %s\n", ~custom, ~target);
fprintf(mf, "%s: %s %s\n"
" $M \"$BLinking$N $C$@$N\"\n"
" $E $(CXX) -o $@ $(LDFLAGS) $(LIBPATHS) %s -Wl,--start-group $^ %s -Wl,--end-group\n"
"%s",
/*~prelink,*/ ~target, ~icpps, ~archives, ~optlist, ~liblist, ~postlink);
fprintf(mf, "createdirs:\n"
" $M \" $BCreating necessary directories ...$N\"\n"
" $E mkdir -p%s\n",
~dirlist);
String clean;
for(int i=0;i<pkgs.GetCount();i++)
clean+=" $("+pkgs[i].name+"_out)";
fprintf(mf,"clean:\n"
" $E rm -rf %s",~clean);
fclose(mf);
#include <time.h>
String ParseCustomStep(const String& s){
String cmd;
for(const char* c=~s;*c;c++){
if(c[0]=='\\' && c[1]=='\"') continue;
if(strncmp(c,"$(PATH)",7)==0){
cmd+="$$f";
c+=6;
} else if(strncmp(c,"$(DIR)",6)==0){
cmd+="`dirname $$f`";
c+=5;
} else if(strncmp(c,"$(FILE)",7)==0){
cmd+="`basename $$f`";
c+=6;
} else if(strncmp(c,"$(TITLE)",8)==0){
cmd+="`basename $$f | sed 's/[.][^.]*$//'`";
c+=7;
} else if(strncmp(c,"$(OUTDIR)",9)==0){
cmd+="$(BIN)/";
c+=8;
} else
cmd+=*c;
// $(INCLUDE),$(!) etc. not implemented yet
}
return cmd;
}
String CustomRule(String rule, const String& pkg){
String ext=ReadValue(rule);
String cmd=ParseCustomStep(ReadValue(rule));
//ignore last part for simplicity
if (cmd.IsEmpty() || ext.IsEmpty())
return "";
if (ext=="pre-link")
return " $E cd $("+pkg+"_src) &&"
"echo \" Applying custom build pre-link step "
"(warning: this is an experimental feature)\"; "
+cmd+";\n";
if (ext=="post-link")
return " $E cd $("+pkg+"_src) &&"
"echo \" Applying custom build post-link step "
"(warning: this is an experimental feature)\"; "
+cmd+";\n";
return " $E cd $("+pkg+"_src) && for f in *"+ext+"; "
"do echo \" Applying custom build step on $$f "
"(warning: this is an experimental feature)\"; "
+cmd+"; done;\n";
}
void Parser::Process(){
String uppout=GetEnv("OUT","/tmp/_out");
String makefile=uppout+"/Makefile";
FILE* mf=fopen(makefile,"w");
if(!mf){
printf("Failed to open file %s\n", ~makefile);
exit(1);
}
fprintf(mf, "# This is an automatically generated makefile for %s package\n"
"# You should never need to modify it...\n", ~main);
bool dep = GetEnv("DEPS","0")=="1";
bool color = GetEnv("COLOR","0")=="1";
String includes;
Vector<String> inc;
Split(GetEnv("INCPATHS"),inc);
for(int i=0; i<nests.GetCount(); i++)
includes+=" -I"+nests[i];
for(int i=0; i<inc.GetCount(); i++)
includes+=" -I"+inc[i];
String libpaths;
Vector<String> lpaths;
Split(GetEnv("LIBPATHS"),lpaths);
for(int i=0; i<lpaths.GetCount(); i++)
libpaths+=" -L"+lpaths[i];
time_t rawtime;
time(&rawtime);
char date[90];
struct tm* t = localtime(&rawtime);
sprintf(date," -DbmYEAR=%i -DbmMONTH=%i -DbmDAY=%i -DbmHOUR=%i -DbmMINUTE=%i -DbmSECOND=%i",
t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
fprintf(mf, "OUT:=%s\n"
"BIN:=%s\n"
"CFLAGS:=%s\n"
"CXXFLAGS:=%s\n"
"SPEEDFLAGS:=%s\n"
"SIZEFLAGS:=%s\n"
"LDFLAGS:=%s\n"
"CC:=%s\n"
"CXX:=%s\n"
"AR:=%s\n"
"MKDIRP:=%s\n"
"E:=%s\n"
"M:=%s\n"
"C:=%s\n"
"B:=%s\n"
"N:=%s\n"
"mc=$M \" Compiling $C$<$N\"\n"
"ma=$M \"=> $BCreating archive$N $C$@$N\"\n"
"cc=$E $(CC) -c -x c %s $< -o $@ $(CPPFLAGS) %s\n"
"cxx=$E $(CXX) -c -x c++ %s $< -o $@ $(CPPFLAGS) %s\n"
"includes:=%s\n"
"LIBPATHS:=%s\n"
"default: build\n"
".PHONY:build clean createdirs custom default\n\n",
~uppout, ~GetEnv("BIN","$(OUT)/bin"),
~GetEnv("CFLAGS","-O2"),
~GetEnv("CXXFLAGS","$(CFLAGS)"),
~GetEnv("SPEEDFLAGS","-O3 -ffunction-sections -fdata-sections"),
~GetEnv("SIZEFLAGS","-Os -finline-limit=20 -ffunction-sections -fdata-sections"),
~GetEnv("LDFLAGS","-Wl,--gc-sections -Wl,-s -Wl,-O,2"),
~GetEnv("CC","$(CC)"), ~GetEnv("CXX","$(CXX)"),
~GetEnv("AR","ar -src"), ~GetEnv("MKDIRP","mkdir -p"),
GetEnv("ECHO","0")=="1"?"":"@",
GetEnv("SILENT","0")=="1"?"@true":(color?"@echo -e":"@echo"),
color?(const char*)("\\e[3"+GetEnv("HIGHLIGHT","4")+"m"):"",
color?"\\e[1m":"", color?"\\e[0m":"",
dep?"-MMD":"", date, dep?"-MMD":"",
date, ~includes, ~libpaths);
String icpps, archives, prelink, postlink, custom;
Vector<String> dirs;
dirs.Add("$(BIN)");
for(int i=0;i<pkgs.GetCount();i++){
const String& pkg=pkgs[i].name;
String base=BaseName(pkg);
String objlist;
Vector<String> pflags;
String opt;
//we add the internal includes twice, to fix the case with relative paths... isn't there a better solution?
opt=EvalVector(pkgs[i].include,i,"-I");
opt+=EvalVector(pkgs[i].include,i,"-I$("+pkg+"_src)/");
opt+=EvalVector(pkgs[i].option,i,"");
for(int j=0;j<pkgs[i].flags.GetCount();j++)
opt+=" -Dflag"+pkgs[i].flags[j];
String fdir=pkg+"/"+FlagDir(pkgs[i].flags);
fprintf(mf, "%s", ~(pkg+"_src="+pkgs[i].dir+"\n"+
pkg+"_out=$(OUT)/"+fdir+"\n"+
pkg+"_opt=$(includes) "+opt+"\n"));
for(int j=0; j<pkgs[i].files.GetCount(); j++){
const File& f=pkgs[i].files[j];
dirs.AddUnique(DirName("$("+pkg+"_out)/"+f.name));
if(f.lang == "brc"){
fprintf(mf, "$(%s_out)/%s.o: $(%s_src)/%s\n"
" $(mc)\n"
" $E sh $(OUT)/brc.sh $< > $(%s_out)/%s.cpp\n"
" $E $(CXX) -c -x c++ $(%s_out)/%s.cpp -o $@ $(CPPFLAGS) $(CXXFLAGS)\n",
~pkg, ~f.name, ~pkg, ~f.name, ~pkg, ~f.name, ~pkg, ~f.name);
objlist+=" $("+pkg+"_out)/"+f.name+".o";
continue;
}
String ext,fopt;
if(f.lang=="c++")
opt="$(CXXFLAGS) ";
else if(f.lang=="c")
opt="$(CFLAGS) ";
if(pkgs[i].opt==SPEED) ext=".speed.o";
else if(pkgs[i].opt==SIZE) ext=".size.o";
else{
if(f.opt==SPEED) ext=".speed.o";
if(f.opt==SIZE) ext=".size.o";
else ext=".o";
}
if(ext==".speed.o")
fopt+="$(SPEEDFLAGS)";
else if(ext==".size.o")
fopt+="$(SIZEFLAGS)";
String fn="$("+pkg+"_out)/" + f.name + ext;
if(dep){
String dep = uppout + "/" + fdir + "/" + f.name + ext;
dep[dep.GetCount()-1]='d';
dep=LoadFile(dep);
if(dep.GetCount())
fprintf(mf, "%s", ~dep);
else
fprintf(mf, "%s: $("+pkg+"_src)/%s\n", ~fn, ~f.name);
} else {
fprintf(mf, "%s: $("+pkg+"_src)/%s\n", ~fn, ~f.name);
}
fprintf(mf," $(mc)\n"
" $(%s) %s $(%s_opt)\n",
~f.lang, ~fopt, ~pkg);
if(f.name.Mid(f.name.GetCount()-4)=="icpp")
icpps+=" "+fn;
else
objlist+=" "+fn;
}
fprintf(mf,"%s_custom:\n", ~pkgs[i].name);
for(int j=0;j<pkgs[i].custom.GetCount();j++){
if(EvalOpt(pkgs[i].custom[j],i)){
if(pkgs[i].custom[j].item.Compare("\"pre-link\"",10)==0)
prelink+=CustomRule(pkgs[i].custom[j].item, pkgs[i].name);
else if(pkgs[i].custom[j].item.Compare("\"post-link\"",11)==0)
postlink+=CustomRule(pkgs[i].custom[j].item, pkgs[i].name);
else{
String rule = CustomRule(pkgs[i].custom[j].item, pkgs[i].name);
if(rule=="") continue;
fprintf(mf,"%s",~rule);
custom+=" "+pkgs[i].name+"_custom";
}
}
}
fprintf(mf,"$(%s_out)/%s.a:%s\n"
" $(ma)\n"
" $E $(AR) $@ $^\n\n",
~pkg, ~base, ~objlist);
archives="$("+pkg+"_out)/"+base+".a "+archives;
}
String liblist,optlist,dirlist;
for(int i=0;i<libs.GetCount();i++)
liblist+=" -l"+libs[i];
for(int i=0;i<linkopts.GetCount();i++)
optlist+=" "+linkopts[i];
for(int i=0;i<dirs.GetCount();i++)
dirlist+=" "+dirs[i];
String target = GetEnv("TARGET");
if(target.IsEmpty()){
target=BaseName(main);
for(int i=0;i<pkgs[0].target.GetCount();i++){
if(EvalOpt(pkgs[0].target[i],0)){
target = pkgs[0].target[i].item;
break;
}
}
}
if(target[0]!='/')
target="$(BIN)/"+target;
dirs.AddUnique(DirName(target));
fprintf(mf, "build: createdirs %s %s\n", ~custom, ~target);
fprintf(mf, "%s: %s %s\n"
" $M \"$BLinking$N $C$@$N\"\n"
" $E $(CXX) -o $@ $(LDFLAGS) $(LIBPATHS) %s -Wl,--start-group $^ %s -Wl,--end-group\n"
"%s",
/*~prelink,*/ ~target, ~icpps, ~archives, ~optlist, ~liblist, ~postlink);
fprintf(mf, "createdirs:\n"
" $M \" $BCreating necessary directories ...$N\"\n"
" $E mkdir -p%s\n",
~dirlist);
String clean;
for(int i=0;i<pkgs.GetCount();i++)
clean+=" $("+pkgs[i].name+"_out)";
fprintf(mf,"clean:\n"
" $E rm -rf %s",~clean);
fclose(mf);
}

View file

@ -1,213 +1,213 @@
########################################################################
# __ __ _ _ __ __ __ _ _ ___ ___ __ __ ___ #
# ( )( ) _( )_ _( )_ ( \/ ) ( ) ( )/ )( _)( _)( )( ) ( _) #
# )(__)( (_ _)(_ _) ) ( /__\ ) \ ) _) ) _) )( )(__ ) _) #
# \____/ (_) (_) (_/\/\_)(_)(_)(_)\_)(___)(_) (__)(____)(___) #
# #
############################## USAGE ###################################
# This makefile is controlled through a set of variables, similar to #
# any other makefile. The prefered way to change them is via command #
# line, e.g.: make PKG="ide usvn" CXX=g++ #
# #
# All of the variables that can control the bahaviour are listed below #
# in DEFAULTS section. Also their default value is shown here. Notice #
# that many of them can contain shell commands (enclosed in ``) which #
# are evaluated before parsing and building each package.
# #
# For boolean type of variables value "1" represents true, anything #
# else is evaluated as false. #
############################# TARGETS ##################################
# This makefile defines five targets that are meant to be used #
# directly by user from the command line: #
# #
# all - builds all (default if any packages are specified) #
# help - shows this help (default if no packages are given) #
# simulate - prints all commands, without executing them #
# clean - deletes all compiled files related to given packages #
# dist-clean - deletes the entire OUT directory (including parsers) #
############################# EXAMPLES #################################
# Typical usage: #
# make PKG=ide FLAGS="GCC" #
# More complicated usage: #
# make PKG="ide UWord Bombs" FLAGS="GCC .NOGTK" ECHO=1 #
# Show help: #
# make help #
# Silent mode: #
# make PKG=ide SILENT=1 #
############################# DEFAULTS #################################
# List of packages to build (space separated). If empty, this help #
# text will be shown. #
PKG:=
# Paths where to look for packages. #
NESTS:=uppsrc bazaar examples reference tutorial $$HOME/MyApps
# Building flags (as in TheIDE).
FLAGS:=GCC
# Additional include paths for compiler (without the leading "-I"). #
INCPATHS:= /usr/include/freetype2 /usr/include/gtk-2.0
INCPATHS+= /usr/local/include/gtk-2.0 /usr/include/glib-2.0
INCPATHS+= /usr/local/include/glib-2.0 /usr/lib/glib-2.0/include
INCPATHS+= /usr/local/lib/glib-2.0/include /usr/lib/gtk-2.0/include
INCPATHS+= /usr/local/lib/gtk-2.0/include /usr/include/cairo
INCPATHS+= /usr/include/pango-1.0 /usr/include/atk-1.0
INCPATHS+= /usr/X11R6/include /usr/X11R6/include/freetype2
INCPATHS+= /usr/X11R6/include/gtk-2.0 /usr/X11R6/include/glib-2.0
INCPATHS+= /usr/X11R6/lib/glib-2.0/include
INCPATHS+= /usr/X11R6/lib/gtk-2.0/include /usr/X11R6/include/cairo
INCPATHS+= /usr/X11R6/include/pango-1.0 /usr/X11R6/include/atk-1.0
INCPATHS+= /usr/local/include/cairo /usr/local/include/pango-1.0
INCPATHS+= /usr/local/include/atk-1.0 /usr/local/include
INCPATHS+= /usr/local/include/libpng /usr/include/gdk-pixbuf-2.0
INCPATHS+= /usr/lib/i386-linux-gnu/glib-2.0/include
INCPATHS+= /usr/lib/x86_64-linux-gnu/glib-2.0/include
# Paths to libraries for linker. #
LIBPATHS:=/usr/X11R6/lib /usr/lib /usr/local/lib
# Directory to store intermediate object files #
OUT:=_out
# Directory where the resulting binaries will be stored #
BIN:=$(OUT)/bin
# ar command #
AR:=ar -src
# Command to create directories equivalent to "mkdir -p". The only #
# good reason to change is if your platform uses mkdir command which #
# doesn't support the -p option #
MKDIRP:=mkdir -p
# C compiler command #
CC:=cc
# C++ compiler command #
CXX:=c++
# Options for C/C++ preprocessor #
CPPFLAGS:=
# Options for C compiler #
CFLAGS:=
# Options for C++ compiler #
CXXFLAGS:=
# Options for linker #
LDFLAGS:=-Wl,--gc-sections -Wl,-s -Wl,-O,2
# Additional options for speed optimization #
SPEEDFLAGS:=-O3 -ffunction-sections -fdata-sections
# Additional options for size optimization #
SIZEFLAGS:=-Os -finline-limit=20 -ffunction-sections -fdata-sections
# Optimization, supply SPEED or SIZE to optimize the executables #
OPT:=
# Platform flag, added to FLAGS, can include shell commands #
PLATFORM:=`uname | tr a-z A-Z` POSIX
# Suppress all messagges #
SILENT:=0
# Print each executed command #
ECHO:=0
# Use dependency files. This will probably work only with gcc-like #
# compilers (requires -MD option). The build usually works correctly #
# even without specifying the dependencies unless you modify included #
# files (*.h, *.lay, ...) without modifying the *.c/cpp files that #
# include them. #
DEPS:=0
# Run the executable(s) sequntially when compiled #
RUN:=0
# Override default name of final executable (absolute or relative path)
TARGET:=
# Add flags from based on mainconfig section (1-based index, set #
# to 0 to disable completely #
USEMAINCFG:=1
# Ask for some additional details during parsing #
INTERACTIVE:=0
# Use colorized output, recognized values are 0, 1 or auto #
COLOR:=auto
# What color should be used in colorized mode, number from 0 to 7 #
HIGHLIGHT:=4
TIME:=TIMEFORMAT=" time taken: %Es"; time
########################################################################
m:=[ "$(SILENT)" = "1" ] || echo
e:=@ #comment out for debugging
dbgparser:=-DflagDEBUG -ggdb3
thisfile:=$(MAKEFILE_LIST)$(.MAKEFILE_LIST)
color:=if [ "$(COLOR)" = "auto" ]; then [ -t 1 ] && c=1 || c=0; else c="$(COLOR)"; fi
pass:=$(color); UPP_NESTS="$(NESTS)" UPP_FLAGS="$(FLAGS)" \
UPP_INCPATHS="$(INCPATHS)" UPP_LIBPATHS="$(LIBPATHS)" UPP_OUT="$(OUT)" \
UPP_BIN="$(BIN)" UPP_AR="$(AR)" UPP_MKDIRP="$(MKDIRP)" UPP_CC="$(CC)" \
UPP_CXX="$(CXX)" UPP_CFLAGS="$(CFLAGS)" UPP_CXXFLAGS="$(CXXFLAGS)" \
UPP_LDFLAGS="$(LDFLAGS)" UPP_SPEEDFLAGS="$(SPEEDFLAGS)" \
UPP_SIZEFLAGS="$(SIZEFLAGS)" UPP_PLATFORM="$(PLATFORM)" \
UPP_SILENT="$(SILENT)" UPP_ECHO="$(ECHO)" UPP_DEPS="$(DEPS)" \
UPP_RUN="$(RUN)" UPP_TARGET="$(TARGET)" UPP_USEMAINCFG="$(USEMAINCFG)" \
UPP_OPT="$(OPT)" UPP_INTERACTIVE="$(INTERACTIVE)" UPP_COLOR="$$c" \
UPP_HIGHLIGHT="$(HIGHLIGHT)"
all: no-package-specified build
do-build: $(OUT)/parser $(OUT)/brc.sh $(OUT)/color.sh
+$e set -e; $(color); B=""; N=""; C=""; color=""; \
[ $$c -eq 1 ] && color="$(SHELL) $(OUT)/color.sh" && B="\e[1m" && N="\e[0m" && C="\e[1;3$(HIGHLIGHT)m"; \
for pkg in $(PKG) ; do \
$m $${B}Parsing package $$C$$pkg$$N $$B...$$N; \
$(TIME) $(pass) $$color $(OUT)/parser $$pkg; \
$m $${B}Building package$$N $$C$$pkg$$N $$B...$$N; \
$(TIME) $$color $(MAKE) -j 3 -f $(OUT)/Makefile && \
$m $${B}Package$$N $$C$$pkg$$N$$B finished ...$$N; \
done; set +e
no-package-specified:
$e if [ -z "$(PKG)" ]; then sed '/^$$/{s/.*//;q;}' $(thisfile) && false; fi
$(OUT)/parser: $(OUT)/parser.cpp
@$m Compiling parser...
+$e $(TIME) $(CXX) -x c++ -o $@ $^ $(dbgparser)
$(OUT)/parser.cpp: $(thisfile)
@$m "Extracting parser..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#://p;' $< | base64 -d | gzip -d > $@
$(OUT)/brc.sh: $(thisfile)
@$m "Extracting brc parser..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#~//p;' $< | base64 -d | gzip -d > $@
$(OUT)/color.sh: $(thisfile)
@$m "Extracting colorizer script..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#%//p;' $< | base64 -d | gzip -d > $@
build: do-build
$e for pkg in $(PKG); do \
if [ "$(RUN)" = "1" ]; then \
for target in "$(TARGET)" "$(BIN)/$(TARGET)" "$(BIN)/$$pkg"; do \
[ -f "$$target" ] && break; \
done; \
[ -e "$$target" ] && { $m "Running $$target"; } && $$target; \
fi; \
done
simulate: $(OUT)/Makefile
+$e for pkg in $(PKG) ; do \
$m Parsing package $$pkg ... && \
$(pass) $(OUT)/parser $$pkg && \
$m Building package $$pkg ... && \
$(MAKE) -nf $(OUT)/Makefile; \
done
help:
$e sed '/^$$/{s/.*//;q;}' $(thisfile);
clean:
+$e for pkg in $(PKG); do \
$m Parsing package $$pkg... && \
$(pass) $(OUT)/parser $$pkg && \
$m Cleaning package $$pkg && \
$(MAKE) -f $(OUT)/Makefile clean; \
done
dist-clean:
@$m Deleting $(OUT) ...
$e rm -rf $(OUT)
parser-clean:
@$m Deleting parser files ...
$e rm -f $(OUT)/parser $(OUT)/parser.cpp
.SUFFIXES:
.PHONY: all help simulate clean dist-clean parser-clean \
build do-build no-package-specified
########################################################################
# __ __ _ _ __ __ __ _ _ ___ ___ __ __ ___ #
# ( )( ) _( )_ _( )_ ( \/ ) ( ) ( )/ )( _)( _)( )( ) ( _) #
# )(__)( (_ _)(_ _) ) ( /__\ ) \ ) _) ) _) )( )(__ ) _) #
# \____/ (_) (_) (_/\/\_)(_)(_)(_)\_)(___)(_) (__)(____)(___) #
# #
############################## USAGE ###################################
# This makefile is controlled through a set of variables, similar to #
# any other makefile. The prefered way to change them is via command #
# line, e.g.: make PKG="ide usvn" CXX=g++ #
# #
# All of the variables that can control the bahaviour are listed below #
# in DEFAULTS section. Also their default value is shown here. Notice #
# that many of them can contain shell commands (enclosed in ``) which #
# are evaluated before parsing and building each package.
# #
# For boolean type of variables value "1" represents true, anything #
# else is evaluated as false. #
############################# TARGETS ##################################
# This makefile defines five targets that are meant to be used #
# directly by user from the command line: #
# #
# all - builds all (default if any packages are specified) #
# help - shows this help (default if no packages are given) #
# simulate - prints all commands, without executing them #
# clean - deletes all compiled files related to given packages #
# dist-clean - deletes the entire OUT directory (including parsers) #
############################# EXAMPLES #################################
# Typical usage: #
# make PKG=ide FLAGS="GCC" #
# More complicated usage: #
# make PKG="ide UWord Bombs" FLAGS="GCC .NOGTK" ECHO=1 #
# Show help: #
# make help #
# Silent mode: #
# make PKG=ide SILENT=1 #
############################# DEFAULTS #################################
# List of packages to build (space separated). If empty, this help #
# text will be shown. #
PKG:=
# Paths where to look for packages. #
NESTS:=uppsrc bazaar examples reference tutorial $$HOME/MyApps
# Building flags (as in TheIDE).
FLAGS:=GCC
# Additional include paths for compiler (without the leading "-I"). #
INCPATHS:= /usr/include/freetype2 /usr/include/gtk-2.0
INCPATHS+= /usr/local/include/gtk-2.0 /usr/include/glib-2.0
INCPATHS+= /usr/local/include/glib-2.0 /usr/lib/glib-2.0/include
INCPATHS+= /usr/local/lib/glib-2.0/include /usr/lib/gtk-2.0/include
INCPATHS+= /usr/local/lib/gtk-2.0/include /usr/include/cairo
INCPATHS+= /usr/include/pango-1.0 /usr/include/atk-1.0
INCPATHS+= /usr/X11R6/include /usr/X11R6/include/freetype2
INCPATHS+= /usr/X11R6/include/gtk-2.0 /usr/X11R6/include/glib-2.0
INCPATHS+= /usr/X11R6/lib/glib-2.0/include
INCPATHS+= /usr/X11R6/lib/gtk-2.0/include /usr/X11R6/include/cairo
INCPATHS+= /usr/X11R6/include/pango-1.0 /usr/X11R6/include/atk-1.0
INCPATHS+= /usr/local/include/cairo /usr/local/include/pango-1.0
INCPATHS+= /usr/local/include/atk-1.0 /usr/local/include
INCPATHS+= /usr/local/include/libpng /usr/include/gdk-pixbuf-2.0
INCPATHS+= /usr/lib/i386-linux-gnu/glib-2.0/include
INCPATHS+= /usr/lib/x86_64-linux-gnu/glib-2.0/include
# Paths to libraries for linker. #
LIBPATHS:=/usr/X11R6/lib /usr/lib /usr/local/lib
# Directory to store intermediate object files #
OUT:=_out
# Directory where the resulting binaries will be stored #
BIN:=$(OUT)/bin
# ar command #
AR:=ar -src
# Command to create directories equivalent to "mkdir -p". The only #
# good reason to change is if your platform uses mkdir command which #
# doesn't support the -p option #
MKDIRP:=mkdir -p
# C compiler command #
CC:=cc
# C++ compiler command #
CXX:=c++
# Options for C/C++ preprocessor #
CPPFLAGS:=
# Options for C compiler #
CFLAGS:=
# Options for C++ compiler #
CXXFLAGS:=
# Options for linker #
LDFLAGS:=-Wl,--gc-sections -Wl,-s -Wl,-O,2
# Additional options for speed optimization #
SPEEDFLAGS:=-O3 -ffunction-sections -fdata-sections
# Additional options for size optimization #
SIZEFLAGS:=-Os -finline-limit=20 -ffunction-sections -fdata-sections
# Optimization, supply SPEED or SIZE to optimize the executables #
OPT:=
# Platform flag, added to FLAGS, can include shell commands #
PLATFORM:=`uname | tr a-z A-Z` POSIX
# Suppress all messagges #
SILENT:=0
# Print each executed command #
ECHO:=0
# Use dependency files. This will probably work only with gcc-like #
# compilers (requires -MD option). The build usually works correctly #
# even without specifying the dependencies unless you modify included #
# files (*.h, *.lay, ...) without modifying the *.c/cpp files that #
# include them. #
DEPS:=0
# Run the executable(s) sequntially when compiled #
RUN:=0
# Override default name of final executable (absolute or relative path)
TARGET:=
# Add flags from based on mainconfig section (1-based index, set #
# to 0 to disable completely #
USEMAINCFG:=1
# Ask for some additional details during parsing #
INTERACTIVE:=0
# Use colorized output, recognized values are 0, 1 or auto #
COLOR:=auto
# What color should be used in colorized mode, number from 0 to 7 #
HIGHLIGHT:=4
TIME:=TIMEFORMAT=" time taken: %Es"; time
########################################################################
m:=[ "$(SILENT)" = "1" ] || echo
e:=@ #comment out for debugging
dbgparser:=-DflagDEBUG -ggdb3
thisfile:=$(MAKEFILE_LIST)$(.MAKEFILE_LIST)
color:=if [ "$(COLOR)" = "auto" ]; then [ -t 1 ] && c=1 || c=0; else c="$(COLOR)"; fi
pass:=$(color); UPP_NESTS="$(NESTS)" UPP_FLAGS="$(FLAGS)" \
UPP_INCPATHS="$(INCPATHS)" UPP_LIBPATHS="$(LIBPATHS)" UPP_OUT="$(OUT)" \
UPP_BIN="$(BIN)" UPP_AR="$(AR)" UPP_MKDIRP="$(MKDIRP)" UPP_CC="$(CC)" \
UPP_CXX="$(CXX)" UPP_CFLAGS="$(CFLAGS)" UPP_CXXFLAGS="$(CXXFLAGS)" \
UPP_LDFLAGS="$(LDFLAGS)" UPP_SPEEDFLAGS="$(SPEEDFLAGS)" \
UPP_SIZEFLAGS="$(SIZEFLAGS)" UPP_PLATFORM="$(PLATFORM)" \
UPP_SILENT="$(SILENT)" UPP_ECHO="$(ECHO)" UPP_DEPS="$(DEPS)" \
UPP_RUN="$(RUN)" UPP_TARGET="$(TARGET)" UPP_USEMAINCFG="$(USEMAINCFG)" \
UPP_OPT="$(OPT)" UPP_INTERACTIVE="$(INTERACTIVE)" UPP_COLOR="$$c" \
UPP_HIGHLIGHT="$(HIGHLIGHT)"
all: no-package-specified build
do-build: $(OUT)/parser $(OUT)/brc.sh $(OUT)/color.sh
+$e set -e; $(color); B=""; N=""; C=""; color=""; \
[ $$c -eq 1 ] && color="$(SHELL) $(OUT)/color.sh" && B="\e[1m" && N="\e[0m" && C="\e[1;3$(HIGHLIGHT)m"; \
for pkg in $(PKG) ; do \
$m $${B}Parsing package $$C$$pkg$$N $$B...$$N; \
$(TIME) $(pass) $$color $(OUT)/parser $$pkg; \
$m $${B}Building package$$N $$C$$pkg$$N $$B...$$N; \
$(TIME) $$color $(MAKE) -j 3 -f $(OUT)/Makefile && \
$m $${B}Package$$N $$C$$pkg$$N$$B finished ...$$N; \
done; set +e
no-package-specified:
$e if [ -z "$(PKG)" ]; then sed '/^$$/{s/.*//;q;}' $(thisfile) && false; fi
$(OUT)/parser: $(OUT)/parser.cpp
@$m Compiling parser...
+$e $(TIME) $(CXX) -x c++ -o $@ $^ $(dbgparser)
$(OUT)/parser.cpp: $(thisfile)
@$m "Extracting parser..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#://p;' $< | base64 -d | gzip -d > $@
$(OUT)/brc.sh: $(thisfile)
@$m "Extracting brc parser..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#~//p;' $< | base64 -d | gzip -d > $@
$(OUT)/color.sh: $(thisfile)
@$m "Extracting colorizer script..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#%//p;' $< | base64 -d | gzip -d > $@
build: do-build
$e for pkg in $(PKG); do \
if [ "$(RUN)" = "1" ]; then \
for target in "$(TARGET)" "$(BIN)/$(TARGET)" "$(BIN)/$$pkg"; do \
[ -f "$$target" ] && break; \
done; \
[ -e "$$target" ] && { $m "Running $$target"; } && $$target; \
fi; \
done
simulate: $(OUT)/Makefile
+$e for pkg in $(PKG) ; do \
$m Parsing package $$pkg ... && \
$(pass) $(OUT)/parser $$pkg && \
$m Building package $$pkg ... && \
$(MAKE) -nf $(OUT)/Makefile; \
done
help:
$e sed '/^$$/{s/.*//;q;}' $(thisfile);
clean:
+$e for pkg in $(PKG); do \
$m Parsing package $$pkg... && \
$(pass) $(OUT)/parser $$pkg && \
$m Cleaning package $$pkg && \
$(MAKE) -f $(OUT)/Makefile clean; \
done
dist-clean:
@$m Deleting $(OUT) ...
$e rm -rf $(OUT)
parser-clean:
@$m Deleting parser files ...
$e rm -f $(OUT)/parser $(OUT)/parser.cpp
.SUFFIXES:
.PHONY: all help simulate clean dist-clean parser-clean \
build do-build no-package-specified

View file

@ -62,7 +62,7 @@ public:
~String() {free(p);}
char& operator[](const int n) const {return p[n];}
bool IsEmpty() const {return *p == 0;}
bool IsEmpty() const {return *p == 0 || strlen(p) == 0;}
const char* operator~() const {return p;}
operator const char*() const {return p;}
String& operator=(const String& s) {return operator=(s.p);}
@ -418,7 +418,11 @@ struct Upp{
};
inline void Split(String s,Vector<String>& v){
while(s.GetCount()) v.AddUnique(ReadValue(s,' '));
while(s.GetCount()){
String val = ReadValue(s,' ');
if(val.GetCount())
v.AddUnique(val);
}
}
String FlagDir(const Vector<String>& v){

View file

@ -15,7 +15,7 @@ toBin() {
BZ2) obj=$tmp/obj.bz2; cat "$1" | bzip2 -9 > $obj ;;
*) obj="$1" ;;
esac
hexdump -e '"\t" 16/1 "%i, " "\n"' $obj | sed '$s/[ ,]\+$/, 0/g'
hexdump -v -e '"\t" 16/1 "%i, " "\n"' $obj | sed '$s/[ ,]\+$/, 0/g'
len="`cat $obj | wc -c`"
}

View file

@ -1,3 +1,3 @@
#ifndef _UppBuilder_icpp_init_stub
#define _UppBuilder_icpp_init_stub
#endif
#ifndef _UppBuilder_icpp_init_stub
#define _UppBuilder_icpp_init_stub
#endif

View file

@ -11,14 +11,14 @@ ARCH="`dpkg-architecture -qDEB_HOST_ARCH`"
ide:
sed -i -e 's/IDE_VERSION[ \t]*"\([0-9]*\)[^"]*"/IDE_VERSION "\1-'$(SERIES)-$(ARCH)'"/' $(CURDIR)/uppsrc/ide/version.h
$(MAKE) -f mkfile $(JOBS) PKG=ide "NESTS=uppsrc" "FLAGS=GUI GCC" TARGET=$@ TIME= COLOR=0
$(MAKE) -f mkfile $(JOBS) PKG=ide "NESTS=uppsrc" "FLAGS=GUI GCC" TARGET=`pwd`/$@ TIME= COLOR=0
ide-nogtk:
sed -i -e 's/IDE_VERSION[ \t]*"\([0-9]*\)[^"]*"/IDE_VERSION "\1-'$(SERIES)-$(ARCH)'-nogtk"/' $(CURDIR)/uppsrc/ide/version.h
$(MAKE) -f mkfile $(JOBS) PKG=ide "NESTS=uppsrc" "FLAGS=GUI NOGTK GCC " TARGET=$@ TIME= COLOR=0
$(MAKE) -f mkfile $(JOBS) PKG=ide "NESTS=uppsrc" "FLAGS=GUI .NOGTK GCC" TARGET=`pwd`/$@ TIME= COLOR=0
umk:
$(MAKE) -f mkfile $(JOBS) PKG=umk "NESTS=uppsrc" "FLAGS=GCC" TARGET=$@ TIME= COLOR=0
$(MAKE) -f mkfile $(JOBS) PKG=umk "NESTS=uppsrc" "FLAGS=GCC" TARGET=`pwd`/$@ TIME= COLOR=0
install:
# this is just a trick to rename files

View file

@ -1,368 +1,367 @@
########################################################################
# __ __ _ _ __ __ __ _ _ ___ ___ __ __ ___ #
# ( )( ) _( )_ _( )_ ( \/ ) ( ) ( )/ )( _)( _)( )( ) ( _) #
# )(__)( (_ _)(_ _) ) ( /__\ ) \ ) _) ) _) )( )(__ ) _) #
# \____/ (_) (_) (_/\/\_)(_)(_)(_)\_)(___)(_) (__)(____)(___) #
# #
############################## USAGE ###################################
# This makefile is controlled through a set of variables, similar to #
# any other makefile. The prefered way to change them is via command #
# line, e.g.: make PKG="ide usvn" CXX=g++ #
# #
# All of the variables that can control the bahaviour are listed below #
# in DEFAULTS section. Also their default value is shown here. Notice #
# that many of them can contain shell commands (enclosed in ``) which #
# are evaluated before parsing and building each package.
# #
# For boolean type of variables value "1" represents true, anything #
# else is evaluated as false. #
############################# TARGETS ##################################
# This makefile defines five targets that are meant to be used #
# directly by user from the command line: #
# #
# all - builds all (default if any packages are specified) #
# help - shows this help (default if no packages are given) #
# simulate - prints all commands, without executing them #
# clean - deletes all compiled files related to given packages #
# dist-clean - deletes the entire OUT directory (including parsers) #
############################# EXAMPLES #################################
# Typical usage: #
# make PKG=ide FLAGS="GCC" #
# More complicated usage: #
# make PKG="ide UWord Bombs" FLAGS="GCC .NOGTK" ECHO=1 #
# Show help: #
# make help #
# Silent mode: #
# make PKG=ide SILENT=1 #
############################# DEFAULTS #################################
# List of packages to build (space separated). If empty, this help #
# text will be shown. #
PKG:=
# Paths where to look for packages. #
NESTS:=uppsrc bazaar examples reference tutorial $$HOME/MyApps
# Building flags (as in TheIDE).
FLAGS:=GCC
# Additional include paths for compiler (without the leading "-I"). #
INCPATHS:= /usr/include/freetype2 /usr/include/gtk-2.0
INCPATHS+= /usr/local/include/gtk-2.0 /usr/include/glib-2.0
INCPATHS+= /usr/local/include/glib-2.0 /usr/lib/glib-2.0/include
INCPATHS+= /usr/local/lib/glib-2.0/include /usr/lib/gtk-2.0/include
INCPATHS+= /usr/local/lib/gtk-2.0/include /usr/include/cairo
INCPATHS+= /usr/include/pango-1.0 /usr/include/atk-1.0
INCPATHS+= /usr/X11R6/include /usr/X11R6/include/freetype2
INCPATHS+= /usr/X11R6/include/gtk-2.0 /usr/X11R6/include/glib-2.0
INCPATHS+= /usr/X11R6/lib/glib-2.0/include
INCPATHS+= /usr/X11R6/lib/gtk-2.0/include /usr/X11R6/include/cairo
INCPATHS+= /usr/X11R6/include/pango-1.0 /usr/X11R6/include/atk-1.0
INCPATHS+= /usr/local/include/cairo /usr/local/include/pango-1.0
INCPATHS+= /usr/local/include/atk-1.0 /usr/local/include
INCPATHS+= /usr/local/include/libpng /usr/include/gdk-pixbuf-2.0
INCPATHS+= /usr/lib/i386-linux-gnu/glib-2.0/include
INCPATHS+= /usr/lib/x86_64-linux-gnu/glib-2.0/include
# Paths to libraries for linker. #
LIBPATHS:=/usr/X11R6/lib /usr/lib /usr/local/lib
# Directory to store intermediate object files #
OUT:=_out
# Directory where the resulting binaries will be stored #
BIN:=$(OUT)/bin
# ar command #
AR:=ar -src
# Command to create directories equivalent to "mkdir -p". The only #
# good reason to change is if your platform uses mkdir command which #
# doesn't support the -p option #
MKDIRP:=mkdir -p
# C compiler command #
CC:=cc
# C++ compiler command #
CXX:=c++
# Options for C/C++ preprocessor #
CPPFLAGS:=
# Options for C compiler #
CFLAGS:=
# Options for C++ compiler #
CXXFLAGS:=
# Options for linker #
LDFLAGS:=-Wl,--gc-sections -Wl,-s -Wl,-O,2
# Additional options for speed optimization #
SPEEDFLAGS:=-O3 -ffunction-sections -fdata-sections
# Additional options for size optimization #
SIZEFLAGS:=-Os -finline-limit=20 -ffunction-sections -fdata-sections
# Optimization, supply SPEED or SIZE to optimize the executables #
OPT:=
# Platform flag, added to FLAGS, can include shell commands #
PLATFORM:=`uname | tr a-z A-Z` POSIX
# Suppress all messagges #
SILENT:=0
# Print each executed command #
ECHO:=0
# Use dependency files. This will probably work only with gcc-like #
# compilers (requires -MD option). The build usually works correctly #
# even without specifying the dependencies unless you modify included #
# files (*.h, *.lay, ...) without modifying the *.c/cpp files that #
# include them. #
DEPS:=0
# Run the executable(s) sequntially when compiled #
RUN:=0
# Override default name of final executable (absolute or relative path)
TARGET:=
# Add flags from based on mainconfig section (1-based index, set #
# to 0 to disable completely #
USEMAINCFG:=1
# Ask for some additional details during parsing #
INTERACTIVE:=0
# Use colorized output, recognized values are 0, 1 or auto #
COLOR:=auto
# What color should be used in colorized mode, number from 0 to 7 #
HIGHLIGHT:=4
TIME:=TIMEFORMAT=" time taken: %Es"; time
########################################################################
m:=[ "$(SILENT)" = "1" ] || echo
e:=@ #comment out for debugging
dbgparser:=-DflagDEBUG -ggdb3
thisfile:=$(MAKEFILE_LIST)$(.MAKEFILE_LIST)
color:=if [ "$(COLOR)" = "auto" ]; then [ -t 1 ] && c=1 || c=0; else c="$(COLOR)"; fi
pass:=$(color); UPP_NESTS="$(NESTS)" UPP_FLAGS="$(FLAGS)" \
UPP_INCPATHS="$(INCPATHS)" UPP_LIBPATHS="$(LIBPATHS)" UPP_OUT="$(OUT)" \
UPP_BIN="$(BIN)" UPP_AR="$(AR)" UPP_MKDIRP="$(MKDIRP)" UPP_CC="$(CC)" \
UPP_CXX="$(CXX)" UPP_CFLAGS="$(CFLAGS)" UPP_CXXFLAGS="$(CXXFLAGS)" \
UPP_LDFLAGS="$(LDFLAGS)" UPP_SPEEDFLAGS="$(SPEEDFLAGS)" \
UPP_SIZEFLAGS="$(SIZEFLAGS)" UPP_PLATFORM="$(PLATFORM)" \
UPP_SILENT="$(SILENT)" UPP_ECHO="$(ECHO)" UPP_DEPS="$(DEPS)" \
UPP_RUN="$(RUN)" UPP_TARGET="$(TARGET)" UPP_USEMAINCFG="$(USEMAINCFG)" \
UPP_OPT="$(OPT)" UPP_INTERACTIVE="$(INTERACTIVE)" UPP_COLOR="$$c" \
UPP_HIGHLIGHT="$(HIGHLIGHT)"
all: no-package-specified build
do-build: $(OUT)/parser $(OUT)/brc.sh $(OUT)/color.sh
+$e set -e; $(color); B=""; N=""; C=""; color=""; \
[ $$c -eq 1 ] && color="$(SHELL) $(OUT)/color.sh" && B="\e[1m" && N="\e[0m" && C="\e[1;3$(HIGHLIGHT)m"; \
for pkg in $(PKG) ; do \
$m $${B}Parsing package $$C$$pkg$$N $$B...$$N; \
$(TIME) $(pass) $$color $(OUT)/parser $$pkg; \
$m $${B}Building package$$N $$C$$pkg$$N $$B...$$N; \
$(TIME) $$color $(MAKE) -j 3 -f $(OUT)/Makefile && \
$m $${B}Package$$N $$C$$pkg$$N$$B finished ...$$N; \
done; set +e
no-package-specified:
$e if [ -z "$(PKG)" ]; then sed '/^$$/{s/.*//;q;}' $(thisfile) && false; fi
$(OUT)/parser: $(OUT)/parser.cpp
@$m Compiling parser...
+$e $(TIME) $(CXX) -x c++ -o $@ $^ $(dbgparser)
$(OUT)/parser.cpp: $(thisfile)
@$m "Extracting parser..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#://p;' $< | base64 -d | gzip -d > $@
$(OUT)/brc.sh: $(thisfile)
@$m "Extracting brc parser..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#~//p;' $< | base64 -d | gzip -d > $@
$(OUT)/color.sh: $(thisfile)
@$m "Extracting colorizer script..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#%//p;' $< | base64 -d | gzip -d > $@
build: do-build
$e for pkg in $(PKG); do \
if [ "$(RUN)" = "1" ]; then \
for target in "$(TARGET)" "$(BIN)/$(TARGET)" "$(BIN)/$$pkg"; do \
[ -f "$$target" ] && break; \
done; \
[ -e "$$target" ] && { $m "Running $$target"; } && $$target; \
fi; \
done
simulate: $(OUT)/Makefile
+$e for pkg in $(PKG) ; do \
$m Parsing package $$pkg ... && \
$(pass) $(OUT)/parser $$pkg && \
$m Building package $$pkg ... && \
$(MAKE) -nf $(OUT)/Makefile; \
done
help:
$e sed '/^$$/{s/.*//;q;}' $(thisfile);
clean:
+$e for pkg in $(PKG); do \
$m Parsing package $$pkg... && \
$(pass) $(OUT)/parser $$pkg && \
$m Cleaning package $$pkg && \
$(MAKE) -f $(OUT)/Makefile clean; \
done
dist-clean:
@$m Deleting $(OUT) ...
$e rm -rf $(OUT)
parser-clean:
@$m Deleting parser files ...
$e rm -f $(OUT)/parser $(OUT)/parser.cpp
.SUFFIXES:
.PHONY: all help simulate clean dist-clean parser-clean \
build do-build no-package-specified
########################################################################
# __ __ _ _ __ __ __ _ _ ___ ___ __ __ ___ #
# ( )( ) _( )_ _( )_ ( \/ ) ( ) ( )/ )( _)( _)( )( ) ( _) #
# )(__)( (_ _)(_ _) ) ( /__\ ) \ ) _) ) _) )( )(__ ) _) #
# \____/ (_) (_) (_/\/\_)(_)(_)(_)\_)(___)(_) (__)(____)(___) #
# #
############################## USAGE ###################################
# This makefile is controlled through a set of variables, similar to #
# any other makefile. The prefered way to change them is via command #
# line, e.g.: make PKG="ide usvn" CXX=g++ #
# #
# All of the variables that can control the bahaviour are listed below #
# in DEFAULTS section. Also their default value is shown here. Notice #
# that many of them can contain shell commands (enclosed in ``) which #
# are evaluated before parsing and building each package.
# #
# For boolean type of variables value "1" represents true, anything #
# else is evaluated as false. #
############################# TARGETS ##################################
# This makefile defines five targets that are meant to be used #
# directly by user from the command line: #
# #
# all - builds all (default if any packages are specified) #
# help - shows this help (default if no packages are given) #
# simulate - prints all commands, without executing them #
# clean - deletes all compiled files related to given packages #
# dist-clean - deletes the entire OUT directory (including parsers) #
############################# EXAMPLES #################################
# Typical usage: #
# make PKG=ide FLAGS="GCC" #
# More complicated usage: #
# make PKG="ide UWord Bombs" FLAGS="GCC .NOGTK" ECHO=1 #
# Show help: #
# make help #
# Silent mode: #
# make PKG=ide SILENT=1 #
############################# DEFAULTS #################################
# List of packages to build (space separated). If empty, this help #
# text will be shown. #
PKG:=
# Paths where to look for packages. #
NESTS:=uppsrc bazaar examples reference tutorial $$HOME/MyApps
# Building flags (as in TheIDE).
FLAGS:=GCC
# Additional include paths for compiler (without the leading "-I"). #
INCPATHS:= /usr/include/freetype2 /usr/include/gtk-2.0
INCPATHS+= /usr/local/include/gtk-2.0 /usr/include/glib-2.0
INCPATHS+= /usr/local/include/glib-2.0 /usr/lib/glib-2.0/include
INCPATHS+= /usr/local/lib/glib-2.0/include /usr/lib/gtk-2.0/include
INCPATHS+= /usr/local/lib/gtk-2.0/include /usr/include/cairo
INCPATHS+= /usr/include/pango-1.0 /usr/include/atk-1.0
INCPATHS+= /usr/X11R6/include /usr/X11R6/include/freetype2
INCPATHS+= /usr/X11R6/include/gtk-2.0 /usr/X11R6/include/glib-2.0
INCPATHS+= /usr/X11R6/lib/glib-2.0/include
INCPATHS+= /usr/X11R6/lib/gtk-2.0/include /usr/X11R6/include/cairo
INCPATHS+= /usr/X11R6/include/pango-1.0 /usr/X11R6/include/atk-1.0
INCPATHS+= /usr/local/include/cairo /usr/local/include/pango-1.0
INCPATHS+= /usr/local/include/atk-1.0 /usr/local/include
INCPATHS+= /usr/local/include/libpng /usr/include/gdk-pixbuf-2.0
INCPATHS+= /usr/lib/i386-linux-gnu/glib-2.0/include
INCPATHS+= /usr/lib/x86_64-linux-gnu/glib-2.0/include
# Paths to libraries for linker. #
LIBPATHS:=/usr/X11R6/lib /usr/lib /usr/local/lib
# Directory to store intermediate object files #
OUT:=_out
# Directory where the resulting binaries will be stored #
BIN:=$(OUT)/bin
# ar command #
AR:=ar -src
# Command to create directories equivalent to "mkdir -p". The only #
# good reason to change is if your platform uses mkdir command which #
# doesn't support the -p option #
MKDIRP:=mkdir -p
# C compiler command #
CC:=cc
# C++ compiler command #
CXX:=c++
# Options for C/C++ preprocessor #
CPPFLAGS:=
# Options for C compiler #
CFLAGS:=
# Options for C++ compiler #
CXXFLAGS:=
# Options for linker #
LDFLAGS:=-Wl,--gc-sections -Wl,-s -Wl,-O,2
# Additional options for speed optimization #
SPEEDFLAGS:=-O3 -ffunction-sections -fdata-sections
# Additional options for size optimization #
SIZEFLAGS:=-Os -finline-limit=20 -ffunction-sections -fdata-sections
# Optimization, supply SPEED or SIZE to optimize the executables #
OPT:=
# Platform flag, added to FLAGS, can include shell commands #
PLATFORM:=`uname | tr a-z A-Z` POSIX
# Suppress all messagges #
SILENT:=0
# Print each executed command #
ECHO:=0
# Use dependency files. This will probably work only with gcc-like #
# compilers (requires -MD option). The build usually works correctly #
# even without specifying the dependencies unless you modify included #
# files (*.h, *.lay, ...) without modifying the *.c/cpp files that #
# include them. #
DEPS:=0
# Run the executable(s) sequntially when compiled #
RUN:=0
# Override default name of final executable (absolute or relative path)
TARGET:=
# Add flags from based on mainconfig section (1-based index, set #
# to 0 to disable completely #
USEMAINCFG:=1
# Ask for some additional details during parsing #
INTERACTIVE:=0
# Use colorized output, recognized values are 0, 1 or auto #
COLOR:=auto
# What color should be used in colorized mode, number from 0 to 7 #
HIGHLIGHT:=4
TIME:=TIMEFORMAT=" time taken: %Es"; time
########################################################################
m:=[ "$(SILENT)" = "1" ] || echo
e:=@ #comment out for debugging
dbgparser:=-DflagDEBUG -ggdb3
thisfile:=$(MAKEFILE_LIST)$(.MAKEFILE_LIST)
color:=if [ "$(COLOR)" = "auto" ]; then [ -t 1 ] && c=1 || c=0; else c="$(COLOR)"; fi
pass:=$(color); UPP_NESTS="$(NESTS)" UPP_FLAGS="$(FLAGS)" \
UPP_INCPATHS="$(INCPATHS)" UPP_LIBPATHS="$(LIBPATHS)" UPP_OUT="$(OUT)" \
UPP_BIN="$(BIN)" UPP_AR="$(AR)" UPP_MKDIRP="$(MKDIRP)" UPP_CC="$(CC)" \
UPP_CXX="$(CXX)" UPP_CFLAGS="$(CFLAGS)" UPP_CXXFLAGS="$(CXXFLAGS)" \
UPP_LDFLAGS="$(LDFLAGS)" UPP_SPEEDFLAGS="$(SPEEDFLAGS)" \
UPP_SIZEFLAGS="$(SIZEFLAGS)" UPP_PLATFORM="$(PLATFORM)" \
UPP_SILENT="$(SILENT)" UPP_ECHO="$(ECHO)" UPP_DEPS="$(DEPS)" \
UPP_RUN="$(RUN)" UPP_TARGET="$(TARGET)" UPP_USEMAINCFG="$(USEMAINCFG)" \
UPP_OPT="$(OPT)" UPP_INTERACTIVE="$(INTERACTIVE)" UPP_COLOR="$$c" \
UPP_HIGHLIGHT="$(HIGHLIGHT)"
all: no-package-specified build
do-build: $(OUT)/parser $(OUT)/brc.sh $(OUT)/color.sh
+$e set -e; $(color); B=""; N=""; C=""; color=""; \
[ $$c -eq 1 ] && color="$(SHELL) $(OUT)/color.sh" && B="\e[1m" && N="\e[0m" && C="\e[1;3$(HIGHLIGHT)m"; \
for pkg in $(PKG) ; do \
$m $${B}Parsing package $$C$$pkg$$N $$B...$$N; \
$(TIME) $(pass) $$color $(OUT)/parser $$pkg; \
$m $${B}Building package$$N $$C$$pkg$$N $$B...$$N; \
$(TIME) $$color $(MAKE) -j 3 -f $(OUT)/Makefile && \
$m $${B}Package$$N $$C$$pkg$$N$$B finished ...$$N; \
done; set +e
no-package-specified:
$e if [ -z "$(PKG)" ]; then sed '/^$$/{s/.*//;q;}' $(thisfile) && false; fi
$(OUT)/parser: $(OUT)/parser.cpp
@$m Compiling parser...
+$e $(TIME) $(CXX) -x c++ -o $@ $^ $(dbgparser)
$(OUT)/parser.cpp: $(thisfile)
@$m "Extracting parser..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#://p;' $< | base64 -d | gzip -d > $@
$(OUT)/brc.sh: $(thisfile)
@$m "Extracting brc parser..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#~//p;' $< | base64 -d | gzip -d > $@
$(OUT)/color.sh: $(thisfile)
@$m "Extracting colorizer script..."
+$e [ -d $(OUT) ] || $(MKDIRP) $(OUT)
+$e $(TIME) sed -n 's/^#%//p;' $< | base64 -d | gzip -d > $@
build: do-build
$e for pkg in $(PKG); do \
if [ "$(RUN)" = "1" ]; then \
for target in "$(TARGET)" "$(BIN)/$(TARGET)" "$(BIN)/$$pkg"; do \
[ -f "$$target" ] && break; \
done; \
[ -e "$$target" ] && { $m "Running $$target"; } && $$target; \
fi; \
done
simulate: $(OUT)/Makefile
+$e for pkg in $(PKG) ; do \
$m Parsing package $$pkg ... && \
$(pass) $(OUT)/parser $$pkg && \
$m Building package $$pkg ... && \
$(MAKE) -nf $(OUT)/Makefile; \
done
help:
$e sed '/^$$/{s/.*//;q;}' $(thisfile);
clean:
+$e for pkg in $(PKG); do \
$m Parsing package $$pkg... && \
$(pass) $(OUT)/parser $$pkg && \
$m Cleaning package $$pkg && \
$(MAKE) -f $(OUT)/Makefile clean; \
done
dist-clean:
@$m Deleting $(OUT) ...
$e rm -rf $(OUT)
parser-clean:
@$m Deleting parser files ...
$e rm -f $(OUT)/parser $(OUT)/parser.cpp
.SUFFIXES:
.PHONY: all help simulate clean dist-clean parser-clean \
build do-build no-package-specified
### PARSER CODE (gzipped and base64 encoded) ###
#:H4sIAI+CLk8CA7Q7bVPbSNKfoYr/MGgJSFjYJle3e4sROZY4WerAULzsJgs8WVkag4IsKZJsYA
#:n89qe7Z0YayS8hW3epFEgzPd09Pf2u4Ycg8sKRz9n2KAqy3G/e7Cz+UIx5+UPCq0MRv9NfszwN
#:ousqCKAJg/7EWBDj0GLOh0no5nzbC90sY2c7i0EUBhFn4zjwWa/7W/fEPGOZ9bi4EAxM+r0wSI
#:BKDm+5z9PUNronJ0cnW+w0HvL8Buiz/MbNWXYTj0KfRXzMU3bjJgmPuA8PWfHSbDYvI8PqAEp+
#:H+TmJj4+LT51prElHn7jXh6nyEwEFIK/uO2GYezBurN1lnQWk1E/DLytxQUBaFpbCGS2LZsRID
#:0l8JPJf48nnCBeW52nxYVntYzN/6dWtWmVlBiy9J7ne/Eoyk3Li6Msr61KeT5KI+JbW3e2yuKE
#:py4QvrgyEUtkTV2XXERX2jpBYepqMVVfB6C7vm/SGeJhAhs7DonFYjC0oESxLsbwXCSGdRMUzU
#:waON9oWOxMnJTCWHByb7FHJtcQKee+wwq48yj4MuIl9FhwAiwncea8CyLfHBNVYA5Gdhw4pmIL
#:MHClcYTYx5ILxECrNcxCBKStcJ4IETjtTrBNsg9gDziFhMaOk1wEVwWlAIk8lYQ2NgURsgcpIU
#:QX8qgiSPWu0YMhnSJOLoAQA2tj5/nMpJ0u4CwBSqoJc5h5tm6lXOhrYsPkOkLFA/PMokU0Ixc9
#:LYIxjsFSCp3fPtspVcKRMtGmQOrCxoRFnZLLYMC6d+OmVSMSc2ANW3UDSMD4U3+UmIZhwZk/Fb
#:CCnHhZBb8BSwvYrJlY1gSsIJsJIiUsoCW8zwUTE0Y4SDk3EzJBwX3FFAT2ikHMNql+HIdsP+sO
#:k/zBnARn0w15HU7LYW1EoO9FMfE8E1NBHpcqcKbhmM1DZamSc/24NflPWVpC44kU2y+GnfrJ1F
#:hReJbhrLxhAjoKQLPRaMxUEE1DI/khY9sLufttV6wrAkPrKRWzI31D6ZRferCAA8xL6lZdyI3J
#:jaHhl/oGSyUjEkl9NitncceswdDJLIhFbh54nzw3y7dJ/jtm6QoE5gahEK5ABOhlQWPIh8N4DJ
#:JoIBxJ0xawuiuHEJ0JlzZtY0DyRft5Ma+vpzCaXODkFaIoXxubONB+Gat1FRWemJkJW3ZQ0cgT
#:02bWvTh5KNVCyGJBaQw+41YQqOb4NeoohL14mLgpr9K1lXycjc0i6pYoYOIN0I2EdmfoyiEhUd
#:qe1cLXAchRQ888HWMZVYpjgMgU7GBQ29iwZDDDSOY4XjWY1QJZLVrWjFxFZFQbRUrITGmCU9GD
#:anTF+Q1cWgQ8DI9KAo1AyAB9+xwGZUQ6DHzNh4OupbnNKkp5nd+UctcY13V1gxbKpAKGttsySl
#:dzWGZ00zROt9h+NHZDcD5w1i6kszzNWB4jL8siUdUy1YWnjtQ6ooFGtyO4Yqurkr+dNklBMCWG
#:IPIuqD2S+pMukueDF/g93bKGwrAAR2OzYlJqJVi/lzyYZPRoeFJiqHMSMZoZ2tjaZXtNk7tU8k
#:VgJOCRrzKCwivUvF14k6lzUEPpDamIXI+noBZvv3QxyFKmtX+PPByq3I7MFwAOHKuDk4B9UcvR
#:v5O3EjMANJUbeJZsLy5Kfk+46//mhpDfFmHBJjP2eRgMN1Hs9po28lqMqMLKcSBgKaswjE5hBm
#:lHFju3QeKgd7y7CUJumtkFjoC1S/xfvzI5hDmJJFEObjv/eG2hXsr3ZYc0E58bDcBKIamJNodD
#:eJoUzL84AzfMeEcwedEGemuXBnGtLRHm8AXe83TEhTrp3sWTnh6dRQc8cod5MgMHrOuevofijZ
#:g3vyDLOEZU8cW72IBAsYxafAkjfYg4tx2Fadsxv7xpb8FWySvkQUTsLKSoCeuedIAD84uFHMht
#:47AUfEqKuEhb34MNjIaV49QdJiTUQUwpvwoBylvKGSmzQmPkOAUBx2nXRKjMVDJSylEOyGNA7n
#:g0GrKjJH/sHfW6Njs97nbfwq/9P7owqyZPwYNwKMbOe//pHf3es1nvyGYfu6cMMQCnIw+jQMiB
#:C4AGm8hLlYvA84HjcKNrGEMgKKMBwER6kL9rMtrPTuNR6nEToVbZQIkD67lBE/E0i8i21lyTMl
#:mGaavcq9IwSZ3f5yAVuRpFA9AN0rBqrAG4ZpnZqYADoxgD8ziM73hqildBl+FbcRyGlyRgcZi/
#:Ly5g7gfqVpkPvgXgefOn7+/lvGiaNFGgDg1POWjGQQhsksmpKLzvwNBPp+LA4RfqGyXjp1As3v
#:DMrOS8+oEwqHT182BBaeIZpSXCYOl5rbVWtHqkMoIW7ud8+Fjowd0NFbjyLYA5eBuOcrcf8lLD
#:MVIi53I5NnxwxJR6X1XXg9j1AVDbha0VXWz9lj/YqlSWCKlgZsJJK4+Q2QBoiSSzdItsjUJ93S
#:tWd6PBm8KLLuCMQ4mAlr+0y/dxWLyjvCt+1SG0hUcVaS9mG+TcFqRXxNNHcohLTUhlUbOWZAYW
#:j8ONDQFDKROSR+UpPa3IksUPpF9suG0rLzbFsSG4HwsOpWxX2dAZN6lPRIuGTYlOCQtG8NxhpI
#:yumY1Rk2aVTgooQUVERxQx7UuCvkDL5Tn94ma8B55nWomnPFumObXWDKeWlUElq3gxjdbbIP1v
#:kKJsoUKrbSOEoFXNqtACyKNXaQ4okGkZB9lD/2Kz3W5j1+3d/kF3nQ2cAeROkfk8iGwjNRQ3g2
#:reQh0XLVNZHmDramCRgkUNB9Jd1zf79qaN2O2BOKCG08ffrRZWXQz+u+zG9W7RPtMULJIFwyTk
#:Qx5hZhxH7E40l2OgxTnknDkicVK5/ciqHHNKiVpVEuCqutG4Yk5RNcJjRlZKJTGN8+PjT7TrpO
#:GgfurQqXMN1QIgpNxJ0X2TbmUd3cudJ8ljNc76PPPSIKHUwA/Sjh6Pa64IRxGMwT5u8Wc/dVPw
#:WK7vD0L3GpwZpPzAhs1GGafalNr9IMNRlsfDEqGgv8Ncz+PgDgFgcH1LP8c2I1QlLGrLDhvATx
#:xcXIAdUEOwkhDQaFWlEjg995ojKO7TVO/2S1falc6lZHkVjjvLSfs1Ftgj6rUiYQuQ2Q0pILnK
#:Rla1SY5MOs6I0g5cSkD1doNc+ShKL3QnEOgq/YKyfsVYGLpwEqa0HjIAzcaEeydLqSfb0nQ2ZZ
#:ca4DCFHsDZeqYwGLQ8SIu7R+8oT16mRBnz5M6apftqBKPc/1HFg+W0WTY6YVF6kWpxG5Lr5SKW
#:ycQZXoXf11NqmXAIGswUYQSSdKp9y/xckP3iLH/pFEEjlEm3RO/VGi8oG6kZq+Sw/oZ+kK/BE5
#:XA1IJDn4Yfli7wQHq7h91Ph7sfrrQg7d35wBpK+c43EdJmOqho5AEMMG20DG3hgMKVPGezd35w
#:MNEcgfyIWJuaIy2A5WPjnyAgQRIZQmvtjWFsAUHsEKopeATa8FPb2cIAoybiUJNFGCvMEGaaI8
#:hoBTxqE/ny0pWTcgw03XkS6cryYH7H5FhQYK8ycscD2Ju/fBkZNntWxCcaJ7UOSEXbMXUobafU
#:drPI3sBhGcIVZoYtnaIFZoCAmIlXANFXGsJlzoEhT2oUPnUmJDlHo3S5MwGFJzaUS54Jh57aEA
#:57Joz040bh0S0RTCsmqGWnhhZTDEtZfiWjMI3Ly3/89JM8ePnBTdp8piV0OIqqc2kYnXkURSQR
#:0rGU1fuxzCllnKFUT8vkLEl9RtI2k1gU98Mg/6vYWqvFgusoTiEPAIsDLbybt3roghTjaBBc65
#:zKhwWMhLP4lHqq4WIGHhrTRi7xg5gE14YdJWkkMP4vEfheuaGlDIO/+KcsgZwJ0BAWGIUDpy6C
#:sNNvrIUftaX7f3TnrMTUoTiqQiUwrWADuW1R7NfTfLamxELRMePYk8VgXETJQmLrmWhttTF42U
#:UtUziZPJ2NvMJuns4SE7FZl5VWSM1AoUlLx6BENgtBsVltcSkAWccUpZjw08U8yqLozAysUhqy
#:XhLiLvZPuR2p5MCqYP1e/RJpZulx6qXxZHFcKQXFcq0enKiHp1TPk0XytDI5m6iRK1XynDp5Tq
#:VcrZVnV8vFIclfRZk7UTVLiKLqrVbQVbmrqopWVGL2wAvjInLWP2ZVikLR2UnAmZrKUux6PkWX
#:NKQiaLmLxciLySsdddOqdMbfQVSAUtecnq8R/lpdghlgq5VRyQcxL+Mp1XxZnEKZlzblLYyxzs
#:5Ee3A8pTmYknKNZUcQYwUt+Oxsdtjn6grWaHwWulJvZD+PLz5fqfQ9cD7TZyspIfweJ3Lq4Kpo
#:wXnWTluqHYw3Nq8cnBZpjVAfSn7FlFf5BpYBKBXg5d42YW/plL1lDcdoGg2JuuxCPKmLHsduCo
#:IshQ3p9Q5LbqnWk+QwNE7coSpOhTJQWR/aTJWckDFlIr0C14a4xLcrJlVMton3fWLfs/TPo1A0
#:7IBFuVQzeGwbnv9ao3gnZ3a1mT/EjDDCT2saVFuD+nlNVv4iZBy6uXeD+qd1/CgRur1WvUnNfy
#:1LZ1vcSyiXZzYu6UwsMYscggj20Whp1VGqrdEzAUtmApJIX8u0s7Iw0/lQ3l59Z2iX+kaCzei7
#:nqU+NArPpdqm/hQ/M9mcE/TpREV6GPiWfv1KsaDU8DMw8XlbqICui5/Lr74mbN5x2l+/oopdwI
#:+rpkoDiYJYDKYkCMEJ+pP0ybnVxTCQqFdXA99xjMPd/Z4xwWnt2wJ939R0YhdoTFeJ2jnWTl+I
#:nUm5t68s8YmNQtLymvZirtXyttXViVRuVerbVGookb62k/6UXYCSvWgTuNv6HjQ+vn6dYO3rXN
#:YAdjZr3bEbQlSX7r6I7+Ad6qYHQ03q1i87ql2vqX0x6zgfu6ed+kfzeowHRnFFtSG+WIT2Hexi
#:WCwrPgSqr66mZYiAXtKT5OqK97Q438opB9NM+EX3DH7/tdtj4truFpTQWDc/q31MrZtLNvtvgN
#:Gt3tHkSVBcB7N8y5Os3jwpxY+GKawNe3A4UdicQIeIqQkD1S5HR0IrKD9riobb7bUtGy4IW4sX
#:o8n7IYSoicXulAiGPCnlKQEhntlEV+9RybRnRMxUYMtPAVXKo2kElYhGMiMoAy/yIe8CV9IW7a
#:uQ0ma7JuCUD4L7iV7fN5KTx9r+x3LbcqMpBHdmNATuxljtc1rjTJ4+IkKTzUydldHQE90VbH0b
#:56dddJ57794btrFpFLd86OCzzHOjgfkMS2zjlW/Yq5FVul/0ck2qlcuNOFJ56tfDf3fTSKo382
#:OeRWs5FHOQ4OYx63PmUtqh2llN2TmSJIpCRXXhi2YpkOCp6+XBmGtb2u+ddU929872f+vCntoG
#:MAU7U/d0lrVFMmxHTvQm2tjcEllc8RHV1CEfVZNzxsZlQSC3bRyOwjzAzFV0GUYpfbHImDt2gx
#:C/Xtqw/RC/acQRVxfgVTopaxi6KRFszyBYXicuiDL2KrDY2qtsbYt+ohghobSfdRSoVPqAyoSr
#:iNYttkelmEj1mIl/dgDyZm7GMjgmrkpx8AlhkOVWuQeF5CPUnnKTmLhfvPKvtpCjSiHDqmIDU5
#:YfKhTdWfTYxaVxaRBGq+wqDwbhKLvBK/nF3b/+aHDx+p8/ilwbu+eZCUM2gzE4g9wPItVdxDtc
#:dHsD5sXXcorlwgZoDdkAAyNQFWQkS7/qZkAXAVxIA2s8oVcAVKZ5EWatVCZEbJvN0il1M7FyXN
#:GVMkGaF6VbYotWJF2ldIzzjDrS1Iqb0oSeyNmYUqZEOBmRl4kCRZ2NDEzJNDfvqw9GL6ekcs2i
#:091URbXMAakZISFku6A8aSWRElTmgJN+thY4Slf70kQWWQ3AsaE2EN1gbhorTUkClgyWUJ1J6g
#:Vefw4fKjDUgQGnHQis9SKaD4uT+U6KRf9mPlWr6D1NmacApRJj1cOSCjsDWp60XbCufJNqe3wT
#:g80qste9Q0UA83etUCrdxMNXLIlTr9Yulc9iU06/evhPwhPogZo6/XqcVv1DR8W1o+Oz79Jv7U
#:wAl+PgZ1L0OArxZPRCH1iQdQzqcRo1hUZUWvOzuHCkr9v/ozt1mep4Ps1WR/nx5cXaKOEryoiY
#:i+bJJKBImyoyqzeLx86cRvEY72miPuADNucrfT7shWhdsXGlnTp349HtLO8zuenotrJj1XohVa
#:tBaRdjSONED6hSOGHyRUXdFj2a6p20kYxN6WCve3p2ClnVKEmy1GN99y8XYiykpDzlEUTpfATu
#:J3BDxu9d7NxlrHUTD3nrpnX4sAtrDEsvFqq43x3svkfc7/f22PvzfQQtLbgKenywe/bu6OQQoI
#:+PTvc/sIP93vmH6orFMrfH/dCYlhGrV2F3csFxGns8E+/KOLUxbJuWf0AJ+o5/ibm0uKS6nCRa
#:kTed5jyZvNSzVBQX3tDvLC1OaVM/Zx2oTelu7JKI8568cnspelwXm+oCbul0JKS6ZQ/Z+op5vH
#:v2q2XYP4mLpkuUEA19iO8rKwOjI94bzo/0VOa8FRRv908Aw48TGP70g5S+1gCqP0tc/5yHCz+M
#:T2Xnz76b8SnY5nJ2tn9G6P41Hx2D/A0yxrWsddG8uvi/5tX6Squ1phH5aR6Ro/MzIYGfJ2Vo/r
#:Lfs1olon9piEo4OMmlxVZrYWHFhBrr4Pxt17JXzGWL8dxr0qfy4koTsPnAc1j6tFS0boWSPGka
#:JpTrZBSqO8ksHWExMaXAX9Jv02r+DBdYnYomOnXFrUETeKslPrCy0AVSkIzn9KWVOvSBF+QPS+
#:KCLeDTLpfIG7FlR2SpcmltqbiUC74UStsN+lRfAVpY6TLPZysm1L631w3jEzge7IwZS+LOrfxn
#:cO8mZpcGPoOnCR9ob6KW6I+C0GcKPWT9PGH15eadKlGL22cRsJ7wNKAbZyEbcBc44tal0amvbu
#:BpGx1IkGs7irP8f7olhf9/vqdvsU66MMAKcd1owOYbVYSGH7Nv7ob2AKUiGq6+9m9vQ26B+VBk
#:y42QMQm/TnFwa6vw75rFQHiLR3mZeZ2fQaRp5cOk9QnGDd18hu4tx6+njljTMFqHcoTkJu4DDd
#:W1SQVtG3cCCzYMhwPhW1Sl9c4FCB9bI7iG7t3JtiB7VghocdEXlG4DA4pEMsRy9Qd2VgrMhdA8
#:xM8ybhg+sGsecVFOK4x0gq8y1YQBclV9QHRQ01f/pp8uXgKjw9gPBg8syMXf8xOjGHMFU9Ss8X
#:miNWnedo9P9e6MgvLiME41uL2jg6OTGqD6riECcYZDtboHpgiwkjSAB8aYeAppAsxbKvx+83IW
#:BVdJC8vjjX2joW5iTUECoC9CAe8CQbkjyB0TN7+ZtqOwmKhu6mD/F7UpATJtX2JmKleKJHF1YD
#:QEaMEY5jifcpa6d/jUkSPmqhwgYuLvmUCXLn5uk0DkPdd8uM7wokMYg8pNLsukpuJKG4i/7Q8/
#:dndPnFcBPR8e9c5+VS9vdz+qx1+PzksYyPrOuurttLt31HsLb4Zd01yWb+zkw08P3E0bmz+327
#:YcGOJFWvnouw/qGRQ8LcaDAiTjnlLoipWBd9hyyD7rBgM5woyZPUp2Z01++DBvmqqvuQBQZ82b
#:P5i7em9vNlszZnZPZkwc/gcSqOMZk91Zi2bRnyXlGeOzZD/0nJVDGYjw+3wQou2t7K1sr/QujW
#:kLXLHA2WErv+xBsZfjAjf1boIxX+nh0n/PWOoBrS5Ey709i214bOOeeehjV7bZRsxW/o0zx8d0
#:Ghabyqx3fy8xfPhQoGg0vg+Jcj2z9EH6kBnTPh+4ozDfElF6CkDz+Nej3sctEcS9kEOw8VBKHM
#:qETIV4ieUywvCgYXgWcRMihnJpYDWGTL+tVj+IwLXp8EVkUPXixtHrWSDSkAidgLdmgJZGRRj/
#:v5Rj2W3jBp4VQP9AEBaszWolOclJ6DZxHSMO4CBA4qAHxy0UResqtR6Q5Lo9WN/eeZEccld20x
#:wMr8iZITm7M5wHh89NUVW3CwpdF1K1t4E2UFZj/3sfKSd+RAmx+BwEGGrz2bZ8NvwB2udhjr/e
#:9IrieqIoYIv8e9/by5MT5sYJciJiFbfDZ7YH8xj3YVD1xQbLyRQuSzl0zv/E88fFKibgwE5Pzt
#:6rnRzPNdtXtgnyIx64vohgX2EG1o66ZB/ATzImiymSwMd4RAbSjnWGh12nl89t7sY4e/vm7Bz+
#:cJgXNsvt3GYjC5ZLjQ5hHs0t9aqmITcpeDBxXtri3bvXDEs7W9Kooal754QTHt1mrO1LLEGEPt
#:E28ARuDNd+oPHPT1LbUbcaUACxGf9zlJwdV1uzEvbEEdv+8JPyLX1Mjeok2iFkia53GY6dY05c
#:9S6/fMPUDTUl81xxlJpMDhX/JNDB4G6K2Wcw/qec8VuMb7zxZ7Z3swmwEWzQavY3wUxgAuZutv
#:3DAKfGlBxk+6ffB1MYM48Atcak45fpFsiZzfLmFkXoZZtz66XK/LqlujqaGUjeW2YfguaPwsae
#:0gBQzUO4Ut4DqDJIc7SwMXjdliMMZMu9RhAaOiDgoTUEUlyu4NMoaX4Dm7tTekkAva3u+yKLp4
#:PH1Xddv6wyjAPkctwIc0SKbgsiYPSqRLPbvHoMeIXA7k1nxua4OETI6rwxijl0mFVbu9/ctywf
#:s5QqlxGG446XFgnhuhI9G14lLIMWwLlpngxlDaiyFnOHXHPLY8bMO+h2Nkygs+kvR4Z+07fhdt
#:9WzAzwubvzSbav7xQ8MuN2y/Wkj79+Mj+baBxQIvvxa8ZFitpgZxAOP8uGnlDe0cGQHbOo9z0/
#:hZ0t0Rf4Ne/hfG77SwnBtaJYKHnDLRX/6lVOnYTXBDsLLJYjMyz3Vq3KCGEXGQw4KUYMn2ZdyL
#:DIKAZn+3Sa3M/ZkY7hwXrw4Jil0dDyPdF0HqOuofbR5Clwh2u7d8vgEJanKquuWMEcdIPFlCXr
#:cYg8Ug3PmUcOzddPlTUJM7lcAmDgCch6FsOm6oRL0Dm8wMakL4GqdD2UUFKEWoB0CX9x7Vt5+P
#:Uw9Je+XBbHDKyN0WSRTWpSofngcA1wlETUBi7eUy1SuXBnDRpUy/fRaT+J8RM9k2igziYjp4NU
#:w2obpF7LPAsJjoRH/UisZbQgev5OB3lUvH+B1h7fuSB8RuNHjiQswkdW0w+++z7Zq4Alv7N1NF
#:KHimZXihHNG6wUIqRpyPaT5owcg0tOLkhprZtz3P5ihs8+5v0ZbMOjIeUZ2u4wDtl5eali/s30
#:QsZbq89UuzwwBxdFpkkcRZMQG/OHZiH8aKmMBYjq/ySIbEUKfFlOrPXTV297O5/toD2C6Ms5Ok
#:UbhEXqVgTyPkhI7YuKNsfxyG/a6Y49zho7cLs9/pDRfvqb94ZbybaJljT8k0+cF+BcgLqazBEc
#:NsMxrMtBuZhwCC0ipR7IJf0HxeiM8eT6LsxfJ26ABAqdtBU3Nkewhvgn4ksquoGGDM4vwAE2Ui
#:ETrIGCTJspIJBgyyq50FKFjy+OP7w5vfChdu7X53ORKLcGx8WHrhs8JDx0JFSafKWabvDgeO5u
#:6HWDn2gNiE8ntFVJT/wt3uuVcLHb4DBTy/C5yZwbtP+XWLRSl8rOoN5IKJQz0lGczsanIFhU4E
#:HQa9i4DTn4NFbUokjawS/n8PbhjT0cPdPGqVigEgBBA9SFrWhf4nAI3XdWXK+XtyuQrtA+XXzl
#:1oZBUE2otsHTnfOwnw7cGtFNZz98FxzxnZMlctzlySnMOlcCM0d7+WJ0gHExxbzUeP0PuvHkJc
#:7A3wUv9gFuuQgMvysdxRHJiTK/GKr7b4EAigMguLLGtfpEPWSTJVtCqC+WJrqem2JdGdLRBMcM
#:47K1eYW/8MK2LR9IwQd4EZP4qh5o+evySm5Pw268cuBZ0/XUxn7ajK+nozi/hVEVoDC80lVycg
#:EhZwfNuksgR1fqRo8hFlT9C96lKgGmWwAA
#:H4sIAEZDOE8CA7Qb/VfbRvJn81csKgEJC9uk79orRuQocVre8fX4aJMCl8qSDAqypEiyCU3gb7
#:+Z2Q+tZNkhfXd9fYm1OzszOzvfu/kujL1o4gdsexKHeeF3bneWvlNjXvGQBtWhOLjXP/MiC+Ob
#:KgigicLhzFiY4NBSEYzTyC2CbS9y85yd7yyFcRTGAZsmoc+OBr8NTs1zllufl1rhyKS/W6MUqB
#:TwVfhBltnG4PT0+HSLnSXjoLgF+qy4dQuW3yaTyGdxMA0yduumaRAHPvzI1Uen07mKDasPKINP
#:YWFu4s/Hpcd+E1v8x2+BVyQZMhMDhfCvwHajKPFg3fk6S/tL6WQYhd7WUosDmtYWApk9y2YESL
#:9S+JOJ/z6fBgTx0uo/LrWe5DK2+D+5qkerhMSQpV+CYi+ZxIVpeUmcF7VVWVBMspj41tadr7Ik
#:DTIXCF9em4glthrXpZfxtbaOU2hczafq6wB01/dNOkM8TGBjxyGxWAyGWlIU63wMz0VgWDdB0c
#:y0jfPttsXO+UlJjIqTTxb7zMQaIuV86jMFdxGHHydBCT3lnADLaZI7b8LYN6dEFZiDkR0Hjklt
#:AQauNY4Q+1RwgRhotYaZi4C0Fc4TIUKn1w+3SfYh7AGnkNDUcdLL8FpRCpHIY0loY5MTIXsQEk
#:J0URBXBCm/NXowpFPEyRYIMbQ2dp7OTdppC2cJUFBNmcPM83UrC7i+pjZMriNUMjLPLVpEM2LR
#:4xIY4xQsRen89vlOqRKOkIk2BVLnNsYt6oxcBgPWvVs3qxoRnwNr2KobQArGn/mT1DQMC878Uc
#:FycvxjFfwGLFWweSe1rBlYTjbnREpYQEt4nxQTM0Y4yoLATMkEOfcVU+DYKwYx36SGSRKx/Xww
#:TosHcxacNRvyOpyWw3rsyxcGbMOBADc0gij13Um2nubiVgzhUgnONBzzuaoslZKvK4B2Ig1LS2
#:g8IyUQNezUz6rGisSzDGLwxiloLQDNR6MxU0HUhEbwQ+a3FwXu152zrhoM7alU1b7wFqWbfu5R
#:q/NtEnJ7dmPoCkoNhKWCEYGkPpuXs7hj1mbodlp8kVuE3nvPzYttkv+OWToHjrlNKLhz4CF7md
#:MYB+NxMgVJtBGOpGlzWN25Q9DOuZNr2hiQfNZ+ns3rywZG00ucvEYU5Wd7Ewd6z2O1rqLcNzMz
#:ZcsOKhr5ZtrMupekD6VacFm0pMbgb9wKAtVCgUYdhbCXjFM3C6p0bSkfZ2NTxeESBUy8Arox1+
#:4cnTukKFLb81pAOwA5auiZp2Ms44w6BohV4Q6GuY0NS4Q3jG2O41XDWy201eJnzchljEa1kaS4
#:zKQmOBU9qMZbnN/ApSoEYsCUEmiHXAbo7RcwKGLUYehrXh10LStsVlHKm+K2lLvGuK6rG7RQpB
#:kwtN0Tcbua1TJjkGVJtsX246kbgfOBs3YhwQ2ynBUJ8rLMU1ctd2099oXWEQ00uh3OFVtdFfzt
#:9EgKnCk+BLG4JfdI6k+6SJ4PPuDvZssac8MCHO3NiknJlWD9XvpgktGj4QmJoc4JxGhmaGNrV7
#:01Te5CyZeAkTCIfZkjKK9Q83bRbS7PQQ5lt6QiYj2egly8/dzFIEuR6P498nCoYjsigwA4cKwO
#:TgL2JS1r/0beSswA0JFu4EmwvbQk+D0NXP83N4KMV4UFm8zYD6JwvIlit9e0kZd8RJZajgMBS1
#:qFYfSVGWR9Uf7chamD3vH+NowC08wvcQSsXeDHrIQPYU4iSJSD2873Ly3US/G97JBm4u92G7BS
#:SOqgzeEQniYF84/OyI3yoM+ZvOwBvbUrg7jWlnBz+AjfRTYJuDrp3sUTnh6dRR88cp95IicHrO
#:uevgf1RcybH5FlHCOq+OFdbkCgWEYtvoKRIUScu77EtO2YH1/1tmCr5BWKMCZ2WhlqwronHODI
#:/GghB2LbOCwEn5EiLtHW92ADk3HlOHWHCSl2mFARIEOA9JZiRshMaYwYpyDgOL2aCKWZCkZKOY
#:oBcQzIXRBPxuw4LT4fHR8NbHZ2Mhi8hr/2/xjArJw8Aw8SQHl2cfTvo+Pfj2x2dGyzd4MzhhiA
#:04mHUSAKgAuABpsoSpWLwfOB43DjGxhDICisAcBEepDRazLaz8+SSeYFJkKtspEUB1Z4ow7i6a
#:jIttZZEzJZhmmr3KvUMEE9+FSAVMRqFA1At0nDqrEG4DplZicDDoxiDCySKLkPMpN/croMv9Rx
#:GF6aGjx/X2ph7gfqVpkPvwbgeYunP30S87yN0kGBOjTccNAsACGwWSYbUXjfgGGYNeLA4WfqGy
#:XjZ1A+3ga5Wcl59QNhUPvq58HC0sRzSku4wdLvte6aav4IZQQt3C+C8WelB/e3VPKKrxDm4Gs8
#:KdxhFJQajpESORfLsQWEI6bQ+6q6HiSuD4DaLmyt6GLrd8GDLYtngZBKaMadtPQIuQ2AFk8yS7
#:fI1ijU171idTcavMm9aAtnHEoEtPylV35PI/WN8q74VYfQKo/K017MNsi5tYRXxNNHcohLTghl
#:kbOWYAYWT6ONDQ5DKROSR+UpPS3PkvkfSF9tuGdLL9bg2BDcTziHQrarbOxMO9Q5okXjjkAnhQ
#:UjeO4wUkbX3MaoSbNSJzkUp8KjI4qY9iVAn6Hl4px+dvPgCDxPU4knPVuuObXuHKeWl0Elr3gx
#:jdbrMPtfkKJsoUKrZyMEp1XNqtACyKNXaY4okGkZB9nD8HKz1+thH+7N/sFgnY2cEeROsfk0im
#:0jMyQ3o2reQj0YLVNZHmEza2SRgsVtB9Jd1zeH9qaN2O0RP6C2M8S/u12suhj877Jb17tD+8wy
#:sEgWjtMoGAcxZsZJzO55uzkBWkEAOWeBSJxMbD+2KsecUaJWlQS4qkE8rZhTXI3wmJGVUklN4+
#:Lk5D3tOm07qJ86dObcQLUACCl3knRfZVt5X/dyF2n6uRpn/SD3sjCl1MAPs74ej2uuCEcRjME+
#:7vDPYeZm4LFc3x9F7g04M0j5gQ2bTfKAalO6AAAZTvIiGZcIOf0d5npeAO4QAEY3d/Tn1GaEqo
#:RFbdlhI/gTB5dasANqEVYSAhqtqlQKp+feBAiK+zTlt/3clXallylYXoXjzgvSfo0F9hn1WpKw
#:Ocj8hhSQXGUTq9o2RyYdZ0JpBy4loHq7Qaz8zEsvdCcQ6Cr9grJ+xVgYuXASprAeMgDNxrh7J0
#:upJ9vCdDZF3xrgMIUewdl6JjcYtDxIiwfHbyhPXqZEGfPk/pql+2oEo9z/s4wHy1mnbH3Couwy
#:0+I2JNfLKpaJxBk+ud/XU2qRcHAazORhBJJ0qn3L/JyT/egsf+yroBGJpFug92qNF5SN0IxVcl
#:h/Qz/I1+CJCmBqwaFPw6umSzyQo93DwfvD3bfXWpD27n1gDaV875sIaTMdlDfyAAaYNrqGtnBE
#:4Uqcs3l0cXAw0xyB/IhYa8yRWmD5eBVAEJAg8Qyhu/bKMLaAIHYI5RT8BNrwp7az1gijJuKQky
#:qMKTOEmc4EMloOj9pEvrx05aQcI013Hnm6sjxa3DE54RTYi5zc8Qj25i9fxYbNniTxmcZJrQNS
#:0XZMHUrbKbXdVNkbOCyDu8LcsIVTtMAMEBAz8Qog+kqDu8wFMORJDeVT50KSczRKlzsXkHtiQ7
#:rkuXDoqQ3usOfCCD9uKI9u8WBaMUEtOzW0mGJY0vIrGYVpXF19/+OP4uDFFZyw+VxL6HAUVefK
#:MPqLKPJIwqVjSav3E5FTijhDqZ6WyVmC+pykbS6xOBlGYfGX2lq3y8KbOMkgDwCLAy28X7R67I
#:IUk3gU3uicih8tjITz+BR6quFiBh4a00au8IpMgGvDjpQ0Epj+jwh8q9zQUsbhX8H7PIWcCdAQ
#:FhiFA6cuArfTr6yFP2pL9/8YLFiJqYM6KqUSmFawkdg2L/braT5bk2Kh6JgH2JPFYKyipJLYes
#:5bWz0MXraqZZSTKbL5yCvsFtk8MRGbdVlphdQcFJq0dAxSZPMQqM1qi0sBiDpGlWLcT6t5lIXq
#:zIysUhqiXuLiVvun3I5UcmRVsH6rfvE0s/Q49dJ4tjiulIJ8uVYPztTDDdXzbJHcVCbnMzVypU
#:peUCcvqJSrtfL8alkdkvhLlbkzVbOAUFVvtYKuyl1WVbSiErNHXpSoyFm/zKoUhbyzk4IzNaWl
#:2PV8ip5tCEXQchc9mZ260RzzwhcXbqQvQ3bJ/4nnITAt3gGpsvgNRBEojc3m/I74qdUxmDF2uz
#:mViBAj8yCjGjFPMigLs454xzHV+ZhpJ04bmokZKeNUdBAxttCCD85mn32ormDt9geuW/XG99P0
#:8sO1TPdD5wNdcwmJ4v0dz8HDa9Wy86ydnlBTGG9vXjs4zdMgrm6ULPMpr3JnlgMoFezl3jZhb1
#:nD3vK2Y3SMtkBddi0e5VOREzcDQZbChnR8h6V3VBsKchhKZ15hqVOhjFXUkzaTJSpkWDlPx8AV
#:Ii5+18WESoq28r5P7HuWfp0KRcYOWKBLNYbHtuH3X2sUH8XMrjbzB5/hRvt+TYPqaVA/rYlOAQ
#:8xh27h3aL+aR1CSpzubmQvU/N3y8I5q3cM5fLcxiX9mSWmyjmI4BCNnFYdZ9oaPXOwROYgiAy1
#:zDwvCzmdDxkd5L1Er9Q3EmxO94CWvJjknk62Wf0GvzTbzOP06UR5Ohn6lv6AS7Ig1fADMPFhm6
#:uArosfyltiEzbvOL0vX1DFLuGP645MG4kCXwymxAnBCfqz9MkZ1sUwEqhXV0PfcYzD3f0jY4bT
#:2l0E3YdqOrELNJpVonaOtdPnYmdC7r1ri1/JUQhbXtM+zLVanre6OpP6rQp9a6SGEhlqOxk27A
#:KU7FmbwN3W96Dx8eXLDGtfFrIGsPNZG0AIgCxAuHuVD4B3qJseDHWou7/syPa+pvZq1nHeDc76
#:9Uv2ek4AjOKKagN9SaUCO9j1sFiuLg7lLa1pGTwBKOkJcnXFe1xabOWUs2km/Kx3Cb//Ojhi/O
#:HvFpTcWGc/yX001tklm8NXwOjW0fHsSVAeAGb5OkjzerOlFD8aJrc27NnhhLI5jg4RU9MGquMA
#:HQmtoHyuwxt0dze2aNAgbC1eTGbfkxCiDhbHDREMeZLKUwJCPLOJrt7TEmnShJipwJZXB1XKky
#:aCUkQTkRGUgRf5EK+JK2mLdosktdmuCTgLRuGnmd7gV5KTz7X9T8W2xUYzCO7MaHPc7ancZ1Oj
#:TZw+IkKTzU2dlcnY490YbJUbF2cDdJ57b34xbGPTUK+C6ODz3HPjkfkES2zjhW/Yq7FVul/0ch
#:2qrcuNOEJ56g/Mf3ezWKg385Mgj9cKKP4gIS4SNgyYS2mHbH91RKdJkFCFjezaq+YqkAgy1yvC
#:aaBtaf/ofHC6u3e+/9sA9tQzgCnYmXzXs6wtEmE7duJX8cbmFs/i1KWrqUN+lk3RORsXBYTYtn
#:E4iYoQM1felZhkdMORM3fqhhHedtqw/QjvQJI4kE/oZTopah56WRFuzyFYPkhWRBl7EVps7UW+
#:tkV/ohghobSfdBSoVPqAzISriNYttkelG0/1mIn/cAHkzdyc5XBMgSzdwSdEYV5Y5R4kkndQq4
#:pNYuJ++cK/3kKOKoUPq4oNTFlcbEi68+ixyyvjyiCMVtmFHo2iSX6Lj/rVW8HhZHT58h8/8Fwb
#:u+25CUM2gzE4g8IPY9mNxDdf9NoD5q3yWTC3AVpDNsDACGTFGYtSsboZ0EUA59LAmpDrFQCVaV
#:6MWSuVCTHbZvN0Sr5krBxXfC1NkOZ5qZfavHVJTy8d4yKnDja17hqa1jM5G5PKlHInw/MyXqDI
#:sxGBKW1y8768YHo+JZlrqs54RxbhIgek5oWAEO2F8qSlREpQkQPO+tla4Chd7XMTWWQ1BMeG2k
#:B0w4VprDAlAVgyWEL1Z6krvP4CPmRgqAMDTjvkWOtFdDBWJ/ONFFW/ZzFVS/WqGuYpQMnEWPa8
#:hMLOgRYnbSvWpW+SbZKvYrBZRfa6d6gIYPGuJUqpm3j4kiV+6tXapXKN1nD61cN/5J5AD9R0M6
#:DHadlvdGRcOz45/yb91s4EcDkOXquix5GIZ6MX+kBF1jGoJ2rUFBpRac1S9UBJX7f/x6BxmeyQ
#:Ps5XR3FZ82xtFPAVZUTMqnkyC8jTporM6s3lqbOgsTzFd52oD/gDm/mVviD2QvReWKX9unDj8d
#:087zO76fiusmPZeiFVq0FpD2lI43gPqFI4YfJFRd0W/TTlN2kjGZvUwaPB2fkZZFWTNM0zjw3d
#:v1yIsZCSBlkQQ5QuJuB+QjdiwScXO3c5694m46B72z182IU1hqUXC1Xcbw52f0Hcv+ztsV8u9h
#:G0tOAq6MnB7vmb49NDgD45Ptt/yw72jy7eVlcslbk97ofGtIxYfnK7EwtOssQLcv4tjVMbwzZr
#:+U8wQd/p33LKHicJlmdNZ0WQNj0BknfSY1/086ot7ae8D3Wp9o7WE69zr3h763JTvtWt+BvtPT
#:7k6Svmye75r5Zh/6iepLaAIAT2lZURv/Hz2s4P1VS3sv71/iks/6G+/E8/zOhOB/D8qRD9YwEi
#:vDxvYuTPoZsHs6gW8XS+f064/rkQF4N8DTLEtbx72bm+/E/nen2l210rKfy4gMLxxTnf+E8zcj
#:N/3j+yugrLP0ssCgj7Cd1uq7ViQjF1cPF6YNkr5rLFgsLr0B26eusE/D0Ehf6UidSh7JVzFTqd
#:RPKdMssmWDA0FvHlA1vNZSG81dfVzakrZw3Yom47v3FlkQt0INsu6OqVWvChFxYP/MEtYNMem4
#:gXspWmZeXlGH+7Cp4SCtcNurjXQVorA+b5bMWEwvbupm28B6+CbS+Dv78V/xmBd5uwKwN/gxeJ
#:HmhXvE4YTsLIZxI5ZPRBymqrzXtZfaqHaDFwnQZZSI/PIjYKXOAnsK6Mfm1xG0/X6EPqW91Mkh
#:f/x91I7P/f7XyNbTr+EVZ960Yb9t2uoDP8hH11J8Q/VH9om9rSv7sFwT7zoWrmm3gUb5l5VNva
#:Ut66tA2IVcmkKNOoi3MIG91inHbfw7hh6XcfdwHenDp8SdvoHooRQz2YHMsXkxLYNu7Vs8kxf1
#:cjS6Y3UOyDuRcJPjqL6cGd6O+xJ7l85h/P4z/aEQjGWHN+x85LGbkQX8d4t+JG0QO7CeKA18QS
#:Gx3Zi1x2UoBU5fgRG9Tl1X/ZT48tgcdx4oejBxYW/F/1E488boqurh+kWpvl9eDkrNpfISAviZ
#:JMA9s7Pjg+rcLJewkeSPPZN4wwg2CVkA9uFePaGQR5mK7f9c19iUXtLE4HS9uNfaMtX13NogDI
#:5yCAb1qudgI5X+oWtw07ieR4dTMH+z/LzXCIhv3wiSZ+JDni58Boc0jBEmYl7wuWuff4q88HzF
#:Xxbcl3wD6ozeVPdK8onrEW43WG7xiiBJRrZlEuVBLX2UD29XD8brB76rwI6ffh8dH5r/Lj9e47
#:+fPX44sSBnK084H8OhvsHR+9hi/DrqooKzZ2ivH7h8DN2ps/9Xq2GBjjK1nx03cf5G/Q5EyNhw
#:okDzyuuRVbAtvfcsgCa2YBAb55Yo+y0jlzb98umKUiadE8VEMLpg8Wrd3bm8tR88TuafP44b8h
#:5zlpnhvMWTKH9BzBNg/PkfbYc1YORUDBq/MwQvNa2VvZXjm6MhrgXQ7v7LCVn/egDCsQ3s2823
#:AarBzhyn81r/SA0gBC3t6exTY8tvGJeeg3V7bZRsJW/oUzJyd0AhZr4tT79EkgePtWYWi3vwmH
#:9CtzFED4iOZZPxi5k6jY4nF2dr5z8uvx0bstHoW9KIDY4aF8AkjicxmjBZKrGN19ieCJhz8IAN
#:JfgXkYIke2usMwBr+lgStXLyu4jeOXcyCExRAyDm41Q5bWQ/i+Zxuj0SSmVvKG+Fd3OYyBO3LV
#:9xxM0s4IES7izxIgwRqH/y3l6HqbyIHP7a+wrEZk2XwVeFrdHpRStUhFSNDTPZQeCiHp5a5Joy
#:RQeCC/nfmyPbY3zV2pVGXjnRl7Jzueb6/rJ4OHkz4PK/zzptPtXo8UARyRj7edbfw4Zk4cIxci
#:NvE4vFvNiEeoUmEb766wFUyhskDDzdm/WDvcXUT4Durk+Oyt0slYkmxf2AbA91gqfRGBvsBcqK
#:3apOjhK9mA3TFSwMtoPobRXm6BVarjy6e2dFOcvT49O4d/nOWZLUo7s0VlwfxIyRDi4czSTTU0
#:4KEADnbKc9t98+YVg5LKSgYVMN3dOFmES6delWGIfYNwSzYWuAJ/gxs20FTnq20NGShwMIofHK
#:hmd9Lm5UrbInmZ4+eDWtTYEEKG6ArXoUxcctIunvjpH8ycNETvFxIjjmKP3LlzN8bEL1jpY062
#:zYc33m4z67vpCHgHpuNk+o1gRjC3uZuu/zbAnyHl5diK6fXAgMWkH0AtMd/3abwGcmZ1e/MF5e
#:U5Z7VrlXN1z+g6XqYgZa85AAqQ5U7Q2J3pA6a5B1XacACTp3Am/KuXpxWyPGTUNpr5RV4RE8d+
#:m+KYEW38Q9CcfhwypoWj4YXD9GQRUFKCP4HXraan79vSFd/lcfHIOGph0fqm7XlWh1mAWolKtN
#:zfi9QMw6J3JbrBlpMdsAuEda9QYWyJD4bwRcZLo5hJ9azaFvbcZOmQZuU6QhC+eNmTmKzr0bPh
#:FYFHoMXzjxpaJ6izFnOB3HPLYeKIawft1orRW6vebWXoO71xorb3YjaAt92ejYott07ANTNOzy
#:5HPfz2m/ndRLPAZrQVPTNIUswG24Rw+JoNgYTwhmo8Nsyczv/5KsFv2Xrw/d3C8tL2bm1TQ9J+
#:CMqPv607E9mZwo8DWgke0/ri9dqqxzHWF7GbCCOBj6DTvAmZIgWF2GyP6sfdWh3dGBzsDQ+NaR
#:YFHNJLu0hroC0EeXoel6Efsn4OUnmKhdQT0BZy0A62VRE/h0PjSVIsZ0cJkm+TqjM5MqX0+hu4
#:AqKOraCDRYQEmSMKbG76PqeJbnoSOoHMHuBcwn/c31Y/+vzI3659RyxO6NkZI7lcUb4DBqSQc0
#:zAqiRY1ndRnck8efejyoCHU9mPseNNJNldWquC3BAS/MXay7SWaJYEnAVr8khoeSYvW/6oBrlU
#:7H6GpiAfpcC8RetICgfmUdeIlnx380esd4APH9l0qlTZz271Kp0FTfq1IWPG0JIz81KY3eUUtD
#:9n4YMPWn8Am/Fw4MubUIeTAVjWKlrfTC7ko9WOmO4c96zAxYJpCYd6CWJ6/soaJO+p8gwgjw8j
#:hwxFAnzqTZwPT35wMHJcioJ2fCIu5W2KMIiFtJ8kRxSkr1Ck44aVU7yp1h0WTeOoM4/eFaQU/3
#:Ku8F6i+9Cyhg95nfkMR3EG8u2vRGjQaEN4HgcVVRaCh4FkOiB79AkbnpjmydFbmEvOS74EnczB
#:G1siVB7ORGxJCucUZGJmuYNrokGWU44vC2Z8hGFceTxuj1Qx4Iujd6cnFy5KzreTIlkeDM6LT9
#:nmLhLW/QiNHRWUMTRWvg2c9Ps1ZjC+qlK14KiCDf8A3JjWp7oWWb3PFJY8oNy+xPSUDlLyAbVS
#:oHhNpUM1rZVPGbAwwIVgp8ioURz4fmoaYpjs4OU5/NbwE90bGtNmpNiKEuhAU9GFpUjHcNiDTi
#:XrXi9vvyxAhML4eP6ZR/M5cA8IQ/3HG+dQP+67x0OnnN3uTfC7N05kyE2XK7cRZgwJbKy2scTo
#:wOF8jLmj4fI7Ou3kH07BzQXndTujXJiFfyMVqRER0WlYjML9J6cffX4EVgaz3hRxl7Hxs1qCz5
#:6Slricme5yYmjbJTDiEzeUzSYFn6S25soPvADuj+IzdGDk6+WVHGuGt/EsgCdNJ0kb+8dqeD2u
#:4hwURk6AwuBKt6/JyYCcuDPLNoEcXqmjNga4tJ9nOaOTUVsAAA==
### BRC parser (gzipped and base64 encoded) ###
#~H4sIAI+CLk8CA31UXW/aMBR9z6+4c70GKMENnSZ1EZXoW1VtmrqXtYSBcQzJBk4Um3Wj7X/ftR
#~MItGh+IP645/r43HM5ecdmmWI69U7ApJkGLcqsMCBy9VuWRkNvVgqYZ0sJmTI59OqFXmeGz3Ay
#~z0sMXhXZkpssV5hmrflCfgLE9XTqol2OK8jXplibnvA8LQ0E0hMJkGmSlYqvJNBwSrz5gExnXM
#~tmxzOrAjdXv4xcFRAkNu/kuxt4qmUCvmajVrs7ZsAWkWZxyZgPdI4XUsSyopQFLzEQU+XXmWq1
#~4ckDHALvAdrHd7mlHQ83X9uQz34OHBInvcUmwkADhIYEnmGxyZDEpc2NpxBFO+j1Q/8VdLbpH2
#~BniO0fB3fa+GPBLrQ+kJoLN0nln2RtHy/BJ7EhEH5kIZD3WRcIkFgRv0r4DE4OinpAdxyfUdaF
#~c7bwXZKlVCijpVPHPgoIBEr44nnXN1+Gd/c7YaRIcyDaYEEFiJSXWInJaAwDeCIuwOmIz+oToB
#~d7kJeI7K0cskNDxCH+4AitZPeQ08Kk9hxnEYkaLpPPw2+3TaUG5+5rvVZbEQsXQZI38lew4d3d
#~8B5TAxVoARtaE6zS0FbLnpxBCO32bt/GaZTefWMVm7iax6RbkU5yJRv2WIb6bdg5E75cThywEm
#~ibxErRvMbR+r++tH9M4QtU+MMRhUcQbLB33CblZcn/autOtLrrGhjD6SlU+9ZT25j9Grg7nfIE
#~rupewYVl3XvVOZjaSFltYhN7ni0Ed1Wo8u5KIdBjjkWA+nN/MjoPLtGJ/g47fWMDTshE5Gucog
#~9EdPS8Msq+QKq2xGNqizwCqiBYGlvc8YEvLPsAlWQuD7W9wjTrdSBuOW6duM2w4GGXFX6jwRat
#~KseofcccmsFV5K3pecUVKrKVIvlxRbZtq9kPZMLwHwz7lkX+XlKwl9h7wfPKFQSlA3v/ACS0qg
#~m8BQAA
#~H4sIAEZDOE8CA31UXW/aMBR9z6+4c70GKMGFTpO6iEr0rZo2Td3LWsLAcQzJBk4Um3aj7X/ftR
#~MItGh+IP645/r43HM5ecfiTDGdeidg0kyDFmVWGBC5epCl0dCLSwHzbCkhUyaHXr3Q68zwGCfz
#~vMTgVZEtuclyhWnWmi/kJ0BcT6cu2uW4gnxtirXpCc/T0kAgPZEAmSVZqfhKAu3PiDcfklnMtW
#~x2PLMqcHP128hVAUFi805/uIGnWibgazZutbsTBmwRahaVjPlA53ghRSwrSlnwEgMxVX6dqVYb
#~njzAIfAeoAN8l1vacX/zrQ15/GvokDjpLTYhBhogtE/gGRabDElc2tx4CmG4g17fD15B483gAB
#~sjdnAc3GnjjwW70PpAai7cJJV/krV9/AOKBj6JDIH+R9YH8j7rAgESKeJXOZ/BKUJREuhOojPK
#~unDOFr7Ls5QKlbSM6thHAYFAFV887/rm6+j2bqeNFGkORBusqQCR8hKLMR1PYAhPxAU4KfFlAw
#~L0Yg/yEpK9lUN2aB9xiD84QjfZPeS0MKk9x1lIwobL9Mvo++emWMNz97V2q92ItQshyZsKVLDR
#~7e3oDlMDFegCG1oTrNLQVsuenEEf2u3dvo3TqL77RioyUTWPSLcineRKNuyxDPXbsHmmfLmcOm
#~Al0DaJlaJ5jaP1f33p4JjCF6jwhyMKjyHYYPu4TcrLkv/V1qDodtc4MIHTU6j2ra22Mfs1cHc6
#~5Qlc1e2CC8u696p5MLWRstrEPvY8WwjuqlDl3ZVCoMcciwD15/50fB5cohP9HXb2xgackKnI1z
#~hFH4jw6HlllH2BVG2Jx9QWeQxUQbA0triTA19Y9gEqyVweanuFadbrQNRy3DpRm2HB+11W+I0G
#~W7SqHKP2HXNoBleRt6bnFVeoyFaK5McV2batZj+RCcM/MexbFvp7ScFeYu8FzytXEJQO7P0DVg
#~ZKir8FAAA=
### Colorizer (gzipped and base64 encoded) ###
#%H4sIAI+CLk8CA32PwU7DMAyG73mKn67qLozQVlwoK4inQILDQuO2UZdkSlK1EuzdScth0iSwJd
#%H4sIAEZDOE8CA32PwU7DMAyG73mKn67qLozQVlwoK4inQILDQuO2UZdkSlK1EuzdScth0iSwJd
#%vy/9myNzf8Uxnue+b3W8/JOese+cecv77nVZnrbC3vNVddxTyfhDPKdBfi4ZowNtBFLq5lZVr7
#%l7xlGziSylETlDXQolNNjAN5hJ7gSaKxWgsjMVk3IDI+SDsGxEnhMdHxuOTffvzlFpMK/QJoNc
#%e7lzUa44m1++Sgh0D6hF2IsAijv3tb7ZCwL0RnQPrCzqhATW+RPqNG2lY4o6yzHHmdFSjqrMT3