From e189d4b516d5c5881c8d05cb48d085e20a8692a7 Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sun, 22 Oct 2023 02:07:03 -0500 Subject: [PATCH] Class ability descriptions added. Full render image paths now defined. Moved some class information around. --- Crawler/Ability.cpp | 6 +- Crawler/Ability.h | 3 +- Crawler/CharacterInfoWindow.cpp | 20 +++++- Crawler/Class.h | 2 + Crawler/ClassInfo.h | 74 ++++++++++++++++++++++ Crawler/ClassSelectionWindow.cpp | 2 + Crawler/Crawler.cpp | 1 - Crawler/Crawler.vcxproj | 1 + Crawler/Crawler.vcxproj.filters | 3 + Crawler/GameState.cpp | 2 +- Crawler/Menu.cpp | 2 +- Crawler/MonsterAttribute.h | 1 + Crawler/Player.h | 6 +- Crawler/Version.h | 2 +- Crawler/assets/config/classes/Ranger.txt | 10 +++ Crawler/assets/config/classes/Thief.txt | 6 ++ Crawler/assets/config/classes/Trapper.txt | 6 ++ Crawler/assets/config/classes/Warrior.txt | 10 +++ Crawler/assets/config/classes/Witch.txt | 6 ++ Crawler/assets/config/classes/Wizard.txt | 10 +++ Crawler/assets/knight_full_render1.png | Bin 6594 -> 6871 bytes Crawler/assets/unknown_full_render.png | Bin 0 -> 1174 bytes 22 files changed, 161 insertions(+), 12 deletions(-) create mode 100644 Crawler/ClassInfo.h create mode 100644 Crawler/assets/unknown_full_render.png diff --git a/Crawler/Ability.cpp b/Crawler/Ability.cpp index ba0b7ca6..db0141a3 100644 --- a/Crawler/Ability.cpp +++ b/Crawler/Ability.cpp @@ -13,6 +13,6 @@ PrecastData::PrecastData(float castTime,float range,float size) InputGroup Ability::DEFAULT; Ability::Ability() - :name("???"),shortName("???"),cooldown(0),COOLDOWN_TIME(0),input(&DEFAULT){}; -Ability::Ability(std::string name,std::string shortName,float cooldownTime,int manaCost,InputGroup*input,std::string icon,Pixel barColor1,Pixel barColor2,PrecastData precastInfo,bool canCancelCast) - :name(name),shortName(shortName),cooldown(0),COOLDOWN_TIME(cooldownTime),manaCost(manaCost),input(input),icon("Ability Icons/"+icon),barColor1(barColor1),barColor2(barColor2),precastInfo(precastInfo),canCancelCast(canCancelCast){} \ No newline at end of file + :name("???"),shortName("???"),description("???"),cooldown(0),COOLDOWN_TIME(0),input(&DEFAULT){}; +Ability::Ability(std::string name,std::string shortName,std::string description,float cooldownTime,int manaCost,InputGroup*input,std::string icon,Pixel barColor1,Pixel barColor2,PrecastData precastInfo,bool canCancelCast) + :name(name),shortName(shortName),description(description),cooldown(0),COOLDOWN_TIME(cooldownTime),manaCost(manaCost),input(input),icon("Ability Icons/"+icon),barColor1(barColor1),barColor2(barColor2),precastInfo(precastInfo),canCancelCast(canCancelCast){} \ No newline at end of file diff --git a/Crawler/Ability.h b/Crawler/Ability.h index 3e2da7f3..b373e5e1 100644 --- a/Crawler/Ability.h +++ b/Crawler/Ability.h @@ -20,6 +20,7 @@ struct PrecastData{ struct Ability{ std::string name=""; std::string shortName=""; + std::string description=""; float cooldown=0; float COOLDOWN_TIME=0; int manaCost=0; @@ -32,5 +33,5 @@ struct Ability{ static InputGroup DEFAULT; Ability(); //NOTE: icon expects the actual name relative to the "Ability Icons" directory for this constructor! - Ability(std::string name,std::string shortName,float cooldownTime,int manaCost,InputGroup*input,std::string icon,Pixel barColor1=VERY_DARK_RED,Pixel barColor2=DARK_RED,PrecastData precastInfo={},bool canCancelCast=false); + Ability(std::string name,std::string shortName,std::string description,float cooldownTime,int manaCost,InputGroup*input,std::string icon,Pixel barColor1=VERY_DARK_RED,Pixel barColor2=DARK_RED,PrecastData precastInfo={},bool canCancelCast=false); }; \ No newline at end of file diff --git a/Crawler/CharacterInfoWindow.cpp b/Crawler/CharacterInfoWindow.cpp index 1e7e5b67..26e6b28f 100644 --- a/Crawler/CharacterInfoWindow.cpp +++ b/Crawler/CharacterInfoWindow.cpp @@ -4,23 +4,37 @@ #include "Menu.h" #include "MenuLabel.h" #include "CharacterRotatingDisplay.h" +#include "ClassInfo.h" INCLUDE_game INCLUDE_GFX +INCLUDE_DATA typedef Attribute A; void Menu::InitializeClassInfoWindow(){ Menu*classInfoWindow=CreateMenu(CLASS_INFO,CENTERED,game->GetScreenSize()-vi2d{64,64}); - MenuLabel*label=new MenuLabel(CLASS_INFO,{{0,8},{classInfoWindow->size.x,16}},"Warrior",2,true,true); + Menu*classSelectionWindow=Menu::menus[CLASS_SELECTION]; + ClassInfo data=classutils::GetClassInfo(classSelectionWindow->S(A::CLASS_SELECTION)); + + MenuLabel*label=new MenuLabel(CLASS_INFO,{{0,8},{classInfoWindow->size.x,16}},data.className,2,true,true); classInfoWindow->AddComponent("Class Name",label); - CharacterRotatingDisplay*classDisplay=new CharacterRotatingDisplay(CLASS_INFO,{{0,0},{72,120}},GFX["knight_full_render1.png"].Decal()); + CharacterRotatingDisplay*classDisplay=new CharacterRotatingDisplay(CLASS_INFO,{{0,0},{72,120}},GFX[data.classFullImgName].Decal()); classInfoWindow->AddComponent("Rotating Character Display",classDisplay); - MenuLabel*baseStatsLabel=new MenuLabel(CLASS_INFO,{{2*classInfoWindow->size.x/3,classInfoWindow->pos.y+20},{classInfoWindow->size.x/3,16}},"Base Stats",1,true,true); + vf2d baseStatsLabelPos={classInfoWindow->size.x/3,classInfoWindow->pos.y+20}; + vf2d labelSize={2*classInfoWindow->size.x/3,16}; + + MenuLabel*baseStatsLabel=new MenuLabel(CLASS_INFO,{baseStatsLabelPos,labelSize},"Base Stats",1,true,true); + MenuLabel*healthDisplayLabel=new MenuLabel(CLASS_INFO,{baseStatsLabelPos+vf2d{0,16*1+8},labelSize},"Health: "+std::to_string(data.baseHealth)+" + "+std::to_string(data.healthGrowthRate).substr(0,3)+" per level",1,false,true); + MenuLabel*atkDisplayLabel=new MenuLabel(CLASS_INFO,{baseStatsLabelPos+vf2d{0,16*2+8},labelSize},"Attack: "+std::to_string(data.baseAtk)+" + "+std::to_string(data.atkGrowthRate).substr(0,3)+" per level",1,false,true); classInfoWindow->AddComponent("Base Stats Text",baseStatsLabel); + classInfoWindow->AddComponent("Health Display Text",healthDisplayLabel); + classInfoWindow->AddComponent("Attack Display Text",atkDisplayLabel); + + } \ No newline at end of file diff --git a/Crawler/Class.h b/Crawler/Class.h index 155f44af..059bfd1e 100644 --- a/Crawler/Class.h +++ b/Crawler/Class.h @@ -3,6 +3,8 @@ #include "Animation.h" #include "olcPixelGameEngine.h" +#undef GetClassInfo + //Classes have bit-wise operator capabilities. enum Class{ ANY=0, diff --git a/Crawler/ClassInfo.h b/Crawler/ClassInfo.h new file mode 100644 index 00000000..b81324db --- /dev/null +++ b/Crawler/ClassInfo.h @@ -0,0 +1,74 @@ +#pragma once +#include +#include "Player.h" + +INCLUDE_DATA + +struct ClassInfo{ + std::string className; + std::string classFullImgName; + int baseHealth; + int baseAtk; + float healthGrowthRate; + float atkGrowthRate; + Ability*ability1; + Ability*ability2; + Ability*ability3; + Ability*rightClickAbility; +}; + +class classutils{ +public: + static inline ClassInfo GetClassInfo(std::string className){ + ClassInfo data{ + DATA.GetProperty(className+".ClassName").GetString(), + DATA.GetProperty(className+".FullRender").GetString(), + DATA.GetProperty(className+".BaseHealth").GetInt(), + DATA.GetProperty(className+".BaseAtk").GetInt(), + float(DATA.GetProperty(className+".HealthGrowthRate").GetReal()), + float(DATA.GetProperty(className+".AtkGrowthRate").GetReal()) + }; + + if(className=="Warrior"){ + data.rightClickAbility=&Warrior::rightClickAbility; + data.ability1=&Warrior::ability1; + data.ability2=&Warrior::ability2; + data.ability3=&Warrior::ability3; + }else + if(className=="Wizard"){ + data.rightClickAbility=&Wizard::rightClickAbility; + data.ability1=&Wizard::ability1; + data.ability2=&Wizard::ability2; + data.ability3=&Wizard::ability3; + }else + if(className=="Ranger"){ + data.rightClickAbility=&Ranger::rightClickAbility; + data.ability1=&Ranger::ability1; + data.ability2=&Ranger::ability2; + data.ability3=&Ranger::ability3; + }else + if(className=="Trapper"){ + data.rightClickAbility=&Trapper::rightClickAbility; + data.ability1=&Trapper::ability1; + data.ability2=&Trapper::ability2; + data.ability3=&Trapper::ability3; + }else + if(className=="Witch"){ + data.rightClickAbility=&Witch::rightClickAbility; + data.ability1=&Witch::ability1; + data.ability2=&Witch::ability2; + data.ability3=&Witch::ability3; + }else + if(className=="Thief"){ + data.rightClickAbility=&Thief::rightClickAbility; + data.ability1=&Thief::ability1; + data.ability2=&Thief::ability2; + data.ability3=&Thief::ability3; + }else{ + std::cout<<"WARNING! Could not get class info for non-existent class "+className+"!"; + throw; + } + + return data; + } +}; \ No newline at end of file diff --git a/Crawler/ClassSelectionWindow.cpp b/Crawler/ClassSelectionWindow.cpp index d728b030..52b4f124 100644 --- a/Crawler/ClassSelectionWindow.cpp +++ b/Crawler/ClassSelectionWindow.cpp @@ -9,4 +9,6 @@ typedef Attribute A; void Menu::InitializeClassSelectionWindow(){ Menu*classSelectionWindow=CreateMenu(CLASS_SELECTION,CENTERED,game->GetScreenSize()-vi2d{4,4}); + + classSelectionWindow->S(A::CLASS_SELECTION)="Warrior"; //Default selected class. } \ No newline at end of file diff --git a/Crawler/Crawler.cpp b/Crawler/Crawler.cpp index 4078fd3b..4b956a11 100644 --- a/Crawler/Crawler.cpp +++ b/Crawler/Crawler.cpp @@ -140,7 +140,6 @@ bool Crawler::OnUserCreate(){ LoadLevel(LEVEL_NAMES["starting_map"_S]); InitializeClasses(); ChangePlayerClass(WARRIOR); - //Warrior::ability4=Ranger::ability1; //Class ability swapping demonstration. GameState::Initialize(); diff --git a/Crawler/Crawler.vcxproj b/Crawler/Crawler.vcxproj index 6214bd90..8485afcf 100644 --- a/Crawler/Crawler.vcxproj +++ b/Crawler/Crawler.vcxproj @@ -266,6 +266,7 @@ + diff --git a/Crawler/Crawler.vcxproj.filters b/Crawler/Crawler.vcxproj.filters index 75671faf..0b679bef 100644 --- a/Crawler/Crawler.vcxproj.filters +++ b/Crawler/Crawler.vcxproj.filters @@ -198,6 +198,9 @@ Header Files\Interface + + Header Files + diff --git a/Crawler/GameState.cpp b/Crawler/GameState.cpp index 4c775df6..2be5b39d 100644 --- a/Crawler/GameState.cpp +++ b/Crawler/GameState.cpp @@ -6,5 +6,5 @@ void GameState::Initialize(){ NEW_STATE(States::GAME_RUN,State_GameRun); NEW_STATE(States::MAIN_MENU,State_MainMenu); - GameState::ChangeState(States::GAME_RUN); + GameState::ChangeState(States::MAIN_MENU); } \ No newline at end of file diff --git a/Crawler/Menu.cpp b/Crawler/Menu.cpp index 8314c59a..4a5901a8 100644 --- a/Crawler/Menu.cpp +++ b/Crawler/Menu.cpp @@ -30,8 +30,8 @@ void Menu::InitializeMenus(){ InitializeTestMenu(); InitializeTestSubMenu(); InitializeInventoryWindow(); - InitializeClassInfoWindow(); InitializeClassSelectionWindow(); + InitializeClassInfoWindow(); InitializeMainMenuWindow(); for(MenuType type=TEST;type`bo^exG)<*SJqgD?9CI9De?IQvc7Q7f zO{HebnE*94Zb&K(EImfj9y@gI#Va4m++a|GuZ+^z`5ip+=(Tx&oc(jqOkzWp&W+Zb zU#|S(1G#<=as?8{$+Y8Mv%l&zM_)wY$csOM5CoKucP5tUAJZ=vz4KVcZouXB05ycu|(RzBeHNnBlRNnC{nxegr|fAC^tW-(c8>V zZ%&VX;Gb)S7em^1y%<+1>5~`%9DhI@#a~lPrBoa&BI1ytI@!Sw#8IkP1Pi6D(5i#U zrC-pbAxUv@6kH1qek@iUT%2`va1{i>4-i)uCq)-2@qbC7MT`f>{djlparX`onpLKn zJ#&DnSw=b$7jyYlG5CrQ1`)snViGg;WM(l7&+&B+A7AfcJj?sspQBGHn12lLiNteE zH!R`};+aiL=e$oGVP#1nJ|`YG=z_$LT$f#b<6LrB;F%F4o1Q0*5R0WQmb;jh4V8GB zII5@`llOhr*f0s!_K~#9!?VK%e+ej40pFN#PSbb~{omf-0P|#2;hJs}c6g0a+ zL&27{Ol1x;3^Wvr%5-dD$`aHA&QqUOyZTt|N=~|OMw2+U6z|Xf_bJH$-n@D9=FOWo zZ{ECl^XAQ)H*em&dGqGYn>TOXym|BH&6_uuwm7FZ^Y-H6e^;N^{d{^_{4s!JDBE;b z{hno6s3zip;j}aEC$)$=GQvyQQN|HpW92Jx*`081O{8ZuZ|QccgI$)nprzb3k2hIF92}df$8mk>A2+k?e|Oq6tqH;b0N|XTe+;4$4?MHN$iQS62#j{^D!0IN z>_2~1&bfEVb`&J5faJ_EMm;JwlA-7Z|J1hW4vM0v_8SVxx`K2WtZz2!bfIt!+c@gI ze@{^qr!mRRhZ>~5fqRlHHpYsgfWzT%3bf(+06)2c=v-!KX46?8 zII@fFvO^7sY5JdhqS&X?E{dY29v8N`fB7(fnwQmraLQv|sVvJf>oXj5HH<$hC8>h; zY-ygt`T6v;kU`=Ua15xn_|q4LQ$RZPbis+^xC-7XP&B>w4aVCzs$R3;~9=SbfZ{Z7jFUue>0%U zWLRCcbg7=PErtqC+i`W!RY3Yy(pCVqrFYjCI1O!GWLRC5^wOs5&^KEi^Xjn*QkG>} zHMF^i%U;fT47xkq!8%%3Ln@39ZEm4@j&ts;f}RXen_GoZ1nX$s0H6xcDnNOj|GtQG z;5@mS|2)?}`@HPclUW6%I^PZef3S|$aCf+aN^$Q4ws7E!Hpl2qgRF9E@ zD0S*?58^)n09dhqW>Z94d0?U*YYIX*^6z8q>gvjgiiVgmAYGcbsh}Z>e>gipD#h%J zduw21I5t!?H2we>p4Cvro_%o-AJ$RL$LZ_jKy9iH-6>}Ic&c%0-!mE3>L6Xb!8d?E z=|1v8a5&c0eZRO?Lv}5yo-R{CX?vam3qlUNWUEw>YEoGJ?Re)NP@l`%y5uV_zU{V4 z-9DEAs~~laVr4i(ukKh*f2|%`aqI5t!MhIWYw5mtpT;iP))v3vLABAxrf>!+Xsmk1 zv>mE_5z=ERl-+tYcQ(jeqZDMKo}W)o3*0b{phDWjJle2tp2*0aHTSfBp(#6pb4DE=}EQNbJEY@9A+6f6iFwob&2lSNW2> z$SfJIRaOc+J(0olC&YG?sCwx{V^h1% zgfw$zD+WMr|DNhAD4Ydp(>G6xKk*={88&q_*XPtmD`;$R9+c6@J*whC7}ZVaW|J#u zOmJ>fk7_X#4y}1~e+8u6hOmIu)aVS5>u*&-#n8pba9p^ybp^Q!&J+$?u|aUUR78($ z>aL@M^w3X`E(Fs(R?w!$)xB0e<`~5-rwGnnZ*J_TJe!NrajH%K*JT>hyCjg`Zb8hOHwNQKs3z!9vZ5XECT`{wkS@EZ)MKNxXgjBG>SmL;m`X*i;!C zzuSlQO5#D(J4PHX3PsyCN&BF>kcuwKX60_<3Y5tKwY~X2wa4@3&6_uG-rU>&N#GjS TJjO{100000NkvXXu0mjf8AcKM delta 2655 zcmV-l3ZV7ZHNrEHBmwJ@B`AO37Y~m^UQ##c_%&dXrc$Mzgkv9$IgYTuo=12zP@y0( zm!v6yK~$8gB?ShS9ucI+4w-v+=R=+wWE9(%N2%oeZoK8_wR%6!{yAtSSS^d!My<{- zcYg7KRK5qf0>*JNZ2p4}Vsb??>eUq`E%|n}ZG}6^wS+UJm@tb)A;?TQspW-0viZ3+ zp~p(v2gPCNNz8h-l4+uyk-;Lf43*p#b8UQ&5?Z4rtw9WW9qb_DkfAzR1Ql^CRV;#q(pG5I!Q`cX z(4-+rad8w}3l9D)RvlcNb#-tR1i>E=R~IKm7b)?+q|hS92bcG8-aCi;?gNBYjj3i| z98fjO$RrbDzOX6=UJ*nX0@b9%Og)ud%)xVg-NVQCyBN>%zW3)EREj2l1AHQJoau%| zyg@v>Y3ZEzi6g8cDa7Z*69zR%{K$3L;xC;s~)=?qRuyS;bI^XNaSU zs!_g>cUj@Q#aXR2Sf@|^!cb9L$#R`)6iF;0g)~ISXrPK3EW~KnNHLM2^Mr?g#PO%e zC6lWPMvev4p+a)};D7Lcd$wk2ddf`-C4l}H+x{2>0=q!FY1`k&w%tAf{LjFZ*7et0 zz}zS4&8`+b0>azC#dTMc_khbCVE9Rw49SuFR6?l)yr0oG6@Z~zAh_nvt#gjk2OvkY zTD}1e4uSD9Wv_d@d!To2|K91$?+2NBa<+KuqK^Oo4>W01SaevkvjT+zBr|0-WMMI4 zIW0J4WHv1{VP#=0Ib&oqEihy>GcjdhWn?g7Ig?xksthwTHZeChHZ?FcGBuMD25<{8 zG*mJ%Ix#jnF*cKp1|thGG*mJ%Ix#jnF*dWi2Fn7oWeQ*j1hWK~D3i$&G6)X>5E1sU zZ=jO{6DWUUNkl2)ak)YdL#hi2!?qDS(rX$5kq`1NzDP7VnrOR}; z-KD#9$98Pz>%3jc&;{uVBO$Hnj6^X=6j^DDP-P1V}%vfwlUsoOR%EF3~e;x&X&t)FqL&2W|h0fbPrEdv6C5I8zHUcG5RyZd{o z2S`W=fjT9adkF^-LST1)Z&e4VEohM@lL;(?&^f$VP<6U#t4(kaLSXc9^c?#=`XoVLPj4)&dB46x~f@ifZlCy zud+f50AR-mLnd%Py@J4}5mYuek(bBRagTTRZ?6wx;jmy3J`JDqz9hg5dkEYG$#mmJ zCh2d_&xssi+jb(H5I%*EMh}L)_`wtJ3w(bxdVqV&pQBOa`)^Lize7b&)TtYe(Z@gt zNtAlWaS{nSO~&v;%sqq|PMzwia*qfO?;ajhGUV*UWRZ8y zbUIDEzPrD-lC?Hd+DX%cOM}7#<6(bLV4_t!pL;|LV;PVdU23cgNzq)I2SZ&X0!Ew1 zDxkV`A9R_0CzHuq#{dAh7niw~IIVP$D4dGG6S;&1;$B?BXfjUhH?~KsDxkV;b&n{F zcqk$uyhf8T_`VPB#pS9DB3g4nt+FDU7NUb@&^U9@bm;6|1ihSm$1u-gm)53!NkP0E%U zc}^#@%>zhTCtaqpr6~^_KE%e(GzMg2#vOSUlD_Z9+@nIn z^Rv_;USoX_g>!Rt-JvdX97lip42Omq%|9Y1#d1^AWuAp25}g880hN`1^1^7uLF?dH zmK7y$5h%92=S{{V%Zz?zh>i9D%F`r@hH3OG4~kvE=Yf)^dKGn4w+{E@ZO(X5MPZ~> zMbGnMuB5=+c?&{}uM}yc*tAuA87Q;@rscaLxo%6Pd#WxmL~yd+Hw}Nf2uR*WQF$Lk z&tz1c%gCA-6s?rf0PzVrn0wKO7hUt?I8Le?vO+}VT26TmnoVagFb6QUN3r~n6&9k` zFviL{=vMSWeba=2IYK&+}d{;tWWs+(r8z*9$7G$tnS&6^e$?z#PDAI)nLi z3S>bNjbPr8kugV-rC)z!l<&m@fyD!Xhs6_oUw(()?+7f*g4^3$xV^oNt-bQ(ki)}6 zI6ORrZnq2m{~r8d{+au8Jv}|Wx``|R0N?=iN>#AZ4oX`E(`yWkK3==T*c6qjV&9&h zJM1O`70kT|WD)m>#u7B?%TN*bNG);5Yogb)IZF`ym_x0eIX1Bc4!W7si}5R!Xw34MRltaJ}YX+UM&!^5d6jB#|Y zD}PCz40X$fS5dKl#WXPJ|4?9M+(W~xRtHs0&ROme z9ZV58H&=hx9ex>t3>0(Y#)cSm40|wTozqwjQkk4tIH-q8!x6cNeebH!YjY5LAhg`m z4qBBvYYj0~$+@kewH6RRPL&Eoa-~TNGv#HTf;k(6-RY*d2N?(;r~!})FtXj#Sfi-w zim**nqw^q{;iW1M)duM3TE*Yft=l>5h(mUx$UKzRI@G?LU~T>uE)&+$($dn>(%M-404^@c!i=>(qyPW_ N07(Z$PDHLkV1gRMEX>4Tx04R}tkv&MmKpe$iQ%j{(94sQ@kfA!+#fmzXDi*;)X)CnqU~=gfG-*gu zTpR`0f`cE6RR0!X5l)%?&0CX zjdyV16NwtUuyz$pQJas zTKEVU+y*YLyPCWQTDYDGy0}HFmww9)|}ot`#607veeb`4RCM> zOq3{l-R0f=y}kW=rqkaKAZ2pwj91|d00006VoOIv051R+00^yMK5YO1010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=L!}E0TLE?t-}BS02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00M4FL_t(|+U=Y>Zo@DPKrO*Q(5cDhPC>@rqBqIeda8~^ zHg8GBOzvc$5d4uP+M=xY<|0;JNLn9ORRsV500000000000029{to?xQ-gd!*J2fV? zpn7c?pO>rH=cN#4B&Ed2@Zsn8d-Di0v0~Pi;wx+|Stds@Q?jH*nWb{Hi5U`gY|hp5 z^)j0Zik0Kmk2zwWB_+v7%NY}KY|e`Y_GoWW;-n-Q2|53z%!yb!;P=C!n-VuQHVH{4 zMouqgNQzVqm=o6v8yjb=q&hawx0EvUEOTlmf6ULzwR*I->e!sSkn!1&=yBydUoW$z zoUvue+>5|X*C;{0k&{}CkEA||La;G!ElqMli@sfW+Y`c3WJ3p%WAubXkA zu_bm->6KJaPU$6Chis{-<6DP{6+{FHQA_OI6eXzNvJ6?b6ca(YPXwt!2#RBDH4rk{ zEjEIDO9&~3AOx*ee~OKuB~ututRz9w=~ZL|EnOkly+;ozRxLZ^6kDun`toys;~P04 z3-DUI6p22e7>q_S617C?h}`5*M^edABS=clP`}dZ9cJ3(OzoGi(XXWbE#?aGDY}x| z#kF=hV?wstGp}=zlj;z`B1f?xp8}ow_=)|X+yrUsLsA_<8cugfF$85QXy^^5u@6#h z1Zn9mA;l1cAOs-@K?p(+f&f7XLJ)!wgdhYV2oQuI1R)4P2trT^Bs-iN>!9yXR<#@) zCLhGu1qS@zJ^)2}>q4#J4ttk6r5v|EsJpkF07*qoM6N<$g65p^VgLXD literal 0 HcmV?d00001