From a58c4564255146d9a9c7d4ee095558c91eaa874e Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 15 Dec 2016 11:43:37 -0800 Subject: [PATCH] apc init --- .gdb/ir.o | Bin 0 -> 15232 bytes .gdb/irmem.o | Bin 0 -> 30488 bytes .gdb/lexer.o | Bin 0 -> 14280 bytes .gdb/lexer_fsm.o | Bin 0 -> 24416 bytes .gdb/lexer_lex.o | Bin 0 -> 7872 bytes .gdb/output.o | Bin 0 -> 1224 bytes .gdb/parser-save.tab.o | Bin 0 -> 29760 bytes .gdb/parser.tab.o | Bin 0 -> 26816 bytes .gdb/scanner.o | Bin 0 -> 15904 bytes .gitignore | 3 + apc.h | 33 + ir.c | 1336 ++++++++++++++++++++++++++++++++++++++++ ir.h | 16 + lexer.c | 518 ++++++++++++++++ lexer_fsm.c | 1038 +++++++++++++++++++++++++++++++ lexer_fsm.rl | 369 +++++++++++ lexer_lex.rl | 69 +++ main.o | Bin 0 -> 2472 bytes name.c | 41 ++ output.c | 39 ++ parser.y | 177 ++++++ ragraph | 3 + ragraph.png | Bin 0 -> 159425 bytes scanner.c | 255 ++++++++ 24 files changed, 3897 insertions(+) create mode 100644 .gdb/ir.o create mode 100644 .gdb/irmem.o create mode 100644 .gdb/lexer.o create mode 100644 .gdb/lexer_fsm.o create mode 100644 .gdb/lexer_lex.o create mode 100644 .gdb/output.o create mode 100644 .gdb/parser-save.tab.o create mode 100644 .gdb/parser.tab.o create mode 100644 .gdb/scanner.o create mode 100644 .gitignore create mode 100644 apc.h create mode 100755 ir.c create mode 100755 ir.h create mode 100644 lexer.c create mode 100644 lexer_fsm.c create mode 100644 lexer_fsm.rl create mode 100755 lexer_lex.rl create mode 100644 main.o create mode 100644 name.c create mode 100644 output.c create mode 100644 parser.y create mode 100755 ragraph create mode 100644 ragraph.png create mode 100644 scanner.c diff --git a/.gdb/ir.o b/.gdb/ir.o new file mode 100644 index 0000000000000000000000000000000000000000..ce9ee2efe5e19026cf3724460b77307ff1d4a30d GIT binary patch literal 15232 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 t<`>}(r%>Ur$3w@C8Urhi2 literal 0 HcmV?d00001 diff --git a/.gdb/irmem.o b/.gdb/irmem.o new file mode 100644 index 0000000000000000000000000000000000000000..7822d5fb9381251846f961c1142724dad1db9ee5 GIT binary patch literal 30488 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 literal 0 HcmV?d00001 diff --git a/.gdb/lexer.o b/.gdb/lexer.o new file mode 100644 index 0000000000000000000000000000000000000000..5833e5a2dd89109ed28f1fa873516ad646d3470d GIT binary patch literal 14280 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

uio^Vj!Tl1z;35MV-=q+7 z9M=%ls{DtTT_6x=7cK1;n{4`=eXDLqWYcMC{R>6DcxLQgNe#m!<50oCp z=PCA2J^>LwWW80!lLk2Ghl4X@YM4WHK#2g6jifkkis#=`9P}G`%5gI&|8O3!;`2U_ z(UX1tAVz;2>!TR1f#<_&#t$DXYA1=&Z^3>xF#5^3zZnc4fcb8Q6a6`g!#I$2vXtWB zA_n`ZV)#DHA5t6+$^OY}%*pvWg8NHeG{|{DRd^c!LS%%S%Cej`=EP4sZWsMiC2uS@ zWOzB&n|8r}VE8Pox9)!Mh7i{!bQ)VSXxO{~?T? z@JNQ|;_D0kCl`$PAv}TM)%ZLnF+5vVo!h{0qTj;s={U}eF8B_HhvWI5*9AYw@K3m3 z`Caf|aXBRPdWCP-{5bT&eS$mx?2$oW3{uw{K40D>RhTmjpuws6kGD zNpN5w`ew=LqyNwr>!W`d87KQ9Dyt;+TkIo2-#c+%|38TkRfbbY&O7mCg%8+&fWxPo z$T;{W1M|n~3y~fCi7(uA>=?c$LS1st(Zu>unB(bmlg(7Wd^&RoLQ_Oq& z`iHF_go-+gpEHovA#pXGyeDkR6WE*;mW8630PYnU-%a-{wh#sSk!{(Zi)@$XY$85=+3+1NooUtLzo9D+jzdqNNc+df=oowc8? NfeMg`mRJk`|>++N6{g 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 r{Ix8+uW31y^*nC+YsCDIQon#i literal 0 HcmV?d00001 diff --git a/.gdb/parser-save.tab.o b/.gdb/parser-save.tab.o new file mode 100644 index 0000000000000000000000000000000000000000..4b63af1e07ec27cd6118912e52cf85f1e94ca559 GIT binary patch literal 29760 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 literal 0 HcmV?d00001 diff --git a/.gdb/scanner.o b/.gdb/scanner.o new file mode 100644 index 0000000000000000000000000000000000000000..595a41c90a92fdcafff61e5770b3e81922b71ee9 GIT binary patch literal 15904 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 T+uHux-w!K*q)RkNWU2oFg`@&b literal 0 HcmV?d00001 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..86a7b85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.tab.c +*.tab.h +lexer_lex.c diff --git a/apc.h b/apc.h new file mode 100644 index 0000000..6a8df1e --- /dev/null +++ b/apc.h @@ -0,0 +1,33 @@ +#include +#include +#include + +//ir.h +#define BUF_SIZE 256 +#define MAX_SETS 256 +#define MAX_ELES 256 +#define MAX_QUADS 256 +#define MAX_MODELS 256 +#define MAX_MODEL_LEN 256 +#define MAX_MAPS 8 +#define MAX_POSTS 256 +#define MAX_CLASS_DEPTH 256 +#define MAX_CLASSES 256 +#define MAX_FRAMES 256 +#define PTRS_IN_PAGE 1024 +#define MAX_CHUNKS 256 +#define PAGES_PER_CHUNK 16 +#define MAX_DEPTH 8 +//irmem.c +#define PAGES_PER_CHUNK 16 +#define MAX_NAME_LEN 128 +#define MAX_DEPTH 8 +//lexer.c +#define FNAME_MAX 1024 +#define FPATH_MAX 8192 + + +struct name +{ + uint8_t name[MAX_NAME_LEN]; +}; diff --git a/ir.c b/ir.c new file mode 100755 index 0000000..8652ddc --- /dev/null +++ b/ir.c @@ -0,0 +1,1336 @@ +/*!@file + \brief IR Memory Implementation + \details Intermediary memory management + \author Jordan Lavatai + \date Aug 2016 + ----------------------------------------------------------------------------*/ +#include +#include +#include //uint8_t as a char +#include //u32_cpy +#include //uint64_t +#include //memset +#include //u8_* functions +#include "apc.h" + + +extern +int +name_u8_cpy(struct name*, struct name*); + +extern +int +name_u8_cmp(struct name*, struct name*); + +extern +int +name_u8_set(struct name*, ucs4_t); + +int +ir_init(void); +struct cdat* +alloc_cdat(void); +struct odat* +alloc_odat(void); +void +alloc_vdat(void); +struct link* +alloc_link(void); +struct ref* +alloc_ref(void); +struct set* +alloc_set(void); +struct cdat* +curr_cdat(void); +struct odat* +curr_odat(void); +struct vdat* +curr_vdat(void); +struct map* +curr_map(void); +struct set* +curr_cdat_set(void); +struct set* +curr_set(int); +struct ref* +curr_ref(void); +struct model* +curr_model(void); + +/* ir.c */ +void +inc_posts(void); +void +push_cdat(struct name*); +void +pop_cdat(void); +void +insert_link_name(struct name*); +void +insert_link_namelist(struct name*); +void +insert_ss_name(struct name*); +void +insert_ss_namelist(struct name*); +void +insert_mlink(struct name*, int); +void +insert_vlink(struct name*, int); +void +insert_ref(struct odat*, int); +void +alloc_vdat(void); +void +insert_vdat(void); +void +insert_map(struct name*, int, int, int, int, uint8_t*); +void +insert_framesheet(struct name*, int, int, int, int, uint8_t*); + + + +//type safety handled by macro expansion (do not call these directly from code, make dependent macros for access to these) +#define CHUNKS_LEN(STACK) ((STACK).csp - (STACK).chunks) +#define CURRENT_CHUNK(STACK) ((STACK).chunks[CHUNKS_LEN(STACK) - 1]) +#define CHUNKS_FULL(STACK) ( (STACK).csp >= \ + (STACK).chunks + MAX_CHUNKS * (STACK).chunk_size) +#define CURRENT_DSP(STACK,TYPE) ((TYPE*) ((STACK).dsp[CHUNKS_LEN(STACK) - 1])) +#define DATA_FULL(STACK,TYPE) ((void*) CURRENT_DSP(STACK,TYPE) >= \ + (CURRENT_CHUNK(STACK) + (STACK).chunk_size)) +#define CSP_PUSH(STACK) (*(++(STACK).csp) = malloc((STACK).chunk_size)) +#define CURRENT_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 1]) +#define PREVIOUS_DATP(STACK,TYPE) (((TYPE**)(STACK).dsp)[CHUNKS_LEN(STACK) - 2]) +#define ALLOC_DAT(STACK,TYPE) (++CURRENT_DATP(STACK,TYPE)) +#define INIT_STACK(STACK,TYPE) \ + { int i; \ + (STACK).chunk_size = PAGES_PER_CHUNK * pagesize; \ + (STACK).max_dats = (STACK).chunk_size / sizeof (TYPE); \ + CSP_PUSH(STACK); \ + for( i = 0; i < MAX_CHUNKS; i++){ \ + (STACK).dsp[i] += pagesize; \ + } \ + } +//Stack-specific macros (called directly from code (safety enforcement) +#define INIT_ODAT() (INIT_STACK(ocs, struct odat)) +#define CURRENT_ODAT() (CURRENT_DATP(ocs,struct odat)) +#define ODAT_FULL() (DATA_FULL(ocs,struct odat)) +#define ODAT_ALLOC() (ALLOC_DAT(ocs,struct odat)) +#define OCS_FULL() (CHUNKS_FULL(ocs)) +#define INIT_VDAT() (INIT_STACK(vcs, struct vdat)) +#define CURRENT_VDAT() (CURRENT_DATP(vcs,struct vdat)) +#define VDAT_FULL() (DATA_FULL(vcs,struct vdat)) +#define VDAT_ALLOC() (ALLOC_DAT(vcs,struct vdat)) +#define VCS_FULL() (CHUNKS_FULL(vcs)) +#define INIT_CDAT() (INIT_STACK(ccs, struct cdat)) +#define CURRENT_CDAT() (CURRENT_DATP(ccs,struct cdat)) +#define CDAT_FULL() (DATA_FULL(ccs, struct cdat)) +#define CDAT_ALLOC() (ALLOC_DAT(ccs, struct cdat)) +#define CCS_FULL() (CHUNKS_FULL(ccs)) +#define INIT_SET() (INIT_STACK(scs, struct set)) +#define CURRENT_SET() (CURRENT_DATP(scs, struct set)) +#define SET_FULL() (DATA_FULL(scs, struct set)) +#define SET_ALLOC() (ALLOC_DAT(scs, struct set)) +#define SCS_FULL() (CHUNKS_FULL(scs)) +#define INIT_LINK() (INIT_STACK(lcs, struct link)) +#define CURRENT_LINK() (CURRENT_DATP(lcs,struct link)) +#define LDAT_FULL() (DATA_FULL(lcs, struct link)) +#define LDAT_ALLOC() (ALLOC_DAT(lcs, struct link)) +#define LCS_FULL() (CHUNKS_FULL(lcs)) +#define INIT_POST() (INIT_STACK(rcs, struct ref)) +#define CURRENT_POST() (CURRENT_DATP(pcs,struct ref)) +#define POST_FULL() (DATA_FULL(pcs,struct ref)) +#define POST_ALLOC() (ALLOC_DAT(pcs,struct ref)) +#define PCS_FULL() (CHUNKS_FULL(pcs)) +#define INIT_REF() (INIT_STACK(rcs, struct ref)) +#define CURRENT_REF() (CURRENT_DATP(rcs,struct ref)) +#define PREVIOUS_REF() (PREVIOUS_DATP(rcs, struct ref)) +#define REF_FULL() (DATA_FULL(rcs,struct ref)) +#define REF_ALLOC() (ALLOC_DAT(rcs,struct ref)) +#define RCS_FULL() (CHUNKS_FULL(rcs)) +//Metadata +#define CURRENT_MODEL() (CURRENT_VDAT()->model_list[CURRENT_VDAT()->num_models]) + + + +/* Dynamically allocate memory for a class data structure, + or cdat, after a class has been identified in a grammar. + We also create a stack of class pointers so that + we can access the cdat during processing of that + cdats sets and elements, a requirement because the + nature of recursive classes prevents us from accessing + the cdat based on the previous index into cdat_buf, + which is a list of all allocated cdats +/* Cdats: A cdat is a class data structure. Cdats serve as the central */ +/* data types of the IR. Cdats contain pointers to their subclasses so that the relationship between */ +/* classes can be determined, but the subclasses are not represented inside */ +/* of the cdat itself but rather in subsequent cdats in cdat_buf. We */ +/* can determine the number of subclasses (the last index into cdat_buf */ +/* that represents a subclass of some arbitrary cdat) each cdat has by */ +/* incrementing num_classes during parse time. */ +/* TODO: Should classes point to their parent class? */ +/* TODO: Talk more about cdat set structure */ +struct cdat { + struct name name; + int idx; + int num_classes; + int num_sets; + struct cdat* class_list[MAX_CLASSES]; + struct set* set_list[MAX_SETS]; +}; + + +/* Sets: What is a set? + Instantiation? + Associations? + Containment? + Usage? + The set is populated at parse time AFTER the elements are populated, due to + the nature of bottom up parsing. */ +struct set { + int cdat_idx; + int num_sets; + struct set* set_list[MAX_SETS]; +}; + +/* Refs: Each set/ele has a reference to its object data (odat) through a refid. + refids are unsigned 64 byte integers that map to the hex values RGBA. During + the construction of the directory structure, users can choose a RGBA value for + each object that any other object can refer to via links (see link). If a user + does not choose an RGBA value, then the object is given one from the system space. + We maintain a doubly linked list of refs in the ref_buf at parse time so that + links can be resolved after the parsing of the directory structure is complete. + For every 16th ref, we create a post so that we can reduce on the search time for + a random access. */ + +struct ref { + int type; //TODO: Is this needed? + struct ref* nextref; + struct ref* lastref; + struct odat* odatp; + int refid; //0xFFFFFF->digit +}; + +/* Links: At parse time, a set/ele can include a link in their + grammar representation instead of the actual data and this signifies + to the APC that that set/ele wishes to use the data of another + set/ele, either its video data (vdat) or object data (odat). The link + itself contains the type of link it is, the refid OR name, and + which set/ele created the link. During parse time, links can be made + to o/vdats that have yet to be parsed. In order to accomodate for this, + we resolve all links AFTER parse time by iterating through the link_buf, + finding the refid that was stored for some object (if the refid exists), + and creating a relative pointer from the original object to the data that + was linked */ + +/* TODO: Explain links more betta */ + +struct olink { + int src_refid; +}; + +struct vlink { + int src_refid; + struct name src_animname; + struct name src_namelist[MAX_DEPTH]; +}; + +struct mlink { + int src_refid; + struct name src_mapname; + struct name src_namelist[MAX_DEPTH]; + +}; + +union link_t { + struct vlink vlink; + struct mlink mlink; + struct olink olink; +}; + + +/* From: src odat ()To: dest odat (refid)*/ +struct link { + int type; //1 = olink, 2 = vlink, 3 = mlink + union link_t link_t; + int dest_refid; //if it exists + struct odat* dest_odatp; + +}; + +struct map { + struct name name; + int height; + int width; + uint8_t filepath[FPATH_MAX]; +}; + +/* Odats: Odats consist of the object data necessary for + each object. Odats are sometimes referred to as archetypes + at compile-time, in order to distinguish the difference from + a runtime object and a compile-time object. + TODO: Need more info about objects at runtime, to described + the reasoning behind odat structure at compile-time*/ +struct odat { + struct name name; + int refid; + int ismap; + int vdat_idx; + struct link* linkp; + struct vdat* vdatp; + struct odat* parent_odatp; // odat == set ? null : set refid + struct ref* refp; /* pointer to it's ref on ref_list */ + struct map map; //only valid if odat ismap + +}; + +/* A framesheet is a grouping of animation frames in + a single direction (N,W,S,E) */ +struct framesheet { + int width; + int height; + int num_frames; + +}; + +/* A model is a collection of framesheets for every + direction (N,W,S,E,NW,NE,SW,SE)*/ +/* NAMED spritesheet */ +struct model { + struct name name; + uint8_t filepath[PATH_MAX]; + struct framesheet spritesheet[8]; //one for each +}; + +/* Vdat: Vdats are the video data of each object. They can not be + created as a stand alone object (because they consist solely + of animation information and not the map which the + animation manipulates). Vdats have a list of models for every + animation that the vdats odat can do for that vdat*/ +struct vdat { + struct odat* creator; //pointer to odat that made this vdat + int num_models; + uint8_t filename[FNAME_MAX]; + int height; + int width; + uint8_t filepath[FPATH_MAX]; + struct model model_list[MAX_MODELS]; +}; + + +struct set_frame +{ struct name namelist[MAX_DEPTH]; + int num_names; + struct set* setp; + struct odat* odatp; +} ; + + + +struct set_stack +{ struct set_frame set_frames[MAX_DEPTH]; + int curr_depth; //used to get most recently created set/odat + to check for undefined parents of namelists +}; + + +//"type free" chunk stacking +struct chunk_stack +{ void* chunks[MAX_CHUNKS]; + void* *csp; //chunk stack pointer + void* dsp[MAX_CHUNKS]; //dat stack pointer (per chunk) + int chunk_size; //size of a chunk (including its forfeited page) + int max_dats; //number of dats per chunk for this stack +} ocs, vcs, ccs, rcs, lcs, pcs, scs; //odat, vdat, cdat, ref, link, post stacks + + + + +/* The cdat_stack is a stack pointers to cdat pointers, the top of which is + the cdat that is currently being parsed. Whenever a new cdat is recognized + by the grammar (CLOPEN), a cdat is pushed onto the cdat_stack, and we refer + to this cdat through the macro CURR_CDAT. By keeping a cdat_stack, we have + access to the current cdat so that the elements and sets can populate themselves + in the cdat accordingly. */ + + +struct cdat* cdat_stack[MAX_CLASSES]; +struct cdat** cdat_stackp; + +struct set_stack ss; +struct name set_namelist[MAX_DEPTH]; +int set_numnames = 0; + +struct name link_namelist[MAX_DEPTH]; +int link_numnames = 0; + +int num_cdats = 0; +int num_odats = 0; +int num_vdats = 0; +int num_sets = 0; +int num_refs = 0; +int ss_refid = 0x0FFFFFFF; /* system space for refids */ +int num_posts = 0; +int num_links = 0; +int num_models = 0; +long pagesize = 0; + + +/* The initalization function of the IR. */ +int +ir_init() +{ struct name name; + + + uint8_t root[4] = "root"; + + u8_stpncpy(name.name, root, 4); + + pagesize = sysconf(_SC_PAGESIZE); + printf("pagesize is %l\n", pagesize); + + INIT_CDAT(); + *cdat_stackp = CURRENT_CDAT(); + name_u8_cpy(&(*cdat_stackp)->name, &name); + + INIT_ODAT(); + INIT_VDAT(); + VDAT_ALLOC(); //NULL vdat + VDAT_ALLOC(); //First vdat req. because alloc_vdat happens after vdat is reduced + INIT_SET(); + INIT_LINK(); + INIT_REF(); + INIT_POST(); + + + return 0; + +} + +void +ir_quit() +{ + int i; + + for(i = 0; i < CHUNKS_LEN(ccs) ; i++) + { + free(ccs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(ocs); i++) + { + free(ocs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(vcs) ; i++) + { + free(vcs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(rcs); i++) + { + free(rcs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(lcs); i++) + { + free(lcs.chunks[i]); + } + for(i = 0; i < CHUNKS_LEN(pcs); i++) + { + free(pcs.chunks[i]); + } + +} + +struct cdat* +alloc_cdat() +{ + num_cdats++; + if(CDAT_FULL()) + { if(CCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) cdats ", num_cdats); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(ccs); + } + else + CDAT_ALLOC(); + + return CURRENT_CDAT(); +} + +//these should probably be inline +struct odat* +alloc_odat +() +{ + num_odats++; + if(ODAT_FULL()) + { if(!OCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) odats ", num_odats); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(ocs); + } + else + ODAT_ALLOC(); + + return CURRENT_ODAT(); +} + +void +alloc_vdat +() +{ num_vdats++; + if(VDAT_FULL()) + { if(!VCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) vdats ", num_vdats); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(vcs); + } + else + VDAT_ALLOC(); + + +} + +struct set* +alloc_set +() +{ num_sets++; + if(SET_FULL()) + { if(!SCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) sets ", num_sets); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(scs); + } + else + SET_ALLOC(); + + return CURRENT_SET(); +} + + +struct link* +alloc_link +() +{ num_links++; + if(LDAT_FULL()) + { if(!LCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) links ", num_links); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(lcs); + } + else + LDAT_ALLOC(); + + return CURRENT_LINK(); + +} + +struct ref* +alloc_ref +() +{ num_refs++; + if(REF_FULL()) + { if(!RCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) refs ", num_refs); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(rcs); + } + else + REF_ALLOC(); + + + if(num_refs % 16 == 0) + { CURRENT_POST() = CURRENT_REF(); + inc_posts(); + } + + return CURRENT_REF(); +} + +void +inc_posts() +{ num_posts++; + if(POST_FULL()) + { if(!PCS_FULL()) + { fprintf(stderr, "You have allocated to many (%d) refs ", num_posts); + exit(EXIT_FAILURE); + } + else + CSP_PUSH(pcs); + } + else + POST_ALLOC(); + +} + +struct cdat* +curr_cdat +() +{ + return (*cdat_stackp); +} + +struct odat* +curr_odat +() +{ + return CURRENT_ODAT(); +} + +struct vdat* +curr_vdat +() +{ + return CURRENT_VDAT(); +} + +struct set* +curr_cdat_set +() +{ + return CURRENT_SET(); +} + +struct set* +curr_set +(int depth) +{ int i; + struct set* setp; + + for(i = 0; i <= depth; i++) + { if(!(setp = setp->set_list[setp->num_sets])) + { printf("You are trying to access a set that does not exist irmem.c\n"); + return NULL; + } + } + + + return setp; +} + +struct ref* +curr_ref +() +{ + return CURRENT_REF(); +} +struct ref* +prev_ref +() +{ + return PREVIOUS_REF(); +} +struct model* +curr_model +() +{ + return &CURRENT_MODEL(); +} + +/* IR.C*/ +void +push_cdat +( name ) + struct name* name; +{ + struct cdat* curr_cdatp; + + curr_cdatp = alloc_cdat(); + + name_u8_cpy(&curr_cdatp->name, name); + curr_cdatp->idx = num_cdats; + + /* Set the cdat as a subclass of the previous cdat */ + (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes] = curr_cdatp; + /* Push the cdat onto the cdat_stack */ + *++cdat_stackp = curr_cdatp; + +} + +void +pop_cdat +() +{ + cdat_stackp--; +} + + +void +insert_set_name +( name ) + struct name* name; +{ + //Push name onto current namelist, set the set_namelist. + name_u8_cpy(&set_namelist[set_numnames++], name); + + +} + + +void +insert_set_namelist +( name ) + struct name* name; +{ int depth, nameidx, i; + + insert_set_name(name); + + //Check if entire string matches first? Only possible if namelist is contiguous (uint8_t strings seperated by \0) + //Create odats/sets for each name in namelist where nameidx > ns_depth + //first check if any parts of namelist matches what is currently on namestack + //we can gauruntee that from ns_depth + 1 -> set_numnames namelists dont match. x + + + //if name_list doesnt match, from the first depth at which namelist doesnt match + //remove the nameframes namelist (zero out ones below?) and replace with current namelist, + //then allocate a new odat and set it to the current set_frame. + for( depth = 0; depth < set_numnames ; depth++ ) + { for (nameidx = 0; nameidx <= depth; nameidx++) + { if( name_u8_cmp(&set_namelist[nameidx], &ss.set_frames[depth].namelist[nameidx]) != 0 ) + { /* Populate the namelist of the set at the current depth */ + for(i = 0; i <= depth; i++) + name_u8_cpy(&ss.set_frames[depth].namelist[i], &set_namelist[i]); + + /* Alloc set and odat */ + ss.set_frames[depth].odatp = alloc_odat(); + ss.set_frames[depth].setp = alloc_set(); + + /* populate set/odat name and cdat_idx */ + name_u8_cpy(&ss.set_frames[depth].odatp->name, &set_namelist[depth]); + ss.set_frames[depth].setp->cdat_idx = ( *cdat_stackp)->idx; + + /* Insert allocated set and odat into their respective trees if there is a depth + (they have parents) */ + if(depth) + { ss.set_frames[depth].odatp->parent_odatp = ss.set_frames[depth-1].odatp; + if(ss.set_frames[depth-1].setp->num_sets < MAX_SETS) + ss.set_frames[depth-1].setp->set_list[ss.set_frames[depth-1].setp->num_sets++] = ss.set_frames[depth].setp; + else + { printf("you have allocated too many sets in insert_namelist()\n"); + //TODO: EXIT() + } + } + else /* no parent set, so assign to cdat set_list */ + { ss.set_frames[depth].odatp->parent_odatp = NULL; //no parent odat = NULL. + if(curr_cdat_set()->num_sets < MAX_SETS) + curr_cdat_set()->set_list[curr_cdat_set()->num_sets++] = ss.set_frames[depth].setp; + else + { printf("you have allocated too many sets in insert_namelist()\n"); + //TODO: EXIT() + } + } + + + ss.set_frames[depth].num_names = set_numnames; + ss.curr_depth = depth; + } + + } + + } + done: + ; +} + +/*. We create new odats for each map variant that are children of the current odat/set + , set their name as the map name, and identify them by marking them as a map. This lets + us distinguish between sibling odatsthat have the same name because the map of the parent + odat had the same name as another, regular odat*/ +#define CURR_SS_FRAME() (ss.set_frames[ss.curr_depth]) +#define CURR_SS_SETP() (CURR_SS_FRAME().setp) +#define CURR_SS_ODATP() (CURR_SS_FRAME().odatp) +void +insert_map +( name, direction, height, width, refid, filepath ) + struct name* name; + int direction, height, width, refid; + uint8_t* filepath; +{ int i; + struct odat* curr_mem_odatp; //pointer to odat in odat_buf + struct set* curr_mem_setp; //pointer to set in set_buf + struct link* linkp; + + curr_mem_odatp = alloc_odat(); + curr_mem_setp = alloc_set(); + //Create a new odat, make its parent be the set. Make a set for mdat, its name should + //be the name of the odat + name of model. That makes a conflict beween odats that are named + //the same thing as the model of a sibling odat that was created from a map. They can have + //same name if the map odat is marked. So mark the map odat. + + //insert parent odat + curr_mem_odatp->parent_odatp = CURR_SS_ODATP(); + //insert into set_list + if(CURR_SS_SETP()->num_sets < MAX_SETS) + CURR_SS_SETP()->set_list[CURR_SS_SETP()->num_sets++] = curr_mem_setp; + else + { printf("You have allocated to many sets, error in insert_map()\n"); + //TODO: EXIT() + } + + //indicate that newly created odat is a map + curr_mem_odatp->ismap = 1; + //set odat and set name + name_u8_cpy(&curr_mem_odatp->name, name); + + /* set cdat idx values for both set and odat */ + curr_mem_setp->cdat_idx = num_cdats; + + + /* Generate refid if needed, put into ref_buf */ + if(!refid) + refid = ss_refid++; + + insert_ref(curr_mem_odatp, refid); + + /* If current odatp on stack has a link, then we need to make our own link. just set the vdat_idx */ + if(CURR_SS_ODATP()->vdat_idx = 0) + { //alloc a link + linkp = alloc_link(); + linkp->type = CURR_SS_ODATP()->linkp->type; + linkp->dest_odatp = CURR_SS_ODATP(); + linkp->dest_refid = refid; + linkp->link_t.mlink.src_refid = CURR_SS_ODATP()->linkp->link_t.mlink.src_refid; + + /* Copy the animation name of the vlink*/ + name_u8_cpy(&linkp->link_t.vlink.src_animname, &CURR_SS_ODATP()->linkp->link_t.vlink.src_animname); + /* Copy the namelist of the vlink*/ + for(i = 0; i < MAX_DEPTH; i++) + name_u8_cpy(&linkp->link_t.vlink.src_namelist[i], &CURR_SS_ODATP()->linkp->link_t.vlink.src_namelist[i]); + } + else + curr_mem_odatp->vdat_idx = CURR_SS_ODATP()->vdat_idx; + + + + +} + + +/* 11/22 Each vdat has a multiple models. Each model has 8 framesheets, one in each + direction, that create a spritesheet. Inserting framesheets into the correct + model is just a matter of checking whether or not the last models name matches + + the current one. We can never get a framesheet that is for the same model before + AND after some other model, due to alphasorting of the files in each directory */ +void +insert_framesheet +( model_name, direction, height, width, refid, filepath ) + struct name* model_name; + int direction, height, width, refid; + uint8_t* filepath; +{ struct vdat* curr_vdatp; + struct model* curr_modelp; + static struct name last_model_name[32]; + + + curr_vdatp = curr_vdat(); + + /* If the model name changed, that means there are no more + framesheets for that model to be processed, a guaruntee we make + b/c the filenames are alphabetically sorted */ + if(!name_u8_cmp(last_model_name, model_name)) + { if(curr_vdatp->num_models) + curr_vdatp->num_models++; + num_models++; // total number of models + } + + + if(CURR_SS_ODATP()->refid == 0) + { if(!refid) + refid = ss_refid++; + insert_ref(CURR_SS_ODATP(), refid);//given a odatp and a refid, insert the odatp into the ref_buf. + //push ref into ref_buf. + } + else + printf("error: redefining a previously set refid\n"); + + curr_modelp = curr_model(); + + name_u8_cpy(&curr_modelp->name, model_name); + curr_modelp->spritesheet[direction].height = height; + curr_modelp->spritesheet[direction].width = width; + + name_u8_cpy(last_model_name, model_name); + + +} + + + +//src_path is stored in link_namelist +void +insert_mlink +( src_mapname, src_refid) + struct name* src_mapname; + int src_refid; +{ struct link* linkp; + int i; + + linkp = alloc_link(); + + /* set type */ + linkp->type = 3; + /* set the name of the src map for the link, if a name exists */ + if(src_mapname) + name_u8_cpy(&linkp->link_t.mlink.src_mapname, src_mapname); + /* Set the source ref id of the link */ + linkp->link_t.mlink.src_refid = src_refid; + /* Copy the entire namelist of the link, if it exists */ + for(i = 0; i < link_numnames; i--) //TODO MAX_DEPTH -> link_namelist_num?? + { name_u8_cpy(&linkp->link_t.mlink.src_namelist[i], &link_namelist[i]); + name_u8_set(&link_namelist[i], (ucs4_t) 0); + } + link_numnames = 0; + + linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack + +} + +void +insert_link_name +( name ) + struct name* name; +{ + //Push name onto current namelist, set the set_namelist. + name_u8_cpy(&link_namelist[link_numnames++], name); + +} + +/* Nearly identical to mlink */ +void +insert_vlink +( src_animname, src_refid ) + struct name* src_animname; + int src_refid; +{ struct link* linkp; + int i; + + linkp = alloc_link(); + + /* set type */ + linkp->type = 2; + + /* set the name of the src animname for the link, if a name exists */ + if(src_animname) + name_u8_cpy(&linkp->link_t.vlink.src_animname, src_animname); + + /* Set the source ref id of the link */ + linkp->link_t.mlink.src_refid = src_refid; + + /* Copy the entire namelist of the link, if it exists */ + for(i = 0; i < link_numnames; i++) //TODO MAX_DEPTH -> link_namelist_num?? + { name_u8_cpy(&linkp->link_t.vlink.src_namelist[i], &link_namelist[i]); + name_u8_set(&link_namelist[i], (ucs4_t) 0);//set to null for next link_namelist + } + + linkp->dest_odatp = CURR_SS_ODATP();//current odat on set_stack + +} + + +/* TODO: Do we really need to store the prev/next pointer? iterating through the + ref_buf could be achieved by iterating until the num_refs anyway. */ +void +insert_ref +( odatp, refid ) + struct odat* odatp; + int refid; +{ struct ref* curr_refp; + struct ref* prev_refp; + + curr_refp = alloc_ref(); + prev_refp = prev_ref(); + + prev_refp->nextref = curr_refp; + curr_refp->lastref = prev_refp; + + curr_refp->odatp = odatp; + curr_refp->refid = refid; + + if(refid % 16) + { POST_ALLOC(); + CURRENT_POST()->refid = refid; + CURRENT_POST()->odatp = odatp; + } + + + +} + +void +insert_vdat +() +{ struct odat* curr_ss_odatp; + struct vdat* curr_vdatp; + + curr_vdatp->creator = curr_ss_odatp; + curr_ss_odatp->vdat_idx = num_vdats; + curr_ss_odatp->vdatp = curr_vdatp; + alloc_vdat(); +} + +void +insert_refid_statement +( refid ) + int refid; +{ CURR_SS_ODATP()->refid = refid; +} +#if 0 + + +/* Called in the reduction of a set. While both odats (eles and sets) + have identical label terminals, we are unable to give a single grammatical rule + for both due to how we allocate odats in the odat buf. Due to the + nature of bottom up parsing, the set label is recognized first, and then the + sets elements are recognized. This means that after we have processed the sets elemenets, + the curr_odat is going to be the last element and NOT the set that was first allocated. + To get around this, we create a global variable set_odatp that will store the pointer + to the odat when it is first allocated (in insert_set_label()) so that insert_set() can + have access to it. Curr set points the sets representation in the cdat, curr_set_odatp + points to the sets representation as an odat*/ + +//TODO: Add insert_set_ref() +//TODO: Is this the correct allocation scheme? No do the one ken suggested +void +insert_s_name +( struct name* name +) +{ + + struct set* curr_setp; + + curr_setp = curr_set(); + curr_set_odatp = alloc_odat(); + + u8_cpy(curr_set_odatp->name, name, 32); + u8_cpy(curr_setp->name, name, 32); + curr_set_odatp->parent_odatp = NULL; + + +} + +/* Inserting a olink instead of a set. Set is really just a placeholder + for another set. Allocate the memory for the set so taht it can be populated*/ +void +insert_set_olink +( int refid +) +{ + struct set* curr_setp; + + curr_setp = curr_set(); + + curr_setp->refid = refid; + +} + +void +insert_set_vlink +( int refid, + uint8_t* anim_name +) +{ + struct cdat* curr_cdatp; + struct odat* curr_odatp; + struct link* curr_linkp; + + + curr_cdatp = curr_cdat(); + curr_odatp = curr_odat(); + curr_linkp = alloc_link(); + + /* Insert vlink into link_stack so that it gets processed at + output time */ + curr_linkp->type = 2; + /* Store the target odat information*/ + curr_linkp->link_t.vlink.refid = refid; + u8_cpy(curr_linkp->link_t.vlink.anim_name, anim_name, 32); + /* Store the linking odat/cdat information */ + curr_linkp->classp = curr_cdatp; + curr_linkp->odatp = curr_odatp; + curr_linkp->set_idx = curr_cdatp->num_sets; + // curr_linkp->ele_idx = -1; + +} + +/* Svlinks dont have animation names */ +void +insert_set_svlink +( int refid +) +{ + struct cdat* curr_cdatp; + struct link* curr_linkp; + + curr_cdatp = curr_cdat(); + curr_linkp = alloc_link(); + + /* Insert svlink into link_stack so that it gets processed at + output time */ + curr_linkp->type = 3; + curr_linkp->classp = curr_cdatp; + curr_linkp->set_idx = curr_cdatp->num_sets; + // curr_linkp->ele_idx = -1; + curr_linkp->link_t.svlink.refid = refid; + +} + +/* At the point of reducing to a set, most of the + sets odat information has already been populated + during the reduction of its right hand side + non terminals (hitbox, root, quad_list). */ +void +insert_set +() +{ int refid; + struct odat* curr_odatp; + struct cdat* curr_cdatp; + struct set* curr_setp; + struct ref* prev_refp; + struct ref* curr_refp; + struct vdat* curr_vdatp; + + curr_odatp = curr_set_odatp; //allocated at insert_set_label + curr_cdatp = curr_cdat(); + curr_setp = curr_set(); + prev_refp = curr_ref(); + curr_refp = alloc_ref(); + curr_vdatp = curr_vdat(); + + curr_vdatp->creator = curr_set_odatp; + + curr_setp->cdat_idx = curr_cdatp->idx; //does a set need its class idx? + u8_cpy(curr_setp->name, curr_odatp->name, 32); + curr_cdatp->num_sets++; + + curr_odatp->cdat_idx = curr_cdatp->idx; + curr_odatp->refp = curr_refp; + + refid = curr_setp->refid; // refid set by insert_set_label(name, refid) + + curr_refp->refid = refid; + curr_refp->lastref = prev_refp; + curr_refp->odatp = curr_odatp; + prev_refp->nextref = curr_refp; + + + +} +/* Created as a seperate function, instead of setting the ODATS vdat_id and + calling inc_vdat() inside of insert_set(), to account for the set reduction + where a vdat is not created (o/v/svlinks). */ +void +insert_set_vdatid +() +{ + struct vdat* curr_vdatp; + + curr_vdatp = curr_vdat(); + + curr_set_odatp->vdat_id = num_vdats; //no vdat_id for odats that have vlinks/svlinks + curr_set_odatp->vdatp = curr_vdatp; + curr_set_odatp = NULL; //This sets odat shouldnt be modified after populating odats vdat info +} + +/* Populates the odat name and refid for odat, allocate the odat here for the rest of + the functions to use via curr_odat(). */ +void +insert_ele_label +( uint8_t* name, + int refid +) +{ + struct odat* curr_odatp; + + curr_odatp = alloc_odat(); + + u8_cpy(curr_odatp->name, name, 32); + curr_odatp->map[0] = 0; + + if(refid != -1) + curr_odatp->refid = refid; + else + curr_odatp->refid = ss_refid++; + +} + +/* We don't make an odat here, at output time we will resolve + the refid to the corresponding odat. */ +void +insert_ele_olink +( int refid +) +{ + /* Do nothing because we already know the refid that + the odat needs for this element (in the quad_file) */ +} + +void +insert_ele_vlink +( int refid, + uint8_t* anim_name +) +{ + struct cdat* curr_cdatp; + struct set* curr_setp; + struct link* curr_linkp; + + curr_cdatp = curr_cdat(); + curr_setp = curr_set(); + curr_linkp = alloc_link(); + + /* Insert vlink into link_stack so that it gets processed at + output time */ + curr_linkp->classp = curr_cdatp; + curr_linkp->type = 2; + curr_linkp->set_idx = curr_cdatp->num_sets; + //curr_linkp->ele_idx = curr_setp->num_ele; + curr_linkp->link_t.vlink.refid = refid; + u8_cpy(curr_linkp->link_t.vlink.anim_name, anim_name, 32); + +} + +void +insert_ele_svlink +( int refid +) +{ + struct cdat* curr_cdatp; + struct set* curr_setp; + struct link* curr_linkp; + + curr_cdatp = curr_cdat(); + curr_setp = curr_set(); + curr_linkp = alloc_link(); + + curr_linkp->classp = curr_cdatp; + curr_linkp->type = 3; + + //curr_linkp->ele_idx = curr_setp->num_ele; + curr_linkp->link_t.svlink.refid = refid; + + +} + +//Insert element into odat_buf and cdatpages +void +insert_ele() +{ + int refid; + struct cdat* curr_cdatp; + struct odat* curr_odatp; + struct vdat* curr_vdatp; + struct set* curr_setp; + struct ele* curr_elep; + struct ref* curr_refp; + struct ref* prev_refp; + + + curr_odatp = curr_odat(); //malloced @ insert_ele_label + curr_vdatp = curr_vdat(); + curr_setp = curr_set(); + prev_refp = curr_ref(); + curr_refp = alloc_ref(); + + curr_vdatp->creator = curr_odatp; + + /* Populate odat for ele */ + curr_odatp->cdat_idx = curr_cdatp->idx; + curr_odatp->refp = curr_refp; + curr_odatp->parent_odatp = curr_set_odatp; + + refid = curr_odatp->refid; + + curr_refp->refid = refid; + curr_refp->lastref = prev_refp; + curr_refp->odatp = curr_odatp; + prev_refp->nextref = curr_refp; + +} + +void +insert_ele_vdatid +() +{ struct odat* curr_odatp; + curr_odatp = curr_odat(); + curr_odatp->vdat_id = num_vdats; +} + + + +#endif + + + + +/* void */ +/* insert_quad */ +/* ( int x, int y, int z, int refid */ +/* ) */ +/* { */ +/* struct quad* curr_quadp; */ + +/* curr_quadp = curr_quad(); */ + +/* curr_quadp->x = x; */ +/* curr_quadp->y = y; */ +/* curr_quadp->z = z; */ +/* curr_quadp->refid = refid; */ + + + +/* } */ + +/* /\* serting the hitbox into the set */ +/* odat. Elements that don't have */ +/* a hitbox will use the sets root. *\/ */ +/* void */ +/* insert_hitbox */ +/* ( int hitbox */ +/* ) */ +/* { struct odat* curr_odatp; */ + +/* curr_odatp = curr_odat(); */ +/* curr_odatp->hitbox = hitbox; */ +/* } */ + +/* /\* Inserting the root into the set */ +/* odat. Elements that don't have */ +/* a root will use the sets root. *\/ */ +/* void */ +/* insert_root */ +/* ( int x, */ +/* int y, */ +/* int z */ +/* ) */ +/* { struct odat* curr_odatp; */ + +/* curr_odatp = curr_odat(); */ +/* curr_odatp->root.x = x; */ +/* curr_odatp->root.y = y; */ +/* curr_odatp->root.z = z; */ +/* } */ + + + + +/* void */ +/* insert_frame_pointer */ +/* ( uint8_t direction, */ +/* void* frame */ +/* ) */ +/* { struct model* curr_modelp; */ + +/* curr_modelp = curr_model(); */ + +/* curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame; */ +/* } */ + diff --git a/ir.h b/ir.h new file mode 100755 index 0000000..0d271b1 --- /dev/null +++ b/ir.h @@ -0,0 +1,16 @@ + + +/*!@file +\brief Intermediate Representation (IR) between Directory Structure and Engine Input +\details The IR serves as a storage structure that is populated during the + parsing of the input directory structure. After parsing is complete, + the IR will be condensed (removed of excess allocated space) and then + output as the input for the engine. In this file we describe the semantic actions + that are called at each step, and the memory buffers that they populate. + See parser.y for the description on how the input grammar is constructed, + and where/when semantic actions are called. + TODO: or just write it here. +\author Jordan Lavatai +\date Aug 2016 +----------------------------------------------------------------------------*/ + diff --git a/lexer.c b/lexer.c new file mode 100644 index 0000000..1550db9 --- /dev/null +++ b/lexer.c @@ -0,0 +1,518 @@ +/*!@file + \brief lexical analyzer implementation for APC + \details The lexer manages two FIFO stacks. One for maintaining tokens, the + other for maintaining a list of files to be scanned. During + execution, the lexer will return a token from its token queue if any + are present. If not, the lexer will will pop an element from its + file queue to 'scanner' to be tokenized. If the file queue is empty, + the lexer will instead call 'parsedir' to traverse the directory tree + and tokenize the results. If 'parsedir' does not generate any new + tokens, we are done. + \author Jordan Lavatai + \date Aug 2016 + ----------------------------------------------------------------------------*/ +/* Standard */ +#include +#include +#include +#include +/* Posix */ +#include +#include +#include +#include +#include +#include +#include +#include //realpath, NAME_MAX, FPATH_MAX +#include + +/* Local */ +#include "parser.tab.h" +#ifndef DE_STACKSIZE +#define DE_STACKSIZE 1024 +#endif +#ifndef TK_STACKSIZE +#define TK_STACKSIZE 1024 +#endif + + +/* Public */ +int lexer_init(void); +int lexer(void); +int lexer_lexfile(const uint8_t*); +void lexer_pushtok(int, YYSTYPE); +uint8_t const* lexer_get_current_filepath(void); +int lexer_lexfilename(uint8_t*); +struct dirent* lexer_direntpa[DE_STACKSIZE],** lexer_direntpp,** lexer_direntpb; +/* Private */ +extern //lexer_fsm.rl +int lexer_lexstring(uint8_t*, int); +extern //lexer_fsm.rl +int lexer_setstr(uint8_t*, int); +extern //scanner.c +int scanner_init(void); +extern //scanner.c +int scanner(void); +static inline +int dredge_current_depth(void); +extern //bison +YYSTYPE yylval; +static +uint8_t const* current_filename; + +static +struct tok +{ YYSTYPE lval; //token val + int tok_t; //token type +} token_stack[TK_STACKSIZE], *tsp, *tsx; + +/* Directory Entity Array/Stack + Simple array for keeping track of dirents yet to be processed by the scanner. + If this list is empty and there are no tokens, the lexer is done. + This array is populated by the scanner as an array, and popped locally by the + lexer as a stack, and is popped as a FIFO stack. +*/ +#define DE_STACK (lexer_direntpa) +#define DE_STACKP (lexer_direntpp) +#define DE_STACKB (lexer_direntpb) +#define DE_LEN() (DE_STACKP - DE_STACKB) +#define DE_INIT() (DE_STACKP = DE_STACKB = DE_STACK) +#define DE_POP() (*DE_STACKB++) + +/* Token Stack + This is a FIFO stack whose pointers are a union of either a pointer to an + integer, or a pointer to two integers (a struct tok). This way, integers may + be added or removed from the stack either singularly (IPUSH/IPOP), or as a + full token of two integers (PUSH/POP). + An alignment error will occur if IPOP or IPUSH are used a non-even number of + times in a sequence! +*/ +#define TK_STACK (token_stack) +#define TK_STACKP (tsp) +#define TK_STACKX (tsx) +#define TK_LEN() (TK_STACKX - TK_STACKP) +#define TK_INIT() (TK_STACKP = TK_STACKX = TK_STACK) +#define TK_POP() (*TK_STACKP++) +#define TK_PUSH(T,L) (*TK_STACKX++ = (struct tok){L,T}) + +/* Initializer + The initializer returns boolean true if an error occurs, which may be handled + with standard errno. +*/ +int lexer_init +() +{ TK_INIT(); + DE_INIT(); + return scanner_init(); +} + +/* Lexer + If the token buffer is empty, 'lexer' will initialize the token buffer and + call 'lexer_scandir'. If SCAN_ERROR is returned, an error is printed + before sending a null return to bison. If 0 tokens are generated, the error + printing is skipped. In all other cases, 'yylval' is set, and the token's + integer representation is returned. +*/ +int lexer +#define $($)#$ +#define SCAN_ERROR -1 +#define TK_EMPTY (TK_STACKP == TK_STACKX) +#define FAIL(...) \ + do { \ + fprintf(stderr,__VA_ARGS__); \ + goto done; \ + } while (0) +() +{ struct tok token; + start: + while (DE_LEN() > 0)//lex any directory entries in our stack + { + if (lexer_lexfile(DE_POP()->d_name) == 0) + FAIL("Lexer failed to tokenize [%s]\n",(*DE_STACKB)->d_name); + } + if (TK_EMPTY) //if there are no tokens, + { TK_INIT(); //initialize the token stack back to 0 + switch (scanner()) + { case SCAN_ERROR: //if an error occurred, + FAIL("Scanner error\n"); + case 0: //if the the scanner finds no dirents, + goto done; //then we are done + default: //if we found some elements to scan, + goto start; //start over and lex them + } + } + token = TK_POP(); + yylval = token.lval; + return token.tok_t; + done: + yylval.val = 0; + return 0; +} + + +/* Token Receiver + This receiver takes a struct tok and pushes it to the FIFO stack. +*/ +void lexer_pushtok +#define $($)#$ //stringifier +#define ERR_TK "Fatal: Generated over " $(TK_STACKSIZE) " tokens in one pass." +( int tok, YYSTYPE lval ) +{ if (TK_LEN() >= TK_STACKSIZE) + { fprintf(stderr, ERR_TK); + exit(EXIT_FAILURE); + } + TK_PUSH(tok, lval); +} + +/* Lexical analysis of a file + Strips a filename to its base name, then sends it to lexer_lex +*/ +int lexer_lexfile +#define HIDDEN_WARNING "%s is hidden and will not be parsed!\n", filename +( const uint8_t *filename +) +{ static uint8_t fname[FNAME_MAX]; + uint8_t *last_period = NULL, *iter; + + if (*filename == '.') + { fprintf (stderr, HIDDEN_WARNING); + return 0; + } + /* Copy the filename and remove its suffix */ + u8_strncpy(fname,filename,FNAME_MAX); + last_period = NULL; + for (iter = fname; *iter; iter++) //find the last '.' char + if (*iter == '.') + last_period = iter; + if (last_period) //if we found one, + *last_period = 0; //truncate the string there + /* Register the current_filename */ + current_filename = filename; + printf("lexer_lexfilename(%s)\n",fname); + return lexer_lexfilename(fname); +} + +uint8_t const* lexer_get_current_filepath +() +{ static uint8_t current_path[FPATH_MAX]; + static uint8_t const* last_filename; + if ((!last_filename || last_filename != current_filename) && + ((uint8_t*) realpath(current_filename, current_path) != (uint8_t*) current_path)) + { perror("realpath: "); + return NULL; + } + return (const uint8_t*)current_path; +} + +/* Scan filename and push the its tokens + onto the stack */ +int lexer_lexfilename +(uint8_t* str) +{ int ntok, len; + uint8_t *filepath; + + + printf("|---- Begin lexerfilename on %s ----|\n", str); + + if(*str == 0) + perror("Lexfilename:: str is NULL so fail\n"); + + /* Determine the filetype of str */ + len = u8_strlen(str); + + ntok += lexer_lexstring(str, len); + + /* Pass back filepath as end of statment operator */ + filepath = u8_strdup(lexer_get_current_filepath()); + yylval.str = filepath; + lexer_pushtok(NAME, yylval); + printf("Pushing filepath %s\n", filepath); + ntok++; + + printf("|---- Ending lexer_lexfilename on %s, %d tokens were lexed ----|\n", str, ntok); + return ntok; +} + +/**************************/ +/****Abandon All Hope******/ +/**************************/ +/*** ***/ +/*** ***/ +/*** ***/ +/*** ***/ + +#if 0 +int +lexer_lexelemap +( uint8_t* str) +{ int setname_len, elename_len, strlen; + uint8_t* setname_end, *elename_end, *newstrt; + uint8_t curr_setname[MAX_SETNAME_LEN] = {0}; + uint8_t curr_elename[MAX_ELENAME_LEN] = {0}; + + newstrt = str; + + SET_CURR_SETNAME(newstrt); + SET_CURR_ELENAME(newstrt); + if(PREV_MAPFILE()) + { printf("Lexer_lexelemap:: previous file was mapfile*\n"); + SET_MAPSTR(newstrt); + } + else + { + if(SETNAME_MATCHES()) + { DEL_FTOK(newstrt); + if(REF(newstrt)) + DEL_FTOK(newstrt); + printf("Lexer_lexelemap:: setname matches\n"); + if(ELENAME_MATCHES()) + DEL_FTOK(newstrt); + if(REF(newstrt)) + DEL_FTOK(newstrt); + } + } + + UPDATE_PREV_ELENAME(newstrt); + UPDATE_PREV_SETNAME(newstrt); + + return newstrt - str; + + +} + +int +lexer_lexelemodel +(uint8_t* str) +{ int setname_len, elename_len; + uint8_t* setname_end, *elename_end, *newstrt; + uint8_t curr_setname[MAX_SETNAME_LEN] = {0}; + uint8_t curr_elename[MAX_ELENAME_LEN] = {0}; + + printf("Lexer_lexelemodel:: Begin str is %s\n", str); + + newstrt = str; + + SET_CURR_SETNAME(newstrt); + SET_CURR_ELENAME(newstrt); + if(SETNAME_MATCHES()) + { printf("Lexer_lexelemodel:: curr_setname(%s) matches prev_setname (%s)\n", curr_setname, prev_setname); + DEL_FTOK(newstrt); + printf("Lexer_lexelemodel:: Deleted setname, newstrt is now %s\n", newstrt); + if(REF(newstrt)) + DEL_FTOK(newstrt); + if(ELENAME_MATCHES()) + { printf("Lexer_lexelemodel:: elename matches\n"); + DEL_FTOK(newstrt); + if(REF(newstrt)) + DEL_FTOK(newstrt); + } + } + UPDATE_PREV_ELENAME(newstrt); + UPDATE_PREV_SETNAME(newstrt); + + return newstrt - str; +} + +int +lexer_lexsetmap +(uint8_t* str) +{ int setname_len, elename_len; + uint8_t* setname_end, *elename_end, *newstrt; + uint8_t curr_setname[MAX_SETNAME_LEN] = {0}; + uint8_t curr_elename[MAX_ELENAME_LEN] = {0}; + + newstrt = str; + + SET_CURR_SETNAME(newstrt); + if(PREV_MAPFILE()) + SET_MAPSTR(newstrt); + else + if( SETNAME_MATCHES()) + DEL_FTOK(newstrt); + if(REF(newstrt)) + DEL_FTOK(newstrt); + + UPDATE_PREV_SETNAME(newstrt); + + return newstrt - str; +} + +int +lexer_lexsetmodel +(uint8_t* str) +{ int setname_len, elename_len; + uint8_t* setname_end, *elename_end, *newstrt; + uint8_t curr_setname[MAX_SETNAME_LEN] = {0}; + uint8_t curr_elename[MAX_ELENAME_LEN] = {0}; + + newstrt = str; + + SET_CURR_SETNAME(newstrt); + if( SETNAME_MATCHES()) + DEL_FTOK(newstrt); + if(REF(newstrt)) + DEL_FTOK(newstrt); + UPDATE_PREV_SETNAME(newstrt); + + return newstrt - str; + +} + +int +lexer_lexsetvlink +(uint8_t* str) +{ int setname_len, elename_len; + uint8_t* setname_end, *elename_end, *newstrt; + uint8_t curr_setname[MAX_SETNAME_LEN] = {0}; + uint8_t curr_elename[MAX_ELENAME_LEN] = {0}; + + newstrt = str; + + SET_CURR_SETNAME(newstrt); + if( SETNAME_MATCHES()) + DEL_FTOK(newstrt); + if(REF((NEXT_TOK(newstrt)))) //if NAME REF REF + DEL_FTOK(newstrt); + UPDATE_PREV_SETNAME(newstrt); + + return newstrt - str; + +} + +int +lexer_lexelevlink +(uint8_t* str) +{ int setname_len, elename_len; + uint8_t* setname_end, *elename_end, *newstrt; + uint8_t curr_setname[MAX_SETNAME_LEN] = {0}; + uint8_t curr_elename[MAX_ELENAME_LEN] = {0}; + + newstrt = str; + + SET_CURR_SETNAME(newstrt); + SET_CURR_ELENAME(newstrt); + if(SETNAME_MATCHES()) + { DEL_FTOK(newstrt); + if(REF(NEXT_TOK(newstrt))) //NAME REF REF, where is set_label + DEL_FTOK(newstrt); + } + + return newstrt - str; +} + +int +lexer_lexsetolink +(uint8_t* str) +{ int setname_len, elename_len; + uint8_t* setname_end, *elename_end; + uint8_t curr_setname[MAX_SETNAME_LEN] = {0}; + uint8_t curr_elename[MAX_ELENAME_LEN] = {0}; + + return 0; + + //do nothing +} + +int +lexer_lexeleolink +(uint8_t* str) +{ int setname_len, elename_len; + uint8_t* setname_end, *elename_end, *newstrt; + uint8_t curr_setname[MAX_SETNAME_LEN] = {0}; + uint8_t curr_elename[MAX_ELENAME_LEN] = {0}; + + newstrt = str; + + SET_CURR_SETNAME(newstrt); + printf("prev_setname %s, curr_setname %s\n", prev_setname, curr_setname); + if(SETNAME_MATCHES()) + { DEL_FTOK(newstrt); + if(REF(newstrt)) + DEL_FTOK(newstrt); + } + + return newstrt - str; + + +} + + + +#define REF(STR) (STR[0] <= 0x39 && STR[0] >= 0x30) +#define DEL_FTOK(STR) (STR = u8_strchr(STR, '_') + 1) +#define NEXT_TOK(STR) (u8_strchr(STR, '_') + 1) +#define SET_CURR_SETNAME(STR) \ + do { \ + printf("Lexer_lexX:: setting curr_setname of str(%s)\n", STR); \ + setname_end = u8_chr(STR, FNAME_MAX, '_'); \ + setname_len = setname_end - str; \ + u8_move(curr_setname, STR, setname_len); \ + printf("Lexer_lexX:: curr_setname is now %s\n",curr_setname); \ + } while (0) +#define SET_CURR_ELENAME(STR) \ + do { \ + printf("Lexer_lexX:: setting curr_elename of str(%s)\n", STR); \ + setname_end = u8_chr(STR, FNAME_MAX, '_') + 1; \ + if(REF(setname_end)) \ + setname_end = u8_chr(setname_end, FNAME_MAX, '_') + 1; \ + elename_end = u8_chr(setname_end, FNAME_MAX, '_'); \ + elename_len = elename_end - setname_end; \ + u8_move(curr_elename, setname_end, elename_len); \ + printf("Lexer_lexX:: curr_elename is now %s\n", curr_elename); \ + } while (0) + +#define SETNAME_MATCHES() (u8_strcmp(curr_setname, prev_setname) == 0) +#define ELENAME_MATCHES() (u8_strcmp(curr_elename, prev_elename) == 0) +#define UPDATE_PREV_SETNAME(STR) \ + do { \ + printf("Lexer_lexX:: updating prev_setname from (%s)", prev_setname); \ + u8_set(prev_setname , (ucs4_t) 0, MAX_SETNAME_LEN ); \ + u8_move(prev_setname, curr_setname, setname_len); \ + printf(" to %s\n", prev_setname); \ + } while (0) +#define UPDATE_PREV_ELENAME(STR) \ + do { \ + u8_set(prev_elename , (ucs4_t) 0, MAX_ELENAME_LEN ); \ + u8_move(prev_elename, curr_elename, elename_len); \ + } while (0) +#define PREV_MAPFILE() (TK_STACKX - 5)->tok_t == MOPEN || (TK_STACKX-3)->tok_t == MOPEN +#define SET_MAPSTR(STR) (STR = u8_strstr(STR, map_key)) + + +#endif + + +/* int lexer_lexmapfile */ +/* #define INC_X() */ +/* (int height, int width) */ +/* { */ +/* int x, y; */ + +/* /\* Give scanner_scanpixels a buffer and a len. Iterate through */ +/* buf with buf[n]. If n == 0, do nothing. if n has a value, push x, */ +/* push y, push (z = n << 24), push (ref_id = n >> 8) *\/ */ +/* //scanner_scanpixels() */ + +/* for(i = 0; i < len; i++) */ +/* if(buf[i] == 0) */ +/* if(x == width) */ +/* x = 0; */ +/* else */ + + + + +/* } */ +/* fname_bytes = (uint8_t*)(DE_POP()->d_name); */ + /* printf("d_name is %s\n", fname_bytes); */ + /* for (fnp = filename, i = 0; i < FNAME_MAX; i += unit_size, fnp++) */ + /* { unit_size = u8_mblen(fname_bytes + i, min(4, FNAME_MAX - i)); */ + /* if (u8_mbtouc(fnp, fname_bytes + i, unit_size) == -1) //add ucs4 char to the filename */ + /* FAIL("Lexer failed to convert ^%s to unicode\n", (fname_bytes + i)); */ + /* if (*fnp == 0) //added a terminating char */ + /* break; */ + /* } */ + /* if(u8_mbtouc(filename, DE_POP()->d_name, FNAME_MAXy) == -1) */ + /* FAIL("Lexer failed to convert d_name into uint8_t\n"); */ + /* ulc_fprintf(stdout, "filename is %11U\n c", filename); */ diff --git a/lexer_fsm.c b/lexer_fsm.c new file mode 100644 index 0000000..1ae11bb --- /dev/null +++ b/lexer_fsm.c @@ -0,0 +1,1038 @@ + +#line 1 "lexer_fsm.rl" +#include +#include +#include +#include +#include + +extern void lexer_pushtok(int, YYSTYPE); +extern int lexer_lexmapfile(int, int); +extern int ipower(int, int); +extern int ttov(uint8_t*, int); +extern uint8_t* ttos(const uint8_t*, int); + +int lexer_setdirection(uint8_t*, int); +int lexer_lexstring(uint8_t*, int); +int lexer_setstr(uint8_t*, int); + +#define $($)#$ +#define PUSHTOK(TOK,LFUNC,UTYPE) \ + do { \ + printf("Lexer_lexstring:: PUSHTOK(" $(TOK) $(LFUNC) $(UTYPE) ")\n"); \ + tok_t = TOK; \ + yylval.UTYPE = LFUNC(ts, p-ts); \ + lexer_pushtok(tok_t, yylval); \ + ++ntok; \ + } while (0); + + +#line 31 "lexer_fsm.c" +static const char _lexstring_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4, 1, 5, 1, 13, 1, + 14, 1, 15, 2, 0, 14, 2, 2, + 6, 2, 2, 7, 2, 2, 8, 2, + 2, 9, 2, 2, 10, 2, 2, 11, + 2, 2, 12 +}; + +static const short _lexstring_key_offsets[] = { + 0, 0, 12, 17, 22, 24, 28, 34, + 40, 48, 54, 63, 69, 75, 76, 82, + 83, 89, 95, 103, 111, 123, 135, 147, + 159, 171, 183, 195, 207, 219, 231, 243, + 255, 267, 279 +}; + +static const char _lexstring_trans_keys[] = { + 48, 69, 78, 83, 87, 126, 49, 57, + 65, 90, 97, 122, 0, 95, 120, 48, + 57, 0, 95, 120, 48, 57, 48, 57, + 0, 95, 48, 57, 0, 95, 65, 90, + 97, 122, 0, 95, 65, 90, 97, 122, + 0, 69, 87, 95, 65, 90, 97, 122, + 0, 95, 65, 90, 97, 122, 0, 69, + 83, 87, 95, 65, 90, 97, 122, 0, + 95, 65, 90, 97, 122, 0, 95, 65, + 90, 97, 122, 95, 35, 95, 65, 90, + 97, 122, 95, 0, 95, 65, 90, 97, + 122, 48, 57, 65, 90, 97, 122, 0, + 95, 48, 57, 65, 90, 97, 122, 0, + 95, 48, 57, 65, 90, 97, 122, 48, + 69, 78, 83, 87, 126, 49, 57, 65, + 90, 97, 122, 48, 69, 78, 83, 87, + 126, 49, 57, 65, 90, 97, 122, 48, + 69, 78, 83, 87, 126, 49, 57, 65, + 90, 97, 122, 48, 69, 78, 83, 87, + 126, 49, 57, 65, 90, 97, 122, 48, + 69, 78, 83, 87, 126, 49, 57, 65, + 90, 97, 122, 48, 69, 78, 83, 87, + 126, 49, 57, 65, 90, 97, 122, 48, + 69, 78, 83, 87, 126, 49, 57, 65, + 90, 97, 122, 48, 69, 78, 83, 87, + 126, 49, 57, 65, 90, 97, 122, 48, + 69, 78, 83, 87, 126, 49, 57, 65, + 90, 97, 122, 48, 69, 78, 83, 87, + 126, 49, 57, 65, 90, 97, 122, 48, + 69, 78, 83, 87, 126, 49, 57, 65, + 90, 97, 122, 48, 69, 78, 83, 87, + 126, 49, 57, 65, 90, 97, 122, 48, + 69, 78, 83, 87, 126, 49, 57, 65, + 90, 97, 122, 48, 69, 78, 83, 87, + 126, 49, 57, 65, 90, 97, 122, 48, + 69, 78, 83, 87, 126, 49, 57, 65, + 90, 97, 122, 0 +}; + +static const char _lexstring_single_lengths[] = { + 0, 6, 3, 3, 0, 2, 2, 2, + 4, 2, 5, 2, 2, 1, 2, 1, + 2, 0, 2, 2, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6 +}; + +static const char _lexstring_range_lengths[] = { + 0, 3, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 0, 2, 0, + 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3 +}; + +static const short _lexstring_index_offsets[] = { + 0, 0, 10, 15, 20, 22, 26, 31, + 36, 43, 48, 56, 61, 66, 68, 73, + 75, 80, 84, 90, 96, 106, 116, 126, + 136, 146, 156, 166, 176, 186, 196, 206, + 216, 226, 236 +}; + +static const char _lexstring_indicies[] = { + 0, 4, 5, 6, 7, 8, 2, 3, + 3, 1, 9, 9, 11, 10, 1, 9, + 9, 12, 10, 1, 13, 1, 14, 14, + 15, 1, 16, 16, 17, 17, 1, 16, + 18, 17, 17, 1, 16, 19, 19, 20, + 17, 17, 1, 16, 21, 17, 17, 1, + 16, 22, 23, 24, 25, 17, 17, 1, + 16, 26, 17, 17, 1, 16, 27, 17, + 17, 1, 28, 1, 29, 30, 17, 17, + 1, 31, 1, 16, 32, 17, 17, 1, + 33, 34, 34, 1, 35, 35, 36, 34, + 34, 1, 37, 37, 34, 34, 34, 1, + 0, 4, 5, 6, 7, 8, 2, 3, + 3, 1, 0, 4, 5, 6, 7, 8, + 2, 3, 3, 1, 0, 4, 5, 6, + 7, 8, 2, 3, 3, 1, 0, 4, + 5, 6, 7, 8, 2, 3, 3, 1, + 0, 4, 5, 6, 7, 8, 2, 3, + 3, 1, 0, 4, 5, 6, 7, 8, + 2, 3, 3, 1, 0, 4, 5, 6, + 7, 8, 2, 3, 3, 1, 0, 4, + 5, 6, 7, 8, 2, 3, 3, 1, + 0, 4, 5, 6, 7, 8, 2, 3, + 3, 1, 0, 4, 5, 6, 7, 8, + 2, 3, 3, 1, 0, 4, 5, 6, + 7, 8, 2, 3, 3, 1, 0, 4, + 5, 6, 7, 8, 2, 3, 3, 1, + 0, 4, 5, 6, 7, 8, 2, 3, + 3, 1, 0, 4, 5, 6, 7, 8, + 2, 3, 3, 1, 0, 4, 5, 6, + 7, 8, 2, 3, 3, 1, 0 +}; + +static const char _lexstring_trans_targs[] = { + 2, 0, 3, 6, 7, 8, 10, 12, + 13, 20, 3, 17, 4, 5, 21, 5, + 22, 6, 23, 9, 32, 24, 11, 14, + 16, 31, 25, 26, 27, 15, 29, 28, + 30, 18, 19, 33, 18, 34 +}; + +static const char _lexstring_trans_actions[] = { + 9, 0, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 13, 13, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 11, 0, 0, + 0, 9, 0, 0, 0, 0 +}; + +static const char _lexstring_to_state_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 17, + 0, 0, 0, 0, 3, 15, 5, 37, + 31, 40, 28, 7, 0, 11, 25, 22, + 34, 19, 1 +}; + +static const int lexstring_start = 1; +static const int lexstring_first_final = 20; +static const int lexstring_error = 0; + +static const int lexstring_en_tok_lexer = 1; + + +#line 114 "lexer_fsm.rl" + + +int +lexer_lexstring +(uint8_t* str, int size) +{ uint8_t *p; + uint8_t *ts, *pe, *eof; + int cs, ntok, tok_t, direction; + + ntok = direction = 0; + p = ts = str; + pe = p + size +1; + + printf("|---Begin lexstring on p = %s, pe = %s.\n",p, pe); + + +#line 195 "lexer_fsm.c" + { + cs = lexstring_start; + } + +#line 130 "lexer_fsm.rl" + +#line 202 "lexer_fsm.c" + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( cs == 0 ) + goto _out; +_resume: + _keys = _lexstring_trans_keys + _lexstring_key_offsets[cs]; + _trans = _lexstring_index_offsets[cs]; + + _klen = _lexstring_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _lexstring_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _lexstring_indicies[_trans]; + cs = _lexstring_trans_targs[_trans]; + + if ( _lexstring_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _lexstring_actions + _lexstring_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 4: +#line 41 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:set_ts. ts = %s\n", p); ts = p; } + break; + case 5: +#line 42 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_SS. p = %s\n",p); + yylval.str = (uint8_t*) "SS"; + lexer_pushtok(SS, yylval); + ntok++; + } + break; + case 13: +#line 79 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_height p = %s\n", p); + PUSHTOK(HEIGHT, ttov, val); + } + break; +#line 294 "lexer_fsm.c" + } + } + +_again: + _acts = _lexstring_actions + _lexstring_to_state_actions[cs]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { + switch ( *_acts++ ) { + case 0: +#line 31 "lexer_fsm.rl" + { PUSHTOK(REF, ttov, ref); } + break; + case 1: +#line 32 "lexer_fsm.rl" + { PUSHTOK(NUM, ttov, val); } + break; + case 2: +#line 33 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_name: from %s to %s\n", ts, p); + PUSHTOK(NAME, ttos, str); + } + break; + case 3: +#line 36 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_map: pushing '~'\n"); + yylval.str = (uint8_t*) '~'; + lexer_pushtok(MOPEN, yylval); + ntok++; + } + break; + case 5: +#line 42 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_SS. p = %s\n",p); + yylval.str = (uint8_t*) "SS"; + lexer_pushtok(SS, yylval); + ntok++; + } + break; + case 6: +#line 47 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_S. p = %s\n", p); + yylval.val = 0; + lexer_pushtok(D, yylval); + } + break; + case 7: +#line 51 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_SW. p = %s\n", p); + yylval.val = 1; + lexer_pushtok(D, yylval); + } + break; + case 8: +#line 55 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_W. p = %s\n", p); + yylval.val = 2; + lexer_pushtok(D, yylval); + } + break; + case 9: +#line 59 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_NW. p = %s\n", p); + yylval.val = 3; + lexer_pushtok(D, yylval); + } + break; + case 10: +#line 63 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_N. p = %s\n", p); + yylval.val = 4; + lexer_pushtok(D, yylval); + } + break; + case 11: +#line 71 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_N. p = %s\n", p); + yylval.val = 6; + lexer_pushtok(D, yylval); + } + break; + case 12: +#line 75 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_N. p = %s\n", p); + yylval.val = 7; + lexer_pushtok(D, yylval); + } + break; + case 14: +#line 82 "lexer_fsm.rl" + { printf("Lexer_lexstring:: action:push_height p = %s\n", p); + PUSHTOK(WIDTH, ttov, val); + } + break; + case 15: +#line 85 "lexer_fsm.rl" + {yylval.str = (uint8_t*) '#'; lexer_pushtok(LINK),yylval); } + break; +#line 392 "lexer_fsm.c" + } + } + + if ( cs == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + _out: {} + } + +#line 131 "lexer_fsm.rl" + + printf("Ending lexstring of file %s, pushed %d tokens.\n",str, ntok); + + return ntok; +} + + + +#line 413 "lexer_fsm.c" +static const char _setdirection_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4, 1, 5, 1, 6, 1, + 7 +}; + +static const char _setdirection_key_offsets[] = { + 0, 0, 6, 8, 12, 14, 16, 20, + 22, 24, 26, 26, 26, 26, 26, 26, + 26, 26 +}; + +static const char _setdirection_trans_keys[] = { + 0, 69, 78, 83, 87, 95, 0, 95, + 0, 69, 87, 95, 0, 95, 0, 95, + 0, 69, 87, 95, 0, 95, 0, 95, + 0, 95, 0 +}; + +static const char _setdirection_single_lengths[] = { + 0, 6, 2, 4, 2, 2, 4, 2, + 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +static const char _setdirection_range_lengths[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +}; + +static const char _setdirection_index_offsets[] = { + 0, 0, 7, 10, 15, 18, 21, 26, + 29, 32, 35, 36, 37, 38, 39, 40, + 41, 42 +}; + +static const char _setdirection_indicies[] = { + 0, 2, 3, 4, 5, 0, 1, 6, + 6, 1, 7, 8, 9, 7, 1, 10, + 10, 1, 11, 11, 1, 0, 12, 13, + 0, 1, 14, 14, 1, 15, 15, 1, + 16, 16, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0 +}; + +static const char _setdirection_trans_targs[] = { + 10, 0, 2, 3, 6, 9, 11, 12, + 4, 5, 13, 14, 7, 8, 15, 16, + 17 +}; + +static const char _setdirection_trans_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0 +}; + +static const char _setdirection_to_state_actions[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 7, 5, 1, 9, 11, 13, + 15, 3 +}; + +static const int setdirection_start = 1; +static const int setdirection_first_final = 10; +static const int setdirection_error = 0; + +static const int setdirection_en_main = 1; + + +#line 166 "lexer_fsm.rl" + + +int +lexer_setdirection +(uint8_t* str, int size) +{ uint8_t *p, *pe, *eof; + int cs; + + + p = str; + pe = str + size + 1; + + printf("|--- Begin lexer_setdirection str = %s, p = %s, pe = %s ---|\n", str,p, pe); + + +#line 501 "lexer_fsm.c" + { + cs = setdirection_start; + } + +#line 181 "lexer_fsm.rl" + +#line 508 "lexer_fsm.c" + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( cs == 0 ) + goto _out; +_resume: + _keys = _setdirection_trans_keys + _setdirection_key_offsets[cs]; + _trans = _setdirection_index_offsets[cs]; + + _klen = _setdirection_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _setdirection_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _setdirection_indicies[_trans]; + cs = _setdirection_trans_targs[_trans]; + + _acts = _setdirection_actions + _setdirection_to_state_actions[cs]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { + switch ( *_acts++ ) { + case 0: +#line 141 "lexer_fsm.rl" + {printf("Lexer_setdirection:: direction is north, returning 4\n"); return 4;; } + break; + case 1: +#line 142 "lexer_fsm.rl" + { printf("Lexer_setdirection:: direction is west, returning 2\n");return 2;} + break; + case 2: +#line 143 "lexer_fsm.rl" + { printf("Lexer_setdirection:: direction is east, returning 6\n");return 6;} + break; + case 3: +#line 144 "lexer_fsm.rl" + { printf("Lexer_setdirection:: direction is south, returning 0\n");return 0;} + break; + case 4: +#line 145 "lexer_fsm.rl" + { printf("Lexer_setdirection:: direction is northeast, returning 5\n");return 5 ;} + break; + case 5: +#line 146 "lexer_fsm.rl" + { printf("Lexer_setdirection:: direction is northwest, returning 3\n");return 3;} + break; + case 6: +#line 147 "lexer_fsm.rl" + { printf("Lexer_setdirection:: direction is southeast, returning 7\n");return 7;} + break; + case 7: +#line 148 "lexer_fsm.rl" + { printf("Lexer_setdirection:: direction is southwest, returning 1\n");return 1;} + break; +#line 607 "lexer_fsm.c" + } + } + + if ( cs == 0 ) + goto _out; + p += 1; + goto _resume; + _out: {} + } + +#line 182 "lexer_fsm.rl" + + printf("|--- Error in: lexer_setdirection ---|\n"); + + return -1; +} + + + +/**************************/ +/****Abandon All Hope******/ +/**************************/ +/*** ***/ +/*** ***/ +/*** ***/ +/*** ***/ + + +#if 0 + +#line 638 "lexer_fsm.c" +static const char _setstr_actions[] = { + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4, 1, 5, 1, 6, 1, + 7, 1, 8 +}; + +static const unsigned char _setstr_key_offsets[] = { + 0, 0, 6, 7, 13, 20, 25, 33, + 34, 35, 36, 42, 50, 55, 60, 66, + 75, 79, 85, 86, 92, 99, 106, 111, + 115, 116, 117, 118, 124, 132, 137, 142, + 148, 157, 161, 167, 168, 174, 181, 184, + 185, 191, 195, 201, 202, 203, 209, 216, + 222, 231, 235, 241, 241, 241, 241, 241, + 241, 250, 251 +}; + +static const char _setstr_trans_keys[] = { + 48, 83, 65, 90, 97, 122, 120, 48, + 57, 65, 90, 97, 122, 0, 48, 57, + 65, 90, 97, 122, 95, 65, 90, 97, + 122, 35, 48, 83, 126, 65, 90, 97, + 122, 95, 48, 120, 48, 57, 65, 90, + 97, 122, 0, 95, 48, 57, 65, 90, + 97, 122, 83, 65, 90, 97, 122, 0, + 65, 90, 97, 122, 0, 83, 65, 90, + 97, 122, 0, 69, 78, 83, 87, 65, + 90, 97, 122, 65, 90, 97, 122, 69, + 87, 65, 90, 97, 122, 120, 48, 57, + 65, 90, 97, 122, 95, 48, 57, 65, + 90, 97, 122, 35, 83, 126, 65, 90, + 97, 122, 95, 65, 90, 97, 122, 35, + 48, 83, 126, 95, 48, 120, 48, 57, + 65, 90, 97, 122, 0, 95, 48, 57, + 65, 90, 97, 122, 83, 65, 90, 97, + 122, 0, 65, 90, 97, 122, 0, 83, + 65, 90, 97, 122, 0, 69, 78, 83, + 87, 65, 90, 97, 122, 65, 90, 97, + 122, 69, 87, 65, 90, 97, 122, 120, + 48, 57, 65, 90, 97, 122, 95, 48, + 57, 65, 90, 97, 122, 35, 83, 126, + 83, 83, 95, 65, 90, 97, 122, 65, + 90, 97, 122, 69, 87, 65, 90, 97, + 122, 48, 120, 48, 57, 65, 90, 97, + 122, 0, 48, 57, 65, 90, 97, 122, + 83, 95, 65, 90, 97, 122, 69, 78, + 83, 87, 95, 65, 90, 97, 122, 65, + 90, 97, 122, 69, 87, 65, 90, 97, + 122, 69, 78, 83, 87, 95, 65, 90, + 97, 122, 95, 0 +}; + +static const char _setstr_single_lengths[] = { + 0, 2, 1, 0, 1, 1, 4, 1, + 1, 1, 0, 2, 1, 1, 2, 5, + 0, 2, 1, 0, 1, 3, 1, 4, + 1, 1, 1, 0, 2, 1, 1, 2, + 5, 0, 2, 1, 0, 1, 3, 1, + 2, 0, 2, 1, 1, 0, 1, 2, + 5, 0, 2, 0, 0, 0, 0, 0, + 5, 1, 0 +}; + +static const char _setstr_range_lengths[] = { + 0, 2, 0, 3, 3, 2, 2, 0, + 0, 0, 3, 3, 2, 2, 2, 2, + 2, 2, 0, 3, 3, 2, 2, 0, + 0, 0, 0, 3, 3, 2, 2, 2, + 2, 2, 2, 0, 3, 3, 0, 0, + 2, 2, 2, 0, 0, 3, 3, 2, + 2, 2, 2, 0, 0, 0, 0, 0, + 2, 0, 0 +}; + +static const short _setstr_index_offsets[] = { + 0, 0, 5, 7, 11, 16, 20, 27, + 29, 31, 33, 37, 43, 47, 51, 56, + 64, 67, 72, 74, 78, 83, 89, 93, + 98, 100, 102, 104, 108, 114, 118, 122, + 127, 135, 138, 143, 145, 149, 154, 158, + 160, 165, 168, 173, 175, 177, 181, 186, + 191, 199, 202, 207, 208, 209, 210, 211, + 212, 220, 222 +}; + +static const char _setstr_indicies[] = { + 0, 3, 2, 2, 1, 4, 1, 5, + 5, 5, 1, 6, 5, 5, 5, 1, + 7, 2, 2, 1, 8, 9, 11, 12, + 10, 10, 1, 13, 1, 14, 1, 15, + 1, 16, 16, 16, 1, 17, 18, 16, + 16, 16, 1, 20, 19, 19, 1, 17, + 19, 19, 1, 17, 21, 19, 19, 1, + 17, 22, 23, 23, 22, 19, 19, 1, + 19, 19, 1, 22, 22, 19, 19, 1, + 24, 1, 25, 25, 25, 1, 26, 25, + 25, 25, 1, 8, 11, 12, 10, 10, + 1, 27, 10, 10, 1, 28, 29, 30, + 31, 1, 32, 1, 33, 1, 34, 1, + 35, 35, 35, 1, 36, 37, 35, 35, + 35, 1, 39, 38, 38, 1, 36, 38, + 38, 1, 36, 40, 38, 38, 1, 36, + 41, 42, 42, 41, 38, 38, 1, 38, + 38, 1, 41, 41, 38, 38, 1, 43, + 1, 44, 44, 44, 1, 45, 44, 44, + 44, 1, 28, 30, 31, 1, 46, 1, + 47, 27, 10, 10, 1, 10, 10, 1, + 48, 48, 10, 10, 1, 49, 1, 50, + 1, 51, 51, 51, 1, 52, 51, 51, + 51, 1, 53, 7, 2, 2, 1, 54, + 55, 55, 54, 7, 2, 2, 1, 2, + 2, 1, 54, 54, 2, 2, 1, 1, + 1, 1, 1, 1, 48, 56, 56, 48, + 27, 10, 10, 1, 57, 1, 1, 0 +}; + +static const char _setstr_trans_targs[] = { + 2, 0, 5, 47, 3, 4, 51, 6, + 7, 18, 22, 40, 57, 8, 9, 10, + 11, 52, 12, 13, 14, 15, 16, 17, + 19, 20, 21, 23, 24, 35, 39, 55, + 25, 26, 27, 28, 53, 29, 30, 31, + 32, 33, 34, 36, 37, 38, 54, 56, + 41, 44, 45, 46, 58, 48, 49, 50, + 42, 43 +}; + +static const char _setstr_trans_actions[] = { + 17, 0, 17, 17, 17, 17, 0, 0, + 0, 17, 17, 17, 0, 0, 17, 17, + 17, 0, 0, 17, 17, 17, 17, 17, + 17, 17, 0, 0, 0, 17, 0, 0, + 0, 17, 17, 17, 0, 0, 17, 17, + 17, 17, 17, 17, 17, 0, 0, 17, + 17, 17, 17, 17, 0, 17, 17, 17, + 17, 0 +}; + +static const char _setstr_to_state_actions[] = { + 0, 0, 0, 0, 13, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 3, 9, 11, + 5, 7, 15 +}; + +static const int setstr_start = 1; +static const int setstr_first_final = 51; +static const int setstr_error = 0; + +static const int setstr_en_main = 1; + + +#line 260 "lexer_fsm.rl" + + +int +lexer_setstr +(uint8_t* str, int size) +{ uint8_t *p, *pe, *eof; + int cs, type, newstrt; + + type = newstrt = 0; + + p = str; + pe = str + size + 1; + + printf("|--- Begin lexer_setstr with str = %s, p = %s, pe = %s ---|\n", str,p, pe); + + +#line 812 "lexer_fsm.c" + { + cs = setstr_start; + } + +#line 276 "lexer_fsm.rl" + +#line 819 "lexer_fsm.c" + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( cs == 0 ) + goto _out; +_resume: + _keys = _setstr_trans_keys + _setstr_key_offsets[cs]; + _trans = _setstr_index_offsets[cs]; + + _klen = _setstr_single_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (unsigned int)(_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _setstr_range_lengths[cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += (unsigned int)((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + _trans = _setstr_indicies[_trans]; + cs = _setstr_trans_targs[_trans]; + + if ( _setstr_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _setstr_actions + _setstr_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 8: +#line 212 "lexer_fsm.rl" + {printf("p = %s \n",p);} + break; +#line 895 "lexer_fsm.c" + } + } + +_again: + _acts = _setstr_actions + _setstr_to_state_actions[cs]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) { + switch ( *_acts++ ) { + case 0: +#line 204 "lexer_fsm.rl" + {printf("Lexer_setstr:: Returning setvlink filetype for %s\n", str); type = 5; newstrt = lexer_lexsetvlink(str); {p++; goto _out; }} + break; + case 1: +#line 205 "lexer_fsm.rl" + {printf("Lexer_setstr:: Returning elevlink filetype for %s\n", str); type = 6; newstrt = lexer_lexelevlink(str); {p++; goto _out; }} + break; + case 2: +#line 206 "lexer_fsm.rl" + {printf("Lexer_setstr:: Returning setmodel filetype\n"); newstrt = lexer_lexsetmodel(str); type = 1; {p++; goto _out; }} + break; + case 3: +#line 207 "lexer_fsm.rl" + {printf("Lexer_setstr:: Returning setmap filetype\n"); newstrt = lexer_lexsetmap(str); type = 2; {p++; goto _out; }} + break; + case 4: +#line 208 "lexer_fsm.rl" + {printf("Lexer_setstr:: Returning elemodel filetype for %s\n", str); newstrt = lexer_lexelemodel(str); type = 3; {p++; goto _out; }} + break; + case 5: +#line 209 "lexer_fsm.rl" + {printf("Lexer_setstr:: Returning elemap filetype for %s\n", str); newstrt = lexer_lexelemap(str); type = 4; {p++; goto _out; }} + break; + case 6: +#line 210 "lexer_fsm.rl" + { printf("Lexer_setstr:: Returning setolink filetype\n"); type = 8; newstrt = lexer_lexsetolink(str); {p++; goto _out; }} + break; + case 7: +#line 211 "lexer_fsm.rl" + { printf("Lexer_setstr:: Returning eleolink filetype\n"); type = 7; newstrt = lexer_lexeleolink(str); {p++; goto _out; }} + break; +#line 936 "lexer_fsm.c" + } + } + + if ( cs == 0 ) + goto _out; + p += 1; + goto _resume; + _out: {} + } + +#line 277 "lexer_fsm.rl" + + printf("|--- End lexer_setstr. Incrementing str by %d, type is %d ---|\n", newstrt, type); + + return newstrt; +} + +#endif + + +/* %%{ */ +/* machine file_matcher; */ + +/* action call_ml { ts = p; fgoto set_hw ;} */ +/* action call_tl { return 0;} */ +/* action set_height {height = ttov(p, p-ts+1); ts = p;} */ +/* action set_width { width = ttov(p, p-ts+1);} */ +/* action call_lmf {lexer_lexmapfile(height, width); } */ +/* action lex_error {printf("input error: character %c in filename %s is invalid\n = %s\n", fc, str, p);} */ + +/* #This machine determines the type of file we are lexing */ +/* #and calls the appropriate machine to handle it. */ + +/* #TODO add mapping name */ +/* width = digit+ %set_width; */ +/* height = digit+ %set_height; */ + +/* set_hw := height . '_' . width [\0] %to(call_lmf); */ + +/* tok_segment = alnum; */ +/* map_end = 'm' . '_' %to(call_ml); */ +/* tok_end = alnum+ . [\0] %to(call_tl); */ + +/* file_matcher := (tok_segment+ . '_' )+ ( map_end | tok_end ); */ + +/* write data; */ +/* }%% */ + +/* int */ +/* lexer_matchfile */ +/* (char* str, int size) */ +/* { *p, *pe; */ +/* char* ts; */ +/* int cs, ntok, height, width; */ + +/* p = str; */ +/* pe = p + size; */ +/* height = width = 0; */ + +/* printf("Checking if filename is a map file:: filename = %s, p = %c, pe = %c\n", str, *p, *pe); */ + +/* %%write init; */ +/* %%write exec noend; */ + +/* printf("Ending lexer_ismapfile on %s\n", str); */ + +/* return ntok; */ +/* } */ + +/* %%{ */ +/* machine vartype; */ + +/* action isele {return 0;} */ +/* action ismodel {return 1;} */ + +/* set_name = alpha+; */ +/* ele_name = alpha+; */ +/* model_name = alpha+; */ + +/* ele = set_name '_' model_name '_' ele_name %isele; */ +/* model = set_name '_' model_name [\0] %ismodel; */ + + +/* ismodel := (ele | model); */ + +/* write data; */ + +/* }%% */ + +/* int */ +/* lexer_ismodel */ +/* (uint8_t* str, int size) */ +/* { uint8_t *p, *pe, *eof; */ +/* int cs; */ + +/* p = str; */ +/* pe = p + size + 1; */ + +/* %%write init; */ +/* %%write exec; */ + + +/* } */ diff --git a/lexer_fsm.rl b/lexer_fsm.rl new file mode 100644 index 0000000..344ffdb --- /dev/null +++ b/lexer_fsm.rl @@ -0,0 +1,369 @@ +#include +#include +#include +#include "apc.h" +#include +#include + +extern void lexer_pushtok(int, YYSTYPE); +extern int lexer_lexmapfile(int, int); +extern int ipower(int, int); +extern int ttov(uint8_t*, int); +extern struct name* tton(const uint8_t*, int); + +int lexer_setdirection(uint8_t*, int); +int lexer_lexstring(uint8_t*, int); +int lexer_setstr(uint8_t*, int); + +#define $($)#$ +#define PUSHTOK(TOK,LFUNC,UTYPE) \ + do { \ + printf("Lexer_lexstring:: PUSHTOK(" $(TOK) $(LFUNC) $(UTYPE) ")\n"); \ + tok_t = TOK; \ + yylval.UTYPE = LFUNC(ts, p-ts); \ + lexer_pushtok(tok_t, yylval); \ + ++ntok; \ + } while (0); + +%%{ + machine lexstring; + + # set up yylval and tok_t to be pushed to stack + action push_ref { PUSHTOK(REF, ttov, ref); } + action push_val { PUSHTOK(NUM, ttov, val); } + action push_name { printf("Lexer_lexstring:: action:push_name: from %s to %s\n", ts, p); + PUSHTOK(NAME, tton, str); + } + action push_map { printf("Lexer_lexstring:: action:push_map: pushing '~'\n"); + yylval.str = (uint8_t*) '~'; + lexer_pushtok(MOPEN, yylval); + ntok++; + } + action set_ts { printf("Lexer_lexstring:: action:set_ts. ts = %s\n", p); ts = p; } + action push_SS { printf("Lexer_lexstring:: action:push_SS. p = %s\n",p); + yylval.str = (uint8_t*) "SS"; + lexer_pushtok(SS, yylval); + ntok++; + } + action push_S { printf("Lexer_lexstring:: action:push_S. p = %s\n", p); + yylval.val = 0; + lexer_pushtok(D, yylval); + } + action push_SW { printf("Lexer_lexstring:: action:push_SW. p = %s\n", p); + yylval.val = 1; + lexer_pushtok(D, yylval); + } + action push_W { printf("Lexer_lexstring:: action:push_W. p = %s\n", p); + yylval.val = 2; + lexer_pushtok(D, yylval); + } + action push_NW { printf("Lexer_lexstring:: action:push_NW. p = %s\n", p); + yylval.val = 3; + lexer_pushtok(D, yylval); + } + action push_N { printf("Lexer_lexstring:: action:push_N. p = %s\n", p); + yylval.val = 4; + lexer_pushtok(D, yylval); + } + action push_NE { printf("Lexer_lexstring:: action:push_NE. p = %s\n", p); + yylval.val = 5; + lexer_pushtok(D, yylval); + } + action push_E { printf("Lexer_lexstring:: action:push_N. p = %s\n", p); + yylval.val = 6; + lexer_pushtok(D, yylval); + } + action push_SE { printf("Lexer_lexstring:: action:push_N. p = %s\n", p); + yylval.val = 7; + lexer_pushtok(D, yylval); + } + action push_height { printf("Lexer_lexstring:: action:push_height p = %s\n", p); + PUSHTOK(HEIGHT, ttov, val); + } + action push_width { printf("Lexer_lexstring:: action:push_height p = %s\n", p); + PUSHTOK(WIDTH, ttov, val); + } + action push_link {yylval.str = (uint8_t*) '#'; lexer_pushtok(LINK),yylval); } + action lex_error { printf("input error: character %c in filename %s is invalid\n p = %s\n", fc, str, p);} + action p { printf("Lexer_lexstring:: p = %s\n", p);} + + # Parses a regular filename (not a mapping) and pushes + # tokens to the parser + N = 'N' %push_N; + W = 'W' %push_W; + S = 'S' %push_S; + E = 'E' %push_E; + NW = 'NW' %push_NW; + NE = 'NE' %push_NW; + SW = 'SW' %push_SW; + SE = 'SE' %push_SE; + + tok_delimiter = [_]; + direction = (N | W | S | E | NW | NE | SW | SE) ; + #make sure 0x123123 doesnt get mistaken for a ref + dimensions = (digit+ - '0') >set_ts %push_height 'x' (digit+ - '0') >set_ts %push_width; + link = '#' %push_link; + SS = ('+SS' %to(push_SS)) | ('+SS' %to(push_SS) link ) ; + ref = '0x' >set_ts alnum+ %push_ref; + val = digit+ >set_ts %push_val ; + name = (lower+ >set_ts) %push_name ; + map = '+MAP' %to(push_map); + tok = name %to(push_name) ; + + +tok_lexer := ((name | val | ref | dimensions | map) tok_delimiter)+ tok [\0]; + + write data; + +}%% + +int +lexer_lexstring +(uint8_t* str, int size) +{ uint8_t *p; + uint8_t *ts, *pe, *eof; + int cs, ntok, tok_t, direction; + + ntok = direction = 0; + p = ts = str; + pe = p + size +1; + + printf("|---Begin lexstring on p = %s, pe = %s.\n",p, pe); + + %%write init; + %%write exec ; + + printf("Ending lexstring of file %s, pushed %d tokens.\n",str, ntok); + + return ntok; +} + + +%%{ + machine setdirection; + + action ret_north {printf("Lexer_setdirection:: direction is north, returning 4\n"); return 4;; } + action ret_west { printf("Lexer_setdirection:: direction is west, returning 2\n");return 2;} + action ret_east { printf("Lexer_setdirection:: direction is east, returning 6\n");return 6;} + action ret_south { printf("Lexer_setdirection:: direction is south, returning 0\n");return 0;} + action ret_northeast { printf("Lexer_setdirection:: direction is northeast, returning 5\n");return 5 ;} + action ret_northwest { printf("Lexer_setdirection:: direction is northwest, returning 3\n");return 3;} + action ret_southeast { printf("Lexer_setdirection:: direction is southeast, returning 7\n");return 7;} + action ret_southwest { printf("Lexer_setdirection:: direction is southwest, returning 1\n");return 1;} + + def = [_\0] %to(ret_south); + N = 'N'[_\0] %to(ret_north); + W = 'W' [_\0] %to(ret_west); + S = 'S' [_\0] %to(ret_south); + E = 'E' [_\0] %to(ret_east); + NW = 'NW' [_\0] %to(ret_northwest); + NE = 'NE' [_\0] %to(ret_northeast); + SW = 'SW' [_\0] %to(ret_southwest); + SE = 'SE' [_\0] %to(ret_southeast); + + direction = (N | W | S | E | NW | NE | SW | SE | def); + + main := direction; + + write data; + +}%% + +int +lexer_setdirection +(uint8_t* str, int size) +{ uint8_t *p, *pe, *eof; + int cs; + + + p = str; + pe = str + size + 1; + + printf("|--- Begin lexer_setdirection str = %s, p = %s, pe = %s ---|\n", str,p, pe); + + %%write init; + %%write exec noend; + + printf("|--- Error in: lexer_setdirection ---|\n"); + + return -1; +} + + + +/**************************/ +/****Abandon All Hope******/ +/**************************/ +/*** ***/ +/*** ***/ +/*** ***/ +/*** ***/ + + +#if 0 +%%{ + machine setstr; + + + action lex_setvlink {printf("Lexer_setstr:: Returning setvlink filetype for %s\n", str); type = 5; newstrt = lexer_lexsetvlink(str); fbreak;} + action lex_elevlink {printf("Lexer_setstr:: Returning elevlink filetype for %s\n", str); type = 6; newstrt = lexer_lexelevlink(str); fbreak;} + action lex_setmodel {printf("Lexer_setstr:: Returning setmodel filetype\n"); newstrt = lexer_lexsetmodel(str); type = 1; fbreak;} + action lex_setmap {printf("Lexer_setstr:: Returning setmap filetype\n"); newstrt = lexer_lexsetmap(str); type = 2; fbreak;} + action lex_elemodel {printf("Lexer_setstr:: Returning elemodel filetype for %s\n", str); newstrt = lexer_lexelemodel(str); type = 3; fbreak;} + action lex_elemap {printf("Lexer_setstr:: Returning elemap filetype for %s\n", str); newstrt = lexer_lexelemap(str); type = 4; fbreak;} + action lex_setolink { printf("Lexer_setstr:: Returning setolink filetype\n"); type = 8; newstrt = lexer_lexsetolink(str); fbreak;} + action lex_eleolink { printf("Lexer_setstr:: Returning eleolink filetype\n"); type = 7; newstrt = lexer_lexeleolink(str); fbreak;} + action p {printf("p = %s \n",p);} + action name_error {printf("In %s, there is a syntactic error. Make sure your set/element names dont conflict with the reserved keywords.\n", str);} + + + N = 'N'; + W = 'W'; + S = 'S'; + E = 'E'; + NW = 'NW'; + NE = 'NE'; + SW = 'SW'; + SE = 'SE'; + + SS = 'SS'; + direction = (N | W | S | E | NW | NE | SW | SE) $p; + + SSD = SS direction; + + + + name = alpha+ $p - SSD $p; + num = digit+ $p; + ref = '0x' $p alnum+ $p; + + + set_label = name | (name '_' ref); + ele_label = name | (name '_' ref); + + model_types = (name) | (name '_' num '_' num) | (name '_' num); + + + set_model = set_label '_' SS %to(lex_setmodel); + set_map = set_label '_' '~' %to(lex_setmap); + ele_model = set_label '_' ele_label '_' SS %to(lex_elemodel); + ele_map = set_label '_' ele_label '_' '~' %to(lex_elemap); + set_olink = ref %to(lex_setolink) [\0] ; + ele_olink = set_label '_' '~' '_' ref [\0] %to(lex_eleolink); + set_vlink = set_label '_' '#' '_' (ref | ref '_' name) [\0] %to(lex_setvlink); + ele_vlink = set_label '_' ele_label '_' '#' '_' (ref | ref '_' name) [\0] %to(lex_elevlink); + + main := (ele_map | set_model | set_map |ele_model | ele_vlink | set_vlink | set_olink | ele_olink); + + write data; + + +}%% + +int +lexer_setstr +(uint8_t* str, int size) +{ uint8_t *p, *pe, *eof; + int cs, type, newstrt; + + type = newstrt = 0; + + p = str; + pe = str + size + 1; + + printf("|--- Begin lexer_setstr with str = %s, p = %s, pe = %s ---|\n", str,p, pe); + + %%write init; + %%write exec noend; + + printf("|--- End lexer_setstr. Incrementing str by %d, type is %d ---|\n", newstrt, type); + + return newstrt; +} + +#endif + + +/* %%{ */ +/* machine file_matcher; */ + +/* action call_ml { ts = p; fgoto set_hw ;} */ +/* action call_tl { return 0;} */ +/* action set_height {height = ttov(p, p-ts+1); ts = p;} */ +/* action set_width { width = ttov(p, p-ts+1);} */ +/* action call_lmf {lexer_lexmapfile(height, width); } */ +/* action lex_error {printf("input error: character %c in filename %s is invalid\n = %s\n", fc, str, p);} */ + +/* #This machine determines the type of file we are lexing */ +/* #and calls the appropriate machine to handle it. */ + +/* #TODO add mapping name */ +/* width = digit+ %set_width; */ +/* height = digit+ %set_height; */ + +/* set_hw := height . '_' . width [\0] %to(call_lmf); */ + +/* tok_segment = alnum; */ +/* map_end = 'm' . '_' %to(call_ml); */ +/* tok_end = alnum+ . [\0] %to(call_tl); */ + +/* file_matcher := (tok_segment+ . '_' )+ ( map_end | tok_end ); */ + +/* write data; */ +/* }%% */ + +/* int */ +/* lexer_matchfile */ +/* (char* str, int size) */ +/* { *p, *pe; */ +/* char* ts; */ +/* int cs, ntok, height, width; */ + +/* p = str; */ +/* pe = p + size; */ +/* height = width = 0; */ + +/* printf("Checking if filename is a map file:: filename = %s, p = %c, pe = %c\n", str, *p, *pe); */ + +/* %%write init; */ +/* %%write exec noend; */ + +/* printf("Ending lexer_ismapfile on %s\n", str); */ + +/* return ntok; */ +/* } */ + +/* %%{ */ +/* machine vartype; */ + +/* action isele {return 0;} */ +/* action ismodel {return 1;} */ + +/* set_name = alpha+; */ +/* ele_name = alpha+; */ +/* model_name = alpha+; */ + +/* ele = set_name '_' model_name '_' ele_name %isele; */ +/* model = set_name '_' model_name [\0] %ismodel; */ + + +/* ismodel := (ele | model); */ + +/* write data; */ + +/* }%% */ + +/* int */ +/* lexer_ismodel */ +/* (uint8_t* str, int size) */ +/* { uint8_t *p, *pe, *eof; */ +/* int cs; */ + +/* p = str; */ +/* pe = p + size + 1; */ + +/* %%write init; */ +/* %%write exec; */ + + +/* } */ diff --git a/lexer_lex.rl b/lexer_lex.rl new file mode 100755 index 0000000..5e395d0 --- /dev/null +++ b/lexer_lex.rl @@ -0,0 +1,69 @@ +/* Ragel State Machine for tokenizing text */ +#include +#include +#include +#include + + +int ipow(int, int); +int ttov(const uint8_t* , int); +uint64_t ttor(const uint8_t* , int); +struct name* tton(const uint8_t* , int); + + +#define MAX_TOK_LEN 64 +#define MAX_TOKENS 16 +#define MAX_STR_SIZE (MAX_TOK_LEN * MAX_TOKENS) + +int ipow(int base, int exp) +{ + int result = 1; + while (exp) + { + if (exp & 1) + result = result * base; + exp = exp >> 1; + base *= base; + } + + return result; +} + +/* Token to Value */ +int ttov(const uint8_t* str, int len) +{ + int i, val = 0; + + for (i = 0; i < len; i++) + { + val += ((str[len - (i + 1)] - '0') * ipow(10,i)); + } + + return val; +} + +uint64_t ttor(const uint8_t* str, int len) +{ + int i; + uint64_t num = 0; + + for (i = 0; i < len; i++) + { + num += ((str[len - (i + 1)] - '0') * ipow(10,i)); + } + + return num; +} + +struct name* tton(const uint8_t* str, int len) +{ + int i; + struct name* namep; + + namep = (name*) malloc(MAX_NAME_LEN); + for(i = 0; i < MAX_NAME_LEN - 1; i++) + namep[i] = str[i]; + namep[i] = '\0'; + + return namep; +} diff --git a/main.o b/main.o new file mode 100644 index 0000000000000000000000000000000000000000..db32a98866b87fa2d3ea74d470a29cd5478619a5 GIT binary patch literal 2472 zcmb`HO-vI(6vwAj1re|yendPB2aF`LX^A1&1TB)vngAv!(S#VXl!Z37yLEPmEs60! zBx!n(g9kl&@!*M*F&@B!Moz@Uvk4wdNZ{g)Llb;&cZLqzt|wnJU%&akH?uR-_dGdv zyCD=J(n910sg5KiBz>aVPq^I#X(i2MN-zD^m-lGt*`8in+}6wE+vVimCsgRAtRFh$_gpg-CXF==L6|fJ@Y=6IWxKNO z_Xf|k4Vn&R|L&OpI|C)+NsiPP19*1;?+xJ506rMNhXS}B!0!fdk~1=vmLe&GEjaFg zESTKRa{>hzaX7QGrUmVs$rzc>vy8>(iCM^S@9oWGEa>K8(q^Ps%p1%x2{{kzp*2HM zZxPQ04UhX2l*)l;HxYs%Z-FBD7(y`QtxzPNMhNEDr#{^%w-`W~OK6nURAR^nZ*(7|d1v43GeZCjZ~w$kWO`wp~y#J0+l~ zMn%fn#Nc4~ma!|}&jo~Fm!Tl{XTEOXhZ@!V_$o|dOuv6Z2xZ=qF{tc_HU=$9kK7%M zr9b8c)#UyqyAB=nk4hlgmtuW9AJqhQeURURBAKdtUk}#NJ`l{m|25%{`B63h{wHCw z-u>-}q$KYN?+<;YzvTEI^q)PT!v|%!gKFjfEFAmyj_MsD+!ih7Jj_@A^^w(Ee^Wp_ JAJzQp{{;n_ILQD2 literal 0 HcmV?d00001 diff --git a/name.c b/name.c new file mode 100644 index 0000000..612426c --- /dev/null +++ b/name.c @@ -0,0 +1,41 @@ +/* Functions for operating on names */ +#include "apc.h" +#include + + +int +name_u8_cpy(struct name*, struct name*); + +int +name_u8_cmp(struct name*, struct name*); + + +/* Copies src into dst. 1 if sucessful, 0 if not */ +int +name_u8_cpy +( struct name* dst, + struct name* src +) +{ if(u8_stpncpy(dst->name, src->name, MAX_NAME_LEN)) + return 1; + + return 0; + +} + + +int +name_u8_cmp +( struct name* x, + struct name* y +) +{ return u8_strncmp(x->name, y->name, MAX_NAME_LEN); +} + +int +name_u8_set +( struct name* name, + ucs4_t uc +) +{ return u8_set(name->name, uc); +} diff --git a/output.c b/output.c new file mode 100644 index 0000000..4513d64 --- /dev/null +++ b/output.c @@ -0,0 +1,39 @@ + +/* void */ +/* condense() */ +/* { */ +/* FILE *vp, *op, *cp; */ +/* int v, m; */ +/* int num_models; */ + +/* vp = fopen("vdat_output", "w+"); */ +/* if(!vp) */ +/* perror("vdat_output failed to open\n"); */ + +/* op = fopen("odat_output", "w+"); */ +/* if(!op) */ +/* perror("odat_output failed to open\n"); */ + +/* cp = fopen("cdat_output", "w+"); */ +/* if(!cp) */ +/* perror("cdat_output failed to open\n"); */ + + + +/* /\* fwrite vdat *\/ */ +/* for(v = 0; v <= vbi; v++) */ +/* { */ +/* num_models = vdat_buf[v].num_models; //data duplication for caching */ +/* for(m = 0; m <= num_models; m++) */ +/* { */ + +/* } */ +/* } */ + +/* /\* fwrite odat *\/ */ +/* /\* Convert ref_list to actual offset *\/ */ + +/* /\* fwrite cdat *\/ */ + + +/* } */ diff --git a/parser.y b/parser.y new file mode 100644 index 0000000..6fe0969 --- /dev/null +++ b/parser.y @@ -0,0 +1,177 @@ +/* Asset Package Compiler */ +%code requires{ + #include + #include + #include "apc.h" +} +%{ + #include + #include + #include + + extern int lexer_init(); //? + extern int lexer(); //? + extern void pop_cdat(void); + extern void push_cdat(uint8_t*); + extern void insert_vdat(void); + extern void insert_refid(int); + extern void insert_set_name(uint8_t*); + extern void insert_set_namelist(uint8_t*); + extern void insert_link_name(uint8_t*); + extern void insert_map(int, uint8_t*, int, int, uint8_t*); + extern void insert_mlink(uint8_t*, int); + extern void insert_vlink(uint8_t*, int); + extern void insert_framesheet(uint_t* int, int, int,int, uint8_t*); + + #define yylex lexer + + + void yyerror(); +%} +%define parse.error verbose +%define lr.type ielr +%glr-parser + +%union { + int ref; + int val; + uint8_t *str; + struct name* name; + void *voidp; +} + + //operators +%token CLOPEN // ( +%token CLCLOSE // ) +%token MOPEN // ~ +%token HB +%token ROOT +%token SS +%token LINK //# +%token SCLOSE +%token CHILD +//terminals +%token NUM +%token PATH +%token REF +%token HEIGHT +%token WIDTH +%token D +%token NAME +%token SHIFT +//nonterminals +%type ref_id + /* Syntax Directed Translation Scheme of the APC grammar */ + +/* Rules */ +%% +cdat_buf: +class_block +; + +class: +NAME CLOPEN {push_cdat($1);} class_block CLCLOSE {pop_cdat();}; +; + +class_list: +class_list class +| class +; + +class_block: +class_list +| class_list statement_list +| statement_list +; + +statement_list: +statement_list statement +| statement +; + +statement: +vdat_statement +| map_statement +| ref_statement +| olink +; + +ref_statement: +set_namelist ref_id {insert_set_refid($2);}; +; + +link_namelist: +link_namelist NAME {insert_link_name($2);}; +| NAME {}; +; + + +set_namelist: +set_namelist NAME {insert_set_name($2);}; +| NAME {insert_set_namelist($1);}; +; + +map_statement: +set_namelist MOPEN map +| set_namelist MOPEN mlink +; + +map: +NAME NUM NUM PATH {insert_map($1, 0, $3, $4, 0, $5);}; +| NAME PATH {insert_map($1, 0, 0, 0, 0, $2);}; +| NAME D PATH {insert_map($1, $2, 0, 0, 0, $3);}; +| NAME D NUM NUM PATH {insert_map($1, $2, $3, $4, 0, $5);}; +| NAME NUM NUM ref_id PATH {insert_map($1, 0, $2, $3, $4, $5);}; +| NAME ref_id PATH {insert_map($1, 0, 0, 0, $2, $3);}; +| NAME D ref_id PATH {insert_map($1, $2, 0, 0, $3, $4);}; +| NAME D NUM NUM ref_id PATH {insert_map($1, $2, $3, $4, $5, $6);}; +; + +//shift list_namelist name > reduce mlink +mlink: +MOPEN LINK NAME LINK link_namelist PATH {insert_mlink($4, 0); }; +| MOPEN LINK link_namelist PATH {insert_mlink(NULL, 0); }; +| MOPEN LINK ref_id PATH {insert_mlink(NULL, $4); }; +| MOPEN LINK NAME LINK ref_id PATH {insert_mlink($4,$6); }; +; + +//shift list_namelist name > reduce vlink +vlink: +LINK NAME LINK link_namelist PATH {insert_vlink($2, 0); }; +| LINK link_namelist PATH {insert_vlink(NULL, 0);}; +| LINK REF PATH {insert_vlink(NULL, $2);};//vdat of ref +| LINK NAME LINK REF PATH {insert_vlink($2, $4);};//modelname of ref +; + + +olink: +set_namelist MOPEN REF +; + +ref_id: +LINK REF {$$ = $2;}; +; + + +vdat_statement: +set_namelist SS spritesheet_statement +| set_namelist SS vlink +; + +spritesheet_statement: +NAME D HEIGHT WIDTH PATH {insert_framesheet($1, $2, $3, $4, 0, $5);}; +| NAME D PATH {insert_framesheet($1, $2, 0, 0, 0, $3);}; +| NAME HEIGHT WIDTH PATH {insert_framesheet($1, 0, $2, $3, 0, $4);}; +| NAME PATH {insert_framesheet($1, 0, 0, 0, 0, $2);}; +| NAME D HEIGHT WIDTH ref_id PATH {insert_framesheet($1, $2, $3, $4, $5, $6);}; +| NAME D ref_id PATH {insert_framesheet($1, $2, 0, 0, $3, $4);}; +| NAME HEIGHT WIDTH ref_id PATH {insert_framesheet($1, 0, $2, $3, $4, $5);}; +| NAME ref_id PATH {insert_framesheet($1, 0, 0, 0, $2, $3);}; +; + +%% + +void +yyerror (char const *s) +{ fprintf(stderr, "%s\n", s); +} diff --git a/ragraph b/ragraph new file mode 100755 index 0000000..cc9c55f --- /dev/null +++ b/ragraph @@ -0,0 +1,3 @@ +#!/bin/bash + +ragel -V -p lexer_fsm.rl | dot -Tpng -o ragraph.png diff --git a/ragraph.png b/ragraph.png new file mode 100644 index 0000000000000000000000000000000000000000..e8a831f9e3f7e27456ff7ddd951c86878169de98 GIT binary patch literal 159425 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

p;9#2~wI@nVgr zl}o-&*!7FQ&XFE@2*8oOBIB=6T89M z#>PK>vf%G_t^rJ4Rt#W9RS;0b=@jNmz8NcGZ?vgzB-d)B27$8U*iCxOOUpiaO}$|Q zIe$Oo$o&18dVsr19xJ3Tv7z(_uxbeGB`DRb?>y4{KI$7lEM8j?05vrojwhP+MbuEY z2M<_VR9aG0UESQ)LXc-|u~{5K;T_@$I%NeUzXLdI+qP}VnnjEV7btY)fKv&V(ij1! z*q-zr0MqbDOXG$beFdBv(%W5pTe{_U6^t%DJ#G@&dSle4@B8;^h+g0quRnhd!u(%I z(`E*SYFL{X?&tg2UmFMA*XZ+0Pjqn<@=rNtEY#Z$UV${=vFn%@YRF-@s(@al0E5ae zjdr30u|RFah46BkbN2Q^$mUpFVs7;9#*!a?tjNp^Pb-rn-1OnT;RQrf6?x#{2dtGSu^^vP8PNLgxixxwPj^r!28asRBXHgHHhRW zRtbmSlPw3QhyS+-oCy*4A(?C zh6Dt>hyF7KM+pARFJl{5?K;wd$fI~RL&f-`n_W_$`VrJI(X|Br$;|OL@ zXfRwhxm^AA#N^~oKBFB-#HpE?02_ws5pJiEiMV?GftIx0m^S!^$@!{b){TTp5TviF z+K9IaLH|{_X=a$EQaJxh6>9|_U?ZZ0g@?x%<$0{tFwI}zrW$cZ(#(rd7+%{NP_wHT zv&J#O@TDx@~IFKB!{=C;XNW}TF@sT?^Vp!I$o!s@iPHWM)Rn@^ttF_Q1!+EDq2 z1W_3qkI3zmelWgID)CbBCPlE@HEY-I#rML%+PZC<7%=;?%h|W~66L<#s?9c|Q zF|neYuI*;)!vcbgu*$&11fID$7u3@lNSazLp1meJrsVbO+t89|KK}ahdIkO}+jf#2 zyj=@-l&t#7E3IhZ88qIfYquUagt`e?1*a~w5( zN*hr&*zN)$lqP$_BooA2wAXd()&Z<+2flzW>}TTQjXy)>o5p#O3Y|hH5Rg0Q5;%q& zPs4CO^b*vOWn?0h+=C@xJWtyG#k)nA1fsRAuBq8z-E=!V9p!8_ejprGZE9-DuQCUd z5tx|LgAV2Z@B0nnhKL!54j*RA;)j4+3)Y%r+DnCsMM@ojctGnE!7fu_WOcxT1D&0n zx2%egI&EXIwH>t;d(u#TVGn>n%$5%J6q7T(w;)1lI8N)Fzi@%{FJNdu+BzIxhjV!{zQHR*3$;t9?`BgRV@HbX)GN>1tHCX1t9j>4|hLN6y+7#l`TUjcHHCbC1&@*o9b z@@!Q7CU_@ESvt@AxJ6T(N5Ijga~CgeKv|DK1bgf_99fpNH0YTPgLd=ifNQVl;@o3| z#}R-mh{)GJKHrNoaMa)Z*4pY*~^V3#1YC3%1U)P`XS z_D+&h{mH(+<)@3k8N+fUKVN83qH7LWrYKdSHRIho>|@n}xV85sB`&Dj+pjxOQ&Yol zT;_}bK#9}=tJ3Fvh63>rEm1EZ1glv zP{`1@09^!JjiHrNQrZSff=Ngy7!L$!?vj@$h>3!2;B{T#&gnFlcgAZLiMU4|G9Qq! zP+cgp5Em~!HQUeqYO2NXvG=Yh-l2Hqj0445d8|EYe7BHCaw(@u^}(Wvfd-94bw%?(Y}}E*Jfu`IC@F~pA$%1B+xcLO`H&TRdVBpp*(2QEJ=BNX zQw4?+*RE3;6*K^rfkMJIzW%}~1#|9J-yvGAGrfI%?_t16NK3Qq+jj?Dd7E_slwy12 zJoG~XGJkXy)xsSmZcUQ|UP_`eu%QgcmdSY*n$|*SwEJ3qp*n9D5E1>h@`{d53F5mP z0Lyx6bT4E(yfeiar8Iu_Ae8RnG28CU~{033Gd8AH$uc9Oc}585KCy6<@mSzB~fv4rJx<4$6fF;_Msy~i&z+0 zT=0fHg~5;00E7>PZ)#{TVzO%jM`kaVUU+)wHs)9nY8ZR($IA&$$oegBQFs3r1=qW2 zVt#GM6{!{$7Lqjzo`D=TVyYXs!!0C)frQT2H!kl=N`%Koo`i-nB7uNdO>r^_@|ie% zK!{U(P`BuXZ8Pa>&%Gkr69NUByPuyw5U`2|Y6jw^6mK;f+}Fp73e$!PIA%?Nti6ePJpBpbl=!NoGP+_`K%Q@o75G0>o1rCMPL*( zp_7|xEZ?p^Kq2kcUiJu8jGho#V{~*h?tc8b_3IDw@#$hY=P;+O1` z!yT7c*$LGi$M&y4{K@4y`O)22Poak57S)MVfdYFb0HQl-$9F|&gf|;dH}m0u5(W$5 zv{AuPTt|QW5k>_PW_!{SC(+IEOi)6He7}{*`kA=P=UFcl+>%P<=yI`yiqZ=>SAnJQ zLngDLOHqYG4rRmjsYXA#f|86w4q<~C$Ih#Zsm5!VPCuxeeuh#{;TH@oTDbW-|4T^R zvrYyQ=fKZny4@>PYI6(|3yXLTjv=J$)iU;yaU;lU3E6ph95XXBRN>HP*)cy`0e0+% z5dnp11U-DhR92OgUvAyd^e!HTj+!=2J_mkLK?a;L|2p4oLJpHeVi@eqnKORB5|qwC z|E<7#Smb-=8ygz@$XFZJKymeYy6BG|Ke9SsgMUiCmAu)GSf53#Towb8H*co$K*KA6E5dI( zp`YLZ4cHoxJNH!nD|@`P!5!19M6vtR&lChOKJH#v=$KOrIi{1{na5_l=TsVT;hY z@Z2~gF=6fpX3dUr&VJ}7G&p~VlKxZl?mQP|4Y&KBK0CcL85oi(9ECf)&Jc}Gi6REh zWUWB8O*`jtmD@DEHPP4vKV+Ss!(km(78X|=cSiW|gV_Mh0sr2GX93bY`sh;@#V~ zcL4#kw6zt!Vb^u8Lg%O4OJ^XL*a=R`QWXijW3U{2+^g-eApHK*+hEB+Q{PS1h^%K%Y{mFu{Mt$VkoLC{E*@QV+d`1H)%GaKVOf0ox^S z`9+UZ=BkVvBo+xl)DWI(dA%@|lAFK#1fBs?9|rLTP=M?)6~O8q*)jSNNECCk`sj&n zr%e5QyuCNVNZF5@IM!huRcwfCpnzbiygepi{K=yoNT`dTnbRi|;i=YPHjcmrvyr9aP&tk);+02$mX>_LN{G`((jwE*Wmatv zbV3p8rkI+?+5ClraVl2{g#Ff<^^m*(H+O^TKgsuujjgP}-4*a_w$Rb3>^Ve+Jzyy< zd!Cv3uDzWB5j)ueTU>OGhOKPxA<1yzBUOw=o)=z?^~_Dw3B!GGeJOwk9y)6ZhFZ;KxbfXwX+ zfe#bnxdq8>c~;)wjGJj`6~CNLM`r-e8Tj~OzbM{T8u&rR2Xk77@UkhQvEt}Au`yqG zb%OUn>iPnjAYE|#Rek|p>U8{5hjtMqz z>VZ^>!>_`4_f{8Ltz!V&a;7tiui4yBflXqn2U9EX*dp)8-s~()St!MT@&lOVw~PJq z@@9{827ZKrj;*PJO0SRYd13f_Y-}$!2KylVvf%U2chED?vBq)QiS$nOC;R_`{ZkL9 zaI^^B=F#$y7?dzEXj1NxS9Ep7a3@qNV@X-T!K+j$?iZ*MFt{tRJQnJbflpC8@Dhd< zkTqjkmn9#^L5(IE4B}8YEllGbBK#lmYUkVR7%(S{JEZw?2c~!KBAMZj^}`c5#`Nm(RkXIQ2t%!aMVd_gy&zUP%_5d?-VYle9 z{_w=*gh$-D@DP|{2tjcrXaQ~Np}i4gloy$qJ@|9Zw^ULGK*oUn$(w#axe|v>u>=n! zBlg{o7g?Cn!ds)Iq1L$txPo6FBX^0S%L{6IxwNmR=SzQoDO_68CNTBKj83?UvEBSJ zf>l@d!0Oe~n)+2uO@3&6B4!T~X@*wk8+VGJEL3ACr5aQ( zE{ZBlc;)o=Es=?9FxvCL&28_&gUNOK(HC)8hypAGFBd}fV1z{RrK{@>I4}@@NmEm1 zl|f@m3-=fU9}fSJkiw<`#stWvrq1<*i9?%L#);t6%FX|>{N4ueQQ%}*eYQdrc61by zkNS1tC-lh6had^u1KLcj;SXu^g;q3d20pfTj?T2}fABljj~zJo#7fY^jaHG&ITz#P}V6RgnNx(!&3P zur~qAd0pSXpCTd=Ql?Z|NXF1YB2t+t6^VovDngVw6&a&gri`gb3KhznNHQx*<_1EA z#EK&IelC{1_j?@g`~Uxref;)bdsENz{oeO=pVxVw*LlC@0}&VhiS;w?(eZ_qrE@tq zO^;i0az(fHZWdv5Yfc1BPKPAb!N0u#1++lGo!Ft@CptRLgO8C6g*oI;O8PO((>(Bi zf*AlI9T9vxotpg#w%0LXnhFcsBjx6`YimG!AK8-1d9?LJ)OG>um~$& zZ5^{NC@40*bRS2}UsPUtknu5J`wE~MKb*CG{ki4mPoLrw6AQ6lYhxkx*%F)(AAbO7 z*m+`715EsQ$>f|yc@zSsc;(7>Dj_ZH}Bj5IyhNWw#=afRiNTIby?Zy9zQDZf;-|!%$p+oJ#aVPM+}X{{tTnP4W`+p|=ggE3Wq6yj zfzNIBC6QsQ?!+Q?XydZw{Q7U-zrRG@Vf>_sJ+vjb9^Ns!9gmrh`9%fA#W$Jz5iO+U zChO073Olm{b3?Cj=3Qr%_&;f!)I5~vWM^x#2L zO!~wItOT4+ zvjb-yxzsfcU3Q?n!$ph64>o|HfI7J4d@>DF`{lrTO&@_fX=Kr=w(vZQ&mC=o&x8(0 z$~ey@mBSEjIQjT3qn=W~qosKP0}1EKO34~X7?(CEBmK%1i=4s@Z!&-&MbFOm#AQ4M z4Eo0(e{`RhH;_GUMKcR3kK*sPHe0-zA6tBGl7ppXZOpXD!+G2&vUO`yhCrmZ#gR|A zm}JNw9j7O_O2L`v_WYa)74yDNM~ihc?fO^}emMvl6Lxe+Y_{@&UkvM#&v$x1kK+m? z+T$}`2LD=8&UJMV7y9we;hAn(@%HF0mAXe@Bv4+`c!xmaO?N$-{VK)Vc3;ttp%7`l zJy$DaMe}G*UP?t5jd3>{^)Dnoyi-OdKA0AZz3b+H27@N?0vlhub`8tZSR&a8$_ie; zepq;1m(HED;zo@cW!$^>VIT#IBYJAI_Vm72-Uy@!Wqaa>orb>Jr%#`^=l)P29$qGX z0G@LyoEJIpUvm*bdi2zYmP7K^@z-j~eJGOZgXmW5P8YFs^cC zEI)dzxvKV|5}Y}%I8Y#2*Mce7?pG*zWK`7>aTgfe?8ED`9VQUH_{7SWjZbi$_(L$n zEu-GkwX5xq{oJujWzB2mVLpESnx2~*h9e1~%$+H{mNDd@834l1bscYS1NHL?Q4FVt zRz-u$SaDdE*al%?vZt|V#++&b97%+EBK(5(tUHL zoMgOGM!Ir-R8?^})~z93%8@_0pt0E#EI@oJAxIF9VpC=bJ|g1;Jh=waXDla~j>80F z096x08rQ^#*$`#SR#OFU1~yLjoZ~ti45wy49y@2g?`8KyC-Hp|_M?=NJ0Mum#^h>eS2P0mG29q5oZg(Gn=tqTEa7 z#A|IXR7mOj`KqU#@%{cMEUZc!im>5^mH4^XS`MjWd5GcIAynqPYg*XB#ALf9PfHo1 zf|eoGm@PDC(f~v^5`IPIsaH3=53Lu9S>Y2Sdp-QBtI|J6*vsT)?@efAAPNtNU_WVk z+78{Nw;MU^8{oT}qZTIg*Sft~+N8te26&np=$LM!=v2859gac(zf`|PgcIi#Wh&`g z-y6B^y;{;fclJBHTEoKL5vvbEH+j*Q+4tlzkiGp@z4aY3A$r0vpI zWg>q$U+SjW&{kdiRx?pY@NAaqm$G(sI z0_)hLB+piSnL>N_pCtv!2OyS4hq%jZ$)~1Y$BZ2L7y3V9>qg2E5sabpWB#esgz7^5 z%RZ#Ix36D15H%q&Q8L(yFZny|Hfu3wLy*E?!5$Vs=>SeCS) z2&&wU1rB_V$>LE!37TK}qCe-@5R4g!U&T3tB8@+lxzC?rPq%M-m1UX5MvM`52~ha2G~FIu(Bg79l-598CY5Q8{j%_G1b~1u`|@ zupi5T%L{@i_D5nLF&9q9H5kZ^ag2VlJ7pC&*YTkFz^t1)d7gUxjVvehoBv9cT;8#Sd2X28L@hJKItXClV7$D(E+#wr}Y*b5A zGb4;~4G5^9q-3IptC(VbzS1-=2sHvQ#{MGnP-78s4q~8EQMRKD9;PEY*L7mmDk+Ij zS&%z7c%>UicIEqudL_OP_z_O7ao4tM-Jvu!@9~!^{FAVX&}>>oeXs(srVtwTpPMw* zN^OO`y?{nU23P?Gl9@F4b&5|6uyKI7o$h{jxE{<4Un<_OW(B_1{f|67KtdO2mkY;F zYD|4Nd$!Vig+lIXVQ1bvYsA;NcOFp0Ikt{{)4u&0#&OXk)`f(0(+DP)=nWWEB{ok%Vkne-ghx{B!FcE|Gxh}HGb(>V@o53r z#`iQ07L?;X(*D|ZjqSgy@dl&z?XA_VU#*RTqw^oKs3%tdX{(N8cxgcSo29nK0tTRW z#FE7%*==a9?!9_-e%PG5#73g(vj%!BeCNo$8a3N)nCyxGrcP%{N~8pc=n&4^U7R7> z%l6{c`-JNpw(1Hrr`N)TU4Kk-QTX|m0w~^qOnBH+{zE1JGKXI*Id5nV*)*Mlkk(Gy z@z1w$*k!KMat4{qS#kO#Gww|pEZ_<7S)?ue`|p*YFmOWX?%mU7&RmO?mC@>6xF+y- zwe6xNJb;*a^b|8_BY13;sEI)iaT*q{I)!}g7TyZ={n^E3I~iSobzL7E3@2#e+onZ} z8?gIo-g8N(pr3BY*rM{~Xto#U@-d6>BijAl_HWrz_Gq31O(`xYkJHDAg!u5{;s`8? zl*ZyRD0s@oRBq7Ov`L+|h!vtn|4GjwEW*QwS|pxVo^F4&XCFKTf@Gn(k#hstn$1co zXaRfre)DDmH-(*dv*#^6eIwh1!dI{6G5<@XquhFNW^q|tr(;^!m%&u9npdAaYYj?b zi;K^MzJV=5{i|zs&hh)rPH`EmCF)RcZ0xLEIdmp>z?_e`R7$2I0KLm!8@IC*Lj31} zodd-AS9$RGm{0kZQ51d?`54Z6-LpmYc=yiRImu9BfRJIYQq3nYQkBqcY4vl!MkpqC zr(-){06vl^uGMdId1v|5ymRKKW}u^qPuL!?diCY%HEVj%VnM;nWC6lnmoyKTk-QeU zASFCT=v(f%!k(H{H~^VQaF3W|qs+~1lew)f6gH9R_d#RE#HFlFSMU^BIOYik;p1Wp z@qy*R)4gV=h@%IVA|_uMom|Q~a57HY9Qh8(7KS4GfCarAI{2wM&t+!qbDZCg65Y}@ zE;s;Tp7H^6DoJ5|yp&m1Gix?Awz#0-T~^)h=IBY2T8kcs7wXxCC0mgdP%qMi#oM&W zVby7VAd)v6bs(l(hM3_hF_#{gvtZu5%?{x=1xs@$&M%^&XNx20^s$c*JrLeR z#;u%>9owQe)CO8qAZ`Le;qGy*2i{2gT|b_4wDAN^l87T6wn%7Le!(V& z+sjDe5{()_m&X+j1&n4a$v39X6>-!tK~5V@)AmM28^9F_aBZwNKDj#2$p{Bn0atMveW|;XCRq4e z#6R&!aN2O`kB(@1)aB+3+kS6jzG5!|Q?yH~=FKx?;%#pq+m$D^EiSluS5~(h-nDn{ zooqW3!}6RV^wl)0ismg^=xxS6Y?52v`6i;S%sl}gx5B3&AX9kRjI8?>K9|^zk~GA} z8%V7YLoVun=gcO1YyRLx@##(gZD2UolgHTd!%;jtoci!}%^cU@v|M$6$!OIw%VzmM zMwmHcBPJ3uk1qz>7(M6+hVN*drqb(g&dSwg7d6@MH;4kQp{+fHKP&Ik+B#-LA8SiX zO{XN=$js;wwN2UmuU;J-aIewiVQ)v<*I{|kzct}lsOGtheQ(zPU%U*H?S`xF$fobj zn?y9(o+FJFbC$!H@~_l!L;aYR;;#hvmcXO|y!1`)0rhM}x|V%f(SfF;coNmf)AY6~CDUc6bgdpK)MgiTgDEiQ-FC>VmGtRqe7 zFc}IOU~-kH<53K-!gyZ0cQ1se$OW#WkSAIUSl)+t;TcDK?l1kDV?+d4T<&roj2j-6 zUH3Y+!TSyOK2+U-m^X~oYalH#2&q^&fH`+IGV8Ps_vj~(^e394S|J0bG*DAZMP#7^ zOn@h%@-4>p+uVG`@?DGiU0Cp@p`a%CNsIykoI0P$0VpUeOrzLkJa~|b?SehA&tP6J&Yd^12V9baSwM3yMp5<-Apd%f+^z3wXE1pi7*X11e zCCYfQm}NJj#{gG(m^7Fl-71Fw2GSRvxY=m3TnqU%A;JQKz*ov|Pw|;wz8r3!{?H>4 zPi)%}?LG>e;TpdF$T2Mrgwn9u`NYPhXs$nb;HH`NaFiHZ$DrrOpKfHB-WX zs@4~~cm4M?j`;L_*_2}T3T&iebu9_`IK*c+J?{8c?C^B4e{}5{%*f$-$n|Z@)Ws4^ zUI}r*x}SskUkR25sjRNE`QZj-t!Y% zsRH9vz8t;C_HwA;lia>+{2DgSM=@cNFDwJzcnJkk#b%3!hfA+!{;?sdWy?|CWVV;r zHw#~1w~>o(Ih|h@nU~2dm-!Nd`gp*mG?Yn&;H|G7w@*6J2&9$K&xxT9ZoLo7l^Nh$D4o^ zP{vQ&FOVv_%gWMHejl=!C{8}k4HZ1T3xqrG?YAgcyiAA$J8qcWU;n$5PVW3Kh6xCe zl}95FSnb}udkPk%fm0+JiCIUq!E!!69^sZrRftSl*yjlt=fAM1pX= ze(RRq;6qqADa^r~6g!sWXq1@)TWKb1flG0Mi?y7;pU%wwVIS_T=s|Oc%Mh~qFhnEJ zY(!mEeM=>Tc?{=a;05~s-1_C!q&8gTjKQq4eRN63Q9J_q2EPb2n$|)Z1Ny<(@TEvj z&;|Gj#74=1cl?%i#G^I?mPap)`?jn@Y*oA3jHGA(AUKDKlUmeQm6hZCeCH5AHK>zq zF}+b50Dz@w^gyEw=~)86MM9h4>(W&Yy+Q_GX3v(HntNP5;q4r3M8W5ffG=(-b&q(z z5xx!oQ#CCM4`q9xceeCH@s{R_?v+Z2-A0@!P)GItJqEEgDUTU*uYTjsjhlrq@`|!8 zMkSdRqp910l=1f5(c!MJyE4y&8!8@^i5lkZ{CCBk-`K@r#p&d#kM94$EtT;{Hu7#C za6txUjyp0ZhlQ2DVg#+t4W8mPAXXdZF!A_^CKmR392^(GW=Kg1f8F@I{?}>~hJ^^L z5S>)0PM=|EJ3>Q;{vs_^EbMr-YKQbY_}b2Vzy#?F$zrYzPh> zx3kIeNf`v}He?Zq-U;L+DAw89W=BKKGy>Q}hY^Sd>g@91EH4K7p>fT<7yHt)L#u0Q z`RyAW^hMqCgyk(&t9D0*s*UYeDyRn7!rsRlSK8JxA_nKGN0ZMAEv^L0N{& zCRq49IoS5p-g7JbDtwX`44B|_@A>@xx*?x!zRrIhcYbf|g1bMG<0QB9n2Ar9E)fx? ze3mSI=#TqtjesRT{}mliujXH_xhapbkcJ zVC=FH5!6uz*>)2r2FY+ZO>P=+DxT@QC<9x~>^i4*R?BU$g5vjlxU|@;4R^h+hkQ}n zcy!P9?J5?knwpvi;^GmgvM&uLbv^we$LGPp z99w()z#TiZva+%c96vs}w1oSV?%&fjROptp0Uy=vx>K!V$0Os+_cQlO{z@59ou{ln zpIWz}_z||VwRAE0&;}!iR33!h$JwVt$$@#|*DMb@H6keb*K_9oKRL|KZ_7ZFUzvYu zKG&qH&Hl61xpU`~?LKiK;IE3L-*SV^A5 z#u-u3cUNjT*^VOhM@3y-UBWjk`o5suGbWDj0(smf^*!7hH_J}o4d+vk^XB#8p&X@a z?9;a|Y^)O24Vl|M`ShTby{47zuYY;!hNKU+wyskXL1$*hrrrc?6n*4KJJfIIE+Eh13kppVKf%c^6+@*tJ`?Mi9`-Dse2)^o5=V}O5Tdbr^R zrBgK?ecFVqSBa)xMTUvqG92)I?q=hR@4tJuQ;=?0M08U4xpOTib=9UUqsl1lyj7?@Dcg5n zSXiSrA?dk8tgKXui;LNPb$gkZWX6u~_D^xP8eEz+gMCj%UG|tsw&r@e{#CaMlbmuV zJ36i-jwQf0gBfdoDuMjAs_8hQKbDt6u2?TDwTu)9F$EoL zIblMJQ;CTTx;8`-~R#hzrEq+!zUcBMxesjNI_zVAAg`a|E$mB`4 z=x?QiCr)hjj_ij|pSK1>9p=vGzuBKhH*H;0%8LVzA%m9;$LdO>k)f}Mp2%)kT zPKvb*p;KQ%gDva*Ttp6J{u_E2T9f>nSl+L0) zqprOy>rOL>{vv-3yUoZU9w!JSAIKBo-vUwIGrqi;*N2aGl>mSz-o`~hz3vPxSAS)R zxNXUqe=K{>2#-cBR#EC0Fm+o_(^%387v%l>$vme`! zA8#NvW%7j-5@0@7RW4W&kj;OhVOkXvW2DeMteTyf8F2h~S6*v)WMpc$_~P4s=L0Wu z3=w00%yh7per=u@#Pg4Wh4|6<51t>?jeee9FE05tV$<&Jzf23VWn{X0JPpzmWL9ub zIvCCRjeped!waEAO^r5Z74In^H9wECKPAEOE&3&*ldLCHe^UqTv}p7;TFYAWz1Uhh zynTMwvw?nXn2S}+!^m0rjY82s=yu2>}%a#kqx<>8v@$wo3;1AMn zk~r=>`?k5+;_lu)K6`v^PbT(A>Ts$?8R)!@IUF^V8JP*Ba)<+khIcBUe)HdddlY7| zy;t(EJ{F)Bt*B~FcYK{0a=#y+3P)r;d?@@UMMlycYNo=Ko5#8jV$7$ziAfrK=*03q zi~?N^*6C;C?EK?KIh8?%;u2ufUbitye1ECOq39X>nw7jikj6FdZPsNUKMtf~N#QqO zc!OGNMP&>P{$0s6v)wQH)wF?f!|`ZgZ?B2^c6r80V`eyoA_L+zhg{gUZChyYa9hrN z;I9d-#TuG^R~*e#PCg!)9#LI4C~YND3Lb2K`p|r2AR*L$47}8o_xe(MSoV#3_tH57 z!4zoH1BVT(NA;WP=5{@I#np9<-#$OzdqMu5l$;#x&RVhA-Qrb)qN3W<)?!#=T4@xYS?(IA*>7F^RIwo z0A9g#y%G$=S6O^`_l6x5|FxW&BSxr!KAIEpm~xIlt`&o_`9+(_)_{4O#!;*n$R{0k zAo^xjmL^!L!MA0LleXy*aifnkjKe^+_}f1n9~igv zWOH+5&6_{}3WAV0OZ(0Jjf)NS$!xx2UQ@M-8*cQBjT`fcWw~=0Cor7ByjfyN(X!~^ zBVbo_lrughT8woYGl&dIb;-x%#aV!ymGbCObH@I)r4RG&yg{E2!|z*(1Ij;S(IfMv z|EzPdCk#7;1r?E$q{XVMiZJ4ArJkOCoOv72JdayPpjtKS*RRhWHRd$7oHwsKt(iYX z(a9!bAdtcW8IJpPZ+mZR$P93j^JH!JAk&F84z{)dV3wCuUB>*@0Nbf*^hkB##+@pL z+S;E7+yvkOn*vKF_0z8s__t-(F2U0VCML}YvaqzV(Gcta9>EEqiL^&plmF_~R)=*0 z5{yX&UOj*CRNOb2%nh0?uh0nFJv$C1uggNaRYQYLS=f4p?$|Nze5>^_cli`sLPJ$K z>Kf<{5FQsq@w>hhXRz<%X-gr22l39?pq<#6Uc?*HKs>wTr%MOJgNsnHx8JjM_wM>M z37l01#>QK;Y!VGPl!gu;E_0^%kvFl3d+4n9FnBckPqDoq4^b_+tw#k^h{sl}^z;Oc zH8pGF5CK;(`KXH}3>imc2Jp=2Q=+n9(zw6=)YukO>_!%-=8+WX4>xL{# zbk;z;8-p-KOaDdFeBj{0K!kDGogCU%!BnBaxv%MH@(|}Z;k0j-fp9Bt*d`H%pZDRz zi)rcMR`&L54<9;|eZ2IHjh$U8c(^+wfr8|K761EcxZTHN9+pXY{b&S4JvEYe4(vU& z8G3*GQ5(YpKf%@1$jWydG#e*EIA%1~|IcH7sJ#Ixp#?Y(psM5;V8Ea(KecX@tF7l| zz8U|=6x$}oqvgkeX&Ds`V1F>^-3WUqKSRN-7U(#s-~%t%Z4g%PqEHaG095i7;t7Yq zQrCNNF7|&CUh2Vl7Hu|=t4RaRhmTm6#ej!~1s3!=3YM-SD6PPphLV3sOl;;j*~#hK zjUTPrg85LVsZ*8j{$vll(TycqRdzMu-qNbkR&3-l_5<-(V0ABD#Fpb%Nqw!nCGP!s z8!1gkozH9Wc%-!d{dW^c0gX0of;oG~ye9o~ErapWmmWRZfQfspv(*_H3yIT@hqsl$ zFb;{g50AB?^;<{3RQ)ITplO9O%$(|}vbUKA)RBR>Dk%nnDdAXauaJBxckgTGav$@u zD-2pCI38Wtf4;206;)+J(0IABt09NAl{D3R`_^K1Cwz20U$|)5d;l0Z`}j8wT@{8M zq4E-~f*ZGK(~v_qV8zOa=)0ppu`GN+@iKoR;Bdx_wuXkPl-WLuKD5R`OaES*&^)?H z6=^XH>|Q6C_?Xvf+&F)m4)?p4Z#Dl)bFjST$JZ{4^ek+3o?&HPhq|9%ws_deHPwM>(;6!*X_RrrZe>?&<#X`E zDzm?^Ve2WB{W)8ku&4;0*i~mb$t?zmbNT?;JN=LS*$I=jLhonEa&L^FZpqays9c+2 zN>CEGi0~>SESUaJOz_m!)YRZ8`Gkqt#BCW$a9eH}Btc;)f?&sP-8yixw*|Ae<&~GO zc+KudjlM9s9~KzU`GhHt8Eak#LvfZUlO;9P{W+970N~pxt^+G;C;2d~u2_em-h2qY z8Ez0Upe5e)UB6d?bJv|C@YS%Z?XN@eUuO~D;83{^uPo7t{Q4^$o>qU%ujTg`jJAH| zO6AOq3_W2QPfsQ86!F}eGPZmBmd*ES8a|1l_Z1x0aZ-$;{4f#{xeX5m6B2*()$OxFOc#xz)pZ4I0tEx9R-_8zY`bPci@9BjbV( zA4c0dIMh?zXJ)Ji6CZNJ*ptrJSYg$N;;xKcL=}m z=YxjW-bpK*Kb1%fTvIOzkhlh&`?e;x;k0LGyy%*&NwLO;CQQEfA2Is`>OvhsmsHw) z_c}WXDmL{OrWW4`6|T}?ewHVElSAA^&Vp*U9%gMC5xyo{a!%;o^ft;Srq zwsqQ}V902iA!h#dqashKvM^c?Sl%3dGIW5isj5CEn7~b&Mnzih{kDxGdzFTAhYpA9 zlz#s3ydN$IMi*^?FoEqAh++B|-P^kLASV9)jT9 zYoPdK(^0mw_AQ&3{rFoP7D4L;JhEC}OLNoVUiCV5yy0>eFp3H;2XfoC5fjoE|MRvn z-s}8#@18w7qiN;S15QwiHFSAO;e4;}Upz5z(7&q4w?22yREoGqwh`~{^xJJuJa>@> z^=S6Oi?-b+KHxm6ojkYbNR{HikKpiOw(42f=M=hchI}AZC)IuTTux&N*g+AMQiR6P zkY5Jg{f#U<#$(-)%TPg7FFAx*MXshztW1WpALTF60im5*U~McKYOnU-;X`Y>R-uEK z+e$%*!nMv%dtyv!;PfsF8ZV6jH5pG$TM!aONJJ@*S+l~UqUyjo0$?snm&X7S~Hod+EdR4Fo`h40d+bf$So!V@+bB&&8bUIx6%tR55OFNn7jSj9LkfS zpJU_Pss7Lkzl+U#YjC(&zeeu)QytiK5NvvW0cahdP@ltN z5WG;A1H~zrwVVjWgaq7^KYR6a5aOE)rm+o> zGs}_0@3eXU5p>Hb=kbqWcbbW?Nla@lQVit1ZT&8%cV)$KGhl*YWOVeS zqZ@V9-(PYXL%!`m)yB;qf1oi_e7w;%<=o1PoQd6%%1oGQW;CwaBixY+%$0dE1I`U8 zgXlkb--N2ZaXA%d$7@CA4kwO4Yy+%Df~GC$Ps>g}##Ra#;JXM(RQ)+=PGI^PkD>iG z-570x30Mj0U?u*Tfp&IH*}1~9z=d%@2gs*JbyN7Gm%=USfdCQuAaE@C@flPZl&`v| zTyMq)jfqYggXqzA7< zr)6klWHDq&UB1mDLi`{RWd~4V?Z=HPV4HH4rKx;KXi^A&4R#2YE5XSq>Xp8stY0=L zE|)r5K`NXYZnI{ce%m**tx=2}(xb~-qX^{z`^9ZUyCnI%KiiW3E>h3QXj|Nc6vPb$ z`K-dZ|J2RVOgqR+yuGiVHYU?l^o)%}>fD>`7-ia!-+}T@Jc+ncLCZpU?+Ui^vEgHZ zm(y^D39Mz`QU3}!N?o3Xq`&08pjLF;*EkPsY;645>(4GMIcfVK$)p(@lU>5laD8+G zp2U^w*HsZ4tf)7!y1Ei$wP9-N8hs*J4bz)q=5l0hNw8X|x!(Y2jy>6vVZiA>Gv2n1 z0Wysl9b`A&%whaUmF1n^Rc4i5V2I~M4?Z=*G~{3SsZ*L%wOabM(etlDFSXj9kjTK| zKo$ZIKKl6aI{L4+hTs?XO;87J0hSKnn|<*uN-Oe5TyXdDecivufpjo{x56zgSRO1! zwAkt=J5Q~yj{VS=oO9>7&d!;33pR{`65FzETh@WtMh<_97TRMAi@YYgVNg6%g`xOa4Fse z9Qsmj#C^bQ5sd6q;wVpL9IKU?le3mCm>zTTg~dvKetuxH%UHwsO){Lu_oz%;_F0HhudAjlUEq8%=ThaGtWi0g3t_CAy&?e%4QwGSvUe3O=SmBRZZz@1a7CuY8?A48? z$evfYgfQC9i$SrNR83n}HRBa4QiLhOs|5=|fMN?cj!|=Z;+GKas{53IkzZl~XW+2f zJIL45M$teYP`0bYs*ru&a93DZ2(Rnmtnq^e1(<)^6dKx`x;%;1g6T z&!~7*T)m%BdFXPNoVHD!JGT)KqdazNSXj62H^(gC9n{l2QB+)90MpXteo{OzZLr~w z@n|-aCQXW8UO8VX8d3`4?qG65jA{4xn)<{zgw(iro~?=L6ft{rzzZU%2C2H+Or7-q zgDsVx9-DNwi7?V^FJsth4*7u)D0r=u^=orhjJo^OUj5E!liR#{Io7ayOydgU=wrvM zAO|=~Hz8yaW7ZP=-Q%NXq7eEt_Y783+Sk&M0=x`1wzik4NEsOG;C!c0jjP%o{KD5$6LczDhT+^iCcg{E)ZGuy5APx> zBE6P+%jfLW)?(>po`*&vkaj;G+k>P4@n?+5iv*w!qUxKNm~@O z4<0+V2~fu824^>vX_X-nrU7U}7Lz7j81$5@&ivD+gB)L=y*+s1`0hc8H&Wob`xk28MV;_)G$W^X8wG z0lS#k*jCSHAW=dpbYD?bVO`n@F%A73>djYUeiHzpS6I1WH zGf0?Aeg&N0>eHuBr?@%PkkM==ekmwZ!_J+>FtmQLUtLIe90EzteqT!~Y=P?K`|Y1WoI@x9sMS?tf+HTb4E=Da*m}G# zYScv^pIf_oD$jz+qXleb|4vN%G{Y&Z75b{Gw)x;y7~itf)V|hoIKF*r7=MWZP4gv& z3CN!IGv{nrGvjdbMvawB_X~w7xkPk>Wl$0fYBpx=tvPt`ub|f4>Zm0oF8hlfX{xKM zOwvWTTv~wu=()w!#&a!44vW%@3*I%GHOuEoX57CoQF)oHa};N}>h9Sj{g z@+zvj>@@x!Yj!H_Z?xE;#h*AAu}3cz~ve3S*s} z?|5$;$330Hp+(mtw{Rb!t7*gk7FrojzcMZ1I$PQ4=pCMJQ^hOhRV<$NW-Tc6u)5Fs z$9T0|1Xo*8^OM^%@ZEw=Z63=B^1!QD(np1>08WFn0*m_Cx3cA`o21!~(NZketzBF9 z$kC&JnKsD|U_kow_hBq#PB{#rmbG_4bW#vQH=|i>VaR^7+=wCG62NZa(qsUGvOn|w zhhCVn5taS-a(hzt0u76ycqWtvk`Z9I?PcN`-1VweI+vDx?b^}EsEK18f94sxZSvTe zn%}F)XCq?1P$7)s=*e{$z&p#aWB-@5Dk)vH&RzDcITwNO2B`WeQ@%Wtx? z7IOQ~4N%s4yeH5N28bC3fT;H50#|ufe@$$z=z-2v{f)H;@UdXvOl|=e8>u9)GQQFl zKJd=n3VP9L?(V~=FYBYCW&|bInR^sbnZd0WZ+}Q@w_?VzG%|e^!u1?GeK$RQtwN7s zo!RBB1H0$?aaH0Pg&te^*y*l#Hx+t3U)QZqR($=S1Gf2t8+_ECBqt^95OW&$tjPD{ z6^d*8y5t}~1wmykYqPvqh?CqQ&|yLir)4AY4AI-oLlcBJD6z=-v za=qPOxOSoBwg3gTvY^z;E4F>a8_)!FFZ3Ss7o!!M(Wtia{d`%?+PZv5w-QA`nzf`|$Y z9-KIcHEKy(AYXSY92X^CCyR%&j!Mlqa|Z_Y^nfJ>K*9EG4+D3K7%R$mmJlic!|qQC1tGTRyqF^MqYk5;JG?O4?k! zVJ&VuH?4+i2Se4YgS40AnHF~}>W!gkJIi>@E^Mr}`OhsQs85VwI)vDC-huyTE5r*qr!Bw{xY|e8P<)@o=w7>BGE{UPo;yFgf9d_EI;8_P_`I- zW@T{j=-4-Qzz*n|E&KO3;}Ix;pkh*cY|6L(QyD8l~RlICj) z-@F0X9C@*Ac+ z(9B8|73Ujkwf`Q+R8s_`wuJq&9V%|kLZZQE?B?MizUpC~Ygez9Gl)Phw~Q||`@+a6 zB&>zCCgeRGvy4pT&MCOM96xZUK4`MB7ux(8h>h@w|()8O6bYejRZc z2CTwv+*cy~!y}V}l{>&yVb~?Z`^$&tPmdlM#|`2$Qt3*t&8^`V zaWPr_WHhU;}vAyxc|EEvbX2Xqy(5wWtMU|M*all_GVgHQ<#9;8Hhkt{m;sbG;4+bx^?T8 zmat+Q0kNu^G9VgD^lEg=DrlH_BcXo_dK;K{EAj%{?+WItVJdqQsTqBcg z`yEoP5!HDRJD5f`0Vkb?MeX|Ph}GjUplE|Mukn{~#H@j4cnNio4!}y_9?5_!nOJQl zW>R_y;0J$nio5&cw+p^G^;5qw`bQXlLGUO`H$Frkcl`0%%@piqk^Csr zDMX_LR!>#>jdnEc$Tz5k=~{?2&IdI2#=oe|JQufc)2{4z&Kk+TaipF-@QPk2_>zO= z8lzrij|13F2La;lcxLhur58073L+uXT?7a6+Or)cF@?^KxtVI_1 zr!WV|v@8988OAF1o-($Kw~tSDkgMSyZ&6$H?vavK&}u%^mFLed4vPz-1cwO6kK_(> z5)c#P(eqw(Ar(vPXzXOi6Mxl%w}1R9$uUsl{>sOOF?V(wyVhZ^NaGR}sp?GDm%L9} z5LbvD@A``04WQ{!tQLS)e7S0@3@Kg@wm8W>Dp1j01g_qjbCQiDv0aJ-;o$*nAPHp_ z8H#2dl_(#N28k|6XZ%=i3#f`zq!b`{lHB+M z&I)D76OTvj508Esp_;R-q)sFI;6eRdT2YEFxa!^|dI##K@-3Nel3v`b&6qsj4>aCE zoJy;I+0hTQ!MSS7lEbhI1L>gbxuw!Kn;k& zY{C3vAh|Q_c7nOvU@_sopt^hRSWlg*&lLlgb&qYhGea(xs=(gd((GI=XV8?nb3>r3 zCC|ol#=)d+Y`)9jfdpWJv4F&if_oDyBpUfk7_4va?LtuzH0p_4c)Dg7xW z2LB`|yJXxY%50Eoz?Lnx7hMHj@dXFLE#m;H)ZV#w-##|y*Bg_F7;VbU;2jt*DnMnm zhGb#N@>z6P0Gy$!zFhY}TlWzvt=df!yrdVHLhMI}(R)*vkYs7sVcD;Ozz~-nEk3id zQ`j#b%gWrd%2rRMrxm8}OKI*Hwdm*>yIAe`1E6V@)zpIOxR^yn-@~eX8O<`DnO1C| z8fX+e^mLB$%lY$|Ke*wRe6C|09AwF{*gZ22_I%+u!q)z~I6PoM3F!`xiK&l)U2M>P zEiZA-b>AEB3%Zo@>88}IT^>XrBX(vKUoS@a@wure*c^kY$FkK3w}KXs_fMerN?fO$ z>=kkADVq0m_u&H>Gvzx68yU4KOon)7WNqdIzAS4HrzpL9Vvw?tLIh#png$*Ll6_pKGDqXiC{*V!AdTk7s%SHuZmXPh%POM$3fcmCGW$ z_i8P`JcAMD)vK&LU(rjDgHll(6yy+ZgbQ$GN{WnZYdFiTCoG2y84RljP*V&T-L0Us zG( zFC+<#=F?qqPW54Yn%5|ICb>)=J60KDW9j!re=CNsEj_)22zV z0h5^Bv8MVf)e3wvclq$=h6#Lk%_qjW7nT@ob8oP^BPnA=s`jnO6*Utd90i*+>%UA# zM{?O)BQ&{m?rq6KT*uto6L(rI+-ZD%ycaLDNXL# zz576x00nT$v}vCnpAY;GNBKks;`KS{=ukh*TQrM?;WAc55pI zkflpa*+sjzO(&F+DF}b)8V2+#w6l8l=)naWHsiYJsM${?`?e+2iAI4K}~B)CwK0_G8wlxA?H28&2#&DJD!WRU2b!x|P9+JCW- zxHv7C6mPLHiAl@PK04~3@=en{JnAcyRp$9nfD{UP>{;cleWan8vBA6JhM17FX^8x* zSUafj%;t-K3p#2YRc9LLh?819v>L@+emeKNuBQF{dTiW)Vta0 zte2l133d;rXpME&dbuoh*|lQ_9^Ja=+ymhviQEX=d*al^OGB#Tm{^?3L>|4!otZ;6 z7Gk1-|HYLf_K~F}_4LW2&{Zf{ud`3r%HoQph9or*@c#YPk`)bQ>P#I>j%G2s-ys(r zdKWoDaIOfw&nms){l{;B6g}fCF;^_${Fg6N!|ujK3O&hbkZig=x8~ck)iuEWS`~e) zrr7=8h3WI!99Da_3CxwB!r9PBasBq~t72%RS_QnvF)3ZSoCaW?Dm4whVXcp4GjE+@ z7E}bC2MC0E`9DQ=v_@@MhL-U0YVBt4rB=|9@M3)B*mX!8uW+Gann|yU^LTnSO1U zo>~eszv>GnkxB}>pGG`RVRZTLA<`{D>A0S7l4}7|rZB2>Y=7ivKIz()jkiXa)`uI5 zckE0MaBaHj+BoBz!|L$gb|&0 z_SsT{aGRR78lST3c8Tz4Avg~wDvI11+!Z}_4o~0-bf5LGvuu5!2aVQNh`aTS7KoRl zk?sIX{*8Wy8nc?wnfmQk#lJA9iNiHWAbUwrWYIWA2NO`DILdgV&QV=F^X+y7Ohr)gLeU%VIFX@5+oDCGfKCcZJz5&xq}V>XP$l0i{= zgik^Ioy;u@qSQRyn&2H@}@-Q=uLxIIF+a^fxf5#Vv{&Ps$88d^5uis_@5U$iQhZQXR7a zB|+b*{gNDIaaR8lc2^m40+iA&!bYw^ued@(2@ncEdWoG`5yzJljTe;qVCLx~-_O%j z+JZJpOW+bC*vQb9(uJoa`&fz5%f{Zm>RpZ;2a62qSS1FEQbT3dd3{pC6JQo)7YY)2 z;Pqr13$u#L7I8qNu!bvtxZ~fcX@3;#H`u}=!eN1GN&inZw2!kg?lged6gm;ZI$nVA zBS+RlJwn{nq4orF;at$`X<{Pg2vvr3$9&j3+W&77u=j1Cf9ewPtp@ObdZOH=OBaFS zSgrbSyQz$6dH4EHjjeO!*s(P3lgxm_ts)*x=0JvcctK`}o&=C-ndrh%!~pB+@WE?8 z?fkDY4PEfE+ju*>!Q2;cm?)4^#AgnB1;1j&uqNC`N1J&a3EyEVa1c(j zmMvR?9M(eS%c5>KVh3(GjwhH>Ap|!x>m-IkRvxr@eIEXmJ`TddFy;gcyvHW^YhN+D z7#jM+nMC$w=^6rgCnn9l49n3nF^qkm@vR$VT(xHONDsG~b_`N?>2fSiD^f|GR@PfRrL6HxE4IZa2Eq1H+c9YoD_G=RYJ&JY zxG=J(&XGIP%87>_&>isg21Y<2&NUcj@jgj*BMb6n|4)aJTp^oc2lcj)i7e_6?xR%r z>;wj`y-Q!{2q?=OIg+F}O&Yld{4@e~2I86zdip?2NX!wGbLF9QA95?E=$Ta8aEPb> zX-2-qP{i`#4+THMjXdyjn)I*e%vHkw5uHVrYu?LELz+LX*-}FH;=X2$M+-S_#bqg# z64fcDTRgca* z`4|hB1w^=vE^+u^7T~6GnPcCRF@MEPc=f!ZqV=FOVLaz1tW=Lui&lI*e6g~0=uDsD z`d|CB9({6vUPI&te09WgJ$Ut}>B)b|V&Wy_{$=5S+m{>b3}- z=kYpSI-grgR4!B+6^QO2H5WIkm?zbZ&W*LTE!x~W*T#h@$9Q6q1a88q(z^uB$8U+j zO%83uM<<(#nzXC=sRMfd_5xg0D4^x(r6+3X=sd@Ler0h;RY!*T<<2F#24SLMgL7I1 zOyZfd2xT(#_;G7C9Zdrh&nuy_8}|Nq6BhkIWaKK$1Xt42-vm7+q9DdD6K?KF>%;Fw ztfGBKc2~uQ$*DGQ%$SfO$N!wrVRB=bluriNxvFoJ3b@FZ{+a!4$ut{gzp;t_lD5hw`6{&ZORDN$?Co6-P4Z{{aRNmA|={`kKG^mCb;NI>BwX`wyJ4uiu1vdYy0aG3$b!I~7+`T$fn zS!Q(Qp+_Xgo}#*RRY47#L0J*dQDyhv2LByrDOmV_BnrFk2N>paN8%uEFJW~+P)>Ds zUk?*?1!^EAz2B0O>M(-hKKm`=?U}WSyIk4o{%F?|y;ozih2_27%>uJ+SBB4?g}qRVGLtV~24#hW5{6E%;DvwZ#~2ArkCCeZ4E|zH`;zb`D^tL<4bqP z*U#Vk!OrB2W4UFY>xPjU zQOA15jP{sCX8oWe*?_Kng&b#E&hM`qL`bRy?b;PwHq!18yHXJO`BSJ~wYIAJ9|8zb z*dycPZT>i(p=pAofSJvTtw=;{jU-T)4E;AdY3v9r6C_2b0f7)zB5zC{2Hi9b_mzea zBY~Db;#QR~X%EW<-`4i3_p1>cPE*hiC9znTPDW_!`S|iZFr?Q+6to$HyZ&XNKpmGi4 z_0*YhvsCXz9pwz6HI;l}5m6K=)JW7`6#_J1=dAJuU!;l9@6@Rz@_D3q*7&Y1OP_yL zJNTm8#+d2}5c{B4@wdalza+2~xT)PZET&928R2}$ zz|HXroB{bMquj4cJB~_2`3}VS`I4{xmey;NJMj1|VdD$|t>!6*zt;G&=&wN=0K_~F zF%z5X6QroZG2x}|9n?0E z68Q`hsEoMg*sAL1N(M_1|0N?&NMm0gFTogOKEaJN{E+!h8aafrFP{5k!$ZIxMBb9Z!k z{%>YpL$~8f)HNkVH&YbUybs(c(pdD(Qsd%9Bl* zRj1$baCVP{p=Vvt6d5oZb9bs<;2~ak8Y%+s|0-g=WW_Oy_bD>;@thBO~SIQ;5+M~(3{`>}$7b~(39{O+wBKh&4#gA%H{BtI7z}n}+v2$o}jIz z^>Ft%-`vv;7CF0IsSfUJNQWV}4Uk~AdwIZNCIVU1(r+exk%%r_maUf%aQm-88+ z4m!EDke9~*M)q|m{W^f@@MCrwmicF!9uzMxz>6kVs_r~i*1i4y?!)O6Wty7=%d^*h zU_`C$ANS!Z^Q?ii6DfD@9Gm=k*^(vVhvkafeC^slfD9sg5F=MF@6z2tGMDl3#@5Kp z%uIDBONX#`E2HR<>CvaLuO(KSgOot8CgDd%Xc8rv)!eBxHT+9)%V}{-`&^V{7eqCa zHBXr4irTubCJY2Cfzl%TaUWBGX|N4Ft^65Aqu)@HEfsDxRs#+%jW&n0WS{vitS-LS zO1INF#4Twjm=Lu^e0-UZ{XBNSc<)2R6QS}=^_(9mgDEvXO8wf_>~qvuY}N+Dofo4Z zM1Chf_S1S#Frtn35r zA?**uE-4{PZ5Ry$x$-(>4Fz(3ZLl=y{BQML;*`9+uM|(DmgA9GpAtT_Q@;V#L2EfF zy<%F#$7l8M5x0IA=Mn-X90^0y$E)C1zY*EWNI{QCE-pi}v4&U_Ma;xJBz+a8 z4Cp7BAYdX}CVSbeSCG#V$etDBxUFqtSaQRzU61Ev>{|J)rYdWG@mA;NtZdPl*(}pY zCnnQ(_2I)aBh4F+pET(<$3U!&5giGCv8pn5%vg}!UOf2+dEsd|SFS*0Fb5da>Z z$`VFsNbVjdI#&db1Mw%W7zj@ZM$Q@v<3>6n9MDIvooZb^JCAE}sTe?ykJ_5Fuh7v#^4N`tD2LeRGSEMX@`jSw^wNVCS>V znsMGb=qEzWv+hJB_W9%279HC2Gfq#O+jYSa@_fz)4_0-7Z#5&R?*HNI&EtB`-?#6N zY>_QX5~1vC%+w4qMT+dQONhpj7(z3~ltg7M>)1)Mq?CPMN>L2SmMlXN!xV!smQwfg z$o#JBdOYs?y8rurXPWwa-tX7zT#oZNj+5*Tcg_n~4!!4-cYlmws|r4OChxa-jUozc zBknV~w&?Z`Be8ST^-2{WnhBHd3KXCez|M2zzE4Ccx$_j&x|kT)EQ-wI$u}fy7#Vi; z*&trC6*3bMM8n2U`SZ9ol1kuGI}LZlDo8f;stnRFkpY62F1=iPYWnWAgR)*E&BD`B z?H7ElR`?f(u#v7pz?Lyl0B($98oab-2}JU%@5&Ws^}O)mRQDmZdmxPHI&$Qulhch| z8JvJ(KcXwA>f0d z%vr(0KVEt@iuksG0VN*tLHyxv%+~147BGT`O*ap_x}KhQ&Ar67;fDLn+Vc}q-58Bm z$zxXhK58$+JZ7Qhb?Zh^fQrb#2LVxj? zMHuse@G(+ePTi3$od)56J710%XY+6?)gA&HE#XXIfSvc=936}Xagd)7cghxx(Onqx zVzks-99w(h`=&iQ?NWrfz!s=as|w(g$Wk3yLeM+quk*neo_R(#Z%D%^U`t5?m@)@m z|1My1$MQuMgE zTqyS-^e@(jm(zu!paBRrLaxWw6!Qf3opW!d!;NbC;TLXLJ%EXyZn&5Q+fF2&?*3BS z`x}~&73`=WiPOfQ<;!o-ia)`Fm{V(%TwxB+d?vyiDRj-+wMGV@NIA(tEE6q{+v4XC z50s28EV}D;i3deDleJuIY%9I%PiIu;@DIANr522s?_!dj;8dT|1UiY8y}bo=H>1lq zEq9>0#ENUU=jADTaltkL)xhxhjmaIxD*`D5trJxv{7*Lz>|wS8%?Tq$6=ej0nis!G zcoL9r_ckyVxEX4qdNIFI(RKO-EbMtmi&Lbem1gB`>~rUp{EVhMQ1J!+YSN-rI)1JH zCqjYjkJjv)LTt*6W^G+_@)@YqL*@>RTyQ9Pm`1U2^=?h{q0lMV{S!MkLERae=(x-o zvpbL865`q5RB-@Wuygdx2bfz5PN3HBMhAv8K!dI~?6ej!hkIJ{PCk1v9PH0Oqz=c`=Axr-vnEZ-jvxPYd6fgZ zckN2?{w4UY@b;ku&vDFka9B5j%6$OR4PxQ2z=4yP*vKl6#UwtJ_uN?DKBXPivqsD% zxIh&vXJbl|jjM9wH*3)L%{QN46w;VSv_AZQElEDzee{X1K6%!)80uVreLWJyfJyi6 zS!kq5CHUzr=M><0VD__b_)f!Ly|Uu~B~n_@qi?oY4uvO`Dc=D|KYBr2U8BpOca8*m zH_yvHS3r*!(hwx4rB$X{=BhhEw5(=f@!6$YizScMZ36p%+@S4lw152EO9fAS{wf~I zhmu7fn)1ODkNuYG?6PqSr7#8dt-HIn+)Ae--%oAPhwYFg6r;GN&AuWMD?R{wZsTA` z!f0vSc(eR*Xin5Y%9V>j+IcZ&c*iF@#0KfwYN;GW;&byd<$38+yh$xhADV)_1Ysv_!X$9~@52M8t+m843vdwHpW_ly##kC*DhcUCVXx zHW-`|G-|95?}s4U4g?y($ib^0a;b*J#Ab?Hk1FM_h6l1Ofl%nnw62GbUo}3bnp1G_ zzhi>^M-%@*b>z3i$gqEr2YqMG0gisqk|h=I9i4jl)sOFs(#4Jhc61{mKRXFrNF^Gs z!4@xpN&)8fLT(0yQnPE1S9}PFFa7$D-&?&Q1V1Lp9a+-O#^bnw8PXLjy5PZ9AHEAh z8v2<^oTghLM>c4w9y3H)xG{0T;^*+_Mu7M37yJI+`^8QLl&HXr z@;^qZlEPJ#6YSs!fz{hDb#KHEf zd1D!DD~X%LVHcH|If{@_xW7ywqQ-@nGcz||1f(#qRIMHaPqYr@B!0s0LH1op?}8cS z@Go93-5F!DOJvmH!!HJ&=FufIWX0TQfUY>V<~!r#`xPGx>+^mErCbTo6&-~yoJ3M^ zV7@Py(FK`=@cw9sYzMeM>WP9A(n)(jtCn3F?pPf4rM6WBj<-g&YW+SZZKQ`s;U%lG z&`Uo$?%utdLG`~;Wd|ERj@mELAV3na_4UHZl<*(_4J+t{Ow#arjN8S9JQjn}ef8(| zWT8?98XFwdj&)hr*LfrzBdk?98)5IN{!w)%gmdiOO{lLjKOLt=pYhq@(Go~2&^_}u zchBnA^U#kNb?aYPM!D5x{{x2=ACQFtJ1CIgaCxL!f4xYyR=hPiAX0jjWh@(?v!ZF+ zjvY6Q>EOp2R5iim^&}9v_Bb4ZAI{HPlxAj`>^+>s>Dsq%+|1}RJZ;g-;qe=aPUR-h zmlj682d25&V03@RWpp-7J+o&oUDOaVK|}t&Tzg@UZ;Oko447Ra&>B^R#P#Uq%gUTa z@eF8hocgutOwB1O8*~GaG)gYVGA@VlS`ZQO@#5o)?nYh*61g5X@_P^f|DR7}Z1JHY zQ?lXl%)A%&H$p`N24yGQZ^kV5rEE2xwI$=(68B3*^mR~P{#+cieySY0R)`(p8S|)s6=YIx}{SirlHK|>(Fi@FIbury? zY03V8YB$QXODW+QLb+gG^2EN1_k22in4j8h&_^sdk>>F!+44E%3@ti>kA!;Daj=&w9_c-MqVso8pi6oUczl%5EI zTsGrWLQJ85I@+u^@!S_{2El7o>d6#s`XEfW&;9X7MT*{J%17Quvftnv#zP{?JaYf_ z*N(!~Yr38p(~gaZu@=n+yC3^0?NvQ;&-qu4-_QMi&q)@MSB0#vsnMf<{t0IqY^t zon4F#vvO}$;3+m|f%>5k>rdYRY8$g=Tx+*5Nf^u0;v?~U8MCy}$%N{rPNoC>Ta7ZIT%2`(O~O$l9Rd-8T*;8&P9@mcrZLXK^N@UOy`*a-;i3>Zsg zAub;-g$*4Yi(}*4FaGw7UbIw$A`|wv<-4cff$ni`nKaSbYVbV~8QIQjdca$B@GiH1PJ|==JFSID5 z6`nZ|#TL@MV@9$BKx^iSo*c4^weMrxq0i2~gZL=h^}J;4D;`s+F~dwGe#>>YDCD+iH z)-;jiObrz&2RNx}93@<72aW2A4lgFU=ZSHe`_l=qXf@hAa1msPG8Rc z!I&TLlnTg;^>NTx#I=oXcVH!Jb1taD#+!|VAfO1H)dH|(ii?n=qk-?>)8(W#2!x|l zM{L&cYCcc*{SOzwvQx#W0VU>B!2BhGF~UfSUp*(|9wi}e^7ZW{Di4kz`Cq?gZ>Gz6 zqPpMD^Cr6@UePd47KGe)i<>d0ei}J^xUv5k{_5~!KUqThYWsS8jq4iqgMvLf^p?1V z`9YAP_={e4~Z zpv=u|I5Oopp}e`E_T@N-dvUjDHFWRCU4D4lThO?oJvhhDF9o!EV^Z#H!9Sgl8QwZ^ z^S3cfGU&`rfg^xQ5lCkf5{cXwfOTb0qzZFTKWmHU@12}S@v~RA{$PT+j!25U(Gs!@ zRX2nN!sOgp=3yV2G;5Yar7yuKr+PZc8Yw0im%LAy_C{@Yq|vtC2XMq{;&}kIvV8Tc z7s)J9%K$VaMJe-VLSRHz&2awhg$tv#|vhxXqB4cLWBglC<@R) zyK-f(+pHl0kx2_R4fgjz=| zGrma0!!s*dWyPE{-XH%sTHONA#O|SEMz@z|91o9v|BAQeROfS!&l&$u)nOi!c+SJ< z;i4z`HO{X+CLC%kZb4iD+JtUo-nz5CyjRGh$P^+8 z&~=`P$nkJzV^b{rt(_0QWMvygzRR3BC$HTW(eB;5S#z7+5gSdjRmPg#py?!>b0*@z zWDzV(?@+-*cgl&&OvO}Pg za|pv^5P8GoF9lY#n*U7>bnI5I&iN%V=AZdPGWS;wp1$+=@sCku2SU{+r$1@XKm=>7 z__vfDNM^wO+hzsp3mRRj*2r1(PVtebGasY8%Hz zDSWeZ@ua9s6H~us?Kx9gA1OIDzApG;x4acuog=05rsK|L6`3Zr!vQ5SZh5sEv(?bC zs)4l@=V2QNtAMIn)66XY)MKq=qmP+S9)dZ{(D>T(elJ#~s50l84`=<2Bo^^G#!AL2 zdAS#2e#n*&{S8KQ?XcO2Ec((c*!VVh!^h+vL$i>*d`j-g0n2|za%=-I^6`61%PkfO zvC+}fk2gs|e6MY0GBzKMH7$vJSYE>)ygSgW$}SN4$aFRU@Bx#UF5=jx=2BRSpYvJJ zn<)qmWv-}N{^`>TpRz8(3{#y)8e*K=VcMHJ z_|M*QlS8!`MMlb;i-=sDGzNj%gelmRb?jS4jf3fe8apm+F=O*-W zs;Wu4G;*JRT=x&O1{tw4zz9z~=>Io(*~4L3lX*YvYjXPW$0rL{Ymhrea5T(+8BlR9 zI#M9W6#?9RXzaY)fXK+mkNjE3Q=JhV%-wXCagHR@p@ zEv{#og`;hpZ~YMPxhC)AJblt@mWqvo09ScVwmm>5fFV4;g<{0O_~gn*p1a-O*tD|b z65*E6MF60J8 zmK7;_d|pS6V8^I%A&=wJOCfWCMc~Z0tZQ4^YR8*M`seLUc+bL?k(fb*KOTP5Q_5DN z6Nm4{q?&1c$eOyD7>_90zjuf~ijPj~F=y++Ja+2W+#PaCWg;#53jYp^mqfe1^`r38 zVI=F$O6rj)o;%8}+vZ8Hx)B7PGfmzKui^SLM;mJ^c5Xhn8e`YCAb*{v@FQc8qD`7N1=t%JQ)S|XUXQVhk4 z7Hg>gVOf*933-!#1$#a|`G$E5mM}{Z(V)J!W}rZf20(i?fP}2SEW&@0^j?ix4h!>YK{kH~HP7RC00H%c}zF3p%O5;?hfC92??V^YvOh6Qz=6a1Ojh7i;kO zsW|~}^C8Utzv_r?OgGA|*lOF1>Pt$_l`B@fzB}K+Z6-jWh~faf3q>Khy14?sYUQhc zySff~d&FhntJf37{rlaFgsX`rBOmjV?>|4!)TJz#bJVFx9eI_ z#_ox|*=O~5YH4_2gpZk)A-2^4I21zm?VEO}y|hCITeu< zm|A{2YFd^2%Gy0eN$`jd!G5UnUX}PS{I0_P?G4(&SZHxz7Lqbg^qPR}IZPg`e|fC_ zL&I+RE_sO1_sq21GomEba_R*e^48^GOAPR}+_RQRi|hfhRqx=JTXRc0>m7?{U^!t^2wT8jL9=T`=FH5w7qAX}i#@-vU1dsij$X@3+8K;VCW-(*F(;n30U1`Tz^0lFfD9} zR=`e$$mz)fOwsrm7k#)8F^x+QMhR|3gy8)2fJy=Jt30|o>D9?nPWRYTKC@eajnnZX zxR6MI1p-=)r6l&@!XCB}0mS}CV-DxR!W4?;EQAT@&mYu?D-|vv~zS`EgG8qAG1@5AcbK9|SA5-#Fs)@+BxG;5<1VxV?*1`Uz z$;EPrHOLGGVwK(VbGP_CUPXnUWU`AT(gB$E_9OZ_c$02q{=$<`c#6;Qzs)(4{9bw)#2=s-U5Nl9q zM^fd2DH5PWTcE%d1f*ShEO}rmAISt>VVuSn5`Xghzf7Grwj+!t$t@&`PINZX1GwPF z!yC;iE__=RY>Kg4B}gjFBD()bAXBcU3f*+!m!ROw&_VAJFl@E*u|ZD_Z}nm zo`;(^WLodR6rK+Dw?>0QGTAL<;Cx}#kX`k_hoU$xo8PE5y)1$l*-4lR8z7l$c^wop zzR_a#+O+(W4w$l(LZAziOAbJL|BtUH4D0Z|1(#en0tXwPj#kh+Rg}?Q!;f0P^cC=m zcWMC9nj7f^R6cgXgmScL@!tnkyV2)*(b5&6Ucj;R+GA;WJ$jhh(}VF#w6V#fhgDb~ zG?n5RYZ%PtgS-w-Lm*G!kOz8_?-fP-+D-dEmRo9ErAjEc84S9t*74(-Jn<2LXJ>b0Xe80J9_I})+2x31#3nzpp783s z4jZ;^iSx#2${}8{$akQt4DKJ>uX2rUySXB@8a)FMvLeL>ppNa|k)KPrm%-j}0aTyh za<=K+igh#{0+D!XZ>Y&KxTrj0zaR-?lRWU%pBMgY5q1x4qjJ`3S*8+8Nv<(exR`Em@Fb1o9 zB6AsZSMd>a$w4SN=F{UF`ECbm6@j6+=!2ukoxBE~_XW$9VN5DUQmMv_=~U_?^g{&`iLg0}%8 z{0E?sSeg*ORLzUK%nKuE*B#%rl0hAWED!*$ChptK=>){v+`-q#0DNY^$USFhgxOZ= zv6wgJzx?vSeqDOm6m#fxMh59f&x}6XHK53mE$bNm3iO&bdg#o@3{6QVOc0~p%m$R| zLL(%S>6H6ND|5y?QXdT-wQt(5zkYHr7=}3+Aq-gAjO0($JvVXPAUX4+T*O|q*7?7T z)8N4Pbgm7Nz@x|Hq3l~-PDh@6<3@F2RLv9EkHCCS;+mtdoS=89-ZOLMqD8t~G$HDU zAe{1rLu4PqUM=-7bDNi`$MNUk@k6ZmxKItO>jxN^k%W;p>Il*zJr2J>5)=URCe za}`ZnnT~A(;-lCSQBj-=%9hs<%f`Ws9Nfi4_s!Y>?xo`8)TvGzCr{fz%LGfgPDx?e zGCu;4@hBh_1Bt$N#GP* z5(|`NJWI_mwGjYD%_IBj1ln`|YqV)d6nA3JAMRqIP`{Kih!x3NB%c*~-#=w*1A*Qn zVeT2Xz-l!wWcD5f@3EAD=qz^`iF;|pyA1z#w{ zR#<|I1n&*pe?dWw8$b8zw5JWZQfzI0@&J>#MT_miyW_)m6|y$*@Y`!KLt1?;=Yt#Z zNOiUo%zyXc^K_V=ZQz(2z;eNQpG8G%s^DFT>`am7@odF!Bn>BS^}OPfWdUVnZBMf0 z3O%iQDwAOjvlZXdO?K=dgw`k0w*wxRQ4y&>lu>c!fwLnRH~?Rn(mwzp%9;(wqy^kR zK2>SXLVTl=iNCE$R=@{Ke858)u_waL=xOQGhL6sJm-3VIp=yzZ!eRobZ4w8F4$jxI z=Qc?+dB#v*o*#Pq-IgE9Sd9rv&55K#=bWhc5{U2LCbzDY8Z1QbUeV@#O&N$+cn5zb`7#+r>9Bt)jsz-KzG1WxADw zI3%RXjsQHb8Lin~>eqb7-z}Kk@XErB_E3aloLiC7od(ZfIQ-LtjbqHmdwW-akXrPL ze$G1U(hA!Es3R&Hv3y}9Gaqbp?y#3BjUiR?-@Cv_hkhh!F^68Xf~!~Kd)8cND*C5w zcabQWpa83e0BibM_V5(rl7Rrt$lAQ-J66W*-K%b%jy3Gcl|HJyd3xd-Zt9czCnrS< zDX25zGksm{YxLT927*L3cfuoe($7HgODVod&0V{956$afbcF7JFBEEcw}EC z3kZqDcHv}bE3N_0Gq(K$Y9bJJF-Ln;a10-9Q~4F0nq+MBBG;f3DdE7JePTahF-THH zITvtU1g7!^2M|7Ww`c-_={EpPIA~AWr+jn_y!^J7xw)~o_uozLj@#&8_iO&nPWbsj z*pX`@;m^*0Qi1wyAzqtwV4-=gJ4)56Su>k^iCIq0;n{*C5g1&6#jOGuHskuxc1_tH z&Di!Q%|ZxM&jSCQoiN~!hYz;qLafusyB60T%84!O~TOloF1v41J5MBQ2>c@tE_+S9QSQhQV4gm zhy(=oq>t8sn771J3GC9XTWJKhNhIvoFw|@p&vb%T;e?ermuXN!`F2hlPf!*f!#3vCD_4%?;Vf&Pa&%hORYN;?T;Z!1#}oM5@sAOpry-x> z4tRF1zr1Yu@(6B!B*gl^3jpUzHMDEgC~BH}DseNN{?oBzI`;5&4CUsrg?m4%3Jy^< zv}fYdv{kFi<*L-Xh-~rW+hVK*3qPe@x$^M?)ZDDX0=h+?z33K#5OW3bqRdozz4H~5LwJr;RMtgyBGkJKQK38fxmRDi$%qWq5{|=<$ z4e(V44IDTQh`BZV05H36A;>kgu}OzfbQe%(1l4rd_}|y9J4B7rjy=0vt4>WJF-b30 z^f}LFsJ7Upx2UcE-IR4)l9G5=>8kzJn9z-*5Ts?ReC6`xrRdWRLaV#_4Mciw|fnt8z3sPU0(3`$=FLw*DZtN5=(J9dBSZ==P zhrpuEKs3|OR0uYnw9+H-f4BgB;67|(Wp>V+*;BX>9;thFk{TbJ{&jVm5eI|om~;8} zGTymz>C$2**WtgfT|2{aWeKb9R%CSaBEOgSe&4WhBjdtvz(ZEU7McJbi;iVDlpx|m zqnS*%ZYKl=;#jbra{o8#pRm7aEXKp2nF798uSw0#Qk@g;j?$uic6ef?DXa}2xs)d- zPYo%zBngU2r@*4lnQp~V8Ot#+PzfX!Lwhf{wAZp91rwMndV+@d8! zl4;DLdrKZ3F!tb z)NUUjnq$pYiVd& z<4~RaHRTHlbR2lqUZU~~%InQf8>aQ9LPXx%w9~BT)lhraIdtsUL?#oSKrV$&EqGP8 zF_1;HXnqv({LknaC{dGm%fsm_GdFc{U2qR*aP^86p3ny;a{V?>_?3gtq&sI!bHhA7 zbQlkva_FDy1*>(ycC1wTg&P|CcDAP%b#6jCddszI)|^*O$exMiBZd!eXSj0X#wt{0 zfwLY$CThnqx@yzB$c)>*m#jMl+<8p?marw!#w-`|G~8i`0yH(H@N?ciz4^XHhMVxf zhtpFZ4|j`NwB$hX$$h0fx#GkwSV~{AKZK<|2d8OX4p@H&irG_q)Eeb&Qe{;=j68gQO4&w@H|$#e~NEBI~>WhyEYmeOP95dvRv4e(qAq2Z9(b6t}PVD{) znp6#FJ~YeMsDgJ4!2LDG1)7-=U(5i!vhmFXjNI9CS>)#ylol#R>vx`==(ol~u2+B$ zIciEUQ{pRLhjNG;Tv* zuy~&bMuL!p|2L3%={fV#C9?~-w@zF@Je$AtyW9h_-0~PZANWQGVTP3YeWVGo$cCZS(Oaa{IkT?93l~F z+)!`{9!%rIesn}uNWPeX>7Sv+)`npor`C7rsj?>qVZRZh)kqx66jYKBAqNv;bMU9X zAT)}sWeUp!4-WyTDkC#}7cJ`DuU`t`A6FA7*3Bi5!2UJp#EDN68(hwLqs2a|X+b*> zrx!0j(`k8Z$AV%*(a8r+tNs|;e!bJcJ$+nT-m9@{%l2x2R0`S9y4%B)YY!yXnsAFY9J}`qDn@bI=@+CrKoMP>oE}FlPldA%TZ4`z zdc|tHzEIeu`~Y7~_p2F1XT2UhnHq{_%~D4ChBcVPyrEm(dT$si+UX4f()1%YG8>pm~nr9X?} zoY?*I?Cqx`pJ{QEY4Ier2mJyjIhK;cA3gH9#x0+F17s$2^ytq^J9nWn*CL_E2p-W# z4~olb;oXsxhv2z1C`07G1wia@ZLH~&G_pieFrc7WT7TyM5*V#om4CgiflD6Atzd8v z%uIzNizruSzUcKg6^*vuu@d#&BfzBf`0c4Ix3SsRzsS;k3~;c>Ab^*`>gW|qhAoE= zpNFNh4IQJKn|*M3mhW;h&k1QCO7A52k;g1}4QRF;0Dx3i%i0IM|6&!NdYK0O zH8U1AS8bm&VatbUG=inN9CADJimFY#LI$}Z4?lp8CFZ;dc2Beey+RW$zZ9puLw0bt zoY4C1-Mcq8;~)C#1_9{=Y@^rH9`&z9;sl{Pdi!VtGqX~~X4mf09wUDt<4GNC?xhwI z&G@l7;=bMU}{JzL#+ zQR=~96*-j`JOJ48hp1ZwGEEgZica8f6{C&4f8_Zm0eCH-k(S~HChe#N3Hx^M*a4xs zG@~wOO0sr58TM6Nrwt|tG|`z69Dq7<2ypV~2YLf4;tea~t4 zieJ4O&g0?dQRGXUfn-u z9Y24h+$d$hjvUhb;&xGXBRG`s2;wtW`GjdfBALwTWsQ%=o(~7pf`{t#>Xh9Z*4l61 zKJLuAMbs;CM;bo|7}stXsg1vFdg=1zMq;xZWu`4P)sZozQ0W&F6TbZkGKScdMBBax z2YmFRG_HnICPiVvV3JvYBB9D#zzUoQXghc;c}ACn4hg>d|V@t(T)PG}yA zGmkAL;S8?p(q=*>V%X~Yuv$It!!-vH}`rMKyni&mohHop3Uo5 z>w3Y32@Vadc;?k@4Z8>=sl3(P2SaJNG~lO7QbyqkYcMUghCDw8<9vT z`XxlP!b=-|2j!hdRRr5zf^rbsa$c1vm@3cNnw0YFt$cr=gv<4VAq)wrD|14yoDY{u zLfPLS*$O!1nV6*s?k#~fImpL{zOnGGBOntNJoxg+=3i)>ls~isnO^`d9&*Fx(bZ=Y zez%|y(pDFl;GtQ$KoOzy1g>WVnT{`SjG}|0S_K!Xk8S+S;N~u_HJ)T=i=&YPAjAR! zDZD37UH$v-;wDNr3{Ie(xy(hG^~Mxu72|daIcDvEiM5-QoVUK|NIHE#zw?G`=SlM> z7tzd>1_QG)!in~V0N%*q1Y&X1rZ_5aAw(}nc@`uiN?HohS$Y3;kL*Lj-jJ99bL*Vg zcT}GEMRb1|Wo7QAC9vhH)~`gLsL?#-^_bIxoZQdwF3Qad2@alaxzpwC`}gC?S$lyw z4r#L+v-IF0Lx)z3>kkR%uP09$A1->>%*yJVVQ?0#JI7OB3hobmKr7N@$6-_$Z?^B* z12P5&H}d_Z3$uSkH5!(6f-)s;DtN{~pDARJigptR4H`ZAs?ZDg`oZ^JF)rJ{?3;vd zUOG|fD)Qe1!gNy*$6F4YHdf6VS!zGY>)}@) zI&x$@!*$^#Kd=KFEN-S{M70}>z8Fzi-}r#ju}9QnACMVu3h$4^Dl5 zIX(T^-bJ~Xpj0wkzI4fSazfmNgX1p?5P`|{DmNoOCVQdn)?M#5GC5wy%G!#j8;lzD zV7b}g(w>y!X0wZjz>wO&y}I_fQ4)A-<246pB+l!ck#x>v_3wF8%RDHr?`8!Sr%}YG zaL^csl@hWucg*CQyDHPUk0;fQ(~R-$yLUg*!%R667)5RJjo}6SJtv=$Lr!~SJ)Sm} zD;f7@!_a{Pll*q1-=l^1yS*#_nCl>bybFZCRJv93<*8nV^<p^xv$} z^;_LGhz#dop9}|u*syS6k1gpw0eg_Z9)*9!Jxdi@EAxw6J*`}CuES@I`aK1Wn@;k5 z42~yWm`jClSM80oAhtCMlfPjPF#{&Cp2_HCmlfg~r)(Ng`E znYE$Pp;F%bJ`j0_A(3nta&I5W7&3jxy@`WX!P*DY6AO-dO1^js!sJElAm$#l9G26B zu{%YtI17ANw)`}?RW!0-_9G|2Icd{zEkeyCTXwSi1<)>s`|-IS8t?V}{P==NAqE{C zu%9L=hunCUDl(2?1(p~iLf2klJOO~QYv%&j%2ZNp-uufw^coIZR+PJt#-7?&^mYd3 z#A(0?P`>QFbed?GxFK+D)&0Mld#}>qHs_A9rm%y(y(W(wQ)lYnc9c7qY}IFu`5Y$? zwd1grJI{V?pnubRL@RLsY$dAH2#A4lX8%1IqWE(LvDr)YTa#{q8qC~Fnri!ATi_YY zYp=<)81`^OnIp`jWdam2`dW|4xQ=T>;i5%e1mv=~{&yd9c76$Lec0dMp@9${t~xmN zYh2RB{{6_*;LYdvK0)ueExn~fq3?jTTUK@>Ol-6rkKIcR16KX@loEY7vTe?}T%tR32W}{@A<#z(1sbSI7PirD z1(8vUgA12a@G*!#!6Hdoxk&oR&F{8wEW~ksc=}hqQp|t?s_XAb;^7wSWDoFxN3xB|9HY zLcksb7?B644o=-}fai)gMwL<5`rQIBuL@TN(oXeWfe{1W7w0pkmA~8W5$@J4w>NG; zxUWMc>q!~0rigGLjZfse_bq7pIr=?7V&p*MZFXZe(%}$l#&HmQjq( zyMZSJy?4od#V=Pg0RlJR%PY>M7&!*nNK3r^g$Q%I}9V3Prz+Z0%nBXr%7R*t>{3H66l^&>)aq zW`N1ev^~d;4U&@%FdWlLpVvhUYhYjnt2TnuC%q9!D^O#B%{?3M5rjIq;fOxR_*-K- z?r_$Qvw1Y@vipVPLvAfi=)MM5LI4?n_(F5}#jwo3q#MDWl9Nz{B(dpF(8f0@EzvHgeIa89-c4ny-+n1eaWz_NGbWryU-B}B;gTrDn#2YN zrS!fzV90>q*|9>$FqWx`*lKtbmSVaGR;ERmPIaUBpw8pQSunHeO2RJyEZLaoWotK9repHcDG+` zw)qu{{)l=(W?OCT&^;}{@`c%1UzfpcF48Y*twqqNu61hHF3-3dcbDoAJa=rbQU$E9 zAvhz@_1>ZnJX3LD4PEeZp?yOPt_P~~gzY!A*o@7aZ>91kVA9Vc9)XA-Zl~yi`xd8B z4L)E&6qU|@#`28aarKW|e$;RJ^hD~WcHTD{)4iM{kdm!y=70MYaBQQkusRP?JyHW) zpqfGCw~#5eY(&_Qd|91#Ft{)qEd=t#HGjzOS$EmoF}seuUt`# zw9^G0ok+1I&N+u&8CN-tnUBMfF%mIJtD)XE8x}RJ)`&u8wHd>D9Bo=`mwdnALQB3+ zGEsILy%u;Ez^bv;*uFB?;i@2?YniX*qt#{JZzSz| zasITv0O*_7Q=X2=|83g$5mRf!-j+AVp4g?qk%7fUU=-Q*<-8k{&%{e-YeSiX#Uw47 zpe_u$$XOb+m$^}O&);4b2C`0sqh<8E_`*PLs{$PdE^^l{QFy~wuTEhB%|hN=5>-10 zds&cBEkBonjPHY0LIV;AUwY5kdkOJbXINtHi@rmS9E@R-!B!@f8zoLhwfqYb;rsZQ za2H8S+0+%V2wgPp-_mIzX|DKBUhfa=?F;O)xq~UfO-}JtztqBu&u9UqJrQdVI)OZ! zAoWI#NIUwFDpX5%FslS7rQcJFD6k$d17z&=p_doVpWnv&1#{5PA^M?>avF7S71Op) z5yV&{0|C5?%U~mR3pc%0!-DH1&=j-8QUDxR9Xw-NrqU><_bg89nXxJmqbtMfSN7LD z4npk4vIH2_=CE~33!6WqFHfnp>_Be&ISi9Y_uI(V^TR{onLyeLI2e5mpVB!;45=EaX^>imQ`>u4j18m*X9eHQM3ua7=jz(gW;1wc^qQ zsx!x-n<0}^+|O^`ydg(dcfZPQ982Ow^%_iV$1{5K@|d_k-6z#C06tY9o;$r=kZ){+E~mLgu-S79Y|6V@RL%vJVuWq zn$QRv=7HC79t|IVISnE+?1MI}z;LRCD}{iqtp_GSn9M@@&FI3b|HB2)*{2`W zlEcJjZ>84zvcY2*ZI`4wzFDm5FoNfXWH$4-{cJEwjRipFeI*8*Jv*BqqOe6b-kxp~ zDMeRj=N(tSeE$o-LB|J3nn$|=8!w(WqBC=zLkixe*Jw1#y-EN=(2^O6O|fU<7kWaS z3Hw;7WFYA30|jC+KA@hQ&WsP7q(?-4Ad|gY17dhX8Q%_S0kjpcy~2&o)XKu@bepAw z#*IE3P@&D^?K@>S3y5wvw65lRGDKnP0SXa$=TWa}8xoBHZ!z&xrMG}k7mH=P!hoAX zwd>N^gC;NGngQd``P0PkSj&wWlVvgOC<*Zb)6(`+?zCg2^v1ZSluJjd96VZ%@&LS} zApNCOYP{5;HXE28mxjG!)wu95H{Yns`wG@$C%w!GF#&1*2w$*xW+%W7eIoha!1mpi$lRIt?4nV$}Hyg`p z3$5J&5@z~O!|YB)k@1Cg<8v=EwWgr}L-H)4w3b;3)S|s-2fj~E+KaX?sC}rWg&YvO z`XedSRdMpEy3&7!|D5IVHa5GGSwXOX-it%%^~)s-pAv_g9`HFMDdm87B-g=7G@`3)k)7 z$w?F*6_>TggE(;e}N zDrJfMsAV-6;Htb2>E0$|*qDHjeP=%}$uo~|!JhbZ5AqQ>5VX7l!6yoDGMS+gUx>Oe z*U3D7@DCHmwl2u{b8xMlpwS`)gToDdf3Ul-@;Wx?E>S2Xa;SZN`1#Fa7elq&TgA4c zH?FO^w1Aq=?T3O}G#c(NSN%+$H}5!O$F+&OK2?Xxh6%-&C+U7?`VW7}Xp8yM&FC+7 zA=ZaZ{+W5>UQYyQkUcph5d(*KVvZ6*L=}!Lp&>b*B_uY7osPuRag5QygHI(IFn_3> zS4t%&5GGBQQl1cUvtU- zUMAwv=+!`;ImACLIOuWKzYa;A-lD7lA*B}$16^zJkDDM>c12}m(B5XMy`=m1>jKig z-`X{efjvCnkK_*wc>c*PXk=}TEz(e*I)kXt3fV@J;n=BTM-5+TsmmjSav$vbxuEwu zp0O-<_&yjdBs1JxN+guV!6=PDEw3wy`CytOI}2rJd7BL-=f=tSQ6Dan#)j1S5`=LJ zLNM~;z8w$mUbK)z{j2&-?&?**iQew+CvW$$oRJqJ)h%>h`m;t3 z4n?b{I-GXhMe$`Q`jRj(%ep0MUb=l_{)uWY_Xj_2^+(LxC z115fMTmq{Hui)NDO0M<{eWk33I&|uknRm+0v`WkE)=z%m%XgUlx*>Pgd(N~{^xM&y z?><&;vh3-RT-Gk_Nm(^4ZUc;J&6uE&01Raeub$g2$-;&OvGV$rm1ez;Gs=L8P6E>V z{NdGdMjqq1ElxlD+B+wt?vO)?L=@$8#?ztU;a4XvjiTp~(J^5*vfmFULG@{x6FyI5 zR8I%a(i17Oj9xjyV>ZOBYh{%-$j8RIpk`OIsZ^ex6s>-LoO|}xZN!KQlF}eJq5bd+ zsA%NoH?UKyR=p<$AmguMn4A{fePe?_Hddz%9aNi&oGq6!Psd)eu3uJK9j{7|IHZV> zu9zM#hmu*HBIF`I-y7{ZXS)%`Ud*j_m-gH7kO-`H5R@S^_Q7t4%LG=5+D)Io$gzd1zRk=OT14I)M|TL!z}`6{byuon?zCmv zL{GGUQcuGg!hpqcMsMFo2gcLJvr?*_2<-F;&^y%@%TSztTObFlX`h;_e0!4VIgqclhF<>K932u8%>qHh~`9+e4|&f zZQa2q=d)lQA0dNwqXk3a$W^BXVjth3F!rPD*P-1+0gh5@F(m+YT}-+u1qyYGk5 zGbWWd*q^II)UMZI`nHEJC!MY~whq7>t@+4TKZ7H<5NRMEhm!uDJW5%`C8my=|LUZ_I+N7Y|O==EmCnGjW*&HU^7;?;_Lp%()6fshWGl zjyGk?l-ULrjBLs|>cu{$skADIJY%G18-~6g@eU{t50RMr^bcBW1E4AYMXAVG+qVrL z*`-~@t9 z$-s>YVOU1#Ivrp9$eM2CKSi|ZP%1cLa{uY<|8alHcf10j(6E6wZ`tD0nfZkE>t&UH zhw*?;jHoT6SG7@0DHwc9=#8(MR;GBQ?yXJjhtJbEOf9Lv%s|UzpliRfYf0Z@{7F+L z$$n%iS<}pH94ns~*9RUNee#Um_Gt?#^XO7V^@m-;q};kPkAlxGr%TAvkmOBd1w);A zBK*dSYqPD=f`A$+sZ#tZMV{n`!rYuJw#6*!1(}6G201kZ*^~t6U@;<_kf<(Cx|B-cB*b&_fRP03V(ik{ILM4%cH_on7;co9 zsd)c9>GX=fwBv!Z4%tb&ha`-qfdl=4(zN65%9Sg-3QI&~Mf)_kc0brtbAMjkhH4Z4 z50lOjv?6Mq$Ts6BZ)D(!r3e>BmjA#P6+0&v@b@R(y*42prWCqP@56Pjkj5%9!xVZ< z~IDqzG!iu3bsBXR$#HZ(hD)as7pP*fE&ql zqcXvb@rjWEE|U>3w=j3ntteZnVO`C|k?hnk57H45U={A|5+WVGx zWM~oZw#@DveArx`%Van8@%eXB#Q+6}8zHL;@LH**0hSG7>+qXXDCSWJPsi*QEeBG! zA{0*$;yJA!62<@Ymo+PF&1E>g>{t2o>n1L#n> zU8Iv5L-XO)CJVfVK|psovHQ+Gwy$E9 z){n<}X5A7dV^x_4zrpsi)XvEpF(NNRfwI}&Zwc^b5Wb2frV%8CeY-BwNgpTQFx(oh_Z;P95q%a%a@ja@Oi%lN8faL& zF`ly^nAsz>;TWM-*f##OX8Z@4S<<|Ek^I9}^f@m2*;i{OPa1c{O4^!=lmx=-d6*%< zhODzvTck~F3MV|irkB1BdE)_0ZWS|CFVqs7Rg8uNc{vA1j!joHWn>_Y; zba|@=@*g9!5;OSHSNt}cO{DgcJs}_D_T$WX?-}~iyfI%US53LDT*XaN`wE_R?0Jn| zu+Cq@02uub>hOAymV(x=H&@wAm4%G4Iqag>nAcWn-~gKb#Dv7_b$joKF{dNoRf5WF zPGpb+o9e#tr82Q#5LD{jm`hR*%S%O;DWIxaNI?+M@Co7Lwjoyz_i|s${3X88isBW_ zzNkZ$&?&+>DguP@BPkjEQt_d@-LvR5E@;%<^2D4CLFHB zSfvBAcz#g!_|$T&Q!US@EEAFb%)Y*9wa;d*7t5EcWNvVXSWaaIA?dEXBk-7lUp#om37C4CE-TVc8A3hx?P4bTIaA$;_XHX(4ox{Hwn3 zsNk?bn3tNOIa3vFW|8dRAmx3vk`aU`m8%y6r zbf^dyoR&lT4{;Y;z*_}^v8HGuGiH3-7t7{>r7|WC{_@kAGiQ8(V)btw9V5`KmyGnQ z$(b`5{M~c%7?QN+8ed*~U)d;7n^nFiLO=hl=+_(}sEF|^2Yu&(kVEAH zbNC!d=9!)H*K`sA^Ao|#RiZvFZe`_s90UetvJRubPhOq~;q7U3G=YTBM+wk3_lH9# zPO>gh4kR*GM_|eev%{b4YbR(l3*TC`?7(ceOfIBZ6nZgva<6Z19c|lQ@OKXaU=%g{ zh4hw5J85A|nUbJT3MED;J=O~zG5D2#s>rV3OWQ9%Nj)yZ|Oi`Wi$`AvV zD@3ZpBxS`=+J#OEsncn!%o0vdC1f(kIY4=ct{01%9YJE9Q}WHd{$UUO#W|`es(0G& zY3FBEmaQb_xzc2ifO>#$spta4@j?d)ZzYuCGqZgKt2S2(Tn6zuH1QZ>yK~>Z<&^9* zERVQ|si5eus_gUU8v~QS9-_nT0O@#z!p}egDidpDP6zD+*v%ug(VuFS98w-Uuw-JS z1(TU>?);k8a&&eqd|jGq^)k=I4*-(O{1`B%@0`0U{|e?_R-tw%(JeszprP|f^|qxE z6;=!l3a)7q*30f~Xr+03^7g~Vr#U1URKfCBI(&ZWw?p_@-l5!B@Y3{M@ULjgoI!>x zS_$m^B-jrhGG_n2^d!1as0(DKpa-c(1BZO`_(s8p`%oO9)aZ^t2idF=Ac&SMk>JY! zEk+od%GBzehg znm?HXJR<&5rmy>6u9K#SKrb}ak2w_Bwk?FMr+S~~GQ)DWOQa4D7*(Zu9jd|1tL)(Y zXU!A1VA8Y->E|b}>LJCU@$;m}gxiN<7OacZ$@PP78KKEDg z8f7IXrV)9&?&0MXYBUuofDf~|bK8~l#kC@xvNp=*`ONvrj#@WF@J&Bd^hiU>W+0P(HFP9V3q@z zx!r}oI6`b|QE&pB$ziO<8+K0Vs)EZ!#)Sj+J zvPYqmFg$piL9#=Y-2;3*znb}Fr59l`#eKJp{z4@ufeD1)3TNi!!Z#8@O6yoO7T{7K zLbc7QX|=F=zAsYJ1jWxOYxu3S);1)wOn_4VQP*n6rN`#ID)^? zRhFZ0WgqL-yh;B7mFX-cPNjU(kOPP826CVfTKD3G`}vObtj%p})Ut{o=`Ey+%;Bv+ zv+uR^XXe6`9$x%xT2ZjJs6&u8(1lohZ{(yJmg^=129lsJn-V4jEv- z`qIy}#_OErj#|YdogL->iSV1xx!-ciBdA5D{nO=JH#-LiCVBw(@1J@&l`$_%X)Dsq z)cax1;WxuM7;w9%H&22r8M<@YO3E{dG? zJlKCeYf*VmVj1=yIkGMe+rf}|_?vRQ#GpumHZ6|%8f4p;>Es~u%we?W1i3>DSHI0R z2XR>hcgrT-4ekP=Tbr;{dD2`Vm7GPB*A;~m^Y8@%$R|Wi-bFDwJtsvzG2cgjA&GLw z=W|VMXB=Gq8-=#Em_kgB0>+`GISx^U7r$rTl4=8|5scI=(KmB7i5XSZm_eXTqUhJ! zXu8lw^p2=0MYp5Sq66L_s{)O6X-mYTq9J;0U)?IKEg&&~oUGm4@6!O#$N@HFoa#Ro zc7HwgmA#KUe0U8OL^Cj%%Y8N=;_jG{f4rp{yOGauK9K-`bt963WH_7#0}#0wl~C&F z8=T4x-qG**NPDXYJd1j|40g)rDzKEsh&P2|&M4D2H}3dxbC8JA5$UOXkH1R~Po(?a z)sHOCh(K!~#43x=vAu}dgz99Of`G5eo~y7wTSp|7fFN{W#N2XodvQ8|k<^w01$Jeo z0?8C8%7vGd`Ns7JPz&@3`?|UeCMjk_M35nCbvap#j$#=bIYbr%L6EG0!uD@Z3#%Ph z1z1xpFySs~7l_Kze#j!0@t|Dv7zq(HLZ+_F`T2ji0N@K^uz~(im_4z#_bvk!1u|4H zaT}HG^=)@+SFp1CR8SDbOo`NyWBlwzobt^_){gt z96&rTqsO4RMO<}vz_-&DA%m#=30tjO-rf<3+NrJNkPG6*4z_MmMT z71A2Nh^j&oXg_G_Xzs30>346~;K80$7zCIgnDcbt*RZ;Y_c}7E&DhhhrYO}nr}Q#` zF20n*k$vjb*=~R}Qc}e?%D79ft0ijclEfg)^u=3UZq@&1$bBu}pRXaeHV*+|g_tme zwssU;a=_zqhGM`I_2I#>X=7|>g%sF$-yg_psf_%Al(}bEr<4*M>Znnp(9cw8{vbi5 zSG;q!0h=&C38L5z$Z8Z^xSMK<(X$CXGs(9H!%dWK4XIBVQ??#?v=UibVN8T{KM(6N zG*XheDdaFp(7p)@$*HD+n@p3+qG=`egic5*GFsLiMg*di{G}f<$TgEDPqyyd`LyXO z*};T0X>&o-xW8{SVW_IyO{>E0l2T{}nb;=zoi~d;v3wo)VHX(xnEEBs zo|VQYNyHn-DVR^J78pav$4o@)EK1&ocAaxVq^_BI>D#U+=YFvVR9Q%r&s@JH8H9^I zwZpIZjn(=iNf}3khZyptU7Jrfd<1;yMxR-?i_DjxeUunb_4RBPLCag2IlnY1(9`ra zV7*5ZmGa#hv`yool++0vNM5+ubP$>5(W^+60z*cnl2Odi(DY~Q$F$^G2zO#O(KmIz zvG+U%ca88ao$&oU#^mXtPsrwm_z|V@+-R0MG^BE>{h~^ zEi6PWOglcbbMlt)PDxa8cJ7v2Y+MW2Lbz>Si#j~g$}NLih9!lomuDk|B&|P zVL9jR|NmttYbk5CYzd*kSVJO{wUm+)!kEUIWsN~5yxvda>g88S7Pu_q!U ziLvv2JTEh!?{XZ!zkZJUv)nW2y58^Ca-PraY{tsqTZawZKUQRF@k`Uu6o6Oh8&OFL z(}6{6vf^af2ES^K9_Ys46K#EYecg_>^`*wAcmk6lE2a!9E1=G%w(?X;v!;LnN+n!L zs#DuG=Wmk@6+Llkq)6};O{}Q)^yNVEPvVi?;kmcCG^B9Bz(`a090ChLHNBl0x2$5} zV*0Wi7%Cs%&9U)l5Cv6yh`uy3&KOyoyoRHZ2wr)JLBUuG3t-SUZroVk#wG$#y7dK- zXArPGxr8MQLfV+u-K*h`yK+JgAR(^|5q*Y&iNWc`;oZ1fr`FlN2)_d5{s>3_Ig=Qg zEo>!u0c~JixHVbrdGSXg2T!7^llY(R9gP0{&6|rURn%H?R~l`jm>$@wc_#Tyn(zSu z8h5<8+X<9c(@7PPnYWI1h9Q!cO64XUOw~1R$l53BIrJ$aJk5m0L(?r)pVCR;ky;A) zf@(u>I2R6Hx?a?Id_vUW-(B9j>WUq_BNe`81xR&6b4RZ3)-x$3?C0(mme=#$lz;XYu#A3`q0^hRU>U1IL%uV@w1K>}_fnE0{FW>7fA2SPoU7?h*f5S~y~Q`3<^ z_VP3l0lFsP`)e=TrWbO75{cIuzUt?=xHIg(i_~ePWh#&hK&5HZ-L5$Rg{&u*X&?AkYwjvWWL5o5`Q{P6{bMH=)LQ9;ca88+ucxT;oM(x0sZJpgJ?F;z?8;XsX^ZDKP%RW$;{c6|)rkH)? zE?rhlrUSM0;4*w25*{Aj&&zB5>%7bbC^f@T-S44OlLtsA%OBKvUPJ9)9}T%N(9eDj zr_auT-~_T-Z2*B?wQ}Vs!&-`T09NCB+P7~d$o%vOLe3rR{W$CNci-9CQC@S!Mv>cl z{>i1~RFG|`9B_T!WU&k-KGf-OXCQGhVeXuQk+dTwg^K+K;AZH@eqM(jwIALmpC9&r zdDpncI$UD>+hr=tnz2{D$4c6wYu8PyEEle5^#;eD2CyM6Sbx6UJ#cU1+r!z21n<;1 zUxrEc8$5WGeiX~s#`Dn)qysl$DW7IvAoVQdb+*T{&ojX;E`74Gr>DY1I z%%C7U7>%E|Z@;XX#n77evOUV!L!_lYDk!)DT6QGT*$XqmoxO~pT2uHg_>ru{mJaLN za^owRh>g1G5YZ)M_ps*tZ`G?^dsxVW*CDT)#k-PY#5ueB;LepRuQgqgMC1r@IOKa7 z_I&XxIGK}T^YP2PQ#UruifY++(4u<|miL{rDpV{p_J<~qGOp3fPo31V+per@E&7j7 z%I)5Nm1E{F=H{j@-B)z&W$WF(`tyRybKcDEVY%gWv6)@#Eibw^`FYKPo;4;H8i`SPlI-DZ1#zWIIZB_D6^hXyL{PA?%MG7gWwd9Bgr zzqXETurTLi*k%PKuISUKPrrWVM^}%%48*K{63J~L($O5WD(7g6Yd?FBv_hyqF6=>s zyr>>P3lIK2>%r%G!7qx@6LIJ)+qQXdlT|%zV-z{f4}9$&v_C8Bq;Jx@y@wB{^A{DO zDbz?E&9VdiALQlrXZ`EwOVe2CirM}*zFS5n-60R(JG#B0FjuE4Ad<{KZb*liS8itE zC21F%D4+zIK7l3OYWhhC-G*%$Q~%}TH^^5O5E40p56PjLk`R&HUbsGxS9ahRP)-#V zP{E6L?V7kLiwuRO%kAHng`7>N+!RuU!K+ipZ%y0TOKQwmM2flA*o3%T5(t)BOTL-v z1cZ_!0R073urFCIt3O1X9~F0bn+G;aL@PJuiHt@V^A@8V>fR>PhB_|0hJ=qxs5&!r z_FYKlYv~oZA38YcZe6mNq&Ubyn4oG1nlaw;esu^l-o1U{S_;!4?`~oD zHGn2~<>wz}6sD*_ia+6a_cE_<0glZ|?+_Kn|uJfk6)8te*$)ta4K60dw;ukizK@)32mq zL|8;#%}&$u3=GTd{b`ijRE0)Ut?=c`YuXhkq*9KkceDOlH3;HSNgDjz$yl?4-`xI5 z8gX3zpMS{_8wQQrqsgkSQ@a64$~p%Qv;FeEa{co^gsyLjJVSlGXhe)xq7iTijsj1B zx!V=<hmv))~z}ruRy=*~u zt*jMj4xgs&D5JDqHG4okA(}kIp4Ts>hW81yTUSB)1Ky&BIZByEIWy^aVQEhZi*!SIgj2UBCj9q%+P~R=Rz!e_g8nn{$`+~WB*~m1VBTQ zq8$J9&tHnE0(em(2*UDFoF_`p25{ip%qP9FJ1UR7ec>s6%Y!niG9`X*x?9qvlRh?lF_U9T z>8;yNjzj3Z2!vMXZ7c6qU3~|?n;rM)GFS^4Uum#3t&!O4&1&nRX(=QX?)ZyUvrT}K z1Z+ygg*;Iq7LslR2Y12vj_cMdD|1s77e8Wnmg5@fx3+aLNiCh~g)F4-j=MbH+ZJzB zXKizYIZBEKGVZy_*9k)fnm2i$z&vCEjH7^Mxdm_XU6KM8h~o9TWu0AofbB$$z>elW z{OM<5#RsnsU%+=qpg{Og(Y42otVTBLJ#DU;6)LaV5d6 zQt9NB6#Km&4m(;UAL`G0rX}J`TLY-x@XRp z*`pcr&9ztqfQ|M^wm50hsW5M#&;t;7bE}B|a)u;vUM-B#?tk8L{l*4b-kt2^=-7_T zh0yfZRqw%Q6^EGque^hYHOZVh?b!`eU}N*6 z6;ifR{mEHKzoQQ&u7PJBit)Dwv8fxyIb z(DcaT`}|nJDBRu$YdO6<0&I}O%At?hxz7i5iO+!|@AKu^HIo*tPkU3o-6VXjH}D8Z ze#BYa^PTNk43unpr9w@fF=G*PX~lVfFo%SM!1ahKcTG0uKVp>8mrJxqUx|&b2g4W1 z1v-ayWZ^VLC1BfI_jkKcZeOE}cC#iE1+zh(dU5=+AU?%j0cHn@oq2yqx- z{w;Mj<9Zgv*f%w8*CN?10?bOI1(h77TN&Vq^G?&qu%YNg5k8GJnR)!iJ%mK$(#PF3Vma)+1c(iz8 zLvGquTLKbqapcGmCDrOMjy#|@{j`P_f_FSO%N!_#Thhm?!$*tv5KPT6#%-NPR|4+~35zKl(H z&X-TyKK}JLDhuQp^Z1k;Lwk^g=~jWGz-9XL)m*a^trsPQZBF34U>n3<9dorR7~V)! zA$mcq=YLs}`?TsB#1#AX`T7hR9&8o{5D}Rh;8!zDBU@dD!R2HSxfcERlI-m4O!5m* zvTi~0@fJ%Y8}4+>$!gjC{65caP~5Q6cWvMOwPV&=XicN0h?ws?vp-BYUU;Fl)(!h7v;OtvI4U^c3c;`wc!Erm@mjF_ zh$i@HVxorZt^1}76r3)6W=R*DI<=_u&cu!~Z~;{NznbO3r;sd+S5TBVXE`YhON!+6o&fyX<0=W>g1M^6wAIpA2(_julG+y1cf zW&g&}6(L;i1{YO4`R-9|jbH&8(C=jTZ@!WE8EQvDtozTNEydL;<8wgj@eA`3k7_N^ zSBzrk@_=0@*5mM#cN&KWy5>_C>iAsWF?4~R3J|4LR9Sre)ZXW)s>mJk{k#8Z!&QI> z1xextbs)Y6ph|wWPRE?Ato%Q2b!|qqK@`y$cu976G56Y#6=VvD? zExVb;yH)Qun?+rt0@2_Mz}6SZMSmnu!OKO%RvP36hs<(pvFss-7S(z-GCOnU&dK4v z& za3SM2H!=yHo$TS5EzPHIaA7H9!8~*3NFZ9V;u`ho+Z=(R1k1>a=%VGu;u{Qqad#?k znG!U4t=(;+A84yVqr6QEuJe=u*LQ;QTM{jPC}V~KqzG?7VcP_>qf^c(uX#%Da8yF1L**jli?e+h}f1u$7Bz--?(w3R6z1x@GKPl z0E4jIJBRw@9GqCni5~a3X*HQ{cwT-EWG-DcT?TEvhA;k0EQQjIhmh1+!)Hcj+|*DF{tw}x6pSu z#Psan53j-dfBsf-M9I>nACTGPVXp~^!T;R+Ud$yS7FSl(6=b%7kJ|k1yz&125!4!f z1UQlS7<|9A3uTBVx$4*^w??G^pt5YDkQ6@;pYPQw0V)KT5=>!x1G8`~EyDOyoiA>0 zvMEX_qa+7p`z7}83lW5Zy^sw(3hE`}ZPcpp2>WJY&i@qx{U7IXe;GS&VtJJ zn&TqNM2|*h<$TOs7OdxBl`4&M*sD}Iiv}q$h(SA0K`*tB~nKO@TxFF!VFGBav&X=9=)Y=_5gI^ zz&y*LSYalHr}`9*H7`ZmHRh*3XlMPf_n@Lq$v#Nmq39Q#>a6JVbBmRD`piBoX$G1= z9(x2xTNxS-CA7lWZHbF31`RaEGlfD%PX^V#Hg+cS3(iuBvm%ta%Gps~&wt8{8NIb> z(MfvMNv}c*WafU1VVZaFrr@qJCscvGdG4cP5LOJgFz(5@=+5k{6U+9`{%2;bcn|ZQ zZjSBL<96uK!TPV8X4#2kUL1dOXBNi!^9VW?(1w)tF=JJ?D*^5&q77FFoZ~#+FJi%N zMK#Ev;SZl?ysr*%@(pOH2PIS*u&h5q0G+u=rACnrA$2(}o`tsCFTK-64>rnQ(3A0a zsa-kOUX>y4HmLzxbs%yy7P1ZSOT)`0 zv)~`DxHQ^e*y~vVkvw&oW|>o8WPIx~WOk*+VJRR6NlkRoQ{!VtDeGf$B7U@8O=JV1 z&`%FIgVMQ<<4{jg81mD85qpo;8_17dK?E*+V}oi-c$YZje78@j-MLu6$)TRH0>b}AAczPl#GyY+_+~@QRdS1v?-Fw`)yl>uI`t{fIGG!vGR#*}T zdrH;9xwK-hjYWmlK;s z%Dho}2`=(D`SBG}a@lB-tf)2Q7@O|Z&1LEu9QX23G-~9SN{`oroB=R##92!Mo=`MQ zn>LNTmKWVP=JH9M#7^WH+q>z*ExeDJ-7pqWwqhtpPukkx10PWPNb{V2rAn!GzN&eyyVVT8pH8A=Llm2o611{lHwOf{Px52cM-uC)4QOw#~=z(F)9zo(o$L zVAdZqKRNz-KBvylbo*$8D;dyK?6@{khZ#S_?8vD2M^BVd!d0(WBw1^pxemy-p6?j3 zYcJl1j4dmz!nOwXvx@58WEIny2i6RBUAT%kF9N!ERZwh3-0|byHRlF(`RG;~z&WG9 z$K5^Krqv6A{~UOmrxTvnj4<63y}XzKp@3SR&WHOnN~zX5_~VVHKHJ-KVZQ6_kN9Zn z@-NFs$}0(-p!It7>WXf2!fI8f!SRpBBE=j@v5%+~n@{VQRe`?!zUmiR|H9uo7u-`e zv1f~FM_XvUj%@&I#`xmX;KC|_6>q~SSncSJ-c9L;DOZ_wnAHC0BreJuT+0V56+fL& z{da|_A20f?^T4h@A^U_iUnE~^sZz{H-}zg9(;y4TCjR>3a`Ny_CG=6JiUkPIKQOe0 zf$^d1fqs;>2Aq6Rb)$j&@e6EEv7; zx28>Y=+8UM_tbC<45tTv7wH?Ax?%&_yL{xws8imSXpbM>+f{Y!57 z!x1lBb6>2oTDrBv5Fej9JTk-Qf>QT0=2>fj#Wz{1yPU(i>Yc!xiosAL4lxeDUZi>x zb_hf_lH2-<<#e)xS?2lhz<8tU(oU6vcU7rL?u{wWFo#k=Z96A)%8Ap|+@6~B#YRio z=R+;U7?gB+jxSk7eB}o)_{Le^M#<*#pyb%3`)}hHq&O#KZaV- z(aIFXWJ=dHM0KAtWK&CRuDQjAYHn7+36c#)luin>;U-HqTW!KEPKgI)SS+f~Ldxbd z%ovj8oZbPA!|-tnx!BPVR8p<389j2)gLp3obkQ6j$nB-4s`VQ-*;>C zYBj0ixkXKuj`o`7pcw|$X_*#E*{Y#?* zR~pwhZfqah7qCjZa|ZrO|IG;gzXM2R(w2mbD$Hj@@5(m>r-w z^s^R4cHOB{ru3kQkDfrx;At+d*qMr+5oY_AtBkgCcc+~(Ny*YZo2>yWa0E{_D63vo zA+j1^Sb&auxSLqe^R_pMe=mv%gvv~RAqnyP{A**s6nrY|?v^`f^{B46U^D(f$ztM8iox(A zWtVanR?2_>oR>>Eo0A$qpx(nllqU5IEdz@IK7IGl&jXZzseoRfpB?{rf={9@C~?o_ z@FGYl8ThVrxl1tH9&`^vOCd>;V%CS(TE#q9O^W&&vIay zP&={bi{Ea;8)F3p==O1A=GwVYZDOxBJ#%TaolZiY!UbMNB!I^K@P=-DSt>V4G!PKH zr6|+rbADf8bl%2Bt1hVq11!|oFK7ZOEGSpd(GaFr78ZcbrEdvA+Mc4)Blo;!aA`9W z#X!@ec9roNFMi2KY2hb(DBz|2r&qtfKiNONw8u(2O1T)7_BjRC|&Qg8hctK1t@YyH?GP z0Z*Y(@F>@p++WpmrxPa69aSNAREt>Hp#ujGmfE#3Z2f%TDh=$X9lz&8 z1054qLB(|gp9Shew%=juqor39s}z&+Y!6~w<^O}HD-eWcZlUcGt)-jgAUQ$Wjdoo& zKfXA6Lx-5xZXon%W70K!7vKaoL)vx_NE+L@gt1I@x-AzdSyU2qd_qix;=w z%#BpEfOcdq7K2~m*`1-(<9R7wz-;YA=-YR7oy|rkS1~-7uqbh3^62ehRoCSx5&Fw_-*P!YK zLKqT_Z6}QJ=DWW;x=o^Mk|ivlrzt&jlt!_x*9VgBP;7bv4S=FhG9u(T08b~s|^pS)YU2&v#Dp}E;mStXXCS- z&H@@_k~gVA9KtvLt>T(eS;-Xydt6z>8B>QL4b0mLU@S5)LpHQbxZGDjx{e z_7McglQd{qJs<~108?OzFZLquClA#8Qjde;D7G%9Q<#5#;d56!p6Ik4Xr?fHX3|aY zd;st&F(NVUa+CP62cS zTv$mZ9>R&=ryLZ9!Zh`AvZ}5THdO!6T8;=9=Q`a^v{{^}n-}39NZP#SP2)WnLsyCy ztnhmVw5wwVu7Fci5Fqa!{c!zNmsY2XB>*1-gcTIa%waoodihd1TsCaj@7K|I7iAW; zVFe765sf>IHxOzYnwQLC)AUUZY2c9wAs-Hs6L(qL$bXIe(`W(Zl*GKq%!xX%Ih&76 zf+dF*Uxr*$LrhvtzkU38mwxN)N{JrFollo+6L$VVOsB_7RD4l}39yqZkF7^6YIElD zS@-Fh6$~&&B~%>xe8}wM)Nj;M#SADEWMBXhxypb%UGrbne{rXyt7dM`Lqv#XRz_D(t``q;u|Df9NKk@8K#6TILY!|W*R$pzL*<9@vN(Hc` zo!5MxayPBGoXZuU;8=jr=-Y`rjm@>jHL^4(}W3JhUhCjY}j93 zJ`FMNQ`Gfj31|j7_jUZ{=a0^F#TZEd+8gaCu=c)rE0fAKBff-tF?vfDFMJC4oUrJ@ zgEb8y*>2GlZfi&g%Q3wiTlH(Qs#*FIMl6y&R1Wmby^}M2TJC4Qu+n>$EnBv4!Rq*g z)uV_!Jp5aJ3+&YxR%8uTJRETSluf=w#_%i8;)2cuA6Si$_pf@O2tcQ~&~|Z>#=Gr> z{8EobRrD}SFpO0(evH%uN{b@?K6@t~T+n;eAQHj;?Y$Dpc>ub6Jv3;OtZ&FT9EBjEK}o!t zyTV}Z_m(q(KGP%dm>U!^z%H&Oj|mn2t*wk-crFzfz*MvJ{I2#BTeWY0$hmrQdit}j z_WoBixc1}HPjt9Kam4fToL^si7xC}Q<*Q{b5iX!y%-zFVPHX1ass;Bk_}2y6zcxf` zDj0+U;=k`kMt)ho#<$ehDP4cwwW|^uJ^A7W{@q9>8OqH%7>)qcyRUlMLCU84A`gL) zUhwryd@5zHfcd!17{D?WNr<$9_ZQC%@yr8gQ6<5YkdBlr1k-t>o{EZci5}!O_-`xs7;rIZ@3@xb!=~v(_hkH)<;iLE%1V+V zu3XI#p?iT}dUXwmbq`q;l0it=L(i{W)jqjWX~+JIrF)~HaZ)v*Ri1bNDNX!Qz)C5; z`Fq`J=f3H{!;qpyMcsDG0;Ysf|KZ1~O}VhEU}b(N`W}LJsvu%uZ{k>S%v+h)k!zak zg-vh7?5c!2D!7dMFJQqd2GchRZ zh;~P=CP<82>yu19F!AncT5czW2dh>U2?aakpo$f|w|FTV&~yR+W_)6Cj0EKc;-}Ex+u}6Od@4ReOPpqXdM5N z8nJacQRc;0=-V#$MP1VqM|f`j#ga4fX=I>b;sWNtyJ6q3j=4U3R{xr7_wnsHnz`yq z9#8OyMO(_Du!zerXVpM^)paUz0T|2r)G}6XE(vF*%yw*b5rj&jAl5CVThbjGbw9Y? z4rpu?F-N~T0v|W$*emChU-M3^pAr9{LpQ7VpBrQJkU)_oAbN@-7ce1?f7a{=P?^wY!DW~z{KKi22CiGLw>`glV><5 zLv6Qx7j-#T?|H_`qf;M8?mG)zYxXdpBT&M~Ns}rgRmYh50LE8YMQnu;wDYf8R&nVH zoT{2s-H59zJ;T;=qa{KKLzb^5O$hXeE0LaI|u zL6?7V|Ni|~#~2@gX}QQv9PU@uoYJ$KgAk0L)&JKEP=1O5(_E;@L3=l?>$n9PEEcT?Fj<;#6T&KkVBnUd0>y%(c zd7m;pI$-+r+>0&ZJqA(cQ<0-z{`pz0*KgJ9a%$(cc~-v{FoI@bGKfM6E`c*=LVO!P zaMTJ1La2hI1#+Mpkn@*}UG`^sh$8ZsmUm z%30vOt_DyIhnT^wzyNso%lXEmP<=YYGz=4-gXfQW8J>E`E(SZx18I~4D(*AS4F@FtYPXE*a)HHLb79b*PPD*4?&Si%&#EC0vm&eUHY!X< zx|RR#*M(^+B1o#A>)GN0_x~~iLpY$L>hsBfdMc@;UbKmO4I7_q!ht<2^< zf&YP=+WmQ*ph`m8UVHO^%Kgn2Kf^`J|6hz-DeiLex3RO|Ho1EUb$&DU5(By}7W7LhkbaTTEUH%`nt z3}jNy*(O@bNLd_}CW*RK(X0i>iz*R3wa|8XUi8@kaL2!Tz}B#`l^co|ePCX|(`-&@ z0U+Kdf-Jb)c4qGlNVR17fr1bDuYetso@K8qEs7(QJMrE(2u3>AQ6nJiNw zpQ)nm42g+=%qpNRX~q?~Oj2GZfbQYF;mS8hvc--&hw$$zqdVd*Hw+rX>FAghT!$D2 zZV?sNl+YXvcd$AcH!yQ5yb?Z9vQ2(?(NvcWt&;M;yLyx*@=0N+&V5n>JZ)gPPA5dV z5&=2x_R)4;;9oS_)+Gkh!*J^Ec;gkG^pAhlr9r`4HzN=NIbGc#>G960?Mh2_M7heh zG_6v_z@_<>oMd-c)2yCY${Bh8#G5+{9IfUd3I)GtXTxI1cMtr`|lO5j0^WxtBo6q&Lf+t7zwpI`zCHho-e_fB5AS z*Tf4NU4>SwD4;1*&Ib}opzpVd`Gc0;o)vs+IGdXlvH%Lr@a6hfc<1JOEvVqOZM&lu6PsPFh8+ zaMBtD>t^BWEh(MD*6&99=SQdFc`|tBiQ&ZbYeF+w^_nSr6;Mp4s6=ZhV?-e%$E4R|;@0i}Ww&5XVfLP5%|-k6?2)4#F`Mwc3Vm5` z=vBZEVA%tJZ zASs2708X5S9xH=bS=uO+?b2+K{j|_FM%QVkGZ8SnT~wq`KY3At$=}JUA%FlT8|?4S zy$_4r{?h`Sn8l(URB+uxqkO?#H0zd|srg}S`1cUsy?wBx6+UaFlG2j8&5o6Tlj&B` z4Q$r+TLcNzbkSB)Dm=zK+e{a4SEC(D=G>#4=+q~*o&iv7p!>}YJD$-uH*;om49IX7 z8tZhYymgQ-$de(KGZJ6c=*m)>5#BHe&w2^V&NC|Dh1AFhrMUxjmGh})ysTVKjDmoR zX-h>*sNg-&nyN?5((|0Xw16n_0LBo_XvJ(GW8u;PmG>S{UB0ur(PxJ9xZD%EmQe0@eAnDRxg6wIK z6pabm{(zSSMSq%tsWtSX*mO_~m;#Mia%xh=Jpg@nTwmb3Vw96-E?oF|cnLRyWLTVn z2}m1W2W?s(fD#KG8Tz`-H)lSb!b|70?}?Z;lMP}sFB#`W+k17Yw5!NP>7F)VV0rtl z&B`XeecK2ihl@i033tqRO)KDlmi6MruzA+;y(fanp|jU$2=N=7(#DQ$pYa+CdurL4 zLvkxGoD`PY9E=bvRgYT6H`xu)%|pQJYxw-JXducsVM|<18pn$!cM^jQmiUQ_OS-uZ zaWkbuA-8>Y{`8**Y>I$gt41z_tZZ5qde2^7qaZJY&o5ZCf+BPQomm3c;veY|j#hmd ztqe+vNGjyjBI^-nH+%NU02+cGlv*?*2z4umJI3EC_^yX_vfKM}MYWN=m+RKG?xLWN zZD7u9{_0?}JTF_vjlyf8<~mGyP?E9+<%02xCfV+-YLR*Q>DQrG63bVp)5(oGYke2G z4TWscPL?+CHR}Vyf%~6}YUs2FK#Ph;7By~)?i6T}L?YCy%f2b@ffm%!Z4Si;73#2p z>%{Swcwv1Yn>bnTBa@4@^g5uxe>t>NMaxrwisX%#VGHd#-!m|O=iwJ{K@T`4bwgmf zC0QhP=Ch)@P5sB=GPbs{na?sNft7zQ)DS2$_aFY3L>F9_`YqPhgGz7Vx&TBW^s7O) zZeP~jeM|yQMlTis;wUg~nUUB{v9*?_9LMe7{+0IA56mQ^Fuh0-67jX-~|6C>1ROFl{g>e2K@SIW2IX;u4~x zE$CS#VtY7&Udr@DTYBT3Jx5DVmvSzh3Ahevz zVQ1NCT3KWxTm`yM3PECID7x}&5VJ%7sNc@@cbqGWIGd%P;wFN1CauD)^ak^h+qhiS zPQl3l@3X9U=$fcP_a-qAe+(2Dll2x>I+a$&)aO+#Ogd^%4I@ebMk6;mg2HMSi-eNZ{2GZY(L`kTz|hK9KrKx&z0_9v0A)q$#gE*7s|t< zKG9e)sNc=CS5m5`1+kF_2YFFR=o!7vWoS}RSRYX+G4C2sG5YB(ha*HX&xrC%eEmLN(e-CT68Oajv zLp?U`e%Z;?WiXL|idK|+F>PTv$qOj>wm$RLh$yU<$coC~d2z(I^)xY(kO(>BmGKb8In8G*8QSgv49tJ^)v&%fT+M}@6p)-=KPWrolCyWK~w9#%p2@X__- z-+#}QL0_q1ff@fG+7+D&J}x>HbcV;n&Xzfr#g$vW1;rPCvR%+m9azXwRcIaJl9PuP zT>l|ECHiI1axPFd#+WhLv+9_@D;VY?fawk$MHS!u*Q5Q2E)d#~aRsW%H>GDX#?=MW zN(>$}ty56Vh$@*y$H%=*w(t76beX6=CF$`&Gpv2z4k@{g>al*cCDG~l@{0$Wr=fA( z{_^es)A_EJ34xgReQGYecKy1?>{C31W>)}hmLqAB?N^!F=;JgcoPMbs>t9rtn@uS2 zrOszi4Gy*wuiD|2o`QZ~iU^(d)bG5{==(`>2eHhZV%Dr)O>m=u%84yX1F7_tWfWRE z7XcdhYcH^rEAx&!y-m?3=hdbkDC1IxipCM)1?#yK(P40>@n5bW{y>DNiDGn1#sh(W zHKysN_gUCC1UdG^fpjpPPO(^*rLu%d4W9huvE)lz& zDss#rBR`SV(WXq~=EsFsudO=TF#EcFM5X?`_X9!^g@6K9z5tUxi`R~-G9xw{uvxm1 z!c3=nCtkGEh{5UkL!j3iQp)T;@lP%FN3%b@j{}fBSZUq&2vgBa0Mm<7m3$tR-YANe zz=9KR-ZmL3rXzlAzh1*v9d2lr`Hj1q+ZJ}6m`)zG&9sijRrt!}>F?VrE6X3ahg%Xw zw|c0HqwQo|D0fI)F-Te(*i`E|pFale?0FyBUw$MYBqZbCDQrVpP98sQTo}6JrZZB56|o`~2AR|XDr0P-Wl<0bfBx<1 z8bnf1P4Win4&ca9P?^*3f}DX0 z&7=l^vseTK3$HwQ+jYGntN07D26TGx-Jau>o18M#hk%) ztM93knUoaKl*l?#mW|y$kWy^Hf(1Pf{ylNxL=DCU+m!nS*F|a0Wvoc)|J|1|FRo7*JS{cR+F@wKz8L2SE0Zzb*0`|#m+IeDxX^k{%?oCJ zcgx)z(`wk7)RRQ$Kxw9|tKr?YAVd8kk zeYKWM8rSkk1`Q4XQz^K;iwHm3SaA;=q|#1Ngeli=ujh_)TUkwaH^ZMQt&P*P-mQV| z?iLiu1-EUZo#hD;KHPtOTOIPWp2MCwuZkG5eMn2$RuPQ~nZPX)2}C#SNk`+y?(@#m zu~(y}?DCQZ#E|7S3eyY=%ZR5)P}<$V&0S18MYsag&)F09bOOhVdK20Hh%Zw>kjVg! z%~unS;i17^rt{V;{LV37dIj|Ni?M4QXENWC>atNN=1B+!`=}>;v3bp7j_}NrQRZ-b zRR*Y_I;z^~E3ntB#*(D4hmKZJ1edRF`RVItZQylaTruuzjKBl(teuMpz*RmOD)-pn z9cZu^JZG^&T%3ubfsqQxKmy`!Fu)X_f8N|ITv9ByNt#A^ouPkYex%Y0P#5f6eXFs1 zqO*ly8f6|L%!I*eIPGiU;ab0%i|Hj7y+5q9aeiM9>Y9zJEdc-v$KDo~VErpwRBwtI z*KrB_hRj)RJ3LM0w`DPy(mG7ZxzGbe44$p|C+#YKSZm?YLm6$Q*pq z$|Q3YQRmAmsVj$3J45rNbYhHM{TA_7D;uId;FU?Coo8+Q=WeBeEi0j{U~M=!xkP|9 zod%VoAT;k}!d8v$j&)n0nMTcG`g4F1!~mfh!yx>DI$NP+pxh2N(fTCQpJthMc$dD6 zdqCj@w6qwx>QA#Y9tW<5|DH({R&k<%jNh7_TQdvV4rISz!?=c@NppGj*Wt?8%*~9S zA;b#u_SN&-wfUGD0K!)@K_X>14M(O}QMeqTu~Ic|Ynh5-(deUtPM41^F30%bqc-jh zi|7*xM8V~L^BNve$&@p|YMObdf^N77<*E7lI;zvbm6qaL1`{<`JPcj% zAR6c>9rFTX#{NAe@5c+$K=DN*zufN2W+_j@@`j~Z*;sW1 zhxao@pUSUhODX!l`dJ$DT~dSJ*(pMUzoMM+hd*q@-qeAu3=33XaXG=Jlt%xKVMEoL za&=1B!{>A9-LJO8eJ<#orIwc3v_8`bAkCMdoMxPEPo+?;0*tB04DKwzPyPKVN%WAe^LkR=pEROuyiY;4a4-4xz4)Jn4 zO}fw?|Lv^a@7}(>N5_ph|KwGdhtE-El|}SO5wI{)S9yT&3FH;k5Gu??7v3rImYQPV zSj|5kZMTm1VJ>)^9v;Jva_lf5(b_Ghn~g(puLgO*fXK9|Qdm+dy@hL0CE&KpyCxDP z{#Xfwh>G9l_Gs26{Vz^i0{Sv{4E@INrJ7rGH5w=fzz^O~m~sO0I`F9yYv~l-;Sg#v z?#~0whP^kgt*A7&WY<#SL$u#(*KR(|GW8O>e{CB-rReZk%GFuSs(d&a0tD)`2USRD zq?HHf77nKKBtK{rBb%dH77I%U2Ci131-4K2<~AZcM12Iggy=&MxlWGLJ)!BG>8k4|J$-ENS?-9yi>Cq@B{yJ5s!5wr9dxUaSvxGWGaS#i~phrUFLkYWHaL4JEt|6Z_I>_IlOnsXr7%M}8 z0Y#%k+qj!`s$_f((LK17JQ4BQI$k!2E^DQVbYTd4?1LnOPWa@|(TE0C_lzc~NAm0399iX~`TFXes&={YpH zv5i$J_`~jCQec#gjPJ(E%H}M{hjf4VonCLB*laUrG7UmnW~Qk)xpY-g9lz_}|2#Ui z`v7-MJmPG~eyB!j`i#x3ys4Uijizn$~gLemWm5fkbJQg0c$qm1SY z4;{H(8mzix;(O}TKeY`bc(UiKm7sbl#xdv`hH509-p%**;u^-g`PFpYEb3pt zo2$=!`Qb+m;^A4BqRtc8rrnLP2KNzKl)-s{{Ha%^W<0-Dj;a_D=-@nSlW#$%l|98E zwkn-WqOMu&c$l!%p$`0n&_RkZ5p8tcdhF`m7+_G`pw_mFlQByQ!FZ@|K2cbd$9k3f z#w@uOaJ(hD32I2gTnrEKy_eN;z9NAO%H^I;PGtabknp9^KrTnEOrl`VCo>5OT*f2w zt68JnWY;M@d%&qVveRsHael2);<38Zz4Qb$Z>$`@IC*0^@@T@4f+l zXzl}#nKm_=-*Aeevm+a%I1y+q$hHB!lk@|{0iBS6Mz8z*j)r?IWnkf1+XfxjlH`vp z$N5rWdm>1LnV=Wt{OWmX_NUdG^^i!KDp>mM57$b9Zvn!(1ug<`O|!TLY^Su{0~2r8 zLJH#YHZ?pfFaH8}cq!lv3(@Nomj6>G9N}8c;i66&6jz*To-tLerfpqL!iWX`BSD{~ zeQ*tQ-f5gr6p&t?Eii~_?t&j{iv0o+ya-A{7G7?Nw5E4}WRqUaWTGpdgV-zEH>t}l zI~E7r5GL_cEU7)}hUt?-nRCY{9<+OSSIJBGP%*Qb0Ky^J6W|^YyMb_Z-&6Jm1~}f| zG@(@U?(iBmjhFBPsr7i|i}@otECm);uaRv$s9T~}{_70Tx51Nje><0gaafV}$>5>Q zhMLGSI)^z#{#i-$SWz~wZ%I=u7`Lr|mY~ScH)8;-40m?)-qAwyIuJUe#i*z%5!~6i z^S7Mxn{>+8=ak3wB=y19OP20OK_r5M+3ek^#yLqFOxyZ~7JmUEGL5=HsSP_&+Mpv9 z9jb$m&xwnlS?mVmJT&~@a$QA7TfjK!GEIEkl*V>BJ)XxO;Qk2nvoF0aso$ORqMq%#+N7^ro?o2j@O|G>RKj zZVF?K!y#6D&~txzvd>bksKg>bI&nvZA(ntg0xfEgGJ>>1sYRwZ}`^o)t zNIsNED1ANOw{MmePo$mJox!5?d!)vwkmw3$NO4P=U6=0#d%>H=f zVjz(zx;U}^*o^75gTqLngeXdHD6hGMLDE%fW0NaIv`pHqoH@EOSXmLbcSC<*!k(8F zz|+b>Jw({lX$m$X#C+fG-(>gv>|Y&qE`lhIL_pE&WK)io#1#%+T(7l_dx`3eKKZ;o znN<3<)f$vl6)g9@;+vM%XcNC@XXpy`9J{2TZWWx-GF#R+-$=5DSsYF5AS%>#zu zKISO0Fcn>UauAwKItQEU9lsraV=g`Fy9Eih0b{VT$g~H=b{1?; zLZKIylMq9pJayVX_E&@TPt&)oB!b5bMcmarBYR4(oIt6(SoU6X8luvzMOsu@t6PoKzf3`IRy<@U6OqC7I`Rqsw4Da2;^N3`nwa{ z9PfDj8y+1So@RHqBgQ0TxD_-p`iJ?e8#-{;G~lr8JjLC9DZ@vmGLojcd&=JBL}3xBjC{S#7zGyk$_p#8I7POoB` zd3cHTVOENJbJ<^;ZYy_TLby{cF|xPpvm&XwqF{Y=o~$W z2LMEQar&K=nrFbhnF-@>^~U-CZ2(FYbiRH2_L8NzcLmAFRkQ#5ygN$ngu`L5|E_^*zsZ4-DGsa*F|DolhpkIG z{ig*O`N#S5iRX&K9OHlT3Y;_U;{<9K6;{*)1Oyt0M&zqjQ0NYYN8elf{^njoc-Wh| zy6?u?2I(x#!Zo3Zw^Z$~x^|RBY#QV-rCTZB@cRNJ(X!tIK~YN_~Td(UPxR!oX^Lxc_-E z?z?05pO2I_4LKxbh}axJ>RN5b{fD%?zo2P;Y+t2dDIl zcI`)gTIj$pbAI7d3aVl}!^xszF&ww({S|@I>s%8qyjGA@i$Uj`B_{r{&7^Eug8@HH zuLeaMQ1Nh$;Y=}DALeg*6!N z1FUwH69UI)3ECp%H?Ce2*WpTRw{&_YE|%6D`=dPkTTVb^ya*OO_>a91t)V+p?~WZm z-uv0x4`32!Z{B>j-_Fn-Wux3&tX$@|yo@{16>rS*jOu?ZZ?Cx0g~v8t=q~t%$#|w3@sK=S$Vk{gIXBNKFZt z`gwqL4+~M#2oKP)SJcv|EkL{$4tSLAvDyk*?-XzmA==1?}_;T zyK$Q|x3<<9wdqs5dm}noNW^>|wy?!{Czw=0RZ2L9^Q)o_V?Wo!azbhl(1yS_6;h zY6nKOFv5DQ;T#&-Dun5PhKk%m>wzm}J|ZZwrWk&%Y#v4$7hn#P<-18Fgd9V$M3Cz} ziL@jn=KXi2+)8orlOP{q<%bYVls0GiAj(5dzBGb=P(OWnMmOo$$d>{|0WmEmubh*( zb?a#qz})QxJ`H-+<;F*RY2N@)B1Aj~)#SnN6+U{IjxN03D@ti_~nrz}cxB zH0nSkJlC76S0pyei=+3YT}Q)F+OW3ktQmXH&wVLpABd<#@s0iWzG->?1a0jDXU_2J z)SP6tI_7=t6Uj6|ZN;~J!0H!$EwMJ3iv#Kr#ks)IGOU4SaS&^gHO+r`+OjVol2u1f zC1*-=g|pxu7y?wRChTeeI)urYKmYWyow*o$7Lp9j_A<=n+Py#L%ZGXtoz!`n+aS@A zr{{=|ZwqU5o884`$PVk6sk#szH?xknvA$*M#a$pZGJ>o*bG}@e=;Ch18foEen$otJ z=Ow3_p`CD9C=v|&Kt*_6Ju8glAZPYudzCa$54Z+K7MCpvKCt|$Kj5<wMX@{{L4~T7CB4VE80#_#qG!o)i6fGs9_b!=!X#Jb-tjnB$Pe_1m^}8(B2x*T6{> zDM!pKqS88c>ZBP7@GxKTMhYW0m=R^H(Ax`%=1G(SiQdRiBX9?)D1liPQ08`rn**ys zW8MqIQSeWX1*Jy<9#Ja*wc6-x=e*(A?>CVJENu?Uol{bySZrV3kEOL$+?a9^P|zn0 z-d2gF|EgE>AE};QZYl}{&wm0H8_`Vr9m*#yY!cPSV16oN@EOlD_7Pi?lf^KQzUy~p zekoN;jG?4XL*``Y{=@cLI&mqnIi|mlDnx8(2pl{jaXf@G)C0c1(ro<2kg?6W>M64q z@6?=hZEHCs9L(uXeo=vC6B@b(V}yiy(v1?$XZ`V3Vh<`i5VU!mCz?1<6SjzM639+; z0n~ZcZr^&?ie$4=dO_j=6DCT%|6__kp8dEWQ7p?o^` ztu_VHCaS!Vyv!u;R6D>6#%kB3KXvH;_g&xSHEPw0pY!E&AVc!7I_9n)h?5o-x76=k z+jnp7;@MDi*2FEKOHe!sm%Hvp>CC`)Y_E6Wuy{4H)P#>ruWvBfOjF4(GK!tuwdD9u z$-q}AY)zn2Qa85(-PqH95s|EAUOWo9HOFFy0dsT8>K5c_AbrKh+R_f!@f1V%|FaK1 zf2c#rJLdb;{XVZ;EchbDxrAJCASs@y0g2as`)~-^pj4W)B~Cp5k zp`%4B@`3|v&68QE@*A1&qLC)e!e3dJtdLM6S`8XE3Xo8T3BZC_HPnzyMH1~p>e0o; zD~v&s$SCe%M=`nNH)_;;mTd6kdc1fP*Oj?)!~>G9AI`GX+dIGOqC_+iE`uE1uKqF5 zTA9JDAgR~DaGT|B2}OMJj@8j;B66NTkAy9+19+!2WT0^N10S&Dy}SP`k61$yLk@saC6OIK zEIW7Hy$>h5BKnkT2UMzTWd)jpy_F>v6wgT;@)9)%i*Xei2PdG9!F$SaR1@UvY$7O* zixQY9p51ig(1Z=wKJQQqWFfq7KH{5u=!6{7ktp)(eG7UC-iVZGz`_)>D=?*vuE#Be zs$c{)WAVg~F>sc+x|hJXt2#dQ@nv~*F~YwNo#wA`El#=>7cD?^xiupJ?ALaj+Ju%A z(hCqf;y426gcU_i8aGBYG_b+cIVh?p=w5|%HUDA4MzT3+yM*WgL+l67ZrZdbiW&f2 zTf5Cn8f2X(kZ$Ze)U-Kz0E%UnNb?yVKpYGPkyY+U1<^APq-N5lWF9-E|@s0Od8X z?MPr@{MABUV@3;}G!15bEd9HRN|!2SQLRVUpjVpt8tTiux|0`AQou&#r}njhs~0i) z@D>${c$v-J=0tMtg3p)|lpwwb)1e%Mq@v8897*yWxddLfUgNiGAhZr5 zNF`=_N2nYnD6;X<%_ww~u*Q|p_|Gq=r0Bz^bn>TJbiN}w1vpHA$_f@ty_9pZ-^LE6 z++Jcm$-?{eL-nG1z5$b9Dn*OIX`-;U>e#U+u!2@OKfZ6<#a*5+X1W%0KIe0!1F{#c z+MV;`3p7Xx97O;uCFtfvJb@dB6dva?IL8H|kVL)*V&nTX76EBlQ8pO+%K_hhdwA4e`zS>r^~`U6Yi*r(;zPCLz+<`VTT#hM_DHTS53e*} zmYn3s9OQ#_{c|Go;~y|T0Ncu9R6A@eM$Hgh>K^7~Qe?Fkmgo%ij_e|%?yF+3hg)t>P;?I=Mi!tTjB z3*KAVpd=W9^X-@rCLb?0K|$bN6RGM1_qH_THvnec*@;dSJV_!4JDvPLZxgw zK1L}vu>%|V?f14y)a#^Yn-3-jR?d@!YhEQO6Zd7W3mm82eJXRXZayDt3pF zw(;f&GgM|VKZ4S)@Ymokt4kL2fASL@#kA+QYLe4LZf6W70}!CBg48lh-g|tdjo#^E zTGxz#&mU*vE9FuKE{m+zu`r~<%(TB%#c4F>w=9yrPQFqGA4#wKtM zr*Z5>&;CqD8V3aU7Sg}9FcJZc z+f(`6DSvc_!=~DDLIT%(co4rA|84bVJ4`B9PUovLsDgmdk^cT(o^E4M`G8I(1iyP3 zaNNx5y|-Xv#6@aO5e@aQ{$ zNP}N6FcnmcHow}?DL>Hz*RUI1mYP`5+L&{0Nfe9XjC3-92aFs&dLcVv3u8-^+*>|{ zzvzx1jGqwV&0S{BheRk>$0<%X8?aVGt|IW=fK4CRj*wl=Tcq%%5Neggvrl$r1dGI? z*$)28d_3dc-&Dz5+!!em@={>bG`g}K{50CLqg(3Lx7JWv8W)ZB(2Ns)A~_gmn6QdX zyF^?LyCT{Kl#mA|-@TyMxE$-%G(0S^xpc72{@$np#?_PM7D_{1+LdD+KLxp^B=sy)0em*k5X3P}o8}I)5zf_xlW~J=Te?h`mLOn;^Q<-ntu}epI$m%(Z`I4fh zH#|T-FL1Ej#dcq=+@0oS7LdZQrfz|vxg`xqinsthFz;rK)j4f~8$$78(%-Xew zZQVnTV+H=A5(av@YRz`oef#a=)YO^lS_U;-d05JxKmS~l5*tFb8p<*FfK6oV)8DVx zJG#lF787`I3ZMV9ZjSX<6C}$TskX~u3|0qT>V5i~8m&hdfZR+tZ>4ep%S+<_M&%#? zSuXcB{$Gc4)g38krKjS{J)pr+iNGl)WR=b-Ak>Dn(IoZQv4)%sc>JuVhIS;MjHsFO z9zz=qxmsz@mOad}vgEb0IC_DHLpDIuxs%$%No3Zky-V^pY93JXptv{fK2n@xEVMY+#|)2+s~=#BiIo98~I7oCujs_R6Bh4pF16=g!nhHhe{%=_t4 zwb%74jbaN9Lp;Km`0g#>z==DxcJ-W&F!OluJ2RR`DEyYLZeyrEdEh2>HuM>UZcA&B z6JlYcYaVwCmW6aIvG*T6GWPrNyG!ZtYe|S8*8uxv!NG$E|L5C1<+u=kjQT{pj#A6) z?LQ|>c*+6D^!BB6Fk65_ot=kuBFsXP7=B54A^?dXM6t8lX80g8&Xw8C?O5;)DMunb zD2K<4bzfbvc6)XD#A!Mw|8PICEDW$*vm;%M=6q}=RL6!%e-=CGuuahCO#{KxC48_iU-oI8s z!5yX%h!3lq${C$92;l3I8G)1 zaeh+Y{{35WR1zdZi}^K(>?|p5eMY*ofCj}ml#27KdMO+HKxp(v`;b}#1`OaEhrDk~ z&+Rd~A8EeyIKW)gEfUzlZvrpg9J`UrI*{dSmc~yi%*zyL=KQZz&arVkpbW){iaWN0 z((8a9zhveBv_z;+VjAtv;dc_YY_VanQa*(aTnvC$n|u83=;nMgn+@oTO<1=oL&*R% z?eyFC_$(G6Lqg~?`Q6Jgt5L1z^+~+Iu2z_jr<-mA&awwAM1%!i?t^q=6W3lI%6Hhk zEXUXa5**mTrRbR(=Dm5zAH>+WV$-HicS6uC^ET&!M_RY3savk`#vhZ-%58yLheZEa z=I$?FCCSlEpuz$foGwc;;4AYm_Bf_9eX#_qIUShReB+D!G5k%MIK_d^);|N>t7Iv4 z_b6Ix;B@8kW3p1?X>MX+nC9lB@lV_=y&WAFUY%n97p{{k#Afim_s@OW4K`1o4bVa1 zd|HZ<_wc}F>rzC^3O#lg_YD_T!ZPgaC1ar{qLJF8{7_so#0>=AW)&wDp%)u60aw@ zG$_>|m-|KDji>WfwFf2eCN3E#44tiBq^dCXh=UVq>i47Bi`p%MME@6Ee;!wJ{{R2u z2V;3<86u34C56fwF+!4Pv$UKRvdhlc${;D3kS$V?y%KdQ5oIlVsfLJn+h$&|rEW0oMXiTOA_^tg45NP@S` z1#U5>SgNN7r#qtV0mty=ISK^@WB_rS9u#&sI8C4egm>bggs_0KGc$W!e73*=KtyO) zVx{+-eGf#(0tPSwdi!s2?2HDLRnmv7rsQ&b-a=(pd{3@(0`WC2F=9CYyuQs!cj4k{ z=lPHv1UBW+`fu^04F{%Zads4j53+NRj}p9R1Me_aN`P?TeKC8x1ks{~H1pnG1_#HE zU5psMu^0WLFb&9E25;YT-4VUA#9?b~$5p>iOkEkkTtHGeU9_N!G|duS$mkcL({Xgn z)8!2w04j{27!&w{Q4{sb;P6h~H)*_{;oc>9EaH)tCO7&Q^Si^HWB;$9wueUq4Ji6Y z+aRV6TSh(c#RQIetv=_%FTtX&0&qn(NZI^QVno1A;K3UizvHc?W{(-$aZE zDtcK?L2PB!E&skw_%z<4mLbQ0>R`mmm4jqgmDnP5N$NmCuJ&*zn1d z5BRE&sD=bo8%CeZ;$#yZU(;62;w8PczeC|Aydf$mNv3!aiTwdldPm7e02g>G1(>Z& zc3V<+LtvmK+*-bhxC78k2`}D%{&&ulzq5;Xcc5I4T>>zPGurve+d8 z_VoP}ul~$>d(3KAZA5oc-op9Ox#i92x#>5|VEyy%jpsiIE_aEs0KFIGEjg9-Wij`? z2}klC1kLBxqyc-0?$Nca*roy};~O0T?#E3U%2*9X>03+_FPX zPnJg)5&dM@Lq>*v+gJ);dE5pM8cWbwEN3T&j^HSZa3HI=)g1zL?0gK%OilwBVb2l!4rs6_YmaV;gOlv|Kr)wChbGacfyM>!Z9uyo29{q)Wc=+j_ z!mOYn_|I@^OdeVj$d*7JhQ^n9k_52NoiIw(dgxC}}uLTbZWRN>2Z z?QNF~#8Y?Y&fr}kInnR=W-=lKc;C3G3wvakXo&m?JVEdib~OnN7n{xfU(CdamO)BW z4AcaNf`|>U;D=&@`0jFl&Lc*_;%kIllhxRGO0EY|zxHYckWOYVIZCDA&&g?G_V$!_tLoF<9Jh7k?c01*l1xT$tIu)jcq2j_2c8x)K)7bOx<#t0>jlbWd484(93UE;wt2AWZ8EokCdix76 zvb?yV@ptpCp3^}K;aIK`70LZ38%w6~CjWnNKVP5xS}j3b#*K@hUg|co=NeI6Qboxk zT0*f*sYFos-e-)sH4+{~9W6C7IJIEIutZ&BM1Gh$_1Tx%zE+dPBp8kx>DcCL&vELc zUXmY$zX3Z6*vwAd(ME`D#FuSU>=~~-(HAS|S}A=FDSgbo#UtXjWTYkwU}@^MwTN>t z2J3;-SesU@$M~pB7K0DT*4*|`%4PtK&WfS?LnMD5jQutu~f0{`_h~ zu`n0Msm+_O5)%R1YSDVj5?zKZ>twXM!+H`{_QtR+07oOnODYOX@I;2O zY}J!~?P#<(7l>j7Gp)MkG^;fk0LxAi`Z2hsVi_Gy{p05zLspOq^`})3{R+vVnQlYQ z>AekxM80kSq{egZm{B0WTIg95`KD^cHL3th0GiSH(XmUF1YlpC@s2Dvlu{G9o`#j} zh9IPV%ut>Zs$`=n3S!tbz6?L5T@uGi{*WLw;gOo#+BP_*8N%oV+z9T>_n1X>84f!= zaEWMxx1@OEV57vHn^5w{VmR@E|5q}=W)QQn6)Q}{L+!tkK^PML{?4LrrPf!suRT|% zc4Rm=0@gI`PQyuDb(Ssp!Kfr+I2}BSt*QoazIpngKnYj!7x3vP!=q?Dc*TjE+cXAy zSGTBBuh9h#zTkywQxg$cPO8J;T(>WL5D2~nd|MK%{EBd}#Vp~%Zs!I3wIVs9Lqh`f zY3y(%#PXqZK8x7G1E7&Hu!p{tzlN4*?gZPvusgJ)*gHZl6s?QwS_I8z%%o#gp;vP7Jt8%!-Rg-0JI*=^uljr4I zQ;3*bc8HiN^D&`Po;~aJ42?@0=@}V|2@9XN55*YBbo4W?Hzym$LMwDWq@jDh9+y@Q zqQotxmbAqUv}0U>F~mQbnaEROKQmNvj!TIvZ#t@t&$Qu64W{zav?EABTEj77$aDjb+mob2$(TVzN;Qz8po# ziUqwLDAfq)btpJ_$g+rn532t*sg)QDPr+ROZ}1^mMFt0F@iW)Oi;aBy`(GE!QUsKo zaM@H%?gQO=zV{Q9js`;F^829+?J~2IP7$$>n7R(KpRk{}$zth5k0kmw79?$Bbq6<0 zN_q-)!){l0^`2G_Bt)#a!bWy}9~ErPTt`5GgATJ}dK_4h&!|)Ot`Y_-rmW&f1~$$3 z*kgm$LZXrIgy4Go{p|9(hH9ZAMZ7EMicAinG%6I_a3O7i3{{PN$LN^XAZ#4ItM8yl z2mQ(qHcph{BN&lE6eKvEa?rZf|23IfrVdiEO}(-{@b!}uvmL3Ve+TDJ6@n^gS@;bCbCha~{@TwN5|L&$Gh;9i3rj7A@-QoEm;{tlP=E&i|G> z%}sjUB)-6{{-62d%1Y)w>aKCha6_H`T{qMj+N|kVou(gdlm|}Cu>D1=@0(t)vptLa zbc+XMYg_oexG}&)if^cSEnbwOp-0J3bX8X&w6ky3WjzJ7v9_2l$^J*W3sI~y(n-B{Z&<$s?l^OI4VLUNtQ7YE*zp(ui3k%# z<~k0a?3rF45O9$Woq=j&Va<>*4f}}1pP|f~iDB!bUu>ISpRvd=$#^i=nORz5D+yzZ z(%o>hon;Va(kaU^Ma7NhK3Eix_$3dGs)UZ@eVrL|4=+u%wRe<@az3uHA zQ}oK_XHxxIm}T-yb&OaUaa1#eCK$MWEe>sc;pybO3$V};vu}Y)Nc$}&{u_11I@!T# zdH(l!rjanmgLkOV;lPb(K$wBHuzGuQdnc$atq(fHTncqA58AtTvlu&Tn|LVREa*6g zl0pXZj5nf=>NrlvcAyCjh!CHAeOwldW2WeKa{pH><_fc?@!8j|TUTFLjF=`F8BTCY zgCtWJ70-C-0QMV-URWZ+X_ySTMMl8<4eNPa9jJC?rjPvpeAV)R=%rm347?!4?b*M^ zgu5oujNlDr1`bOA(ugwPJ@uV?cjN_2doOWPKrVZQrf}|r)f$S_Z`E@t#HWZhl&grH z-Ay3>^>f;WMz5bEi!q*3c34iCB5NA`Ylf<6WqJk_Qh37^Km#aG>CPB#4RF^6+MeeO z7&155Bw3U?IN_BpT|ITh__IqJ^TjXW&EJ69g-j=>hI1ksKfa9rmeCeAFN%xT(MwYh zMqf%N;Ab^d8d0gr#6XHT%&UnFE+$!m9*a>wOJO8?GHOTvwt+Nx{_Re%al`Tb`}M2$ zrre-+dxr>=^afQ+iK?U>L?XkUEhW2QbKHRrjDi7T*Yffu&FxN;=AI99*| zpD&M*b-hCJCI2Z7EPwYx^EO}vTFUD1`tie!3*r=KPIUQG8QcxCB!7QaHWAY4Vm>Ai1aCl7^Zd~Z?0Ev zj8Ul~NVgwf#wLh&B6D9^5+qD{n)^j4&Q`MGSonM33{Bv337edu2R&MI6VqniqF%#@ zeKNry#N_p;*gN12EiRmQ`z19{@HVJPY~gAlF`mAy5!3q)$7UKS`-7;80D2JtVs2uxCRZ#Xh~kCHbR^;Eo1+4@T3YmR#!gM8Dz z2D!}=6NBe%+(kr@DKCYfr3|bm-)Z&`d8m>Za;i4(m!B`kREXPD>YCK z{PS*Y+#o$e$6DV*cj1ti`43{9i7)VQ0fFy484(6y@Cw&J>IHhm$pk%GtkF@64R$ku zA#*T2-@1D@Yly$~AJQzPJ?rd^Vx6^Gw4jV|NS&HX$$t!n51t;iKUP)s$(!TE6H!^g?}MPEYS+X91?6SHpBhJSUHfkAHqg_yEygI7eSJ(Xv5jf=7f*2Yick!B%f zm9M@iE!>JY3e1NPojQWy3pBd2a2!R$)8pBu zYrqnyFj_dfVL+|P2}?mj&>mX3c=5#)Nc)a$g@3*%;9xirBmCpPh<6NQ-L9KPu?K?0 z8MgfD)ZUaewZ42_av0(y3|Tz-WUaJ8$T5{%A7*MYf(!dBR`LwlBch|NeBCXS`Lk!u zlBEKvwR5Qp-qN$4TlTg#%|2pdKQIZ&ZPenTrx=PdRxI{pMYbGs_Pv9taolWV!4h}v za(@2j&4wNBj-b#SK_e`@O{*vewQ@eUbvF#-I>2-hLLtVV|M6c(P%CB4+gwOr4c4~u z%|=~nahXAI-Y>-GMLY0xdNEU!Er(JcSv|D6lkM zRwL}Pf8F&R90_jJ6}sn*Kv?>njG8I%xKj^;AdIJCMqoRDZh8tnQm)sZQs>Nw$MR%RorCNt;fIjoAJG{o)Aqg z!9v#XE}Ro_W+rXPeN4MaGX_bEgW@c-n9BN>!Z;Yqohynm;A_F4=&G;38hQ!_vMn}9 zG^B~Be)s7+JCa?M4mGHu!#IxO!uVq7U4T4sz>c`oe-wYQ%h+{5`1 zWj;N%s0^@`I{+IHUS!6kr*kR(WNCx|bMqp`T?d5WfC*e^=-HN^ZjmIjA08NAhd+;2 zeJy}9wnY5@<;SO%AO(;!_o-6ABM>1f3GcE+T*O(A&kc}C6;R;$?8~vnLT^Dq@}=th zceR{q+f7#%%FX81-$J=2GgkE&{D*PKwmksb#7JQWFy_cwu%GFLNZ;Xo7!(bXbV~|b zh(_Vp$2wa}hW$)QQ*3vMlRfZ`f_Cm#=9LV@68)TrgLOxbR-QbD5xKHIFRoMP&LhHI zovQ!p$u!JASH(dDGN??`8s-IjLK%IHt|4}qo7?YV2ZKcH@v?{Pq}afhL}BxGuYc@= zKjE_pFBkBhR=AToG<4(#D4Rnn(V`OkC^E&LQiOvS@JGXdfs<@Lq(AWxy|Rx z+xl?h|KBGNKmN2PPRX+S2_iuay;1ibo>}m8rUB$sX4X$*y<~&mU+T#<#U}_(yeP(NdNs5vVa!=M)B>Dd8~9Ug++cj=^4Q;gRWh> zW=5%fI?M(-2F?Jl*O@*%$tqs(iK53dCr`F}{c7s5QzK(W!9!rWsZkXR?;VU=A(A1{ z-+lkqcEQa9wG?LXJ5f|=q{l=@U$ZTO8em8DiR%Q&lFPD=4vC=ulCyaH*!;-mT#@fn zb&Dk^+mkA^;xZ%Y6rMkyDodDTJr+2lq61T3(N+_=16W_7j0wZOE`YPy29`<1{>urn zhj>M$fi!8nG#%m^1+onJq3MXZmVQcbIUkER{_n%njxiV>G|M%T3c`XsyoRM%Y=Evs z52mgy2%;IAwFgR7$)eKeORsQ|7dqyuFK;cQ_Lk9Y$)@r*w8hN0y3U`d(^0hD1U3F3 zSW>VL6^1aZeSIdq@kw#br4~j~xgo!fX70kosTfr5I=4yJuvbQ=ZQ^qWG8ndsjF1bb z5yOO>NwLrZf-U$GK_0^$>DsaM^$H0>qg9x1H=C8LqyUA22T#eO_;|8}M>g)yjxipm ztq$=!tOZb>ihuvGXzy9owbXtI>=-a-A{&;UWw@ah9#%tX;R%O@QTK9|?D+N|>)R%q z_Ab9AYC12kYnbPqm~a-7z?U-DYEu}6G}E8%vHh$SP(70uOVTJ|)G219g=c`$;3^MW zusG_|-|>H6R@|GHk2vOIw$C@QvF^l(2+bfK#p`(E4vPhp<&Oxu4BjD_f10N7wkRWT z@}49FcERJYG-grkI=FRDWxK%1lP4V(XGq^91h|nSH#roeNK;LhP#Pn`HiD&Wqp0cH zf_5`*lrg!w(4|aR4<5Z|u$S}fV&PHpwgtE@D2P0*U%&^CmvM9^1=4mq%5hbk~Gcvu+IC&eO>2{JM)N(uP4_z1EvG0h;j zL{0w(e&_r;Ce41pO8jwYzM`(P zA48e-cXWzZqh|k;wbvxxX#o&c1e|CAnGet+weVdB5UIv#!dX#$7 z#3S0_g`Ub9L&$TDaybM3pKGp$JEUF+M`#zm!dDU?%Hju6&g*IhoSUcT*0?*0!-)@Vn04?FrJvlhr`!2a&TlgR`6sy5IfIDz zRVj>30j&%3e@mU%G&tnDdr|kX_IBM`ijr&UG1rN$gTGF2pS{sk$rTTKW%m_~f;lzPjFgnj z+PQ0&#!rN`fnqWmKt}iEk83Au)mC6qDyv~gzEp%*n=&;MgiE%10PW9uc0!=lX_caO+E&)0}QLid{N1Z&n z(tA_fHK)g|Rf8E(#Mnjfp=A5Bz5TW?pN2EVqjcn1lWKgEl8l8lK^BRcVLu|Q-{8U8 zCH_|JLKY~!nQQX8VL2#4XSu&6vmbuiAS7m-ggIkk2E*(5Tk8wo$UL_%RBwBH&F@Qj?8}$$O<{* zQ#!sqsI>rcYw?>J>Bbmf$-AKue}m(5#t<}VuFsNl_Ad$9`oPk8>DKw3J|t&P&kx8j z-4WkZ&(JC(ZRU&_sc%<8+V@3*%WWyTs+Tw1c}36!Y~R~@+c`f7ici%0oLATE+n37foqm3`8U3Vqjx1enFf3W+ zynMJ}o`zd_pL!oB4H%s~wUzJUlP|kX(2T5rX)A!jh4cCEWizSp-_SZx4v|9OFWSHG zI!9$gEyEjWs$it9fxLrl;+=1tE@8BRtRQrXYHsHtV&I4V4RwIHdC z=6NUb%YJjm{0Blj*U&S7g!&#fC}|N&)mn$_7(xW4i-;_R!+;@g?43^mFOB%>vO*Wk zbb&TVFP7XF4o}9UHUQx?D%dyR*4uVWaxwfpVc!7ac$Vn%=*@^Kb?pM3yC3_~8 zF-cy>OZbxQu=Gh;U41+hdNyv_EM+uv+llVY=9J|zAG3=ycwu)g|}* zezmtQc+|jbO2ZN1tG=Oi0plKql%D!c>xR%HBO-JFv*R{2cm9XA`i=Oce5|@&1#;;h zA3r~2Pb?%6@l^`>2RCx1+nY)87REb?P7HarhK1>WU)MnW3bt+K#?%A$6jxioJ%>{X zbjxBdO~n+FnrjV=FPM<**p)q)w<7!Pa&lPdcvc2_~=^wj;}9f z_LPTUbrrAjfij+)sjw`~HFocLE^}gw9$)>+%iR75S=DUpq4yh4CB*)-@yvpJ=h27W z&zTsNp0#0&qQwT=L@j5Vz#ZPfA%_jjKU6|a>`1{-I6Vof`L&ZTZefDZH73Jm40mL! z&k;`Mr2pA`7=Z0{N5i^K>6vZ|biCRrTI?U_el;$qDr>_DMWKIBMa9&X3jbowyd}y~ zBNyf`kbw*L7Z(-PvRip1XmC&Ks2rR5DIYs07XN8>>`mRSt6td-@!7HJb^R9m&rkAs z?Q{D})W%8WyC!`wKBAw!1|Jgb7uox zw%_{99YI000o>c-BuyNsF|ll>kk!~Cm?pPIE%bu*E0qEqTUq*HGlX44O~7z{X_E?o zHY-|Lt&d*1B1NgECSS)N)q7ZGxI$VI$|JM9S7DiM83m(?4rive{!-mArAR*|)3UVH zGTVe-99DP+<}Arf%QDS${~l9nmv@Zw}msTmh3M`v2L8krDfg{;nB9^+sL+LvHMgrEqCTSI-%MJ2^zid;akH zk?_@IQTs<0CWNeNqN6e;DpzP7=9xw>rPpchaka+~7v$-xo{7dDqFL6HQP8FMrQ4VGgrk1&pI5-g)J-Cq#UlH5-Nn|@f65{a&-FZGTiukOiCRewcwX92J52t;*+y5JUsKp zyEAC7MZ=8IgJ0Y4;Y-ey9|NBkYb_RnMrDgc)k3-ZnvF$b_lEvrNDUn#_2FkmF?AIc zi93u~*hSwsrc~X4sng#==oVrii}JFD{fXE=B$}yEX7^r|Sd0+xMC}6Zi9lOg7V=(&Fm_w7R{i+K+)34;y{kbY1MT2X*e0zkf#(Vgt%gl@%jFV(Jk z!1kaZaW{&}mTGqQQJ{>5A}Iy2W`|4-W1tylqSk?j-M@+pJot|DCuc99Km;8BIjVRA(;?@s`jfaG6?`(-Sk_=R%bm}^lpzprKiH(42a3?2amO3jM0}U5g!22x zhE4fb)-#Izf$-jlSqBauu8)LX#*;(7zHiQ3X#@%o^`efilo8BF{-5VqyVHnG^mein zum*qm1(FLhx*cv2wS5^9WStC)wxL_Nk69|0+UbRVeTOZ=xv;R1>C?~dN!5~p?y@f* zk2w^-X9=9rpnFwCwTd=%#m6u2vSn5wbO@fNaDQPN!NPRat7||%1kaevYT*4R7xw|z zDPkNJ?=7(RFAQBJ=fXnS2{jVuRJe0RkIUIM@PirTvOJXHXDU$RPP|_5hjJ|{j$QEO z%NIt(0c7Q$B$eoKNXalSSC+KSwfV3tKWT24g_=CiDS|)Q%1a~lu^Xs{!6z?GF7j({ z8R1fYvGQ$V_pz&3^$Nf$yJZ%1TdKbX3MPs;cx~O!$5T202bojyG5~16vt|k^{tV!o z%ZuM;Uc;cF$ZhqxRiF+-$B%#Lwg1VJC++2L-?HU~TRN++g{$ow5~3w$%^*q_x%zUF zdh~E^{TWwSSpqJuscd;*)a|EcD%uq>-)A@lgab!o__t*SXQL($e-Sfsse}sEXA!Rv zK00C&S<*GPGmZ|ha?C-v)z?M0t3bj5j4fINnllGTtkFL_9v8v9$Wn%ojNa#DplJ2u zqvDAE3&SHzdZna2trS8Lq=1Y>f4b~_Ni)imCWt@qyQq)fb#!uD@}!2FpIWUh(kKw8t4Yn7Z?DT{v8-NCail$b--V*+6^`jM)c&A_haHO&rNK&wJ9oSO{cH2ui(Fv%WkBvL4}+e?-rxz+ioJ$iDL@0CHrwC>zF5_W(}5 zeY~UyjHW|}1Lkg@YF*%Yi3G6&SUKus8Clfh%kp_M(|KycfZUkxNkUHu`FAmvuZm>_ z{kAzp>EtmTTOYmZ6Nz88pz~(r+r5H(-QMTRu`io{aO$Ul>iI0u-I>0&B*b&V@OP2GXxZ%hPof{@8Dd7S`yjlu2 zPk~%WT7)J76YKO2Xvq5i#5P*6`*6*d>y7a!hyEBeiaDS6PHe!tPp6-Fn>Ta6dNo1x zh{*vPqC0e(_YUU5Z%k?o z`%Yv#0L(yzSbIZBzsNV_i~;U#4g8&t1iZ8mmbuXq@z5X|DZ4&0o_D`#-MV!v%1CJB zJg=zs+4(PO4(cRP4*(~MZ=1PgjFF*pocI+ZYcmk*nTR&4C4tR=OfPB*SXwp3N#(<{ zKlmU3X)to_HphIMiT$>0n-RxA4Ti{L4jGwFgB)}rc%groGu^3e=d%pr7C(bIz{%6ca;3gUCsRmkR3D6A`r2k|;VkF`=KkT-q- z`LCr|`5|v6wWY?6s=OxOpyi;^obG?JqK+>@r%Mok<>1h>h=mrioB~Ld=}?=B3dE2E zBAl#bpkbF(3ruDxOG<$pKNfBu)8fS=m}z3~26203b?ITug_@H)48QJt-0#2i^Nxe~ zoCZhcg8o|~l-wxhG+OZUn?M!%NkhYedfCa)XkVX`?*}4r1?7v? zANz^9qwJZKIK`$O&?vtbF)^ZMC{8w%od7y3CQ)2-Inx;DiUl1@P_}|8Y+@!uMB1_A zGRLpPN3uzj_*0RVKrDakPocH#J#gUJze1xazv?QO-^}u~SYe1BN%}wde`fGqr2`1> zbjypgRep}Sg0f_%gfgY2)P*7@;m`o3q8oS&61k^GH1rGd8C9M zrcg-wx5%!Y0_6i@Heq;%$T{H@G#3Ju{pKt3Lvv|WxG@Q7=NkNI8Y>+sShw!nxn6b$ zcs`^>!i{`6$h(tc;z>Y|%QC5g-!KKT^}@gYvZO7#c}#tKqt_x`yiA%DT|QMd>g}N= zR$9qy@epNg{?l=O`B7Bstc;ei^=x7;i;eqKZmM?z>Uy$KV%v$&IbW{QGJ=BW@ulIj~O;=rjar1P!>SWpx zOgsqaX>_h=B!|J?g!tvQ_0`45h=`|DM9{$_nL?cM{@f4GD%V#7czkpEYztm+SXWg! zu1;kw@8a_20TxJr zm}6Ln6vJtWI1^7e5U;<~uOHmRF`o~H?NcjS1l9XcbwDqLB-e7H2~Dn#D-It2Z<$PH8?1$(FE=H`l@q3HMg&J8@9NGKJu90WGe zFqPy)HH6Wm=g}=So%#MC@PsbS!_=HUyRb={C}-o%V?gf zl|FMFQP#?k9&#Pl^tEWCr4nGkZ5~sM*~=Bsi?9!E8pq8@Q}1ix$!f2S zs7=gn31Gu&4#=fx`{33sqa+paGKm7tVMAN2Cefa_M>SWeL zu$prMlx!M(QiDc~l&8EQaH4B(3PK7z;u7^6giT!eILUPs(rMDjZx%rz5!Go0P=t=^ zJWM5ZIHg=CNcvK^N!8C45o0`t<#BgbVtFKc6=Z0PWtVV{0F>oKWM6(}pcALJHxaQgDlbAO`7fNqegZ3bLJnS?e3R6|-T(A|KoUCAX+_gsLrD&}rT! zY6z!^St?n(<9UYk{DUw=7X8w(%hVI45nrBrz8dKp%~~B=BoaV60TJgbgZGztpDJ4k zD2C(#m{5PS9q zQ@Hi~X4?0!Prgqf0+3kEEjy{~`E9k2!BwH*U^Q~E@^Bo$GDP*2bxuCFxuG@XhcZNf@%sBDfY&| zyy4TD<+i373U>gykjmma-k{F#$flLSPb-RvKYUa1D4m%1;BNXXID3 z^Z)Fdnbc~gpN)!JTq z)9R8=(y9Y;UO*Lep(@_q+l6xk;TNN}rc#np;p$9^?~bS9xFzBfL7#~3(!Q&mH^B~) zVtjHpj*$FPE|FBePO5GSwktm0KTrDa!xSP9fcXWt@RWH0?*8Hs0VU(ehV4#+!NS`P zT-pfJBwwadvcjG@r&QFWNb~egntxLS(1=PUB2+`b4A?VV*ejr=27N8D({4vwQj`BSCWv`tk0YtzmZt*j4Ei*=~{~bw?Ls{cQ>^4~WPr~<^ zf7WmTh-*?)LmE&{NqkwrH{oGo7Tp4&y;S_d{RIB$q^CEW4NSSOQO}6=ECScspro?z zhuPpoE(et7wMW6LQ7|>-IP4L|}Celk=i8FI(Z_Q$zLV zHcNV^j$nzUb;+zBFOC2Cen`jhwBK81gCXPVC$hBvdv6pLGVS7 zX7a}O{IRGuc%)$K$n}Ip#PMYjc|&ay>yKa2rqaG1sbSB+7L>`(Le%qNr~(5 z(mCre7!!j{GT#;W*~0tzQ5#*x6i$c>Kg=w#{TSOad|V6#41969xAGr@fVI%l8VVtl zQ!SiyWI$5*VSg*^KN_OHQA~)GmvF>T3FSLoL@kbcW+*#k+Zv;horY(B zeyLmeGHTh;7|9rf%Rku5SJP6o6Ae78nAbA|!T&hHA)WWH&HMp{wue?!>|R=qh4>MX z1M8n$@FWdPTUHe^+Etk0qUP{;T2UeR(Gbk%tCU z=r=v;c{JB7~fqrK1_pBH7|Lls8-;zMPq-r61N`>$pwUjT<9|4!!6$WCq$TQZ=#{ zb9Aoac|<#>!+C@UR&iR)z~;?sg#WMvd+3nD8^PKJ8f{ic{4W)(PZa-i(QQ#Wioi$Q zh;+6^KR7-Jw`g3lU;y_7Ba%{*bbS25lA8CZ#semtM8*;4daSmTm{8gOi~gccmIDD+ zqpZG9_ze` zMhN*LnfR}G6(Cd~KpZaEm*G%afM#za=d6Hp$wIT)TDk|Tb=Wupd~%5rR00V;X-&C- zqS0rP^RTUaJc?_0`A?rdz0mz}u*f67f6Dd|>lJa>6+da2X;S!O5qpU(#sDa= z_QKSnMhVzfYH3e>QE7-ogVv&9qSEw7C>#PVMO)Atq>aUMCv4j9-@bhfxNA7U;(m(P zU-Bt?^zPk^cC#Xjlg=98+TaSp-l3ouH!v}SVx|;caMu9cMQa$4G6It}9TeBxaz!jj z5xaOi8f2y-H~PO17F{j1Q+rkzilZhkf%A{rCv)aJaw^F^mPJx4AvM5{bTvo2Sj)dkItFr_p>4WtdQPFN?z)lE&L@l{KuC86no*cG_rE!iPsjH zzhJ*BBz&AVqON#Yl$TSJQ%RE=tC~R7#>_{od(@Mm;x%Fr z%7+z68*#2i3SeQ8yC(lrv)nH5IMcyea9^pz;rtIP7SLX{V!>XsvtNF`?y-08-bp7- zjYOvrnt#}S^E(7ZKod{tR0IYlJoH-iWtps~A)=Y5$F>xmnCJsJ#V6+FIiS>p@T9K! z=;T&P3c`wk|bL1OV%p@k@=uFitP3ld27%rKEXDi9EP@I0r!yz~D=S z8lsSd8xcOu;40jX&D7C%V`^(DL}iOW(Zbp~pk`#hKDv!mMcLFZvTln#amL@9Z~bx2 zuZrIhKKF#yUw2u;eCE$yArK4sL|ZH|nEso=yC#~|ut_S-z{74ay5an-d^29q z8`|JwFmo73j{jfjdX)=M^ih`k!Fim750QqmUrp zBi4Xiz)7un((Bi&YDqx5`F&=2YQd5--@gYANf>Fd)^)70-<1tcPKHJ#IGymS}2T8V_w_9_{v)=5>n~ieNC~RbCAn!f0Q&9srTh0Xd6O0%@P_2L# z9jSi{U%x&=$}8hFjIbQJgK@w$ccYkjd5I$|Gd$>`3>*(_VwOACqlJ7P#n#4M?Q3Pn zfPBsc1bC3@efH-Etq%ek{q*T%M$i2n?|z1aR`mRN1U>dkqFz|yjHL}VG=dOu&AE4E zzDMx7IgidH{WIe@fo!@*aNAf+-(XaRVsT--^5eqpkh~~s=0Ka|8U*VXU5=|@zfA`8 zWQg8;FipOitn2&+R#Y>mw{{@jGwY;=~-p-p&LxWHT~X zFy}&cokJMUJ@4~<(;BM0&Y(v1es{;)5JU{hyL4>K}C1SK45PcM{dJ^F_Noi z(4)tVlJ!+!PdnCN#nIb{>FEY&S21v-?3j_dEMA<*snXKcp6}6D{keWTtYer0&S6?& zvbb>le-F!}2vfG4rV0N2eRSG+`Pr_ zzt8m;^y70~m6v#oDouqE;4TwSRn6z328m!kDLab8l4o#D`!Xr5EWKSEwqpEpY$Itv za}QcKkBoe(?}C5tR~&ZuBSDz$Cg9l9nYh?!Kc zYt7fC)jjXQ{)W?M&dBGN)_1>3^LO>+nh}5;nIR zJdVWRyl>EQKqwU)8k%G)s-D>|G#WQ{qAQkT&P+5Gu++ro+sZTLU-#j|;JTQfShs%t zA&VaoVZT;n^^}tYpcFjtuRkdjXJbAR`rLNh+(~CVtWlKjh>VP^D9%n0`7L68szf>c ze9j{7Cm3hcfJH1n9M9KsWK|s_lf&=@<@;AN3N~8#Brq2E5M!=ju23a`cQ&`vfDQKa zMd9?JGu*a(U;Ni!_xOs9@`oHRqHf5&2lv}(_jUAEIn+D336q9s^_)1KpPcr~FY4DZ zcCDt?n>}6yoBKmSIZU@3%<45^qTC; zvpYmh<|O?LQL@h$Z?G4MGDV-?lzaL>^qQZSSd{8{FW&7iL+NP98jN6qkBmPZK^ZZZ zp)wb%q|Uu|eP?Y2M~q;)>WxDNL-_r7u+#z(Fe6>NSXr$XUVVA$=h0}0t&?W*FD9-i z)$7hiJ$`%=9VWh!{g^q(q&IKkU$rdH83l*PJgvI}~y4soXltb}YA;vhJTeb-EMe7CU-max2 ziXpt2z6};9rNM8Kz*XogWB7Ik<4%+`e^p2QGWVHwUNSoDWaFpD_@NFE^>X;mm7L4p zwd?aAm^Epst=%0U;QG$q!#FTE?j+GZEAgDxf<_6G<4nTH_a_*|9l_8n3KCZ4<;w-z zie2~+U_7~$op|2sWxeG)#^7G6qRv$XSaBzu@Txz-G(%a&c3&q>*O}$-4i)W0IfqG; z2}~Lq zDpR7gBnPUMLu2pQCcr;0rHH>v1?_@`#2@Uh>FU}5O7!Av@n0@0AhVLEe&wV zhGCXz!UO}wokh=1d2kYQK zum^ugsVy(o_i#?f&i1v$p_8{&`T6nuhVrk&uIJ^AO-T8$i)CNCOXs#SP+IX4aycmP zAIwcC<^G4ITF#KU6?MRErvqowFJA2EwAv;J6tD2vvv5WnSlAREOYA%Uff4}P9z{da zf+wa~oxbpCx2w!57xYYd@1RP6RG??gxX>rA(XZpG{98>twcru2?upBRpo0|H29QIc zLRl?&CE2;U`f=5_^XdGV^0R?NNyb42P8V&1h>Q5m4Un>g_vU>+e)?%I$7mKtMPPv+ z4V+o=_U$dGpDa6n)$LJ!db%Z$()olFJKAwTZUK2X#g8)%>F(w%U^D8Q_gOv9BTgO3 zPyk9#SzpxpjkQgb-#?On3#OzN}y`nYq;de=3ON32-f)kdk%Wf(9jhfeSImnrJ3?|ul> zZ4Tkr1ct|5Jyz^@Cl3k#}Gh%m)()-Vz?alR$!AyyenZ=S&-N=}l}x zY7Y6t6HhTwMEGUzn4{cwU~NIlX$Fl1yP#^4e! zsMTKHOW2#rRJTJ*6 zv|9{0rlalM1TH8|e-aWjJn}CaO(>l$amZ_S(MOx$}9%W!(vX-h@JlNQ(>%w&al`Px`pZ_Ar^ zm&u#1{`K-(+ws5Jv2o)@7`4GDuaD>Ld11+IH1d4Xg*dH$ecxa=&Y~UVH`Dh&mV0^4 zg-HqfBkTQFrUfThO{3SjvuVXc+J6;MToO6(Uo6MD3|grjX}{0=`zi0cx+TZa+(i=r zXETkF91J(HFNw7NXq9cO#q_yzW4Uxj7uEHYZ`&=JT8fQw!ogO?G0gi><`qt+Nm!6l z84BV2a5t~Qee4P1d>x_AQ86ePGisXwX^NL>Fe!EA+9S4BRyVQcc7QMc?@myjBm9I+ zhH#4s;9pZ`4+LX5LyYw@ZbocJv90RFb zGTn`=9YReLkMO*u03q^~d(EeCH*h$3&9VR6f7_9YMzJ57>A)RK!VZry{bWJWe;e*b z`#+M(o`B14J(Av66b}q##{nDH$v(ZPV6D{SNC;vG+fr%D&Ce?6a6Bj_B?Z1gJW+Nw zQ{Y`j(>Gv78A0HF{MTzATO|*Kkpq7?jGJgMZ@tuKf6>%c@4| zWIAXhG;!t+Q9Q93dF{B~cZo7A8jR*xADU}3+L_}a^5#2CZW>K0`}g0tK+|d~Sf@_o z$M3<+P*^!wcZ>#98tM5b#kMCNwcdc9{57FWwG-&b4)1cVTtJa=w9D?-|f1_m@8KE^G&k zsh)Wz4-NfcI*;jI6V(rTYYP2{)pYn1@`uDvD>71kOGAGx!+d>DDr=!Trl%*ha*f8EEny6xJ3) zl>o!`{JVY!w@R>}JPqj|`!vS>fLSeuUDgmSTrlN+|2DmSEY-Ah(hhrf1P31kyT$Z% zDS^^v3Dx`J+0eDBsbf4~z@@yqF|Zo+GYRh0;bb#CYYNrdpnaa`p`^bB5Vb*jNZ-IL zyuXH0{T&8b@)bIag35OjpHWZR@nMg{8}nOFKfQrIM2kH140>+j!v3Pq6Ie4WogMtG zD2jt)C)EM_FkQ-~P98Zf>z0lW|8Uvw-%tcLJXJvI>jpH~3g93M-k*vmwN z-|%f4N76$To0V*RYWRj0;!{;vP|yjPUH1uR`d)v>59}m*=iO0b50Bd2nWmHyR`&P; zfwf`zKloM67C5fx6^Y3~0YSS~2J*kW@UU`6V}#`n0!66ZPku!hT(?u4jAC>RFOV;zO>f4MS?Mx_kigWFas^GVu{hTL< zLkbNznlA|w$*&;{%|o^5f))QA>3VdAZ*VXBcH#Cx>M6XC4^W!6TYiK{LwQpPerFrR zT2|UOEh((YfHvSQ;5*V8@Psz1us!9?(7r?{Fi%!o+Gn8Y(-UEHsTSLqt~`Zy;|Of; zHtI8?P`G!egUKmIMQ{(;vy!wKJu=K_M7n^dTkEi9z+P$_1X=>cv|2lWR^) zlH~mT{ASAg9NWd7p1k1QWYtYu1bpgHUo|dC#T@#?)TGa=Q+2whFEhV#Pdj$c<$3?|gGBh=PT(aIboCUDq z)NZqg!=TYdpip;t2nRSJKOi!mY;T(KYg+{x2B5sfYg-;H;F)hXds2EA_OcetH$;JZnP=6McmuDBYDYTMo zP7sRXQ-Mt8m;5pI2w{f%n(g@AOH;msV%fZPahpafp5{45j%b|n{o7{&{E!{b`*EBG z++=W+#91L(-!JL<>vW?q;3i`!i=~60oUWuDm`lJF7*?Z2*8@PF4E@KRVHx+WMXN_1 zr%$Ba?r^)Il7GD|Fffox!pLI+-e~+?eWzUdd*t;cV>p8+un1yt>CB93_2;^>B{WY+!f5S2|8mCil!;q~d#^*BpI4lBOXS0{FJ{%u=+;q1JielJ|H5 zee`ah-}}cRb4JDYBa7Gm@{w|q&-df{Q4|mRBe68_z%hb(#Aa4BRfIbAfS*wuYL!J;k%%$by?@&Leq;|q`ATQgxbdiax)L%o*i1xLmf9h7R7B80s_|>L zZ#zN+%nGWM$jB<8CV8#*Qq#_tT#rksq%*=tCSt-8EBP-LZ`F4^#QMT90$%c&H*MKI zn|Zr5L)^fu#s88Ms-dnY@sVFWIX_9t5Do*gdL4u2dZ1lo)r6<1+XX?19i`YtZCA|H;X5guWgX@s`eiPfc*X}>S93L?#- zevcmV?c*>>oea}e6iEgkJrrqxP(0^gK|&?fkwGY&ocT;nrxs3GQ(kXC9-*_StZeSA zwE)L2Nsu^uW*NQzc)km)$5>*@%&Z@cV29849MUVmfxK&@+;}$^$t4JP+&y&V>kPO? zii+ct3Hl)b(XB;^o58z4lY#1_M96vz(D0HtXo6jZ1aWyhTziCfySSvf(&ksZe}7{9 z_wqoZUa#S;#}x7u*Y1dZyz29ODKI#s*~x<&Y8f14Hi4&NVRZV&A4sc@T}17z`YM-% zBfMOgZ$nqm)~Ux~o#a?t>qxgMZLci(J6*Ks|$bj)l9l3S>l z4l^#EUY1JQpjxsAT?nuGRi2b0u^tsh*dgi;TD1LgKpDrxFrXU&8;k5dtkG{q7If{x zzrhJwC$eBrh%`?WksQ5|bP;FEE3xeTtl=yXl={5|)e0mrfU0pfc;GJ2F8L!17PNn? zhBHJ9=1VT&=Kji~lZP_gGs=7UTL`@i{Z|ngY}h?P4=>+y4~1efmz_$S*Wfj4h9$rD zPWVHsdGlcbQsomcuhDf~AF)ocbqP|j7kk+>&=B^m zl)WtUn)&G=pg#qSRJt-cWY)mp%L7pDtnFfj5x2R zr`rZ$wI7SX%KH1r;0>EMhv;(fU2Xn^?;LuMzMw_(=8@QR@i+~kslzY0O?F{IM{3ly zCIaw*Gk5n-0FOfVkih58n%B?mE}Np9sh^CeX9jmWoxLt3x?Lfn6$jdWW2ix!+YT_Y zT}&k~n&wi2hDv^23v2SW-w;LE4MzRgw^USB-TVHnYKS*`LPFc8)i#?UpdRaQ^&zEM zF)q0Fp=`g$=Jb@M{H5|AlV(B0wqCpfbt2#N`yCAx^4kvqz<6{#)UsR0eTMx;!YKSo-f{?}um8z5Kgb z$5cEt95>d@ja83h=^Nz6$RrSq?$!NcmmMCg*eBkC3`O$WcWR)1Ac^(4#$#n)9}UGe zEG6S>*VUM%W;oRLZHtSg6%&3HR8@g?uPr4x+~Gn4zjl?1k7&~0MAN7Py)E$5)^+PF z4;}ejUTRx)sQV*BSIQVejCX^&HQ)Ko>-zcOBSt*_t6O}|?d?{v!Ik9!W53VfWx^M? za!_Ts@rt20+q`?=<#_sa$l-SGz&XEmFG6c!TV3qsS-xlscuvT{&zUo`|G%=%1g^?D zZU3ifaVpEnQd2}NcXG*cMG?}}a0A&?QZX0Yvk-+qghtKRQdAV&Q3F{;#$9lM88sC} zM7C5wCPfhxEFlpQ{@?2yj?L%u=QH!Z4B$EEd7j_zzOVbbuKWHiCrS_j25)|%irA3) zI0%&3EsI$c0kDgdw%ZZHWGrAm+XXWVB8JUY(C>o}2HxR_hEOZlYZUk4KQ1;HGNQ$s zvdy#L4icy?dp&KA40iCnRprlrJj|UQ#g%2U)ho#hGphYy6kKB*KS+)`}T;`_tiiT#hTa!&ZkFTG?{a!^* zQs(_rPYO5k#c=I;>{#EZor4415vFoj(R0QBG@gzoPfk?esKE(Vnfv9!mX@#kTCG^M zstndUEF_!EvY0+`oI8`117K&mJ10d3c3Qr5bkvBk*O7@s`4V6F7O|N=^KnLp=8kUk zDv!R%=6!sA+n-hNGo{>(^i7S|dELF-@@Y+t=l^EU^~Hq&PbQx`dp3s9AM*KzHw@u+ z|7+YZ7^cQhxW_Vms#X7Qc2jqDW9$)6Vqzz96GZP-uv4?9O+!5Gg@BBu?d=B-x-ol& zz{kWWXFm643Jg)R|9P|L1yaT)-=I|58yz@^@+wUw zDI8teWQ`~CK2qr)_c%Y3FRza`KK-`vw^t48z5+%lvrC(!GKbBuds}&gJa_*@#px_~ z>i5vQC}K;w6K)vmX3m@$THF#m$Io}(od=VOyE<(1=Dg_%lfhfW$a!qCCN?rliVQuB zu|%8}=t??xHcnTqh@7)Ql$Off1Rm8ph;0-oiBLB2PJ2g&M2h(!aXooBeZhhRyo=uV z95Sq1UVPi&dm7w#5wM5UlL-Q%$R89&bC@19Wm=QkDuQ!t-DP6YV2*fKQZFnl49lo^ z?#|AqW{8|uj{!>HIX3wEufKL#Sa`DZR!R!OSm3SpO<8rWj$u23nb1ji^DF|l$In4)ewd!{pt zWBSLY_3L%yiR3zVPe@^4eE|IOP%UVFTgm1SZQ#O!cEvLQI4e6){(((dWWRw11KDev zjsH=WklX>?pLCB0u1H0p7!|velj91_pT%nWs8OR;y%P@{JsO4t#st!u{7o?sfFIIh z2akWfq>FKJw);tuAfb*?=@&CI$4NOudgu+EhSXtU`KI05?*bYSQNKK0&J-X z1H|V6%q!t$$^aRm9fTpF%-rxNWFK4Tfj{BVflqCND?J+->_XTvva<+^C>fy8d3r~- z#u`+2_5a>!f0&*uf_<4N7y)RUGc7IC8G@ES&e!)i*V4v4q-NoOG%k)x$ZFE@f5E(n zU1igcnpj$x2$g>EPk-zrF%$xbI!0F*suEks@6KW#>NVcwy|!%^eo_A5C}-MHNe9K6 zGWwmVFcU!^Ku7E*fvPx=YWYTs9`gyK1M*Luzwq$-p%EMqc;RS3VEuESS6_LhM4uB6 zMfmKwcEo;BXow!Rf8;+Y^mn+m^zm9*P_Xls?A<(NA5;+Z}9ENv#<+MhWn zbsxZbLewmq`yJx^+Z-M1cj#rqHyPBEs?vddb6MB5{_WqD5gkAuE)EgL9LUQ}+Vko9 zI{yS(6j*Y7t*1p1)`RPqEJKELAL-bnrWWYNiaaoByWsn}%u!|I9UL;eZQV2ej*6ZI zC(Ie}!d+3%lF5a{%{hd}QYg0Ooq89N23#Y*ct>_28U;+Wu^60H5Mm!+W&vb#jx%=H zIe^wRXB(~WiZ7uLb+%lQi3^r4kC;J>x%@yd=ZL`&E5&QN~;$e0JpY0Hr%TA*6MNK zRh0B?7}C4H8_ECG^W)jLi8nIqucgCS(%aRgXS8rq7mcAdZ^4-zaaE9j9;VGz1qIwa|1&-uKP=T9i7<2~Q zw1-bO7sDM)eFWT3JH!D@*^}UfU6xdxr==~2`M=aP*W5ypys7b>)m)B=Q4R{tHS{EBj@T|0|0tQmpG|WaP9Zath?+$JxLq8>O(|YJU&csV&L;?`PA@3;`ch#OFH}~icFk_30UI@cG zi|>3v*AI`($r?`4lZEy#4DK>-boii&^bChmwomOkq4?s)5!f@1?6?g_&}4A6om^>G zpAVY9Qz5TN*)b8ik^M4O>V@hb@5ou#s0%yTlNe7`9PvNT0D#)hJI1j-M?LLI+;aV_ zl&u?k`ZPupHgv_a+%As0gNm0=+tf?YT0$@VWHtN-lCV(K}aMtPCxufejGNC5iLFa=u)6sv~t8EULpT_=V(LPB3-D zPO~W_`(b*@V{GN-5#jnsZxg0-djvCl6;<3c-An8xq zWXiIDO9MoZuvBxHl_LWIZssT+TotQlE=GO5qVt%TIH$coG9omda8&}2ECCL}_S2;f z>)borTz|<>-IFcBt}Z**!o!793Oc+4bBQ9R+brT)cef{*CRg+UC)!_w%5k==UwHq1 z%FGyc-9Xo`tTbDxicJtU#HFGBr@X2>J)IXk*80%VqgQ^eFkE8{`ABKI0`d@p7jNFY zS@OkJ=x_O_oCupnxu8MV>gM^$th`Sb7}{B4F%>Trz=V~!aS=c0#5u%-mX>d(ek$HZ zPXZP<0t*BcM``HzDI3@fFm@g6Mb0b+uk}t$86QT%#f}wI{A70{%lbs_{N4da{(B44 zOZXmp7Z@WstT9gHdT%}`ZcF<`yORXWnZ-SxR#(e}rXl=sA#*?fe8u3WcixpyO!ct= z*AGV9`QNp^mLhr%Zt)sWpcvnP?AeqJqn@0KoV9Ze5w%@+#VNTMqyy5%H2nN`p0ufq zqJ>Q6FrH&HwF#;jx)H2ISiG8^zHHxZoLT<;z8Hv;z*-_J#_3aG0{r0=id z%M5zNNng(R70F0eZ2tt0lqrmL60R+V`1@RjR*1vb@@>`}WSo?^J`6*S`2hE3Rj3;u>A;+iel%?_D)a)-DgGzw)nYC0h4jGXgG2$+_2I2PzO^gHj_n%SIW}UO&$g&CU#nJv?qB|ueTT0KIJ2#Bm9+uJ8 zEjVrVOLu@w*B~h1^1N=zfU&Uyi+jccigy`%Svt*(%s$>i-d;Mw<&U?g-$+^%E!m3Jwb77aiadhtY(C+HL3iIUG!6+*>0t4x=NjqqRbTP3 zPf<#D#S%($W-h3z5;{kaP+km;hp}hbXQKxI)@8VsQVbDmlKq}BbercZAVGpXcff)yK>OP(A|bADH@lU5dwZ7XAEefI_q z&>v--L2|_;_+_WxIp{?OP?obo^wz7(dj~MmwUl~9A^|zp!m{&FSllS~IJC#`8bEgV z{lH+Opkeoec=rd`TjhgQsU#JNjpc;Hg}cnhjb+PFLs(e8%LQK8fSN)R!jlV+sgfzc zXFg@_lsn~ESRxZmyDwZu*M}bV3>iIy7u%|d(M@*Rf*G{DVRRehIeGNJMVskv14oB?=^%Gz5vp3tOL3GrQ($M`lcxeQMMct_!RrYo*F*F&nT26 zp00_bER`y0w%tTiqZ_en_?tusvP_ihs!VVp*Qb|!VHXUiDg{B#M@e#c({`oZUkKK8 zVxPOxaib!D`rbt18w|hnpHWq^$oP_m@BpX}0F^UVcClK|QGED2uWsaavWihMAq~iu z%i3&dd5Kvl!?0O717~v}=djiNK=+@%G6tZ->6@T?X*`6gw2u-+-rP7aeHERWYlC08 zGn@42$O4&x>p`6m;NXvYXTT5a^(p*r1Q|6KS6LP4!(yA-3!r10y}0(C+$c9k$Mq7F zfn#MrH+{~-tjrQbOtO!$o@KF?LY!R>Z_oTU>?5H(G0F)&kB0l1`cM3=`tmLBKVZNd zayacHS3gQTDV+jJYk)gB;KW{V$1eeLXAU`8O;xgH zB4y2ZT4;RPqU--=`|B%pQ5jDd?QB0ApRpXBzVr2c-}3bfzkhw}bb@>Wyucexn&eq5 zJh=z*GLG6`JOX~K$0SU==4_a%=_F7v1Ck?bH>{xw;( zpTu&cWV_}CuN&Xx!b{Yd#_u?OS#BNLPI8G6VxhTb8KKMuD^(W*_g?)}Z2EZ2&p4c< zibD)+f+{j9C%+6=@?;zyb}F@W3I0f?CV*?}QJ%^)C_X~9*fG;O2wz4HH-2^KN~06L zw{e71fcie3g9y_eaF?^m>+}W~@5jBT$CYK=LZ5Z&Ux6zfr9|n#7+$6XGv5A7- zG!{Z6tK)=ep&J`4R9HuvHY`oUeHmc^$oC;#bJfhG3E=|@G-;JU!31}``Win z_v6vNtwd>DmJyU2Wvr$!xVRTDJ1Bf8Aj0?$eH#ODvaw`Jz~hpbBDDC$LwdBue4_?M zk!gX*0rLM(38->a8yRTeuY3BLd0B-A(Mrb*A!E_YT6P1!h<1;dZhlk-^F?hf+UZl6 zNgtG~&UBj0HbO@8QyOc2#ZTnScnx`k$CgKe29Q`s+venCOh(u3t;RxVW-poFKXCIBeE2qz33u)1Uh8 z2SOOXz2FIQ0SWF!h?`H%l*v?niRhztThQ`w<$2=p3n*QOS49U5S`RszIiisi@ z{Ypg_&+7-Z9su0v$?h(=j_HMG?uGQmBL;!oDK72^RT~jueB+>5H%*Z=wSHbj;qAD% z$IsWLBz3tvGoq`N)3*PcKjhq~#q&pwvm4>kZPf5FueBUF_q%R=K5BXX+h0azom`U_ z>>S&E%J1Q;-8yaAoPFk%;2%rE&Yt|r_w}29Pg_9C`n|ltv)Udm`{C6Zzrk(F{<}QG zC*f4#n-ACdo_yNFV2BF>*v?_l;kLm6$<#%05({t$;BWcVx|L(seQxopzo9VX7Cktj zo7%qS_r1Ap%1tsgg&ID+FR*oqFN50||9Y%(v8GNoXE-}oFPf5{GqNOCeFdC_jj7(5 zmH-xkmClUj96zf7MjwnEHOhJ7L_O4aat~bc7mT!^910}{3mB8e;$fQ)x+m}-etnf> z?2S`;Vz=gUHZoO&#xy4sBW+$HFF5&P$q3UTaJ4Wm-ncFtg~d$BOtO_0F66~1!s5r) z%^$^whK0>#&nY-DA1Q$}&;{^IiL0%H!oDo$UW?|<?!; zqQu^~I#MUEXo%)^uJSwLi4{b^#GZ+x6Ru>ccekQh93yxQ%DeK)z={>8yUWgwO@B z{M~*H;H=IV=yOplA(0T8_Ch`Ae^w8|jqkGi#-4^{?wE7^p;~cD*Y+!v;nQ-aPH<~! z`Bt^P7;GHdu0U``q3pnDgF569+mc61S8${R4~Djij$sRS>e(}KWV$Kf#C0&oo1B&D zo`9|Gy_xO_W}ZVGEnf=M6CLA4M-eu$LiW7RS=m`^0(Gi!DquyU#3VEiaRY1CH0CkU z6zwG0Q%w|{PK7u|$3A?@m*8An6)rqGnt(AtjJK&ST5enYlxZ@uWW%9aAsk6LC+2z= zPd9GIpi*?#CKkJjb$OLvG6TTn-tcqX(_OQ2pG$Hq6zLmxbJVP2ZsC8 z{~>mQvc|>FFZsce6XIJr-Tu%p9Y*hPfzJcHRo;X_SDuceXH%@Nm%8NKP-DC z0~;{p#C^601jW0FPmE8wsIb9cV<`IiAf7XI4QO}+&1b!7Q`EobG4--;Rqn+}XjI{w zzyvct$-pVHSHdA=K{oD($WG&k*83+pAXP6% z&E|}!n(lx}dy+4$C_#K8J`6a%ts4259@df6f zqwQzqD-?_^6I(cX^qTS$6@%$KZ~^T0>r_(jgA|XW#ffI591Pj&8uhC0&e4QpNXEIm z3m&KGj!wq6bzE&;z4>pFZBE|EXK*7T^pD8l+uWH+{Qw zHNJaH2QyeG?}M$~k%uJ41Io7~Hah&8-u|6;{$1`;eUVui>U*cunN9y-oJY#(>FKOx z7OyPLJc8cXcwXLEc%8zd>cOE5wbe>Vz!lVb-jWlOC9*2KQ$!Hne@TrrzW?rjnt{Uc z@w_P`Fvc;y<}{;TDSmb3w{ZOUJ^FW}wZW^bzNQ`*K0(oYP+4*A>tkhf7+(dcsH(#y zaW-|6ZMjURtk}fFM3})HOD<6eIY6N`Y`Dxn*0iTielA;3`tE0k=LwtI!G!;&ROp(z!<^#-=uVlpqgv@>Ub>b6(~R7R`c5_NV0daInwYN8*@3$6= znr^(!Mf>TQHGXF}=0gRb!Ua#7+uXTva=BrlAQ;614H4h^S%290AN&LYvjliDc3@w* z3qayo01Zr03#b0agF-hz+8;mZ!?cX(BWj~!S#WOX44=NnH!2@&URjTBOCq9N5Z4EP zne}p$LA%u|qeZ)L*<%Z1`TS1kRO&nmgw5*B$L8GsE>bC#^hWX*Y3|JPn>_mRn(%AF6Kk-B0(?PIqzWrV-Tfl&DG7J9(C(2+~ZaOc4C?_W3KilCof zEarKWND-PqqxVIc070q=JLOqHMK)tSZ2q{=e)x#9iH}Mm)~UoJ3;SFq@W{|frY1h* zqYIG(&l~fs8FIiP^qe}xw62DjA99hOI!<9bDmkHZ4ws#l zo*s&if+1OgggpH*v|*KOsa~z&v@mI-7_*EBzI-~WfR}=0^Ph&X!FqqZrwq&pPq0K4 z3p=BH%Pm9^>Uw!U;gQz9X)?o2THO%14OU_4p3W>~(nFkfAACnB;z*l-%5f`Kt@?<8 z;0}X+Ujbs6>FtvL@AV%H^#(mtu4ME&bbWqs2%|VJH6A_wTO7dv&j0i3ct9f_GzP$@ zd+4W|X!}y1=q{-dqiA(ku>nj){mE5|T4FlxW20 zg?Q8y>$}v7xxn4fty^Qc-!H%Gwu7S>0Z3Kl1z+O)_PTuN;6VgE_1(q+243rA;vRaK z^QGYzCd-^e){`uV@r8qfG^B}=L&i|(6FyL9xws+%4*5Es+A6K&&`kD0jwrlqB| zAl19sLb_rEIUx`_VD30y+b`wmT6Lf^apdJJ6JBj$2E##d9a+z6xZ)v8v4qHwsYlPS z&3AX+Q5z0s+qu^wS7(l^cs*m#<26tKJd)Ba@>fBo2$;#GFg5wd%^NpHz%qSAKtQPq zeu`bT&*D;-$s8<(clgC6zu3jDUlLzsrC}zQ?z#2S>VNU-(2tgT<2vtJ>a@=0&n;PF zKdY|drv!sYNfnH841P+w?*qWbI%JR8Z`b#)e>4JgCCd`Qd!VPNF=8dh?Cz&PYPH4a zQ8XO4YnAe$smckmN@tTO8PE@11x+p=oJ5&Q>~1lK54$j!&XHWa7~CMgv8LG|M#wC2 z@ZcvAx5v+uE;D6HIJMl)yXs|tADc8~x57SjZ(wE4T0R>(<;?}_INmF%_r?xt%R?O) zTOZC_MMG?JzQeg<6Ld3#R;&taWqLFQmtMpOOdzM^TC)!!NP)X5J?g7Gq=BognQL^w zJR;UjHK5ifmm+l$pN~u86r1I{e)jtn7LhEFjbZ*gJqJdY7gBZc!Dq}ibXT({!>8hb zT$=;-$75ie$BpI4=)CFcY&zKkTb)^Rs%JG|rD%mIF68~(P(uaHO;1lBL(%ZY+i$Cw z?_f{POS^F4Dtn>zd60AH=FOdTYS*)814p{DDaW(KD;^gBE1IE z^`?mf(7BrnW?}5``)zgS!_4Tgsk}Or;i)VtzW^nIiE zcvX7wF0d$cQLn$gfyV3-`!$-7ab&^G+&N2-_+$#F)o$jKiIlyUJl-l9iRvaloTq10 zR{s3HWq?8o>ktm#{p`N!^L%6`jZ$qQfUu0i*y>kV^4~2J6WpY}Fl2MnxoI1ylZfi1 z9G6Lx9vr_izwbZ|%`eeozEAunv_a$;<&dFtlveARk z)x=>trkj(Xp}gqX&iJ~X@i}owqsjT2;i@raHFUCC-m5{ur$P_Tpci>@>sx^Zur8a+ zA5;d)LyTK6c;^uSXy~?Wm<)#BXXJ+lHLz{(Fd+DNCtF*O5Y9t*SUHicm(a8$jfsP# zdZOWI!VCaj26?ubH0K^E9=xqEWt!)qi};;Fm_0BVU(>+TpM}-ubpe z#;&>uDXasUMW&^tb+A|A&p0!QW&C#z+F8w+wspISFC}clkh&9HDpSA;@ys-_eOlN| zWBtc^K+Vb8KyFs=(&*8b7x*-P)`t&DoTVaYol(KG1f-gV)mzl#Macf97fKUbHp#aeF6{L0#=V+cJm1nvGOvQJ}>ytUP{Brfn~2qU$?=SD-%Ltn}iJaTPx~ zbE{%M_xxn**UuV)Xj}_31P^*isetNUQxt6dzGliL>21kP%#IFj@vgW_AYI0f9UBa> zqu4`v&5oon5p8Dc+l0cB>}`JyQhPte->497%ChHY+?pas*k8l>^wwAtE{wAWN5;Q6q;bu_nE+z)vBxWVvNh~@&|5?L31@9y1B46T6dhYwW!9z4E2AQ4$S zc>HtMKIo_+kvz2%wTDsyXYRT1FF6w^xspL@*49 ziU@hzI|G_2I`5eYc9yQ**&yHqoyf=YHsjFs)*gBIdm&=bVbtwbiP=p(K0*dreXa#= zURBqR&Ta~9x3P}~GJ(}-GM1?LeWNy4wdOI)ckSMNjGS?-`v-scGv;(6ZTBhp1@-ry zI4#US{sCP%Z+6k0%e(#wj-Nr zU^-hPfvBI<+k=pbV~*V&g{3xb-@ePgS5ZsvxWbr(9A3nmE=$awlJNvd)%pgRC3&Dn z`kyvGofB-1zK*-2gFV4GX1%|u21z?J)}-VaQYZI7++tBXvZqv}flz8A%NT(=wTpn-Q zz;hW4$3!`@tzD@gg155va7_9+gvL;myI@sY{NUHjUWaZzyg|JKRDNr;i71=2(v0bY zZVFi9WS+49V@)`f@c6HPUEMt+RP-7Au~OM(*|SI#3`5LMonc(^sjg-^#c;ek8;BNA zE0n1@gPF{WzuH-b-p?*tIk2VqC?YkZzr#Ht%QWc7VpC(|tNhP}_^4=7S1U<9c%oL% z&0BSDxRXBqcw#Z5Z;ucR=>sY2tyz(L^O29wva`n9ky;Q`f2KhO{AL8>HP*9*P;4rC z(=~Zd_&$yE<2LR4jp|lbAE>MiAcE=Pp`m+;U#Off@aSLn)rYS5?3BPjCVyO;Q^+?q zwU5qh>oxrcE~=2~S(CzOTPU1!8m9p~5w`uyyBlsz&Wl@9{h8<(YVb|r;pJOMNAnoB zBNrFl$#0Dw-wWM99t$;&&}tF<6db7uoa$^ibLLE{3FM`Q=ELw7l>DP1*2EoEU||bf zB{EqaB2sI3nsi6?Y)-Y#d&ZrM!hF!Refy#O*y}R+GDas+Qdoc-UcmlMznFK9VOch- zS992?yZd{R<*q^q`2cAPTss<#d9qE^RiC%DZWcok+Z#HJS~8@;x!}`sNrMb!coad# z0`zLsijaSTnz%ITKvh2TZcJ7Fc&LGH&41#k2sP)PzX9e~8`!>m-Nc^17WInpQhWT* z=i9+Em8S*-Fq=YR>^#jrq9H~d%cXS#w=)0t>q8?}e zy4HhGwFJI|{2pUgy>00PtgfrcOCfIBzt*X?7(FQh0aw#%{4n$E%*BeMCTGqnSHyd* zqv^vnTVamKhFb4HZn-yd=kxmxfnM8a*u5>k45vKoBQ;sPTRy%&y1I-ubns~)+t_(T z#T?3xBUtL*Fom!Dy}z2Fa%#pwm~D~s8Y9cUt2o@3W4K{(O#GY%y6NcnoI`>ej($7s#s z<;=nAO{d>b$dEP;tYfHb@(Nuqi{uL2D&SL4(LB6MJN zxxAE^T0UBQey}rjy((@@p}W;-k#sNI8F$y-dnXr{g+-0t`ZF+3qlcxCpocv44o2CM z@g}9VxThawcUAtP3|GIg#z#K2@n3f?H1OH6z$_&9#SrF1>Qbupv1K@jCH3&4d+B?* zL|M`E>&(oF+>Izn zhL~81r`fRL8X$2gFYj1>l2W%AJQSUI=nMFMd?uP$1jp`?FY1w^Pgt*FDfRhqpr88v z7YkJvNsn23M+ntg;cR*t(Zo$^u1Q7VWNw9R*=dlw#@(uMN9zUe(l`>g*m1R^@hZno zahSw7?$SSHTqiTfVj)W@NiyC7yCV%y37bKg-bT2J3ax5a{nK3t8mDe2A;DeaNh>8; z0lZKnk?2=KPc$Q1HfrN*$4k0`#>H{5(YpYSF|a2PbvgonxN^FM)%#Cc);JjYyguZN zubYLB*;K7qpYp?shQfeBE8h5F0r+0|vdek#$?VQC0WTK|rmParX|BqHtECa+aodx> z%snEnha5l=?W)9vQh{+d`K0iwX$!?#yHsK!6wOu2%SbfR z@rdO6m(Dl7z2kFp&24ZzFu3;7P__F}q`1)ktCYg%pWRNMPNHv*+DB6`DFgS(J4eJg z7Le1<_#(&e{q-WhOTR(1;{e>rcr<0VR2pE=@f-eY!--}r%ss3ljX~uk6h9pLeK;wy z0Lx%AF9*|S>i%NMIDQ8rJWNTW;*tpel2ZDZIqIBQI+%7G&OI7K zaqfmp#?dI5Y5|C+>1nd^$o%ODm2**J)FHR8kCGW14$ zF~lR<)}6W8H7H!(w|{wynt!Z`i_jDs1s&2n2r!=J49vLV($+3BhYO5`Pk*q>lCRWnDpu` zdN7C&Zng1Z2TDfS#ZmJ&QYvPeY5}{d7c0wj)u}e!(+f&W8PfC //print +#include //strncmp +#include //errno +#include //tolower +/* Posix */ +#include //warnx +#include //exit +#include //chdir +#include //opendir +#include //unicode strings +/* Internal */ +#include "parser.tab.h" +/* Public */ +int scanner_init(void); +void scanner_quit(void); +int scanner(void); +int scanner_scanpixels(int*,int); +/* Private */ +extern //lexer.c +int lexer_lexstring(const uint8_t*); +extern //lexer.c +void lexer_pushtok(int, int); +static +int dredge_current_depth(void); +/* Mem */ +extern //lexer.c +struct dirent* lexer_direntpa[], **lexer_direntpp; +extern //SRC_DIR/bin/tools/apc.c +const char* cargs['Z']; +#ifndef DL_STACKSIZE +#define DL_STACKSIZE 64 +#endif +#ifndef DL_CD_STACKSIZE +#define DL_CD_STACKSIZE DL_STACKSIZE //square tree +#endif +static +struct dirlist +{ DIR* dirp; + struct dirent* child_directory_stack[DL_CD_STACKSIZE],** cds; +} directory_list_stack[DL_STACKSIZE + 1],* dls; //+1 for the root dir +static +FILE* current_open_file = NULL; + +/* Directory Listing Stack + FILO Stack for keeping an open DIR* at each directory depth for treewalk. + This stack is depth-safe, checking its depth during push operations, but not + during pop operations, to ensure the thread doesn't open too many files at + once (512 in c runtime), or traverse too far through symbolic links. + A directory listing includes a DIR* and all DIR-typed entity in the directory + as recognized by dirent, populated externally (and optionally). + This stack behaves abnormally by incrementing its PUSH operation prior to + evaluation, and the POP operations after evaluation. This behavior allows + the 'DL_CURDEPTH' operation to map to the current element in the 'dl_stack' + array, and it is always treated as the "current depth". This also allows us + to init the root directory to 'directory_list_stack'[0] and pop it in a safe + and explicit manner. +*/ +#define DL_STACK (directory_list_stack) +#define DL_STACKP (dls) +#define DL_CD_STACK ((*DL_STACKP).child_directory_stack) +#define DL_CD_STACKP ((*DL_STACKP).cds) +#define DL_CURDIR() ((*DL_STACKP).dirp) +#define DL_LEN() (DL_STACKP - DL_STACK) +#define DL_CD_LEN() (DL_CD_STACKP - DL_CD_STACK) +#define DL_INIT() (DL_STACKP = DL_STACK) +#define DL_CD_INIT() (DL_CD_STACKP = DL_CD_STACK) +#define DL_POP() ((*DL_STACKP--).dirp) +#define DL_CD() (*DL_CD_STACKP) +#define DL_CD_CURNAME() (DL_CD()->d_name) +#define DL_CD_POP() (*--DL_CD_STACKP) +#define DL_PUSH(D) ((*++DL_STACKP).dirp = D) +#define DL_CD_PUSH(E) (*DL_CD_STACKP++ = E) + + +/* Initializer + Initializer expects a function pointer to its lexical analysis function. + Sets up stack pointers and returns boolean true if 'opendir' encounters an + error, or if dredge_current_depth returns boolean true. +*/ +int scanner_init +#define CWDSTR "./" +#define ROOTDIR (cargs['d'] ? cargs['d'] : CWDSTR) +() +{ DL_INIT(); + DL_STACK[0].dirp = opendir(ROOTDIR); + if (current_open_file != NULL) + { fclose(current_open_file); + current_open_file = NULL; + } + printf("Root dir %s\n",ROOTDIR); + return !chdir(ROOTDIR) && (DL_STACK[0].dirp == NULL || dredge_current_depth() == -1); +} + +/* Quit */ +void scanner_quit +() +{ if (DL_CURDIR()) + closedir(DL_CURDIR()); +} + +/* Scanner + The main driver of the scanner will advance the current treewalk state and + tokenize tree-based push/pop operations. It will call 'lexer_lex' to + tokenize directory names prior to making a push operation. safe checking for + all returns from the filesystem handler will exit on serious system errors. + + after pushing a new directory to the directory list, the scanner will dredge + the directory and alphabetically sort all file entries into the lexer's file + array, while placing all subdirectory entries in the current depth's child + directory stack to be scanned later. + + Returns the number of tokens generated on success, -1 on error. +*/ +int scanner +#define $($)#$ //stringifier +#define ERR_CHILD "Fatal: Maximum of " $(DL_CD_STACKSIZE) \ + " child directories exceeded for directory at depth %i\n" \ + ,DL_LEN() +#define ERR_DEPTH "Fatal: Maximum directory depth of " $(DL_STACKSIZE) \ + " exceeded during directory scan\n" +#define ERR_DL "Fatal: Directory List Stack Corruption %x\n", DL_LEN() +() +{ int ntok = 0; + scan: + if (DL_CD_LEN() >= DL_CD_STACKSIZE)//fail if maxchildren exceeded + { fprintf(stderr, ERR_CHILD); + goto fail; + } + if (DL_CD_LEN() > 0) //There are entities to process + { if (DL_CD_POP() == NULL) //If the dirent is null, then the + goto libfail; //lib function in dirent has failed +<<<<<<< HEAD + ntok += lexer_lexstring(DL_CD_CURNAME());//lex the directory name +======= + ntok += lexer_lexstring(DL_CD_CURNAME()); //lex the directory name +>>>>>>> 15d3ab5e7871ff459af13089b82bf5f17f731ebd + if (DL_LEN() >= DL_STACKSIZE) //fail if maxdepth exceeded + { fprintf(stderr, ERR_DEPTH); + goto fail; + } + if (chdir(DL_CD_CURNAME())) //move into the new directory + goto libfail; + if (DL_CURDIR() == NULL) //open the cwd + goto libfail; + lexer_pushtok(CLOPEN, 0); //Push "Open Directory" token + ntok++; + return dredge_current_depth(); //Filter and sort the current depth + } + else if (DL_LEN() >= 0) //Any dirs left? (Including root) + { if (closedir(DL_POP())) //close the directory we just left + goto libfail; + if (DL_LEN() == -1) //If we just popped root, + goto done; //we're done + lexer_pushtok(CLCLOSE, 0); //Else push "Close Directory" token, + ntok++; + if (!chdir("..")) //move up a directory and + goto scan; //start over + } + fprintf(stderr, ERR_DL); + libfail: + perror("scanner: "); + fail: + return -1; + done: + return ntok; +} + +/* Scan Pixels + Scans up to 'len' pixels from the current file into 'buf'. + Returns the number of pixels scanned from the file, or -1 on error +*/ +int scanner_scanpixels +( int* buf, + int max_len +) +{ static int col_len, row_len, row; + //Open the current file if not yet open + if (current_open_file == NULL) + { if ((current_open_file = fopen(DL_CD_CURNAME(),"rb")) == NULL) + { perror("fopen: "); + return -1; + } + //Verify file header, get row_len/col_len + //if (read_img_header(&row_len, &col_len)) + //return -1; + row = 0; + } + //Read pixels into the buffer if there are rows left in the image + if (row++ < row_len) + //TODO: return read_img_pixels(buf, col_len); + printf("SCANPIXELS NOT IMPLEMENTED\n."); + //Close the file and return 0 + fclose(current_open_file); + current_open_file = NULL; + return 0; +} + +/* Directory Entity Sort and Filter (Dredge) + This filter removes all unhandled file types, and places any 'DT_DIR' type + files in the current Directory List's directory stack. Upon finishing, + the 'CE_STACK' is sorted alphabetically, and the current 'DL_CD_STACK' is + populated. Prints warnings for unhandled files. + + Returns -1 if 'readdir' encounters an error, otherwise returns the number of + directory entries sent to the external 'lexer_direntpa' array. +*/ +typedef //so we can typecast dirent's 'alphasort()' to take const void*s +int (*qcomp)(const void*, const void*); +static inline +int dredge_current_depth +#define READDIR_ERROR (-1) +#define READDIR_DONE (0) +#define DPS_LEN() (lexer_direntpp - lexer_direntpa) +#define DPS_PUSH(E) (*lexer_direntpp++ = E) +() +{ struct dirent** direntpp = lexer_direntpa; + DIR* cwd = DL_CURDIR(); + struct dirent* direntp; + DL_CD_INIT(); + scan_next: + if ((direntp = readdir(cwd)) != NULL) + { switch (direntp->d_type) + { case DT_REG: + DPS_PUSH(direntp); + goto scan_next; + case DT_DIR: + if (*(direntp->d_name) == '.') //skip hidden files and relative dirs + goto scan_next; + DL_CD_PUSH(direntp); + goto scan_next; + case DT_UNKNOWN: + warnx("unknown file %s: ignoring", direntp->d_name); + default: + goto scan_next; + } + } + if (errno) + return -1; + qsort(lexer_direntpa, DPS_LEN(), sizeof direntp, (qcomp)alphasort); + return DPS_LEN(); +} -- 2.18.0