From 312627a008511638755f3d13b6d187feea7310bd Mon Sep 17 00:00:00 2001 From: myitinos Date: Sat, 2 Nov 2019 22:53:54 +0800 Subject: [PATCH] [NEW] checkpoint --- .vscode/settings.json | 53 ++++++++++++++++++ Dockerfile | 3 +- README.md | 7 ++- docker-compose.yml | 10 ++++ flag.txt | 2 +- ground0.cpp | 9 +++ lib/Character.cpp | 126 +++++++++++++++++++++++------------------- lib/Character.hpp | 40 ++++++++------ lib/Element.cpp | 60 ++++++++++++++++++++ lib/Element.hpp | 30 ++++++++++ lib/Game.cpp | 101 +++++++++++++++++++++++++++++++++ lib/Game.hpp | 22 ++++++++ lib/Spell.cpp | 40 +++++++------- lib/Spell.hpp | 21 ++++--- lib/UserInterface.cpp | 63 ++++++++------------- lib/UserInterface.hpp | 15 ++--- main.cpp | 30 +++------- main0.cpp | 106 +++++++++++++++++++++++++++++++++++ poc.py | 18 ++++++ test | Bin 0 -> 126784 bytes test.cpp | 12 ++++ 21 files changed, 589 insertions(+), 179 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 docker-compose.yml create mode 100644 ground0.cpp create mode 100644 lib/Element.cpp create mode 100644 lib/Element.hpp create mode 100644 lib/Game.cpp create mode 100644 lib/Game.hpp create mode 100644 main0.cpp create mode 100644 poc.py create mode 100755 test create mode 100644 test.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..29fef4f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,53 @@ +{ + "files.associations": { + "chrono": "cpp", + "array": "cpp", + "atomic": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "map": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "typeinfo": "cpp" + } +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index a8069ba..8b13c8c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,5 @@ WORKDIR /app COPY ./flag.txt . COPY ./spell-warz-again . -CMD socat tcp-listen:12345,reuseaddr,fork EXEC:\"./spell-warz-again\" - EXPOSE 12345/tcp +CMD socat tcp-listen:12345,reuseaddr,fork EXEC:./spell-warz-again diff --git a/README.md b/README.md index 5e26d13..e3c159b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ -# spell-warz-again-and-again +# spell-warz-again +Hello guys, there's an update to my last game
+Now you can choose your own name! Cool isn't it :)
+Also, I made the new Arch-Mage a little weak
+please defeat him again!
+`nc 103.200.7.150 30311` \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..14cfa9d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +version: "2" + +services: + main: + build: . + container_name: "spell-warz-again" + network_mode: "bridge" + restart: on-failure + ports: + - "30311:12345" diff --git a/flag.txt b/flag.txt index f824bde..c7dd174 100644 --- a/flag.txt +++ b/flag.txt @@ -1 +1 @@ -slashroot{dummy} +SlashRootCTF{h1dd3n_Sp3l1_f0r_a_h1dd3n_fl4g} diff --git a/ground0.cpp b/ground0.cpp new file mode 100644 index 0000000..2354c35 --- /dev/null +++ b/ground0.cpp @@ -0,0 +1,9 @@ +#include "lib/Spell.hpp" + +int main(int argc, char const *argv[]) +{ + int i = 3; + Spell spell = Spell("?", Element("Void"), Spell::NULL_TYPE, 0, 0); + spell.getElement().getName() + return 0; +} diff --git a/lib/Character.cpp b/lib/Character.cpp index 09438ee..372c53e 100644 --- a/lib/Character.cpp +++ b/lib/Character.cpp @@ -1,61 +1,51 @@ #include "Character.hpp" -#include + const int Character::maxLevel = 0xffff; const int Character::maxExperience = 0x0fffffff; -Character::Character() +Character::Character(std::string characterName, + Element *characterAffinity) { + this->name = characterName; + this->affinity = characterAffinity; this->level = 1; this->experience = 0; - this->maxHP = 10; - this->curHP = maxHP; - this->maxMP = 5; - this->curMP = maxMP; - this->atk = 1; - this->def = 1; - memset(this->name, 0, 16); -} - -Character::Character(char *n) : Character::Character() -{ - strcpy(this->name, n); - this->name[15] = 0; -} - -Character::Character(const char *n) : Character::Character() -{ - strcpy(this->name, n); - this->name[15] = 0; + this->maxHP = 100; + this->maxMP = 50; + this->curHP = this->maxHP; + this->curMP = this->maxMP; } -Character::Character(char *n, int l, int e, int h, int m, int a, int d) +Character::Character(std::string characterName, + Element *characterAffinity, + int characterLevel) { - strcpy(this->name, n); - this->name[15] = 0; - this->level = l; - this->experience = e; - this->maxHP = h; - this->curHP = maxHP; - this->maxMP = m; - this->curMP = maxMP; - this->atk = a; - this->def = d; + this->name = characterName; + this->affinity = characterAffinity; + this->level = characterLevel; + this->experience = characterLevel; + this->maxHP = characterLevel * 10; + this->curHP = this->maxHP; + this->maxMP = characterLevel * 5; + this->curMP = this->maxMP; } -Character::Character(const char *n, int l, int e, int h, int m, int a, int d) +Character::Character(std::string characterName, + Element *characterAffinity, + int characterLevel, + int characterHP, + int characterMP) { - strcpy(this->name, n); - this->name[15] = 0; - this->level = l; - this->experience = e; - this->maxHP = h; - this->curHP = maxHP; - this->maxMP = m; - this->curMP = maxMP; - this->atk = a; - this->def = d; + this->name = characterName; + this->affinity = characterAffinity; + this->level = characterLevel; + this->experience = characterLevel; + this->maxHP = characterHP; + this->curHP = this->maxHP; + this->maxMP = characterMP; + this->curMP = this->maxMP; } -char *Character::getName() +std::string Character::getName() { return this->name; } @@ -106,16 +96,6 @@ int Character::getCurMP() return this->curMP; } -int Character::getAtk() -{ - return this->atk; -} - -int Character::getDef() -{ - return this->def; -} - void Character::levelUp() { if ((this->level <= maxLevel) && this->readytoLevelUp()) @@ -190,10 +170,37 @@ bool Character::canCastSpell(Spell *s) return this->curMP >= s->getCost(); } -void Character::castSpell(Spell *s, Character *t) +bool Character::castSpell(Spell *s, Character *t) { - this->reduceMP(s->getCost()); - t->reduceHP(s->getAmount()); + if (this->canCastSpell(s)) + { + this->reduceMP(s->getCost()); + int pwr = s->getPower(); + int spellCompatibility = s->getElement()->compatibilityAgainst(t->getAffinity()); + + if (spellCompatibility == Element::WEAK_COMPATIBILITY) + { + pwr /= 2; + } + else if (spellCompatibility == Element::STRONG_COMPATIBILITY) + { + pwr *= 2; + } + + if (s->getType() == Spell::TYPE_DESTRUCTION) + { + t->reduceHP(pwr); + } + else if (s->getType() == Spell::TYPE_RESTORATION) + { + t->restoreHP(pwr); + } + return true; + } + else + { + return false; + } } void Character::rest() @@ -213,4 +220,9 @@ void Character::revive() { this->curHP = 1; } +} + +Element *Character::getAffinity() +{ + return this->affinity; } \ No newline at end of file diff --git a/lib/Character.hpp b/lib/Character.hpp index 14d107c..97c121d 100644 --- a/lib/Character.hpp +++ b/lib/Character.hpp @@ -1,25 +1,25 @@ #ifndef SPELL_WARZ_CHARACTER_HPP #define SPELL_WARZ_CHARACTER_HPP 1 -#include +#include #include "Spell.hpp" +#include "Element.hpp" class Character { protected: static const int maxLevel; static const int maxExperience; - char name[16]; - int experience; + std::string name; + Element *affinity; int level; - int atk; - int def; - int curHP; - int curMP; + int experience; int maxHP; int maxMP; + int curHP; + int curMP; void restoreHP(int); void restoreMP(int); @@ -27,24 +27,30 @@ protected: void reduceMP(int); public: - Character(); - Character(char *name); - Character(const char *name); - Character(char *name, int level, int exp, int hp, int mp, int atk, int def); - Character(const char *name, int level, int exp, int hp, int mp, int atk, int def); + Character(std::string characterName, + Element *characterAffinity); + + Character(std::string characterName, + Element *characterAffinity, + int characterLevel); + + Character(std::string characterName, + Element *characterAffinity, + int characterLevel, + int characterHP, + int characterMP); - void castSpell(Spell *src, Character *dst); + bool castSpell(Spell *src, Character *dst); bool canCastSpell(Spell *src); - char *getName(); + std::string getName(); + Element *getAffinity(); int getLevel(); int getExperience(); int getMaxHP(); - int getCurHP(); int getMaxMP(); + int getCurHP(); int getCurMP(); - int getAtk(); - int getDef(); int toNextLevel(); bool readytoLevelUp(); diff --git a/lib/Element.cpp b/lib/Element.cpp new file mode 100644 index 0000000..2098d2b --- /dev/null +++ b/lib/Element.cpp @@ -0,0 +1,60 @@ +#include "Element.hpp" + +int Element::WEAK_COMPATIBILITY = -1; +int Element::NEUTRAL_COMPATIBILITY = 0; +int Element::STRONG_COMPATIBILITY = 1; + +Element::Element(std::string elementName, + Element *elementWeakAgainst, + Element *elementStrongAgainst) + : name(elementName), + weakAgainst(elementWeakAgainst), + strongAgainst(elementStrongAgainst) +{ +} + +std::string Element::getName() +{ + return this->name; +} + +void Element::setStrongAgainst(Element *element) +{ + this->strongAgainst = element; +} + +void Element::setWeakAgainst(Element *element) +{ + this->weakAgainst = element; +} + +bool Element::isStrongAgainst(Element *element) +{ + return this->strongAgainst == element; +} + +bool Element::isWeakAgainst(Element *element) +{ + return this->weakAgainst == element; +} + +int Element::compatibilityAgainst(Element *element) +{ + if (this->isStrongAgainst(element)) + { + return Element::STRONG_COMPATIBILITY; + } + else if (this->isWeakAgainst(element)) + { + return Element::WEAK_COMPATIBILITY; + } + else + { + return Element::NEUTRAL_COMPATIBILITY; + } +} + +bool Element::operator<(Element &element) +{ + return this->name < element.name; +} \ No newline at end of file diff --git a/lib/Element.hpp b/lib/Element.hpp new file mode 100644 index 0000000..66d5c8c --- /dev/null +++ b/lib/Element.hpp @@ -0,0 +1,30 @@ +#ifndef SPELL_WARZ_ELEMENT_HPP +#define SPELL_WARZ_ELEMENT_HPP 1 + +#include + +class Element +{ +protected: + std::string name; + Element *strongAgainst; + Element *weakAgainst; + +public: + static int WEAK_COMPATIBILITY; + static int NEUTRAL_COMPATIBILITY; + static int STRONG_COMPATIBILITY; + + Element(std::string elementName, + Element *elementWeakAgainst = nullptr, + Element *elementStrongAgainst = nullptr); + std::string getName(); + void setStrongAgainst(Element *element); + void setWeakAgainst(Element *element); + bool isStrongAgainst(Element *element); + bool isWeakAgainst(Element *element); + int compatibilityAgainst(Element *element); + bool operator<(Element &rhs); +}; + +#endif \ No newline at end of file diff --git a/lib/Game.cpp b/lib/Game.cpp new file mode 100644 index 0000000..5883a83 --- /dev/null +++ b/lib/Game.cpp @@ -0,0 +1,101 @@ +#include "Game.hpp" + +std::map Game::Elements; +std::map> Game::SpellBook; +std::vector Game::PlayerParty; + +bool Game::isPartyAlive(std::vector &party) +{ + std::vector::iterator it; + for (it = party.begin(); it != party.end(); ++it) + { + if (it->isAlive()) + { + return true; + } + } + return false; +} + +void Game::init() +{ + /* initialise elements */ + Game::Elements["Fire"] = Element("Fire"); + Game::Elements["Water"] = Element("Water"); + Game::Elements["Wind"] = Element("Wind"); + Game::Elements["Earth"] = Element("Earth"); + Game::Elements["Holy"] = Element("Holy"); + Game::Elements["Dark"] = Element("Dark"); + Game::Elements["Void"] = Element("Void"); + Game::Elements["Fire"].setStrongAgainst(&Game::Elements["Earth"]); + Game::Elements["Fire"].setWeakAgainst(&Game::Elements["Water"]); + Game::Elements["Water"].setStrongAgainst(&Game::Elements["Fire"]); + Game::Elements["Water"].setWeakAgainst(&Game::Elements["Wind"]); + Game::Elements["Wind"].setStrongAgainst(&Game::Elements["Water"]); + Game::Elements["Wind"].setWeakAgainst(&Game::Elements["Earth"]); + Game::Elements["Earth"].setStrongAgainst(&Game::Elements["Wind"]); + Game::Elements["Earth"].setWeakAgainst(&Game::Elements["Fire"]); + Game::Elements["Holy"].setStrongAgainst(&Game::Elements["Dark"]); + Game::Elements["Holy"].setWeakAgainst(&Game::Elements["Dark"]); + Game::Elements["Dark"].setStrongAgainst(&Game::Elements["Holy"]); + Game::Elements["Dark"].setWeakAgainst(&Game::Elements["Holy"]); + + /* initialise spell book */ + SpellBook[Game::Elements["Fire"]] = { + Spell("Fire Bolt", &Game::Elements["Fire"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Warm Touch", &Game::Elements["Fire"], Spell::TYPE_RESTORATION, 10, 10), + Spell("Flame Javelin", &Game::Elements["Fire"], Spell::TYPE_DESTRUCTION, 25, 15), + Spell("Flaming Rocket", &Game::Elements["Fire"], Spell::TYPE_DESTRUCTION, 50, 20), + Spell("Sun's Strike", &Game::Elements["Fire"], Spell::TYPE_DESTRUCTION, 100, 25), + Spell("Big Bang", &Game::Elements["Fire"], Spell::TYPE_DESTRUCTION, 200, 30)}; + SpellBook[Game::Elements["Water"]] = { + Spell("Water Splash", &Game::Elements["Water"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Healing Water", &Game::Elements["Water"], Spell::TYPE_RESTORATION, 10, 10), + Spell("Jet Stream", &Game::Elements["Water"], Spell::TYPE_DESTRUCTION, 25, 15), + Spell("Rain of Healing", &Game::Elements["Water"], Spell::TYPE_RESTORATION, 25, 20), + Spell("Whirlpool", &Game::Elements["Water"], Spell::TYPE_DESTRUCTION, 50, 25), + Spell("Tsunami", &Game::Elements["Water"], Spell::TYPE_DESTRUCTION, 100, 30), + }; + SpellBook[Game::Elements["Wind"]] = { + Spell("Breath of Wind", &Game::Elements["Wind"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Wind of Restoration", &Game::Elements["Wind"], Spell::TYPE_RESTORATION, 10, 10), + Spell("Air Needle", &Game::Elements["Wind"], Spell::TYPE_DESTRUCTION, 25, 15), + Spell("Tornado", &Game::Elements["Wind"], Spell::TYPE_DESTRUCTION, 50, 20), + Spell("Twin Tornado", &Game::Elements["Wind"], Spell::TYPE_DESTRUCTION, 100, 25), + Spell("Triple Tornado", &Game::Elements["Wind"], Spell::TYPE_DESTRUCTION, 200, 30), + }; + SpellBook[Game::Elements["Earth"]] = { + Spell("Rock Throw", &Game::Elements["Earth"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Earth Sheet", &Game::Elements["Earth"], Spell::TYPE_RESTORATION, 10, 10), + Spell("Earth Split", &Game::Elements["Earth"], Spell::TYPE_DESTRUCTION, 25, 15), + Spell("Crushed Earth", &Game::Elements["Earth"], Spell::TYPE_DESTRUCTION, 50, 20), + Spell("Wall of Eden", &Game::Elements["Earth"], Spell::TYPE_RESTORATION, 50, 25), + Spell("Earthquake", &Game::Elements["Earth"], Spell::TYPE_DESTRUCTION, 100, 30), + }; + SpellBook[Game::Elements["Holy"]] = { + Spell("Holy Light", &Game::Elements["Holy"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Healing Light", &Game::Elements["Holy"], Spell::TYPE_RESTORATION, 25, 10), + Spell("Light of Judgment", &Game::Elements["Holy"], Spell::TYPE_DESTRUCTION, 50, 15), + Spell("Flame of Purgatory", &Game::Elements["Holy"], Spell::TYPE_DESTRUCTION, 100, 20), + Spell("God's Protection", &Game::Elements["Holy"], Spell::TYPE_RESTORATION, 1000000000, 25), + }; + SpellBook[Game::Elements["Dark"]] = { + Spell("Dark Touch", &Game::Elements["Dark"], Spell::TYPE_DESTRUCTION, 10, 5), + Spell("Hell's Touch", &Game::Elements["Dark"], Spell::TYPE_DESTRUCTION, 25, 10), + Spell("Hell's Inferno", &Game::Elements["Dark"], Spell::TYPE_DESTRUCTION, 50, 15), + Spell("Eclipse", &Game::Elements["Dark"], Spell::TYPE_DESTRUCTION, 100, 20), + Spell("Hell on Earth", &Game::Elements["Dark"], Spell::TYPE_DESTRUCTION, 200, 25), + }; + SpellBook[Game::Elements["Void"]] = { + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 1, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 10, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 100, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 1000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 10000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 100000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 1000000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 10000000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 100000000, 1), + Spell("?", &Game::Elements["Void"], Spell::TYPE_DESTRUCTION, 1000000000, 1), + }; +} \ No newline at end of file diff --git a/lib/Game.hpp b/lib/Game.hpp new file mode 100644 index 0000000..82b0c1d --- /dev/null +++ b/lib/Game.hpp @@ -0,0 +1,22 @@ +#ifndef SPELL_WARZ_GAME_HPP +#define SPELL_WARZ_GAME_HPP 1 + +#include +#include + +#include "Element.hpp" +#include "Spell.hpp" +#include "Character.hpp" + +namespace Game +{ +extern std::map Elements; +extern std::map> SpellBook; +extern std::vector PlayerParty; + +void init(); +bool isPartyAlive(std::vector &party); + +} // namespace Game + +#endif \ No newline at end of file diff --git a/lib/Spell.cpp b/lib/Spell.cpp index f5b8492..1389a0f 100644 --- a/lib/Spell.cpp +++ b/lib/Spell.cpp @@ -1,11 +1,19 @@ #include "Spell.hpp" -Spell::Spell(std::string n, int t, int a, int c) +int Spell::TYPE_RESTORATION = 1; +int Spell::TYPE_DESTRUCTION = 2; + +Spell::Spell(std::string spellName, + Element *spellElement, + int spellType, + int spellPower, + int spellCost) { - this->name = std::string(n); - this->type = t; - this->amount = a; - this->cost = c; + this->name = spellName; + this->element = spellElement; + this->type = spellType; + this->power = spellPower; + this->cost = spellCost; } int Spell::getType() @@ -13,9 +21,9 @@ int Spell::getType() return this->type; } -int Spell::getAmount() +int Spell::getPower() { - return this->amount; + return this->power; } int Spell::getCost() @@ -23,20 +31,12 @@ int Spell::getCost() return this->cost; } +Element *Spell::getElement() +{ + return this->element; +} + std::string Spell::getName() { return this->name; } - -std::vector Spell::Book = { - Spell("Napalm Beat", 1, 4, 1), - Spell("Fire Ball", 1, 6, 2), - Spell("Cold Bolt", 1, 8, 3), - Spell("Stone curse", 1, 10, 4), - Spell("Lightning Bolt", 1, 12, 5), - Spell("Soul Strike", 1, 14, 6), - Spell("Fire Wall", 1, 16, 7), - Spell("Frost Diver", 1, 18, 8), - Spell("Lighting Storm", 1, 20, 9), - Spell("Asura's Strike", 1, 50, 10), -}; \ No newline at end of file diff --git a/lib/Spell.hpp b/lib/Spell.hpp index 618bbaa..2da261a 100644 --- a/lib/Spell.hpp +++ b/lib/Spell.hpp @@ -1,27 +1,32 @@ #ifndef SPELL_WARZ_SPELL_CPP #define SPELL_WARZ_SPELL_CPP 1 -#include #include +#include "Element.hpp" + class Spell { protected: std::string name; - + Element *element; int type; - int amount; + int power; int cost; public: - int TYPE_RESTORATION = 0; - int TYPE_DESTRUCTION = 1; - static std::vector Book; + static int TYPE_RESTORATION; + static int TYPE_DESTRUCTION; - Spell(std::string, int, int, int); + Spell(std::string spellName, + Element *spellElement, + int spellType, + int spellPower, + int spellCost); int getType(); - int getAmount(); + int getPower(); int getCost(); + Element *getElement(); std::string getName(); }; diff --git a/lib/UserInterface.cpp b/lib/UserInterface.cpp index 885aba1..6b5df89 100644 --- a/lib/UserInterface.cpp +++ b/lib/UserInterface.cpp @@ -1,7 +1,6 @@ #include "UserInterface.hpp" +#include "Game.hpp" -const int UserInterface::interval = 500; // in ms -const int UserInterface::miniInterval = 50; // in ms const int UserInterface::maxDay = 28; const int UserInterface::maxMonth = 12; const int UserInterface::maxYear = 100; @@ -10,8 +9,6 @@ int UserInterface::day = 1; int UserInterface::month = 1; int UserInterface::year = 90; -bool UserInterface::gameOver = false; - std::vector UserInterface::dayName = { "Morndas", "Tirdas", @@ -37,30 +34,24 @@ std::vector UserInterface::monthName = { "Evening Star", }; -void UserInterface::print(std::string msg) +void UserInterface::print(std::string msg, int interval) { std::cout << msg << std::flush; - std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); + std::this_thread::sleep_for(std::chrono::milliseconds(interval)); } -void UserInterface::print(char *msg) -{ - std::cout << msg << std::flush; - std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); -} -void UserInterface::print(const char *msg) +void UserInterface::println(std::string msg, int interval) { - std::cout << msg << std::flush; - std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::interval)); + std::cout << msg << std::endl; + std::this_thread::sleep_for(std::chrono::milliseconds(interval)); } -void UserInterface::printByChar(const char *msg) +void UserInterface::printByChar(std::string msg, int interval) { - int len = strlen(msg); - for (size_t i = 0; i < len; i++) + for (size_t i = 0; i < msg.size(); i++) { - std::cout << msg[i] << std::flush; - std::this_thread::sleep_for(std::chrono::milliseconds(UserInterface::miniInterval)); + std::cout << msg.at(i) << std::flush; + std::this_thread::sleep_for(std::chrono::milliseconds(interval)); } } @@ -74,22 +65,21 @@ void UserInterface::welcomeMessage() Character *UserInterface::characterCreation() { - char buffer[128] = {0}; - char choice = 0; - int i; - short b; - while (choice != 'y' && choice != 'Y') + std::string buffer; + std::cout << "Who should we call you?\n" + << ">" << std::flush; + std::cin >> buffer; + std::cout << "Now pick your elements: \n"; + std::map::iterator it; + int i = 0; + int max = Game::Elements.size() - 2; + for (it = Game::Elements.begin(); i < max; ++it) { - std::cout << "Who should we call you?\n" - << ">" << std::flush; - - std::cin >> buffer; - - std::cout << "So you are a young mage named \"" << buffer << "\" correct? (y/N)\n" - << ">"; - std::cin >> choice; + std::cout << "[" << i++ << "] " << it->second.getName() << '\n'; } - return new Character(buffer); + int element = UserInterface::getNumber("#", 0, max); + + return new Character(buffer, Game::Elements.begin() + element); } void UserInterface::epilogue() @@ -202,17 +192,12 @@ void UserInterface::nextDay() month = 1; if (UserInterface::year++ >= UserInterface::maxYear) { - UserInterface::gameOver = true; + exit(0); } } } } -bool UserInterface::isGameOver() -{ - return gameOver; -} - void UserInterface::characterInfo(Character *c) { std::cout << "++++++++++++++++++++++++" diff --git a/lib/UserInterface.hpp b/lib/UserInterface.hpp index 3fb5e60..eeb3956 100644 --- a/lib/UserInterface.hpp +++ b/lib/UserInterface.hpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include "Character.hpp" #include "Spell.hpp" @@ -13,8 +13,6 @@ class UserInterface { protected: - static const int interval; // in ms - static const int miniInterval; // in ms static const int maxDay; static const int maxMonth; static const int maxYear; @@ -26,15 +24,10 @@ protected: static int month; static int year; - static bool gameOver; - public: - static void print(std::string); - static void print(const char *); - static void print(char *); - static void printByChar(std::string); - static void printByChar(const char *); - static void printByChar(char *); + static void print(std::string msg, int interval = 500); + static void println(std::string msg, int interval = 500); + static void printByChar(std::string msg, int interval = 50); static void welcomeMessage(); static void epilogue(); diff --git a/main.cpp b/main.cpp index 87b8d6c..a3222eb 100644 --- a/main.cpp +++ b/main.cpp @@ -1,16 +1,14 @@ -#include -#include -#include -#include -#include #include +#include #include #include "lib/Character.hpp" #include "lib/Spell.hpp" +#include "lib/Element.hpp" #include "lib/UserInterface.hpp" #include "lib/BattleInterface.hpp" +#include "lib/Game.hpp" std::string loadFlag() { @@ -23,28 +21,14 @@ std::string loadFlag() int main() { - std::string flag; - Character *player; - Character *archMage; - Character *enemy; - BattleInterface battle; - std::vector enemies; - - flag = loadFlag(); - srand(time(0)); alarm(600); + srand(time(0)); + std::string flag = loadFlag(); + Game::init(); UserInterface::welcomeMessage(); UserInterface::epilogue(); - player = UserInterface::characterCreation(); - archMage = new Character("Arch-Mage", 500, 0, 5000, 5000, 1, 1); - enemies = { - new Character("Abby", 1, 1, 10, 5, 1, 1), - new Character("John", 2, 3, 20, 10, 1, 1), - new Character("Adam", 3, 7, 40, 25, 1, 1), - new Character("Christo", 4, 11, 80, 40, 1, 1), - new Character("Greg", 5, 16, 160, 80, 1, 1), - }; + Game::PlayerParty.push_back(UserInterface::characterCreation()); while (player->isAlive() && !UserInterface::isGameOver()) { diff --git a/main0.cpp b/main0.cpp new file mode 100644 index 0000000..490f03c --- /dev/null +++ b/main0.cpp @@ -0,0 +1,106 @@ +#include +#include +#include + +#include "lib/Character.hpp" +#include "lib/Spell.hpp" +#include "lib/Element.hpp" +#include "lib/BattleInterface.hpp" +#include "lib/UserInterface.hpp" + +std::string loadFlag() +{ + std::string flagString; + std::ifstream flagFile("flag.txt"); + flagFile >> flagString; + flagFile.close(); + return flagString; +} + +int main() +{ + + std::map Elements; + std::map> SpellBook; + std::vector PlayerParty; + + /* initialise elements */ + Elements["Fire"] = new Element("Fire"); + Elements["Water"] = new Element("Water"); + Elements["Wind"] = new Element("Wind"); + Elements["Earth"] = new Element("Earth"); + Elements["Holy"] = new Element("Holy"); + Elements["Dark"] = new Element("Dark"); + Elements["Void"] = new Element("Void"); + Elements["Fire"]->setStrongAgainst(Elements["Earth"]); + Elements["Fire"]->setWeakAgainst(Elements["Water"]); + Elements["Water"]->setStrongAgainst(Elements["Fire"]); + Elements["Water"]->setWeakAgainst(Elements["Wind"]); + Elements["Wind"]->setStrongAgainst(Elements["Water"]); + Elements["Wind"]->setWeakAgainst(Elements["Earth"]); + Elements["Earth"]->setStrongAgainst(Elements["Wind"]); + Elements["Earth"]->setWeakAgainst(Elements["Fire"]); + Elements["Holy"]->setStrongAgainst(Elements["Dark"]); + Elements["Holy"]->setWeakAgainst(Elements["Dark"]); + Elements["Dark"]->setStrongAgainst(Elements["Holy"]); + Elements["Dark"]->setWeakAgainst(Elements["Holy"]); + + /* initialise spell book */ + SpellBook[Elements["Fire"]] = { + new Spell("Fire Bolt", Elements["Fire"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Warm Touch", Elements["Fire"], Spell::RESTORATION_TYPE, 10, 10), + new Spell("Flame Javelin", Elements["Fire"], Spell::DESTRUCTION_TYPE, 25, 15), + new Spell("Flaming Rocket", Elements["Fire"], Spell::DESTRUCTION_TYPE, 50, 20), + new Spell("Sun's Strike", Elements["Fire"], Spell::DESTRUCTION_TYPE, 100, 25), + new Spell("Big Bang", Elements["Fire"], Spell::DESTRUCTION_TYPE, 200, 30)}; + SpellBook[Elements["Water"]] = { + new Spell("Water Splash", Elements["Water"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Healing Water", Elements["Water"], Spell::RESTORATION_TYPE, 10, 10), + new Spell("Jet Stream", Elements["Water"], Spell::DESTRUCTION_TYPE, 25, 15), + new Spell("Rain of Healing", Elements["Water"], Spell::RESTORATION_TYPE, 25, 20), + new Spell("Whirlpool", Elements["Water"], Spell::DESTRUCTION_TYPE, 50, 25), + new Spell("Tsunami", Elements["Water"], Spell::DESTRUCTION_TYPE, 100, 30), + }; + SpellBook[Elements["Wind"]] = { + new Spell("Breath of Wind", Elements["Wind"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Wind of Restoration", Elements["Wind"], Spell::RESTORATION_TYPE, 10, 10), + new Spell("Air Needle", Elements["Wind"], Spell::DESTRUCTION_TYPE, 25, 15), + new Spell("Tornado", Elements["Wind"], Spell::DESTRUCTION_TYPE, 50, 20), + new Spell("Twin Tornado", Elements["Wind"], Spell::DESTRUCTION_TYPE, 100, 25), + new Spell("Triple Tornado", Elements["Wind"], Spell::DESTRUCTION_TYPE, 200, 30), + }; + SpellBook[Elements["Earth"]] = { + new Spell("Rock Throw", Elements["Earth"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Earth Sheet", Elements["Earth"], Spell::RESTORATION_TYPE, 10, 10), + new Spell("Earth Split", Elements["Earth"], Spell::DESTRUCTION_TYPE, 25, 15), + new Spell("Crushed Earth", Elements["Earth"], Spell::DESTRUCTION_TYPE, 50, 20), + new Spell("Wall of Eden", Elements["Earth"], Spell::RESTORATION_TYPE, 50, 25), + new Spell("Earthquake", Elements["Earth"], Spell::DESTRUCTION_TYPE, 100, 30), + }; + SpellBook[Elements["Holy"]] = { + new Spell("Holy Light", Elements["Holy"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Healing Light", Elements["Holy"], Spell::RESTORATION_TYPE, 25, 10), + new Spell("Light of Judgment", Elements["Holy"], Spell::DESTRUCTION_TYPE, 50, 15), + new Spell("Flame of Purgatory", Elements["Holy"], Spell::DESTRUCTION_TYPE, 100, 20), + new Spell("God's Protection", Elements["Holy"], Spell::RESTORATION_TYPE, 1000000000, 25), + }; + SpellBook[Elements["Dark"]] = { + new Spell("Dark Touch", Elements["Dark"], Spell::DESTRUCTION_TYPE, 10, 5), + new Spell("Hell's Touch", Elements["Dark"], Spell::DESTRUCTION_TYPE, 25, 10), + new Spell("Hell's Inferno", Elements["Dark"], Spell::DESTRUCTION_TYPE, 50, 15), + new Spell("Eclipse", Elements["Dark"], Spell::DESTRUCTION_TYPE, 100, 20), + new Spell("Hell on Earth", Elements["Dark"], Spell::DESTRUCTION_TYPE, 200, 25), + }; + SpellBook[Elements["Void"]] = { + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 1, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 10, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 100, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 1000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 10000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 100000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 1000000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 10000000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 100000000, 1), + new Spell("?", Elements["Void"], Spell::DESTRUCTION_TYPE, 1000000000, 1), + }; +} diff --git a/poc.py b/poc.py new file mode 100644 index 0000000..de89014 --- /dev/null +++ b/poc.py @@ -0,0 +1,18 @@ +from pwn import * + +if __name__ == "__main__": + p = process("./main") + print p.recvuntil(">") + p.sendline(("A" * 16) + ("\xff\xff\xff\x0f\x01")) + print p.recvuntil(">") + p.sendline("y") + print p.recvuntil(">") + p.sendline("2") + print p.recvuntil(">") + p.sendline("4") + print p.recvuntil(">") + p.sendline("y") + for i in xrange(99): + print p.recvuntil(">") + p.sendline("9") + p.interactive() diff --git a/test b/test new file mode 100755 index 0000000000000000000000000000000000000000..34d41a2e27966a417e371f40012a624e017f5395 GIT binary patch literal 126784 zcmeFa4VYC^`v<(|W7nkAAcSxbO(auIqz|T#sZ*vLH4(}*)zl2r%$UwpQi-WFro%{) zgb+^;$)J*iQRyVf$RH#`;f#71Nk-DVzkA(loxS!sXCFQO&wE|(dtII9(eJEv-|JrY z$6EJVd+j~@+?AHzFE%E|P@g#CDnpdc=bBVWsQkg=Nj16}O^sCJ9OG=G5$N&wPw|Cf zPArJ{C`{m@5eKAp%OyP&TT4ELs&_(a=k!TFi75(=L@rZ1lfJs>AADTm-yn{BhRX`| zcA~#3$sdBPhaPc9pVSrEI4#QTj`v@+av? z|80`=Q0xmDeH0QeeLUZJ$I|z{J47)Idz`@a3RS!7(2n#x){ivL7$W;~^2;dc7lrIK z!?-Ljcl6~cm*tJUG%q*5c*>~0A~sA>Pf!;Ig?K63NLo_|lh zV*maTvu}K2UGAD&yOQ3d1IZ&E`VhZ#m%uhC6P@jPP<*F4`c!3apK$7;W_`F6{x5ZK za(K1T4xL1*pNWnl)sKKek?M;b>c>0CPjHam$D#fs2RU&L{r=`)FL^eS{`We_dDfxd z*B#{e9QwV+LH;`qa`rmNx!*xfjYItg2Y+sN=y#)oy-gkTdBK5yx�F4tkyoeO&l2 z^z*)hoYoHgo`ifADZVtfT%p2I?(R_E*+I`($Ui@VoDR_QB;yRjl?;dDlgMBg$O{v_ zW5--_3FU&zjm*sP6AJP(CwjAryqTFs=75YrnPanyvd8C6^kx@j4C<3tke{8AH99Yw zX^|;64fWZreqH7l9|ylGcC=?ylHHnXVL`V zU?H?`$FxbJ;MCYrn?Brfs5d1$e{5bPt)nP>IeY{S{z<3T!W=Xn>g{x8=8)0wQFeA_ zZvMnKvG9nqG?s~jNzAj(h;J{DpA2d&YsYMnosN4nSUch*dJvnX4*`JWjq zJ{%k=9Xcf&eTEP3)q6l@#}1u4T&WdwHvM~tP8}&5$Kro+_+Pw0E}62fk)XsGjRhCc z;*A8si!f?7{J7v0g6xGs?U-ht)auXH>T9%mmsTIp>d({a>$G~QqM+7m^%rRTiBf;kR$a>xS*_#b z#tW%JegYlXF4CR9F`-VYk5$aTdaWK?7V9JRAvrY8)F(l!mmw6SM6F)Gu4$#!s~AuN zmsXDf7yKk?_43k5(2})!47lK@t5)AESZf%mT0I7M@Z;9%n+I!g9jDc|(CUY4^)x@! zXOvbiFPQ}?N2}NOd4*d2DM|=%idIk8VCpkdt3Op$0_SS=r)l-&TK(x-{UWWtl~%u0 zt3N}lU#``ksnu6#^=E1IYqk1wwE9Y|p7zeiKgT_A+ylowaNGmOJ#gFu$31Y|1IImZ z+ylowaNGmOJ@Ef$54cPAC%DVZuUfz*oG>1$)<#jL6aJ~ywW_zXt;0{{%vt? zD!x%Uhv>C64ftI6JeBFFrnX9ypQbV$(bQIo@?t8}(M)ZHD9@)d9m&)#73KS=Oh+-b z<)VBKmFWnkcBUv#r7|7k)E0_z5tZpErgoGl-%4dVf~ob0@@Oj4(MxTrDBnb7I&!H^ z7UdySrlXcxmnaXUG99thCW>-zD$~(Qts%*mDDa3$w>E^-JUWGx9`M{mlE`R@^QmxICTx$9BgrJUs3f93T~fCa@|+fdr!si zxu3pc_%vy#X>smM61-6&M7%8cyF5?O?x_2nqjB!iI`=z)tKBi1-5(wGwuFFeDIlSt zW}N6pwV&Cu6#g)ZFB|4A>3JHs40q{w-e&Hyo&!+`T#ASUa`4Y)GYfn%BUL+vwReJ8 zJ`9a|Wemk&Pjr_~54g+H0`5|O;4U~seD`(vV+Bd}2hvgXb}|eI?Dz}B(v9xYuLJ(Y zAc{7_U4;JBB(jmewzs}gJ7eEv14=i&MPI4u5=coe-LnriZ)6evK$4KWle!y38kB5G zyt&tiksC=%(y^=1v9!3xT{>)M>7eSqrD;`tO9yRJ?YB^SQm1SfSUx2=#Yciwkn0gz zmJO>e^&}Bv*|4foPka8ht<;me?@Udb#niM^X!AA+F4@%eX4VC2)T2>-S!&YAjlzdk zP5ZE#WL3jXu6LIf*Fi)4mxk{`%NDF<{d-bc$$poRNSvj^0;PlY!qghkfEse6Fa8v! zL6cz!nlP=tY}j5l4c}_mw0eJP3e9?Vz_)PVYT2*t^|Vdk(YNO3(i)7AYzg!B)ZO1Z#SP z@pM%+DuQqTV&Ag?-n;8`;SLP7Ihcd9D!q-@0*!sLC}>d?D|Z79SMdd6LW04#tSC zW$4Rz1eB$wT)AOJb7oRQqg+|5OX#Xe=*s*IsXZ(S!7&s;LTd6QX$O_f$&vaP<_+-En`ZFU^CKP(EC?zXz@g)^plKf&{yp> zODQ!_w0brm)H9k=$)DPu3iOr4J_xZ0vTz}lKS8G0_pOWp<*Zgv0@D*Yi}KBIavE}z zKd=+C=E{vN9JkKMZ{JyPz{+GZxP! zjj_sgxq+zQlVUf!OFs*27%C()t3UAZAxknk%3wiCjXRiGsqsBiMNwCykyPV)L0>3j zt4>8oE@X4wmgYRcazxSR^90R#>sdCZIn$Xy=6uiy=8U^Of;qnq5#}(fKM>F6sE%fH zv0Qrfd1fw@#m|1T**@Ivia)fXZtOWy$y`B?U~Jcigi1<>msw7jv7atuW6xu{Wo(TJ zWADHdabdA*WHObDH?I?FC}V#-XfyUUyY0;!jJ-lCIZd!fF!q}HHe)ww zD(R8^`587gh3S^DzsAGZc^MImJ%jaUR)64P)?XR>0vDCBRUVtMfBkARc81;db2Z!b z$X+Xzd_b^AF!q)QZN`44siYg*Sjy?obj#RAWbBhPr$T3Cd)8kW+mrQI#=gZxW$d17 zZN?_rjeXEw?4;SQ8=LbqsqtapX~7=B*xSo(#{S4+!-la-%DIW@ma%8V!Pr-5#D*Gs zHS4d8^&AkvQpSG7MP=-v!8T(rV5-VU%k0H8&34_`nNP8?s|9-mV`n{JGxjeQ8)j@* zDQ5!HEo0lq!q|6d#D*F>g!Na(j`_uA>|QP^W1HBGy_~7a*w^gE;hOEbv5S_nv0DUt z1Y;k$-)3y0gRvedXC`-R8GAJz{15D;5gTf3_8=iy89S-YX6)}=RK~Vu=0cf`2QXC` zyVc(IHdaDLgxk;xSoS0v`z5n8ftHNLcn&1cStz+tEuE$Qzy+EQeLhx&CY0V4E82!bq3R z*jfcLg)X{H*D{}6mMxpSQqJ4lEfYx243cxYWs}Qp)7wAUY)a+kg)&Z0F;&@gzTKvc zT2Z$tfCB+aH=T81q|1S$(4~yVJ+5@E9nYQ27iQCAQqDfs!m{aklG8`X5phbMXN%Lm z|JZEG0itjX48%(?3>e>ZrSwd zUyxHEo%1zUzkmAEn?sN%34@9 zy+U%X5pu-X>w2#(PQM0hHhHM~vzMmAkUy1eZUwdp11 z3$y9RN7$xwnQqy%yB=~T3pv83nR9G5oolygDHoMZF?O5ou@^6Ju;~`5%R{;_vS|qE zvaf%rO_oaB7ik9rX{?VM$^Y4Z0ro9el!Y`T$) z%BC++^v~Xc69Sxv7;gXUD(mY`>uZhmHK4v)yM`Nk3k5_}ppvg=^&x23rH@wY51hco z*U+5KR!(B8L=jhU;#iw@gdG>66*BDItS1vlW-7`2JdLO{bJt2a?=hb!A__q{&83_x z1%0(3@Zm_W*G-t(YwZd6_jS7U>5;Xos^TrazxSRs|d=OEafZ`a#jn1JiRHY>}pez&TgfWbJ%TfNa63Z5~Aqy zRRx9bqr(s=*`4W3ASDkUgpv=@ts&vX^-@j=^NFI*R~MA?m6Y@AUNUyIAOw{x?DabN zu-Do%LOl5moBXB}eh~{7MV~KGY-lOe{iN`Rh49%-ASH*9l0VUS5lX%#=dGAH&#~ zgxQ#FAAKXFD5ni!p&sEaf8bT7s?ek`HCa*@GF6R>)0mnlsgs$iMqfP_#n45+H*!%8 z{4cmzCEVr@bmyX)UhBD7A*p9`QO)cpxL7W!4K>0dl|N=OwNO&OVX8`7qnYZF)QwD4 z$+0g}SIZE8rxh`QL>rnwC(v0DLOhJ=OrQ|A`~@+6F_oy4D^;i-XTGqZa-NiPBGZ$p z1K*qF@TV;e1#{)*Km)rxMBlJvp8EhRxQfkVYe~V0bx^QbP(kIDBbt-+WbTu4@&sK^ z=I$uD@+MYN1>{K<9+uEI(YXw~*n;Wh!o8&A_Mf5Tcnn4@o)xugQHO z3EeSQu4bRB5qDTLo*kCZ&y~V&WqMUm$#$gVhO3m4YFxjp>rQi4Q%$O&EIuryPoX0X_;TZJF&B7Bk}vQ132L4dR8vjerYt8crN1lX+$rR& z78Bo|D_bB7_F5a7(#LabRNh#@YJ{cqkLZ*FYPM#&M`R9C^UME0O>a--O_iO-GGACq zPm*d@e&lRne)LNrMLF#*7Rt``2WptALX*YRWO5nO@&=}=anXmViITdEscQ6H z$W$?S(RL0~)zELuRGuRKKn_#Y1gqs@#S!jzAQ#o#exHlwlG>h&DucYp#X?DK&PA2H z9^j%!QtQ4D-cTv>cBUpv>JFx=%siB-iITdCsVe_>VX6}KsVFYwY&%=@=j#%GA4T6E z7{I)&1r3ITeHaW+byGuHY5O1x5k;)Z)UmJ2C@CbKg>Y@uh2YRGVWsj=cb3XIc6K>S z&82f0sJ4==618HSPWTb3H43Vxf^bOiE#w3{yMl#OOCh;}7?NEbx63!MdMfx!STbkV z*;OogD;-Bby%wyVs1@pMuZ4Q!G0N?Gx56w913OS zxh&P58;3~M=Cf7oAX4o*Qtd|!1^edn3&9tX8-JHV2C5_ZhW; zP~=@1-*q)Y!$|wg&4J;pVL4~VQJfuf!n5Nn?$w?hU%Q)C|9yv0JvkWrHQz$@Yq9m_ z?Dzu}Q^Zi9>?nFETS&cxW=9{*G%Gu9|40Z{+3{M@&);RoCYOa|$GI#;Ij{+9%Z^6= zW2%bLJ}xG!{KrK#JU-xJqNH}XFo`OjYUdPkV8RU=GQSpWMZ9ZlOz} zA-WwyD=;0wu)r%BZ=V<8pfDK)=CvZFS+&t~;h07tWAdv<(m1{?j!ha%WjA_k=1g0G?8 zr9t)77&)7T*t6qoX=6DHsk5o)m>p+uu+-SxC>n=k$0O5Oy~|lL4{K8Ix7|?h{tn7} zYWUA!A@=N8FKzr~yRcEr9OXTk9V6$SUF>c(^Uh=8_Uw3*)Nla{_lSu{8V)55_g|_s zRFiv`;0wu)xl+SxSx6xX32KOOg8WSf)V2`;J_eZa+JmH)V?hQ~`>OqA3_E~*juAQ#2(MRq*! zzR+Hc{E1BE8G`)BR5iJVF||VY&>vXCRFxgCU~0LfE@G<68)q=JP*SHdRb|INx#*G9 z5nNQ+@hf|Ah7c8!9oJ9gIRBzcqQF*siNFrHL=92Z>yI@R8no_#Y#2h$R}8cDEicOb$_YaNi3v-Jf&t&NOp|H zEE2b&aQ@3)R{`wHlI_{?o;%p+*S3nGP$gnO>P`9r>a_@}r^ZNw;9F?Vj;p1OMJ%Mw zrk-PV9L4IXvH2`Z7Db=BuHG|+)oaC)d03NrpM4JX3Nev*ZBfI26brFu#|x!;AHOGT z6f;M8FKTvti`}heUK|UzXUASr!$~aMBPJec*o8FQo}@HXllv{f7m^*zWE48GkU|m? z)KJfkTM%9AcIf6nYu2z_^g4ScXUDnW+0o6t+Oy-F$?V)Wwybs)hLQ(Y1_OR3hsajW7P1Fk2e*Xljm0ze-tB^uwvJg>3;$|T?OVxgT zSA>&mwJU4dO@uy4usQGz$K+)x`68Aqinu$#lJPD;Bp83-QI;%fg?htDyJ161r*0YaW+8mbg6}K%x|}W5Tg^i1glKi$%2(E`VIa<)dzNy{)cN;!qWwZq z#L%PR>g$puH5|^uMXk{AbkeZm0_8xJB9^icd!D*eM&T3|k}O0k4LLiqhKX(M8Xjej ztGUvLg^MCaAZs|Mh<&(bqwt}q6&e@-#UCQ&Agq36xuZ8drYk1 zQv9i(HAglFMzDq|6FkMj?K_CQx3h*VS$H`K7aD%N0~+R?uY9PI%?K7^-$7gBMu<1n>%3!8@P*y$?IHHh{L?VE_+Qo|w^UKP}^BWbwxJf)#ZrR!LTeG{=z z2I5i{QfJd}uBPG4hZos2Y{eR?EIyKj+xHPm3)zQN?+EjG0id<*fsdeJQcy#+P_$wp z_I<>!(#$dzBG#DTDqX2*XngaVsYiJdM^3F#Z;18_?fZzM1*~BQ7VZ&C6lwUMDrh*z zrF^KC!AUGc6y*aOzAo2E4e31rSceNqNKnIiT|>Ic(zc4#?DTTc>+Et$I{w*<0CXw| zNh@R;GPqY!#GOg1^>yhZRiDVcidr#1JCW+|pG&HfC1a>qA$(2y2+>Q~Lh2=SAJK%S zos^ICJMeAlC#b~xqNw%}$uI*%p}PJs%k0)6`-pg!q8vDzi|lBB;QO~kA1X%UnVKwj z3R{?}hQ|P=CQ9n_OjRTB5~hj~4DIJJRSo_VnaY#IAIN8_nqNP2u|iBCf55{-0H zEEheJ+K7v4H*zl*lO;8SwIIpVA2ZysR}-{akAGvq5~NV@YMtOs#?H z=LqW51cvVCMd)XM)=c&DE;VC&ZVKzCmDWJ@v%ucZ>!*kN?VEL$8&p3dt$q%Ouev=I zS_9QjdwW0EMd;@at(ofQH`Gac?hEV3tu;{nY@!A-@xgDk7<{4Q;3Tb?>c?mGbADJq zHLqI^Q2mUs_j7lIe*UdBQ~g|M^|MZVCBLabJ0(JcgIZmo8vk0I(q|j$q@%LJ1fQ!l zP?|iZ)hWThuMIbJq9r&XOz>u{ffC$1g5W1KKBe)Qmf)AfSKSp8v<6CWtyZTrPSfg? z;CE0bU2%Pw;FekgCAeIxQ-b%u7Ve51OYmRftFG}IS_38ciU@)q()g6dEiA#y!UT`j z8YscLwK}D7H?2+yUV}R6ifh6IH_;j>!LzkGCHR{);jS2I2|ggc>aM8J8Ysc-BM6?W z@hOetEy0h53BEyVpag%c)hUfH)9RGq7f>f%ks2oW=xWPEC3vbPL<#;><5Pl%Sb~2L zUv*bJt2I!9&x;^eSY8 zhgMf5`8sHIY7_aqR#zeU8fkTEJ9&>*S1$Q>ziRnKZ7grn_zET88jVkFF*|8|9?5sV z#-}!$CxB0e`$_SY#!=m$Z1_m6f!afUjyhYoogQ~APjm=(V@;|Woh4eG3isEqSmvv6 z->mVeaKEPUsc?7J_*A$b(D+oin`(S@(oN$vJ{9ggT3waoyIQML;eJD_tB`!BYjrBz z4{3GflJDo2EqhhCZ`1e+C7)m8Q{nET@p&ZQlNz52_gNZWvgDhr@u^Aut5%mN`L5OK z)b+;usFTBI6h!lmSqVNzYoG)#MxAZ=I6c*MU2})wv!%jvlNvsKwVu@QS*r1=;nP~< zQ^RM9#;1nQL9I>=ACFe2hR-&wu1>lsNvl)CXPH)4CHV}kP7R-FT3v+|rj;U+3x@5`ML#tB<)@!x8M9J4ut5ZkU<*1X>??R{$5aqi!(F+&xzT93Td)?A2 zQ@+CyZ?`O+ex$UxzGV85nBqI{o?cI{A1E%ujhvg-;6~1B+)i@)PCackL6`oh0%dJ) zP~LbJo%nisiE9sY)vXd-S9nnd^SyI!WBaIdv;@-N{^YNmc>4V)AmwE6$ zZ+dB`Kq?C=%8K4f(izKA!9PsrcS$;-c=u+!-nV+!s6Q1e7U_q!+#lozzq4$As*8An z@6l9xOPlt>Jz+LUT6q-OHaOI&-8l%36K(51lsP<#%=jp@XnMAJCV~y&Z%lp>Y$6P0 z{NiKz0%Qs+z1f+`H2=9e{e3+y;NSX3<1YKpE=3*gZMerPv`d(6r zchcfbk2pmN>s_{+0$wNDc9K&nUIZ)O0e!ua45_a~k@}p*w?=)J+AKk)cIxqA@H)}< zlN_5iUL_gYOo^h+CXH_zl9uq3)TVh9ZI(yT=4hBUbF^NrVr}%-+G=?Qu9t7Z4S8el z$N*HUp^#N!YSH~~ykCK)ce(b~UdJ{|oZH~Vz=_uTtvQ=a5bQF#iD6#noQ9kdd;$2? zjYV*TQ4!>wt;-WHsXdcw#BioIq_-PNti{`jEA$uj2JoWZvSAhA1W7b}m4bwqt#g$> z@E(_I+&;W$-G_Q++lJ~{mBpPD+iqeLWPjkGXaeg7RiJ98c;AITa745SduR4YciG6b zkWxXe?|+nBkC!k|E1}K_WQT896{-*%QT3JRYS4$M-id}a14_5JOFzQO<{nI{i@+6& zAp&isN?FvVq|$}X0=Nm>TD+*(YX*8f3GpSH-0H2&GP4I)RF`_Cv+lHdavF~nzi=}= zL$9J|^->TjQ7ju&kFJ`ju0DODp~3zhYJNMs?FH+2Vv8nWggEP?LFXckZQ~_TuA~1& z%+Df~wU~G0a%jxSGCk(~h)p_pglG~P^Rc2uSj>lT%rWk)K<}Z@+XL+p@*@N~Q@rI) z1bVpW*9vqs1-_&**&gT?`$RI{^Eh@;gYl0Hx$S-a?lL1RGl;0-P2Ut{+~$|XbC4Ej zl;Tw`@6^P(+cCuKl!-z}CGU5|;K4Y?{^28c=~g(n5^wm&GYHmuvT6GHsM;SWk$uSG zXij*UGj69N7nU(f2eCSCtaO=xmOMyD_!Wm+$pGGzO1I||HhZLd?0e> z`w-!6g1p2Q5u6OD%#L4C zLG@1hftoYnbrg!Lus~CDDCrMur<3)IL6J3L)Z9y}CVn`DbCjr>cOq3GW!Vfu zkP9Ax7wsbYLPX$_MIwI&h6>zCti$m&u#xynHjT3V@=Fr@2A1Nga9@d*ZCC@CgnO>y zJN@iVi-nc=ZH7~XwjyT=ZQUC0t@K?aaUterQQS>ZZo$`b7)3di9}mOMpe^f`q;>`> zrv~RoaBoIGzV0x$77J2v90uFcc&_`qx%F=}{=2#LfUR$r7>CqL_}p5ZVrdz5Zpjoa z*TVmPEbqszUK`6ePm*h=7|XAKN_#ZhSpGqbU5sNnmg{j-ID9PkgssOkmQOe-!dSi# zo2HPlyajydGV)lyVF47ikL7QXX9AfEg*}0L1&X0G4_^bn6Td!|RZhTKmk?a*JgCKV zEv`g_*6IUX>?wz>73y#@98B8rPXUPuzJSVCrq#4~1S7r0EIgVEF`q9|xMi6urQwwa((_jK$3J3S2u?`e|OQ^;D*zh+iOZLFR8 z+}~ujQCDafzv8W=#l&aZwYU%hECANtoUif%ZXX7zk1pGJ{o|7c_}+eXS6{A2H8|fB zgMp=sPmGQ==s42#oh@{aJ(QzHG zDKrHV!H6mX%y)kP&tRafti_18Z^eSX2$zJmJ7{@OZG#fm>$R3d-dEeTfsFfgZkC}W z2HVnT$$=@$VaigN61EfbrJ)+s)GLbW$VqYZ9<+7@($D{So2#8tLP zd)aiIT!tMTHgUBpup;5hB5o=M=$&X?yFkj~o{F%V2x5i_W1kbncUVDno!V5_F+u4fuWaW?$x!Q3p;m}{s(%&k z8HWxlN%yblUL!Vm2Y+b9o|#W}`LLk+uxMD`yItqW7q;8H*Ap7m zUN7n`@68D&do7BW3N>5I!f&NSbl}z0NONE?ycY>+PT`$H`y*w<2V$r}5$U?g*2p^0 zg2F&2h$^B>4hX-ELKULv4?O#a=C^j5-^eHWh&n~r=&C^sxgI(Le)!Gi zv8FI*Ut3K)MB7~6TWd{u2Ww%9I=I+S1|3T_UxLZ7pp)Mq+tqcixRG$J^Qp zVj6^;la5~u<=N!=C45THP5W9%^tlsStfB9;yDP3h+g+t1#t@yFgylu;iITuVCt@|y zxbryC)Yvbz%z*Dc;k4A?RZ}oSQ(6{h#!eT?ZGJ}6QW`b&%7Z@%UFvaWmOys3{!Y6? zATI?#3q7q-S2EO!dMw$1)*}C8?iB)p*F5OTwgLnYh?=lmWVF8@3Mms1g|v zqiTVW7Lw@uN0>B7@xeqnNHlUvlp|>;qY`C=b#NnEhpmGY1AEroP)9S@c^y1Wrd+xF zTkGIoA{hnGXnqpKkaaLl*D-V*+)gdnJ;fs8A?`^Mnt6lk;MG{Mk7*t3b4c@y!#XH_ z?@xIz!a6t`8ilQc+bRBdHKT1eb2r8xInZexyq6k9S_kumG^g;+pq;x?FmxS!o5IMh z>n5dG>tG#bK8DdKv=-}NV=UA`zeQUIn`&J~TnEMP{Yjnng|34`p-9wqu$v}6bRAqb z3pyV2I=D{^7rLBP>)=7ugsp?w5c+>v2Oq%Gm*MN+dsrPE*Fo=p{+o5M`W_MEf4UCN z#w`;#?U>d!O}^qrw%+7f5cV&B?>RWmMcYK$Nx%hgMQVck z66~AaiQsHp*kE%rz25NBy=t`a2Tr5wMFd4O6-QzmX?o#>yp zPwIpq5$5pt5Iy(y~wPvre4dh+Z2X zORx6{{;*zufils0Jy94Jw6#v?E_yxbSbD9DZ0ny^ufjXz8SIs#%zS+;&~4$8=~aez zIJRGy$22VP;#;xtBLgeN=t3yJ4m^kLc1c|f7ChY65yNMT;$O3m{Fzp@?^RVZU)4N? zK|z;*@VgjRYiNz6Q%>7m9W!t~Zavv@gF1nfk?svMbFzKs&)E#*6yR z=#u@xS)g(s?vJfyO*g+?NXhDh&xBTM$$0uT8@$vXbQtds+#!nZqPT^MBSdi%x5k;+ zezKfmD(2BR=rV|2)n6;F*hFwEn_{^ZH?8ugQ7@D#iCehi0!+NXr0GIP;0b|3&@=Rv z56I}rOIwDFc+rYuDC_9(I*OmT?_%`@~?M}Yxnsad+z(DN1jbmrS1 zAz1E8L+9`4si5(`(!Sc3RI1wy`n=^W^F zG@s`4UOz0K?wBItK@aNKS5KKw&$OP!(BlFRtiV-GFrUU)&q*9(KFy(gI(-Lvmsdso zF#oiC8Vj=rlm_!@GeHgJ({{oAfJlQb=n|Sw7vXUP&Zp;0re19MbU;1w=|yBaww{9p z3PD5J9dyItALP>}6u$`hbOICz9V<9#vyU~b#>bXVFA>jK{B1t1pX9g)i<(b&&=C3` z)&ci7T&vxV`ackfu1V1dFe!NG|r>~+EF`pJ=jkD)dGx#JXhJ=-P1H1p< z$fpOLr5UcW^>lBXmjk&`p(9! zt&ldEEpSME>@s6CZd(8lJnn&pg1mEGFHE!z#_$2qMUxn|uM8UiZ8h%5{fi#>+I1a` zKMa8R7)GiLr6GiNH_$?)nVQrzdeuVkHQ_xowgr9!?+~%i0um=RVze`i!4)}u)z1wh6iEi>D7eobm_>%k{_exGyqY|oQ~zau8}cH^kn%?aV-Xx{l9KM!N@mh6 z6cEYlip2Y0YT4Q@Bh+&uSFJ}j!(o1%czO_zx8~eNI$-V4pU{gZAMOT4=GI}HHHIS; zYY~bHEX2zrJ;}UN{6P#zc%Fx^F_zNzYWiMETjwe{mQH&gcg=kh=&WTCaa0QKkr2H5 zZ4a_(;EQ)f4oWZmDZTWEz*$gw-x+jWQo5VU+d)k)MFR5&TES*W*{MHS=Ovp;HVqe- z6QTPX>F?9@RV<>XVnaN2)vcDNVk+G+v|os2z|lT_e-HGKGcb;yzKQx1PoK(6(d!?0 zb=pV5TH)0js`1_CRUH4?yefX3r;NSoCa=!gq zw64t4p5|bw0F;usBp_%?vYwN{P=nhHfr#5_Tn+JUh8b;S{@f|Y{9u~xlxOh|W!wq% zG5bEDp(}d{t^<)WqdtZ{8BZ?zr*?&mzE-dd8Wz)3#O(A3u>ar_030}DHg=_PlfFS8 zHzUEJkDF9b<+!&wFBn2q5sDQcR)1WkP{+2RU)_OzF~>7o9!f;G|OTl1>eXi(l(&)DI zf2%(TgC1lCl*QSq8u_X={7+9rWJB(GSbux+EDaEd63YT#f}fA?w5Mtn@?g~e!O9!P zMYWQhIzK+>RhyODI3)HFDgx}#Izo_6#G^g5RNJmC!u_l7 zFW|0Uv6gU~2)E}f@BT}A_h+!n1CAwQMb~)Nm7mGo59{`wsa-~v5d*)ewjvu}ZFlc% zj?uy&qTYvpS^id}@O2@ERjCWjRVXL1cRWebGf}M^C9Rx=UZs`yP!(+f>8~N-uQnK| zG^Vs0kv3CYL|5}bX)L3F=PfK6#yKvI!^Z;pz|v{)g~+%FG+~k-U({Fi0tE~Ue=7A7 zocSTGZIYvCP*E9SjgVGU;9cm-LTfh4UGn5H(p|nTZ;NMI@%zoH%Ae{Y)r2?wsY&$R zHePNXOI)XvCjLh+X#DEF@Qb48H$XP-goOnZf;L_}cd} z#E_F!94RN+MxDnMj9oY_DKah9C01_wBS4P2ttFmeq;=h*s>p?F_Y~~LO%(a$^95r6 zDPkjB5Tt^uA$a0sA7|k*U#_y!z}@@ln5y*6bnQsP!MULC5f!^3%xP7y45gh)& zH{>thLQ(Y17PH9L@lrY$8>CM~@} zyVba98i>WB{1$a2Xh>|lRYV`c$C<${$({=e&|*8uF2%ZRZptTioB@9pXu>_9nLjWc z3~vaLu!1TQaJLwv9gmh^8RfrkZ!xP39JP0gj^P_Nst;PKH(cYZFy(EnPMLR>R;MEK z2!<#1oKEW9IPKtspU4USrY62q z4^Myxd|kdo75uS_O0ahcI+RKHE$fvw%Nl~Ov~eEsr;(mTIUx8gv zgyz#j^tgLlZs!ktMAfCVd8*@Jr?xN*F`xpwS-S``GtvQP%$AWGd)+Xg^s`>q4=6o^ zYmw5wdS#^hE?ksr7{lDYOP2$OrnmbJIVK^nX9RkE=dU>LSslM@aV}0)52u$N>RbAA zuZEVp+$9@h+*f{8{3Ehm!p$SqyNEV|ZzCCv_C%rY$3MqCaNGmOJ#gFu$31Y|1IImZ z+ylowaNGmOJ@Ee(55yRBjK?3mvDBbzJo@y@Ey^}-$ns_v88_tSk2TV=io7|7yCCll zqic-N4EF}G!V zjiJT)Z6~^hdW&*zlj2=N3-hujLUeW(_{Y1r&w<%q;>ymNU<}F1&36@yb4do{hMe4@ zyuyNlJR@Ubaemf>T%$Mmyg9@pRHc8YFeH1Tx1cD?n_G}?^vW%A4bILUo0n~56cpuW zjV&-TCPS_&kb16+oT7rsY$<7l-&5^VR6H>!d#sDCzac9xj|8WU&CX}G+l#Yc2YJPn zo;yCr8?=H;;$Lbpuz2kF3EBBx=^WH}ii^f)LA^VS{sm*<5>HWqH+ziGmHaDx>CVo} z1Cbpo3j^}UWf$ca7-?hjatkM-cks9h@}-Vf8%ElMLN9)zIrtHw9CSynH#fgvqN<&Q z&I*dUb;}%-S(KGOK09+vPWG7Fy16nl^Ib`kb8^SzxN;}DE}UB2&UIB!mp3PO;-yzj z%$=H@)GmY!fiY*rb?=Hthx_5kW!E4abK(1nYa1F?0M`REfKPiG8ukL+*EKXW!(-aj zz!c#3zzkqL&z=>VYls#|=k-DZq1vp*=7a=mlO6TmYN`Tm@VTtOgzd9t5_(9_{g$ zNz;HSz-7P;;5wiexC^)d_!F=tPQqp^Z)k|`WEk`=?KZ#*fvZ5j0$2^~2RsPO1GdDu zMgW)sZ1X(i0#kur;0WLX;1u90-~wPZumX4xxDD76hsXh73NZc!vDg%;Xr!h z!-K#=;FG{|;7VWx@LOON@U)c;4Ryd&U?R?%#{rXpi-8%y4KFn`OaWE_7Xj(FLe>KZ z19t(vz$3u>fvsB_#+sL*H*gDZEU?)t&>J`xxE#0)xCK}N3;@>y6L2zh{;LfQNx&4K z8|VS%07n4l0&{@Nf!l#wfHlAX@CY#BG{Z<(h4#RFpc^<7m;w{Ky{tPE-;w7w86-0CRu~fOCOQ1D6AL1GfP80|UUrz=T%le+}9Ld%xDu z-~sLedV#Tclw<+0HE8KR^}zTy(H__Wcm#MJu=QE+JFo{Z zA2 zVHF*ybb5Pv9Y7>+>dT!pGpFc3y@Bb#zCbTsA3%fIk2;fG2*5_Q3AI1;7EoRlui!JAu`}dSIhn7$a4T>pkj}pAfz7`{d)#H~0qhDK2pkUd0;d3LfJ=aff$M?&cEj($vA`q1 zB4F!wmgz;a*}umZRjSOq)^tOK?PV7y(1ya7xG-URdj zmjerdYk=jzt-uQ4_rNM(-&%|};4Q$G$r$&*6yP4<2;g79X~0%LBHqATfa`%Pfi=Lb zK%*n%0owo%0Q&-)@54L+rUPdIbAZc$Uf?ERIdCs<1+Z@?#9=@30Wb%+05~7G3b+zj z4crPm2n+yQcE51@ry@B@tcL7%bdw|~T z7w8AXk}N(kQ->HaQxap&YSuWRJf?9X)gx^iqtY50Fg${v$o$A#;2?faANV&0Uz#WO zYu;*Li>8wkW*S$Y+5O_qZIGR~zrMiwz8G&*AwSfXJ~2~0=|YpnkNq~pFwSCqSU&Z! z2Kqb)jQ( z|CePy=+hv-mrkE%`F92APeh?_1HBUT^Yr#3toHjs-w=h~EDm`abZjfF_+DqVZx8yq zDDBfhUk^H#4Xgbat9_o7KSHO+-XIuge9Qyga3k;Obd2$F;2`=6&=WzwR;R}f47T3} zdMfBx_N@L#TmA0`-3_{vea+&rzXjdNf9*jh`6ui02U+sdLC;<6OwR-TX3$&c?OA=1 zYvzGI5Oi!CEd57W@>hWF0sT&$9y`ghAM_QVch~7m7V`Ilz6Eq_e=YgfTk@Nkh<_A% zd(bPR(9=O*ABCO=`r0V;d7!U~LSF%TMHKor(8+!$`}TvrJPN&8Bdp_5=j zj=Pg5EX|i);9mlHSLpf{S@Avsx|6?MXhXj@LjJxI-{b$%)*Y`UBegNx<8+HUaOxB`fz-Y|D&xXCw6F1 zMh0Yz1y3YhsShvcw??5a0KE`&T;5yqhp`=PP(?qYK<(SYj`%w?9mtlmEn9XG-{a2v zg(IMk0KJdi4`kedu3V^VeFCn#L7x^vkJaW-DtLB+$0_HG0=*jarn-!NYzz5fCg_z> z=u1Ig0eZIHK9&~+YF`QZ0nnY+q#Drog6^cB0mW*f^zQ*oKHK3mnMStT& z!#D+Wr#-a`^mx#n@?t9JH2!+%`oTV$BBcK)(3?kTKNIvLXzwI{Dd;~s&?y(>fKKu6 zM!DcFZA}!{P;nh78@Rw1AUV)uF}?@=3_WAZEnhc-5~H4U9t-V39|yYASV))cZL!wI zLLTU&(cVVa#=<<%$Aa!O7FNjiPGeyk=y_4v?*}~>bb#dpxyF$%={~}6(1kCDLQC8A zDEpFPnt~1NtxKKfR0ilHKu?U-`iW~AOP;3oUeME@cFu_lK)(WXr<}10^mb9`)u6Wq zo!0xH4ceaNAn2Dz>Az(n&XuFcPXYauDD(`_8%62g3%V;x{|i8G8b$sp(EobM*+12w z*MT0%eivMF5cCruKVA0^&4u39Txf-a&?%HBw!dJY7Hsi5x%{aIXF26col;~t9>La2|i;F<6o z&hhX)$P;^wpu12t3-l*I|6ZrFonH_W$yg4aQU8jZdq_qh=r@7h6W`GFDj^8GT<=~vw!!T0zw z^r*%R9_48>FGk7bkH+E zza8J>X{V_4jLj25h==Z}J_Vj=V{1Qn-UH7_@LMu?vqk=HhJ&F-D;pX*>U8eHaG|am z?OTCC)>*g z|6M^Z2R)LF)cr-0sBm!EHqx&5G*f$nrJ)eK5J2zm#-y}the{YlWB ze4Gxt5A@-Bd)~*1yKrPJWe{6gI*1Kq&0}zSKy!T9dsaim2B^1V;$&UpuLlg z^h`?tbf@<8tjkYP+Iv7h5=Fm4(0>Fy(*BI}FaMkVEB>bcs=w*KPWB&Zui`@giBRky z^vlEd;27l?ic=xdF$Fw5Ry&X54A3tJ-L@Ce_OM>iM}rQq`jFQ~B!2-2qd<=|&WOGW z^ueGz*-#DoaL}XKP!FD^;BlIZt&q4EgYINQSI{?u4lxmJ7!LX-&?D(cHcSD1JLpa} zE&_c$=v{UB6Ro+t7W8V+apGh3e~U%m3HoPI(-ooompZ?0XR3 zPI>n_P^mx$6*lghmMD1I_;r&4$ zXQO8cXA!+C=swV$=I?OOr-44o*8XPEo_yf~eLd*8_#VF+QbK*ftcDBpbnqSqFYSHe z7izrPIn5UEocX%5J^|1ZK*uGo)z`IF>=Q7lkD!l1Iz84Mv^NR#i=)VQgWf8N{2b7m zf$lVq=7Qb`bYv1sKkeC_<)Hr#{ha*01@!Mh@1eIxE>h?40nlS1-^soN+yF@i-AR5D z=;wg$1$4(ZVn6ZnoO^c2v&p!WlBaNNfB5@W@MstnKw5640}rScUF%~P=+8OyL3SPi{b|sz(%aL` zPn3z?8W&ELQQG$aeSMVvM}WROO8aS`FN;E70(#M;hKBjNe)3?7^ji=5UeIymV%g8f zU*fsBS)h-C{P7^i7oTA9P%Pwq85%b$z_%29Ly7Ok5I*f0fc8jS+rZ~^|0NytPovnA z2l|dE^m(9f2OV2fOIPh);0oEl6MY-#ThX5Eu*T)!U=G_4`ccp^{4Kh?*GYa@1$x{% zjLBH|VSE#d$Bpys=Hm8^7#AsUK*oCKy;%n6d7xjX_Y=#>jN;}6{Rz;W_J#{UfB22a z=g8E473gn+9x3j9L9Yfq2l7W!|Gk?hJ`kJMyw&}2Y0X`}__XFp^GtX14ij6%n=4X?PBQfU2NyZDY=F&;VJF(`xNk&zi z`SxU^HqLxuvau-MoIBZA8E+n(WV~sb|C(ZaYMKvCF=jV1>n0nIH8OWiHlA;6K5&Pz zv9bB*6yrc+bLSLeZi2aKit$Jj^Y=T9iYDfsJB+WJn3Z=Jzcn#e++oaWYJNS{c)Y3k z{#0XIQ*-%Lt!?&jvwX~x0k=Dcaf zb1lsJJB{@%68GL|ypm}CG0oVLXnr@%IGkvHG|ebKDe=u|#+;MQ9n*~^C!23gH@2T_ zK0n>qdvfB#(~U1qF<+Qr)SY5JGQ)VfrCBn=Slcr3=jq1EQ_Wd-8JkWu>t+~-PBnMU zFy@_>xMhZM&*|n@cNvRLH{ZL<*m}CT`Yxm9^u(v`GCpl(u9+EQ>~Cd04S3=V^M1gp zGZGKqWjueT`M}*VM&+62pQt-rPK@!?h31cd z4=*%71suK5+yGc`k+~AE`66>M;NV5(9KbVe%>%PzjMv+my8-*!np**nC7EjgTa(PE z0X0eH{eb!H%)_&wQakf|z}**{%K(pD+_4<6_fqpIJX3r4Qqu=m(ZT$qEXMe>gZUj` z_GRWrfX6N~-voScnfY(PpO={n0naC!cLOSu&Hvm7?;3T}ShA zz$2Z^Qh>jc`CDm>aj28|4Pahp^8>(Joz2$)KXo>r1w5W&J_vX<#r$h7nx~kxfQ4Pm zPXN_j%!dF!cInsvXVqP4mY2sEbGn&F9*8kkcQXTkue+JmfU@ppCE%&<<_bVncXJWo zXm@iK;Q1bA-TlzIhq(*za}RS1;PIa3D!_X^&82{^dz$kA_g`h!`=H=e=3c;$SD96S znOB?Z0WV!`E(d&lwYdPWEY;ir*R4yv@-4u;zGlNiF~-w<&3%B6`kJ2s{_JaR1pF(_ zdeafL;B}_W@=7&DQ|0_cxybeAnN60Ptsj^Unui zgWLQ8@TJ@Q7;x_Z^KHQ61I!ly+Xk4A0R9?amH;*kG~a=jb`HGqMZoie&7bh9$I8Lx z7l5A!o0|cTUTeMrc=uZK3BZ@vn)d-vah}%yfDUG1^8r)xfF2sSaTlWk+Ej| zQ;6SKb1&fFShEVSG}~McSd(oo2Yi=pE&x0<&YTH&dz`s{DWr@ucLHXOH#Y%Rk2fm- z-;6hx0Dd2D&ILS|V;+1GzRodg042HRHo&8~=32m(Tyq)Vk6g1H@a(PTktg8mTg?FA z$6L*6z+<q;3<_f@9x0#Co^YYADfH(8Zy2oRT+B|a?pdruP0$4f0Tm|@gg1Hn> zmT%4jJe6<61S#!Nh6x=}_; zD+`IBg{2j>1MmEpm=|NrS1=#6c2Q}k#+;aH-Vih4gvrKitxZEr(^)YlQsI+SiLOJ6 z30IkE#*Iu;S|s!_2O61HT|!&4pK&vno3#R7VsZ~^u z-;8HIRsV%7<1Q0_TnzX#6Y@cG2{xESF2iHpsHl6R&#^ z{^%>|f5@`(i|p=y29+`{p#m>=aZNvo*Gn8HagxM25+9cMoWwN}H%t6f;`b5{No;hU zAwH)`yh!5Z68lNKUg9{3lO)cO_^`z1B(9OTS>mS>zn93p{_}qml4ER*`}gV7&6PB4 zbaB47*wwW|=MKr2US2Fp9ouo)#vZW{hclq%YJh4SaYn4MDPnybUgEDY%CB)oypf;= zltzv-%-}rIsxe0z8EU@S>l+(t9NOy>3^ji3^-T;lPwe$47-~M*>oI#>dJTV%GnyH$ zi1jBLbrIqhXJE3PA4yINL**%*8b^1(s`MKE9%r0n^xYAu{$yk3u1NK#7&VRTcYf8mt=r zMrkJ&{!9+>C#6HG9~Dwh;h=i8zOWSheH*^SK%eA}>>uT&exg3y4-=%Enh^PS2>x(? zE<$}I{ht>6iAKDPuj=>Bzu`{^;eY>c_*;hXSId4+4XLk{^{0i@A3{C(ZNpT2!ACp; z0K5naQ@vWh)p~X<>Z94a<0BzPo+9Ht9Dl=K6T&|h{1mUcka#J(z6s%1c6}RCuk70W z4(l_3!I%j7WLMh_T%qhjbws=F75bcvcRUb>{S(O#xIcqW`279+HtIJ#&ny@6!{^=0 zLQc!DdAdQ?htBIygq-ksx)1f|!`_SEVBP7tAo`pf%k{ISaarw`9!CAiTxI)rpX6UJ z<-i>Ac@X(M693nzr+%MU$9#h%|Fzi9os9Y;ZMb5(tbYpi#2@%KS16gMV#7i8yIh zzsAhpL+XE$8LyQ58Q7hXoWTFn+}A+KRaNO0 zJP=SP1jvkW014q&gq~EVlkO-&(&>V9(n*@G1~M6)OLf)lbeZa^rm8wWfRN$;&j9kf zSR$Z7kQX5Y6;MD1)KQlUS-g?ubKanD>EkgzS-N<>8HRD;`}Wy;-*fBKt?KIAUCCVN z+^Vn6-REzgz4zH?pL4Hf032hkCk5Xj4W|73J>c3_lGNPh9maG{m-O1d_X_^qYdQ5v z^3XgOw3P4LmouR0KP~u?l3w%rvEX|y<@9n({6E3BT~kZvEL4Q(&vEMe6~PCDzAxqJ zhXSDVtDa(DK=8{1@B1bLCkuX`;Cm!}R`ACJKksV{bO`>Y;BQ>Vz?p)d4f~q%?G?V& z{w)hW=Q&QO?elrT|Ixug!tm8xDd29QKOZ>J|BRIXCBa`5ynHJIrwaaO2w$BGtA4(t zPv-$AIy)cdgr`aRdj-GMDbH@fuaI^?cIJ9n@PUW;I~H@zH9nW=Kl?C$e}-=fIvbbr zeRKx{%I8}JpX>13pMzm&e0@_GP1~~zIMLbr1k=&^%9WCyV#?_H3%(`pmGn7>KWP&U z(HWBZo+atKj^ccm3!UQypLY?Ndi8e8TBIjBXNq3vk@Q8u2c(>8!Tdq+h1YXJZO`6$ zB>mBNqGuu2%yk}cqCe*r{;uQwp9KHG*BKw+TOtF+MCm((pEcj71V2dlcA=y{9t}n5 zKlLmF=Lp^<_`SkcI!-_Ip=i1BN#I21-CazePw2dC(xd#}Vc=N7e<%2e)6R6(Ezx<_ zk$cwzN0-%IUy<~Md-x|U=lF-2&K)98R31Jc_?M)!oV;P7a zll1>0cv|{J%SL;oh|b0xobaQP{!QS-&)ZI9;3~m;j$z!@Yc~QXI^UG?=s5j@;C)hG zh)r|l(6HL40-4(m;99mY{<29wC-Jll(6#d8Mhqy*_e6oo!8ZuMX*+!6I8N{C z$Lj@u=K-d3w$M*5;PkuiWx&>w;f&8{^8K$Dq-O{>>*aely<^S02FlOTxDlb4gd;r037!f1dzO<$3)J zjJ_d1UI@B`_ddyhw%bF3&%K;+u!p&x6#SeU`MZ|?VDJsm`TUiPi+V^b5`5%ajGxK3 z#HR$mTKWs!VJ?a@CpxQyZ?&CAA!iA%zR2m$lk|5AzWX@_H2w2}KlUKwOC|leC>YTx zIOQw?r*{6m(AgyEFBkl`phwpcd`sLdbap?+0KS^*P{<3S|30a&j?+s8-}og?r#ycU z6e6YHdu=U#o8SdWFT)@)i~&pO=S#jxek^e<@FNbKpK$#qw@dodg%7oy3o&4c&gVpL zZV)=>3qDWUNAVW~U;QX2?346Mz%WE7_gMy%Pg20CJx@b_(xvUTQPQ6*VsU*Ycu3H}d~{?NS)^a%bRz^Pv@kp|Ot_)9Pn;R^)NHtz;b`Tof1-|GZ- z?bSyFUnt{R<-^gPQhwp9Qy{kctX;<^5mZdzh@UG zJW|q+FXnu|wYwJoI&iA*8w(l#ill#0(*MWK+VtmiMfcYgR{=k;-Vb&a(o?%_+`)9T zoqu8IzrFP>@z={6YWsGaPodQ8ecy=%2N~a$< z)z{S{cS-tPU+44?@8(+A&2(J*^FqaM=5*T5R{$saZ$Hntmgjy+@6HEL0z*<49|3Sg$e47($d0rFTwXZJvIMZ?MhdqKL zvfW%t=a^4$`lSwE-6FU89W3JbG(!a+G{^wAX)INW48w2=iuJZ(c z|NZ=3`}ZcnebJlRFK2vG+Ghu+SNXqP@JD65Xgh!SEH2M{M{b`1oXT_5(@bZSZ;6`( zKUwI5jm`Cj&~f$Yze;*nUmtfi(|_Z${Jf5rGH|VnkT$oQ8{moMOvkmaP8WQh=;e7r z><+oUm2Zj1Fkq=2-1*v3y^OoyVYv^*S0j(f_TK zQ`47C`ZR$!QZ)?@c~JHY9G^g{Y#Gt{?jWsq2@dPBIXAa z%3M&#<~l0HbdG(1zbpNvz@z%BU(&xLf>!A~Cb(;l{Zw$*&z3qTn*QGar*^wyCznUd z@JGSlmU?OX44=#CU3|CT@5s1@IxyGkg0B+(JX-L9Rop%so@XE}_$|PxJgX#Mh(U9m z(a-ps_waXfMif5&6u6d|f8l?RTpf)s0#5YrmvSoKepB!(Z{+8t+Y)ouaQctSc*j?B zT_^Z2Mb2n>)}TX8d+z0QQ0wOUtl+yGx%3S1sPg|eNx%0=eqQ_iU`*(U{%0O$T%R2i zeDpfTRStYZ@STq`uKan*I;L~uR~grOT`jolw^_KJ)1P=Pr`LYG0XXTG36aD2YOdV| zmoK5)4}{Kl?_*Hg{}c#Ps@FUjcUrGI1;75=wdoH(kL`BX4|X(gqO<>$G>oPOIa zj6=Pe>uJH?7P+eJyyO6~S3jIsF6$tRB>j(&UfW6_bNkTwOn?4OjD8%?({+rwf^gE<~wI6R6{LHU&I;H=R;1^5#Yx{g3IL$}qzQXAb;#=aM zCH>Vq7&uw*k3x|Vzdh>6fx85E=N)edzT#OXpyTeZKFxHth`v_*YQeuI@o}y3qMrv&<#grSD}wjl&lE6yFxR0OPVf5J?hyQX;s1*y{X>Ggk_?uGByrln~;6sly&>{HcS*Gvm z@!tymx{Oop$AKKD|HIWxK=B_4ewfH5<%c7DPXEdioc=V)w@+}_Z~R^0QT_P3q`&b} zCUBC_`FFujdyWAu&%#m8*Y(463hu6dT?(A!)eDXszC-XG4*rPH`PCJiuh#eQP0XKl z`U^Pmq3bWbTX1*%?$|L-|NR%4zP8&Zfk(B^grtA=E>5rG`u_;-j>k1%3@Xpl(r!od zV~M8(fBPE@3<-YxXE^;A9%Vq+k9Gl%D$frk{co=2^je}`(nYL6a1{}8PI|a z$oN7@zj~bMxcpWT+#MIc6a2?AUbLNui%cgk{H$&GDZ$-!nYVx&J$o`2WQCOHkP_4R znaFc3e@SrHZ~T_vr;A?e7CJXfFr5Ku2em8izL@brDgR}X{wIRFdbYdF>0LRw3OJRY z&X}OvE@Lvo4 zvjzXVt(@MqLk`}?xEnu^Q~W+AaK6ylE%@@i45%LYmEf;^m2s{6`t3~r#)lc#ar(00 zBX=|2&$mR!C7j-sKVKExU9Wsr@EuP3bYMIfeJ%NZOz7V(_^#U+I8*SS2=4mf`@pC~ z$BjeS4V?IJmm@d6C+XdIhB=>QI`3Y^86F||b_;%%*h?yBz9aZ+B8NXI=|6_?M&)@| z+Idj$$AMFM)}6?}M+N_pq`&4)1~mO=pl>Ms?&oXMUk9A%pZYDv|5E5Y1AKve4&TVH zLFwQ43ZvTZxgF8`e;IH}zh3%9>3`(!7~cVUbREsN#5KT`rap5$e^h=~-%SFi_8feP(;p!8uaWfb zdf)AWzbE?Z1WA7Y4wDb1b5?YK79kHpMO8oIgM|LYk*Vx zto{xIX~F-iq<8uANa%ISckeBnP{%LDlST3EOOpPB=pVXP@-6WjlOF49G9ESGGj3w~ zu0P~v!582;xiyrT*ffJooyO}^B zR|VfK?Rl}#|DNENLcY>bf~og5wQ$R=`r+253}RQDGUak+yXP0HQ72nI2ij``4GFwfo z9Ltn5S(Mi#JQu`6Pb|(93Z-lYMF!zbOlE0*Q?XR`@ue&2d6jCWn$McN^O-{a5_~Ha zy-YFZ<$TV8zAwt>6W+N4>w8xW;E~A@uix`FuIr-QdQt^{9966IF3E1&mQ1D+0+?b{ zLBy7)$MfmFir>G)v~xPspI+ppQhlAN zEu5^!8yfMdW#8||Gu@tNs+a7!fd7%IUUvCf!1vwfyPo z(k+GsLcPD3@?M$jUp^+= zNBzyR7?>)eLS3e59hU13u^fs^EC(osF|pPw=QoX2$4iwev)?k$+fY4UV<$M(&E!0QL*0B3X7Bnm~I7ZO6r}@xf>xaD|Jepiu_Qy+Ge6Q?}LQNL4=yo()S9SY@ZwkVaw0o0Z zT^TSD8nm7fXq9?ZoOT!y+3ZN~d?X4;{;F~30+K8lNvQXLz zi*KYfSqGi5gE=gGLYWxS9tum)$)O-6ODCi^~1UB>^9d`5BnB zM!K7!o6A%)sNw8XP+76v6^v@gI1Di}j-+OWKC1XB8b?-FvHlbN(O74)a7^`x7WGr( zgKI=useB$)+c(^C5XFHqR?8EbT(U?d7v=mQ8?t5wF~rAtOed4x zFqvpx9>_U!SdA@eqH60hFaiUy8;wW22;SpLHBt+fr(%zL zD{Q75`6{dJBi#jmi(fc@g2z(h?u=jol`GnbQB@QZXjw3UBNe)uH2jpN=8#cx>2qOf zLf55IWH|LrtcL|{gnyyhcs4RJw5IWR!Q^O>H*73)5_~?12tsoCu1Cd|T1}on7E`SU{Mf z8Vx*I%wIg|dlRJ!SYJnrEuNCMSKSn9Ll!U;+PmA8E%AOy3ZRJNx}sndfN(xRFaL}!O_X7MxR zD=Wv<$XOH8q)R=x65xgObKbZ=J~BCK=l7Ny>RAZRCR|G~Zh}EWy&E-|*I_ubYWNq^ z)SD**S}-s_uvr&gO1{-OrV;VkvY)B??0;#^gfJdE_O?-5MzReIStF#)5JBsD)vkO1fGu z6*sNe1P?P@BZJ&^b)su+AiCN-Y^}mzmD4LK$9OK_YRm9U&V$oFJGOi|T(>KF`@Lib z)))4HP$9!%`dmc@15|py8m3Vl4Pm5Qg+V!mV?_Ip+_5^RZNa_B4qP~<*@4^KF};jE zwo^H#sZuqL>DiKFG$G35a;*I!#uj0b3F}Ver|AzYS~L}SSiGP*(S!YzT$0O=iVw~+ z?l;U0=>KZx(lUHLrExEl&0<+0aG`qD46Xlwpk?ql($T8vI2IQvX5(aTWP5TE(HOOp z$yhT~Gw+1pA-4}n2cm5UJ_LE3`iC6z4!z_|>8YbXdTtL+u(G3dmpd!X+L_e~o>@V8 zT3*m0XZv>+%rJF&(ik?f4XdHF$moj-@j5#?JC<;tPj|Tok^zc%-z;%KQ?@Wa=Or)9 zTg{4>ECr$4Fk7Yh;Fw>){K0r!VzDzO{X>|jV~wrWg|h+jU^Qlz$ex55x28zTI2>+= zNN9R6J4+c&mS4nJ4YOpN!dv#8{;DgyrfYfCyR^NrRV{wLa6#KKc3hXVnUb#yDWBF? zTBg5f*^K@{+ydMUUg)McBl&d#FYVswZanYEJDIL9qh znV}GH)Kp2yInJK$eKu&r!zHxH-V3dui|qTSEGj}^anw)iNl_YZgWeoQbJnm;vVRLp72zJ`Y%Ra-xE@#vYctz09hIe_witsp z0HcR^gBCmo**tZPlYww}?A? zg$Y{T=*+3Z&sthPfF0Dp-y_Q$$gBs8ABgrdfrW7PWlIy=gSjm&Nv3Gw$;12%Y8Nwv zT&3iVVfI?^#g^C?%TJ-6g0W*q#tI%8D`jM$HeHy*paz~RcNvtzyICrVYr1!oIaFP=$4P#|9uH=Al?mdYf;1}U6EMVMt| zn~#_U6uA?j63hyT%d8NwXgrRUlmH+=9Jm$^ZRi8ZWOu$;^*5CfuWJ@sGsSBEh!Met zv+R+BhTC>JDTl38PHfYfv(bjfFJz@)jS@h_;umfSX9q=7)+vdS>SSgX~w7T8fvPi6> z`arIlM(Ye3ZGT$WW}VuJE2mXk=o-5XLPcM*F~Lz2tf*MS1b!KrDz(?n=*H4T!5^h1 z#KsW?p-_W-5esRwF{VNK8X+b<>N>Py`H6YiBiUftV;Mz=WBZSd)o5?Cbta*TAve5r za3ZPgP!ikF%9gIp`9eWuiY-x`fjlF_!D@=yh#c4a&f-W=GND&T5WrEk(r^_YJ{3K%VeIZxkedV&bF`iL=6Nz8b_jqIM&uI zc679Di`tEcs)WgZVWO06)3=vHF@Zw3Dpaf8c{W=%m$9U1)ulU=+fox+F%GwGo+ zk|GYYNh~2IyAW(9LZZg<4mL$kxtiRmtI6RtlGaz@we6!+kZcO+8P9C}891`xJ2CO+^9 z&*C_&osP|>h*!R9)u3uNArh~jVdXVpYJh9dEjJ!Y<)!Nxkf z!@|se8m<@jWHS?)Y{(52Nbj};+lNC0T8M;-W8-P_nUGf)647z(9DD?0k`_GrNfJ!g ze~L&*Je929$qfm@&f)d!q(Ua*+-F@-zh1YoxOKcnmhyC_jRE=Nu-Z5iH9*3G5uu*7 z%j|*Ct&JPSn@-R$#AfTEezm7Q(C9&f*pTgxWn5UxoN+oVs0H+wR;1Oz-eSD1wq|@Q zV>Jqw;ur@jrDtp=;w+9xy4Kkc;XO6e30OgJt+isg5AIvj65uW zOxGP-DpXQ~=M1GwX)hHa<^s}f(KyZyHe1~qzYWyH?AYZ!;Ye+B2uhO{R>qGb%#>ZQ zZoe3v%$=7-D5(l|+pKZOTP~cwteg?oK{4B~m&H2Kqq9;nt;C766uc4m8Q@|tt_CA1 z=(MT2MNyU^tvbKdsYF&s?kG-zvf3OX{Us?E!gePO=hog#F5R*i5I93q9b=qFpy?3-qntl zmTfz7wl@uB<~e2)-(Wk%fDHt(Jg4n!mHW(1%sLZS_Tj1+3Y)lbc*B-8&NfLCG|_x> zzx0wl^vAN-bX@|*DcfixU3w6(HA6s}y)lPNzqU$&WXGWa{fGI&! zy|H_2Q)kKv4XNxmVj*I&6J093`}d7Q`m*syQ8ZX z?y+DLqlb799Bon;LNn6>$B;~Rl2beD)YyyAaUHTe(ZpATSxr#SF@n^P;JUIK1IT%R`(%Aif|5hZ zYgWaWT9UEo$7x>GuV`Cg-;lJo;XqcyBVm&%6MW%z%G8KM#N?_usWqv+7$}#vtcf-9 z*>K%WL|NH4ht-7_;aRHHorpbkXGu*}Flb}z_vZd^O&w+W@Df1a4>WI4=}r~>@w{(e zq5`F3epqHa;Ju~NW-?_%{Tqj2n)N@ph3dfCdPc}vxyjnmu=0dO+!!&v`5J0p?%%5Q}4oyI2NLQ)@ujBzOI1jkQTyBFdnd#jt+yv zVb!Hk-5NfKcsztV&UQE0(b?)^RI}YOXw&`Iz|D`>i5PY><$&q8U27|jZ78Zr{8l?z zXOoZ_&7;fWv|$j525y=80q>s3 z*=)n`@B(48U#Yp(ZHrW|^Ce8zOo`w)2K{CSyy531^okL@`gr#9W|Wl7DeCap+`!(iISan5dS zR1RBDSwDk~7uA!d&ZsDUwI@-TP(g7%!Zaj_1t_&7TktdG`Y5?}b%-!DXfcPa%J7Vp$P;Iav4w6vT|OOFpxD2o!659jPhM5sW?^E>{FpPgx6a-v{tWT zxP6K}-2AoM@?}TiOezSW-h891_%#AAJ)I~?W)&+KU0@B>epZ+19qX81h7=<(!CVm*JD8k^d>6K+0uT=9)MO9yo4qHJk=B2&$eB!1H7nhB2v9^yv$N;B>M`rrjxc{tvP697#VTcvIX~tc4L&C z#S=}KSq*09Ox`eOGcx9VlWJywdyJ?JP4`STZY%QobXXrac7;rEYmebVBkhw|Nv$sI z;hF)zqU8Zk6IJ^XPQ2B{yt^VCRUR?9inq>7ChB@~UY)mT9PT}4OOd!uEoZG}W9G1j z{4@~V^qMxmoT=b!g{pab3q>!3ap?RV3KXVEVS_1QSQJTb>zk3Lu=uAgxAj}?Kf&Ql z=YoRNMu4HJjpj&kM1nRA_!d2b_ihKTXNHC_0a6VHd&q@{tiLEcS zb*9voI`<4$JM{3ZMVf{DX5rzWZw6qsEMmS9o7i&Ik5Lx!jaZ?{5seMce2m&y(EOO* z-qv33yT*OFZ@BH_3oD3*!_&Nb!4#A&3|6Tc@ z_Y=d3@%bR<`%-)lKmVpYulEH`diVK0{Qj?h`cp~sKlH!w1A0GIo+sjL~y5`F#!N{CDES82u!8yfP_-2N8-{wY-cz7O)R zdLNL)N=Eb1`)2(9Ug-H-<$1mDk>{ycR8B3wz==!nf!b8*E&ntAMel>s;hMibul2uL zp6}(y61UFb4|;z<2-EW)!k_#6PGFRUG+QFE0AJ`@VE#4F@F)J)?f)A9ho4`tfYa&y z75XuB&6Ur3zXRXH&;R~-PM~)!uaeO3dcV(kKCw_z%Kf|t^+~>KzKVVsAHw+$zr?@j z{V+`^cenmumFK0I6Ny(Oq1=0e9~jqiORB^Z&hve*@-KQn^ZlBV?{5Czah~7tKRBJ< zFFLLEc{l$bI?w;|ebgF>gx)tg4dCYgPe@BFN4!nf1E=%z4;;gH+4$3XYrTj)wCv_V`RDpU&f(O%!YG$Dj2wY4QP1yrgP)(P L1(k=KuZjN;gq+z{ literal 0 HcmV?d00001 diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..45b5de0 --- /dev/null +++ b/test.cpp @@ -0,0 +1,12 @@ +#include + +#include "lib/Game.hpp" +#include "lib/Character.hpp" + +int main(int argc, char const *argv[]) +{ + Game::init(); + Character player = Character("Myitinos", &Game::Elements["Fire"]); + std::cout << Game::SpellBook[player.getAffinity()].at(0).getName() << std::endl; + return 0; +}