[
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.md",
    "content": "---\nname: Bug Report\nabout: Found a bug that you wish to tell us about? Start here. [MCA 6.0.0+ ONLY]\ntitle: ''\nlabels: needs review\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**Steps to Reproduce**\nPlease include steps we can take to reproduce the bug:\n1. Launch Minecraft\n2. Create a World\n3. etc...\n\n**Minecraft Information (please complete all questions entirely):**\n - Minecraft Version: [e.g. 1.12.2]\n - Forge Version: [e.g. 14.23.5.2838]\n - MCA Version: [e.g. 6.0.0] **Any version below 6.0.0 is NOT supported. Do not submit an issue for these versions.**\n - Launcher: [e.g. Standard, Twitch, MultiMC]\n\n**Modpack Information**\nComplete this section if you are using a modpack.\n - Modpack Name: [e.g. FTB Infinity]\n - Modpack Version: [e.g 3.1.0]\n\n**Mods List**\nComplete this section if you are NOT using a modpack but have other mods installed alongside MCA.\n - Please list the other mods you have installed\n\n**Additional context**\nAdd any other context about the problem here that you feel is useful. Screenshots, world files, logs, etc.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-change-request.md",
    "content": "---\nname: Feature Change Request\nabout: Suggest your idea for MCA relating to a current problem in the mod.\ntitle: \"[REQUEST] \"\nlabels: ''\nassignees: ''\n\n---\n\n**Please describe the problem you are experiencing and requesting a change for**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like to see**\nA clear and concise description of what you ideally want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you have considered, if applicable. For example, if you're able to do what you want with a simple in-game workaround, include how to do that here.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".gitignore",
    "content": "# eclipse\nbin\n*.launch\n.settings\n.metadata\n.classpath\n.project\n\n# idea\nout\n*.ipr\n*.iws\n*.iml\n.idea\n\n# gradle\nbuild\n.gradle\n\n# other\neclipse\nrun\nclasses\n"
  },
  {
    "path": "CHANGELOG",
    "content": "6.0.1\nFeature: Whistle to call your family has been added back into the game.\nFeature: Special skins for naming your children certain names (secret!)\nFeature: Improved the villager editor with the ability to specify desired careers and textures.\nFeature: Villager health is now configurable.\n\nFixed: Guards not properly defending villagers when injured.\nFixed: Potential crash client-side when exiting the game.\nFixed: Career names and IDs were not matching in the Trade GUI.\nFixed: Inability to interact with villagers when using some other mods.\n\n6.0.0\nFeature: In-game notifications for updates.\nFeature: Modified female bodies have been added back.\nFeature: Player children now take a profession on growing to an adult.\nFeature: Rose Gold generation can now be disabled.\n\nChanged: \"Romantic\" interaction constraint changed to \"Adults\".\n\nFixed: You are now notified of your child's death.\nFixed: Interaction fatigue was not applying properly.\nFixed: Crashes resulting from using the Villager Spawner block.\nFixed: Inability to interact with some villagers.\nFixed: Guards now behave more like normal villagers.\nFixed: Villagers from eggs will no longer spawn with the Nitwit or Child profession.\nFixed: Negative gifts will no longer be taken from the player.\nFixed: Engagement ring now works properly.\nFixed: Automatic crash reporting wasn't working properly.\nFixed: Inability to procreate with Guards.\nFixed: Crash when a villager dies of fall damage.\nFixed: Villagers wandering away from their homes.\nFixed: The villager editor will no longer produce Pillagers.\nFixed: The force child growth command now works properly.\nFixed: Romantic actions appearing on non-adults.\nFixed: Crashes with other mods referencing onPlaySoundAtEntityEvent.\nFixed: Overspawn of guards in villagers. Now limited to 10 guards at a time.\nFixed: Missing message for riding horses on spouses.\n\n6.0.0-beta\nThis version of MCA has been fully rewritten from the ground up to be more user, server, and mod friendly with a streamlined and robust codebase. Compatibility with previous saves should not be expected.\n\nMajor: RadixCore is no longer a required dependency.\n\nFeature: Villagers performing a chore or movement action show their status below their name.\nFeature: Player marriage has been shifted to the /mca command.\nFeature: Added /mca-admin commands for operators and server administrators.\nFeature: GUI and API elements have been externalized and may be customized as you please with a constraints system.\nFeature: More configuration options for server administrators.\nFeature: Children now grow in stages - baby, toddler, child, teen, adult.\nFeature: Added Guard careers: Hero, Archer, Warrior.\nFeature: All skins are now 64x64 and additional skins of this size are now supported.\n\nChanged: Chores are now smarter, require no configuration before running, and should play more nicely with modded items.\nChanged: Mining is now called Prospecting.\nChanged: Villager personalities and moods no longer affect interactions.\nChanged: The crystal ball and setup menu is no longer required.\nChanged: Reaper battle has been tweaked for fairness.\nChanged: Reviving villagers no longer requires a memorial item.\nChanged: Engagement ring now allows marriage with only 50% of the required hearts.\n\nFixed: Random crashing on servers due to java.lang.ClassCastException when approaching villages.\nFixed: Villagers all have their proper vanilla trades based on their profession.\nFixed: Married to \"?\" will no longer occur on LAN.\nFixed: Health display issues have been fixed.\nFixed: Lost/forgotten player histories on servers.\nFixed: Villagers should trend towards their home points and not wander too far away.\nFixed: Crashes related to null item stacks."
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "README.md",
    "content": "Minecraft Comes Alive\n=====================\nMinecraft Comes Alive (MCA) is a Minecraft mod that replaces Minecraft's villagers with normal player-like NPCs. It works in single player, LAN, and SMP.\n\nVillagers can be interacted with - you can talk to them, ask them to follow you, set their home, give them gifts, etc. Interacting with people builds relationships. Get your relationship high enough and you will be able to marry someone.\n\nAfter getting married, you will be able to have children who will do many chores for you such as: Farming, Fishing, Woodcutting, Hunting, and Mining.\n\nChildren will eventually grow up into adults. Adults can get married and have children of their own, and this cycle can repeat indefinitely!\n\n## Dependencies\nAt runtime, MCA has no external dependencies other than Minecraft Forge.\n\nFor development, MCA depends on Lombok. It will be installed automatically when you set up your development environment. Install the Lombok plugin for your relevant IDE if you have trouble building in your IDE.\n\n## Contributing\nAny contributions to are welcome. Simply clone into your workspace, set it up, make your changes, and submit a pull request for review.\n\n## Credits\nThese individuals made substantial contributions to MCA - without them, continued progress may have been impossible.\n - SheWolfDeadly\n - ntzrmtthihu777\n - ko2fan\n - Akjosch\n - Innectic\n"
  },
  {
    "path": "build.gradle",
    "content": "buildscript {\n    repositories {\n        mavenCentral()\n        jcenter()\n        maven { url = \"http://files.minecraftforge.net/maven\" }\n    }\n    dependencies {\n        classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'\n    }\n}\napply plugin: 'net.minecraftforge.gradle.forge'\n//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.\n\nversion = \"6.0.1\"\ngroup = \"com.minecraftcomesalive\" // http://maven.apache.org/guides/mini/guide-naming-conventions.html\narchivesBaseName = \"MCA-1.12.2\"\n\nsourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.\ncompileJava {\n    sourceCompatibility = targetCompatibility = '1.8'\n}\n\nminecraft {\n    version = \"1.12.2-14.23.5.2768\"\n    runDir = \"run\"\n    \n    // the mappings can be changed at any time, and must be in the following format.\n    // snapshot_YYYYMMDD   snapshot are built nightly.\n    // stable_#            stables are built at the discretion of the MCP team.\n    // Use non-default mappings at your own risk. they may not always work.\n    // simply re-run your setup task after changing the mappings to update your workspace.\n    mappings = \"snapshot_20171003\"\n    // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.\n}\n\ndependencies {\n    provided 'org.projectlombok:lombok:1.16.4'\n    // you may put jars on which you depend on in ./libs\n    // or you may define them like so..\n    //compile \"some.group:artifact:version:classifier\"\n    //compile \"some.group:artifact:version\"\n      \n    // real examples\n    //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev'  // adds buildcraft to the dev env\n    //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env\n\n    // the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.\n    //provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'\n\n    // the deobf configurations:  'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided,\n    // except that these dependencies get remapped to your current MCP mappings\n    //deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev'\n    //deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'\n\n    // for more info...\n    // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html\n    // http://www.gradle.org/docs/current/userguide/dependency_management.html\n\n}\n\nprocessResources {\n    // this will ensure that this task is redone when the versions change.\n    inputs.property \"version\", project.version\n    inputs.property \"mcversion\", project.minecraft.version\n\n    // replace stuff in mcmod.info, nothing else\n    from(sourceSets.main.resources.srcDirs) {\n        include 'mcmod.info'\n                \n        // replace version and mcversion\n        expand 'version':project.version, 'mcversion':project.minecraft.version\n    }\n        \n    // copy everything else except the mcmod.info\n    from(sourceSets.main.resources.srcDirs) {\n        exclude 'mcmod.info'\n    }\n}\n\njar {\n    classifier = 'universal'\n}"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Tue Jun 18 00:42:38 PDT 2019\r\ndistributionBase=GRADLE_USER_HOME\r\ndistributionPath=wrapper/dists\r\nzipStoreBase=GRADLE_USER_HOME\r\nzipStorePath=wrapper/dists\r\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-2.14-all.zip\r\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Sets default memory used for gradle commands. Can be overridden by user or command line properties.\n# This is required to provide enough memory for the Minecraft decompilation process.\norg.gradle.jvmargs=-Xmx3G\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# For Cygwin, ensure paths are in UNIX format before anything is touched.\nif $cygwin ; then\n    [ -n \"$JAVA_HOME\" ] && JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\nfi\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >&-\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >&-\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\r\nset CMD_LINE_ARGS=%$\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "src/main/java/mca/api/API.java",
    "content": "package mca.api;\n\nimport com.google.common.base.Charsets;\nimport mca.api.types.APIButton;\nimport mca.api.types.Gift;\nimport mca.api.types.SkinsGroup;\nimport mca.client.gui.component.GuiButtonEx;\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumConstraint;\nimport mca.enums.EnumGender;\nimport mca.util.Util;\nimport net.minecraft.client.gui.GuiButton;\nimport net.minecraft.client.gui.GuiScreen;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.StringUtils;\nimport net.minecraftforge.fml.common.ObfuscationReflectionHelper;\nimport net.minecraftforge.fml.common.registry.VillagerRegistry;\nimport org.apache.commons.io.IOUtils;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\nimport java.io.InputStream;\nimport java.util.*;\n\n/**\n * Class API handles interaction with MCA's configurable options via JSON in the resources folder\n */\npublic class API {\n    private static Map<String, Gift> giftMap = new HashMap<>();\n    private static Map<String, APIButton[]> buttonMap = new HashMap<>();\n    private static List<String> maleNames = new ArrayList<>();\n    private static List<String> femaleNames = new ArrayList<>();\n    private static List<SkinsGroup> skinGroups = new ArrayList<>();\n    private static Random rng;\n\n    /**\n     * Performs initialization of the API\n     */\n    public static void init() {\n        rng = new Random();\n\n        // Load skins\n        SkinsGroup[] skins = Util.readResourceAsJSON(\"api/skins.json\", SkinsGroup[].class);\n        Collections.addAll(skinGroups, skins);\n\n        // Load names\n        InputStream namesStream = StringUtils.class.getResourceAsStream(\"/assets/mca/lang/names.lang\");\n        try {\n            // read in all names and process into the correct list\n            List<String> lines = IOUtils.readLines(namesStream, Charsets.UTF_8);\n            lines.stream().filter((l) -> l.contains(\"name.male\")).forEach((l) -> maleNames.add(l.split(\"\\\\=\")[1]));\n            lines.stream().filter((l) -> l.contains(\"name.female\")).forEach((l) -> femaleNames.add(l.split(\"\\\\=\")[1]));\n        } catch (Exception e) {\n            MCA.getLog().fatal(e);\n            throw new RuntimeException(\"Failed to load all NPC names from file\", e);\n        }\n\n        // Read in buttons\n        buttonMap.put(\"main\", Util.readResourceAsJSON(\"api/gui/main.json\", APIButton[].class));\n        buttonMap.put(\"interact\", Util.readResourceAsJSON(\"api/gui/interact.json\", APIButton[].class));\n        buttonMap.put(\"debug\", Util.readResourceAsJSON(\"api/gui/debug.json\", APIButton[].class));\n        buttonMap.put(\"editor\", Util.readResourceAsJSON(\"api/gui/editor.json\", APIButton[].class));\n        buttonMap.put(\"work\", Util.readResourceAsJSON(\"api/gui/work.json\", APIButton[].class));\n        buttonMap.put(\"location\", Util.readResourceAsJSON(\"api/gui/location.json\", APIButton[].class));\n\n        // Load gifts and assign to the appropriate map with a key value pair and print warnings on potential issues\n        Gift[] gifts = Util.readResourceAsJSON(\"api/gifts.json\", Gift[].class);\n        for (Gift gift : gifts) {\n            if (!gift.exists()) {\n                MCA.getLog().warn(\"Could not find gift item or block in registry: \" + gift.getName());\n            } else {\n                giftMap.put(gift.getName(), gift);\n            }\n        }\n    }\n\n    /**\n     * Returns a random skin based on the profession and gender provided.\n     *\n     * @param villager The villager who will be assigned the random skin.\n     * @return String location of the random skin\n     */\n    public static String getRandomSkin(EntityVillagerMCA villager) {\n        VillagerRegistry.VillagerProfession profession = villager.getProfessionForge();\n        EnumGender gender = EnumGender.byId(villager.get(EntityVillagerMCA.GENDER));\n        String name = villager.get(EntityVillagerMCA.VILLAGER_NAME);\n\n        //Special-case skins\n        if (gender == EnumGender.MALE) {\n            switch (name.toLowerCase()) {\n                case \"pewdiepie\": return \"mca:skins/male/special/pewdiepie_boy.png\";\n                case \"sven\": return \"mca:skins/male/special/sven.png\";\n                case \"noob\":\n                case \"noober\":\n                case \"neeber\": return \"mca:skins/male/special/noob.png\";\n                case \"shepard\": return \"mca:skins/male/special/shepard.png\";\n                case \"minsc\": return \"mca:skins/male/special/minsc.png\";\n            }\n        } else if (gender == EnumGender.FEMALE) {\n            switch (name.toLowerCase()) {\n                case \"pewdiepie\": return \"mca:skins/female/special/pewdiepie_girl.png\";\n            }\n        }\n\n        //Default skin behavior\n        Optional<SkinsGroup> group = skinGroups.stream()\n                        .filter(g -> g.getGender() == gender && profession.getRegistryName() != null && g.getProfession().equals(profession.getRegistryName().toString()))\n                        .findFirst();\n\n        return group.map(g -> g.getPaths()[rng.nextInt(g.getPaths().length - 1)]).orElseGet(() -> {\n            MCA.getLog().warn(\"No skin found for profession: `\" + profession.getRegistryName() + \"`. A random skin will be generated.\");\n            SkinsGroup randomGroup = null;\n            while (randomGroup == null || randomGroup.getGender() != gender) {\n                randomGroup = skinGroups.get(rng.nextInt(skinGroups.size() - 1));\n            }\n            return randomGroup.getPaths()[rng.nextInt(randomGroup.getPaths().length)];\n        });\n    }\n\n    /**\n     * Returns an API button based on its ID\n     *\n     * @param id String id matching the targeted button\n     * @return Instance of APIButton matching the ID provided\n     */\n    public static Optional<APIButton> getButtonById(String key, String id) {\n        return Arrays.stream(buttonMap.get(key)).filter(b -> b.getIdentifier().equals(id)).findFirst();\n    }\n\n    /**\n     * Returns the value of a gift from an ItemStack\n     *\n     * @param stack ItemStack containing the gift item\n     * @return int value determining the gift value of a stack\n     */\n    public static int getGiftValueFromStack(ItemStack stack) {\n        if (stack.getItem().getRegistryName() == null) return 0;\n\n        String name = stack.getItem().getRegistryName().toString();\n        return giftMap.containsKey(name) ? giftMap.get(name).getValue() : -5;\n    }\n\n    /**\n     * Returns the proper response type based on a gift provided\n     *\n     * @param stack ItemStack containing the gift item\n     * @return String value of the appropriate response type\n     */\n    public static String getResponseForGift(ItemStack stack) {\n        int value = getGiftValueFromStack(stack);\n        return \"gift.\" + (value <= 0 ? \"fail\" : value <= 5 ? \"good\" : value <= 10 ? \"better\" : \"best\");\n    }\n\n    /**\n     * Gets a random name based on the gender provided.\n     *\n     * @param gender The gender the name should be appropriate for.\n     * @return A gender appropriate name based on the provided gender.\n     */\n    public static String getRandomName(@Nonnull EnumGender gender) {\n        if (gender == EnumGender.MALE) return maleNames.get(rng.nextInt(maleNames.size()));\n        else if (gender == EnumGender.FEMALE) return femaleNames.get(rng.nextInt(femaleNames.size()));\n        return \"\";\n    }\n\n    /**\n     * Adds API buttons to the GUI screen provided.\n     *\n     * @param guiKey   String key for the GUI's buttons\n     * @param villager Optional EntityVillagerMCA the GuiScreen has been opened on\n     * @param player   EntityPlayer who has opened the GUI\n     * @param screen   GuiScreen instance the buttons should be added to\n     */\n    public static void addButtons(String guiKey, @Nullable EntityVillagerMCA villager, EntityPlayer player, GuiScreen screen) {\n        List<GuiButton> buttonList = ObfuscationReflectionHelper.getPrivateValue(GuiScreen.class, screen, Constants.GUI_SCREEN_BUTTON_LIST_FIELD_INDEX);\n        for (APIButton b : buttonMap.get(guiKey)) {\n            GuiButtonEx guiButton = new GuiButtonEx(screen, b);\n            buttonList.add(guiButton);\n\n            // Ensure that if a constraint is attached to the button\n            if (villager == null && b.getConstraints().size() > 0) {\n                MCA.getLog().error(\"No villager provided for list of buttons with constraints! Button ID:\" + b.getIdentifier());\n                continue;\n            }\n\n            // Remove the button if we specify it should not be present on constraint failure\n            // Otherwise we just mark the button as disabled.\n            boolean isValid = b.isValidForConstraint(villager, player);\n            if (!isValid && b.getConstraints().contains(EnumConstraint.HIDE_ON_FAIL)) buttonList.remove(guiButton);\n            else if (!isValid) guiButton.enabled = false;\n        }\n    }\n\n    /**\n     * Returns an instance of the button linked to the given ID on the provided GuiScreen\n     *\n     * @param id     String id of the button desired\n     * @param screen GuiScreen containing the button\n     * @return GuiButtonEx matching the provided id\n     */\n    public static Optional<GuiButtonEx> getButton(String id, GuiScreen screen) {\n        List<GuiButton> buttonList = ObfuscationReflectionHelper.getPrivateValue(GuiScreen.class, screen, Constants.GUI_SCREEN_BUTTON_LIST_FIELD_INDEX);\n        Optional<GuiButton> button = buttonList.stream().filter(\n                (b) -> b instanceof GuiButtonEx && ((GuiButtonEx) b).getApiButton().getIdentifier().equals(id)).findFirst();\n\n        return button.map(guiButton -> (GuiButtonEx) guiButton);\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/api/types/APIButton.java",
    "content": "package mca.api.types;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumConstraint;\nimport net.minecraft.entity.player.EntityPlayer;\n\nimport java.util.List;\n\n/**\n * APIButton is a button defined in assets/mca/api/gui/*\n * <p>\n * These buttons are dynamically attached to a GuiScreen and include additional instruction/constraints for building\n * and processing interactions.\n */\n@AllArgsConstructor\npublic class APIButton {\n    @Getter private int id;             // numeric id\n    @Getter private String identifier;  // string identifier for the button in the .lang file\n    @Getter private int x;              // x position\n    @Getter private int y;              // y position\n    @Getter private int width;          // button width\n    @Getter private int height;         // button height\n    @Getter private boolean notifyServer;   // whether the button press is sent to the server for processing\n    @Getter private boolean targetServer;   // whether the button is processed by the villager or the server itself\n    private String constraints;     // list of EnumConstraints separated by a pipe character |\n    @Getter private boolean isInteraction;  // whether the button is an interaction that generates a response and boosts/decreases hearts\n\n    public List<EnumConstraint> getConstraints() {\n        return EnumConstraint.fromStringList(constraints);\n    }\n\n    /**\n     * Determines if the given villager and player match the constraints for this button, allowing the action to be performed\n     *\n     * @param villager Instance of the EntityVillagerMCA the button would perform the action on\n     * @param player   Instance of the EntityPlayer performing the action\n     * @return boolean whether the button is valid for a constraint\n     */\n    public boolean isValidForConstraint(EntityVillagerMCA villager, EntityPlayer player) {\n        List<EnumConstraint> constraints = getConstraints();\n\n        if (constraints.contains(EnumConstraint.ADULTS) && !villager.isChild()) {\n            return true;\n        } else if (constraints.contains(EnumConstraint.SPOUSE) && villager.isMarriedTo(player.getUniqueID())) {\n            return true;\n        } else if (constraints.contains(EnumConstraint.NOT_SPOUSE) && !villager.isMarriedTo(player.getUniqueID())) {\n            return true;\n        } else if (constraints.contains(EnumConstraint.FAMILY) && (villager.playerIsParent(player) || villager.isMarriedTo(player.getUniqueID()))){\n            return true;\n        } else if (constraints.contains(EnumConstraint.NOT_FAMILY) && !(villager.playerIsParent(player) || villager.isMarriedTo(player.getUniqueID()))) {\n            return true;\n        } else if (constraints.isEmpty()) {\n            return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/api/types/Gift.java",
    "content": "package mca.api.types;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\nimport mca.core.MCA;\nimport net.minecraft.block.Block;\nimport net.minecraft.item.Item;\n\n@AllArgsConstructor\n@Getter\npublic class Gift {\n    private String type;\n    private String name;\n    private int value;\n\n    /**\n     * Used for verifying if a given gift exists in the game's registries.\n     * @return True if the item/block exists.\n     */\n    public boolean exists() {\n        if (getType().equals(\"block\")) {\n            return Block.getBlockFromName(getName()) != null;\n        } else if (getType().equals(\"item\")) {\n            return Item.getByNameOrId(getName()) != null;\n        } else {\n            MCA.getLog().warn(\"Could not process gift '\" + getName() + \"'- bad type name of '\" + getType() + \"'. Must be 'item' or 'block'\");\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/api/types/SkinsGroup.java",
    "content": "package mca.api.types;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\nimport mca.enums.EnumGender;\n\n@AllArgsConstructor\npublic class SkinsGroup {\n    private String gender;\n    @Getter private String profession;\n    @Getter private String[] paths;\n\n    public EnumGender getGender() {\n        return EnumGender.byName(gender);\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/blocks/BlockVillagerSpawner.java",
    "content": "package mca.blocks;\n\nimport com.google.common.base.Optional;\nimport mca.core.MCA;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.block.Block;\nimport net.minecraft.block.material.Material;\nimport net.minecraft.block.state.IBlockState;\nimport net.minecraft.util.math.AxisAlignedBB;\nimport net.minecraft.util.math.BlockPos;\nimport net.minecraft.world.World;\n\nimport java.util.Random;\n\npublic class BlockVillagerSpawner extends Block {\n\n    public BlockVillagerSpawner() {\n        super(Material.IRON);\n        setTickRandomly(true);\n        setBlockUnbreakable();\n    }\n\n    @Override\n    public void updateTick(World world, BlockPos pos, IBlockState state, Random random) {\n        super.updateTick(world, pos, state, random);\n\n        int nearbyVillagers = world.getEntitiesWithinAABB(EntityVillagerMCA.class, new AxisAlignedBB(pos).expand(32D, 32D, 32D)).size();\n        if (nearbyVillagers < MCA.getConfig().villagerSpawnerCap) {\n            int yMod = 0;\n\n            // Start from the current point possible and count up until air is hit. This allows the spawner to\n            // be placed anywhere below ground and still spawn a villager on a top level.\n            while (pos.getY() + yMod < 256) {\n                BlockPos current = pos.add(0, yMod, 0);\n                BlockPos above = pos.add(0, yMod + 1, 0);\n\n                if (world.isAirBlock(current) && world.isAirBlock(above)) {\n                    EntityVillagerMCA villager = new EntityVillagerMCA(world, Optional.absent(), Optional.absent());\n                    villager.setPosition(current.getX(), current.getY(), current.getZ());\n                    world.spawnEntity(villager);\n                    break;\n                }\n\n                yMod++;\n            }\n        }\n\n        world.scheduleUpdate(pos, this, MCA.getConfig().villagerSpawnerRateMinutes * 72000);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/MCAGuiFactory.java",
    "content": "package mca.client;\n\nimport mca.client.gui.GuiConfigPage;\nimport net.minecraft.client.Minecraft;\nimport net.minecraft.client.gui.GuiScreen;\nimport net.minecraftforge.fml.client.IModGuiFactory;\n\nimport java.util.Set;\n\npublic class MCAGuiFactory implements IModGuiFactory\n{\n    @Override\n    public void initialize(Minecraft minecraftInstance) {}\n\n    @Override\n    public GuiScreen createConfigGui(GuiScreen screen) {\n        return new GuiConfigPage(screen);\n    }\n\n    @Override\n    public Set<RuntimeOptionCategoryElement> runtimeGuiCategories() {\n        return null;\n    }\n\n    @Override\n    public boolean hasConfigGui() {\n        return true;\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/gui/GuiConfigPage.java",
    "content": "package mca.client.gui;\n\nimport mca.core.MCA;\nimport net.minecraft.client.gui.GuiScreen;\nimport net.minecraftforge.fml.client.config.GuiConfig;\nimport net.minecraftforge.fml.client.config.IConfigElement;\n\nimport java.util.List;\n\npublic class GuiConfigPage extends GuiConfig {\n    public GuiConfigPage(GuiScreen parent) {\n        this(parent,\n                MCA.getConfig().getCategories(),\n                MCA.MODID, false, false, GuiConfig.getAbridgedConfigPath(MCA.getConfig().getInstance().toString()));\n    }\n\n    public GuiConfigPage(GuiScreen parentScreen, List<IConfigElement> configElements, String modID, boolean allRequireWorldRestart, boolean allRequireMcRestart, String title) {\n        super(parentScreen, configElements, modID, allRequireWorldRestart, allRequireMcRestart, title);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/gui/GuiInteract.java",
    "content": "package mca.client.gui;\n\nimport mca.api.API;\nimport mca.client.gui.component.GuiButtonEx;\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.core.forge.NetMCA;\nimport mca.entity.EntityVillagerMCA;\nimport mca.entity.data.ParentData;\nimport mca.entity.data.PlayerHistory;\nimport mca.enums.EnumMarriageState;\nimport mca.enums.EnumMoveState;\nimport net.minecraft.client.gui.GuiButton;\nimport net.minecraft.client.gui.GuiScreen;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.util.ResourceLocation;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\nimport org.lwjgl.input.Keyboard;\nimport org.lwjgl.input.Mouse;\nimport org.lwjgl.opengl.GL11;\n\nimport java.io.IOException;\nimport java.util.Optional;\n\n@SideOnly(Side.CLIENT)\npublic class GuiInteract extends GuiScreen {\n    private static final ResourceLocation ICON_TEXTURES = new ResourceLocation(\"mca:textures/gui.png\");\n    private static boolean displaySuccessChance;\n    private final EntityVillagerMCA villager;\n    private final EntityPlayer player;\n\n    private boolean inGiftMode;\n\n    private int timeSinceLastClick;\n\n    private int marriedIconU = 0;\n    private int engagedIconU = 64;\n    private int notMarriedIconU = 16;\n    private int parentsIconU = 32;\n    private int giftIconU = 48;\n    private int redHeartIconU = 80;\n    private int blackHeartIconU = 96;\n    private int goldHeartIconU = 112;\n\n    private int mouseX;\n    private int mouseY;\n\n    // Tracks which page we're on in the GUI for sending button events\n    private String activeKey;\n\n    public GuiInteract(EntityVillagerMCA villager, EntityPlayer player) {\n        super();\n        this.villager = villager;\n        this.player = player;\n        this.activeKey = \"main\";\n    }\n\n    @Override\n    public void initGui() {\n        drawMainButtonMenu();\n    }\n\n    @Override\n    public void onGuiClosed() {\n    }\n\n    @Override\n    public boolean doesGuiPauseGame() {\n        return false;\n    }\n\n    @Override\n    public void updateScreen() {\n        if (timeSinceLastClick < 100) {\n            timeSinceLastClick++;\n        }\n    }\n\n    @Override\n    public void drawScreen(int i, int j, float f) {\n        super.drawScreen(i, j, f);\n        drawIcons();\n        drawTextPopups();\n\n        mouseX = Mouse.getEventX() * width / mc.displayWidth;\n        mouseY = height - Mouse.getEventY() * height / mc.displayHeight - 1;\n    }\n\n    @Override\n    public void handleMouseInput() throws IOException {\n        super.handleMouseInput();\n\n        if (Mouse.getEventDWheel() < 0) {\n            player.inventory.currentItem = player.inventory.currentItem == 8 ? 0 : player.inventory.currentItem + 1;\n        } else if (Mouse.getEventDWheel() > 0) {\n            player.inventory.currentItem = player.inventory.currentItem == 0 ? 8 : player.inventory.currentItem - 1;\n        }\n    }\n\n    @Override\n    protected void mouseClicked(int posX, int posY, int button) throws IOException {\n        super.mouseClicked(posX, posY, button);\n\n        // Right mouse button\n        if (inGiftMode && button == 1) NetMCA.INSTANCE.sendToServer(new NetMCA.ButtonAction(activeKey, \"gui.button.gift\", villager.getUniqueID()));\n    }\n\n    @Override\n    protected void keyTyped(char keyChar, int keyCode) {\n        // Hotkey to leave gift mode\n        if (keyCode == Keyboard.KEY_ESCAPE) {\n            if (inGiftMode) {\n                inGiftMode = false;\n                enableAllButtons();\n            } else {\n                this.mc.displayGuiScreen(null);\n            }\n        } else if (keyCode == Keyboard.KEY_LCONTROL) {\n            displaySuccessChance = !displaySuccessChance;\n        } else {\n            try {\n                int intInput = Integer.parseInt(String.valueOf(keyChar));\n\n                if (intInput > 0) {\n                    player.inventory.currentItem = intInput - 1;\n                }\n            } catch (NumberFormatException ignored) {\n                // When a non numeric character is entered.\n            }\n        }\n    }\n\n    private void drawIcons() {\n        PlayerHistory history = villager.getPlayerHistoryFor(player.getUniqueID());\n        EnumMarriageState marriageState = EnumMarriageState.byId(villager.get(EntityVillagerMCA.MARRIAGE_STATE));\n        int marriageIconU =\n                marriageState == EnumMarriageState.MARRIED ? marriedIconU :\n                        marriageState == EnumMarriageState.ENGAGED ? engagedIconU :\n                                notMarriedIconU;\n        int heartIconU =\n                history.getHearts() < 0 ? blackHeartIconU :\n                        history.getHearts() >= 100 ? goldHeartIconU :\n                                redHeartIconU;\n\n        GL11.glPushMatrix();\n        {\n            GL11.glColor3f(255.0F, 255.0F, 255.0F);\n            GL11.glScalef(2.0F, 2.0F, 2.0F);\n\n            this.mc.getTextureManager().bindTexture(ICON_TEXTURES);\n            this.drawTexturedModalRect(5, 15, heartIconU, 0, 16, 16);\n            this.drawTexturedModalRect(5, 30, marriageIconU, 0, 16, 16);\n\n            if (canDrawParentsIcon()) this.drawTexturedModalRect(5, 45, parentsIconU, 0, 16, 16);\n\n            if (canDrawGiftIcon()) this.drawTexturedModalRect(5, 60, giftIconU, 0, 16, 16);\n        }\n        GL11.glPopMatrix();\n    }\n\n    private void drawTextPopups() {\n        EnumMarriageState marriageState = EnumMarriageState.byId(villager.get(EntityVillagerMCA.MARRIAGE_STATE));\n        String marriageInfo;\n\n        if (hoveringOverHeartsIcon()) {\n            int hearts = villager.getPlayerHistoryFor(player.getUniqueID()).getHearts();\n            this.drawHoveringText(hearts + \" hearts\", 35, 55);\n        }\n\n        if (hoveringOverMarriageIcon()) {\n            String spouseName = villager.get(EntityVillagerMCA.SPOUSE_NAME);\n            if (marriageState == EnumMarriageState.MARRIED) marriageInfo = MCA.getLocalizer().localize(\"gui.interact.label.married\", spouseName);\n            else if (marriageState == EnumMarriageState.ENGAGED) marriageInfo = MCA.getLocalizer().localize(\"gui.interact.label.engaged\", spouseName);\n            else marriageInfo = MCA.getLocalizer().localize(\"gui.interact.label.notmarried\");\n\n            this.drawHoveringText(marriageInfo, 35, 85);\n        }\n        if (canDrawParentsIcon() && hoveringOverParentsIcon()) {\n            ParentData data = ParentData.fromNBT(villager.get(EntityVillagerMCA.PARENTS));\n            this.drawHoveringText(MCA.getLocalizer().localize(\"gui.interact.label.parents\", data.getParent1Name(), data.getParent2Name()), 35, 115);\n        }\n\n        if (canDrawGiftIcon() && hoveringOverGiftIcon()) this.drawHoveringText(MCA.getLocalizer().localize(\"gui.interact.label.gift\"), 35, 145);\n    }\n\n    private boolean hoveringOverHeartsIcon() {\n        return mouseX <= 32 && mouseX >= 16 && mouseY >= 32 && mouseY <= 48;\n    }\n\n    private boolean hoveringOverMarriageIcon() {\n        return mouseX <= 32 && mouseX >= 16 && mouseY >= 66 && mouseY <= 81;\n    }\n\n    private boolean hoveringOverParentsIcon() {\n        return mouseX <= 32 && mouseX >= 16 && mouseY >= 100 && mouseY <= 115;\n    }\n\n    private boolean hoveringOverGiftIcon() {\n        return mouseX <= 32 && mouseX >= 16 && mouseY >= 124 && mouseY <= 148;\n    }\n\n    private boolean canDrawParentsIcon() {\n        ParentData data = ParentData.fromNBT(villager.get(EntityVillagerMCA.PARENTS));\n        return !data.getParent1UUID().equals(Constants.ZERO_UUID) &&\n                !data.getParent2UUID().equals(Constants.ZERO_UUID);\n    }\n\n    private boolean canDrawGiftIcon() {\n        return villager.getPlayerHistoryFor(player.getUniqueID()).isGiftPresent();\n    }\n\n    protected void actionPerformed(GuiButton button) {\n        GuiButtonEx btn = (GuiButtonEx) button;\n        String id = btn.getApiButton().getIdentifier();\n\n        if (timeSinceLastClick <= 2) {\n            return; /* Prevents click-throughs on Mojang's button system */\n        }\n        timeSinceLastClick = 0;\n\n        /* Progression to different GUIs */\n        if (id.equals(\"gui.button.interact\")) {\n            activeKey = \"interact\";\n            drawInteractButtonMenu();\n            return;\n        } else if (id.equals(\"gui.button.work\")) {\n            activeKey = \"work\";\n            drawWorkButtonMenu();\n            return;\n        } else if (id.equals(\"gui.button.backarrow\")) {\n            drawMainButtonMenu();\n            activeKey = \"main\";\n            return;\n        } else if (id.equals(\"gui.button.location\")) {\n            activeKey = \"location\";\n            drawLocationButtonMenu();\n            return;\n        }\n\n        /* Anything that should notify the server is handled here */\n        else if (btn.getApiButton().isNotifyServer()) {\n            NetMCA.INSTANCE.sendToServer(new NetMCA.ButtonAction(activeKey, id, villager.getUniqueID()));\n        } else if (id.equals(\"gui.button.gift\")) {\n            this.inGiftMode = true;\n            disableAllButtons();\n            return;\n        }\n\n        this.mc.displayGuiScreen(null);\n    }\n\n    private void drawMainButtonMenu() {\n        buttonList.clear();\n        API.addButtons(\"main\", villager, player, this);\n\n        EnumMoveState moveState = EnumMoveState.byId(villager.get(EntityVillagerMCA.MOVE_STATE));\n        if (moveState == EnumMoveState.FOLLOW) disableButton(\"gui.button.follow\");\n        else if (moveState == EnumMoveState.STAY) disableButton(\"gui.button.stay\");\n        else if (moveState == EnumMoveState.MOVE) disableButton(\"gui.button.move\");\n    }\n\n    private void drawInteractButtonMenu() {\n        buttonList.clear();\n        API.addButtons(\"interact\", villager, player, this);\n    }\n\n    private void drawWorkButtonMenu() {\n        buttonList.clear();\n        API.addButtons(\"work\", villager, player, this);\n    }\n\n    private void drawLocationButtonMenu() {\n        buttonList.clear();\n        API.addButtons(\"location\", villager, player, this);\n    }\n\n    private void disableButton(String id) {\n        Optional<GuiButtonEx> b = API.getButton(id, this);\n\n        b.ifPresent(guiButtonEx -> guiButtonEx.enabled = false);\n    }\n\n    private void enableAllButtons() {\n        buttonList.forEach((b) -> b.enabled = true);\n    }\n\n    private void disableAllButtons() {\n        buttonList.forEach((b) -> b.enabled = false);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/gui/GuiNameBaby.java",
    "content": "package mca.client.gui;\n\nimport mca.api.API;\nimport mca.core.MCA;\nimport mca.core.forge.NetMCA;\nimport mca.items.ItemBaby;\nimport net.minecraft.client.gui.GuiButton;\nimport net.minecraft.client.gui.GuiScreen;\nimport net.minecraft.client.gui.GuiTextField;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.ItemStack;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\nimport org.lwjgl.input.Keyboard;\n\nimport java.io.IOException;\n\n@SideOnly(Side.CLIENT)\npublic class GuiNameBaby extends GuiScreen {\n    private final EntityPlayer player;\n\n    private GuiTextField babyNameTextField;\n    private GuiButton doneButton;\n    private GuiButton randomButton;\n    private ItemBaby baby;\n\n    public GuiNameBaby(EntityPlayer player, ItemStack babyStack) {\n        super();\n        this.player = player;\n\n        if (babyStack.getItem() instanceof ItemBaby) this.baby = (ItemBaby) babyStack.getItem();\n    }\n\n    @Override\n    public void updateScreen() {\n        super.updateScreen();\n\n        if (babyNameTextField != null) {\n            babyNameTextField.updateCursorCounter();\n            doneButton.enabled = !babyNameTextField.getText().isEmpty();\n        }\n    }\n\n    @Override\n    public void initGui() {\n        Keyboard.enableRepeatEvents(true);\n\n        buttonList.clear();\n        buttonList.add(doneButton = new GuiButton(1, width / 2 - 40, height / 2 - 10, 80, 20, MCA.getLocalizer().localize(\"gui.button.done\")));\n        buttonList.add(randomButton = new GuiButton(2, width / 2 + 105, height / 2 - 60, 60, 20, MCA.getLocalizer().localize(\"gui.button.random\")));\n        babyNameTextField = new GuiTextField(3, fontRenderer, width / 2 - 100, height / 2 - 60, 200, 20);\n        babyNameTextField.setMaxStringLength(32);\n\n        if (this.baby == null) this.mc.displayGuiScreen(null);\n    }\n\n    @Override\n    public void onGuiClosed() {\n        Keyboard.enableRepeatEvents(false);\n    }\n\n    @Override\n    public boolean doesGuiPauseGame() {\n        return false;\n    }\n\n    @Override\n    protected void actionPerformed(GuiButton button) {\n        if (button == doneButton) {\n            NetMCA.INSTANCE.sendToServer(new NetMCA.BabyName(babyNameTextField.getText().trim()));\n            mc.displayGuiScreen(null);\n        } else if (button == randomButton) {\n            babyNameTextField.setText(API.getRandomName(baby.getGender()));\n        }\n    }\n\n    @Override\n    protected void keyTyped(char c, int i) {\n        babyNameTextField.textboxKeyTyped(c, i);\n    }\n\n    @Override\n    protected void mouseClicked(int clickX, int clickY, int clicked) throws IOException {\n        super.mouseClicked(clickX, clickY, clicked);\n        babyNameTextField.mouseClicked(clickX, clickY, clicked);\n    }\n\n    @Override\n    public void drawScreen(int sizeX, int sizeY, float offset) {\n        drawDefaultBackground();\n        drawString(fontRenderer, MCA.getLocalizer().localize(\"gui.title.namebaby\"), width / 2 - 100, height / 2 - 70, 0xa0a0a0);\n        babyNameTextField.drawTextBox();\n        super.drawScreen(sizeX, sizeY, offset);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/gui/GuiStaffOfLife.java",
    "content": "package mca.client.gui;\n\nimport mca.core.MCA;\nimport mca.core.forge.NetMCA;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.client.gui.GuiButton;\nimport net.minecraft.client.gui.GuiScreen;\nimport net.minecraft.client.gui.inventory.GuiInventory;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.nbt.NBTTagCompound;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.UUID;\n\n@SideOnly(Side.CLIENT)\npublic class GuiStaffOfLife extends GuiScreen {\n    private Map<String, NBTTagCompound> villagerData;\n    private GuiButton reviveButton;\n    private GuiButton nameButton;\n    private GuiButton backButton;\n    private GuiButton nextButton;\n    private GuiButton closeButton;\n    private EntityVillagerMCA dummy;\n    private EntityPlayer player;\n\n    // selection fields\n    private int index = 0;\n    private List<String> keys = new ArrayList<>();\n\n    public GuiStaffOfLife(EntityPlayer player) {\n        super();\n        this.player = player;\n    }\n\n    @Override\n    public void initGui() {\n        NetMCA.INSTANCE.sendToServer(new NetMCA.SavedVillagersRequest());\n\n        buttonList.clear();\n        buttonList.add(backButton = new GuiButton(1, width / 2 - 123, height / 2 + 65, 20, 20, \"<<\"));\n        buttonList.add(nextButton = new GuiButton(2, width / 2 + 103, height / 2 + 65, 20, 20, \">>\"));\n        buttonList.add(nameButton = new GuiButton(3, width / 2 - 100, height / 2 + 65, 200, 20, \"\"));\n        buttonList.add(reviveButton = new GuiButton(4, width / 2 - 100, height / 2 + 90, 60, 20, MCA.getLocalizer().localize(\"gui.button.revive\")));\n        buttonList.add(closeButton = new GuiButton(5, width / 2 + 40, height / 2 + 90, 60, 20, MCA.getLocalizer().localize(\"gui.button.exit\")));\n    }\n\n    @Override\n    public boolean doesGuiPauseGame() {\n        return false;\n    }\n\n    @Override\n    protected void actionPerformed(GuiButton guibutton) {\n        if (guibutton == reviveButton) {\n            NetMCA.INSTANCE.sendToServer(new NetMCA.ReviveVillager(UUID.fromString(keys.get(index))));\n            mc.displayGuiScreen(null);\n        } else if (guibutton == backButton) selectData(index - 1);\n        else if (guibutton == nextButton) selectData(index + 1);\n        else if (guibutton == closeButton) mc.displayGuiScreen(null);\n    }\n\n    @Override\n    public void drawScreen(int sizeX, int sizeY, float offset) {\n        drawDefaultBackground();\n        drawDummy();\n        drawCenteredString(fontRenderer, MCA.getLocalizer().localize(\"gui.title.staffoflife\"), width / 2, height / 2 - 110, 0xffffff);\n        super.drawScreen(sizeX, sizeY, offset);\n    }\n\n    public void setVillagerData(Map<String, NBTTagCompound> data) {\n        villagerData = data;\n\n        if (data.size() > 0) {\n            dummy = new EntityVillagerMCA(player.world);\n            keys.addAll(data.keySet());\n            selectData(0);\n        } else {\n            nameButton.displayString = \"No villagers found.\";\n            backButton.enabled = false;\n            nextButton.enabled = false;\n            nameButton.enabled = false;\n            reviveButton.enabled = false;\n        }\n    }\n\n    private void updateDummy(NBTTagCompound nbt) {\n        dummy.readEntityFromNBT(nbt);\n        dummy.setHealth(20.0F);\n    }\n\n    private void selectData(int i) {\n        if (i < 0) i = keys.size() - 1;\n        else if (i > keys.size() - 1) i = 0;\n\n        index = i;\n        updateDummy(villagerData.get(keys.get(index)));\n        nameButton.displayString = dummy.getDisplayName().getUnformattedText();\n    }\n\n    private void drawDummy() {\n        int posX = width / 2;\n        int posY = height / 2 + 45;\n\n        if (dummy != null) GuiInventory.drawEntityOnScreen(posX, posY, 60, 0, 0, dummy);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/gui/GuiVillagerEditor.java",
    "content": "package mca.client.gui;\n\nimport mca.api.API;\nimport mca.api.types.APIButton;\nimport mca.client.gui.component.GuiButtonEx;\nimport mca.core.MCA;\nimport mca.core.forge.NetMCA;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.client.Minecraft;\nimport net.minecraft.client.gui.GuiButton;\nimport net.minecraft.client.gui.GuiScreen;\nimport net.minecraft.client.gui.GuiTextField;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\nimport org.lwjgl.input.Keyboard;\n\nimport java.awt.*;\nimport java.awt.datatransfer.StringSelection;\nimport java.io.IOException;\n\n@SideOnly(Side.CLIENT)\npublic class GuiVillagerEditor extends GuiScreen {\n    private final EntityVillagerMCA villager;\n    private final EntityPlayer player;\n\n    private GuiTextField nameTextField;\n    private GuiTextField professionTextField;\n    private GuiTextField textureTextField;\n\n    public GuiVillagerEditor(EntityVillagerMCA EntityHuman, EntityPlayer player) {\n        super();\n        this.player = player;\n        villager = EntityHuman;\n    }\n\n    @Override\n    public void updateScreen() {\n        super.updateScreen();\n        nameTextField.updateCursorCounter();\n        professionTextField.updateCursorCounter();\n        textureTextField.updateCursorCounter();\n    }\n\n    @Override\n    public void initGui() {\n        Keyboard.enableRepeatEvents(true);\n        drawEditorGui();\n\n        nameTextField = new GuiTextField(1, fontRenderer, width / 2 - 205, height / 2 - 95, 150, 20);\n        nameTextField.setMaxStringLength(32);\n        nameTextField.setText(villager.get(EntityVillagerMCA.VILLAGER_NAME));\n        professionTextField = new GuiTextField(2, fontRenderer, width / 2 - 190, height / 2 + 10, 250, 20);\n        professionTextField.setMaxStringLength(64);\n        professionTextField.setText(villager.getVanillaCareer().getName());\n        textureTextField = new GuiTextField(3, fontRenderer, width / 2 - 190, height / 2 - 15, 250, 20);\n        textureTextField.setMaxStringLength(128);\n        textureTextField.setText(villager.get(EntityVillagerMCA.TEXTURE));\n    }\n\n    @Override\n    public void onGuiClosed() {\n        Keyboard.enableRepeatEvents(false);\n    }\n\n    @Override\n    protected void actionPerformed(GuiButton guiButton) {\n        APIButton btn = ((GuiButtonEx) guiButton).getApiButton();\n        if (btn.isNotifyServer()) {\n            NetMCA.INSTANCE.sendToServer(new NetMCA.ButtonAction(\"editor\", btn.getIdentifier(), villager.getUniqueID()));\n        } else if (btn.getIdentifier().equals(\"gui.button.done\")) {\n            mc.displayGuiScreen(null);\n        } else if (btn.getIdentifier().equals(\"gui.button.copyuuid\")) {\n            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(villager.getUniqueID().toString()), null);\n            Minecraft.getMinecraft().player.sendChatMessage(\"Villager UUID copied to clipboard.\");\n        } else if (btn.getIdentifier().equals(\"gui.button.profession.set\")) {\n            String profession = professionTextField.getText();\n            NetMCA.INSTANCE.sendToServer(new NetMCA.SetProfession(villager.getUniqueID(), profession));\n            new java.util.Timer().schedule(new java.util.TimerTask() {\n                        @Override\n                        public void run() {\n                            NetMCA.INSTANCE.sendToServer(new NetMCA.CareerRequest(villager.getUniqueID()));\n                        }\n                    },500\n            );\n        } else if (btn.getIdentifier().contains(\"gui.button.texture\")) {\n            String texture = btn.getIdentifier().endsWith(\".set\") ? textureTextField.getText() : API.getRandomSkin(villager);\n            NetMCA.INSTANCE.sendToServer(new NetMCA.SetTexture(villager.getUniqueID(), texture));\n            textureTextField.setText(texture);\n        }\n    }\n\n    @Override\n    protected void keyTyped(char c, int i) {\n        if (i == Keyboard.KEY_ESCAPE) {\n            Minecraft.getMinecraft().displayGuiScreen(null);\n        } else {\n            if (nameTextField.textboxKeyTyped(c, i)) {\n                String text = nameTextField.getText().trim();\n                NetMCA.INSTANCE.sendToServer(new NetMCA.SetName(text, villager.getUniqueID()));\n            }\n            textureTextField.textboxKeyTyped(c, i);\n            professionTextField.textboxKeyTyped(c, i);\n            drawEditorGui();\n        }\n    }\n\n    @Override\n    protected void mouseClicked(int clickX, int clickY, int clicked) throws IOException {\n        super.mouseClicked(clickX, clickY, clicked);\n        nameTextField.mouseClicked(clickX, clickY, clicked);\n        professionTextField.mouseClicked(clickX, clickY, clicked);\n        textureTextField.mouseClicked(clickX, clickY, clicked);\n    }\n\n    @Override\n    public boolean doesGuiPauseGame() {\n        return false;\n    }\n\n    private void drawEditorGui() {\n        buttonList.clear();\n        API.addButtons(\"editor\", villager, player, this);\n    }\n\n    @Override\n    public void drawScreen(int sizeX, int sizeY, float offset) {\n        drawGradientRect(0, 0, width, height, -1072689136, -804253680);\n        drawString(fontRenderer, \"Name:\", width / 2 - 205, height / 2 - 110, 0xffffff);\n        drawCenteredString(fontRenderer, MCA.getLocalizer().localize(\"gui.title.editor\"), width / 2, height / 2 - 110, 0xffffff);\n        nameTextField.drawTextBox();\n        professionTextField.drawTextBox();\n        textureTextField.drawTextBox();\n        super.drawScreen(sizeX, sizeY, offset);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/gui/GuiWhistle.java",
    "content": "package mca.client.gui;\n\nimport lombok.NonNull;\nimport mca.core.forge.NetMCA;\nimport net.minecraft.nbt.NBTTagCompound;\nimport org.apache.commons.lang3.StringUtils;\n\nimport mca.core.MCA;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.client.Minecraft;\nimport net.minecraft.client.gui.GuiButton;\nimport net.minecraft.client.gui.GuiScreen;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\n\nimport java.util.List;\n\nimport static mca.entity.EntityVillagerMCA.*;\n\n@SideOnly(Side.CLIENT)\npublic class GuiWhistle extends GuiScreen {\n    private EntityVillagerMCA dummyHuman;\n    private List<NBTTagCompound> villagerDataList;\n\n    private GuiButton selectionLeftButton;\n    private GuiButton selectionRightButton;\n    private GuiButton villagerNameButton;\n    private GuiButton callButton;\n    private GuiButton exitButton;\n    private int loadingAnimationTicks;\n    private int selectedIndex;\n\n    @Override\n    public void updateScreen() {\n        super.updateScreen();\n\n        if (loadingAnimationTicks != -1) {\n            loadingAnimationTicks++;\n        }\n\n        if (loadingAnimationTicks >= 20) {\n            loadingAnimationTicks = 0;\n        }\n    }\n\n    @Override\n    public void initGui() {\n        buttonList.clear();\n        buttonList.add(selectionLeftButton = new GuiButton(1, width / 2 - 123, height / 2 + 65, 20, 20, \"<<\"));\n        buttonList.add(selectionRightButton = new GuiButton(2, width / 2 + 103, height / 2 + 65, 20, 20, \">>\"));\n        buttonList.add(villagerNameButton = new GuiButton(3, width / 2 - 100, height / 2 + 65, 200, 20, \"\"));\n        buttonList.add(callButton = new GuiButton(4, width / 2 - 100, height / 2 + 90, 60, 20, MCA.getLocalizer().localize(\"gui.button.call\")));\n        buttonList.add(exitButton = new GuiButton(6, width / 2 + 40, height / 2 + 90, 60, 20, MCA.getLocalizer().localize(\"gui.button.exit\")));\n        NetMCA.INSTANCE.sendToServer(new NetMCA.GetFamily());\n    }\n\n    @Override\n    public boolean doesGuiPauseGame() {\n        return false;\n    }\n\n    @Override\n    protected void actionPerformed(GuiButton guibutton) {\n        if (guibutton == exitButton) {\n            Minecraft.getMinecraft().displayGuiScreen(null);\n        }\n\n        if (villagerDataList != null && villagerDataList.size() > 0) {\n            NBTTagCompound data = villagerDataList.get(selectedIndex - 1);\n\n            if (guibutton == selectionLeftButton) {\n                if (selectedIndex == 1) {\n                    selectedIndex = villagerDataList.size();\n                }\n\n                else {\n                    selectedIndex--;\n                }\n            }\n\n            else if (guibutton == selectionRightButton) {\n                if (selectedIndex == villagerDataList.size()) {\n                    selectedIndex = 1;\n                }\n\n                else {\n                    selectedIndex++;\n                }\n            }\n\n            else if (guibutton == callButton) {\n                NetMCA.INSTANCE.sendToServer(new NetMCA.CallToPlayer(data.getUniqueId(\"uuid\")));\n                Minecraft.getMinecraft().displayGuiScreen(null);\n            }\n\n            villagerNameButton.displayString = data.getString(\"name\");\n            updateDummyVillagerWithData(data);\n        }\n    }\n\n    @Override\n    public void drawScreen(int sizeX, int sizeY, float offset) {\n        drawDefaultBackground();\n        drawCenteredString(fontRenderer, MCA.getLocalizer().localize(\"gui.title.whistle\"), width / 2, height / 2 - 110, 0xffffff);\n\n        if (loadingAnimationTicks != -1) {\n            drawString(fontRenderer, \"Loading\" + StringUtils.repeat(\".\", loadingAnimationTicks % 10), width / 2 - 20, height / 2 - 10, 0xffffff);\n        }\n\n        else {\n            if (villagerDataList.size() == 0) {\n                drawCenteredString(fontRenderer, \"No family members could be found in the area.\", width / 2, height / 2 + 50, 0xffffff);\n            }\n\n            else {\n                drawCenteredString(fontRenderer, selectedIndex + \" / \" + villagerDataList.size(), width / 2, height / 2 + 50, 0xffffff);\n            }\n        }\n\n        if (dummyHuman != null) {\n            drawDummyVillager();\n        }\n\n        super.drawScreen(sizeX, sizeY, offset);\n    }\n\n    private void drawDummyVillager() {\n        final int posX = width / 2;\n        int posY = height / 2 + 45;\n        net.minecraft.client.gui.inventory.GuiInventory.drawEntityOnScreen(posX, posY, 75, 0, 0, dummyHuman);\n    }\n\n    public void setVillagerDataList(@NonNull List<NBTTagCompound> dataList) {\n        this.villagerDataList = dataList;\n        this.loadingAnimationTicks = -1;\n        this.selectedIndex = 1;\n\n        try {\n            NBTTagCompound firstData = dataList.get(0);\n            villagerNameButton.displayString = firstData.getString(\"name\");\n            dummyHuman = new EntityVillagerMCA(Minecraft.getMinecraft().world);\n            updateDummyVillagerWithData(firstData);\n        }\n\n        catch (IndexOutOfBoundsException e) {\n            callButton.enabled = false;\n        }\n    }\n\n    private void updateDummyVillagerWithData(NBTTagCompound nbt) {\n        dummyHuman.set(VILLAGER_NAME, nbt.getString(\"name\"));\n        dummyHuman.set(TEXTURE, nbt.getString(\"texture\"));\n        dummyHuman.set(GIRTH, nbt.getFloat(\"girth\"));\n        dummyHuman.set(TALLNESS, nbt.getFloat(\"tallness\"));\n        dummyHuman.set(IS_INFECTED, nbt.getBoolean(\"infected\"));\n        dummyHuman.set(AGE_STATE, nbt.getInteger(\"ageState\"));\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/gui/component/GuiButtonEx.java",
    "content": "package mca.client.gui.component;\n\nimport lombok.Getter;\nimport mca.api.types.APIButton;\nimport mca.core.MCA;\nimport net.minecraft.client.gui.GuiButton;\nimport net.minecraft.client.gui.GuiScreen;\n\npublic class GuiButtonEx extends GuiButton {\n    @Getter private APIButton apiButton;\n\n    public GuiButtonEx(GuiScreen gui, APIButton apiButton) {\n        super(apiButton.getId(), (gui.width / 2) + apiButton.getX(), (gui.height / 2) + apiButton.getY(), apiButton.getWidth(), apiButton.getHeight(), MCA.getLocalizer().localize(apiButton.getIdentifier()));\n        this.apiButton = apiButton;\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/client/model/ModelGrimReaper.java",
    "content": "package mca.client.model;\n\nimport mca.entity.EntityGrimReaper;\nimport mca.enums.EnumReaperAttackState;\nimport net.minecraft.client.model.ModelBiped;\nimport net.minecraft.client.model.ModelRenderer;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.util.math.MathHelper;\nimport org.lwjgl.opengl.GL11;\n\npublic class ModelGrimReaper extends ModelBiped {\n    private ModelRenderer head;\n    private ModelRenderer rightArm;\n    private ModelRenderer leftLeg;\n    private ModelRenderer cowl;\n    private ModelRenderer chest;\n    private ModelRenderer leftArm;\n    private ModelRenderer rightLeg;\n\n    private ModelRenderer cowlPreAttack;\n    private ModelRenderer rightArmPreAttack;\n    private ModelRenderer leftLegPreAttack;\n    private ModelRenderer headPreAttack;\n    private ModelRenderer chestPreAttack;\n    private ModelRenderer leftArmPreAttack;\n    private ModelRenderer rightLegPreAttack;\n    private ModelRenderer scytheHandlePreAttack;\n    private ModelRenderer scytheHeadPreAttack;\n\n    private ModelRenderer cowlPostAttack;\n    private ModelRenderer rightArmPostAttack;\n    private ModelRenderer leftLegPostAttack;\n    private ModelRenderer headPostAttack;\n    private ModelRenderer chestPostAttack;\n    private ModelRenderer leftArmPostAttack;\n    private ModelRenderer rightLegPostAttack;\n    private ModelRenderer scytheHandlePostAttack;\n    private ModelRenderer scytheHeadPostAttack;\n\n    private ModelRenderer cowlBlock;\n    private ModelRenderer rightArmBlock;\n    private ModelRenderer leftLegBlock;\n    private ModelRenderer headBlock;\n    private ModelRenderer chestBlock;\n    private ModelRenderer leftArmBlock;\n    private ModelRenderer rightLegBlock;\n    private ModelRenderer scytheHandleBlock;\n    private ModelRenderer scytheHeadBlock;\n\n    private ModelRenderer cowlRest;\n    private ModelRenderer rightArmRest;\n    private ModelRenderer leftLegRest;\n    private ModelRenderer chestRest;\n    private ModelRenderer leftArmRest;\n    private ModelRenderer rightLegRest;\n    private ModelRenderer scytheHandleRest;\n    private ModelRenderer scytheHeadRest;\n    private ModelRenderer headRest;\n\n    public ModelGrimReaper() {\n        this.textureWidth = 64;\n        this.textureHeight = 64;\n\n        this.leftLeg = new ModelRenderer(this, 0, 16);\n        this.leftLeg.mirror = true;\n        this.leftLeg.setRotationPoint(1.9F, 12.0F, 0.0F);\n        this.leftLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.leftArm = new ModelRenderer(this, 40, 16);\n        this.leftArm.mirror = true;\n        this.leftArm.setRotationPoint(5.0F, 2.0F, 0.0F);\n        this.leftArm.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.rightLeg = new ModelRenderer(this, 0, 16);\n        this.rightLeg.setRotationPoint(-1.9F, 12.0F, 0.0F);\n        this.rightLeg.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.chest = new ModelRenderer(this, 16, 16);\n        this.chest.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.chest.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F);\n        this.cowl = new ModelRenderer(this, 0, 0);\n        this.cowl.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.cowl.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F);\n        this.head = new ModelRenderer(this, 32, 0);\n        this.head.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.head.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.5F);\n        this.rightArm = new ModelRenderer(this, 40, 16);\n        this.rightArm.setRotationPoint(-5.0F, 2.0F, 0.0F);\n        this.rightArm.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);\n\n        this.leftArmPreAttack = new ModelRenderer(this, 40, 16);\n        this.leftArmPreAttack.mirror = true;\n        this.leftArmPreAttack.setRotationPoint(5.0F, 2.0F, 0.0F);\n        this.leftArmPreAttack.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(leftArmPreAttack, -2.276432943376204F, -1.9577358219620393F, 0.136659280431156F);\n        this.cowlPreAttack = new ModelRenderer(this, 32, 0);\n        this.cowlPreAttack.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.cowlPreAttack.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.5F);\n        this.setRotateAngle(cowlPreAttack, -0.27314402793711257F, 0.18203784098300857F, 0.0F);\n        this.rightLegPreAttack = new ModelRenderer(this, 0, 16);\n        this.rightLegPreAttack.setRotationPoint(-1.9F, 12.0F, 0.0F);\n        this.rightLegPreAttack.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(rightLegPreAttack, 0.22759093446006054F, -0.22759093446006054F, 0.0F);\n        this.leftLegPreAttack = new ModelRenderer(this, 0, 16);\n        this.leftLegPreAttack.mirror = true;\n        this.leftLegPreAttack.setRotationPoint(1.9F, 12.0F, 0.0F);\n        this.leftLegPreAttack.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(leftLegPreAttack, 0.31869712141416456F, -0.22759093446006054F, 0.0F);\n        this.chestPreAttack = new ModelRenderer(this, 16, 16);\n        this.chestPreAttack.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.chestPreAttack.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F);\n        this.setRotateAngle(chestPreAttack, 0.0F, -0.22759093446006054F, 0.0F);\n        this.scytheHandlePreAttack = new ModelRenderer(this, 36, 32);\n        this.scytheHandlePreAttack.setRotationPoint(7.0F, -12.4F, 17.2F);\n        this.scytheHandlePreAttack.addBox(0.0F, 0.0F, 0.0F, 1, 31, 1, 0.0F);\n        this.setRotateAngle(scytheHandlePreAttack, -1.0471975511965976F, -0.36425021489121656F, 0.0F);\n        this.rightArmPreAttack = new ModelRenderer(this, 40, 16);\n        this.rightArmPreAttack.setRotationPoint(-5.0F, 2.0F, 0.0F);\n        this.rightArmPreAttack.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(rightArmPreAttack, -0.6373942428283291F, 2.1399481958702475F, 0.0F);\n        this.headPreAttack = new ModelRenderer(this, 0, 0);\n        this.headPreAttack.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.headPreAttack.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F);\n        this.setRotateAngle(headPreAttack, -0.27314402793711257F, 0.18203784098300857F, 0.0F);\n        this.scytheHeadPreAttack = new ModelRenderer(this, 0, 32);\n        this.scytheHeadPreAttack.setRotationPoint(7.8F, -11.8F, 17.5F);\n        this.scytheHeadPreAttack.addBox(0.0F, 0.0F, 0.0F, 16, 16, 0, 0.0F);\n        this.setRotateAngle(scytheHeadPreAttack, -1.0471975511965976F, -0.36425021489121656F, 0.0F);\n\n        this.chestPostAttack = new ModelRenderer(this, 16, 16);\n        this.chestPostAttack.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.chestPostAttack.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F);\n        this.setRotateAngle(chestPostAttack, 0.5918411493512771F, 0.5918411493512771F, 0.0F);\n        this.leftArmPostAttack = new ModelRenderer(this, 40, 16);\n        this.leftArmPostAttack.mirror = true;\n        this.leftArmPostAttack.setRotationPoint(5.0F, 2.0F, 0.0F);\n        this.leftArmPostAttack.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(leftArmPostAttack, -0.7740535232594852F, 1.0927506446736497F, 0.136659280431156F);\n        this.cowlPostAttack = new ModelRenderer(this, 32, 0);\n        this.cowlPostAttack.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.cowlPostAttack.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.5F);\n        this.setRotateAngle(cowlPostAttack, 0.7740535232594852F, 0.7285004297824331F, 0.0F);\n        this.scytheHeadPostAttack = new ModelRenderer(this, 0, 32);\n        this.scytheHeadPostAttack.setRotationPoint(0.8F, 8.9F, -24.0F);\n        this.scytheHeadPostAttack.addBox(0.0F, 0.0F, 0.0F, 16, 16, 0, 0.0F);\n        this.setRotateAngle(scytheHeadPostAttack, -1.6235052702051254F, 2.9543188248508017F, -0.27314402793711257F);\n        this.scytheHandlePostAttack = new ModelRenderer(this, 37, 32);\n        this.scytheHandlePostAttack.setRotationPoint(-4.3F, 9.0F, 6.7F);\n        this.scytheHandlePostAttack.addBox(0.0F, 0.0F, 0.0F, 1, 31, 1, 0.0F);\n        this.setRotateAngle(scytheHandlePostAttack, 1.5025539530419183F, 2.9595548126067843F, -0.36425021489121656F);\n        this.rightLegPostAttack = new ModelRenderer(this, 0, 16);\n        this.rightLegPostAttack.setRotationPoint(2.0F, 10.0F, 6.6F);\n        this.rightLegPostAttack.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(rightLegPostAttack, 0.5462880558742251F, 0.5918411493512771F, -0.091106186954104F);\n        this.headPostAttack = new ModelRenderer(this, 0, 0);\n        this.headPostAttack.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.headPostAttack.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F);\n        this.setRotateAngle(headPostAttack, 0.7740535232594852F, 0.7285004297824331F, 0.0F);\n        this.leftLegPostAttack = new ModelRenderer(this, 0, 16);\n        this.leftLegPostAttack.mirror = true;\n        this.leftLegPostAttack.setRotationPoint(5.4F, 9.8F, 4.6F);\n        this.leftLegPostAttack.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(leftLegPostAttack, 0.5009094953223726F, 0.6829473363053812F, -0.045553093477052F);\n        this.rightArmPostAttack = new ModelRenderer(this, 40, 16);\n        this.rightArmPostAttack.setRotationPoint(-5.0F, 1.7F, 3.3F);\n        this.rightArmPostAttack.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(rightArmPostAttack, -1.593485607070823F, 2.5497515042385164F, 0.0F);\n\n        this.cowlBlock = new ModelRenderer(this, 32, 0);\n        this.cowlBlock.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.cowlBlock.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.5F);\n        this.setRotateAngle(cowlBlock, 0.091106186954104F, 0.0F, 0.0F);\n        this.leftLegBlock = new ModelRenderer(this, 0, 16);\n        this.leftLegBlock.mirror = true;\n        this.leftLegBlock.setRotationPoint(1.9F, 12.0F, 0.0F);\n        this.leftLegBlock.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(leftLegBlock, -0.136659280431156F, 0.045553093477052F, 0.0F);\n        this.headBlock = new ModelRenderer(this, 0, 0);\n        this.headBlock.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.headBlock.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F);\n        this.setRotateAngle(headBlock, 0.136659280431156F, 0.0F, 0.0F);\n        this.rightArmBlock = new ModelRenderer(this, 40, 16);\n        this.rightArmBlock.setRotationPoint(-5.0F, 2.0F, 0.0F);\n        this.rightArmBlock.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(rightArmBlock, -1.2292353921796064F, 0.0F, 1.8668041679331349F);\n        this.scytheHandleBlock = new ModelRenderer(this, 36, 32);\n        this.scytheHandleBlock.setRotationPoint(-18.5F, -3.7F, -10.1F);\n        this.scytheHandleBlock.addBox(0.0F, 0.0F, 0.0F, 1, 31, 1, 0.0F);\n        this.setRotateAngle(scytheHandleBlock, 1.2292353921796064F, 1.5481070465189704F, 0.0F);\n        this.rightLegBlock = new ModelRenderer(this, 0, 16);\n        this.rightLegBlock.setRotationPoint(-1.9F, 12.0F, 0.0F);\n        this.rightLegBlock.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(rightLegBlock, -0.136659280431156F, 0.091106186954104F, 0.0F);\n        this.chestBlock = new ModelRenderer(this, 16, 16);\n        this.chestBlock.setRotationPoint(0.0F, 0.0F, 1.0F);\n        this.chestBlock.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F);\n        this.setRotateAngle(chestBlock, -0.091106186954104F, 0.091106186954104F, 0.0F);\n        this.leftArmBlock = new ModelRenderer(this, 40, 16);\n        this.leftArmBlock.mirror = true;\n        this.leftArmBlock.setRotationPoint(5.0F, 2.0F, 0.0F);\n        this.leftArmBlock.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(leftArmBlock, -1.5025539530419183F, 0.40980330836826856F, 0.136659280431156F);\n        this.scytheHeadBlock = new ModelRenderer(this, 0, 32);\n        this.scytheHeadBlock.setRotationPoint(-18.5F, -3.7F, -10.1F);\n        this.scytheHeadBlock.addBox(0.0F, 0.0F, 0.5F, 16, 16, 0, 0.0F);\n        this.setRotateAngle(scytheHeadBlock, 1.2292353921796064F, 1.5481070465189704F, 0.0F);\n\n        this.rightArmRest = new ModelRenderer(this, 40, 16);\n        this.rightArmRest.setRotationPoint(-5.0F, 2.0F, 0.0F);\n        this.rightArmRest.addBox(-3.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(rightArmRest, 0.091106186954104F, -0.045553093477052F, 0.4553564018453205F);\n        this.rightLegRest = new ModelRenderer(this, 0, 16);\n        this.rightLegRest.setRotationPoint(-1.9F, 12.0F, 0.0F);\n        this.rightLegRest.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(rightLegRest, 0.045553093477052F, 0.091106186954104F, 0.0F);\n        this.leftArmRest = new ModelRenderer(this, 40, 16);\n        this.leftArmRest.mirror = true;\n        this.leftArmRest.setRotationPoint(5.0F, 2.0F, 0.0F);\n        this.leftArmRest.addBox(-1.0F, -2.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(leftArmRest, -1.6845917940249266F, -1.5481070465189704F, 0.9560913642424937F);\n        this.chestRest = new ModelRenderer(this, 16, 16);\n        this.chestRest.setRotationPoint(0.0F, 0.0F, 0.1F);\n        this.chestRest.addBox(-4.0F, 0.0F, -2.0F, 8, 12, 4, 0.0F);\n        this.setRotateAngle(chestRest, 0.0F, 0.091106186954104F, 0.0F);\n        this.leftLegRest = new ModelRenderer(this, 0, 16);\n        this.leftLegRest.mirror = true;\n        this.leftLegRest.setRotationPoint(1.9F, 12.0F, 0.0F);\n        this.leftLegRest.addBox(-2.0F, 0.0F, -2.0F, 4, 12, 4, 0.0F);\n        this.setRotateAngle(leftLegRest, 0.045553093477052F, 0.045553093477052F, 0.0F);\n        this.headRest = new ModelRenderer(this, 0, 0);\n        this.headRest.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.headRest.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.0F);\n        this.setRotateAngle(headRest, 1.0927506446736497F, 0.0F, 0.03159045946109736F);\n        this.scytheHeadRest = new ModelRenderer(this, 0, 32);\n        this.scytheHeadRest.setRotationPoint(-0.1F, -7.3F, -11.7F);\n        this.scytheHeadRest.addBox(0.0F, 0.0F, 0.5F, 16, 16, 0, 0.0F);\n        this.setRotateAngle(scytheHeadRest, 0.091106186954104F, 1.2747884856566583F, 0.091106186954104F);\n        this.cowlRest = new ModelRenderer(this, 32, 0);\n        this.cowlRest.setRotationPoint(0.0F, 0.0F, 0.0F);\n        this.cowlRest.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.5F);\n        this.setRotateAngle(cowlRest, 1.0471975511965976F, 0.0F, 0.0F);\n        this.scytheHandleRest = new ModelRenderer(this, 36, 32);\n        this.scytheHandleRest.setRotationPoint(-1.0F, 7.0F, -10.1F);\n        this.scytheHandleRest.addBox(0.5F, -15.5F, 0.5F, 1, 31, 1, 0.0F);\n        this.setRotateAngle(scytheHandleRest, 0.091106186954104F, 1.2747884856566583F, 0.091106186954104F);\n    }\n\n    @Override\n    public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) {\n        EntityGrimReaper reaper = (EntityGrimReaper) entity;\n\n        if (reaper.getAttackState() == EnumReaperAttackState.PRE) {\n            this.leftLegPreAttack.render(f5);\n            this.leftArmPreAttack.render(f5);\n            this.rightLegPreAttack.render(f5);\n            this.chestPreAttack.render(f5);\n            this.cowlPreAttack.render(f5);\n            this.headPreAttack.render(f5);\n            this.rightArmPreAttack.render(f5);\n            this.scytheHandlePreAttack.render(f5);\n            this.scytheHeadPreAttack.render(f5);\n        } else if (reaper.getAttackState() == EnumReaperAttackState.POST) {\n            this.leftLegPostAttack.render(f5);\n            this.leftArmPostAttack.render(f5);\n            this.rightLegPostAttack.render(f5);\n            this.chestPostAttack.render(f5);\n            this.cowlPostAttack.render(f5);\n            this.headPostAttack.render(f5);\n            this.rightArmPostAttack.render(f5);\n            this.scytheHandlePostAttack.render(f5);\n            this.scytheHeadPostAttack.render(f5);\n        } else if (reaper.getAttackState() == EnumReaperAttackState.BLOCK) {\n            this.cowlBlock.render(f5);\n            this.leftLegBlock.render(f5);\n            this.headBlock.render(f5);\n            this.rightArmBlock.render(f5);\n            this.scytheHandleBlock.render(f5);\n            this.rightLegBlock.render(f5);\n            this.chestBlock.render(f5);\n            this.leftArmBlock.render(f5);\n            this.scytheHeadBlock.render(f5);\n        } else if (reaper.getAttackState() == EnumReaperAttackState.REST) {\n\n            GL11.glPushMatrix();\n            {\n                double amt = Math.cos(reaper.getFloatingTicks()) / 4;\n                GL11.glTranslated(0.0D, amt, 0.0D);\n\n                this.rightArmRest.render(f5);\n                this.rightLegRest.render(f5);\n                this.leftArmRest.render(f5);\n                this.chestRest.render(f5);\n                this.leftLegRest.render(f5);\n                this.cowlRest.render(f5);\n\n                GL11.glPushMatrix();\n                {\n                    double amt2 = Math.cos(reaper.getFloatingTicks()) / 8;\n                    GL11.glTranslated(0.0D, amt2, 0.0D);\n\n                    this.scytheHeadRest.render(f5);\n                    this.scytheHandleRest.render(f5);\n                }\n                GL11.glPopMatrix();\n            }\n            GL11.glPopMatrix();\n        } else {\n            rightLeg.rotateAngleX = MathHelper.clamp(MathHelper.cos(100F * 0.6662F + 3.141593F) * 2.5F * f1, 0.0F, 1.1F);\n            leftLeg.rotateAngleX = MathHelper.clamp(MathHelper.cos(100F * 0.6662F + 3.141593F) * 2.5F * f1, 0.0F, 1.1F);\n            rightLeg.rotateAngleX = MathHelper.clamp(MathHelper.cos(100F * 0.6662F + 3.141593F) * 2.5F * f1, 0.0F, 1.1F);\n            leftLeg.rotateAngleX = MathHelper.clamp(MathHelper.cos(100F * 0.6662F + 3.141593F) * 2.5F * f1, 0.0F, 1.1F);\n\n            rightLeg.rotateAngleY = 0.0F;\n            leftLeg.rotateAngleY = 0.0F;\n\n            this.leftLeg.render(f5);\n            this.leftArm.render(f5);\n            this.rightLeg.render(f5);\n            this.chest.render(f5);\n            this.cowl.render(f5);\n            this.head.render(f5);\n            this.rightArm.render(f5);\n        }\n    }\n\n    public void setRotateAngle(ModelRenderer modelRenderer, float x, float y, float z) {\n        modelRenderer.rotateAngleX = x;\n        modelRenderer.rotateAngleY = y;\n        modelRenderer.rotateAngleZ = z;\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/model/ModelVillagerMCA.java",
    "content": "package mca.client.model;\n\nimport mca.enums.EnumGender;\nimport org.lwjgl.opengl.GL11;\n\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.client.model.ModelBiped;\nimport net.minecraft.client.model.ModelRenderer;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.inventory.EntityEquipmentSlot;\nimport net.minecraft.item.ItemStack;\n\npublic class ModelVillagerMCA extends ModelBiped {\n    private ModelRenderer breasts;\n\n    public ModelVillagerMCA() {\n        super(0.0F, 0.0F, 64, 64);\n        breasts = new ModelRenderer(this, 18, 21);\n        breasts.addBox(-3F, 0F, -1F, 6, 3, 3);\n        breasts.setRotationPoint(0F, 3.5F, -3F);\n        breasts.setTextureSize(64, 64);\n        breasts.mirror = true;\n    }\n\n    @Override\n    public void render(Entity entity, float swing, float swingAmount, float age, float headYaw, float headPitch, float scale) {\n        super.render(entity, swing, swingAmount, age, headYaw, headPitch, scale);\n        EntityVillagerMCA villager = (EntityVillagerMCA)entity;\n        if (EnumGender.byId(villager.get(EntityVillagerMCA.GENDER)) == EnumGender.FEMALE && !villager.isChild() && villager.getItemStackFromSlot(EntityEquipmentSlot.CHEST) == ItemStack.EMPTY) {\n            GL11.glPushMatrix();\n            GL11.glTranslated(0.005D, -0.05D, -0.28D);\n            GL11.glScaled(1.15D, 1.0D, 1.0D);\n            GL11.glRotatef(60.0F, 1.0F, 0.0F, 0.0F);\n            breasts.render(scale);\n            GL11.glPopMatrix();\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/network/ClientMessageQueue.java",
    "content": "package mca.client.network;\n\nimport mca.core.MCA;\nimport mca.core.forge.NetMCA;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.client.Minecraft;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.passive.EntityVillager;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.world.World;\nimport net.minecraftforge.fml.common.ObfuscationReflectionHelper;\nimport net.minecraftforge.fml.common.network.simpleimpl.IMessage;\n\nimport java.util.Optional;\nimport java.util.UUID;\nimport java.util.concurrent.ConcurrentLinkedQueue;\n\npublic class ClientMessageQueue {\n    private static ConcurrentLinkedQueue<IMessage> scheduledMessages = new ConcurrentLinkedQueue<>();\n\n    public static void processScheduledMessages() {\n        IMessage next = scheduledMessages.poll();\n\n        if (next != null) handle(next);\n    }\n\n    public static void add(IMessage msg) {\n        scheduledMessages.add(msg);\n    }\n\n    private static void handle(IMessage msg) {\n        if (msg instanceof NetMCA.CareerResponse) handleCareerId((NetMCA.CareerResponse) msg);\n        else if (msg instanceof NetMCA.InventoryResponse) handleInventory((NetMCA.InventoryResponse) msg);\n        else MCA.getLog().error(\"Unexpected message in queue:\" + msg.getClass().getName());\n    }\n\n    private static void handleCareerId(NetMCA.CareerResponse msg) {\n        EntityPlayer player = Minecraft.getMinecraft().player;\n\n        try {\n            Optional<EntityVillagerMCA> villager = getVillagerByUUID(player.getEntityWorld(), msg.getEntityUUID());\n\n            if (villager.isPresent()) {\n                ObfuscationReflectionHelper.setPrivateValue(EntityVillager.class, villager.get(), msg.getCareerId(), EntityVillagerMCA.VANILLA_CAREER_ID_FIELD_INDEX);\n            }\n        } catch (ClassCastException e) {\n            MCA.getLog().error(\"Failed to cast entity to villager on career ID update.\");\n        } catch (Exception e) {\n            MCA.getLog().error(\"Failed to set career ID on villager!\", e);\n        }\n    }\n\n    private static void handleInventory(NetMCA.InventoryResponse msg) {\n        EntityPlayer player = Minecraft.getMinecraft().player;\n        if (player != null) {\n            Optional<EntityVillagerMCA> villager = getVillagerByUUID(player.world, msg.getEntityUUID());\n            villager.ifPresent(entityVillagerMCA -> entityVillagerMCA.inventory.readInventoryFromNBT(msg.getInventoryNBT().getTagList(\"inventory\", 10)));\n        }\n    }\n\n    private static Optional<EntityVillagerMCA> getVillagerByUUID(World world, UUID uuid) {\n        try {\n            synchronized (world.loadedEntityList) {\n                return world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(uuid)).map(EntityVillagerMCA.class::cast).findFirst();\n            }\n        } catch (ClassCastException ignored) {\n            MCA.getLog().error(\"Failed to cast entity with UUID \" + uuid.toString() + \" to a villager!\");\n        }\n        return Optional.empty();\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/client/render/RenderGrimReaper.java",
    "content": "package mca.client.render;\n\nimport mca.client.model.ModelGrimReaper;\nimport mca.entity.EntityGrimReaper;\nimport net.minecraft.client.renderer.entity.RenderBiped;\nimport net.minecraft.client.renderer.entity.RenderManager;\nimport net.minecraft.util.ResourceLocation;\nimport org.lwjgl.opengl.GL11;\n\npublic class RenderGrimReaper<T extends EntityGrimReaper> extends RenderBiped<T> {\n    private static final ResourceLocation TEXTURE = new ResourceLocation(\"mca:textures/entity/grimreaper.png\");\n\n    public RenderGrimReaper(RenderManager manager) {\n        super(manager, new ModelGrimReaper(), 0.5F);\n    }\n\n    @Override\n    public void doRender(T entity, double posX, double posY, double posZ, float angle, float offsetY) {\n        super.doRender(entity, posX, posY, posZ, angle, offsetY);\n    }\n\n    @Override\n    protected void preRenderCallback(T entity, float partialTickTime) {\n        super.preRenderCallback(entity, partialTickTime);\n\n        double scale = 1.3D;\n        GL11.glScaled(scale, scale, scale);\n    }\n\n    @Override\n    protected ResourceLocation getEntityTexture(T entity) {\n        return TEXTURE;\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/render/RenderReaperFactory.java",
    "content": "package mca.client.render;\n\nimport mca.entity.EntityGrimReaper;\nimport net.minecraft.client.renderer.entity.Render;\nimport net.minecraft.client.renderer.entity.RenderManager;\nimport net.minecraftforge.fml.client.registry.IRenderFactory;\n\npublic class RenderReaperFactory implements IRenderFactory<EntityGrimReaper> {\n    public static final RenderReaperFactory INSTANCE = new RenderReaperFactory();\n\n    @Override\n    public Render<? super EntityGrimReaper> createRenderFor(RenderManager manager) {\n        return new RenderGrimReaper(manager);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/render/RenderVillagerFactory.java",
    "content": "package mca.client.render;\n\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.client.renderer.entity.Render;\nimport net.minecraft.client.renderer.entity.RenderManager;\nimport net.minecraftforge.fml.client.registry.IRenderFactory;\n\npublic class RenderVillagerFactory implements IRenderFactory<EntityVillagerMCA> {\n    public static final RenderVillagerFactory INSTANCE = new RenderVillagerFactory();\n\n    @Override\n    public Render<? super EntityVillagerMCA> createRenderFor(RenderManager manager) {\n        return new RenderVillagerMCA(manager);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/client/render/RenderVillagerMCA.java",
    "content": "package mca.client.render;\n\nimport mca.client.model.ModelVillagerMCA;\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumAgeState;\nimport net.minecraft.client.Minecraft;\nimport net.minecraft.client.model.ModelBiped;\nimport net.minecraft.client.renderer.BufferBuilder;\nimport net.minecraft.client.renderer.GlStateManager;\nimport net.minecraft.client.renderer.Tessellator;\nimport net.minecraft.client.renderer.entity.RenderBiped;\nimport net.minecraft.client.renderer.entity.RenderManager;\nimport net.minecraft.client.renderer.entity.layers.LayerBipedArmor;\nimport net.minecraft.client.renderer.entity.layers.LayerHeldItem;\nimport net.minecraft.client.renderer.vertex.DefaultVertexFormats;\nimport net.minecraft.util.ResourceLocation;\nimport org.lwjgl.opengl.GL11;\n\npublic class RenderVillagerMCA<T extends EntityVillagerMCA> extends RenderBiped<EntityVillagerMCA> {\n    private static final ResourceLocation gui = new ResourceLocation(\"mca:textures/gui.png\");\n    private static final float LABEL_SCALE = 0.027F;\n\n    public RenderVillagerMCA(RenderManager manager) {\n        super(manager, new ModelVillagerMCA(), 0.5F);\n        this.addLayer(new LayerBipedArmor(this));\n        this.addLayer(new LayerHeldItem(this));\n    }\n\n    @Override\n    protected void preRenderCallback(EntityVillagerMCA villager, float partialTickTime) {\n        if (villager.isChild()) {\n            float scaleForAge = EnumAgeState.byId(villager.get(EntityVillagerMCA.AGE_STATE)).getScaleForAge();\n            GlStateManager.scale(scaleForAge, scaleForAge, scaleForAge);\n        }\n\n        if (villager.isRiding()) {\n            GlStateManager.translate(0, 0.5, 0);\n        }\n    }\n\n    @Override\n    public void renderName(EntityVillagerMCA entity, double x, double y, double z) {\n        super.renderName(entity, x, y ,z);\n        if (canRenderName(entity)) {\n            if (entity.getHealth() < entity.getMaxHealth()) {\n                renderHealth(entity, x, y, z, (int) entity.getHealth(), (int) entity.getMaxHealth());\n            }\n\n            if (entity.getCurrentActivity() != null) {\n                double d0 = entity.getDistanceSq(this.renderManager.renderViewEntity);\n                float f = entity.isSneaking() ? NAME_TAG_RANGE_SNEAK : NAME_TAG_RANGE;\n                if (d0 < (double) (f * f)) {\n                    this.renderEntityName(entity, x, y - 0.25F, z, \"(\" + entity.getCurrentActivity() + \")\", d0);\n                }\n            }\n        }\n    }\n\n    private void renderHealth(EntityVillagerMCA villager, double posX, double posY, double posZ, int currentHealth, int maxHealth) {\n        final int redHeartU = 80;\n        final int darkHeartU = 96;\n        int heartsDrawn = 0;\n\n        float maxHealthF = Math.round((float)maxHealth / 2.0F);\n        float currentHealthF = Math.round((float)currentHealth / 2.0F);\n        int heartsMax = Math.round((maxHealthF / maxHealthF) * 10.0F);\n        int heartsToDraw = Math.round((currentHealthF / maxHealthF) * 10.0F);\n\n        for (int i = 0; i < heartsMax; i++) {\n            int heartU = i < heartsToDraw ? redHeartU : darkHeartU;\n            heartsDrawn++;\n\n            GL11.glPushMatrix();{\n                GL11.glTranslatef((float) posX + 0.0F, (float) posY + villager.height + 1.0F, (float) posZ);\n                GL11.glRotatef(-renderManager.playerViewY, 0.0F, 1.0F, 0.0F);\n                GL11.glRotatef(renderManager.playerViewX, 1.0F, 0.0F, 0.0F);\n                GL11.glScalef(-LABEL_SCALE, -LABEL_SCALE, LABEL_SCALE);\n                GL11.glDisable(GL11.GL_LIGHTING);\n                GL11.glTranslatef(-2.0F, 2.0F, -2.0F);\n                drawTexturedRectangle(gui, (int)posX + (heartsDrawn * 8) - 45, (int)posY - 4, heartU, 0, 16, 16);\n            }\n            GL11.glPopMatrix();\n            GL11.glDepthMask(true);\n            GL11.glEnable(GL11.GL_LIGHTING);\n        }\n    }\n\n    @Override\n    protected ResourceLocation getEntityTexture(EntityVillagerMCA villager) {\n        return villager.getTextureResourceLocation();\n    }\n\n    @Override\n    protected boolean canRenderName(EntityVillagerMCA entity) {\n        float distance = Minecraft.getMinecraft().player.getDistance(entity);\n        return distance < 5F;\n    }\n\n    public static void drawTexturedRectangle(ResourceLocation texture, int x, int y, int u, int v, int width, int height)\n    {\n        Minecraft.getMinecraft().renderEngine.bindTexture(texture);\n\n        float f = 0.00390625F;\n        float f1 = 0.00390625F;\n\n        final Tessellator tessellator = Tessellator.getInstance();\n        BufferBuilder buffer = tessellator.getBuffer();\n\n        buffer.begin(7, DefaultVertexFormats.POSITION_TEX);\n        buffer.pos(x + 0, y + height, 0.0D).tex((u + 0) * f, ((v + height) * f1)).endVertex();\n        buffer.pos(x + width, y + height, 0.0D).tex((u + width) * f, ((v + height) * f1)).endVertex();\n        buffer.pos(x + width, y + 0,\t0.0D).tex((u + width) * f, ((v + 0) * f1)).endVertex();\n        buffer.pos(x + 0, y + 0, 0.0D).tex((u + 0) * f, ((v + 0) * f1)).endVertex();\n        tessellator.draw();\n    }\n\n    @Override\n    protected void renderLivingAt(EntityVillagerMCA entityLiving, double x, double y, double z) {\n        if (entityLiving.isEntityAlive() && entityLiving.isSleeping()) {\n            super.renderLivingAt(entityLiving, x + (double)entityLiving.renderOffsetX, y + (double)entityLiving.renderOffsetY, z + (double)entityLiving.renderOffsetZ);\n        } else {\n            super.renderLivingAt(entityLiving, x, y, z);\n        }\n    }\n\n    @Override\n    protected void applyRotations(EntityVillagerMCA entityLiving, float p_77043_2_, float rotationYaw, float partialTicks) {\n        if (entityLiving.isSleeping()) {\n            GlStateManager.rotate(entityLiving.getBedOrientationInDegrees(), 0.0F, 1.0F, 0.0F);\n            GlStateManager.rotate(this.getDeathMaxRotation(entityLiving), 0.0F, 0.0F, 1.0F);\n            GlStateManager.rotate(270.0F, 0.0F, 1.0F, 0.0F);\n            rotationYaw = 180.0f;\n        }\n        super.applyRotations(entityLiving, p_77043_2_, rotationYaw, partialTicks);\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/command/CommandAdminMCA.java",
    "content": "package mca.command;\n\nimport com.google.common.base.Optional;\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.core.minecraft.ItemsMCA;\nimport mca.entity.EntityGrimReaper;\nimport mca.entity.EntityVillagerMCA;\nimport mca.entity.data.PlayerSaveData;\nimport mca.items.ItemBaby;\nimport mca.util.Util;\nimport net.minecraft.command.CommandBase;\nimport net.minecraft.command.CommandException;\nimport net.minecraft.command.ICommandSender;\nimport net.minecraft.command.WrongUsageException;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.server.MinecraftServer;\nimport net.minecraft.util.text.TextComponentString;\n\nimport java.util.Arrays;\nimport java.util.UUID;\n\npublic class CommandAdminMCA extends CommandBase {\n    @Override\n    public String getName() {\n        return \"mca-admin\";\n    }\n\n    @Override\n    public String getUsage(ICommandSender commandSender) {\n        return \"/mca-admin <subcommand> <arguments>\";\n    }\n\n    @Override\n    public void execute(MinecraftServer server, ICommandSender commandSender, String[] input) throws CommandException {\n        try {\n            if (!MCA.getConfig().enableAdminCommands) {\n                sendMessage(commandSender, \"MCA admin commands have been disabled by the server administrator.\");\n                return;\n            }\n\n            if (input.length == 0) {\n                throw new WrongUsageException(\"\");\n            }\n\n            final EntityPlayer player = (EntityPlayer) commandSender;\n            String subcommand = input[0].toLowerCase();\n            String[] arguments = Arrays.copyOfRange(input, 1, input.length);\n            MCA.getLog().info(player.getName() + \" entered debug command \" + Arrays.toString(input));\n\n            switch (subcommand) {\n                case \"help\": displayHelp(commandSender); break;\n                case \"ffh\": forceFullHearts(player); break;\n                case \"fbg\": forceBabyGrow(player); break;\n                case \"fcg\": forceChildGrow(player); break;\n                case \"clv\": clearLoadedVillagers(player);break;\n                case \"inh\": incrementHearts(player); break;\n                case \"deh\": decrementHearts(player); break;\n                case \"sgr\": spawnGrimReaper(player); break;\n                case \"kgr\": killGrimReaper(player); break;\n                case \"dpd\": dumpPlayerData(player); break;\n                case \"rvd\": resetVillagerData(player, arguments); break;\n                case \"rpd\": resetPlayerData(player, arguments); break;\n                case \"cve\": clearVillagerEditors(player); break;\n                default: throw new WrongUsageException(\"\");\n            }\n        } catch (ClassCastException e) {\n            throw new CommandException(\"MCA commands cannot be used through rcon.\");\n        } catch (WrongUsageException e) {\n            throw new CommandException(\"Your command was invalid or improperly formatted. Usage: \" + getUsage(commandSender));\n        }\n    }\n\n    private void forceFullHearts(EntityPlayer player) {\n        for (Entity entity : player.world.loadedEntityList) {\n            if (entity instanceof EntityVillagerMCA) {\n                EntityVillagerMCA villager = (EntityVillagerMCA) entity;\n                villager.getPlayerHistoryFor(player.getUniqueID()).setHearts(100);\n            }\n        }\n        sendMessage(player, Constants.Color.GREEN + \"Forced full hearts on all villagers.\");\n    }\n\n    private void forceBabyGrow(EntityPlayer player) {\n        for (ItemStack stack : player.inventory.mainInventory) {\n            if (stack.getItem() instanceof ItemBaby) {\n                stack.getTagCompound().setInteger(\"age\", MCA.getConfig().babyGrowUpTime);\n            }\n        }\n        sendMessage(player, Constants.Color.GREEN + \"Forced any held babies to grow up age.\");\n    }\n\n    private void forceChildGrow(EntityPlayer player) {\n        player.world.loadedEntityList.stream()\n                .filter(e -> e instanceof EntityVillagerMCA && ((EntityVillagerMCA)e).isChild())\n                .forEach(e -> ((EntityVillagerMCA) e).addGrowth(999999));\n        sendMessage(player, Constants.Color.GREEN + \"Forced any children to grow to adults.\");\n    }\n\n    private void clearLoadedVillagers(EntityPlayer player) {\n        int n = 0;\n        for (Entity entity : player.world.loadedEntityList) {\n            if (entity instanceof EntityVillagerMCA) {\n                entity.setDead();\n                ++n;\n            }\n        }\n        sendMessage(player, Constants.Color.GREEN + \"Cleared \" + n + \" villagers from the world.\");\n    }\n\n    private void incrementHearts(EntityPlayer player) {\n        for (Entity entity : player.world.loadedEntityList) {\n            if (entity instanceof EntityVillagerMCA) {\n                EntityVillagerMCA villager = (EntityVillagerMCA) entity;\n                villager.getPlayerHistoryFor(player.getUniqueID()).changeHearts(10);\n            }\n        }\n        sendMessage(player, Constants.Color.GREEN + \"Increased hearts for all villagers by 10.\");\n    }\n\n    private void decrementHearts(EntityPlayer player) {\n        for (Entity entity : player.world.loadedEntityList) {\n            if (entity instanceof EntityVillagerMCA) {\n                EntityVillagerMCA villager = (EntityVillagerMCA) entity;\n                villager.getPlayerHistoryFor(player.getUniqueID()).changeHearts(-10);\n            }\n        }\n        sendMessage(player, Constants.Color.GREEN + \"Decreased hearts for all villagers by 10.\");\n    }\n\n    private void spawnGrimReaper(EntityPlayer player) {\n        EntityGrimReaper reaper = new EntityGrimReaper(player.world);\n        reaper.setPosition(player.posX, player.posY, player.posZ);\n        player.world.spawnEntity(reaper);\n    }\n\n    private void killGrimReaper(EntityPlayer player) {\n        player.world.loadedEntityList.stream().filter((e) -> e instanceof EntityGrimReaper).forEach((e) -> e.setDead());\n    }\n\n    private void dumpPlayerData(EntityPlayer player) {\n        PlayerSaveData.get(player).dump(player);\n    }\n\n    private void resetVillagerData(EntityPlayer sender, String[] arguments) {\n        Optional<EntityVillagerMCA> target = Util.getEntityByUUID(sender.world, UUID.fromString(arguments[0]), EntityVillagerMCA.class);\n        if (!target.isPresent()) {\n            sendMessage(sender, \"Target villager was not found.\");\n        } else {\n            target.get().reset();\n            sendMessage(sender, target.get().getDisplayName().getUnformattedText() + \" has been reset successfully.\");\n        }\n    }\n\n    private void resetPlayerData(EntityPlayer sender, String[] arguments) {\n        Optional<Entity> target = com.google.common.base.Optional.fromJavaUtil(sender.world.loadedEntityList.stream()\n                .filter(e -> e instanceof EntityPlayer && e.getName().equals(arguments[0]))\n                .findFirst());\n        if (!target.isPresent()) {\n            sendMessage(sender, \"Player not found on the server.\");\n        } else {\n            PlayerSaveData.get((EntityPlayer)target.get()).reset();\n            sendMessage(sender, \"Player data for \" + target.get().getName() + \" has been reset successfully.\");\n            sendMessage(target.get(), \"Your player data has been reset by \" + sender.getName() + \".\");\n        }\n    }\n\n    private void clearVillagerEditors(EntityPlayer sender) {\n        ItemStack editorStack = new ItemStack(ItemsMCA.VILLAGER_EDITOR);\n        sender.world.playerEntities.stream().filter(p -> p.inventory.hasItemStack(editorStack)).forEach(p -> {\n            int i = 0;\n            while (i < p.inventory.getSizeInventory() - 1) {\n                if (p.inventory.getStackInSlot(i).getItem() == ItemsMCA.VILLAGER_EDITOR) {\n                    p.inventory.setInventorySlotContents(i, ItemStack.EMPTY);\n                }\n                i++;\n            }\n        });\n        sendMessage(sender, \"All villager editors cleared from inventories.\");\n    }\n\n    @Override\n    public int getRequiredPermissionLevel() {\n        return 4;\n    }\n\n    private void sendMessage(ICommandSender commandSender, String message) {\n        commandSender.sendMessage(new TextComponentString(Constants.Color.GOLD + \"[MCA] \" + Constants.Format.RESET + message));\n    }\n\n    private void sendMessage(ICommandSender commandSender, String message, boolean noPrefix) {\n        if (noPrefix) {\n            commandSender.sendMessage(new TextComponentString(message));\n        } else {\n            sendMessage(commandSender, message);\n        }\n    }\n\n    private void displayHelp(ICommandSender commandSender) {\n        sendMessage(commandSender, Constants.Color.DARKRED + \"--- \" + Constants.Color.GOLD + \"OP COMMANDS\" + Constants.Color.DARKRED + \" ---\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin ffh \" + Constants.Color.GOLD + \" - Force all hearts on all villagers.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin fbg \" + Constants.Color.GOLD + \" - Force your baby to grow up.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin fcg \" + Constants.Color.GOLD + \" - Force nearby children to grow.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin clv \" + Constants.Color.GOLD + \" - Clear all loaded villagers. \" + Constants.Color.RED + \"(IRREVERSABLE)\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin inh \" + Constants.Color.GOLD + \" - Increase hearts by 10.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin deh \" + Constants.Color.GOLD + \" - Decrease hearts by 10.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin kgr \" + Constants.Color.GOLD + \" - Kill all Grim Reapers in the world.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin dpd \" + Constants.Color.GOLD + \" - Dumps player data to chat.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin rvd <UUID>\" + Constants.Color.GOLD + \" - Resets the given villager.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin rpd <PlayerName>\" + Constants.Color.GOLD + \" - Resets the given player's MCA data.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin cve\" + Constants.Color.GOLD + \" - Remove all villager editors from the game.\", true);\n\n        sendMessage(commandSender, Constants.Color.DARKRED + \"--- \" + Constants.Color.GOLD + \"GLOBAL COMMANDS\" + Constants.Color.DARKRED + \" ---\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca-admin help \" + Constants.Color.GOLD + \" - Shows this list of commands.\", true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/command/CommandMCA.java",
    "content": "package mca.command;\n\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.core.MCAServer;\nimport net.minecraft.command.CommandBase;\nimport net.minecraft.command.CommandException;\nimport net.minecraft.command.ICommandSender;\nimport net.minecraft.command.WrongUsageException;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.server.MinecraftServer;\nimport net.minecraft.util.text.TextComponentString;\n\nimport java.util.Arrays;\n\npublic class CommandMCA extends CommandBase {\n    @Override\n    public String getName() {\n        return \"mca\";\n    }\n\n    @Override\n    public String getUsage(ICommandSender commandSender) {\n        return \"/mca <subcommand> <arguments>\";\n    }\n\n    @Override\n    public void execute(MinecraftServer server, ICommandSender commandSender, String[] input) throws CommandException {\n        try {\n            if (!MCA.getConfig().allowPlayerMarriage) {\n                sendMessage(commandSender, \"MCA commands have been disabled by the server administrator.\");\n                return;\n            }\n\n            if (input.length == 0) {\n                throw new WrongUsageException(\"\");\n            }\n\n            final EntityPlayer player = (EntityPlayer) commandSender;\n            String subcommand = input[0].toLowerCase();\n            String[] arguments = Arrays.copyOfRange(input, 1, input.length);\n            MCA.getLog().info(player.getName() + \" entered command \" + Arrays.toString(input));\n\n            switch (subcommand) {\n                case \"help\":\n                    displayHelp(commandSender);\n                    break;\n                case \"propose\":\n                    EntityPlayer target = player.world.getPlayerEntityByName(arguments[0]);\n                    if (target != null) {\n                        MCAServer.get().sendProposal(player, target);\n                    } else {\n                        player.sendMessage(new TextComponentString(\"Player not found on the server.\"));\n                    }\n                    break;\n                case \"accept\":\n                    target = player.world.getPlayerEntityByName(arguments[0]);\n                    if (target != null) {\n                        MCAServer.get().acceptProposal(player, target);\n                    } else {\n                        player.sendMessage(new TextComponentString(\"Player not found on the server.\"));\n                    }\n                    break;\n                case \"proposals\":\n                    MCAServer.get().listProposals(player);\n                    break;\n                case \"procreate\":\n                    MCAServer.get().procreate(player);\n                    break;\n                case \"separate\":\n                    MCAServer.get().endMarriage(player);\n                    break;\n                case \"reject\":\n                    target = player.world.getPlayerEntityByName(arguments[0]);\n                    if (target != null) {\n                        MCAServer.get().rejectProposal(player, target);\n                    } else {\n                        player.sendMessage(new TextComponentString(\"Player not found on the server.\"));\n                    }\n                    break;\n                default:\n                    throw new WrongUsageException(\"\");\n            }\n        } catch (ClassCastException e) {\n            throw new CommandException(\"MCA commands cannot be used through rcon.\");\n        } catch (WrongUsageException e) {\n            throw new CommandException(\"Your command was invalid or improperly formatted. Usage: \" + getUsage(commandSender));\n        }\n    }\n\n    @Override\n    public int getRequiredPermissionLevel() {\n        return 0;\n    }\n\n    private void sendMessage(ICommandSender commandSender, String message) {\n        commandSender.sendMessage(new TextComponentString(Constants.Color.GOLD + \"[MCA] \" + Constants.Format.RESET + message));\n    }\n\n    private void sendMessage(ICommandSender commandSender, String message, boolean noPrefix) {\n        if (noPrefix) {\n            commandSender.sendMessage(new TextComponentString(message));\n        } else {\n            sendMessage(commandSender, message);\n        }\n    }\n\n    private void displayHelp(ICommandSender commandSender) {\n        sendMessage(commandSender, Constants.Color.DARKRED + \"--- \" + Constants.Color.GOLD + \"PLAYER COMMANDS\" + Constants.Color.DARKRED + \" ---\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca propose <PlayerName>\" + Constants.Color.GOLD + \" - Proposes marriage to the given player.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca proposals \" + Constants.Color.GOLD + \" - Shows all active proposals.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca accept <PlayerName>\" + Constants.Color.GOLD + \" - Accepts the player's marriage request.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca reject <PlayerName>\" + Constants.Color.GOLD + \" - Rejects the player's marriage request.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca procreate \" + Constants.Color.GOLD + \" - Starts procreation.\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca separate \" + Constants.Color.GOLD + \" - Ends your marriage.\", true);\n        sendMessage(commandSender, Constants.Color.DARKRED + \"--- \" + Constants.Color.GOLD + \"GLOBAL COMMANDS\" + Constants.Color.DARKRED + \" ---\", true);\n        sendMessage(commandSender, Constants.Color.WHITE + \" /mca help \" + Constants.Color.GOLD + \" - Shows this list of commands.\", true);\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/core/Config.java",
    "content": "package mca.core;\n\nimport net.minecraftforge.common.config.ConfigElement;\nimport net.minecraftforge.common.config.Configuration;\nimport net.minecraftforge.fml.client.config.IConfigElement;\nimport net.minecraftforge.fml.common.event.FMLPreInitializationEvent;\n\nimport java.io.Serializable;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic final class Config implements Serializable {\n    private transient final Configuration config;\n\n    public boolean overwriteOriginalVillagers;\n    public boolean enableDiminishingReturns;\n    public boolean enableInfection;\n    public int infectionChance;\n    public boolean allowGrimReaper;\n    public int guardSpawnRate;\n    public int chanceToHaveTwins;\n    public int marriageHeartsRequirement;\n    public int roseGoldSpawnWeight;\n    public int babyGrowUpTime;\n    public int childGrowUpTime;\n    public int villagerSpawnerCap;\n    public int villagerSpawnerRateMinutes;\n    public int villagerMaxHealth;\n    public boolean allowTrading;\n    public boolean logVillagerDeaths;\n    public boolean enableRevivals;\n    public String villagerChatPrefix;\n    public boolean allowPlayerMarriage;\n    public boolean enableAdminCommands;\n    public boolean allowCrashReporting;\n    public boolean allowUpdateChecking;\n    public boolean allowRoseGoldGeneration;\n\n    public Config(FMLPreInitializationEvent event) {\n        config = new Configuration(event.getSuggestedConfigurationFile());\n        addConfigValues();\n    }\n\n    private void addConfigValues() {\n        overwriteOriginalVillagers = config.get(\"General\", \"Overwrite Original Villagers?\", true, \"Should original villagers be overwritten by MCA villagers?\").getBoolean();\n        enableDiminishingReturns = config.get(\"General\", \"Enable Interaction Fatigue?\", true, \"Should interactions yield diminishing returns over time?\").getBoolean();\n        enableInfection = config.get(\"General\", \"Enable Zombie Infection?\", true, \"Should zombies be able to infect villagers?\").getBoolean();\n        infectionChance = config.get(\"General\", \"Chance of Infection\", 5, \"Chance that a villager will be infected on hit from a zombie. Default is 5 for 5%.\").getInt();\n        allowGrimReaper = config.get(\"General\", \"Allow Grim Reaper?\", true, \"Should the Grim Reaper boss be enabled?\").getBoolean();\n        guardSpawnRate = config.get(\"General\", \"Guard Spawn Rate\", 6, \"How many villagers that should be in a village before a guard spawns.\").getInt();\n        chanceToHaveTwins = config.get(\"General\", \"Chance to Have Twins\", 2, \"Chance that you will have twins. Default is 2 for 2%.\").getInt();\n        marriageHeartsRequirement = config.get(\"General\", \"Marriage Hearts Requirement\", 100, \"Number of hearts required to get married.\").getInt();\n        roseGoldSpawnWeight = config.get(\"General\", \"Rose Gold Spawn Weight\", 6, \"Spawn weights for Rose Gold\").getInt();\n        babyGrowUpTime = config.get(\"General\", \"Baby Grow Up Time (Minutes)\", 30, \"Minutes it takes for a baby to be ready to grow up.\").getInt();\n        childGrowUpTime = config.get(\"General\", \"Child Grow Up Time (Minutes)\", 60, \"Minutes it takes for a child to grow into an adult.\").getInt();\n        villagerSpawnerCap = config.get(\"General\", \"Villager Spawner Cap\", 5, \"Maximum number of villagers that a spawner will create in the area before it stops.\").getInt();\n        villagerSpawnerRateMinutes = config.get(\"General\", \"Villager Spawner Rate\", 30, \"The spawner will spawn 1 villager per this many minutes.\").getInt();\n        allowTrading = config.get(\"General\", \"Enable Trading?\", true, \"Is trading with villagers enabled?\").getBoolean();\n        logVillagerDeaths = config.get(\"General\", \"Log Villager Deaths?\", true, \"Should villager deaths be logged?\").getBoolean();\n        enableRevivals = config.get(\"General\", \"Enable Revivals?\", true, \"Should reviving dead villagers be enabled?\").getBoolean();\n        villagerChatPrefix = config.get(\"General\", \"Villager Chat Prefix\", \"\", \"Formatting prefix used for all chat with villagers.\").getString();\n        allowPlayerMarriage = config.get(\"General\", \"Allow Player Marriage?\", true, \"Enables or disables player marriage.\").getBoolean();\n        enableAdminCommands = config.get(\"General\", \"Enable Admin Commands?\", true, \"Enables or disables MCA admin commands for ops.\").getBoolean();\n        allowCrashReporting = config.get(\"General\", \"Allow Crash Reporting?\", true, \"If enabled, sends crash reports to MCA developers.\").getBoolean();\n        allowUpdateChecking = config.get(\"General\", \"Allow Update Checking?\", true, \"If enabled, notifies you when an update to MCA is available.\").getBoolean();\n        allowRoseGoldGeneration = config.get(\"General\", \"Allow Rose Gold World Generation\", true, \"If enabled, generates rose gold in your world. If disabled, generates stone instead.\").getBoolean();\n        villagerMaxHealth = config.get(\"General\", \"Villager Max Health\", 20, \"Each villager's maximum health. 1 point equals 1 heart.\").getInt();\n        config.save();\n    }\n\n    public Configuration getInstance() {\n        return config;\n    }\n\n    public List<IConfigElement> getCategories() {\n        List<IConfigElement> elements = new ArrayList<>();\n\n        for (String s : config.getCategoryNames()) {\n            if (s.equals(\"server\")) continue;\n\n            IConfigElement element = new ConfigElement(config.getCategory(s));\n            elements.addAll(element.getChildElements());\n        }\n\n        return elements;\n    }\n}"
  },
  {
    "path": "src/main/java/mca/core/Constants.java",
    "content": "package mca.core;\n\nimport java.util.UUID;\n\npublic class Constants {\n    public static final int GUI_ID_INTERACT = 1;\n    public static final int GUI_ID_NAMEBABY = 2;\n    public static final int GUI_ID_INVENTORY = 3;\n    public static final int GUI_ID_STAFFOFLIFE = 4;\n    public static final int GUI_ID_VILLAGEREDITOR = 5;\n    public static final int GUI_ID_GUIDEBOOK = 6;\n    public static final int GUI_ID_WHISTLE = 7;\n    public static final UUID ZERO_UUID = new UUID(0, 0);\n    private static final String SECTION_SIGN = \"\\u00a7\";\n\n    public static final int GUI_SCREEN_BUTTON_LIST_FIELD_INDEX = 7;\n\n    /**\n     * All possible font colors\n     */\n    public final class Color {\n        public static final String BLACK = SECTION_SIGN + \"0\";\n        public static final String DARKBLUE = SECTION_SIGN + \"1\";\n        public static final String DARKGREEN = SECTION_SIGN + \"2\";\n        public static final String DARKAQUA = SECTION_SIGN + \"3\";\n        public static final String DARKRED = SECTION_SIGN + \"4\";\n        public static final String PURPLE = SECTION_SIGN + \"5\";\n        public static final String GOLD = SECTION_SIGN + \"6\";\n        public static final String GRAY = SECTION_SIGN + \"7\";\n        public static final String DARKGRAY = SECTION_SIGN + \"8\";\n        public static final String BLUE = SECTION_SIGN + \"9\";\n        public static final String GREEN = SECTION_SIGN + \"A\";\n        public static final String AQUA = SECTION_SIGN + \"B\";\n        public static final String RED = SECTION_SIGN + \"C\";\n        public static final String LIGHTPURPLE = SECTION_SIGN + \"D\";\n        public static final String YELLOW = SECTION_SIGN + \"E\";\n        public static final String WHITE = SECTION_SIGN + \"F\";\n    }\n\n    /**\n     * All possible font formats.\n     */\n    public final class Format {\n        public static final String OBFUSCATED = SECTION_SIGN + \"k\";\n        public static final String BOLD = SECTION_SIGN + \"l\";\n        public static final String STRIKE = SECTION_SIGN + \"m\";\n        public static final String UNDERLINE = SECTION_SIGN + \"n\";\n        public static final String ITALIC = SECTION_SIGN + \"o\";\n        public static final String RESET = SECTION_SIGN + \"r\";\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/core/Localizer.java",
    "content": "package mca.core;\n\nimport com.google.common.base.Charsets;\nimport net.minecraft.util.StringUtils;\nimport org.apache.commons.io.IOUtils;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.util.*;\nimport java.util.stream.Collectors;\n\npublic class Localizer {\n    private Map<String, String> localizerMap = new HashMap<>();\n    private static final ArrayList<String> EMPTY_LIST = new ArrayList<>();\n\n    public Localizer() {\n        InputStream inStream = StringUtils.class.getResourceAsStream(\"/assets/mca/lang/en_us.lang\");\n\n        try {\n            List<String> lines = IOUtils.readLines(inStream, Charsets.UTF_8);\n\n            for (String line : lines) {\n                if (line.startsWith(\"#\") || line.isEmpty()) {\n                    continue;\n                }\n\n                String[] split = line.split(\"\\\\=\");\n                String key = split[0];\n                String value = split[1];\n\n                localizerMap.put(key, value);\n            }\n        } catch (IOException e) {\n            MCA.getLog().error(\"Error initializing localizer: \" + e);\n        }\n    }\n\n    public String localize(String key, String... vars) {\n        ArrayList<String> list = new ArrayList<>();\n        Collections.addAll(list, vars);\n        return localize(key, vars != null ? list : EMPTY_LIST);\n    }\n\n    public String localize(String key, ArrayList<String> vars) {\n        String result = localizerMap.getOrDefault(key, key);\n        if (result.equals(key)) {\n            List<String> responses = localizerMap.entrySet().stream().filter(entry -> entry.getKey().contains(key)).map(Map.Entry::getValue).collect(Collectors.toList());\n            if (responses.size() > 0) result = responses.get(new Random().nextInt(responses.size()));\n        }\n\n        return parseVars(result, vars).replaceAll(\"\\\\\\\\\", \"\");\n    }\n\n    private String parseVars(String str, ArrayList<String> vars) {\n        int index = 1;\n        str = str.replaceAll(\"%Supporter%\", MCA.getInstance().getRandomSupporter());\n\n        String varString = \"%v\" + index + \"%\";\n        while (str.contains(\"%v\") && index < 10) { // signature of a var being present\n            try {\n                str = str.replaceAll(varString, vars.get(index - 1));\n            } catch (IndexOutOfBoundsException e) {\n                str = str.replaceAll(varString, \"\");\n                MCA.getLog().warn(\"Failed to replace variable in localized string: \" + str);\n            } finally {\n                index++;\n                varString = \"%v\" + index + \"%\";\n            }\n        }\n\n        return str;\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/core/MCA.java",
    "content": "package mca.core;\n\nimport com.google.gson.Gson;\nimport mca.api.API;\nimport mca.command.CommandAdminMCA;\nimport mca.command.CommandMCA;\nimport mca.core.forge.EventHooks;\nimport mca.core.forge.GuiHandler;\nimport mca.core.forge.NetMCA;\nimport mca.core.forge.ServerProxy;\nimport mca.core.minecraft.ItemsMCA;\nimport mca.core.minecraft.ProfessionsMCA;\nimport mca.core.minecraft.RoseGoldOreGenerator;\nimport mca.entity.EntityGrimReaper;\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumGender;\nimport mca.util.Util;\nimport net.minecraft.creativetab.CreativeTabs;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.ResourceLocation;\nimport net.minecraftforge.common.MinecraftForge;\nimport net.minecraftforge.fml.common.FMLCommonHandler;\nimport net.minecraftforge.fml.common.Mod;\nimport net.minecraftforge.fml.common.Mod.EventHandler;\nimport net.minecraftforge.fml.common.SidedProxy;\nimport net.minecraftforge.fml.common.event.*;\nimport net.minecraftforge.fml.common.network.NetworkRegistry;\nimport net.minecraftforge.fml.common.registry.EntityRegistry;\nimport net.minecraftforge.fml.common.registry.GameRegistry;\nimport org.apache.commons.io.FileUtils;\nimport org.apache.logging.log4j.Logger;\n\nimport java.io.*;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.net.URLConnection;\nimport java.nio.charset.StandardCharsets;\nimport java.util.*;\n\n@Mod(modid = MCA.MODID, name = MCA.NAME, version = MCA.VERSION, guiFactory = \"mca.client.MCAGuiFactory\")\npublic class MCA {\n    public static final String MODID = \"mca\";\n    public static final String NAME = \"Minecraft Comes Alive\";\n    public static final String VERSION = \"6.0.1\";\n    @SidedProxy(clientSide = \"mca.core.forge.ClientProxy\", serverSide = \"mca.core.forge.ServerProxy\")\n    public static ServerProxy proxy;\n    public static CreativeTabs creativeTab;\n    @Mod.Instance\n    private static MCA instance;\n    private static Logger logger;\n    private static Localizer localizer;\n    private static Config config;\n    private static long startupTimestamp;\n    public static String latestVersion = \"\";\n    public static boolean updateAvailable = false;\n    public String[] supporters = new String[0];\n\n    public static Logger getLog() {\n        return logger;\n    }\n\n    public static MCA getInstance() {\n        return instance;\n    }\n\n    public static Localizer getLocalizer() {\n        return localizer;\n    }\n\n    public static Config getConfig() {\n        return config;\n    }\n\n    public static long getStartupTimestamp() {\n        return startupTimestamp;\n    }\n\n    @EventHandler\n    public void preInit(FMLPreInitializationEvent event) {\n        startupTimestamp = new Date().getTime();\n        instance = this;\n        logger = event.getModLog();\n        proxy.registerEntityRenderers();\n        localizer = new Localizer();\n        config = new Config(event);\n        creativeTab = new CreativeTabs(\"MCA\") {\n            @Override\n            public ItemStack getTabIconItem() {\n                return new ItemStack(ItemsMCA.ENGAGEMENT_RING);\n            }\n        };\n        MinecraftForge.EVENT_BUS.register(new EventHooks());\n        NetworkRegistry.INSTANCE.registerGuiHandler(this, new GuiHandler());\n        NetMCA.registerMessages();\n\n        if (MCA.getConfig().allowUpdateChecking) {\n            latestVersion = Util.httpGet(\"https://minecraftcomesalive.com/api/latest\");\n            if (!latestVersion.equals(VERSION) && !latestVersion.equals(\"\")) {\n                updateAvailable = true;\n                MCA.getLog().warn(\"An update for Minecraft Comes Alive is available: v\" + latestVersion);\n            }\n        }\n\n        supporters = Util.httpGet(\"https://minecraftcomesalive.com/api/supporters\").split(\",\");\n        MCA.getLog().info(\"Loaded \" + supporters.length + \" supporters.\");\n    }\n\n    @EventHandler\n    public void init(FMLInitializationEvent event) {\n        GameRegistry.registerWorldGenerator(new RoseGoldOreGenerator(), MCA.getConfig().roseGoldSpawnWeight);\n        EntityRegistry.registerModEntity(new ResourceLocation(MODID, \"EntityVillagerMCA\"), EntityVillagerMCA.class, EntityVillagerMCA.class.getSimpleName(), 1120, this, 50, 2, true);\n        EntityRegistry.registerModEntity(new ResourceLocation(MODID, \"GrimReaperMCA\"), EntityGrimReaper.class, EntityGrimReaper.class.getSimpleName(), 1121, this, 50, 2, true);\n        ProfessionsMCA.registerCareers();\n\n        proxy.registerModelMeshers();\n        ItemsMCA.assignCreativeTabs();\n    }\n\n    @EventHandler\n    public void postInit(FMLPostInitializationEvent event) {\n        API.init();\n    }\n\n    @EventHandler\n    public void serverStarting(FMLServerStartingEvent event) {\n        event.registerServerCommand(new CommandMCA());\n        event.registerServerCommand(new CommandAdminMCA());\n    }\n\n    @EventHandler\n    public void serverStopping(FMLServerStoppingEvent event) {\n        checkForCrashReports();\n    }\n\n    public String getRandomSupporter() {\n        if (supporters.length > 0) {\n            return supporters[new Random().nextInt(supporters.length)];\n        } else {\n            return API.getRandomName(EnumGender.getRandom());\n        }\n    }\n\n    public void checkForCrashReports() {\n        if (MCA.getConfig().allowCrashReporting) {\n            File crashReportsFolder = new File(System.getProperty(\"user.dir\") + \"/crash-reports/\");\n            File[] crashReportFiles = crashReportsFolder.listFiles(File::isFile);\n            try {\n                if (crashReportFiles != null) {\n                    Optional<File> newestFile = Arrays.stream(crashReportFiles).max(Comparator.comparingLong(File::lastModified));\n                    if (newestFile.isPresent() && newestFile.get().lastModified() > startupTimestamp) {\n                        // Raw Java for sending the POST request as the HttpClient from Apache libs is not present on servers.\n                        MCA.getLog().warn(\"Crash detected! Attempting to upload report...\");\n                        Map<String, String> payload = new HashMap<>();\n                        payload.put(\"minecraft_version\", FMLCommonHandler.instance().getMinecraftServerInstance().getMinecraftVersion());\n                        payload.put(\"operating_system\", System.getProperty(\"os.name\") + \" (\" + System.getProperty(\"os.arch\") + \") version \" + System.getProperty(\"os.version\"));\n                        payload.put(\"java_version\", System.getProperty(\"java.version\") + \", \" + System.getProperty(\"java.vendor\"));\n                        payload.put(\"mod_version\", MCA.VERSION);\n                        payload.put(\"body\", FileUtils.readFileToString(newestFile.get(), \"UTF-8\"));\n\n                        byte[] out = new Gson().toJson(payload).getBytes(StandardCharsets.UTF_8);\n                        URL url = new URL(\"http://minecraftcomesalive.com/api/crash-reports\");\n                        URLConnection con = url.openConnection();\n                        HttpURLConnection http = (HttpURLConnection)con;\n                        http.setRequestMethod(\"POST\");\n                        http.setDoOutput(true);\n                        http.setFixedLengthStreamingMode(out.length);\n                        http.setRequestProperty(\"Content-Type\", \"application/json; charset=UTF-8\");\n                        http.setRequestProperty(\"User-Agent\", \"Minecraft Client \" + FMLCommonHandler.instance().getMinecraftServerInstance().getMinecraftVersion());\n                        http.connect();\n                        OutputStream os = http.getOutputStream();\n                        os.write(out);\n                        os.flush();\n                        os.close();\n                        if (http.getResponseCode() != 200) {\n                            MCA.getLog().error(\"Failed to submit crash report. Non-OK response code returned: \" + http.getResponseCode());\n                        } else {\n                            MCA.getLog().warn(\"Crash report submitted successfully.\");\n                        }\n                    }\n                }\n            } catch (IOException e) {\n                MCA.getLog().error(\"An unexpected error occurred while attempting to submit the crash report.\", e);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/core/MCAServer.java",
    "content": "package mca.core;\n\nimport mca.core.minecraft.ItemsMCA;\nimport mca.core.minecraft.VillageHelper;\nimport mca.entity.EntityGrimReaper;\nimport mca.entity.EntityVillagerMCA;\nimport mca.entity.data.PlayerSaveData;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.effect.EntityLightningBolt;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.math.BlockPos;\nimport net.minecraft.util.text.TextComponentString;\nimport net.minecraft.world.World;\nimport net.minecraftforge.fml.common.FMLCommonHandler;\n\nimport java.util.*;\n\npublic class MCAServer {\n    private static MCAServer instance;\n    // Maps a player's UUID to a list of UUIDs that have proposed to them with /mca propose\n    private static Map<UUID, List<UUID>> proposals;\n    // List of UUIDs that initiated procreation mapped to the time the request expires.\n    private static Map<UUID, Long> procreateMap;\n    private int serverTicks = 0;\n    private int reaperSummonTicks = 0;\n    private BlockPos reaperSpawnPos = BlockPos.ORIGIN;\n    private World reaperSpawnWorld = null;\n\n    private MCAServer() {\n        proposals = new HashMap<>();\n        procreateMap = new HashMap<>();\n    }\n\n    public static MCAServer get() {\n        if (instance == null) {\n            instance = new MCAServer();\n        }\n        return instance;\n    }\n\n    public void tick() {\n        serverTicks++;\n\n        if (serverTicks >= 100) {\n            World overworld = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld(0);\n            VillageHelper.tick(overworld);\n            serverTicks = 0;\n        }\n\n        if (reaperSummonTicks > 0) {\n            reaperSummonTicks--;\n            if (reaperSummonTicks % 20 == 0) { // every second\n                EntityLightningBolt lightningBolt = new EntityLightningBolt(reaperSpawnWorld, reaperSpawnPos.getX(), reaperSpawnPos.getY(), reaperSpawnPos.getZ(), false);\n                reaperSpawnWorld.addWeatherEffect(lightningBolt);\n            }\n\n            if (reaperSummonTicks == 0) { // when counter reaches 0\n                EntityGrimReaper reaper = new EntityGrimReaper(reaperSpawnWorld);\n                reaper.setPosition(reaperSpawnPos.getX(), reaperSpawnPos.getY(), reaperSpawnPos.getZ());\n                reaperSpawnWorld.spawnEntity(reaper);\n            }\n        }\n\n        // Collect all expired procreate requests and remove them.\n        List<UUID> removals = new ArrayList<>();\n        procreateMap.keySet().stream()\n                .filter((k) -> procreateMap.get(k) < System.currentTimeMillis())\n                .forEach(removals::add);\n        removals.forEach(procreateMap::remove);\n    }\n\n    /**\n     * Returns true if receiver has a proposal from sender.\n     *\n     * @param sender   Command sender\n     * @param receiver Player whose name was entered by the sender\n     * @return boolean\n     */\n    private boolean hasProposalFrom(EntityPlayer sender, EntityPlayer receiver) {\n        return getProposalsFor(receiver).contains(sender.getUniqueID());\n    }\n\n    /**\n     * Returns all proposals for the provided player\n     *\n     * @param player Player whose proposals should be returned.\n     * @return List<UUID>\n     */\n    private List<UUID> getProposalsFor(EntityPlayer player) {\n        return proposals.getOrDefault(player.getUniqueID(), new ArrayList<>());\n    }\n\n    /**\n     * Removes the provided proposer from the target's list of proposals.\n     *\n     * @param target   Target player who's proposal list will be modified.\n     * @param proposer The proposer to the target player.\n     */\n    private void removeProposalFor(EntityPlayer target, EntityPlayer proposer) {\n        List<UUID> list = getProposalsFor(target);\n        list.remove(proposer.getUniqueID());\n        proposals.put(target.getUniqueID(), list);\n    }\n\n    /**\n     * Lists all proposals for the given player.\n     *\n     * @param sender Player whose active proposals will be listed.\n     */\n    public void listProposals(EntityPlayer sender) {\n        List<UUID> proposals = getProposalsFor(sender);\n\n        if (proposals.size() == 0) {\n            infoMessage(sender, \"You have no active proposals.\");\n        } else {\n            infoMessage(sender, \"You have active proposals from: \");\n        }\n\n        // Send the name of all online players to the command sender.\n        proposals.forEach((uuid -> {\n            EntityPlayer player = sender.world.getPlayerEntityByUUID(uuid);\n            if (player != null) {\n                infoMessage(sender, \"- \" + player.getName());\n            }\n        }));\n    }\n\n    /**\n     * Sends a proposal from the sender to the receiver.\n     *\n     * @param sender   The player sending the proposal.\n     * @param receiver The player being proposed to.\n     */\n    public void sendProposal(EntityPlayer sender, EntityPlayer receiver) {\n        // Ensure the sender isn't already married.\n        if (PlayerSaveData.get(sender).isMarriedOrEngaged()) {\n            failMessage(sender, \"You cannot send a proposal since you are already married or engaged.\");\n            return;\n        }\n\n        // Ensure the sender isn't himself.\n        if (sender == receiver) {\n            failMessage(sender, \"You cannot propose to yourself.\");\n            return;\n        }\n\n        // Ensure the receiver hasn't already been proposed to by this player.\n        if (hasProposalFrom(sender, receiver)) {\n            failMessage(sender, \"You have already sent a proposal to \" + receiver.getName());\n        } else {\n            // Send the proposal messages.\n            successMessage(sender, \"Your proposal to \" + receiver.getName() + \" has been sent!\");\n            infoMessage(receiver, sender.getName() + \" has proposed marriage. To accept, type /mca accept \" + sender.getName());\n\n            // Add the proposal to the receiver's proposal list.\n            List<UUID> list = getProposalsFor(receiver);\n            list.add(sender.getUniqueID());\n            proposals.put(receiver.getUniqueID(), list);\n        }\n    }\n\n    /**\n     * Rejects and removes a proposal from the receiver to the sender.\n     *\n     * @param sender   The person rejecting the proposal.\n     * @param receiver The initial proposer.\n     */\n    public void rejectProposal(EntityPlayer sender, EntityPlayer receiver) {\n        // Ensure a proposal existed.\n        if (!hasProposalFrom(receiver, sender)) {\n            failMessage(sender, receiver.getName() + \" hasn't proposed to you.\");\n        } else {\n            // Notify of the proposal failure and remove it.\n            successMessage(sender, \"Your rejection has been sent.\");\n            failMessage(receiver, sender.getName() + \" rejected your proposal.\");\n            removeProposalFor(sender, receiver);\n        }\n    }\n\n    /**\n     * Accepts and removes a proposal from the receiver to the sender.\n     *\n     * @param sender   The person accepting the proposal.\n     * @param receiver The initial proposer.\n     */\n    public void acceptProposal(EntityPlayer sender, EntityPlayer receiver) {\n        // Ensure a proposal is active.\n        if (!hasProposalFrom(receiver, sender)) {\n            failMessage(sender, receiver.getName() + \" hasn't proposed to you.\");\n        } else {\n            // Notify of acceptance.\n            successMessage(receiver, sender.getName() + \" has accepted your proposal!\");\n\n            // Set both player datas as married.\n            PlayerSaveData senderData = PlayerSaveData.get(sender);\n            PlayerSaveData receiverData = PlayerSaveData.get(receiver);\n            senderData.marry(receiver.getUniqueID(), receiver.getName());\n            receiverData.marry(sender.getUniqueID(), sender.getName());\n\n            // Send success messages.\n            successMessage(sender, \"You and \" + receiver.getName() + \" are now married.\");\n            successMessage(receiver, \"You and \" + sender.getName() + \" are now married.\");\n\n            // Remove the proposal.\n            removeProposalFor(sender, receiver);\n        }\n    }\n\n    /**\n     * Ends the sender's marriage and notifies their spouse if the spouse is online.\n     *\n     * @param sender The person ending their marriage.\n     */\n    public void endMarriage(EntityPlayer sender) {\n        // Retrieve all data instances and an instance of the ex-spouse if they are present.\n        PlayerSaveData senderData = PlayerSaveData.get(sender);\n\n        // Ensure the sender is married\n        if (!senderData.isMarriedOrEngaged()) {\n            failMessage(sender, \"You are not married.\");\n            return;\n        }\n\n        // Lookup the spouse, if it's a villager, we can't continue\n        Optional<Entity> spouse = sender.world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(senderData.getSpouseUUID())).findFirst();\n        if (spouse.isPresent() && spouse.get() instanceof EntityVillagerMCA) {\n            failMessage(sender, \"You cannot use this command when married to a villager.\");\n            return;\n        }\n\n        PlayerSaveData receiverData = PlayerSaveData.getExisting(sender.world, senderData.getSpouseUUID());\n\n        // Notify the sender of the success and end both marriages.\n        successMessage(sender, \"Your marriage to \" + senderData.getSpouseName() + \" has ended.\");\n        senderData.endMarriage();\n        receiverData.endMarriage();\n\n        // Notify the ex if they are online.\n        spouse.ifPresent(e -> failMessage((EntityPlayer) e, sender.getName() + \" has ended their marriage with you.\"));\n    }\n\n    /**\n     * Initiates procreation with a married player.\n     *\n     * @param sender The person requesting procreation.\n     */\n    public void procreate(EntityPlayer sender) {\n        // Ensure the sender is married.\n        PlayerSaveData senderData = PlayerSaveData.get(sender);\n        if (!senderData.isMarriedOrEngaged()) {\n            failMessage(sender, \"You cannot procreate if you are not married.\");\n            return;\n        }\n\n        // Ensure we don't already have a baby\n        if (senderData.isBabyPresent()) {\n            failMessage(sender, \"You already have a baby.\");\n            return;\n        }\n\n        // Ensure the spouse is online.\n        EntityPlayer spouse = sender.world.getPlayerEntityByUUID(senderData.getSpouseUUID());\n        if (spouse != null) {\n            // If the spouse is online and has previously sent a procreation request that hasn't expired, we can continue.\n            // Otherwise we notify the spouse that they must also enter the command.\n            if (!procreateMap.containsKey(spouse.getUniqueID())) {\n                procreateMap.put(sender.getUniqueID(), System.currentTimeMillis() + 10000);\n                infoMessage(spouse, sender.getName() + \" has requested procreation. To accept, type /mca procreate within 10 seconds.\");\n            } else {\n                // On success, add a randomly generated baby to the original requester.\n                successMessage(sender, \"Procreation successful!\");\n                successMessage(spouse, \"Procreation successful!\");\n                spouse.addItemStackToInventory(new ItemStack(sender.world.rand.nextBoolean() ? ItemsMCA.BABY_BOY : ItemsMCA.BABY_GIRL));\n\n                PlayerSaveData spouseData = PlayerSaveData.get(spouse);\n                spouseData.setBabyPresent(true);\n                senderData.setBabyPresent(true);\n            }\n        } else {\n            failMessage(sender, \"Your spouse is not present on the server.\");\n        }\n    }\n\n    private void successMessage(EntityPlayer player, String message) {\n        player.sendMessage(new TextComponentString(Constants.Color.GREEN + message));\n    }\n\n    private void failMessage(EntityPlayer player, String message) {\n        player.sendMessage(new TextComponentString(Constants.Color.RED + message));\n    }\n\n    private void infoMessage(EntityPlayer player, String message) {\n        player.sendMessage(new TextComponentString(Constants.Color.YELLOW + message));\n    }\n\n    public void setReaperSpawnPos(World world, BlockPos pos) {\n        this.reaperSpawnWorld = world;\n        this.reaperSpawnPos = pos;\n    }\n\n    public void startSpawnReaper() {\n        this.reaperSummonTicks = 20 * 4; // 3 seconds\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/core/forge/ClientProxy.java",
    "content": "package mca.core.forge;\n\nimport mca.client.render.RenderReaperFactory;\nimport mca.client.render.RenderVillagerFactory;\nimport mca.core.minecraft.BlocksMCA;\nimport mca.core.minecraft.ItemsMCA;\nimport mca.entity.EntityGrimReaper;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraftforge.fml.client.registry.RenderingRegistry;\n\npublic class ClientProxy extends ServerProxy {\n    @Override\n    public void registerEntityRenderers() {\n        RenderingRegistry.registerEntityRenderingHandler(EntityVillagerMCA.class, RenderVillagerFactory.INSTANCE);\n        RenderingRegistry.registerEntityRenderingHandler(EntityGrimReaper.class, RenderReaperFactory.INSTANCE);\n    }\n\n    @Override\n    public void registerModelMeshers() {\n        ItemsMCA.registerModelMeshers();\n        BlocksMCA.registerModelMeshers();\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/core/forge/EventHooks.java",
    "content": "package mca.core.forge;\n\nimport mca.client.network.ClientMessageQueue;\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.core.MCAServer;\nimport mca.core.minecraft.BlocksMCA;\nimport mca.core.minecraft.ItemsMCA;\nimport mca.core.minecraft.ProfessionsMCA;\nimport mca.core.minecraft.WorldEventListenerMCA;\nimport mca.entity.EntityVillagerMCA;\nimport mca.items.ItemBaby;\nimport net.minecraft.block.Block;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.EntityLivingBase;\nimport net.minecraft.entity.monster.EntityMob;\nimport net.minecraft.entity.passive.EntityVillager;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.init.Blocks;\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.stats.StatList;\nimport net.minecraft.util.EnumActionResult;\nimport net.minecraft.util.math.BlockPos;\nimport net.minecraft.util.text.TextComponentString;\nimport net.minecraft.util.text.event.ClickEvent;\nimport net.minecraft.world.World;\nimport net.minecraftforge.event.RegistryEvent;\nimport net.minecraftforge.event.entity.EntityJoinWorldEvent;\nimport net.minecraftforge.event.entity.PlaySoundAtEntityEvent;\nimport net.minecraftforge.event.entity.item.ItemTossEvent;\nimport net.minecraftforge.event.entity.living.LivingDamageEvent;\nimport net.minecraftforge.event.entity.living.LivingDeathEvent;\nimport net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;\nimport net.minecraftforge.event.entity.player.PlayerInteractEvent;\nimport net.minecraftforge.event.world.BlockEvent;\nimport net.minecraftforge.event.world.WorldEvent;\nimport net.minecraftforge.fml.common.FMLCommonHandler;\nimport net.minecraftforge.fml.common.eventhandler.Event;\nimport net.minecraftforge.fml.common.eventhandler.SubscribeEvent;\nimport net.minecraftforge.fml.common.gameevent.PlayerEvent;\nimport net.minecraftforge.fml.common.gameevent.TickEvent;\nimport net.minecraftforge.fml.common.registry.GameRegistry;\nimport net.minecraftforge.fml.relauncher.Side;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Optional;\nimport java.util.UUID;\n\npublic class EventHooks {\n    // Maps a player UUID to the itemstack of their held ItemBaby. Filled when a player dies so the baby is never lost.\n    public Map<UUID, ItemStack> limbo = new HashMap<>();\n\n    @SubscribeEvent\n    public void onRegisterItems(RegistryEvent.Register<Item> event) {\n        ItemsMCA.register(event);\n        BlocksMCA.registerItemBlocks(event);\n\n        GameRegistry.addSmelting(BlocksMCA.ROSE_GOLD_ORE, new ItemStack(ItemsMCA.ROSE_GOLD_INGOT), 5.0F);\n    }\n\n    @SubscribeEvent\n    public void onRegisterBlocks(RegistryEvent.Register<Block> event) {\n        BlocksMCA.register(event);\n    }\n\n    @SubscribeEvent\n    public void onWorldLoad(WorldEvent.Load event) {\n        if (event.getWorld().isRemote) event.getWorld().addEventListener(new WorldEventListenerMCA());\n    }\n\n    @SubscribeEvent\n    public void onClientTick(TickEvent.ClientTickEvent event) {\n        ClientMessageQueue.processScheduledMessages();\n    }\n\n    @SubscribeEvent\n    public void onServerTick(TickEvent.ServerTickEvent event) {\n        MCAServer.get().tick();\n    }\n\n    @SubscribeEvent\n    public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {\n        if (!MCA.updateAvailable) return;\n        TextComponentString updateMessage = new TextComponentString(Constants.Color.DARKGREEN + \"An update for Minecraft Comes Alive is available: v\" + MCA.latestVersion);\n        String updateURLText = Constants.Color.YELLOW + \"Click \" + Constants.Color.BLUE + Constants.Format.ITALIC + Constants.Format.UNDERLINE + \"here\" + Constants.Format.RESET + Constants.Color.YELLOW + \" to download the update.\";\n\n        TextComponentString chatComponentUpdate = new TextComponentString(updateURLText);\n        chatComponentUpdate.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, \"https://minecraftcomesalive.com/download\"));\n        chatComponentUpdate.getStyle().setUnderlined(true);\n\n        event.player.sendMessage(updateMessage);\n        event.player.sendMessage(chatComponentUpdate);\n\n        MCA.updateAvailable = false;\n    }\n\n    @SubscribeEvent\n    public void onWorldUnload(WorldEvent.Unload event) {\n        // Only send crash reports on unloading the overworld. This will never change based on other mods installed\n        // and ensures only one crash report is sent per instance.\n        if (!event.getWorld().isRemote && event.getWorld().provider.getDimension() == 0) MCA.getInstance().checkForCrashReports();\n    }\n\n    @SubscribeEvent\n    public void onEntityJoinWorld(EntityJoinWorldEvent event) {\n        World world = event.getWorld();\n        Entity entity = event.getEntity();\n\n        if (world.isRemote) return;\n        if (!MCA.getConfig().overwriteOriginalVillagers) return;\n\n        if (entity.getClass().equals(EntityVillager.class)) {\n            EntityVillager originalVillager = (EntityVillager) entity;\n            originalVillager.setDead();\n\n            EntityVillagerMCA newVillager = new EntityVillagerMCA(world, com.google.common.base.Optional.of(originalVillager.getProfessionForge()), com.google.common.base.Optional.absent());\n            newVillager.setPosition(originalVillager.posX, originalVillager.posY, originalVillager.posZ);\n            newVillager.finalizeMobSpawn(world.getDifficultyForLocation(newVillager.getPos()), null, false);\n            newVillager.forcePositionAsHome();\n            world.spawnEntity(newVillager);\n        }\n    }\n\n    @SubscribeEvent\n    public void onEntityInteractSpecific(PlayerInteractEvent.EntityInteractSpecific event) {\n        if (event.getTarget() instanceof EntityVillagerMCA && event.getEntityPlayer() != null) {\n            EntityPlayer player = event.getEntityPlayer();\n            EntityVillagerMCA villager = (EntityVillagerMCA)event.getTarget();\n\n            if (villager.getProfessionForge() == ProfessionsMCA.bandit) {\n                event.setResult(Event.Result.DENY);\n            } else if (player.getHeldItemMainhand().getItem() == ItemsMCA.VILLAGER_EDITOR) {\n                player.openGui(MCA.getInstance(), Constants.GUI_ID_VILLAGEREDITOR, player.world, villager.getEntityId(), 0, 0);\n                event.setResult(Event.Result.ALLOW);\n            } else {\n                player.addStat(StatList.TALKED_TO_VILLAGER);\n                player.openGui(MCA.getInstance(), Constants.GUI_ID_INTERACT, player.world, villager.getEntityId(), 0, 0);\n                event.setResult(Event.Result.ALLOW);\n            }\n        }\n    }\n\n    @SubscribeEvent\n    public void onEntityDamaged(LivingDamageEvent event) {\n        if (event.getEntity() instanceof EntityVillagerMCA) {\n            EntityVillagerMCA villager = (EntityVillagerMCA)event.getEntity();\n            Entity source = event.getSource() != null ? event.getSource().getTrueSource() : null;\n\n            if (source instanceof EntityLivingBase) {\n                villager.world.loadedEntityList.stream().filter(e ->\n                        e instanceof EntityVillagerMCA &&\n                        e.getDistance(villager) <= 10.0D &&\n                        ((EntityVillagerMCA)e).getProfessionForge() == ProfessionsMCA.guard)\n                .forEach(e -> ((EntityVillagerMCA) e).setAttackTarget((EntityLivingBase)source));\n            }\n        }\n    }\n\n    @SubscribeEvent\n    public void onItemToss(ItemTossEvent event) {\n        ItemStack stack = event.getEntityItem().getItem();\n        if (stack.getItem() instanceof ItemBaby) {\n            event.getPlayer().addItemStackToInventory(stack);\n            event.setCanceled(true);\n        }\n    }\n\n    @SubscribeEvent\n    public void onPlaceEvent(BlockEvent.PlaceEvent event) {\n        int x = event.getPos().getX();\n        int y = event.getPos().getY();\n        int z = event.getPos().getZ();\n        Block placedBlock = event.getPlacedBlock().getBlock();\n\n        if (placedBlock == Blocks.FIRE && event.getWorld().getBlockState(new BlockPos(x, y - 1, z)).getBlock() == Blocks.EMERALD_BLOCK) {\n            int totemsFound = 0;\n\n            // Check on +/- X and Z for at least 3 totems on fire.\n            for (int i = 0; i < 4; i++) {\n                int dX = 0;\n                int dZ = 0;\n\n                if (i == 0 || i == 2) dX = -3;\n                else dZ = 3;\n\n                // Scan upwards to ensure it's obsidian, and on fire.\n                for (int j = -1; j < 2; j++) {\n                    Block block = event.getWorld().getBlockState(new BlockPos(x + dX, y + j, z + dZ)).getBlock();\n                    if (block != Blocks.OBSIDIAN && block != Blocks.FIRE) break;\n\n                    // If we made it up to 1 without breaking, make sure the block is fire so that it's a lit totem.\n                    if (j == 1 && block == Blocks.FIRE) totemsFound++;\n                }\n            }\n\n            if (totemsFound >= 3 && !event.getWorld().isDaytime()) {\n                MCAServer.get().setReaperSpawnPos(event.getWorld(), new BlockPos(x + 1, y + 10, z + 1));\n                MCAServer.get().startSpawnReaper();\n                for (int i = 0; i < 2; i++) event.getWorld().setBlockToAir(new BlockPos(x, y - i, z));\n            }\n        }\n    }\n\n    @SubscribeEvent\n    public void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {\n        // When players respawn check to see if their baby was saved in limbo. Add it back to their inventory.\n        if (limbo.containsKey(event.player.getUniqueID())) {\n            event.player.inventory.addItemStackToInventory(limbo.get(event.player.getUniqueID()));\n            limbo.remove(event.player.getUniqueID());\n        }\n    }\n\n    @SubscribeEvent\n    public void onLivingDeath(LivingDeathEvent event) {\n        // If a player dies while holding a baby, remember it until they respawn.\n        if (event.getEntityLiving() instanceof EntityPlayer) {\n            EntityPlayer player = (EntityPlayer)event.getEntityLiving();\n            Optional<ItemStack> babyStack = player.inventory.mainInventory.stream().filter(s -> s.getItem() instanceof ItemBaby).findFirst();\n            babyStack.ifPresent(s -> limbo.put(player.getUniqueID(), babyStack.get()));\n        }\n    }\n\n    @SubscribeEvent\n    public void onLivingSetTarget(LivingSetAttackTargetEvent event) {\n        // Mobs shouldn't attack infected villagers. Account for this when they attempt to set their target.\n        if (event.getEntityLiving() instanceof EntityMob && event.getTarget() instanceof EntityVillagerMCA) {\n            EntityMob mob = (EntityMob) event.getEntityLiving();\n            EntityVillagerMCA target = (EntityVillagerMCA) event.getTarget();\n\n            if (target.get(EntityVillagerMCA.IS_INFECTED)) {\n                mob.setAttackTarget(null);\n            }\n        }\n    }\n\n    @SubscribeEvent\n    public void onPlaySoundAtEntityEvent(PlaySoundAtEntityEvent event) {\n        // Cancel all villager sounds. We unfortunately cannot control on a per entity basis as getEntity() always returns null.\n        if (FMLCommonHandler.instance().getEffectiveSide() != Side.CLIENT) return;\n        try {\n            event.setCanceled(event.getSound().getSoundName().toString().contains(\"villager\"));\n        } catch (NullPointerException e) {\n            // throw out potential NPEs due to bad event data. some of these have been reported\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/core/forge/GuiHandler.java",
    "content": "package mca.core.forge;\n\nimport mca.client.gui.*;\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.client.gui.GuiScreenBook;\nimport net.minecraft.client.gui.inventory.GuiChest;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.inventory.ContainerChest;\nimport net.minecraft.world.World;\nimport net.minecraftforge.fml.common.network.IGuiHandler;\n\npublic class GuiHandler implements IGuiHandler {\n    @Override\n    public Object getServerGuiElement(int guiId, EntityPlayer player, World world, int entityId, int posY, int posZ) {\n        switch (guiId) {\n            case Constants.GUI_ID_INVENTORY:\n                EntityVillagerMCA villager = (EntityVillagerMCA) world.getEntityByID(entityId);\n                if (villager == null || villager.inventory == null) return null;\n                return new ContainerChest(player.inventory, villager.inventory, player);\n            default:\n                return null;\n        }\n    }\n\n    @Override\n    public Object getClientGuiElement(int guiId, EntityPlayer player, World world, int entityId, int unused1, int unused2) {\n        switch (guiId) {\n            case Constants.GUI_ID_INVENTORY:\n                Entity entity = world.getEntityByID(entityId);\n                if (entity == null) return null;\n                return new GuiChest(player.inventory, ((EntityVillagerMCA) entity).inventory);\n            case Constants.GUI_ID_INTERACT:\n                return new GuiInteract((EntityVillagerMCA) world.getEntityByID(entityId), player);\n            case Constants.GUI_ID_NAMEBABY:\n                return new GuiNameBaby(player, player.inventory.getStackInSlot(player.inventory.currentItem));\n            case Constants.GUI_ID_STAFFOFLIFE:\n                return new GuiStaffOfLife(player);\n            case Constants.GUI_ID_VILLAGEREDITOR:\n                return new GuiVillagerEditor((EntityVillagerMCA) world.getEntityByID(entityId), player);\n            case Constants.GUI_ID_GUIDEBOOK:\n                return new GuiScreenBook(player, player.inventory.getCurrentItem(), false);\n            case Constants.GUI_ID_WHISTLE:\n                return new GuiWhistle();\n            default:\n                MCA.getLog().fatal(\"Failed to handle provided GUI ID on client: \" + guiId);\n                return null;\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/core/forge/NetMCA.java",
    "content": "package mca.core.forge;\n\nimport io.netty.buffer.ByteBuf;\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\nimport lombok.NoArgsConstructor;\nimport mca.client.gui.GuiStaffOfLife;\nimport mca.client.gui.GuiWhistle;\nimport mca.client.network.ClientMessageQueue;\nimport mca.core.MCA;\nimport mca.core.minecraft.ProfessionsMCA;\nimport mca.entity.EntityVillagerMCA;\nimport mca.entity.data.SavedVillagers;\nimport mca.entity.inventory.InventoryMCA;\nimport mca.items.ItemBaby;\nimport mca.server.ServerMessageHandler;\nimport net.minecraft.client.Minecraft;\nimport net.minecraft.client.gui.GuiScreen;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.EntityLiving;\nimport net.minecraft.entity.passive.EntityVillager;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.entity.player.EntityPlayerMP;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.nbt.NBTTagCompound;\nimport net.minecraft.util.EnumParticleTypes;\nimport net.minecraft.util.ResourceLocation;\nimport net.minecraft.util.text.TextComponentString;\nimport net.minecraft.world.World;\nimport net.minecraftforge.fml.common.ObfuscationReflectionHelper;\nimport net.minecraftforge.fml.common.network.ByteBufUtils;\nimport net.minecraftforge.fml.common.network.NetworkRegistry;\nimport net.minecraftforge.fml.common.network.simpleimpl.IMessage;\nimport net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;\nimport net.minecraftforge.fml.common.network.simpleimpl.MessageContext;\nimport net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;\nimport net.minecraftforge.fml.common.registry.VillagerRegistry;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\nimport scala.collection.parallel.ParIterableLike;\n\nimport javax.annotation.Nullable;\nimport java.util.*;\n\npublic class NetMCA {\n    public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel(\"mca\");\n\n    public static void registerMessages() {\n        INSTANCE.registerMessage(ButtonActionHandler.class, ButtonAction.class, 0, Side.SERVER);\n        INSTANCE.registerMessage(SayHandler.class, Say.class, 1, Side.CLIENT);\n        INSTANCE.registerMessage(BabyNameHandler.class, BabyName.class, 2, Side.SERVER);\n        INSTANCE.registerMessage(CareerResponseHandler.class, CareerResponse.class, 3, Side.CLIENT);\n        INSTANCE.registerMessage(CareerRequestHandler.class, CareerRequest.class, 4, Side.SERVER);\n        INSTANCE.registerMessage(InventoryRequestHandler.class, InventoryRequest.class, 5, Side.SERVER);\n        INSTANCE.registerMessage(InventoryResponseHandler.class, InventoryResponse.class, 6, Side.CLIENT);\n        INSTANCE.registerMessage(SavedVillagersRequestHandler.class, SavedVillagersRequest.class, 7, Side.SERVER);\n        INSTANCE.registerMessage(SavedVillagersResponseHandler.class, SavedVillagersResponse.class, 8, Side.CLIENT);\n        INSTANCE.registerMessage(ReviveVillagerHandler.class, ReviveVillager.class, 9, Side.SERVER);\n        INSTANCE.registerMessage(SetNameHandler.class, SetName.class, 10, Side.SERVER);\n        INSTANCE.registerMessage(SpawnParticlesHandler.class, SpawnParticles.class, 11, Side.CLIENT);\n        INSTANCE.registerMessage(GetFamilyHandler.class, GetFamily.class, 12, Side.SERVER);\n        INSTANCE.registerMessage(GetFamilyResponseHandler.class, GetFamilyResponse.class, 13, Side.CLIENT);\n        INSTANCE.registerMessage(CallToPlayerHandler.class, CallToPlayer.class, 14, Side.SERVER);\n        INSTANCE.registerMessage(SetTextureHandler.class, SetTexture.class, 15, Side.SERVER);\n        INSTANCE.registerMessage(SetProfessionHandler.class, SetProfession.class, 16, Side.SERVER);\n    }\n\n    @SideOnly(Side.CLIENT)\n    private static EntityPlayer getPlayerClient() {\n        return Minecraft.getMinecraft().player;\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    @Getter\n    public static class ButtonAction implements IMessage {\n        private String guiKey;\n        private String buttonId;\n        private UUID targetUUID;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            buf.writeBoolean(targetUUID != null);\n            ByteBufUtils.writeUTF8String(buf, this.guiKey);\n            ByteBufUtils.writeUTF8String(buf, this.buttonId);\n\n            if (targetUUID != null) {\n                ByteBufUtils.writeUTF8String(buf, this.targetUUID.toString());\n            }\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            boolean hasTarget = buf.readBoolean();\n            this.guiKey = ByteBufUtils.readUTF8String(buf);\n            this.buttonId = ByteBufUtils.readUTF8String(buf);\n\n            if (hasTarget) {\n                this.targetUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n            }\n        }\n\n        public boolean targetsServer() {\n            return getTargetUUID() == null;\n        }\n    }\n\n    public static class ButtonActionHandler implements IMessageHandler<ButtonAction, IMessage> {\n        @Override\n        public IMessage onMessage(ButtonAction message, MessageContext ctx) {\n            EntityPlayerMP player = ctx.getServerHandler().player;\n\n            // The message can target a particular villager, or the server itself.\n            if (!message.targetsServer()) {\n                EntityVillagerMCA villager = (EntityVillagerMCA) player.getServerWorld().getEntityFromUuid(message.targetUUID);\n                if (villager != null) player.getServerWorld().addScheduledTask(() -> villager.handleButtonClick(player, message.guiKey, message.buttonId));\n            } else ServerMessageHandler.handleMessage(player, message);\n            return null;\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class Say implements IMessage {\n        private String phraseId;\n        private int speakingEntityId;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, this.phraseId);\n            buf.writeInt(this.speakingEntityId);\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            this.phraseId = ByteBufUtils.readUTF8String(buf);\n            this.speakingEntityId = buf.readInt();\n        }\n    }\n\n    public static class SayHandler implements IMessageHandler<Say, IMessage> {\n\n        @Override\n        public IMessage onMessage(Say message, MessageContext ctx) {\n            EntityPlayer player = getPlayerClient();\n            EntityVillagerMCA villager = (EntityVillagerMCA) player.getEntityWorld().getEntityByID(message.speakingEntityId);\n\n            if (villager != null) villager.say(com.google.common.base.Optional.of(player), message.phraseId);\n\n            return null;\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class BabyName implements IMessage {\n        private String babyName;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, this.babyName);\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            this.babyName = ByteBufUtils.readUTF8String(buf);\n        }\n    }\n\n    public static class BabyNameHandler implements IMessageHandler<BabyName, IMessage> {\n\n        @Override\n        public IMessage onMessage(BabyName message, MessageContext ctx) {\n            EntityPlayerMP player = ctx.getServerHandler().player;\n            ItemStack stack = player.inventory.getStackInSlot(player.inventory.currentItem);\n\n            if (stack.getItem() instanceof ItemBaby) stack.getTagCompound().setString(\"name\", message.babyName);\n\n            return null;\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    @Getter\n    public static class CareerResponse implements IMessage {\n        private int careerId;\n        private UUID entityUUID;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeVarInt(buf, careerId, 4);\n            ByteBufUtils.writeUTF8String(buf, entityUUID.toString());\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            this.careerId = ByteBufUtils.readVarInt(buf, 4);\n            this.entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n        }\n    }\n\n    public static class CareerResponseHandler implements IMessageHandler<CareerResponse, IMessage> {\n\n        @Override\n        public IMessage onMessage(CareerResponse message, MessageContext ctx) {\n            // must be thrown in the queue and processed on the main thread since we must loop through the loaded entity list\n            // it could change while looping and cause a ConcurrentModificationException.\n            ClientMessageQueue.add(message);\n            return null;\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class CareerRequest implements IMessage {\n        private UUID entityUUID;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, entityUUID.toString());\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            this.entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n        }\n    }\n\n    public static class CareerRequestHandler implements IMessageHandler<CareerRequest, IMessage> {\n\n        @Override\n        public IMessage onMessage(CareerRequest message, MessageContext ctx) {\n            EntityPlayerMP player = ctx.getServerHandler().player;\n            int careerId = -255;\n\n            try {\n                EntityVillagerMCA villager = (EntityVillagerMCA) player.getServerWorld().getEntityFromUuid(message.entityUUID);\n\n                if (villager != null) careerId = ObfuscationReflectionHelper.getPrivateValue(EntityVillager.class, villager, EntityVillagerMCA.VANILLA_CAREER_ID_FIELD_INDEX);\n            } catch (ClassCastException ignored) {\n                MCA.getLog().error(\"UUID provided in career request does not match an MCA villager!: \" + message.entityUUID.toString());\n                return null;\n            } catch (NullPointerException ignored) {\n                MCA.getLog().error(\"UUID provided in career request does not match a loaded MCA villager!: \" + message.entityUUID.toString());\n                return null;\n            }\n\n            if (careerId == -255) {\n                MCA.getLog().error(\"Career ID wasn't assigned for UUID: \" + message.entityUUID);\n                return null;\n            }\n\n            return new CareerResponse(careerId, message.entityUUID);\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class InventoryRequest implements IMessage {\n        private UUID entityUUID;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, entityUUID.toString());\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            this.entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n        }\n    }\n\n    public static class InventoryRequestHandler implements IMessageHandler<InventoryRequest, IMessage> {\n\n        @Override\n        public IMessage onMessage(InventoryRequest message, MessageContext ctx) {\n            EntityPlayerMP player = ctx.getServerHandler().player;\n            EntityVillagerMCA villager = (EntityVillagerMCA) player.getServerWorld().getEntityFromUuid(message.entityUUID);\n            if (villager != null && villager.inventory != null) return new InventoryResponse(villager.getUniqueID(), villager.inventory);\n            return null;\n        }\n    }\n\n    @NoArgsConstructor\n    @Getter\n    public static class InventoryResponse implements IMessage {\n        private UUID entityUUID;\n        private NBTTagCompound inventoryNBT;\n\n        public InventoryResponse(UUID entityUUID, InventoryMCA inventory) {\n            this.inventoryNBT = new NBTTagCompound();\n            this.entityUUID = entityUUID;\n            this.inventoryNBT.setTag(\"inventory\", inventory.writeInventoryToNBT());\n        }\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, entityUUID.toString());\n            ByteBufUtils.writeTag(buf, inventoryNBT);\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            this.entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n            this.inventoryNBT = ByteBufUtils.readTag(buf);\n        }\n    }\n\n    public static class InventoryResponseHandler implements IMessageHandler<InventoryResponse, IMessage> {\n\n        @Override\n        public IMessage onMessage(InventoryResponse message, MessageContext ctx) {\n            ClientMessageQueue.add(message);\n            return null;\n        }\n    }\n\n    public static class SavedVillagersRequest implements IMessage {\n\n        @Override\n        public void fromBytes(ByteBuf buf) {}\n\n        @Override\n        public void toBytes(ByteBuf buf) {}\n    }\n\n    public static class SavedVillagersRequestHandler implements IMessageHandler<SavedVillagersRequest, IMessage> {\n\n        @Override\n        public IMessage onMessage(SavedVillagersRequest message, MessageContext ctx) {\n            return new SavedVillagersResponse(ctx.getServerHandler().player);\n        }\n    }\n\n    @NoArgsConstructor\n    public static class SavedVillagersResponse implements IMessage {\n        private Map<String, NBTTagCompound> villagers = new HashMap<>();\n\n        public SavedVillagersResponse(EntityPlayer player) {\n            villagers = SavedVillagers.get(player.world).getMap();\n        }\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            buf.writeInt(villagers.size());\n            villagers.forEach((k,v) -> {\n                ByteBufUtils.writeUTF8String(buf, k);\n                ByteBufUtils.writeTag(buf, v);\n            });\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            int size = buf.readInt();\n            for (int i = 0; i < size; i++) {\n                String k = ByteBufUtils.readUTF8String(buf);\n                NBTTagCompound v = ByteBufUtils.readTag(buf);\n                villagers.put(k, v);\n            }\n        }\n    }\n\n    public static class SavedVillagersResponseHandler implements IMessageHandler<SavedVillagersResponse, IMessage> {\n\n        @Override\n        public IMessage onMessage(SavedVillagersResponse message, MessageContext ctx) {\n            GuiScreen screen = Minecraft.getMinecraft().currentScreen;\n            if (screen instanceof GuiStaffOfLife) ((GuiStaffOfLife) screen).setVillagerData(message.villagers);\n            return null;\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class ReviveVillager implements IMessage {\n        private UUID target;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, target.toString());\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            target = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n        }\n    }\n\n    public static class ReviveVillagerHandler implements IMessageHandler<ReviveVillager, IMessage> {\n\n        @Override\n        public IMessage onMessage(ReviveVillager message, MessageContext ctx) {\n            EntityPlayer player = ctx.getServerHandler().player;\n            SavedVillagers villagers = SavedVillagers.get(player.world);\n            NBTTagCompound nbt = SavedVillagers.get(player.world).loadByUUID(message.target);\n            if (nbt != null) {\n                EntityVillagerMCA villager = new EntityVillagerMCA(player.world);\n                villager.setPosition(player.posX, player.posY, player.posZ);\n                player.world.spawnEntity(villager);\n\n                villager.readEntityFromNBT(nbt);\n                villager.reset();\n\n                villagers.remove(message.target);\n                player.inventory.mainInventory.get(player.inventory.currentItem).damageItem(1, player);\n            }\n\n            return null;\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class SetName implements IMessage {\n        private String name;\n        private UUID entityUUID;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, entityUUID.toString());\n            ByteBufUtils.writeUTF8String(buf, name);\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n            name = ByteBufUtils.readUTF8String(buf);\n        }\n    }\n\n    public static class SetNameHandler implements IMessageHandler<SetName, IMessage> {\n\n        @Override\n        public IMessage onMessage(SetName message, MessageContext ctx) {\n            World world = ctx.getServerHandler().player.world;\n            java.util.Optional<Entity> entity = world.loadedEntityList.stream().filter((e) -> e.getUniqueID().equals(message.entityUUID)).findFirst();\n            if (!entity.isPresent()) return null;\n            if (entity.get() instanceof EntityVillagerMCA) {\n                EntityVillagerMCA villager = (EntityVillagerMCA) entity.get();\n                villager.set(EntityVillagerMCA.VILLAGER_NAME, message.name);\n            }\n            return null;\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class SpawnParticles implements IMessage {\n        private UUID entityUUID;\n        private EnumParticleTypes particleType;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, entityUUID.toString());\n            buf.writeInt(particleType.getParticleID());\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            entityUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n            particleType = EnumParticleTypes.getParticleFromId(buf.readInt());\n        }\n    }\n\n    public static class SpawnParticlesHandler implements IMessageHandler<SpawnParticles, IMessage> {\n        @Override\n        public IMessage onMessage(SpawnParticles message, MessageContext ctx) {\n            World world = getPlayerClient().world;\n            java.util.Optional<Entity> entity = world.loadedEntityList.stream().filter((e) -> e.getUniqueID().equals(message.entityUUID)).findFirst();\n            if (!entity.isPresent()) return null;\n            if (entity.get() instanceof EntityVillagerMCA) {\n                EntityVillagerMCA villager = (EntityVillagerMCA) entity.get();\n                villager.spawnParticles(message.particleType);\n            }\n            return null;\n        }\n    }\n\n    @NoArgsConstructor\n    public static class GetFamily implements IMessage {\n        @Override\n        public void toBytes(ByteBuf buf) {}\n\n        @Override\n        public void fromBytes(ByteBuf buf) {}\n    }\n\n    public static class GetFamilyHandler implements IMessageHandler<GetFamily, IMessage> {\n        @Override\n        public IMessage onMessage(GetFamily message, MessageContext ctx) {\n            EntityPlayer player = ctx.getServerHandler().player;\n            List<EntityVillagerMCA> villagers = new ArrayList<>();\n            List<NBTTagCompound> familyData = new ArrayList<>();\n\n            player.world.loadedEntityList.stream().filter(e -> e instanceof EntityVillagerMCA).forEach(e -> villagers.add((EntityVillagerMCA)e));\n            villagers.stream().filter(e -> e.isMarriedTo(player.getUniqueID()) || e.playerIsParent(player)).forEach(e -> {\n                NBTTagCompound nbt = new NBTTagCompound();\n                e.writeEntityToNBT(nbt);\n                familyData.add(nbt);\n            });\n            return new GetFamilyResponse(familyData);\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class GetFamilyResponse implements IMessage {\n        private List<NBTTagCompound> familyData;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            buf.writeInt(familyData.size());\n            familyData.stream().forEach(n -> ByteBufUtils.writeTag(buf, n));\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            familyData = new ArrayList<>();\n            int size = buf.readInt();\n            for (int i = 0; i < size; i++) {\n                familyData.add(ByteBufUtils.readTag(buf));\n            }\n        }\n    }\n\n    public static class GetFamilyResponseHandler implements IMessageHandler<GetFamilyResponse, IMessage> {\n        @Override\n        public IMessage onMessage(GetFamilyResponse message, MessageContext ctx) {\n            GuiScreen screen = Minecraft.getMinecraft().currentScreen;\n            if (screen instanceof GuiWhistle) {\n                GuiWhistle whistleScreen = (GuiWhistle)screen;\n                whistleScreen.setVillagerDataList(message.familyData);\n            }\n            return null;\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class CallToPlayer implements IMessage {\n        private UUID targetUUID;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, targetUUID.toString());\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            targetUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n        }\n    }\n\n    public static class CallToPlayerHandler implements IMessageHandler<CallToPlayer, IMessage> {\n        @Override\n        public IMessage onMessage(CallToPlayer message, MessageContext ctx) {\n            EntityPlayer player = ctx.getServerHandler().player;\n            Optional<Entity> entity = player.world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(message.targetUUID)).findFirst();\n            entity.ifPresent(e -> {\n                e.setPosition(player.posX, player.posY, player.posZ);\n                ((EntityLiving)e).getNavigator().clearPath();\n            });\n            return null;\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class SetProfession implements IMessage {\n        private UUID targetUUID;\n        private String profession;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, targetUUID.toString());\n            ByteBufUtils.writeUTF8String(buf, profession);\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            targetUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n            profession = ByteBufUtils.readUTF8String(buf);\n        }\n    }\n\n    public static class SetProfessionHandler implements IMessageHandler<SetProfession, IMessage> {\n        @Override\n        public IMessage onMessage(SetProfession message, MessageContext ctx) {\n            boolean isCareerSet = false;\n            EntityPlayer player = ctx.getServerHandler().player;\n            Optional<Entity> entity = player.world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(message.targetUUID)).findFirst();\n            if (entity.isPresent()) {\n                // Loop through all professions in the registry\n                for (Map.Entry<ResourceLocation, VillagerRegistry.VillagerProfession> professionEntry : ProfessionsMCA.registry.getEntries()) {\n                    List<VillagerRegistry.VillagerCareer> careers = ObfuscationReflectionHelper.getPrivateValue(VillagerRegistry.VillagerProfession.class, professionEntry.getValue(), 3);\n\n                    // Career ids are based on their index in the careers list\n                    for (int i = 0; i < careers.size(); i++) {\n                        VillagerRegistry.VillagerCareer career = careers.get(i);\n\n                        // If we found the correct career, set the profession and career accordingly\n                        if (career.getName().equals(message.profession)) {\n                            EntityVillagerMCA villager = (EntityVillagerMCA)entity.get();\n                            villager.setProfession(professionEntry.getValue());\n                            villager.setVanillaCareer(i);\n                            player.sendMessage(new TextComponentString(\"Career set to \" + message.profession));\n                            isCareerSet = true;\n                            break;\n                        }\n                    }\n                }\n            } else {\n                MCA.getLog().error(\"Entity not found on career set!: \" + message.targetUUID.toString());\n                return null;\n            }\n\n            if (!isCareerSet) {\n                player.sendMessage(new TextComponentString(\"Career not found: \" + message.profession));\n            }\n            return null;\n        }\n    }\n\n    @AllArgsConstructor\n    @NoArgsConstructor\n    public static class SetTexture implements IMessage {\n        private UUID targetUUID;\n        private String texture;\n\n        @Override\n        public void toBytes(ByteBuf buf) {\n            ByteBufUtils.writeUTF8String(buf, targetUUID.toString());\n            ByteBufUtils.writeUTF8String(buf, texture);\n        }\n\n        @Override\n        public void fromBytes(ByteBuf buf) {\n            targetUUID = UUID.fromString(ByteBufUtils.readUTF8String(buf));\n            texture = ByteBufUtils.readUTF8String(buf);\n        }\n    }\n\n    public static class SetTextureHandler implements IMessageHandler<SetTexture, IMessage> {\n        @Override\n        public IMessage onMessage(SetTexture message, MessageContext ctx) {\n            EntityPlayer player = ctx.getServerHandler().player;\n            Optional<Entity> entity = player.world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(message.targetUUID)).findFirst();\n            entity.ifPresent(e -> ((EntityVillagerMCA)e).set(EntityVillagerMCA.TEXTURE, message.texture));\n            return null;\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/core/forge/ServerProxy.java",
    "content": "package mca.core.forge;\n\npublic class ServerProxy {\n    public void registerEntityRenderers() {\n        // Server-side, no rendering.\n    }\n\n    public void registerEventHandlers() {\n\n    }\n\n    public void registerModelMeshers() {\n\n    }\n}"
  },
  {
    "path": "src/main/java/mca/core/minecraft/BlocksMCA.java",
    "content": "package mca.core.minecraft;\n\nimport mca.blocks.BlockVillagerSpawner;\nimport mca.core.MCA;\nimport net.minecraft.block.Block;\nimport net.minecraft.block.BlockOre;\nimport net.minecraft.client.Minecraft;\nimport net.minecraft.client.renderer.ItemModelMesher;\nimport net.minecraft.client.renderer.block.model.ModelResourceLocation;\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemBlock;\nimport net.minecraft.util.ResourceLocation;\nimport net.minecraftforge.event.RegistryEvent;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\nimport net.minecraftforge.registries.IForgeRegistry;\n\nimport java.util.ArrayList;\n\npublic final class BlocksMCA {\n    public static final Block ROSE_GOLD_BLOCK = new BlockOre();\n    public static final Block ROSE_GOLD_ORE = new BlockOre();\n    public static final BlockVillagerSpawner VILLAGER_SPAWNER = new BlockVillagerSpawner();\n\n    private static final ArrayList<Block> BLOCKS = new ArrayList<>();\n\n    public static void register(RegistryEvent.Register<Block> event) {\n        ROSE_GOLD_BLOCK.setHardness(3.0F).setResistance(5.0F).setCreativeTab(MCA.creativeTab);\n        ROSE_GOLD_BLOCK.setHarvestLevel(\"pickaxe\", 2);\n        ROSE_GOLD_ORE.setHardness(3.0F).setResistance(5.0F).setCreativeTab(MCA.creativeTab);\n        ROSE_GOLD_ORE.setHarvestLevel(\"pickaxe\", 2);\n        VILLAGER_SPAWNER.setCreativeTab(MCA.creativeTab);\n\n        Block[] blocks = {\n                ROSE_GOLD_BLOCK,\n                ROSE_GOLD_ORE,\n                VILLAGER_SPAWNER\n        };\n\n        setBlockName(ROSE_GOLD_BLOCK, \"rose_gold_block\");\n        setBlockName(ROSE_GOLD_ORE, \"rose_gold_ore\");\n        setBlockName(VILLAGER_SPAWNER, \"villager_spawner\");\n\n        for (Block block : blocks) {\n            event.getRegistry().register(block);\n            BLOCKS.add(block);\n        }\n    }\n\n    public static void registerItemBlocks(RegistryEvent.Register<Item> event) {\n        IForgeRegistry<Item> registry = event.getRegistry();\n        ItemBlock[] items = {\n                new ItemBlock(ROSE_GOLD_BLOCK),\n                new ItemBlock(ROSE_GOLD_ORE),\n                new ItemBlock(VILLAGER_SPAWNER)\n        };\n\n        for (ItemBlock item : items) {\n            Block block = item.getBlock();\n            ResourceLocation registryName = block.getRegistryName();\n            registry.register(item.setRegistryName(registryName));\n        }\n    }\n\n    private static void setBlockName(Block block, String blockName) {\n        block.setRegistryName(MCA.MODID, blockName);\n        block.setUnlocalizedName(block.getRegistryName().toString());\n    }\n\n    @SideOnly(Side.CLIENT)\n    public static void registerModelMeshers() {\n        ItemModelMesher mesher = Minecraft.getMinecraft().getRenderItem().getItemModelMesher();\n\n        for (Block block : BLOCKS) {\n            mesher.register(Item.getItemFromBlock(block), 0, new ModelResourceLocation(block.getRegistryName(), \"inventory\"));\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/core/minecraft/ItemsMCA.java",
    "content": "package mca.core.minecraft;\n\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.items.*;\nimport net.minecraft.client.Minecraft;\nimport net.minecraft.client.renderer.ItemModelMesher;\nimport net.minecraft.client.renderer.block.model.ModelResourceLocation;\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.nbt.NBTTagCompound;\nimport net.minecraft.nbt.NBTTagList;\nimport net.minecraft.nbt.NBTTagString;\nimport net.minecraft.util.ResourceLocation;\nimport net.minecraftforge.event.RegistryEvent;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\n\nimport java.lang.reflect.Field;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic final class ItemsMCA {\n    public static final ItemSpawnEgg EGG_MALE = new ItemSpawnEgg(true);\n    public static final ItemSpawnEgg EGG_FEMALE = new ItemSpawnEgg(false);\n    public static final Item WEDDING_RING = new ItemWeddingRing().setMaxStackSize(1);\n    public static final Item WEDDING_RING_RG = new ItemWeddingRing().setMaxStackSize(1);\n    public static final Item ENGAGEMENT_RING = new ItemEngagementRing().setMaxStackSize(1);\n    public static final Item ENGAGEMENT_RING_RG = new ItemEngagementRing().setMaxStackSize(1);\n    public static final Item MATCHMAKERS_RING = new ItemMatchmakersRing().setMaxStackSize(2);\n    public static final Item BABY_BOY = new ItemBaby(true);\n    public static final Item BABY_GIRL = new ItemBaby(false);\n    public static final Item ROSE_GOLD_INGOT = new Item().setUnlocalizedName(\"rose_gold_ingot\");\n    public static final Item ROSE_GOLD_DUST = new Item().setUnlocalizedName(\"rose_gold_dust\");\n    public static final Item GOLD_DUST = new Item().setUnlocalizedName(\"gold_dust\");\n    public static final Item VILLAGER_EDITOR = new ItemVillagerEditor();\n    public static final Item STAFF_OF_LIFE = new ItemStaffOfLife();\n    public static final Item WHISTLE = new ItemWhistle();\n    public static final ItemGuideBook BOOK_DEATH = new ItemGuideBook();\n    public static final ItemGuideBook BOOK_ROMANCE = new ItemGuideBook();\n    public static final ItemGuideBook BOOK_FAMILY = new ItemGuideBook();\n    public static final ItemGuideBook BOOK_ROSE_GOLD = new ItemGuideBook();\n    public static final ItemGuideBook BOOK_INFECTION = new ItemGuideBook();\n\n    private static final List<Item> ITEMS = new ArrayList<>();\n\n    public static void register(RegistryEvent.Register<Item> event) {\n        for (Field f : ItemsMCA.class.getFields()) {\n            try {\n                Object instance = f.get(null);\n                if (instance instanceof Item) {\n                    Item item = (Item) instance;\n                    setItemName(item, f.getName().toLowerCase());\n                    event.getRegistry().register(item);\n                    ITEMS.add(item);\n                }\n            } catch (Exception e) {\n                MCA.getLog().error(\"Error while registering items: \", e);\n            }\n        }\n    }\n\n    public static void assignCreativeTabs() {\n        ITEMS.stream().forEach(i -> i.setCreativeTab(MCA.creativeTab));\n    }\n\n    public static void setBookNBT(ItemStack stack) {\n        Item book = stack.getItem();\n        NBTTagCompound nbt = new NBTTagCompound();\n\n        if (book == BOOK_DEATH) {\n            nbt.setString(\"title\", \"Death, and How to Cure It!\");\n            nbt.setString(\"author\", \"Ozzie the Warrior\");\n            nbt.setBoolean(\"resolved\", true);\n\n            NBTTagList pages = new NBTTagList();\n            pages.appendTag(new NBTTagString(\"\"\n                    + \"I couldn't count how many times my family has been blown to pieces by creepers.\\n\\nHow are they still around, you may ask?\"\n                    + \"\\n\\nEasy! I, dear reader, have discovered a CURE for death itself! And through this book, I can share it with you.\"));\n\n            /*\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Memorials\\n\\n\" + Constants.Format.RESET\n                    + \"When a family member dies, they will drop a chest - and inside will be an \" + Constants.Format.BOLD + \"item\" + Constants.Format.RESET + \" that was important to them.\\n\\n\"\n                    + \"This is the key to reviving someone, don't lose it! Only your spouse and children will drop these items.\"));\n            */\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Staff Of Life\\n\\n\" + Constants.Format.RESET\n                    + \"The Staff is a powerful item that can revive up to 5 people. Wave the staff around and speak the name of the villager you wish to revive. Within moments, your loved one will be fully revived!\\n\\n\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Summoning Grim\\n\\n\" + Constants.Format.RESET\n                    + \"Unfortunately, you must obtain the Staff from the Grim Reaper himself.\\n\\n\"\n                    + \"To summon him, you must build an altar consisting of 3 obsidian columns that are at least 2 blocks high. They may be higher if you like.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Summoning Grim pt. 2\\n\\n\" + Constants.Format.RESET\n                    + \"     # # # X # # #\\n\"\n                    + \"     # # # # # # #\\n\"\n                    + \"     # # # # # # #\\n\"\n                    + \"     X # # E # # X\\n\\n\"\n                    + \"X = Obsidian Column\\n\"\n                    + \"E = Emerald\\n\"\n                    + \"# = Empty\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Summoning Grim pt. 3\\n\\n\" + Constants.Format.RESET\n                    + \"After building the altar, wait until night and light all 3 columns.\\n\\n\"\n                    + \"When you're ready to fight, light the emerald block and run!\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Fighting Grim\\n\\n\" + Constants.Format.RESET\n                    + \"Grim is tough. Use full diamond armor, lots of potions, and lots of enchantments.\\n\\n\"\n                    + \"He can:\\n\"\n                    + \"- Fly\\n\"\n                    + \"- Block attacks\\n\"\n                    + \"- Blind you\\n\"\n                    + \"- Move your items\\n\"\n                    + \"- Teleport\\n\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Fighting Grim pt. 2\\n\\n\" + Constants.Format.RESET\n                    + \"If you hit Grim while he's blocking, he will teleport behind you and strike.\\n\\n\"\n                    + \"Do not try to use arrows or poison, he is immune!\\n\\n\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Fighting Grim pt. 3\\n\\n\" + Constants.Format.RESET\n                    + \"When Grim is at \" + Constants.Format.BOLD + \"half health\" + Constants.Format.RESET + \" he will teleport into the air and begin healing.\\n\\n\"\n                    + \"While healing, he will summon his minions from the underworld to fight you.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Fighting Grim pt. 4\\n\\n\" + Constants.Format.RESET\n                    + \"When Grim is healed, he will continue attacking you, but he won't be able to heal again for 3 minutes and 30 seconds.\\n\\n\"\n                    + \"Each time Grim heals, he will not be able to restore as much health has he did previously.\"));\n\n            nbt.setTag(\"pages\", pages);\n        }\n\n        else if (book == BOOK_ROMANCE)\n        {\n            nbt.setString(\"title\", \"Relationships and You\");\n            nbt.setString(\"author\", \"Gerry the Librarian\");\n            nbt.setBoolean(\"resolved\", true);\n\n            NBTTagList pages = new NBTTagList();\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Introduction\\n\\n\" + Constants.Format.RESET\n                    + \"Interaction is key to building relationships and finding the love of your life.\\n\\n\"\n                    + \"I've happily written this book in order to share my knowledge of interaction, love, and, unfortunately, divorce, to anyone who may need a little push in the right direction.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Interacting\\n\" + Constants.Format.RESET\n                    + \"Choose wisely when interacting with a villager!\\n\\n\"\n                    + \"If choosing a romantic interaction, be sure that the villager you are talking to likes you a lot.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Interacting pt. 2\\n\" + Constants.Format.RESET\n                    + \"Don't be annoying! Talking to someone for too long will bore them, and your interactions may stop succeeding.\\n\\n\"\n                    + \"If this happens, simply wait a few minutes before trying to talk to them again.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Marriage\\n\" + Constants.Format.RESET\n                    + \"To get married, simply gift a villager a wedding ring once you feel you have reached the highest relationship level.\\n\\n\"\n                    + \"Once you're married, you can then procreate and have children of your own!\"));\n\n            nbt.setTag(\"pages\", pages);\n        }\n\n        else if (book == BOOK_FAMILY)\n        {\n            nbt.setString(\"title\", \"Managing Your Family Vol. XI\");\n            nbt.setString(\"author\", \"Leanne the Cleric\");\n            nbt.setBoolean(\"resolved\", true);\n\n            NBTTagList pages = new NBTTagList();\n            pages.appendTag(new NBTTagString(\"\"\n                    + \"Children are our future! Make sure to have as many as you possibly can.\\n\\nNot only do you get to experience the joy of\"\n                    + \" raising a child, but once they are past the baby stage, put them to work!\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Babies\\n\\n\" + Constants.Format.RESET\n                    + \"When you are married, simply approach your spouse and offer to 'Procreate'.\\n\\n\"\n                    + \"After a short dance, you'll be the proud owner of a new baby boy or girl (or maybe even both)!\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Growth\\n\\n\" + Constants.Format.RESET\n                    + \"Babies take time to grow, make sure to hold them until they are ready, or give them to your spouse to take care of.\\n\\n\"\n                    + \"Once a baby is ready to grow, you may place it on the ground and it will grow into a child!\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Adolescence\\n\\n\" + Constants.Format.RESET\n                    + \"Children will grow slowly from a baby to a teen.\\n\\nHowever, the magical properties of Golden Apples are said to accelerate \"\n                    + \"any child's growth. I have yet to try this myself.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Chores\\n\\n\" + Constants.Format.RESET\n                    + \"Any child can harvest, chop wood, prospect, hunt, and fish. You'll need to provide them with the tools they need to do so.\\n\\n\"\n                    + \"If a tool breaks and the child doesn't have another, they will have no choice but to stop working.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Adulthood\\n\\n\" + Constants.Format.RESET\n                    + \"As sad as it may be, children will eventually grow into adults.\\n\\n\"\n                    + \"Adults can be married off by using Matchmaker's Rings, or they will eventually get married on their own.\"));\n\n            nbt.setTag(\"pages\", pages);\n        }\n\n        else if (book == BOOK_ROSE_GOLD)\n        {\n            nbt.setString(\"title\", \"On Rose Gold\");\n            nbt.setString(\"author\", \"William the Miner\");\n            nbt.setBoolean(\"resolved\", true);\n\n            NBTTagList pages = new NBTTagList();\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Warning!\\nTOP SECRET\\n\\n\" + Constants.Format.RESET\n                    + \"This manual is the property of William Mining Co.\\n\\nIf you are not a William Mining Co. employee, please refrain from \"\n                    + \"reading this manual and return promptly to William the Miner.\"));\n\n            pages.appendTag(new NBTTagString(\"\"\n                    + \"Ah, rose gold - a lovely combination of silver, copper, and gold that smelts into a pinkish orange metal.\\n\\n\"\n                    + \"Most use it as an alternative to gold for crafting rings as it is much less expensive.\\n\\n\"\n                    + \"However, it has some interesting qualities that are easy to miss.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Creating Dust\\n\\n\" + Constants.Format.RESET\n                    + \"Rose gold, once smelted, can be crushed into a fine dust.\\n\\n\"\n                    + \"Look closely at rose gold dust in bright light, and you'll see shiny flecks of pure gold!\\n\\n\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Washing Dust\\n\\n\" + Constants.Format.RESET\n                    + \"With a little work, we can actually extract the gold from the dust and create pure gold ingots. Simply mix dust with a bucket of water.\\n\\n\"\n                    + \"The lighter silver and copper components will wash away, leaving you with about 6 smaller piles of gold dust.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Extracting Gold\\n\\n\" + Constants.Format.RESET\n                    + \"Arrange 9 piles of dust on your crafting table, and if you're lucky, you'll find a gold nugget in one of them!\\n\\n\"\n                    + \"And of course, once you have 9 gold nuggets, you'll be able to craft them into a solid gold ingot.\"));\n\n            nbt.setTag(\"pages\", pages);\n        }\n\n        else if (book == BOOK_INFECTION)\n        {\n            nbt.setString(\"title\", \"Beware the Infection!\");\n            nbt.setString(\"author\", \"Richard the Zombie\");\n            nbt.setBoolean(\"resolved\", true);\n\n            NBTTagList pages = new NBTTagList();\n\n            pages.appendTag(new NBTTagString(\"\"\n                    + \"Good day, readers! I've written this book so that you may not end up suffering the same fate as I.\\n\\n\"\n                    + \"Although I caught the infection, I was luckily able to keep all of my mental faculties.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"What is the Infection?\\n\\n\" + Constants.Format.RESET\n                    + \"I discovered long ago that the zombies that appear at night are actually villagers in the late stages of infection!\\n\\n\"\n                    + \"Newly infected villagers turn green, are unable to speak, and occasionally try to bite!\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Curing\\n\\n\" + Constants.Format.RESET\n                    + \"Contrary to popular belief, the infection can be cured if caught in time.\\n\\n\"\n                    + \"You must first weaken the villager or zombie with a potion.\\n\\n\"\n                    + \"Then, immediately feed them a golden apple.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Curing pt. 2\\n\\n\" + Constants.Format.RESET\n                    + \"Zombies that can be cured often have enlarged heads and noses.\\n\\n\"\n                    + \"Any other zombies you see unfortunately are too far gone, and cannot be cured.\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Curing pt. 3\\n\\n\" + Constants.Format.RESET\n                    + \"Zombies will take a couple of minutes to be fully cured.\\n\\n\"\n                    + \"Villagers who were recently infected, though, and haven't had time to degrade into a full zombie, will be cured instantly!\"));\n\n            pages.appendTag(new NBTTagString(Constants.Format.BOLD + \"Warnings\\n\\n\" + Constants.Format.RESET\n                    + \"Villagers are highly susceptible to infection, and children even more so!\\n\\n\"\n                    + \"If you carry a baby with you while fighting zombies, there is a chance it can become infected.\"));\n\n            nbt.setTag(\"pages\", pages);\n        }\n\n        stack.setTagCompound(nbt);\n    }\n\n    @SideOnly(Side.CLIENT)\n    public static void registerModelMeshers() {\n        ItemModelMesher mesher = Minecraft.getMinecraft().getRenderItem().getItemModelMesher();\n\n        for (Item item : ITEMS) mesher.register(item, 0, new ModelResourceLocation(item.getRegistryName(), \"inventory\"));\n    }\n\n    private static void setItemName(Item item, String itemName) {\n        item.setUnlocalizedName(itemName);\n        item.setRegistryName(new ResourceLocation(MCA.MODID + \":\" + itemName));\n    }\n}"
  },
  {
    "path": "src/main/java/mca/core/minecraft/ProfessionsMCA.java",
    "content": "package mca.core.minecraft;\n\nimport mca.util.ItemStackCache;\nimport mca.util.ResourceLocationCache;\nimport net.minecraft.entity.IMerchant;\nimport net.minecraft.entity.passive.EntityVillager;\nimport net.minecraft.init.Blocks;\nimport net.minecraft.init.Items;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.ResourceLocation;\nimport net.minecraft.village.MerchantRecipe;\nimport net.minecraft.village.MerchantRecipeList;\nimport net.minecraftforge.event.RegistryEvent;\nimport net.minecraftforge.fml.common.Mod;\nimport net.minecraftforge.fml.common.eventhandler.SubscribeEvent;\nimport net.minecraftforge.fml.common.registry.GameRegistry;\nimport net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerCareer;\nimport net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession;\nimport net.minecraftforge.registries.IForgeRegistry;\n\nimport java.util.Arrays;\nimport java.util.Random;\n\n@GameRegistry.ObjectHolder(\"mca\")\npublic class ProfessionsMCA {\n    public static final VillagerProfession guard = new VillagerProfession(\"mca:guard\", \"minecraft:textures/entity/villager/villager.png\", \"minecraft:textures/entity/zombie_villager/zombie_villager.png\");\n    public static final VillagerProfession bandit = new VillagerProfession(\"mca:bandit\", \"minecraft:textures/entity/villager/villager.png\", \"minecraft:textures/entity/zombie_villager/zombie_villager.png\");\n    public static final VillagerProfession child = new VillagerProfession(\"mca:child\", \"minecraft:textures/entity/villager/villager.png\", \"minecraft:textures/entity/zombie_villager/zombie_villager.png\");\n    public static final VillagerProfession baker = new VillagerProfession(\"mca:baker\", \"minecraft:textures/entity/villager/farmer.png\", \"minecraft:textures/entity/zombie_villager/zombie_farmer.png\");\n    public static final VillagerProfession miner = new VillagerProfession(\"mca:miner\", \"minecraft:textures/entity/villager/smith.png\", \"minecraft:textures/entity/zombie_villager/zombie_smith.png\");\n\n    public static VillagerCareer guard_warrior;\n    public static VillagerCareer guard_archer;\n    public static VillagerCareer guard_hero;\n    public static VillagerCareer bandit_marauder;\n    public static VillagerCareer bandit_outlaw;\n    public static VillagerCareer bandit_pillager;\n    public static VillagerCareer child_child;\n    public static VillagerCareer baker_baker;\n    public static VillagerCareer miner_miner;\n\n    public static IForgeRegistry<VillagerProfession> registry;\n\n    private static final VillagerProfession[] FORBIDDEN_RANDOM_PROFESSIONS = {\n            bandit, child\n    };\n\n    public static void registerCareers() {\n        guard_warrior = new VillagerCareer(guard, \"warrior\");\n        guard_archer = new VillagerCareer(guard, \"archer\");\n        guard_hero = new VillagerCareer(guard, \"hero\");\n        bandit_marauder = new VillagerCareer(bandit, \"marauder\");\n        bandit_outlaw = new VillagerCareer(bandit, \"outlaw\");\n        bandit_pillager = new VillagerCareer(bandit, \"pillager\");\n        child_child = new VillagerCareer(child, \"child\");\n        baker_baker = new VillagerCareer(baker, \"baker\");\n        miner_miner = new VillagerCareer(miner, \"miner\");\n\n        baker_baker.addTrade(1, new BakerTradesLvl1());\n        baker_baker.addTrade(2, new BakerTradesLvl2());\n        baker_baker.addTrade(3, new BakerTradesLvl3());\n\n        miner_miner.addTrade(1, new MinerTradesLvl1());\n        miner_miner.addTrade(2, new MinerTradesLvl2());\n        miner_miner.addTrade(3, new MinerTradesLvl3());\n    }\n\n    public static ItemStack getDefaultHeldItem(VillagerProfession profession, VillagerCareer career) {\n        if (profession == ProfessionsMCA.guard) return career == ProfessionsMCA.guard_archer ? ItemStackCache.get(Items.BOW) : ItemStackCache.get(Items.IRON_SWORD);\n        else if (profession == ProfessionsMCA.bandit) return ItemStackCache.get(Items.IRON_SWORD);\n        return ItemStack.EMPTY;\n    }\n\n    public static VillagerProfession randomProfession() {\n        ResourceLocation resource = null;\n        while (resource == null || resource.getResourcePath().contains(\"nitwit\") || inForbiddenProfessions(registry.getValue(resource))) {\n            int i = new Random().nextInt(registry.getKeys().size() - 1);\n            resource = (ResourceLocation)registry.getKeys().toArray()[i];\n        }\n        return registry.getValue(resource);\n    }\n\n    @Mod.EventBusSubscriber(modid = \"mca\")\n    public static class RegistrationHandler {\n        /**\n         * Register this mod's {@link VillagerProfession}s.\n         *\n         * @param event The event\n         */\n        @SubscribeEvent\n        public static void onEvent(final RegistryEvent.Register<VillagerProfession> event) {\n            registry = event.getRegistry();\n            registry.register(guard);\n            registry.register(bandit);\n            registry.register(child);\n            registry.register(baker);\n            registry.register(miner);\n        }\n    }\n\n    public static class BakerTradesLvl1 implements EntityVillager.ITradeList {\n\n        @Override\n        public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 1), new ItemStack(Items.WHEAT, 6)));\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.MILK_BUCKET, 1), new ItemStack(Items.BREAD, 2)));\n        }\n    }\n\n    public static class BakerTradesLvl2 implements EntityVillager.ITradeList {\n\n        @Override\n        public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 2), new ItemStack(Items.EGG, 12)));\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.SUGAR, 2), new ItemStack(Items.CAKE, 1)));\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.STONE_HOE, 1), new ItemStack(Items.WHEAT, 10)));\n        }\n    }\n\n    public static class BakerTradesLvl3 implements EntityVillager.ITradeList {\n\n        @Override\n        public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.CAKE, 1), new ItemStack(Items.EMERALD, 5)));\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 2), new ItemStack(Items.BREAD, 4)));\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 3), new ItemStack(Items.COOKIE, 6)));\n            recipeList.add(new MerchantRecipe(new ItemStack(Blocks.PUMPKIN, 1), new ItemStack(Items.PUMPKIN_PIE, 1)));\n        }\n    }\n\n    public static class MinerTradesLvl1 implements EntityVillager.ITradeList {\n\n        @Override\n        public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {\n            recipeList.add(new MerchantRecipe(new ItemStack(Blocks.COBBLESTONE, 8), new ItemStack(Blocks.STONE, 4)));\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 1), new ItemStack(Blocks.TORCH, 8)));\n        }\n    }\n\n    public static class MinerTradesLvl2 implements EntityVillager.ITradeList {\n\n        @Override\n        public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.GOLD_INGOT, 3), new ItemStack(Items.EMERALD, 2)));\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 1), new ItemStack(Items.COAL, 3)));\n        }\n    }\n\n    public static class MinerTradesLvl3 implements EntityVillager.ITradeList {\n\n        @Override\n        public void addMerchantRecipe(IMerchant merchant, MerchantRecipeList recipeList, Random random) {\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.EMERALD, 4), new ItemStack(Items.IRON_PICKAXE, 1)));\n            recipeList.add(new MerchantRecipe(new ItemStack(Blocks.EMERALD_BLOCK, 1), new ItemStack(Items.DIAMOND_PICKAXE, 1)));\n            recipeList.add(new MerchantRecipe(new ItemStack(Items.IRON_INGOT, 8), new ItemStack(Items.DIAMOND, 1)));\n        }\n    }\n\n    private static boolean inForbiddenProfessions(VillagerProfession profIn) {\n        for (VillagerProfession profession : FORBIDDEN_RANDOM_PROFESSIONS) {\n            if (profession == profIn) {\n                return true;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/core/minecraft/RoseGoldOreGenerator.java",
    "content": "package mca.core.minecraft;\n\nimport mca.core.MCA;\nimport net.minecraft.block.Block;\nimport net.minecraft.init.Blocks;\nimport net.minecraft.util.math.BlockPos;\nimport net.minecraft.world.World;\nimport net.minecraft.world.chunk.IChunkProvider;\nimport net.minecraft.world.gen.IChunkGenerator;\nimport net.minecraft.world.gen.feature.WorldGenMinable;\nimport net.minecraftforge.fml.common.IWorldGenerator;\n\nimport java.util.Random;\n\npublic final class RoseGoldOreGenerator implements IWorldGenerator {\n    public RoseGoldOreGenerator() {\n    }\n\n    public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) {\n        if (world.provider.getDimension() == 0) generateSurface(world, random, chunkX * 16, chunkZ * 16);\n    }\n\n    private void generateSurface(World world, Random random, int x, int z) {\n        this.addOreSpawn(BlocksMCA.ROSE_GOLD_ORE, world, random, x, z, 16, 16, 6, 5);\n    }\n\n    public void addOreSpawn(Block block, World world, Random random, int blockPosX, int blockPosZ, int maxX, int maxZ, int maxVeinSize, int chancesToSpawn) {\n        if (block == BlocksMCA.ROSE_GOLD_ORE && !MCA.getConfig().allowRoseGoldGeneration) block = Blocks.STONE;\n\n        int range = 25;\n        for (int x = 0; x < chancesToSpawn; x++) {\n            int posX = blockPosX + random.nextInt(maxX);\n            int posY = 12 + random.nextInt(range);\n            int posZ = blockPosZ + random.nextInt(maxZ);\n            (new WorldGenMinable(block.getDefaultState(), maxVeinSize)).generate(world, random, new BlockPos(posX, posY, posZ));\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/core/minecraft/SoundsMCA.java",
    "content": "package mca.core.minecraft;\n\nimport net.minecraft.util.ResourceLocation;\nimport net.minecraft.util.SoundEvent;\nimport net.minecraftforge.event.RegistryEvent;\nimport net.minecraftforge.registries.IForgeRegistry;\n\npublic final class SoundsMCA {\n    private static final ResourceLocation loc_reaper_scythe_out = new ResourceLocation(\"mca:reaper.scythe.out\");\n    public static final SoundEvent reaper_scythe_out = new SoundEvent(loc_reaper_scythe_out);\n    private static final ResourceLocation loc_reaper_scythe_swing = new ResourceLocation(\"mca:reaper.scythe.swing\");\n    public static final SoundEvent reaper_scythe_swing = new SoundEvent(loc_reaper_scythe_swing);\n    private static final ResourceLocation loc_reaper_idle = new ResourceLocation(\"mca:reaper.idle\");\n    public static final SoundEvent reaper_idle = new SoundEvent(loc_reaper_idle);\n    private static final ResourceLocation loc_reaper_death = new ResourceLocation(\"mca:reaper.death\");\n    public static final SoundEvent reaper_death = new SoundEvent(loc_reaper_death);\n    private static final ResourceLocation loc_reaper_block = new ResourceLocation(\"mca:reaper.block\");\n    public static final SoundEvent reaper_block = new SoundEvent(loc_reaper_block);\n    private static final ResourceLocation loc_reaper_summon = new ResourceLocation(\"mca:reaper.summon\");\n    public static final SoundEvent reaper_summon = new SoundEvent(loc_reaper_summon);\n\n    public static void register(RegistryEvent.Register<SoundEvent> event) {\n        IForgeRegistry<SoundEvent> registry = event.getRegistry();\n        reaper_scythe_out.setRegistryName(loc_reaper_scythe_out);\n        reaper_scythe_swing.setRegistryName(loc_reaper_scythe_swing);\n        reaper_idle.setRegistryName(loc_reaper_idle);\n        reaper_death.setRegistryName(loc_reaper_death);\n        reaper_block.setRegistryName(loc_reaper_block);\n        reaper_summon.setRegistryName(loc_reaper_summon);\n\n        registry.register(reaper_scythe_out);\n        registry.register(reaper_scythe_swing);\n        registry.register(reaper_idle);\n        registry.register(reaper_death);\n        registry.register(reaper_block);\n        registry.register(reaper_summon);\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/core/minecraft/VillageHelper.java",
    "content": "package mca.core.minecraft;\n\nimport com.google.common.base.Optional;\nimport mca.core.MCA;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.entity.player.EntityPlayerMP;\nimport net.minecraft.util.math.AxisAlignedBB;\nimport net.minecraft.util.math.BlockPos;\nimport net.minecraft.util.math.Vec3d;\nimport net.minecraft.util.text.TextComponentString;\nimport net.minecraft.village.Village;\nimport net.minecraft.world.World;\n\nimport java.util.List;\n\npublic class VillageHelper {\n\n    public static void tick(World world) {\n        world.getVillageCollection().getVillageList().forEach(v -> spawnGuards(world, v));\n    }\n\n    public static void forceSpawnGuards(EntityPlayerMP player) {\n        Village nearestVillage = player.world.getVillageCollection().getNearestVillage(player.getPosition(), 100);\n        spawnGuards(player.world, nearestVillage);\n    }\n\n    public static void forceRaid(EntityPlayerMP player) {\n        Village nearestVillage = player.world.getVillageCollection().getNearestVillage(player.getPosition(), 100);\n        startRaid(player.world, nearestVillage);\n    }\n\n    private static void spawnGuards(World world, Village village) {\n        int guardCapacity = village.getNumVillagers() / MCA.getConfig().guardSpawnRate;\n        int guards = 0;\n\n        // Grab all villagers in the area\n        List<EntityVillagerMCA> list = world.getEntitiesWithinAABB(EntityVillagerMCA.class,\n                new AxisAlignedBB((double) (village.getCenter().getX() - village.getVillageRadius()),\n                        (double) (village.getCenter().getY() - 4),\n                        (double) (village.getCenter().getZ() - village.getVillageRadius()),\n                        (double) (village.getCenter().getX() + village.getVillageRadius()),\n                        (double) (village.getCenter().getY() + 4),\n                        (double) (village.getCenter().getZ() + village.getVillageRadius())));\n\n        // Count up the guards\n        for (EntityVillagerMCA villager : list) {\n            if (villager.getProfessionForge().getRegistryName().equals(ProfessionsMCA.guard.getRegistryName())) guards++;\n        }\n\n        // Spawn a new guard if we don't have enough, up to 10\n        if (guards < guardCapacity && guards < 10) {\n            Vec3d spawnPos = findRandomSpawnPos(world, village, village.getCenter(), 2, 4, 2);\n\n            if (spawnPos != null) {\n                EntityVillagerMCA guard = new EntityVillagerMCA(world, Optional.of(ProfessionsMCA.guard), Optional.absent());\n                guard.setPosition(spawnPos.x + 0.5D, spawnPos.y + 1.0D, spawnPos.z + 0.5D);\n                guard.finalizeMobSpawn(world.getDifficultyForLocation(guard.getPos()), null, false);\n                world.spawnEntity(guard);\n            }\n        }\n    }\n\n    private static void startRaid(World world, Village village) {\n        int banditsToSpawn = world.rand.nextInt(5) + 1;\n\n        while (banditsToSpawn > 0) {\n            EntityVillagerMCA bandit = new EntityVillagerMCA(world, Optional.of(ProfessionsMCA.bandit), Optional.absent());\n            BlockPos spawnLocation = village.getCenter();\n            bandit.setPosition(spawnLocation.getX(), spawnLocation.getY(), spawnLocation.getZ());\n            world.spawnEntity(bandit);\n            banditsToSpawn--;\n        }\n    }\n\n    private static Vec3d findRandomSpawnPos(World world, Village village, BlockPos pos, int x, int y, int z) {\n        for (int i = 0; i < 10; ++i) {\n            BlockPos blockpos = pos.add(world.rand.nextInt(16) - 8, world.rand.nextInt(6) - 3, world.rand.nextInt(16) - 8);\n\n            if (village.isBlockPosWithinSqVillageRadius(blockpos) && isAreaClearAround(world, new BlockPos(x, y, z), blockpos))\n                return new Vec3d((double) blockpos.getX(), (double) blockpos.getY(), (double) blockpos.getZ());\n        }\n\n        return null;\n    }\n\n    private static boolean isAreaClearAround(World world, BlockPos blockSize, BlockPos blockLocation) {\n        if (!world.getBlockState(blockLocation.down()).isTopSolid()) return false;\n        int i = blockLocation.getX() - blockSize.getX() / 2;\n        int j = blockLocation.getZ() - blockSize.getZ() / 2;\n\n        for (int k = i; k < i + blockSize.getX(); ++k) {\n            for (int l = blockLocation.getY(); l < blockLocation.getY() + blockSize.getY(); ++l) {\n                for (int i1 = j; i1 < j + blockSize.getZ(); ++i1) {\n                    if (world.getBlockState(new BlockPos(k, l, i1)).isNormalCube()) {\n                        return false;\n                    }\n                }\n            }\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/core/minecraft/WorldEventListenerMCA.java",
    "content": "package mca.core.minecraft;\n\nimport mca.core.forge.NetMCA;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.block.state.IBlockState;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.passive.EntityVillager;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.util.SoundCategory;\nimport net.minecraft.util.SoundEvent;\nimport net.minecraft.util.math.BlockPos;\nimport net.minecraft.world.IWorldEventListener;\nimport net.minecraft.world.World;\nimport net.minecraftforge.fml.common.ObfuscationReflectionHelper;\n\nimport javax.annotation.Nullable;\n\npublic class WorldEventListenerMCA implements IWorldEventListener {\n    public void notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags) {\n    }\n\n    public void notifyLightSet(BlockPos pos) {\n    }\n\n    public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) {\n    }\n\n    public void playSoundToAllNearExcept(@Nullable EntityPlayer player, SoundEvent soundIn, SoundCategory category, double x, double y, double z, float volume, float pitch) {\n    }\n\n    public void playRecord(SoundEvent soundIn, BlockPos pos) {\n    }\n\n    public void spawnParticle(int particleID, boolean ignoreRange, double xCoord, double yCoord, double zCoord, double xSpeed, double ySpeed, double zSpeed, int... parameters) {\n    }\n\n    public void spawnParticle(int id, boolean ignoreRange, boolean p_190570_3_, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed, int... parameters) {\n    }\n\n    public void onEntityAdded(Entity entityIn) {\n        // Ask the server to send the villager's career ID when it is loaded into the world client-side\n        if (entityIn instanceof EntityVillagerMCA) {\n            // Career ID is not data managed, but we depend on it to display the proper profession for the villager alongside their name.\n            // The ID is randomized client-side with populateBuyingList(), which doesn't affect anything. This throws off the career ID that we send the client.\n            // To stop this, we default the career ID and level client-side to 1. This prevents populateBuyingList() from running and allows our career ID sent from the server to apply.\n            ObfuscationReflectionHelper.setPrivateValue(EntityVillager.class, (EntityVillagerMCA) entityIn, 1, EntityVillagerMCA.VANILLA_CAREER_ID_FIELD_INDEX);\n            ObfuscationReflectionHelper.setPrivateValue(EntityVillager.class, (EntityVillagerMCA) entityIn, 1, EntityVillagerMCA.VANILLA_CAREER_LEVEL_FIELD_INDEX);\n            NetMCA.INSTANCE.sendToServer(new NetMCA.CareerRequest(entityIn.getUniqueID()));\n\n            // The villager's inventory is also not synced to the client until it is opened in a Container.\n            // When the entity joins the client world, ask the server to send over the inventory data.\n            NetMCA.INSTANCE.sendToServer(new NetMCA.InventoryRequest(entityIn.getUniqueID()));\n        }\n    }\n\n    public void onEntityRemoved(Entity entityIn) {\n    }\n\n    public void broadcastSound(int soundID, BlockPos pos, int data) {\n    }\n\n    public void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data) {\n    }\n\n    public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) {\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/entity/EntityGrimReaper.java",
    "content": "package mca.entity;\n\n\nimport mca.core.MCA;\nimport mca.core.minecraft.ItemsMCA;\nimport mca.core.minecraft.SoundsMCA;\nimport mca.enums.EnumReaperAttackState;\nimport mca.util.Util;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.EntityLivingBase;\nimport net.minecraft.entity.SharedMonsterAttributes;\nimport net.minecraft.entity.ai.*;\nimport net.minecraft.entity.effect.EntityLightningBolt;\nimport net.minecraft.entity.monster.EntityMob;\nimport net.minecraft.entity.monster.EntitySkeleton;\nimport net.minecraft.entity.monster.EntityZombie;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.entity.player.EntityPlayerMP;\nimport net.minecraft.entity.player.InventoryPlayer;\nimport net.minecraft.entity.projectile.EntityArrow;\nimport net.minecraft.init.Items;\nimport net.minecraft.init.MobEffects;\nimport net.minecraft.init.SoundEvents;\nimport net.minecraft.inventory.EntityEquipmentSlot;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.network.datasync.DataParameter;\nimport net.minecraft.network.datasync.DataSerializers;\nimport net.minecraft.network.datasync.EntityDataManager;\nimport net.minecraft.potion.PotionEffect;\nimport net.minecraft.util.DamageSource;\nimport net.minecraft.util.SoundEvent;\nimport net.minecraft.util.math.MathHelper;\nimport net.minecraft.world.BossInfo;\nimport net.minecraft.world.BossInfoServer;\nimport net.minecraft.world.World;\n\npublic class EntityGrimReaper extends EntityMob {\n    private static final DataParameter<Integer> ATTACK_STATE = EntityDataManager.<Integer>createKey(EntityGrimReaper.class, DataSerializers.VARINT);\n    private static final DataParameter<Integer> STATE_TRANSITION_COOLDOWN = EntityDataManager.<Integer>createKey(EntityGrimReaper.class, DataSerializers.VARINT);\n\n    private final BossInfoServer bossInfo = (BossInfoServer) (new BossInfoServer(this.getDisplayName(), BossInfo.Color.PURPLE, BossInfo.Overlay.PROGRESS)).setDarkenSky(true);\n    private EntityAINearestAttackableTarget aiNearestAttackableTarget = new EntityAINearestAttackableTarget(this, EntityPlayer.class, true);\n    private int healingCooldown;\n    private int timesHealed;\n\n    private float floatingTicks;\n\n    public EntityGrimReaper(World world) {\n        super(world);\n        setSize(1.0F, 2.6F);\n        this.experienceValue = 100;\n\n        this.tasks.addTask(1, new EntityAISwimming(this));\n        this.tasks.addTask(4, new EntityAIWander(this, 1.0D));\n        this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));\n        this.tasks.addTask(6, new EntityAILookIdle(this));\n        this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false, new Class[0]));\n        this.targetTasks.addTask(2, aiNearestAttackableTarget);\n    }\n\n    @Override\n    protected final void applyEntityAttributes() {\n        super.applyEntityAttributes();\n        this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(40.0D);\n        this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.30F);\n        this.getEntityAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(12.5F);\n        this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(225.0F);\n    }\n\n    @Override\n    protected void dropFewItems(boolean hitByPlayer, int lootingLvl) {\n        dropItem(ItemsMCA.STAFF_OF_LIFE, 1);\n    }\n\n    @Override\n    protected void entityInit() {\n        super.entityInit();\n        this.dataManager.register(ATTACK_STATE, 0);\n        this.dataManager.register(STATE_TRANSITION_COOLDOWN, 0);\n    }\n\n    public EnumReaperAttackState getAttackState() {\n        return EnumReaperAttackState.fromId(this.dataManager.get(ATTACK_STATE));\n    }\n\n    public void setAttackState(EnumReaperAttackState state) {\n        // Only update if needed so that sounds only play once.\n        if (this.dataManager.get(ATTACK_STATE) != state.getId()) {\n            this.dataManager.set(ATTACK_STATE, state.getId());\n\n            switch (state) {\n                case PRE:\n                    this.playSound(SoundsMCA.reaper_scythe_out, 1.0F, 1.0F);\n                    break;\n                case POST:\n                    this.playSound(SoundsMCA.reaper_scythe_swing, 1.0F, 1.0F);\n                    break;\n            }\n        }\n    }\n\n    public boolean hasEntityToAttack() {\n        return this.getAttackTarget() != null;\n    }\n\n    @Override\n    public void onStruckByLightning(EntityLightningBolt entity) {\n        return;\n    }\n\n    @Override\n    public boolean attackEntityFrom(DamageSource source, float damage) {\n        bossInfo.setPercent(this.getHealth() / this.getMaxHealth());\n\n        // Ignore wall damage and fire damage.\n        if (source == DamageSource.IN_WALL || source == DamageSource.ON_FIRE || source.isExplosion() || source == DamageSource.IN_FIRE) {\n            // Teleport out of any walls we may end up in.\n            if (source == DamageSource.IN_WALL) {\n                teleportTo(this.posX, this.posY + 3, this.posZ);\n            }\n\n            return false;\n        }\n\n        // Ignore damage when blocking, and teleport behind the player when they attempt to block.\n        else if (!world.isRemote && this.getAttackState() == EnumReaperAttackState.BLOCK && source.getImmediateSource() instanceof EntityPlayer) {\n            EntityPlayer player = (EntityPlayer) source.getImmediateSource();\n\n            double deltaX = this.posX - player.posX;\n            double deltaZ = this.posZ - player.posZ;\n\n            this.playSound(SoundsMCA.reaper_block, 1.0F, 1.0F);\n            teleportTo(player.posX - (deltaX * 2), player.posY + 2, this.posZ - (deltaZ * 2));\n            setStateTransitionCooldown(0);\n            return false;\n        }\n\n        // Randomly portal behind the player who just attacked.\n        else if (!world.isRemote && source.getImmediateSource() instanceof EntityPlayer && rand.nextFloat() >= 0.30F) {\n            EntityPlayer player = (EntityPlayer) source.getImmediateSource();\n\n            double deltaX = this.posX - player.posX;\n            double deltaZ = this.posZ - player.posZ;\n\n            teleportTo(player.posX - (deltaX * 2), player.posY + 2, this.posZ - (deltaZ * 2));\n        }\n\n        // Teleport behind the player who fired an arrow and ignore its damage.\n        else if (source.getImmediateSource() instanceof EntityArrow) {\n            EntityArrow arrow = (EntityArrow) source.getImmediateSource();\n\n            if (arrow.shootingEntity instanceof EntityPlayer && getAttackState() != EnumReaperAttackState.REST) {\n                EntityPlayer player = (EntityPlayer) arrow.shootingEntity;\n                double newX = player.posX + rand.nextFloat() >= 0.50F ? 2 : -2;\n                double newZ = player.posZ + rand.nextFloat() >= 0.50F ? 2 : -2;\n\n                teleportTo(newX, player.posY, newZ);\n            }\n\n            arrow.setDead();\n            return false;\n        }\n\n        // Still take damage when healing, but reduced by a third.\n        else if (this.getAttackState() == EnumReaperAttackState.REST) {\n            damage /= 3;\n        }\n\n        super.attackEntityFrom(source, damage);\n\n        if (!world.isRemote && this.getHealth() <= (this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).getBaseValue() / 2) && healingCooldown == 0) {\n            setAttackState(EnumReaperAttackState.REST);\n            healingCooldown = 4200; // 3 minutes 30 seconds\n            teleportTo(this.posX, this.posY + 8, this.posZ);\n            setStateTransitionCooldown(1200); // 1 minute\n        }\n\n        return true;\n    }\n\n    protected void attackEntity(Entity entity, float damage) {\n        EntityLivingBase entityToAttack = this.getAttackTarget();\n        if (entityToAttack == null) return;\n\n        // Set attack state to post attack.\n        // If we're blocking, we will teleport away instead of attacking to prevent an unfair attack.\n        // Attacking us WHILE we're blocking will cause us to attack, however.\n        if (this.getDistance(entityToAttack) <= 0.8D && getAttackState() == EnumReaperAttackState.PRE) {\n            if (getAttackState() == EnumReaperAttackState.BLOCK) {\n                int rX = this.getRNG().nextInt(10);\n                int rZ = this.getRNG().nextInt(10);\n                teleportTo(this.posX + 5 + rX, this.posY, this.posZ + rZ);\n            } else {\n                entity.attackEntityFrom(DamageSource.causeMobDamage(this), this.world.getDifficulty().getDifficultyId() * 5.75F);\n\n                if (entity instanceof EntityLivingBase) {\n                    ((EntityLivingBase) entity).addPotionEffect(new PotionEffect(MobEffects.WITHER, this.world.getDifficulty().getDifficultyId() * 20, 1));\n                }\n\n                setAttackState(EnumReaperAttackState.POST);\n                setStateTransitionCooldown(10); // For preventing immediate return to the PRE or IDLE stage. Ticked down in onUpdate()\n            }\n        }\n\n        // Check if we're waiting for cooldown from the last attack.\n        if (getStateTransitionCooldown() == 0) {\n            // Within 3 blocks from the target, ready the scythe\n            if (getDistance(entityToAttack) <= 3.5D) {\n                // Check to see if the player's blocking, then teleport behind them.\n                // Also randomly swap their selected item with something else in the hotbar and apply blindness.\n                if (entityToAttack instanceof EntityPlayer) {\n                    EntityPlayer player = (EntityPlayer) entityToAttack;\n\n                    if (player.isActiveItemStackBlocking()) {\n                        double dX = this.posX - player.posX;\n                        double dZ = this.posZ - player.posZ;\n\n                        teleportTo(player.posX - (dX * 2), player.posY + 2, this.posZ - (dZ * 2));\n\n                        if (!world.isRemote && rand.nextFloat() >= 0.20F) {\n                            int currentItem = player.inventory.currentItem;\n                            int randomItem = rand.nextInt(InventoryPlayer.getHotbarSize());\n                            ItemStack currentItemStack = player.inventory.mainInventory.get(currentItem);\n                            ItemStack randomItemStack = player.inventory.mainInventory.get(randomItem);\n\n                            player.inventory.mainInventory.set(currentItem, randomItemStack);\n                            player.inventory.mainInventory.set(randomItem, currentItemStack);\n\n                            player.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, this.world.getDifficulty().getDifficultyId() * 40, 1));\n                        }\n                    } else // If the player is not blocking, ready the scythe, or randomly block their attack.\n                    {\n                        // Don't block if we've already committed to an attack.\n                        if (rand.nextFloat() >= 40.0F && getAttackState() != EnumReaperAttackState.PRE) {\n                            setStateTransitionCooldown(20);\n                            setAttackState(EnumReaperAttackState.BLOCK);\n                        } else {\n                            setAttackState(EnumReaperAttackState.PRE);\n                            setStateTransitionCooldown(20);\n                        }\n                    }\n                }\n            } else // Reset the attacking state when we're more than 3 blocks away.\n            {\n                setAttackState(EnumReaperAttackState.IDLE);\n            }\n        }\n    }\n\n    protected Entity findPlayerToAttack() {\n        return world.getClosestPlayerToEntity(this, 48.0D);\n    }\n\n    @Override\n    public int getTalkInterval() {\n        return 300;\n    }\n\n    @Override\n    protected SoundEvent getAmbientSound() {\n        return SoundsMCA.reaper_idle;\n    }\n\n    @Override\n    protected SoundEvent getDeathSound() {\n        return SoundsMCA.reaper_death;\n    }\n\n    @Override\n    protected SoundEvent getHurtSound(DamageSource source) {\n        return SoundEvents.ENTITY_WITHER_HURT;\n    }\n\n    @Override\n    public void onUpdate() {\n        super.onUpdate();\n        extinguish(); // No fire.\n\n        if (!MCA.getConfig().allowGrimReaper) {\n            setDead();\n        }\n\n        EntityLivingBase entityToAttack = this.getAttackTarget();\n\n        if (entityToAttack != null && getAttackState() != EnumReaperAttackState.REST) {\n            attackEntity(entityToAttack, 5.0F);\n            this.getMoveHelper().setMoveTo(entityToAttack.posX, entityToAttack.posY, entityToAttack.posZ, 6.0F);\n        }\n\n        // Increment floating ticks on the client when resting.\n        if (world.isRemote && getAttackState() == EnumReaperAttackState.REST) {\n            floatingTicks += 0.1F;\n        }\n\n        // Increase health when resting and check to stop rest state.\n        // Runs on common to spawn lightning.\n        if (getAttackState() == EnumReaperAttackState.REST) {\n            if (!world.isRemote && getStateTransitionCooldown() == 1) {\n                setAttackState(EnumReaperAttackState.IDLE);\n                timesHealed++;\n            } else if (!world.isRemote && getStateTransitionCooldown() % 100 == 0) {\n                this.setHealth(this.getHealth() + MathHelper.clamp(10.5F - (timesHealed * 3.5F), 3.0F, 10.5F));\n\n                // Let's have a light show.\n                int dX = rand.nextInt(8) + 4 * rand.nextFloat() >= 0.50F ? 1 : -1;\n                int dZ = rand.nextInt(8) + 4 * rand.nextFloat() >= 0.50F ? 1 : -1;\n                int y = Util.getSpawnSafeTopLevel(world, (int) posX + dX, 256, (int) posZ + dZ);\n\n                EntityLightningBolt bolt = new EntityLightningBolt(world, dX, y, dZ, false);\n                world.addWeatherEffect(bolt);\n\n                // Also spawn a random skeleton or zombie.\n                if (!world.isRemote) {\n                    EntityMob mob = rand.nextFloat() >= 0.50F ? new EntityZombie(world) : new EntitySkeleton(world);\n                    mob.setPosition(posX + dX + 4, y, posZ + dZ + 4);\n\n                    if (mob instanceof EntitySkeleton) {\n                        mob.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.BOW));\n                    }\n\n                    world.spawnEntity(mob);\n                }\n            }\n        }\n\n        // Prevent flying off into oblivion on death...\n        if (this.getHealth() <= 0.0F) {\n            motionX = 0;\n            motionY = 0;\n            motionZ = 0;\n            return;\n        }\n\n        // Stop at our current position if resting\n        if (getAttackState() == EnumReaperAttackState.REST) {\n            motionX = 0;\n            motionY = 0;\n            motionZ = 0;\n        }\n\n        // Logic for flying.\n        fallDistance = 0.0F;\n\n        if (motionY > 0) {\n            motionY = motionY * 1.04F;\n        } else {\n            double yMod = Math.sqrt((motionX * motionX) + (motionZ * motionZ));\n            motionY = motionY * 0.6F + yMod * 0.3F;\n        }\n\n        // Tick down cooldowns.\n        if (getStateTransitionCooldown() > 0) {\n            setStateTransitionCooldown(getStateTransitionCooldown() - 1);\n        }\n\n        if (healingCooldown > 0) {\n            healingCooldown--;\n        }\n\n        // See if our entity to attack has died at any point.\n        if (entityToAttack != null && entityToAttack.isDead) {\n            this.setAttackTarget(null);\n            setAttackState(EnumReaperAttackState.IDLE);\n        }\n\n        // Move towards target if we're not resting\n        if (entityToAttack != null && getAttackState() != EnumReaperAttackState.REST) {\n            // If we have a creature to attack, we need to move downwards if we're above it, and vice-versa.\n            double sqDistanceTo = Math.sqrt(Math.pow(entityToAttack.posX - posX, 2) + Math.pow(entityToAttack.posZ - posZ, 2));\n            float moveAmount = 0.0F;\n\n            if (sqDistanceTo < 8F) {\n                moveAmount = MathHelper.clamp(((8F - (float) sqDistanceTo) / 8F) * 4F, 0, 2.5F);\n            }\n\n            if (entityToAttack.posY + 0.2F < posY) {\n                motionY = motionY - 0.05F * moveAmount;\n            }\n\n            if (entityToAttack.posY - 0.5F > posY) {\n                motionY = motionY + 0.01F * moveAmount;\n            }\n        }\n    }\n\n    @Override\n    public void onDeath(DamageSource source) {\n        super.onDeath(source);\n    }\n\n    @Override\n    public String getName() {\n        return \"Grim Reaper\";\n    }\n\n    @Override\n    protected boolean canDespawn() {\n        return true;\n    }\n\n    public int getStateTransitionCooldown() {\n        return this.dataManager.get(STATE_TRANSITION_COOLDOWN);\n    }\n\n    public void setStateTransitionCooldown(int value) {\n        this.dataManager.set(STATE_TRANSITION_COOLDOWN, value);\n    }\n\n    public float getFloatingTicks() {\n        return floatingTicks;\n    }\n\n    private void teleportTo(double x, double y, double z) {\n        if (!world.isRemote) {\n            this.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 2.0F, 1.0F);\n            this.setPosition(x, y, z);\n            this.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 2.0F, 1.0F);\n        }\n    }\n\n    @Override\n    public boolean isNonBoss() {\n        return false;\n    }\n\n    /**\n     * Add the given player to the list of players tracking this entity. For instance, a player may track a boss in\n     * order to view its associated boss bar.\n     */\n    @Override\n    public void addTrackingPlayer(EntityPlayerMP player) {\n        super.addTrackingPlayer(player);\n        this.bossInfo.addPlayer(player);\n    }\n\n    /**\n     * Removes the given player from the list of players tracking this entity. See {@link Entity#addTrackingPlayer} for\n     * more information on tracking.\n     */\n    @Override\n    public void removeTrackingPlayer(EntityPlayerMP player) {\n        super.removeTrackingPlayer(player);\n        this.bossInfo.removePlayer(player);\n    }\n\n}"
  },
  {
    "path": "src/main/java/mca/entity/EntityVillagerMCA.java",
    "content": "package mca.entity;\n\nimport com.google.common.base.Optional;\nimport com.google.common.base.Predicate;\nimport mca.api.API;\nimport mca.api.types.APIButton;\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.core.forge.NetMCA;\nimport mca.core.minecraft.ItemsMCA;\nimport mca.core.minecraft.ProfessionsMCA;\nimport mca.entity.ai.*;\nimport mca.entity.data.ParentData;\nimport mca.entity.data.PlayerHistory;\nimport mca.entity.data.PlayerSaveData;\nimport mca.entity.data.SavedVillagers;\nimport mca.entity.inventory.InventoryMCA;\nimport mca.enums.*;\nimport mca.items.ItemSpecialCaseGift;\nimport mca.util.ItemStackCache;\nimport mca.util.ResourceLocationCache;\nimport mca.util.Util;\nimport net.minecraft.block.BlockBed;\nimport net.minecraft.block.BlockHorizontal;\nimport net.minecraft.block.state.IBlockState;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.SharedMonsterAttributes;\nimport net.minecraft.entity.ai.*;\nimport net.minecraft.entity.monster.EntityVex;\nimport net.minecraft.entity.monster.EntityVindicator;\nimport net.minecraft.entity.monster.EntityZombie;\nimport net.minecraft.entity.passive.EntityHorse;\nimport net.minecraft.entity.passive.EntityVillager;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.entity.player.EntityPlayerMP;\nimport net.minecraft.init.Blocks;\nimport net.minecraft.init.Items;\nimport net.minecraft.init.SoundEvents;\nimport net.minecraft.inventory.EntityEquipmentSlot;\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.nbt.NBTTagCompound;\nimport net.minecraft.network.datasync.DataParameter;\nimport net.minecraft.network.datasync.DataSerializers;\nimport net.minecraft.network.datasync.EntityDataManager;\nimport net.minecraft.util.*;\nimport net.minecraft.util.math.BlockPos;\nimport net.minecraft.util.math.Vec3d;\nimport net.minecraft.util.registry.RegistryNamespaced;\nimport net.minecraft.util.text.ITextComponent;\nimport net.minecraft.util.text.TextComponentString;\nimport net.minecraft.util.text.TextComponentTranslation;\nimport net.minecraft.world.World;\nimport net.minecraftforge.fml.common.ObfuscationReflectionHelper;\nimport net.minecraftforge.fml.common.registry.VillagerRegistry;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\n\nimport javax.annotation.Nonnull;\nimport javax.annotation.Nullable;\nimport java.util.*;\n\nimport static net.minecraft.block.BlockBed.OCCUPIED;\nimport static net.minecraft.block.BlockBed.PART;\n\npublic class EntityVillagerMCA extends EntityVillager {\n    public static final int VANILLA_CAREER_ID_FIELD_INDEX = 13;\n    public static final int VANILLA_CAREER_LEVEL_FIELD_INDEX = 14;\n\n    public static final DataParameter<String> VILLAGER_NAME = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.STRING);\n    public static final DataParameter<String> TEXTURE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.STRING);\n    public static final DataParameter<Integer> GENDER = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);\n    public static final DataParameter<Float> GIRTH = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.FLOAT);\n    public static final DataParameter<Float> TALLNESS = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.FLOAT);\n    public static final DataParameter<NBTTagCompound> PLAYER_HISTORY_MAP = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.COMPOUND_TAG);\n    public static final DataParameter<Integer> MOVE_STATE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);\n    public static final DataParameter<String> SPOUSE_NAME = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.STRING);\n    public static final DataParameter<Optional<UUID>> SPOUSE_UUID = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.OPTIONAL_UNIQUE_ID);\n    public static final DataParameter<Integer> MARRIAGE_STATE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);\n    public static final DataParameter<Boolean> IS_PROCREATING = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);\n    public static final DataParameter<NBTTagCompound> PARENTS = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.COMPOUND_TAG);\n    public static final DataParameter<Boolean> IS_INFECTED = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);\n    public static final DataParameter<Integer> AGE_STATE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);\n    public static final DataParameter<Integer> ACTIVE_CHORE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);\n    public static final DataParameter<Boolean> IS_SWINGING = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);\n    public static final DataParameter<Boolean> HAS_BABY = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);\n    public static final DataParameter<Boolean> BABY_IS_MALE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);\n    public static final DataParameter<Integer> BABY_AGE = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.VARINT);\n    public static final DataParameter<Optional<UUID>> CHORE_ASSIGNING_PLAYER = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.OPTIONAL_UNIQUE_ID);\n    public static final DataParameter<BlockPos> BED_POS = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BLOCK_POS);\n    public static final DataParameter<BlockPos> WORKPLACE_POS = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BLOCK_POS);\n    public static final DataParameter<BlockPos> HANGOUT_POS = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BLOCK_POS);\n    public static final DataParameter<Boolean> SLEEPING = EntityDataManager.createKey(EntityVillagerMCA.class, DataSerializers.BOOLEAN);\n\n    private static final Predicate<EntityVillagerMCA> BANDIT_TARGET_SELECTOR = (v) -> v.getProfessionForge() != ProfessionsMCA.bandit && v.getProfessionForge() != ProfessionsMCA.child;\n    private static final Predicate<EntityVillagerMCA> GUARD_TARGET_SELECTOR = (v) -> v.getProfessionForge() == ProfessionsMCA.bandit;\n\n    public final InventoryMCA inventory;\n    public int babyAge = 0;\n    public UUID playerToFollowUUID = Constants.ZERO_UUID;\n\n    private BlockPos home = BlockPos.ORIGIN;\n    private int startingAge = 0;\n    private float swingProgressTicks;\n\n    public float renderOffsetX;\n    public float renderOffsetY;\n    public float renderOffsetZ;\n\n    public EntityVillagerMCA() {\n        super(null);\n        inventory = null;\n    }\n\n    public EntityVillagerMCA(World worldIn) {\n        super(worldIn);\n        inventory = new InventoryMCA(this);\n    }\n\n    public EntityVillagerMCA(World worldIn, Optional<VillagerRegistry.VillagerProfession> profession, Optional<EnumGender> gender) {\n        this(worldIn);\n\n        if (!worldIn.isRemote) {\n            EnumGender eGender = gender.isPresent() ? gender.get() : EnumGender.getRandom();\n            set(GENDER, eGender.getId());\n            set(VILLAGER_NAME, API.getRandomName(eGender));\n            setProfession(profession.isPresent() ? profession.get() : ProfessionsMCA.randomProfession());\n            setVanillaCareer(getProfessionForge().getRandomCareer(worldIn.rand));\n            set(TEXTURE, API.getRandomSkin(this));\n\n            applySpecialAI();\n        }\n    }\n\n    @Override\n    protected void entityInit() {\n        super.entityInit();\n        this.dataManager.register(VILLAGER_NAME, \"\");\n        this.dataManager.register(TEXTURE, \"\");\n        this.dataManager.register(GENDER, EnumGender.MALE.getId());\n        this.dataManager.register(GIRTH, 0.0F);\n        this.dataManager.register(TALLNESS, 0.0F);\n        this.dataManager.register(PLAYER_HISTORY_MAP, new NBTTagCompound());\n        this.dataManager.register(MOVE_STATE, EnumMoveState.MOVE.getId());\n        this.dataManager.register(SPOUSE_NAME, \"\");\n        this.dataManager.register(SPOUSE_UUID, Optional.of(Constants.ZERO_UUID));\n        this.dataManager.register(MARRIAGE_STATE, EnumMarriageState.NOT_MARRIED.getId());\n        this.dataManager.register(IS_PROCREATING, false);\n        this.dataManager.register(PARENTS, new NBTTagCompound());\n        this.dataManager.register(IS_INFECTED, false);\n        this.dataManager.register(AGE_STATE, EnumAgeState.ADULT.getId());\n        this.dataManager.register(ACTIVE_CHORE, EnumChore.NONE.getId());\n        this.dataManager.register(IS_SWINGING, false);\n        this.dataManager.register(HAS_BABY, false);\n        this.dataManager.register(BABY_IS_MALE, false);\n        this.dataManager.register(BABY_AGE, 0);\n        this.dataManager.register(CHORE_ASSIGNING_PLAYER, Optional.of(Constants.ZERO_UUID));\n        this.dataManager.register(BED_POS, BlockPos.ORIGIN);\n        this.dataManager.register(WORKPLACE_POS, BlockPos.ORIGIN);\n        this.dataManager.register(HANGOUT_POS, BlockPos.ORIGIN);\n        this.dataManager.register(SLEEPING, false);\n        this.setSilent(false);\n    }\n\n    @Override\n    protected void applyEntityAttributes() {\n        super.applyEntityAttributes();\n        this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(MCA.getConfig().villagerMaxHealth);\n        this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(32.0D);\n\n        if (this.getHealth() <= MCA.getConfig().villagerMaxHealth) {\n            this.setHealth(MCA.getConfig().villagerMaxHealth);\n        }\n    }\n\n    public <T> T get(DataParameter<T> key) {\n        return this.dataManager.get(key);\n    }\n\n    public <T> void set(DataParameter<T> key, T value) {\n        this.dataManager.set(key, value);\n    }\n\n    @Override\n    public boolean attackEntityAsMob(@Nonnull Entity entityIn) {\n        super.attackEntityAsMob(entityIn);\n        return entityIn.attackEntityFrom(DamageSource.causeMobDamage(this), this.getProfessionForge() == ProfessionsMCA.guard ? 9.0F : 2.0F);\n    }\n\n    @Override\n    public void readEntityFromNBT(NBTTagCompound nbt) {\n        super.readEntityFromNBT(nbt);\n        set(VILLAGER_NAME, nbt.getString(\"name\"));\n        set(GENDER, nbt.getInteger(\"gender\"));\n        set(TEXTURE, nbt.getString(\"texture\"));\n        set(GIRTH, nbt.getFloat(\"girth\"));\n        set(TALLNESS, nbt.getFloat(\"tallness\"));\n        set(PLAYER_HISTORY_MAP, nbt.getCompoundTag(\"playerHistoryMap\"));\n        set(MOVE_STATE, nbt.getInteger(\"moveState\"));\n        set(MARRIAGE_STATE, nbt.getInteger(\"marriageState\"));\n        set(SPOUSE_UUID, Optional.of(nbt.getUniqueId(\"spouseUUID\")));\n        set(SPOUSE_NAME, nbt.getString(\"spouseName\"));\n        set(IS_PROCREATING, nbt.getBoolean(\"isProcreating\"));\n        set(IS_INFECTED, nbt.getBoolean(\"infected\"));\n        set(AGE_STATE, nbt.getInteger(\"ageState\"));\n        set(ACTIVE_CHORE, nbt.getInteger(\"activeChore\"));\n        set(CHORE_ASSIGNING_PLAYER, Optional.of(nbt.getUniqueId(\"choreAssigningPlayer\")));\n        set(HAS_BABY, nbt.getBoolean(\"hasBaby\"));\n        set(BABY_IS_MALE, nbt.getBoolean(\"babyIsMale\"));\n        set(PARENTS, nbt.getCompoundTag(\"parents\"));\n        set(BED_POS, new BlockPos(nbt.getInteger(\"bedX\"), nbt.getInteger(\"bedY\"), nbt.getInteger(\"bedZ\")));\n        set(HANGOUT_POS, new BlockPos(nbt.getInteger(\"hangoutX\"), nbt.getInteger(\"hangoutY\"), nbt.getInteger(\"hangoutZ\")));\n        set(WORKPLACE_POS, new BlockPos(nbt.getInteger(\"workplaceX\"), nbt.getInteger(\"workplaceY\"), nbt.getInteger(\"workplaceZ\")));\n        set(SLEEPING, nbt.getBoolean(\"sleeping\"));\n        inventory.readInventoryFromNBT(nbt.getTagList(\"inventory\", 10));\n\n        // Vanilla Age doesn't apply from the superclass call. Causes children to revert to the starting age on world reload.\n        this.startingAge = nbt.getInteger(\"startingAge\");\n        setGrowingAge(nbt.getInteger(\"Age\"));\n\n        this.home = new BlockPos(nbt.getDouble(\"homePositionX\"), nbt.getDouble(\"homePositionY\"), nbt.getDouble(\"homePositionZ\"));\n        this.playerToFollowUUID = nbt.getUniqueId(\"playerToFollowUUID\");\n        this.babyAge = nbt.getInteger(\"babyAge\");\n\n        applySpecialAI();\n    }\n\n    @Override\n    public void writeEntityToNBT(NBTTagCompound nbt) {\n        super.writeEntityToNBT(nbt);\n        nbt.setUniqueId(\"uuid\", this.getUniqueID()); // for SavedVillagers\n        nbt.setString(\"name\", get(VILLAGER_NAME));\n        nbt.setString(\"texture\", get(TEXTURE));\n        nbt.setInteger(\"gender\", get(GENDER));\n        nbt.setFloat(\"girth\", get(GIRTH));\n        nbt.setFloat(\"tallness\", get(TALLNESS));\n        nbt.setTag(\"playerHistoryMap\", get(PLAYER_HISTORY_MAP));\n        nbt.setInteger(\"moveState\", get(MOVE_STATE));\n        nbt.setInteger(\"marriageState\", get(MARRIAGE_STATE));\n        nbt.setDouble(\"homePositionX\", home.getX());\n        nbt.setDouble(\"homePositionY\", home.getY());\n        nbt.setDouble(\"homePositionZ\", home.getZ());\n        nbt.setUniqueId(\"playerToFollowUUID\", playerToFollowUUID);\n        nbt.setUniqueId(\"spouseUUID\", get(SPOUSE_UUID).or(Constants.ZERO_UUID));\n        nbt.setString(\"spouseName\", get(SPOUSE_NAME));\n        nbt.setBoolean(\"isProcreating\", get(IS_PROCREATING));\n        nbt.setBoolean(\"infected\", get(IS_INFECTED));\n        nbt.setInteger(\"ageState\", get(AGE_STATE));\n        nbt.setInteger(\"startingAge\", startingAge);\n        nbt.setInteger(\"activeChore\", get(ACTIVE_CHORE));\n        nbt.setUniqueId(\"choreAssigningPlayer\", get(CHORE_ASSIGNING_PLAYER).or(Constants.ZERO_UUID));\n        nbt.setTag(\"inventory\", inventory.writeInventoryToNBT());\n        nbt.setInteger(\"babyAge\", babyAge);\n        nbt.setTag(\"parents\", get(PARENTS));\n        nbt.setInteger(\"bedX\", get(BED_POS).getX());\n        nbt.setInteger(\"bedY\", get(BED_POS).getY());\n        nbt.setInteger(\"bedZ\", get(BED_POS).getZ());\n        nbt.setInteger(\"workplaceX\", get(WORKPLACE_POS).getX());\n        nbt.setInteger(\"workplaceY\", get(WORKPLACE_POS).getY());\n        nbt.setInteger(\"workplaceZ\", get(WORKPLACE_POS).getZ());\n        nbt.setInteger(\"hangoutX\", get(HANGOUT_POS).getX());\n        nbt.setInteger(\"hangoutY\", get(HANGOUT_POS).getY());\n        nbt.setInteger(\"hangoutZ\", get(HANGOUT_POS).getZ());\n        nbt.setBoolean(\"sleeping\", get(SLEEPING));\n    }\n\n    @Override\n    protected void damageEntity(@Nonnull DamageSource damageSource, float damageAmount) {\n        // Guards take 50% less damage\n        if (getProfessionForge() == ProfessionsMCA.guard) {\n            damageAmount *= 0.50;\n        }\n        super.damageEntity(damageSource, damageAmount);\n\n        // Check for infection to apply. Does not affect guards.\n        if (MCA.getConfig().enableInfection && getProfessionForge() != ProfessionsMCA.guard && damageSource.getImmediateSource() instanceof EntityZombie && getRNG().nextFloat() < MCA.getConfig().infectionChance / 100) {\n            set(IS_INFECTED, true);\n        }\n    }\n\n    @Override\n    public void onUpdate() {\n        super.onUpdate();\n        updateSwinging();\n        updateSleeping();\n\n        if (this.isServerWorld()) {\n            onEachServerUpdate();\n        } else {\n            onEachClientUpdate();\n        }\n    }\n\n    @Override\n    protected SoundEvent getAmbientSound() {\n        return null;\n    }\n\n    @Override\n    protected SoundEvent getHurtSound(DamageSource damageSourceIn) {\n        return SoundEvents.ENTITY_GENERIC_HURT;\n    }\n\n    @Override\n    protected SoundEvent getDeathSound() {\n        return get(IS_INFECTED) ? SoundEvents.ENTITY_ZOMBIE_DEATH : null;\n    }\n\n    @Override\n    public boolean processInteract(EntityPlayer player, @Nonnull EnumHand hand) {\n        // No-op, handled by EventHooks\n        return true;\n    }\n\n    @Override\n    public void onDeath(@Nonnull DamageSource cause) {\n        if (!world.isRemote) {\n            if (MCA.getConfig().logVillagerDeaths) {\n                String causeName = cause.getImmediateSource() == null ? \"Unknown\" : cause.getImmediateSource().getName();\n                MCA.getLog().info(\"Villager death: \" + get(VILLAGER_NAME) + \". Caused by: \" + causeName + \". UUID: \" + this.getUniqueID().toString());\n            }\n\n            //TODO: player history gets lsot on revive\n            //TODO: childp becomes to child on revive (needs verification)\n\n            inventory.dropAllItems();\n            inventory.clear(); //fixes issue #1227, dropAllItems() should clear, but it does not work\n\n            if (isMarried()) {\n                UUID spouseUUID = get(SPOUSE_UUID).or(Constants.ZERO_UUID);\n                Optional<EntityVillagerMCA> spouse = Util.getEntityByUUID(world, spouseUUID, EntityVillagerMCA.class);\n                PlayerSaveData playerSaveData = PlayerSaveData.getExisting(world, spouseUUID);\n\n                // Notify spouse of the death\n                if (spouse.isPresent()) {\n                    spouse.get().endMarriage();\n                } else if (playerSaveData != null) {\n                    playerSaveData.endMarriage();\n                    EntityPlayer player = world.getPlayerEntityByUUID(spouseUUID);\n                    if (player != null) {\n                        player.sendMessage(new TextComponentString(Constants.Color.RED + MCA.getLocalizer().localize(\"notify.spousedied\", get(VILLAGER_NAME), cause.getImmediateSource().getName())));\n                    }\n                }\n            }\n\n            // Notify all parents of the death\n            ParentData parents = ParentData.fromNBT(get(PARENTS));\n            Arrays.stream(parents.getParentEntities(world))\n                    .filter(e -> e instanceof EntityPlayer)\n                    .forEach(e -> {\n                        EntityPlayer player = (EntityPlayer) e;\n                        player.sendMessage(new TextComponentString(Constants.Color.RED + MCA.getLocalizer().localize(\"notify.childdied\", get(VILLAGER_NAME), cause.getImmediateSource().getName())));\n                    });\n\n            SavedVillagers.get(world).save(this);\n        }\n    }\n\n    @Override\n    protected void onGrowingAdult() {\n        Entity[] parents = ParentData.fromNBT(get(PARENTS)).getParentEntities(world);\n        set(AGE_STATE, EnumAgeState.ADULT.getId());\n        Arrays.stream(parents).filter((e) -> e instanceof EntityPlayer).forEach((e) -> {\n            PlayerHistory history = getPlayerHistoryFor(e.getUniqueID());\n            history.setDialogueType(EnumDialogueType.ADULT);\n            e.sendMessage(new TextComponentString(MCA.getLocalizer().localize(\"notify.child.grownup\", this.get(VILLAGER_NAME))));\n        });\n\n        // set profession away from child for villager children\n        if (getProfessionForge() == ProfessionsMCA.child) {\n            setProfession(ProfessionsMCA.randomProfession());\n            setVanillaCareer(getProfessionForge().getRandomCareer(world.rand));\n        }\n    }\n\n    @Override\n    @Nonnull\n    public ITextComponent getDisplayName() {\n        // translate profession name\n        ITextComponent careerName = new TextComponentTranslation(\"entity.Villager.\" + getVanillaCareer().getName());\n        EnumAgeState age = EnumAgeState.byId(get(AGE_STATE));\n        String professionName = age != EnumAgeState.ADULT ? age.localizedName() : careerName.getUnformattedText();\n        String color = this.getProfessionForge() == ProfessionsMCA.bandit ? Constants.Color.RED : this.getProfessionForge() == ProfessionsMCA.guard ? Constants.Color.GREEN : \"\";\n\n        return new TextComponentString(String.format(\"%1$s%2$s%3$s (%4$s)\", color, MCA.getConfig().villagerChatPrefix, get(VILLAGER_NAME), professionName));\n    }\n\n    @Override\n    @Nonnull\n    public String getCustomNameTag() {\n        return get(VILLAGER_NAME);\n    }\n\n    @Override\n    @Nonnull\n    public boolean hasCustomName() {\n        return true;\n    }\n\n    @Override\n    public void swingArm(EnumHand hand) {\n        this.setActiveHand(EnumHand.MAIN_HAND);\n        super.swingArm(EnumHand.MAIN_HAND);\n\n        if (!get(IS_SWINGING) || swingProgressTicks >= 8 / 2 || swingProgressTicks < 0) {\n            swingProgressTicks = -1;\n            set(IS_SWINGING, true);\n        }\n    }\n\n    private void updateSwinging() {\n        if (get(IS_SWINGING)) {\n            swingProgressTicks++;\n\n            if (swingProgressTicks >= 8) {\n                swingProgressTicks = 0;\n                set(IS_SWINGING, false);\n            }\n        } else {\n            swingProgressTicks = 0;\n        }\n        swingProgress = swingProgressTicks / (float) 8;\n    }\n\n    @Override\n    @Nonnull\n    public ItemStack getItemStackFromSlot(EntityEquipmentSlot slotIn) {\n        if (slotIn == EntityEquipmentSlot.MAINHAND) {\n            VillagerRegistry.VillagerProfession profession = getProfessionForge();\n            EnumChore chore = EnumChore.byId(get(ACTIVE_CHORE));\n            if (get(HAS_BABY)) {\n                return ItemStackCache.get(get(BABY_IS_MALE) ? ItemsMCA.BABY_BOY : ItemsMCA.BABY_GIRL);\n            } else if (chore != EnumChore.NONE) {\n                return inventory.getBestItemOfType(chore.getToolType());\n            } else {\n                return ProfessionsMCA.getDefaultHeldItem(profession, getVanillaCareer());\n            }\n        } else {\n            return inventory.getBestArmorOfType(slotIn);\n        }\n    }\n\n    public void setStartingAge(int value) {\n        this.startingAge = value;\n        setGrowingAge(value);\n    }\n\n    public PlayerHistory getPlayerHistoryFor(UUID uuid) {\n        if (!get(PLAYER_HISTORY_MAP).hasKey(uuid.toString())) {\n            updatePlayerHistoryMap(PlayerHistory.getNew(this, uuid));\n        }\n        return PlayerHistory.fromNBT(this, uuid, get(PLAYER_HISTORY_MAP).getCompoundTag(uuid.toString()));\n    }\n\n    public void updatePlayerHistoryMap(PlayerHistory history) {\n        NBTTagCompound nbt = get(PLAYER_HISTORY_MAP);\n        nbt.setTag(history.getPlayerUUID().toString(), history.toNBT());\n        set(PLAYER_HISTORY_MAP, nbt);\n        this.dataManager.setDirty(PLAYER_HISTORY_MAP);\n    }\n\n    public void reset() {\n        set(PLAYER_HISTORY_MAP, new NBTTagCompound());\n        dataManager.setDirty(PLAYER_HISTORY_MAP);\n\n        setHealth(20.0F);\n\n        set(SPOUSE_NAME, \"\");\n        set(SPOUSE_UUID, Optional.of(Constants.ZERO_UUID));\n        set(MARRIAGE_STATE, EnumMarriageState.NOT_MARRIED.getId());\n        set(HAS_BABY, false);\n    }\n\n    public VillagerRegistry.VillagerCareer getVanillaCareer() {\n        return this.getProfessionForge().getCareer(ObfuscationReflectionHelper.getPrivateValue(EntityVillager.class, this, VANILLA_CAREER_ID_FIELD_INDEX));\n    }\n\n    public void setVanillaCareer(int careerId) {\n        ObfuscationReflectionHelper.setPrivateValue(EntityVillager.class, this, careerId, VANILLA_CAREER_ID_FIELD_INDEX);\n    }\n\n    private void setSizeForAge() {\n        EnumAgeState age = EnumAgeState.byId(get(AGE_STATE));\n        this.setSize(age.getWidth(), age.getHeight());\n        this.setScale(1.0F); // trigger rebuild of the bounding box\n    }\n\n    private void toggleMount(EntityPlayerMP player) {\n        if (getRidingEntity() != null) {\n            dismountRidingEntity();\n        } else {\n            try {\n                List<EntityHorse> horses = world.getEntities(EntityHorse.class, h -> (h.isHorseSaddled() && !h.isBeingRidden() && h.getDistance(this) < 3.0D));\n                startRiding(horses.stream().min(Comparator.comparingDouble(this::getDistance)).get(), true);\n                getNavigator().clearPath();\n            } catch (NoSuchElementException e) {\n                say(Optional.of(player), \"interaction.ridehorse.fail.notnearby\");\n            }\n        }\n    }\n\n    private void goHome(EntityPlayerMP player) {\n        if (home.equals(Vec3d.ZERO)) {\n            say(Optional.of(player), \"interaction.gohome.fail\");\n        } else {\n            say(Optional.of(player), \"interaction.gohome.success\");\n            if (!getNavigator().setPath(getNavigator().getPathToXYZ(home.getX(), home.getY(), home.getZ()), 1.0D)) {\n                attemptTeleport(home.getX(), home.getY(), home.getZ());\n            }\n        }\n    }\n\n    public BlockPos getWorkplace() {\n        return get(WORKPLACE_POS);\n    }\n\n    public BlockPos getHangout() {\n        return get(HANGOUT_POS);\n    }\n\n    /**\n     * Forces the villager's home to be set to their position. No checks for safety are made.\n     * This is used on overwriting the original villager.\n     */\n    public void forcePositionAsHome() {\n        this.home = this.getPosition();\n    }\n\n    private void setHome(EntityPlayerMP player) {\n        if (attemptTeleport(player.posX, player.posY, player.posZ)) {\n            say(Optional.of(player), \"interaction.sethome.success\");\n            this.home = player.getPosition();\n            this.setHomePosAndDistance(this.home, 32);\n            BlockPos bed = searchBed();\n            if (bed != null) {\n                set(BED_POS, bed);\n            }\n        } else {\n            say(Optional.of(player), \"interaction.sethome.fail\");\n        }\n    }\n\n    public void setWorkplace(EntityPlayerMP player) {\n        say(Optional.of(player), \"interaction.setworkplace.success\");\n        set(WORKPLACE_POS, player.getPosition());\n    }\n\n    public void setHangout(EntityPlayerMP player) {\n        say(Optional.of(player), \"interaction.sethangout.success\");\n        set(HANGOUT_POS, player.getPosition());\n    }\n\n    public void say(Optional<EntityPlayer> player, String phraseId, @Nullable String... params) {\n        ArrayList<String> paramsList = new ArrayList<>();\n        if (params != null) Collections.addAll(paramsList, params);\n\n        if (player.isPresent()) {\n            EntityPlayer thePlayer = player.get();\n\n            // Provide player as the first param, always\n            paramsList.add(0, thePlayer.getName());\n\n            // Infected villagers do not speak.\n            if (get(IS_INFECTED)) {\n                thePlayer.sendMessage(new TextComponentString(getDisplayName().getFormattedText() + \": \" + \"???\"));\n                this.playSound(SoundEvents.ENTITY_ZOMBIE_AMBIENT, 0.5F, rand.nextFloat() + 0.5F);\n            } else {\n                String dialogueType = getPlayerHistoryFor(player.get().getUniqueID()).getDialogueType().getId();\n                String phrase = MCA.getLocalizer().localize(dialogueType + \".\" + phraseId, paramsList);\n                thePlayer.sendMessage(new TextComponentString(String.format(\"%1$s: %2$s\", getDisplayName().getFormattedText(), phrase)));\n            }\n        } else {\n            MCA.getLog().warn(new Throwable(\"Say called on player that is not present!\"));\n        }\n    }\n\n    public boolean isMarried() {\n        return !get(SPOUSE_UUID).or(Constants.ZERO_UUID).equals(Constants.ZERO_UUID);\n    }\n\n    public boolean isMarriedTo(UUID uuid) {\n        return get(SPOUSE_UUID).or(Constants.ZERO_UUID).equals(uuid);\n    }\n\n    public void marry(EntityPlayer player) {\n        set(SPOUSE_UUID, Optional.of(player.getUniqueID()));\n        set(SPOUSE_NAME, player.getName());\n        set(MARRIAGE_STATE, EnumMarriageState.MARRIED.getId());\n    }\n\n    private void endMarriage() {\n        set(SPOUSE_UUID, Optional.of(Constants.ZERO_UUID));\n        set(SPOUSE_NAME, \"\");\n        set(MARRIAGE_STATE, EnumMarriageState.NOT_MARRIED.getId());\n    }\n\n    private void handleInteraction(EntityPlayerMP player, PlayerHistory history, APIButton button) {\n        float successChance = 0.85F;\n        int heartsBoost = button.getConstraints().contains(EnumConstraint.ADULTS) ? 15 : 5;\n\n        String interactionName = button.getIdentifier().replace(\"gui.button.\", \"\");\n\n        successChance -= button.getConstraints().contains(EnumConstraint.ADULTS) ? 0.25F : 0.0F;\n        successChance += (history.getHearts() / 10.0D) * 0.025F;\n\n        if (MCA.getConfig().enableDiminishingReturns) successChance -= history.getInteractionFatigue() * 0.05F;\n\n        boolean succeeded = rand.nextFloat() < successChance;\n        if (MCA.getConfig().enableDiminishingReturns && succeeded)\n            heartsBoost -= history.getInteractionFatigue() * 0.05F;\n\n        history.changeInteractionFatigue(1);\n        history.changeHearts(succeeded ? heartsBoost : (heartsBoost * -1));\n        String responseId = String.format(\"%s.%s\", interactionName, succeeded ? \"success\" : \"fail\");\n        say(Optional.of(player), responseId);\n    }\n\n    public void handleButtonClick(EntityPlayerMP player, String guiKey, String buttonId) {\n        PlayerHistory history = getPlayerHistoryFor(player.getUniqueID());\n        java.util.Optional<APIButton> button = API.getButtonById(guiKey, buttonId);\n        if (!button.isPresent()) {\n            MCA.getLog().warn(\"Button not found for key and ID: \" + guiKey + \", \" + buttonId);\n        } else if (button.get().isInteraction()) handleInteraction(player, history, button.get());\n\n        switch (buttonId) {\n            case \"gui.button.move\":\n                set(MOVE_STATE, EnumMoveState.MOVE.getId());\n                this.playerToFollowUUID = Constants.ZERO_UUID;\n                break;\n            case \"gui.button.stay\":\n                set(MOVE_STATE, EnumMoveState.STAY.getId());\n                break;\n            case \"gui.button.follow\":\n                set(MOVE_STATE, EnumMoveState.FOLLOW.getId());\n                this.playerToFollowUUID = player.getUniqueID();\n                stopChore();\n                break;\n            case \"gui.button.ridehorse\":\n                toggleMount(player);\n                break;\n            case \"gui.button.sethome\":\n                setHome(player);\n                break;\n            case \"gui.button.gohome\":\n                goHome(player);\n                break;\n            case \"gui.button.setworkplace\":\n                setWorkplace(player);\n                break;\n            case \"gui.button.sethangout\":\n                setHangout(player);\n                break;\n            case \"gui.button.trade\":\n                if (MCA.getConfig().allowTrading) {\n                    setCustomer(player);\n                    player.displayVillagerTradeGui(this);\n                } else {\n                    player.sendMessage(new TextComponentString(MCA.getLocalizer().localize(\"info.trading.disabled\")));\n                }\n                break;\n            case \"gui.button.inventory\":\n                player.openGui(MCA.getInstance(), Constants.GUI_ID_INVENTORY, player.world, this.getEntityId(), 0, 0);\n                break;\n            case \"gui.button.gift\":\n                ItemStack stack = player.inventory.getStackInSlot(player.inventory.currentItem);\n                int giftValue = API.getGiftValueFromStack(stack);\n                if (!handleSpecialCaseGift(player, stack)) {\n                    if (stack.getItem() == Items.GOLDEN_APPLE) set(IS_INFECTED, false);\n                    else {\n                        history.changeHearts(giftValue);\n                        say(Optional.of(player), API.getResponseForGift(stack));\n                    }\n                }\n                if (giftValue > 0) {\n                    player.inventory.decrStackSize(player.inventory.currentItem, 1);\n                }\n                break;\n            case \"gui.button.procreate\":\n                if (PlayerSaveData.get(player).isBabyPresent())\n                    say(Optional.of(player), \"interaction.procreate.fail.hasbaby\");\n                else if (history.getHearts() < 100) say(Optional.of(player), \"interaction.procreate.fail.lowhearts\");\n                else {\n                    EntityAITasks.EntityAITaskEntry task = tasks.taskEntries.stream().filter((ai) -> ai.action instanceof EntityAIProcreate).findFirst().orElse(null);\n                    if (task != null) {\n                        ((EntityAIProcreate) task.action).procreateTimer = 20 * 3; // 3 seconds\n                        set(IS_PROCREATING, true);\n                    }\n                }\n                break;\n            case \"gui.button.infected\":\n                set(IS_INFECTED, !get(IS_INFECTED));\n                break;\n            case \"gui.button.texture.randomize\":\n                set(TEXTURE, API.getRandomSkin(this));\n                break;\n            case \"gui.button.profession.randomize\":\n                setProfession(ProfessionsMCA.randomProfession());\n                setVanillaCareer(getProfessionForge().getRandomCareer(world.rand));\n                break;\n            case \"gui.button.gender\":\n                EnumGender gender = EnumGender.byId(get(GENDER));\n                if (gender == EnumGender.MALE) {\n                    set(GENDER, EnumGender.FEMALE.getId());\n                } else {\n                    set(GENDER, EnumGender.MALE.getId());\n                }\n                // intentional fall-through here\n            case \"gui.button.texture\":\n                set(TEXTURE, API.getRandomSkin(this));\n                break;\n            case \"gui.button.random\":\n                set(VILLAGER_NAME, API.getRandomName(EnumGender.byId(get(GENDER))));\n                break;\n            case \"gui.button.profession\":\n                RegistryNamespaced<ResourceLocation, VillagerRegistry.VillagerProfession> registry = ObfuscationReflectionHelper.getPrivateValue(VillagerRegistry.class, VillagerRegistry.instance(), \"REGISTRY\");\n                setProfession(ProfessionsMCA.randomProfession());\n                setVanillaCareer(getProfessionForge().getRandomCareer(world.rand));\n                applySpecialAI();\n                break;\n            case \"gui.button.prospecting\":\n                startChore(EnumChore.PROSPECT, player);\n                break;\n            case \"gui.button.hunting\":\n                startChore(EnumChore.HUNT, player);\n                break;\n            case \"gui.button.fishing\":\n                startChore(EnumChore.FISH, player);\n                break;\n            case \"gui.button.chopping\":\n                startChore(EnumChore.CHOP, player);\n                break;\n            case \"gui.button.harvesting\":\n                startChore(EnumChore.HARVEST, player);\n                break;\n            case \"gui.button.stopworking\":\n                stopChore();\n                break;\n        }\n    }\n\n    private boolean handleSpecialCaseGift(EntityPlayer player, ItemStack stack) {\n        Item item = stack.getItem();\n\n        if (item instanceof ItemSpecialCaseGift && !this.isChild()) { // special case gifts are rings so far so prevent giving them to children\n            boolean decStackSize = ((ItemSpecialCaseGift) item).handle(player, this);\n            if (decStackSize) player.inventory.decrStackSize(player.inventory.currentItem, -1);\n            return true;\n        } else if (item == Items.CAKE) {\n            Optional<Entity> spouse = Util.getEntityByUUID(world, get(SPOUSE_UUID).or(Constants.ZERO_UUID));\n            if (spouse.isPresent()) {\n                EntityVillagerMCA progressor = this.get(GENDER) == EnumGender.FEMALE.getId() ? this : (EntityVillagerMCA) spouse.get();\n                progressor.set(HAS_BABY, true);\n                progressor.set(BABY_IS_MALE, rand.nextBoolean());\n                progressor.spawnParticles(EnumParticleTypes.HEART);\n            } else say(Optional.of(player), \"gift.cake.fail\");\n        } else if (item == Items.GOLDEN_APPLE && this.isChild()) {\n            this.addGrowth(((startingAge / 4) / 20 * -1));\n            return true;\n        }\n\n        return false;\n    }\n\n    private void onEachClientUpdate() {\n        if (get(IS_PROCREATING)) {\n            this.rotationYawHead += 50.0F;\n        }\n\n        if (this.ticksExisted % 20 == 0) {\n            onEachClientSecond();\n        }\n    }\n\n    private void onEachClientSecond() {\n        this.setSizeForAge();\n    }\n\n    private void onEachServerUpdate() {\n        if (this.ticksExisted % 20 == 0) { // Every second\n            onEachServerSecond();\n        }\n\n        if (this.ticksExisted % 200 == 0 && this.getHealth() > 0.0F) { // Every 10 seconds and when we're not already dead\n            if (this.getHealth() < this.getMaxHealth()) {\n                this.setHealth(this.getHealth() + 1.0F); // heal\n            }\n        }\n\n        if (isChild()) {\n            EnumAgeState current = EnumAgeState.byId(get(AGE_STATE));\n            EnumAgeState target = EnumAgeState.byCurrentAge(startingAge, getGrowingAge());\n            if (current != target) {\n                set(AGE_STATE, target.getId());\n            }\n        }\n    }\n\n    private void onEachServerSecond() {\n        NBTTagCompound memories = get(PLAYER_HISTORY_MAP);\n        memories.getKeySet().forEach((key) -> PlayerHistory.fromNBT(this, UUID.fromString(key), memories.getCompoundTag(key)).update());\n\n        if (get(HAS_BABY)) {\n            set(BABY_AGE, get(BABY_AGE) + 1);\n\n            if (get(BABY_AGE) >= MCA.getConfig().babyGrowUpTime * 60) { // grow up time is in minutes and we measure age in seconds\n                EntityVillagerMCA child = new EntityVillagerMCA(world, Optional.absent(), Optional.of(get(BABY_IS_MALE) ? EnumGender.MALE : EnumGender.FEMALE));\n                child.set(EntityVillagerMCA.AGE_STATE, EnumAgeState.BABY.getId());\n                child.setStartingAge(MCA.getConfig().childGrowUpTime * 60 * 20 * -1);\n                child.setScaleForAge(true);\n                child.setPosition(this.posX, this.posY, this.posZ);\n                child.set(EntityVillagerMCA.PARENTS, ParentData.create(this.getUniqueID(), this.get(SPOUSE_UUID).get(), this.get(VILLAGER_NAME), this.get(SPOUSE_NAME)).toNBT());\n                world.spawnEntity(child);\n\n                set(HAS_BABY, false);\n                set(BABY_AGE, 0);\n            }\n        }\n    }\n\n    public ResourceLocation getTextureResourceLocation() {\n        if (get(IS_INFECTED)) {\n            return ResourceLocationCache.getResourceLocationFor(String.format(\"mca:skins/%s/zombievillager.png\", get(GENDER) == EnumGender.MALE.getId() ? \"male\" : \"female\"));\n        } else {\n            return ResourceLocationCache.getResourceLocationFor(get(TEXTURE));\n        }\n    }\n\n    @Override\n    protected void initEntityAI() {\n        super.initEntityAI();\n        this.tasks.addTask(0, new EntityAIProspecting(this));\n        this.tasks.addTask(0, new EntityAIHunting(this));\n        this.tasks.addTask(0, new EntityAIChopping(this));\n        this.tasks.addTask(0, new EntityAIHarvesting(this));\n        this.tasks.addTask(0, new EntityAIFishing(this));\n        this.tasks.addTask(0, new EntityAIMoveState(this));\n        this.tasks.addTask(0, new EntityAIAgeBaby(this));\n        this.tasks.addTask(0, new EntityAIProcreate(this));\n        this.tasks.addTask(5, new EntityAIGoWorkplace(this));\n        this.tasks.addTask(5, new EntityAIGoHangout(this));\n        this.tasks.addTask(1, new EntityAISleeping(this));\n        this.tasks.addTask(10, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F));\n        this.tasks.addTask(10, new EntityAILookIdle(this));\n    }\n\n    private void applySpecialAI() {\n        if (getProfessionForge() == ProfessionsMCA.bandit) {\n            this.tasks.taskEntries.clear();\n            this.tasks.addTask(1, new EntityAIAttackMelee(this, 0.8D, false));\n            this.tasks.addTask(2, new EntityAIMoveThroughVillage(this, 0.6D, false));\n\n            this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityVillagerMCA.class, 100, false, false, BANDIT_TARGET_SELECTOR));\n            this.targetTasks.addTask(1, new EntityAINearestAttackableTarget<>(this, EntityPlayer.class, true));\n        } else if (getProfessionForge() == ProfessionsMCA.guard) {\n            removeCertainTasks(EntityAIAvoidEntity.class);\n\n            this.tasks.addTask(1, new EntityAIAttackMelee(this, 0.8D, false));\n            this.tasks.addTask(2, new EntityAIMoveThroughVillage(this, 0.6D, false));\n\n            this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityVillagerMCA.class, 100, false, false, GUARD_TARGET_SELECTOR));\n            this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityZombie.class, 100, false, false, null));\n            this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityVex.class, 100, false, false, null));\n            this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityVindicator.class, 100, false, false, null));\n        } else {\n            //every other villager is allowed to defend itself from zombies while fleeing\n            this.tasks.addTask(0, new EntityAIDefendFromTarget(this));\n\n            this.targetTasks.taskEntries.clear();\n            this.targetTasks.addTask(0, new EntityAINearestAttackableTarget<>(this, EntityZombie.class, 100, false, false, null));\n        }\n    }\n\n    //guards should not run away from zombies\n    //TODO: should only avoid zombies when low on health\n    private void removeCertainTasks(Class typ) {\n        Iterator<EntityAITasks.EntityAITaskEntry> iterator = this.tasks.taskEntries.iterator();\n\n        while (iterator.hasNext()) {\n            EntityAITasks.EntityAITaskEntry entityaitasks$entityaitaskentry = iterator.next();\n            EntityAIBase entityaibase = entityaitasks$entityaitaskentry.action;\n\n            if (entityaibase.getClass().equals(typ)) {\n                iterator.remove();\n            }\n        }\n    }\n\n    public void spawnParticles(EnumParticleTypes particleType) {\n        if (this.world.isRemote) {\n            for (int i = 0; i < 5; ++i) {\n                double d0 = this.rand.nextGaussian() * 0.02D;\n                double d1 = this.rand.nextGaussian() * 0.02D;\n                double d2 = this.rand.nextGaussian() * 0.02D;\n                this.world.spawnParticle(particleType, this.posX + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, this.posY + 1.0D + (double) (this.rand.nextFloat() * this.height), this.posZ + (double) (this.rand.nextFloat() * this.width * 2.0F) - (double) this.width, d0, d1, d2);\n            }\n        } else {\n            NetMCA.INSTANCE.sendToAll(new NetMCA.SpawnParticles(this.getUniqueID(), particleType));\n        }\n    }\n\n    public void stopChore() {\n        set(ACTIVE_CHORE, EnumChore.NONE.getId());\n        set(CHORE_ASSIGNING_PLAYER, Optional.of(Constants.ZERO_UUID));\n    }\n\n    public void startChore(EnumChore chore, EntityPlayer player) {\n        set(ACTIVE_CHORE, chore.getId());\n        set(CHORE_ASSIGNING_PLAYER, Optional.of(player.getUniqueID()));\n    }\n\n    public boolean playerIsParent(EntityPlayer player) {\n        ParentData data = ParentData.fromNBT(get(PARENTS));\n        return data.getParent1UUID().equals(player.getUniqueID()) || data.getParent2UUID().equals(player.getUniqueID());\n    }\n\n    @Override\n    public BlockPos getHomePosition() {\n        return home;\n    }\n\n    @Override\n    public void detachHome() {\n        // no-op, skip EntityVillager's detaching homes which messes up MoveTowardsRestriction.\n    }\n\n    public String getCurrentActivity() {\n        EnumMoveState moveState = EnumMoveState.byId(get(MOVE_STATE));\n        if (moveState != EnumMoveState.MOVE) {\n            return moveState.getFriendlyName();\n        }\n\n        EnumChore chore = EnumChore.byId(get(ACTIVE_CHORE));\n        if (chore != EnumChore.NONE) {\n            return chore.getFriendlyName();\n        }\n\n        return null;\n    }\n\n    public void moveTowardsBlock(BlockPos target) {\n        moveTowardsBlock(target, 0.5D);\n    }\n\n    public void moveTowardsBlock(BlockPos target, double speed) {\n        double range = getNavigator().getPathSearchRange() - 6.0D;\n\n        if (getDistanceSq(target) > Math.pow(range, 2.0)) {\n            Vec3d vec3d = RandomPositionGenerator.findRandomTargetBlockTowards(this, (int) range, 8, new Vec3d(target.getX(), target.getY(), target.getZ()));\n            if (vec3d != null && !getNavigator().setPath(getNavigator().getPathToXYZ(vec3d.x, vec3d.y, vec3d.z), speed)) {\n                attemptTeleport(vec3d.x, vec3d.y, vec3d.z);\n            }\n        } else {\n            if (!getNavigator().setPath(getNavigator().getPathToPos(target), speed)) {\n                attemptTeleport(target.getX(), target.getY(), target.getZ());\n            }\n        }\n    }\n\n    //searches for the nearest bed\n    public BlockPos searchBed() {\n        List<BlockPos> nearbyBeds = Util.getNearbyBlocks(getPos(), world, BlockBed.class, 8, 8);\n        List<BlockPos> valid = new ArrayList<>();\n        for (BlockPos pos : nearbyBeds) {\n            IBlockState state = world.getBlockState(pos);\n            if (!(state.getValue(OCCUPIED)) && state.getValue(PART) != BlockBed.EnumPartType.HEAD) {\n                valid.add(pos);\n            }\n        }\n        return Util.getNearestPoint(getPos(), valid);\n    }\n\n    /**\n     * Returns the orientation of the bed in degrees.\n     */\n    @SideOnly(Side.CLIENT)\n    public float getBedOrientationInDegrees() {\n        BlockPos bedLocation = get(EntityVillagerMCA.BED_POS);\n        IBlockState state = bedLocation == BlockPos.ORIGIN ? null : this.world.getBlockState(bedLocation);\n        if (state != null && state.getBlock().isBed(state, world, bedLocation, this)) {\n            EnumFacing enumfacing = state.getBlock().getBedDirection(state, world, bedLocation);\n\n            switch (enumfacing) {\n                case SOUTH:\n                    return 90.0F;\n                case WEST:\n                    return 0.0F;\n                case NORTH:\n                    return 270.0F;\n                case EAST:\n                    return 180.0F;\n            }\n        }\n\n        return 0.0F;\n    }\n\n    public boolean isSleeping() {\n        return get(SLEEPING);\n    }\n\n    private void updateSleeping() {\n        if (isSleeping()) {\n            BlockPos bedLocation = get(EntityVillagerMCA.BED_POS);\n\n            final IBlockState state = this.world.isBlockLoaded(bedLocation) ? this.world.getBlockState(bedLocation) : null;\n            final boolean isBed = state != null && state.getBlock().isBed(state, this.world, bedLocation, this);\n\n            if (isBed) {\n                final EnumFacing enumfacing = state.getBlock() instanceof BlockHorizontal ? state.getValue(BlockHorizontal.FACING) : null;\n\n                if (enumfacing != null) {\n                    float f1 = 0.5F + (float) enumfacing.getFrontOffsetX() * 0.4F;\n                    float f = 0.5F + (float) enumfacing.getFrontOffsetZ() * 0.4F;\n                    this.setRenderOffsetForSleep(enumfacing);\n                    this.setPosition((double) ((float) bedLocation.getX() + f1), (double) ((float) bedLocation.getY() + 0.6875F), (double) ((float) bedLocation.getZ() + f));\n                } else {\n                    this.setPosition((double) ((float) bedLocation.getX() + 0.5F), (double) ((float) bedLocation.getY() + 0.6875F), (double) ((float) bedLocation.getZ() + 0.5F));\n                }\n\n                this.setSize(0.2F, 0.2F);\n\n                this.motionX = 0.0D;\n                this.motionY = 0.0D;\n                this.motionZ = 0.0D;\n            } else {\n                set(EntityVillagerMCA.BED_POS, BlockPos.ORIGIN);\n                stopSleeping();\n            }\n        } else {\n            this.setSize(0.6F, 1.8F);\n        }\n    }\n\n    private void setRenderOffsetForSleep(EnumFacing bedDirection) {\n        this.renderOffsetX = -1.0F * (float) bedDirection.getFrontOffsetX();\n        this.renderOffsetZ = -1.0F * (float) bedDirection.getFrontOffsetZ();\n    }\n\n    public void startSleeping() {\n        if (this.isRiding()) {\n            this.dismountRidingEntity();\n        }\n\n        set(SLEEPING, true);\n\n        BlockPos bedLocation = get(EntityVillagerMCA.BED_POS);\n        IBlockState blockstate = this.world.getBlockState(bedLocation);\n        if (blockstate.getBlock() == Blocks.BED) {\n            blockstate.getBlock().setBedOccupied(world, bedLocation, null, true);\n        }\n    }\n\n    public void stopSleeping() {\n        BlockPos bedLocation = get(EntityVillagerMCA.BED_POS);\n        if (bedLocation != BlockPos.ORIGIN) {\n            IBlockState blockstate = this.world.getBlockState(bedLocation);\n\n            if (blockstate.getBlock().isBed(blockstate, world, bedLocation, this)) {\n                blockstate.getBlock().setBedOccupied(world, bedLocation, null, false);\n                BlockPos blockpos = blockstate.getBlock().getBedSpawnPosition(blockstate, world, bedLocation, null);\n\n                if (blockpos == null) {\n                    blockpos = bedLocation.up();\n                }\n\n                this.setPosition((double) ((float) blockpos.getX() + 0.5F), (double) ((float) blockpos.getY() + 0.1F), (double) ((float) blockpos.getZ() + 0.5F));\n            }\n        }\n\n        set(SLEEPING, false);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/entity/ai/AbstractEntityAIChore.java",
    "content": "package mca.entity.ai;\n\nimport com.google.common.base.Optional;\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.entity.ai.EntityAIBase;\nimport net.minecraft.entity.player.EntityPlayer;\n\npublic abstract class AbstractEntityAIChore extends EntityAIBase {\n    protected final EntityVillagerMCA villager;\n\n    public AbstractEntityAIChore(EntityVillagerMCA entityIn) {\n        this.villager = entityIn;\n        this.setMutexBits(4);\n    }\n\n    @Override\n    public void updateTask() {\n        super.updateTask();\n\n        if (!getAssigningPlayer().isPresent()) {\n            MCA.getLog().warn(\"Force-stopped chore because assigning player was not present.\");\n            villager.stopChore();\n        }\n    }\n\n    Optional<EntityPlayer> getAssigningPlayer() {\n        EntityPlayer player = villager.world.getPlayerEntityByUUID(villager.get(EntityVillagerMCA.CHORE_ASSIGNING_PLAYER).or(Constants.ZERO_UUID));\n        return Optional.fromNullable(player);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIAgeBaby.java",
    "content": "package mca.entity.ai;\n\nimport com.google.common.base.Optional;\nimport mca.core.MCA;\nimport mca.entity.EntityVillagerMCA;\nimport mca.entity.data.ParentData;\nimport mca.enums.EnumGender;\nimport net.minecraft.entity.ai.EntityAIBase;\n\npublic class EntityAIAgeBaby extends EntityAIBase {\n    private final EntityVillagerMCA villager;\n\n    public EntityAIAgeBaby(EntityVillagerMCA entityIn) {\n        this.villager = entityIn;\n        this.setMutexBits(4);\n    }\n\n    public boolean shouldExecute() {\n        return villager.get(EntityVillagerMCA.HAS_BABY);\n    }\n\n    public void updateTask() {\n        if (villager.ticksExisted % 1200 != 0) return;\n        villager.babyAge += 1;\n\n        if (villager.babyAge < MCA.getConfig().babyGrowUpTime) return;\n\n        EntityVillagerMCA child = new EntityVillagerMCA(villager.world, Optional.absent(), Optional.of(villager.get(EntityVillagerMCA.BABY_IS_MALE) ? EnumGender.MALE : EnumGender.FEMALE));\n        child.set(EntityVillagerMCA.PARENTS, ParentData.fromVillager(villager).toNBT());\n        child.setPosition(villager.posX, villager.posY, villager.posZ);\n\n        villager.world.spawnEntity(child);\n        villager.set(EntityVillagerMCA.HAS_BABY, false);\n    }\n}"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIChopping.java",
    "content": "package mca.entity.ai;\n\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumChore;\nimport mca.util.Util;\nimport net.minecraft.block.BlockLeaves;\nimport net.minecraft.block.BlockLog;\nimport net.minecraft.block.state.IBlockState;\nimport net.minecraft.init.Blocks;\nimport net.minecraft.item.ItemAxe;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.EnumHand;\nimport net.minecraft.util.math.BlockPos;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class EntityAIChopping extends AbstractEntityAIChore {\n    private int chopTicks;\n    private BlockPos targetTree;\n\n    public EntityAIChopping(EntityVillagerMCA entityIn) {\n        super(entityIn);\n        this.setMutexBits(1);\n    }\n\n    public boolean shouldExecute() {\n        if (villager.getHealth() < villager.getMaxHealth()) {\n            villager.stopChore();\n        }\n        return EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) == EnumChore.CHOP;\n    }\n\n    public void updateTask() {\n        if (!villager.inventory.contains(ItemAxe.class)) {\n            villager.say(getAssigningPlayer(), \"chore.chopping.noaxe\");\n            villager.stopChore();\n        }\n        if (targetTree == null) {\n            List<BlockPos> nearbyLogs = Util.getNearbyBlocks(villager.getPos(), villager.world, BlockLog.class, 10, 5);\n            List<BlockPos> nearbyTrees = new ArrayList<>();\n\n            // valid \"trees\" are logs on the ground with leaves around them\n            nearbyLogs.stream()\n                    .filter(log -> {\n                        IBlockState down = villager.world.getBlockState(log.down());\n                        List<BlockPos> leaves = Util.getNearbyBlocks(log, villager.world, BlockLeaves.class, 1, 5);\n                        return leaves.size() > 0 && (down.getBlock() == Blocks.GRASS || down.getBlock() == Blocks.DIRT);\n                    })\n                    .forEach(nearbyTrees::add);\n            targetTree = Util.getNearestPoint(villager.getPos(), nearbyTrees);\n            return;\n        }\n        double distance = Math.sqrt(villager.getDistanceSq(targetTree));\n        if (distance >= 4.0D) villager.getNavigator().setPath(villager.getNavigator().getPathToPos(targetTree), 0.5D);\n        else {\n            IBlockState state = villager.world.getBlockState(targetTree);\n            if (state.getBlock() instanceof BlockLog) {\n                BlockLog log = (BlockLog) state.getBlock();\n                villager.swingArm(EnumHand.MAIN_HAND);\n                chopTicks++;\n\n                if (chopTicks >= 80) {\n                    chopTicks = 0;\n                    villager.inventory.addItem(new ItemStack(log, 1));\n                    villager.getHeldItem(EnumHand.MAIN_HAND).damageItem(2, villager);\n                    if (villager.world.rand.nextFloat() >= 0.90) destroyTree(targetTree);\n                }\n            } else targetTree = null;\n        }\n    }\n\n    private void destroyTree(BlockPos origin) {\n        BlockPos pos = origin;\n        while (villager.world.getBlockState(pos).getBlock() instanceof BlockLog) {\n            villager.world.setBlockToAir(pos);\n            pos = pos.add(0, 1, 0);\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIDefendFromTarget.java",
    "content": "package mca.entity.ai;\n\nimport net.minecraft.entity.EntityCreature;\nimport net.minecraft.entity.EntityLivingBase;\nimport net.minecraft.entity.ai.EntityAIBase;\nimport net.minecraft.util.EnumHand;\n\npublic class EntityAIDefendFromTarget extends EntityAIBase {\n    private EntityCreature attacker;\n\n    private int attackTick;\n\n    public EntityAIDefendFromTarget(EntityCreature creature) {\n        this.attacker = creature;\n        this.setMutexBits(0);\n    }\n\n    public boolean shouldExecute() {\n        this.attackTick--;\n\n        EntityLivingBase entitylivingbase = this.attacker.getAttackTarget();\n\n        if (entitylivingbase == null) {\n            return false;\n        } else if (!entitylivingbase.isEntityAlive()) {\n            return false;\n        } else if (this.attackTick > 0) {\n            return false;\n        } else {\n            return 4.0D >= this.attacker.getDistanceSq(entitylivingbase.posX, entitylivingbase.getEntityBoundingBox().minY, entitylivingbase.posZ);\n        }\n    }\n\n    public boolean shouldContinueExecuting() {\n        return false;\n    }\n\n    public void startExecuting() {\n        this.attackTick = 10;\n\n        EntityLivingBase entitylivingbase = this.attacker.getAttackTarget();\n        if (entitylivingbase != null) {\n            this.attacker.getLookHelper().setLookPositionWithEntity(entitylivingbase, 30.0F, 30.0F);\n\n            this.attacker.swingArm(EnumHand.MAIN_HAND);\n            this.attacker.attackEntityAsMob(entitylivingbase);\n        }\n    }\n\n    public void resetTask() {\n    }\n\n    public void updateTask() {\n\n    }\n}"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIFishing.java",
    "content": "package mca.entity.ai;\n\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumChore;\nimport mca.util.Util;\nimport net.minecraft.block.BlockStaticLiquid;\nimport net.minecraft.init.Blocks;\nimport net.minecraft.init.Items;\nimport net.minecraft.item.ItemFishFood;\nimport net.minecraft.item.ItemFishingRod;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.EnumHand;\nimport net.minecraft.util.math.BlockPos;\n\nimport java.util.Comparator;\nimport java.util.List;\n\npublic class EntityAIFishing extends AbstractEntityAIChore {\n    private BlockPos targetWater;\n    private boolean hasCastRod;\n    private int ticks;\n\n    public EntityAIFishing(EntityVillagerMCA entityIn) {\n        super(entityIn);\n        this.setMutexBits(1);\n    }\n\n    public boolean shouldExecute() {\n        if (villager.getHealth() < villager.getMaxHealth()) {\n            villager.stopChore();\n        }\n        return EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) == EnumChore.FISH;\n    }\n\n    public void updateTask() {\n        super.updateTask();\n\n        if (!villager.inventory.contains(ItemFishingRod.class)) {\n            villager.say(getAssigningPlayer(), \"chore.fishing.norod\");\n            villager.stopChore();\n            return;\n        }\n\n        if (targetWater == null) {\n            List<BlockPos> nearbyStaticLiquid = Util.getNearbyBlocks(villager.getPos(), villager.world, BlockStaticLiquid.class, 12, 3);\n            targetWater = nearbyStaticLiquid.stream()\n                    .filter((p) -> villager.world.getBlockState(p).getBlock() == Blocks.WATER)\n                    .min(Comparator.comparingDouble(villager::getDistanceSq)).orElse(null);\n        } else if (villager.getDistanceSq(targetWater) > 5.0D) villager.getNavigator().setPath(villager.getNavigator().getPathToPos(targetWater), 0.8D);\n        else if (villager.getDistanceSq(targetWater) < 5.0D) {\n            villager.getNavigator().clearPath();\n\n            if (!hasCastRod) {\n                villager.swingArm(EnumHand.MAIN_HAND);\n                hasCastRod = true;\n            }\n\n            ticks++;\n\n            if (ticks >= villager.world.rand.nextInt(200) + 200) {\n                if (villager.world.rand.nextFloat() >= 0.35F) {\n                    int typesSize = ItemFishFood.FishType.values().length;\n                    ItemFishFood.FishType type = ItemFishFood.FishType.values()[villager.world.rand.nextInt(typesSize)];\n                    ItemStack stack = new ItemStack(Items.FISH, 1, type.getMetadata());\n\n                    villager.swingArm(EnumHand.MAIN_HAND);\n                    villager.inventory.addItem(stack);\n                    villager.getHeldItem(EnumHand.MAIN_HAND).damageItem(2, villager);\n                }\n                ticks = 0;\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIGoHangout.java",
    "content": "package mca.entity.ai;\n\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumChore;\n\npublic class EntityAIGoHangout extends AbstractEntityAIChore {\n    private boolean atHangout = false;\n    \n    public EntityAIGoHangout(EntityVillagerMCA villagerIn) {\n        super(villagerIn);\n        this.setMutexBits(1);\n    }\n\n    public boolean shouldExecute() {\n        if (villager.getHangout().getY() == 0) {\n            return false; //no workplace\n        }\n\n        //no time, has to work\n        if (EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) != EnumChore.NONE) {\n            return false;\n        }\n\n        long time = villager.world.getWorldTime() % 24000L;\n\n        if (time < 9000 || time > 11000) {\n            //spare time is over, villager will start going home\n            atHangout = false;\n            return false;\n        }\n\n        double validArea = 64.0D; //allows 8 blocks radius to stay\n        double distance = villager.getDistanceSq(villager.getHangout());\n\n        if (!atHangout) {\n            if (distance < 9.0) {\n                //arrived at hangout\n                atHangout = true;\n            } else {\n                //did not reach workplace for today -> shrink valid area so the villager gathers clearly at his workplace\n                validArea = 4.0D;\n            }\n        }\n\n        return distance > validArea;\n    }\n\n    public boolean shouldContinueExecuting() {\n        return !villager.getNavigator().noPath();\n    }\n\n    public void startExecuting() {\n        villager.moveTowardsBlock(villager.getHangout());\n    }\n\n    public void updateTask() {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIGoWorkplace.java",
    "content": "package mca.entity.ai;\n\nimport mca.entity.EntityVillagerMCA;\n\npublic class EntityAIGoWorkplace extends AbstractEntityAIChore {\n    private boolean atWork = false;\n\n    public EntityAIGoWorkplace(EntityVillagerMCA villagerIn) {\n        super(villagerIn);\n        this.setMutexBits(1);\n    }\n\n    public boolean shouldExecute() {\n        if (villager.getWorkplace().getY() == 0 || villager.world.isRaining()) {\n            return false; //no workplace or it is raining\n        }\n\n        long time = villager.world.getWorldTime() % 24000L;\n\n        if (time < 4000 || time > 7000) {\n            //work is over, villager will start spreading\n            atWork = false;\n            return false;\n        }\n\n        double validArea = 576.0D; //allows 24 blocks radius to work\n        double distance = villager.getDistanceSq(villager.getWorkplace());\n\n        if (!atWork) {\n            if (distance < 9.0) {\n                //arrived at workplace\n                atWork = true;\n            } else {\n                //did not reach workplace for today -> shrink valid area so the villager gathers clearly at his workplace\n                validArea = 4.0D;\n            }\n        }\n\n        return distance > validArea;\n    }\n\n    public boolean shouldContinueExecuting() {\n        return !villager.getNavigator().noPath();\n    }\n\n    public void startExecuting() {\n        //MCA.getLog().info(villager.getName() + \" goes to work\");\n        villager.moveTowardsBlock(villager.getWorkplace());\n    }\n\n    public void updateTask() {\n\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIHarvesting.java",
    "content": "package mca.entity.ai;\n\nimport mca.core.MCA;\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumChore;\nimport mca.util.Util;\nimport net.minecraft.block.BlockCrops;\nimport net.minecraft.block.properties.IProperty;\nimport net.minecraft.block.state.IBlockState;\nimport net.minecraft.item.*;\nimport net.minecraft.util.EnumHand;\nimport net.minecraft.util.NonNullList;\nimport net.minecraft.util.math.BlockPos;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class EntityAIHarvesting extends AbstractEntityAIChore {\n    private int blockWork = 0;\n    private int lastCropScan = 0;\n\n    public EntityAIHarvesting(EntityVillagerMCA villagerIn) {\n        super(villagerIn);\n        this.setMutexBits(1);\n    }\n\n    public boolean shouldExecute() {\n        if (villager.getHealth() < villager.getMaxHealth()) {\n            villager.stopChore();\n        }\n        return EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) == EnumChore.HARVEST && (blockWork - villager.ticksExisted) < 0;\n    }\n\n    public boolean shouldContinueExecuting() {\n        return !villager.getNavigator().noPath();\n    }\n\n    private BlockPos searchCrop(int rangeX, int rangeY) {\n        List<BlockPos> nearbyCrops = Util.getNearbyBlocks(villager.getPos(), villager.world, BlockCrops.class, rangeX, rangeY);\n        List<BlockPos> harvestable = new ArrayList<>();\n        for (BlockPos pos : nearbyCrops) {\n            IBlockState state = villager.world.getBlockState(pos);\n            BlockCrops crop = (BlockCrops) state.getBlock();\n\n            if (crop.isMaxAge(state)) {\n                harvestable.add(pos);\n            }\n        }\n\n        return Util.getNearestPoint(villager.getPos(), harvestable);\n    }\n\n    public void startExecuting() {\n        if (!villager.inventory.contains(ItemHoe.class)) {\n            villager.say(getAssigningPlayer(), \"chore.harvesting.nohoe\");\n            villager.stopChore();\n        }\n\n        //search crop\n        BlockPos target = searchCrop(16, 3);\n\n        //no crop next to villager -> long range scan\n        //limited to once a minute to reduce CPU usage\n        if (target == null && villager.ticksExisted - lastCropScan > 1200) {\n            //MCA.getLog().info(villager.getName() + \" scans for crops\");\n            lastCropScan = villager.ticksExisted;\n            target = searchCrop(32, 16);\n        }\n\n        if (target == null) {\n            if (villager.getWorkplace().getY() > 0 && villager.getDistanceSq(villager.getWorkplace()) > 256.0D) {\n                //go to their workplace (if set and more than 16 blocks away)\n                //MCA.getLog().info(villager.getName() + \" goes to workplace\");\n                villager.moveTowardsBlock(villager.getWorkplace());\n            } else {\n                //failed (no crop on range), allows now other, lower priority tasks to interrupt\n                //MCA.getLog().info(villager.getName() + \" idles\");\n                blockWork = villager.ticksExisted + 100 + villager.getRNG().nextInt(100);\n            }\n        } else {\n            //harvest if next to it, else try to reach it\n            double distanceTo = Math.sqrt(villager.getDistanceSq(target));\n            if (distanceTo >= 2.0D) {\n                if (!villager.getNavigator().setPath(villager.getNavigator().getPathToPos(target), 0.5D)) {\n                    villager.attemptTeleport(target.getX(), target.getY(), target.getZ());\n                }\n            } else {\n                //harvest\n                IBlockState state = villager.world.getBlockState(target);\n                if (state.getBlock() instanceof BlockCrops) {\n                    BlockCrops crop = (BlockCrops) state.getBlock();\n                    NonNullList<ItemStack> drops = NonNullList.create();\n                    crop.getDrops(drops, villager.world, target, state, 0);\n                    for (ItemStack stack : drops) {\n                        villager.inventory.addItem(stack);\n                    }\n\n                    villager.swingArm(EnumHand.MAIN_HAND);\n                    villager.getHeldItem(EnumHand.MAIN_HAND).damageItem(2, villager);\n\n                    try {\n                        IProperty<Integer> property = (IProperty<Integer>) crop.getBlockState().getProperty(\"age\");\n                        villager.world.setBlockState(target, state.withProperty(property, 0));\n                    } catch (Exception e) { // age property may have some issues on certain mods, if it errors just set to air\n                        MCA.getLog().warn(\"Error resetting crop age at \" + target.toString() + \"! Setting to air.\");\n                        villager.world.setBlockToAir(target);\n                    }\n                }\n\n                //wait before harvesting next crop\n                ItemStack hoeStack = villager.inventory.getBestItemOfType(ItemHoe.class);\n                float efficiency = hoeStack == ItemStack.EMPTY ? 0.0f : Item.ToolMaterial.valueOf(((ItemHoe) hoeStack.getItem()).getMaterialName()).getEfficiency();\n                blockWork = villager.ticksExisted + (int) Math.max(2.0f, 60.0f - efficiency * 5.0f);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIHunting.java",
    "content": "package mca.entity.ai;\n\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumChore;\nimport net.minecraft.entity.item.EntityItem;\nimport net.minecraft.entity.passive.EntityAnimal;\nimport net.minecraft.entity.passive.EntityTameable;\nimport net.minecraft.item.ItemSword;\nimport net.minecraft.util.DamageSource;\nimport net.minecraft.util.EnumHand;\n\nimport java.util.Comparator;\nimport java.util.Optional;\n\npublic class EntityAIHunting extends AbstractEntityAIChore {\n    private int ticks = 0;\n    private int nextAction = 0;\n    private EntityAnimal target = null;\n\n    public EntityAIHunting(EntityVillagerMCA entityIn) {\n        super(entityIn);\n        this.setMutexBits(1);\n    }\n\n    public boolean shouldExecute() {\n        if (villager.getHealth() < villager.getMaxHealth()) {\n            villager.stopChore();\n        }\n        return EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) == EnumChore.HUNT;\n    }\n\n    public void updateTask() {\n        super.updateTask();\n\n        if (!villager.inventory.contains(ItemSword.class)) {\n            villager.say(getAssigningPlayer(), \"chore.hunting.nosword\");\n            villager.stopChore();\n        }\n\n        if (target == null) {\n            ticks++;\n\n            if (ticks >= nextAction) {\n                ticks = 0;\n                if (villager.world.rand.nextFloat() >= 0.0D) {\n                    Optional<EntityAnimal> animal = villager.world.getEntitiesWithinAABB(EntityAnimal.class, villager.getEntityBoundingBox().grow(15.0D, 3.0D, 15.0D)).stream()\n                            .filter((a) -> !(a instanceof EntityTameable))\n                            .min(Comparator.comparingDouble(villager::getDistance));\n\n                    if (animal.isPresent()) {\n                        target = animal.get();\n                        target.getNavigator().setPath(target.getNavigator().getPathToEntityLiving(villager), 1.0F);\n                    }\n                }\n\n                nextAction = 300;\n            }\n        } else {\n            boolean pathSuccess = villager.getNavigator().setPath(villager.getNavigator().getPathToEntityLiving(target), 0.6F);\n\n            if (!pathSuccess || target.isDead) {\n                // search for EntityItems around the target and grab them\n                villager.world.loadedEntityList.stream()\n                        .filter((e) -> e instanceof EntityItem && e.getDistance(target) <= 5.0D)\n                        .forEach((item) -> {\n                            villager.inventory.addItem(((EntityItem) item).getItem());\n                            item.setDead();\n                        });\n                target = null;\n            } else if (villager.getDistance(target) <= 3.5F) {\n                villager.getNavigator().setPath(villager.getNavigator().getPathToEntityLiving(target), 1.0F);\n                villager.swingArm(EnumHand.MAIN_HAND);\n                target.attackEntityFrom(DamageSource.causeMobDamage(villager), 6.0F);\n                villager.getHeldItem(EnumHand.MAIN_HAND).damageItem(2, villager);\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIMoveState.java",
    "content": "package mca.entity.ai;\n\nimport mca.core.Constants;\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumMoveState;\nimport net.minecraft.entity.ai.EntityAIBase;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.pathfinding.PathNavigate;\n\npublic class EntityAIMoveState extends EntityAIBase {\n    private final EntityVillagerMCA villager;\n\n    public EntityAIMoveState(EntityVillagerMCA entityIn) {\n        this.villager = entityIn;\n        this.setMutexBits(1);\n    }\n\n    public boolean shouldExecute() {\n        return !villager.playerToFollowUUID.equals(Constants.ZERO_UUID) || EnumMoveState.byId(villager.get(EntityVillagerMCA.MOVE_STATE)) == EnumMoveState.STAY;\n    }\n\n    public void updateTask() {\n        PathNavigate nav = villager.getNavigator();\n        EntityPlayer playerToFollow = villager.world.getPlayerEntityByUUID(villager.playerToFollowUUID);\n\n        switch (EnumMoveState.byId(villager.get(EntityVillagerMCA.MOVE_STATE))) {\n            case FOLLOW:\n                double distance = playerToFollow != null ? villager.getDistance(playerToFollow) : -1.0D;\n                if (playerToFollow == null) {\n                    villager.set(EntityVillagerMCA.MOVE_STATE, EnumMoveState.MOVE.getId());\n                    break;\n                } else if (distance >= 3.0D && distance <= 10.0D) {\n                    nav.setPath(nav.getPathToEntityLiving(playerToFollow), villager.isRiding() ? 1.7D : 0.8D);\n                } else if (distance > 10.0D) {\n                    villager.attemptTeleport(playerToFollow.posX, playerToFollow.posY, playerToFollow.posZ);\n                } else { // close enough to avoid crowding the player\n                    nav.clearPath();\n                }\n                break;\n            case STAY:\n                nav.clearPath();\n                break;\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIProcreate.java",
    "content": "package mca.entity.ai;\n\nimport lombok.RequiredArgsConstructor;\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.core.minecraft.ItemsMCA;\nimport mca.entity.EntityVillagerMCA;\nimport mca.entity.data.PlayerSaveData;\nimport net.minecraft.entity.ai.EntityAIBase;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.init.SoundEvents;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.EnumParticleTypes;\nimport net.minecraft.util.SoundCategory;\n\n@RequiredArgsConstructor\npublic class EntityAIProcreate extends EntityAIBase {\n    private final EntityVillagerMCA villager;\n    public int procreateTimer;\n\n    @Override\n    public boolean shouldExecute() {\n        return villager.get(EntityVillagerMCA.IS_PROCREATING);\n    }\n\n    @Override\n    public void updateTask() {\n        if (procreateTimer % 5 == 0) villager.spawnParticles(EnumParticleTypes.HEART);\n\n        if (--procreateTimer <= 0) {\n            villager.set(EntityVillagerMCA.IS_PROCREATING, false);\n\n            EntityPlayer spousePlayer = villager.world.getPlayerEntityByUUID(villager.get(EntityVillagerMCA.SPOUSE_UUID).or(Constants.ZERO_UUID));\n            if (spousePlayer != null) {\n                villager.world.playSound(null, villager.posX, villager.posY, villager.posZ, SoundEvents.ENTITY_CHICKEN_EGG, SoundCategory.NEUTRAL, 1.0F, 1.0F);\n                spousePlayer.inventory.addItemStackToInventory(new ItemStack(villager.getRNG().nextBoolean() ? ItemsMCA.BABY_BOY : ItemsMCA.BABY_GIRL));\n                PlayerSaveData.get(spousePlayer).setBabyPresent(true);\n\n                if (villager.getRNG().nextFloat() < MCA.getConfig().chanceToHaveTwins / 100)\n                    spousePlayer.inventory.addItemStackToInventory(new ItemStack(villager.getRNG().nextBoolean() ? ItemsMCA.BABY_BOY : ItemsMCA.BABY_GIRL));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAIProspecting.java",
    "content": "package mca.entity.ai;\n\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumChore;\nimport mca.util.Util;\nimport net.minecraft.block.Block;\nimport net.minecraft.block.BlockOre;\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemPickaxe;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.math.BlockPos;\n\npublic class EntityAIProspecting extends AbstractEntityAIChore {\n    private int ticks;\n\n    public EntityAIProspecting(EntityVillagerMCA entityIn) {\n        super(entityIn);\n        this.setMutexBits(4);\n    }\n\n    public boolean shouldExecute() {\n        if (villager.getHealth() < villager.getMaxHealth()) {\n            villager.stopChore();\n        }\n        return EnumChore.byId(villager.get(EntityVillagerMCA.ACTIVE_CHORE)) == EnumChore.PROSPECT;\n    }\n\n    public void updateTask() {\n        super.updateTask();\n\n        ItemStack pickStack = villager.inventory.getBestItemOfType(ItemPickaxe.class);\n        if (pickStack == ItemStack.EMPTY) {\n            villager.say(getAssigningPlayer(), \"chore.mining.nopick\");\n            villager.stopChore();\n            return;\n        }\n\n        float efficiency = Item.ToolMaterial.valueOf(((ItemPickaxe) pickStack.getItem()).getToolMaterialName()).getEfficiency();\n        float notifyRate = Math.max(600 - efficiency * 50, 100);\n\n        if (ticks >= notifyRate) {\n            BlockPos closestOre = Util.getNearestPoint(villager.getPos(), Util.getNearbyBlocks(villager.getPos(), villager.world, BlockOre.class, 4, 3));\n\n            if (closestOre != null) {\n                Block block = villager.world.getBlockState(closestOre).getBlock();\n                villager.say(getAssigningPlayer(), \"chore.mining.orenotify\", block.getLocalizedName());\n                pickStack.damageItem(2, villager);\n            }\n            ticks = 0;\n            return;\n        }\n        ticks++;\n    }\n}"
  },
  {
    "path": "src/main/java/mca/entity/ai/EntityAISleeping.java",
    "content": "package mca.entity.ai;\n\nimport mca.core.minecraft.ProfessionsMCA;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.util.math.BlockPos;\n\npublic class EntityAISleeping extends AbstractEntityAIChore {\n    private int failed = 0;\n\n    public EntityAISleeping(EntityVillagerMCA villagerIn) {\n        super(villagerIn);\n        this.setMutexBits(1);\n    }\n\n    public boolean shouldExecute() {\n        //let the avoid tasks work\n        if (villager.getHealth() < villager.getMaxHealth()) {\n            return false;\n        }\n\n        if (villager.ticksExisted - failed < 1200) {\n            //wake up if still sleeping\n            if (villager.isSleeping()) {\n                villager.stopSleeping();\n            }\n            return false;\n        }\n\n        long time = villager.world.getWorldTime() % 24000L;\n        if (villager.get(EntityVillagerMCA.BED_POS) == BlockPos.ORIGIN && time < 16000) { //at tick 18000 villager without bed are allowed to automatically choose one\n            //wake up if still sleeping\n            if (villager.isSleeping()) {\n                villager.stopSleeping();\n            }\n            return false;\n        }\n\n        //if guards detect enemies they won't sleep\n        if (villager.getProfessionForge() == ProfessionsMCA.guard && villager.getAttackTarget() != null) {\n            //wake up, this is a emergency!\n            if (villager.isSleeping()) {\n                villager.stopSleeping();\n            }\n            return false;\n        }\n\n        if (time > (villager.getProfessionForge() == ProfessionsMCA.guard ? 14000 : 12000) && time < 23000) {\n            return true;\n        } else {\n            //wake up if still sleeping\n            if (villager.isSleeping()) {\n                villager.stopSleeping();\n            }\n            return false;\n        }\n    }\n\n    public boolean shouldContinueExecuting() {\n        return shouldExecute() && (!villager.getNavigator().noPath() || villager.isSleeping());\n    }\n\n    public void startExecuting() {\n        if (villager.get(EntityVillagerMCA.BED_POS) == BlockPos.ORIGIN || villager.getDistanceSq(villager.get(EntityVillagerMCA.BED_POS)) < 4.0) {\n            //search for the nearest bed, might be a different than before\n            BlockPos pos = villager.searchBed();\n\n            if (pos == null) {\n                //no bed found, let's forget about the remembered bed\n                if (villager.get(EntityVillagerMCA.BED_POS) != BlockPos.ORIGIN) {\n                    //TODO: notify the player?\n                    //MCA.getLog().info(villager.getName() + \" lost the bed\");\n                    villager.set(EntityVillagerMCA.BED_POS, BlockPos.ORIGIN);\n                } else {\n                    //MCA.getLog().info(villager.getName() + \" has no bed\");\n                }\n                failed = villager.ticksExisted;\n            } else {\n                //MCA.getLog().info(villager.getName() + \" sleeps now\");\n                villager.set(EntityVillagerMCA.BED_POS, pos);\n                villager.startSleeping();\n            }\n        } else {\n            //MCA.getLog().info(villager.getName() + \" is going to bed\");\n            villager.moveTowardsBlock(villager.get(EntityVillagerMCA.BED_POS), 0.75);\n        }\n    }\n\n    public void resetTask() {\n        if (villager.isSleeping()) {\n            //MCA.getLog().info(villager.getName() + \" wakes up\");\n            villager.stopSleeping();\n        }\n    }\n\n    public void updateTask() {\n        if (villager.isSleeping()) {\n            villager.setRotationYawHead(0.0f);\n            villager.rotationYaw = 0.0f;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/entity/data/ParentData.java",
    "content": "package mca.entity.data;\n\nimport lombok.Getter;\nimport mca.core.Constants;\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.nbt.NBTTagCompound;\nimport net.minecraft.world.World;\n\nimport java.util.UUID;\n\nimport static mca.entity.EntityVillagerMCA.*;\n\n@Getter\npublic class ParentData {\n    private UUID parent1UUID = Constants.ZERO_UUID;\n    private UUID parent2UUID = Constants.ZERO_UUID;\n    private String parent1Name = \"\";\n    private String parent2Name = \"\";\n\n    public static ParentData fromNBT(NBTTagCompound nbt) {\n        ParentData data = new ParentData();\n        data.parent1UUID = nbt.getUniqueId(\"parent1UUID\");\n        data.parent2UUID = nbt.getUniqueId(\"parent2UUID\");\n        data.parent1Name = nbt.getString(\"parent1Name\");\n        data.parent2Name = nbt.getString(\"parent2Name\");\n        return data;\n    }\n\n    public static ParentData create(UUID parent1UUID, UUID parent2UUID, String parent1Name, String parent2Name) {\n        ParentData data = new ParentData();\n        data.parent1UUID = parent1UUID;\n        data.parent2UUID = parent2UUID;\n        data.parent1Name = parent1Name;\n        data.parent2Name = parent2Name;\n        return data;\n    }\n\n    public static ParentData fromVillager(EntityVillagerMCA villager) {\n        ParentData data = new ParentData();\n        data.parent1Name = villager.get(VILLAGER_NAME);\n        data.parent1UUID = villager.getUniqueID();\n        data.parent2Name = villager.get(SPOUSE_NAME);\n        data.parent2UUID = villager.get(SPOUSE_UUID).or(Constants.ZERO_UUID);\n        return data;\n    }\n\n    public NBTTagCompound toNBT() {\n        NBTTagCompound nbt = new NBTTagCompound();\n        nbt.setUniqueId(\"parent1UUID\", parent1UUID);\n        nbt.setUniqueId(\"parent2UUID\", parent2UUID);\n        nbt.setString(\"parent1Name\", parent1Name);\n        nbt.setString(\"parent2Name\", parent2Name);\n        return nbt;\n    }\n\n    public ParentData setParents(UUID parent1UUID, String parent1Name, UUID parent2UUID, String parent2Name) {\n        this.parent1UUID = parent1UUID;\n        this.parent2UUID = parent2UUID;\n        this.parent1Name = parent1Name;\n        this.parent2Name = parent2Name;\n        return this;\n    }\n\n    public Entity getParentEntity(World world, UUID uuid) {\n        return world.loadedEntityList.stream().filter(e -> e.getUniqueID().equals(uuid)).findFirst().orElse(null);  // TODO: This should definitely be changed to an optional\n    }\n\n    public Entity[] getParentEntities(World world) {\n        return new Entity[]{\n                getParentEntity(world, getParent1UUID()),\n                getParentEntity(world, getParent2UUID())\n        };\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/entity/data/PlayerHistory.java",
    "content": "package mca.entity.data;\n\nimport lombok.Getter;\nimport mca.core.Constants;\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumDialogueType;\nimport net.minecraft.nbt.NBTTagCompound;\n\nimport java.util.UUID;\n\npublic class PlayerHistory {\n    @Getter private int hearts;\n    @Getter private int interactionFatigue;\n    @Getter private boolean giftPresent;\n    @Getter private int greetTimer;\n    @Getter private EnumDialogueType dialogueType;\n\n    @Getter private UUID playerUUID;\n    private EntityVillagerMCA villager;\n\n    private PlayerHistory() {\n        hearts = 0;\n        interactionFatigue = 0;\n        giftPresent = false;\n        greetTimer = 0;\n        playerUUID = Constants.ZERO_UUID;\n        dialogueType = EnumDialogueType.ADULT;\n    }\n\n    public static PlayerHistory getNew(EntityVillagerMCA villager, UUID uuid) {\n        PlayerHistory history = new PlayerHistory();\n        history.villager = villager;\n        history.playerUUID = uuid;\n\n        if (villager.isChild()) {\n            history.setDialogueType(EnumDialogueType.CHILD);\n        } else {\n            history.setDialogueType(EnumDialogueType.ADULT);\n        }\n        return history;\n    }\n\n    public static PlayerHistory fromNBT(EntityVillagerMCA villager, UUID uuid, NBTTagCompound nbt) {\n        PlayerHistory history = new PlayerHistory();\n        history.villager = villager;\n        history.playerUUID = uuid;\n\n        history.hearts = nbt.getInteger(\"hearts\");\n        history.interactionFatigue = nbt.getInteger(\"interactionFatigue\");\n        history.giftPresent = nbt.getBoolean(\"giftPresent\");\n        history.greetTimer = nbt.getInteger(\"greetTimer\");\n        history.dialogueType = EnumDialogueType.byValue(nbt.getString(\"dialogueType\"));\n\n        return history;\n    }\n\n    public NBTTagCompound toNBT() {\n        NBTTagCompound nbt = new NBTTagCompound();\n\n        nbt.setInteger(\"hearts\", hearts);\n        nbt.setInteger(\"interactionFatigue\", interactionFatigue);\n        nbt.setBoolean(\"giftPresent\", giftPresent);\n        nbt.setInteger(\"greetTimer\", greetTimer);\n        nbt.setString(\"dialogueType\", dialogueType.getId());\n\n        return nbt;\n    }\n\n    public void setHearts(int value) {\n        hearts = value;\n        villager.updatePlayerHistoryMap(this);\n    }\n\n    public void changeHearts(int value) {\n        hearts += value;\n        villager.updatePlayerHistoryMap(this);\n    }\n\n    public void changeInteractionFatigue(int value) {\n        interactionFatigue += value;\n        villager.updatePlayerHistoryMap(this);\n    }\n\n    public void update() {\n        // every 5 minutes reduce interaction fatigues\n        if (villager.ticksExisted % 6000 == 0) changeInteractionFatigue(-1);\n    }\n\n    public void setDialogueType(EnumDialogueType type) {\n        this.dialogueType = type;\n        villager.updatePlayerHistoryMap(this);\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/entity/data/PlayerSaveData.java",
    "content": "package mca.entity.data;\n\nimport lombok.Getter;\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.enums.EnumMarriageState;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.nbt.NBTTagCompound;\nimport net.minecraft.util.text.TextComponentString;\nimport net.minecraft.world.World;\nimport net.minecraft.world.storage.WorldSavedData;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Modifier;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.UUID;\nimport java.util.stream.Collectors;\n\n@Getter\npublic class PlayerSaveData extends WorldSavedData {\n    private static final String PREFIX = \"MCA-Player-V1-\";\n\n    private UUID spouseUUID = Constants.ZERO_UUID;\n    private EnumMarriageState marriageState = EnumMarriageState.NOT_MARRIED;\n    private String spouseName = \"\";\n    private boolean babyPresent = false;\n\n    public PlayerSaveData(String id) {\n        super(id);\n    }\n\n    public static PlayerSaveData get(EntityPlayer player) {\n        String dataId = PREFIX + player.getUniqueID().toString();\n        PlayerSaveData data = (PlayerSaveData) player.world.loadData(PlayerSaveData.class, dataId);\n\n        if (data == null) {\n            data = new PlayerSaveData(dataId);\n            player.world.setData(dataId, data);\n        }\n\n        return data;\n    }\n\n    public static PlayerSaveData getExisting(World world, UUID uuid) {\n        return (PlayerSaveData) world.loadData(PlayerSaveData.class, PREFIX + uuid.toString());\n    }\n\n    @Override\n    public NBTTagCompound writeToNBT(NBTTagCompound nbt) {\n        nbt.setUniqueId(\"spouseUUID\", spouseUUID);\n        nbt.setInteger(\"marriageState\", marriageState.getId());\n        nbt.setString(\"spouseName\", spouseName);\n        nbt.setBoolean(\"babyPresent\", babyPresent);\n        return nbt;\n    }\n\n    @Override\n    public void readFromNBT(NBTTagCompound nbt) {\n        spouseUUID = nbt.getUniqueId(\"spouseUUID\");\n        marriageState = EnumMarriageState.byId(nbt.getInteger(\"marriageState\"));\n        spouseName = nbt.getString(\"spouseName\");\n        babyPresent = nbt.getBoolean(\"babyPresent\");\n    }\n\n    public boolean isMarriedOrEngaged() {\n        return marriageState != EnumMarriageState.NOT_MARRIED;\n    }\n\n    public void marry(UUID uuid, String name) {\n        spouseUUID = uuid;\n        marriageState = EnumMarriageState.MARRIED;\n        spouseName = name;\n        markDirty();\n    }\n\n    public void endMarriage() {\n        spouseUUID = Constants.ZERO_UUID;\n        spouseName = \"\";\n        marriageState = EnumMarriageState.NOT_MARRIED;\n        markDirty();\n    }\n\n    public void setBabyPresent(boolean value) {\n        this.babyPresent = value;\n        markDirty();\n    }\n\n    public void reset() {\n        endMarriage();\n        setBabyPresent(false);\n        markDirty();\n    }\n\n    public List<Field> getDataFields() {\n        return Arrays.stream(this.getClass().getDeclaredFields()).filter(f -> !Modifier.isFinal(f.getModifiers())).collect(Collectors.toList());\n    }\n\n    public void dump(EntityPlayer player) {\n        for (Field f : getDataFields()) {\n            try {\n                player.sendMessage(new TextComponentString(f.getName() + \" = \" + f.get(this).toString()));\n            } catch (Exception e) {\n                MCA.getLog().error(\"Error dumping player data!\");\n                MCA.getLog().error(e);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/entity/data/SavedVillagers.java",
    "content": "package mca.entity.data;\n\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.nbt.NBTTagCompound;\nimport net.minecraft.world.World;\nimport net.minecraft.world.storage.WorldSavedData;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.UUID;\n\n/**\n * SavedVillagers handles saving dead villagers to the world which allows them to be restored later.\n */\npublic class SavedVillagers extends WorldSavedData {\n    private static final String DATA_ID = \"MCA-Villagers-V1\";\n    private Map<String, NBTTagCompound> villagerData = new HashMap<>();\n\n    public SavedVillagers(String id) {\n        super(id);\n    }\n\n    public static SavedVillagers get(World world) {\n        SavedVillagers data = (SavedVillagers) world.loadData(SavedVillagers.class, DATA_ID);\n        if (data == null) {\n            data = new SavedVillagers(DATA_ID);\n            world.setData(DATA_ID, data);\n        }\n        return data;\n    }\n\n    public void save(EntityVillagerMCA villager) {\n        villagerData.put(villager.getUniqueID().toString(), villager.writeToNBT(new NBTTagCompound()));\n        markDirty();\n    }\n\n    public void remove(UUID uuid) {\n        villagerData.remove(uuid.toString());\n        markDirty();\n    }\n\n    public Map<String, NBTTagCompound> getMap() {\n        return villagerData;\n    }\n\n    public NBTTagCompound loadByUUID(UUID uuid) {\n        return villagerData.get(uuid.toString());\n    }\n\n    @Override\n    public NBTTagCompound writeToNBT(NBTTagCompound nbt) {\n        villagerData.forEach(nbt::setTag);\n        return nbt;\n    }\n\n    @Override\n    public void readFromNBT(NBTTagCompound nbt) {\n        nbt.getKeySet().forEach((k) -> villagerData.put(k, nbt.getCompoundTag(k)));\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/entity/inventory/InventoryMCA.java",
    "content": "package mca.entity.inventory;\n\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.inventory.EntityEquipmentSlot;\nimport net.minecraft.inventory.InventoryBasic;\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemArmor;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.nbt.NBTTagCompound;\nimport net.minecraft.nbt.NBTTagList;\n\nimport javax.annotation.Nullable;\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class InventoryMCA extends InventoryBasic {\n    private EntityVillagerMCA villager;\n\n    public InventoryMCA(EntityVillagerMCA villager) {\n        super(\"Villager Inventory\", true, 27);\n        this.villager = villager;\n    }\n\n    public int getFirstSlotContainingItem(Item item) {\n        for (int i = 0; i < this.getSizeInventory(); i++) {\n            ItemStack stack = this.getStackInSlot(i);\n            if (stack.getItem() != item) continue;\n            return i;\n        }\n        return -1;\n    }\n\n    public boolean contains(Class clazz) {\n        for (int i = 0; i < this.getSizeInventory(); ++i) {\n            final ItemStack stack = this.getStackInSlot(i);\n            final Item item = stack.getItem();\n\n            if (item.getClass() == clazz) return true;\n        }\n        return false;\n    }\n\n    /**\n     * Gets the best quality (max damage) item of the specified type that is in the inventory.\n     *\n     * @param type The class of item that will be returned.\n     * @return The item stack containing the item of the specified type with the highest max damage.\n     */\n    public ItemStack getBestItemOfType(@Nullable Class type) {\n        if (type == null) return ItemStack.EMPTY;\n        else return getStackInSlot(getBestItemOfTypeSlot(type));\n    }\n\n    public ItemStack getBestArmorOfType(EntityEquipmentSlot slot) {\n        ItemStack returnStack = ItemStack.EMPTY;\n\n        List<ItemStack> armors = new ArrayList();\n        for (int i = 0; i < this.getSizeInventory(); ++i) {\n            ItemStack stack = this.getStackInSlot(i);\n            if (stack.getItem() instanceof ItemArmor) {\n                ItemArmor armor = (ItemArmor) stack.getItem();\n                if (armor.armorType == slot) armors.add(stack);\n            }\n        }\n\n        int highestMaxDamage = 0;\n        for (ItemStack stack : armors) {\n            if (stack.getMaxDamage() > highestMaxDamage) {\n                returnStack = stack;\n                highestMaxDamage = stack.getMaxDamage();\n            }\n        }\n        return returnStack;\n    }\n\n    public int getBestItemOfTypeSlot(Class type) {\n        int highestMaxDamage = 0;\n        int best = -1;\n\n        for (int i = 0; i < this.getSizeInventory(); ++i) {\n            ItemStack stackInInventory = this.getStackInSlot(i);\n\n            final String itemClassName = stackInInventory.getItem().getClass().getName();\n\n            if (itemClassName.equals(type.getName()) && highestMaxDamage < stackInInventory.getMaxDamage()) {\n                highestMaxDamage = stackInInventory.getMaxDamage();\n                best = i;\n            }\n        }\n\n        return best;\n    }\n\n    public void dropAllItems() {\n        for (int i = 0; i < this.getSizeInventory(); i++) {\n            ItemStack stack = this.getStackInSlot(i);\n            villager.entityDropItem(stack, 1.0F);\n        }\n    }\n\n    public void readInventoryFromNBT(NBTTagList tagList) {\n        for (int i = 0; i < this.getSizeInventory(); ++i) {\n            this.setInventorySlotContents(i, ItemStack.EMPTY);\n        }\n\n        for (int i = 0; i < tagList.tagCount(); ++i) {\n            NBTTagCompound nbt = tagList.getCompoundTagAt(i);\n            int slot = nbt.getByte(\"Slot\") & 255;\n\n            if (slot < this.getSizeInventory()) {\n                this.setInventorySlotContents(slot, new ItemStack(nbt));\n            }\n        }\n    }\n\n    public NBTTagList writeInventoryToNBT() {\n        NBTTagList tagList = new NBTTagList();\n\n        for (int i = 0; i < this.getSizeInventory(); ++i) {\n            ItemStack itemstack = this.getStackInSlot(i);\n\n            if (itemstack != ItemStack.EMPTY) {\n                NBTTagCompound nbt = new NBTTagCompound();\n                nbt.setByte(\"Slot\", (byte) i);\n                itemstack.writeToNBT(nbt);\n                tagList.appendTag(nbt);\n            }\n        }\n\n        return tagList;\n    }\n}"
  },
  {
    "path": "src/main/java/mca/enums/EnumAgeState.java",
    "content": "package mca.enums;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\nimport mca.core.MCA;\n\nimport java.util.Arrays;\nimport java.util.Optional;\n\n@AllArgsConstructor\n@Getter\npublic enum EnumAgeState {\n    UNASSIGNED(-1, 0.8f, 2.0f, 1.5f),\n    BABY(0, 0.3f, 0.5f, 0.4f),\n    TODDLER(1, 0.3f, 0.6f, 0.5f),\n    CHILD(2, 0.5f, 1.1f, 1f),\n    TEEN(3, 0.6f, 1.6f, 1.35f),\n    ADULT(4, 0.8f, 2f, 1.5f);\n\n    int id;\n    float width;\n    float height;\n    float scaleForAge;\n\n    public static EnumAgeState byId(int id) {\n        Optional<EnumAgeState> state = Arrays.stream(values()).filter((e) -> e.id == id).findFirst();\n        return state.orElse(UNASSIGNED);\n    }\n\n    public static EnumAgeState byCurrentAge(int startingAge, int growingAge) {\n        int step = startingAge / 4;\n        if (growingAge >= step) return EnumAgeState.TEEN;\n        else if (growingAge >= step * 2) return EnumAgeState.CHILD;\n        else if (growingAge >= step * 3 && growingAge < step * 2) return EnumAgeState.TODDLER;\n        else if (growingAge >= step * 4 && growingAge < step * 3) return EnumAgeState.BABY;\n        return EnumAgeState.ADULT;\n    }\n\n    public String localizedName() {\n        return MCA.getLocalizer().localize(\"enum.agestate.\" + name().toLowerCase());\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/enums/EnumChore.java",
    "content": "package mca.enums;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\nimport mca.core.MCA;\nimport net.minecraft.item.*;\n\nimport java.util.Arrays;\nimport java.util.Optional;\n\n@AllArgsConstructor\npublic enum EnumChore {\n    NONE(0, \"none\", null),\n    PROSPECT(1, \"gui.label.prospecting\", ItemPickaxe.class),\n    HARVEST(2, \"gui.label.harvesting\", ItemHoe.class),\n    CHOP(3, \"gui.label.chopping\", ItemAxe.class),\n    HUNT(4, \"gui.label.hunting\", ItemSword.class),\n    FISH(5, \"gui.label.fishing\", ItemFishingRod.class);\n\n    @Getter int id;\n    String friendlyName;\n    @Getter Class toolType;\n\n    public static EnumChore byId(int id) {\n        Optional<EnumChore> state = Arrays.stream(values()).filter((e) -> e.id == id).findFirst();\n        return state.orElse(NONE);\n    }\n\n    public String getFriendlyName() {\n        return MCA.getLocalizer().localize(this.friendlyName);\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/mca/enums/EnumConstraint.java",
    "content": "package mca.enums;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Optional;\n\n@AllArgsConstructor\n@Getter\npublic enum EnumConstraint {\n    FAMILY(\"family\"),\n    NOT_FAMILY(\"notfamily\"),\n    ADULTS(\"adults\"),\n    SPOUSE(\"spouse\"),\n    NOT_SPOUSE(\"notspouse\"),\n    HIDE_ON_FAIL(\"hideonfail\");\n\n    String id;\n\n    public static List<EnumConstraint> fromStringList(String constraints) {\n        List<EnumConstraint> list = new ArrayList<>();\n\n        if (constraints != null && !constraints.isEmpty()) {\n            String[] splitConstraints = constraints.split(\"\\\\|\");\n\n            for (String s : splitConstraints) {\n                EnumConstraint constraint = byValue(s);\n                if (s != null) {\n                    list.add(constraint);\n                }\n            }\n        }\n\n        return list;\n    }\n\n    public static EnumConstraint byValue(String value) {\n        Optional<EnumConstraint> state = Arrays.stream(values()).filter((e) -> e.id.equals(value)).findFirst();\n        return state.orElse(null);\n    }\n\n}\n\n"
  },
  {
    "path": "src/main/java/mca/enums/EnumDialogueType.java",
    "content": "package mca.enums;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\n\nimport java.util.Arrays;\n\n@AllArgsConstructor\n@Getter\npublic enum EnumDialogueType {\n    CHILDP(\"childp\"),\n    CHILD(\"child\"),\n    ADULT(\"adult\"),\n    SPOUSE(\"spouse\");\n\n    String id;\n\n    public static EnumDialogueType byValue(String value) {\n        return Arrays.stream(values()).filter(c -> c.getId().equals(value)).findFirst().orElse(null);\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/mca/enums/EnumGender.java",
    "content": "package mca.enums;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\n\nimport java.util.Arrays;\nimport java.util.Optional;\nimport java.util.Random;\n\n@AllArgsConstructor\n@Getter\npublic enum EnumGender {\n    UNASSIGNED(0, \"unassigned\"),\n    MALE(1, \"male\"),\n    FEMALE(2, \"female\");\n\n    int id;\n    String strName;\n\n    public static EnumGender byId(int id) {\n        Optional<EnumGender> gender = Arrays.stream(values()).filter((e) -> e.id == id).findFirst();\n        return gender.orElse(UNASSIGNED);\n    }\n\n    public static EnumGender getRandom() {\n        return new Random().nextBoolean() ? MALE : FEMALE;\n    }\n\n    public static EnumGender byName(String name) {\n        Optional<EnumGender> gender = Arrays.stream(values()).filter((e) -> e.getStrName().equals(name)).findFirst();\n        return gender.orElse(UNASSIGNED);\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/mca/enums/EnumMarriageState.java",
    "content": "package mca.enums;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\n\nimport java.util.Arrays;\nimport java.util.Optional;\n\n@AllArgsConstructor\n@Getter\npublic enum EnumMarriageState {\n    NOT_MARRIED(0),\n    ENGAGED(1),\n    MARRIED(2);\n\n    int id;\n\n    public static EnumMarriageState byId(int id) {\n        Optional<EnumMarriageState> state = Arrays.stream(values()).filter((e) -> e.id == id).findFirst();\n        return state.orElse(NOT_MARRIED);\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/mca/enums/EnumMoveState.java",
    "content": "package mca.enums;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\nimport mca.core.MCA;\n\nimport java.util.Arrays;\n\n@AllArgsConstructor\npublic enum EnumMoveState {\n    MOVE(0, \"\"),\n    STAY(1, \"gui.label.staying\"),\n    FOLLOW(2, \"gui.label.following\");\n\n    @Getter int id;\n    String friendlyName;\n\n    public static EnumMoveState byId(int id) {\n        return Arrays.stream(values()).filter(s -> s.id == id).findFirst().orElse(MOVE);\n    }\n\n    public String getFriendlyName() {\n        return MCA.getLocalizer().localize(friendlyName);\n    }\n}\n\n"
  },
  {
    "path": "src/main/java/mca/enums/EnumReaperAttackState.java",
    "content": "package mca.enums;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\n\nimport java.util.Arrays;\n\n@AllArgsConstructor\n@Getter\npublic enum EnumReaperAttackState {\n    IDLE(0),\n    PRE(1),\n    POST(2),\n    REST(3),\n    BLOCK(4);\n\n    int id;\n\n    public static EnumReaperAttackState fromId(int id) {\n        return Arrays.stream(values()).filter(s -> s.id == id).findFirst().orElse(IDLE);\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/items/ItemBaby.java",
    "content": "package mca.items;\n\nimport com.google.common.base.Optional;\nimport mca.api.API;\nimport mca.core.Constants;\nimport mca.core.Localizer;\nimport mca.core.MCA;\nimport mca.core.minecraft.ProfessionsMCA;\nimport mca.entity.EntityVillagerMCA;\nimport mca.entity.data.ParentData;\nimport mca.entity.data.PlayerSaveData;\nimport mca.enums.EnumAgeState;\nimport mca.enums.EnumDialogueType;\nimport mca.enums.EnumGender;\nimport net.minecraft.client.Minecraft;\nimport net.minecraft.client.util.ITooltipFlag;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.item.EntityItem;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.nbt.NBTTagCompound;\nimport net.minecraft.util.ActionResult;\nimport net.minecraft.util.EnumHand;\nimport net.minecraft.util.math.BlockPos;\nimport net.minecraft.world.World;\nimport net.minecraftforge.fml.common.FMLCommonHandler;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\n\nimport java.util.List;\n\npublic class ItemBaby extends Item {\n    private boolean isMale;\n\n    public ItemBaby(boolean isMale) {\n        this.isMale = isMale;\n        this.setMaxStackSize(1);\n    }\n\n    @Override\n    public void onUpdate(ItemStack itemStack, World world, Entity entity, int unknownInt, boolean unknownBoolean) {\n        super.onUpdate(itemStack, world, entity, unknownInt, unknownBoolean);\n\n        if (!world.isRemote) {\n            if (!itemStack.hasTagCompound()) {\n                NBTTagCompound compound = new NBTTagCompound();\n\n                compound.setString(\"name\", \"\");\n                compound.setInteger(\"age\", 0);\n                compound.setUniqueId(\"ownerUUID\", entity.getUniqueID());\n                compound.setString(\"ownerName\", entity.getName());\n                compound.setBoolean(\"isInfected\", false);\n\n                itemStack.setTagCompound(compound);\n            } else {\n                updateBabyGrowth(itemStack);\n            }\n        }\n    }\n\n    @Override\n    public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {\n        BlockPos pos = player.getPosition();\n        ItemStack stack = player.getHeldItem(hand);\n        int posX = pos.getX();\n        int posY = pos.getY() + 1;\n        int posZ = pos.getZ();\n\n        // Right-clicking an unnamed baby allows you to name it\n        if (world.isRemote && getBabyName(stack).equals(\"\"))\n            player.openGui(MCA.getInstance(), Constants.GUI_ID_NAMEBABY, player.world, player.getEntityId(), 0, 0);\n\n        if (!world.isRemote) {\n            if (isReadyToGrowUp(stack) && !getBabyName(stack).equals(\"\")) { // Name is good and we're ready to grow\n                EntityVillagerMCA child = new EntityVillagerMCA(world, Optional.of(ProfessionsMCA.child), Optional.of(this.isMale ? EnumGender.MALE : EnumGender.FEMALE));\n                child.set(EntityVillagerMCA.VILLAGER_NAME, getBabyName(stack));\n                child.set(EntityVillagerMCA.TEXTURE, API.getRandomSkin(child)); // allow for special-case skins to be applied with the proper name attached to the child at this point\n                child.set(EntityVillagerMCA.AGE_STATE, EnumAgeState.BABY.getId());\n                child.setStartingAge(MCA.getConfig().childGrowUpTime * 60 * 20 * -1);\n                child.setScaleForAge(true);\n                child.setPosition(posX, posY, posZ);\n                world.spawnEntity(child);\n\n                PlayerSaveData playerData = PlayerSaveData.get(player);\n                child.set(EntityVillagerMCA.PARENTS, ParentData.create(player.getUniqueID(), playerData.getSpouseUUID(), player.getName(), playerData.getSpouseName()).toNBT());\n                player.inventory.setInventorySlotContents(player.inventory.currentItem, ItemStack.EMPTY);\n                playerData.setBabyPresent(false);\n\n                // set proper dialogue type\n                child.getPlayerHistoryFor(player.getUniqueID()).setDialogueType(EnumDialogueType.CHILDP);\n            }\n        }\n\n        return super.onItemRightClick(world, player, hand);\n    }\n\n    private String getBabyName(ItemStack stack) {\n        return stack.getTagCompound().getString(\"name\");\n    }\n\n    @Override\n    public boolean onEntityItemUpdate(EntityItem entityItem) {\n        if (!entityItem.world.isRemote) {\n            updateBabyGrowth(entityItem.getItem());\n        }\n\n        return super.onEntityItemUpdate(entityItem);\n    }\n\n    @SideOnly(Side.CLIENT)\n    @Override\n    public void addInformation(ItemStack stack, World worldIn, List<String> tooltip, ITooltipFlag flagIn) {\n        super.addInformation(stack, worldIn, tooltip, flagIn);\n        Localizer loc = MCA.getLocalizer();\n\n        if (stack.hasTagCompound()) {\n            EntityPlayer player = Minecraft.getMinecraft().player;\n            NBTTagCompound nbt = stack.getTagCompound();\n            String textColor = ((ItemBaby) stack.getItem()).isMale ? Constants.Color.AQUA : Constants.Color.LIGHTPURPLE;\n            int ageInMinutes = nbt.getInteger(\"age\");\n            String ownerName = nbt.getUniqueId(\"ownerUUID\").equals(player.getUniqueID()) ? MCA.getLocalizer().localize(\"label.you\") : nbt.getString(\"ownerName\");\n\n            if (getBabyName(stack).equals(\"\"))\n                tooltip.add(textColor + loc.localize(\"gui.label.name\") + \" \" + Constants.Format.RESET + MCA.getLocalizer().localize(\"label.unnamed\"));\n            else\n                tooltip.add(textColor + loc.localize(\"gui.label.name\") + \" \" + Constants.Format.RESET + nbt.getString(\"name\"));\n\n            tooltip.add(textColor + loc.localize(\"gui.label.age\") + \" \" + Constants.Format.RESET + ageInMinutes + \" \" + (ageInMinutes == 1 ? loc.localize(\"gui.label.minute\") : loc.localize(\"gui.label.minutes\")));\n            tooltip.add(textColor + loc.localize(\"gui.label.parent\") + \" \" + Constants.Format.RESET + ownerName);\n\n            if (nbt.getBoolean(\"isInfected\")) tooltip.add(Constants.Color.GREEN + loc.localize(\"gui.label.infected\"));\n            if (isReadyToGrowUp(stack)) tooltip.add(Constants.Color.GREEN + loc.localize(\"gui.label.readytogrow\"));\n            if (nbt.getString(\"name\").equals(loc.localize(\"gui.label.unnamed\"))) tooltip.add(Constants.Color.YELLOW + loc.localize(\"gui.label.rightclicktoname\"));\n        }\n    }\n\n    private void updateBabyGrowth(ItemStack itemStack) {\n        if (itemStack.hasTagCompound() && FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter() % 1200 == 0) {\n            int age = itemStack.getTagCompound().getInteger(\"age\");\n            age++;\n            itemStack.getTagCompound().setInteger(\"age\", age);\n        }\n    }\n\n    private boolean isReadyToGrowUp(ItemStack itemStack) {\n        return itemStack.getTagCompound().getInteger(\"age\") >= MCA.getConfig().babyGrowUpTime;\n    }\n\n    public EnumGender getGender() {\n        return isMale ? EnumGender.MALE : EnumGender.FEMALE;\n    }\n}"
  },
  {
    "path": "src/main/java/mca/items/ItemEngagementRing.java",
    "content": "package mca.items;\n\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.client.util.ITooltipFlag;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.world.World;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\n\nimport javax.annotation.Nullable;\nimport java.util.List;\n\npublic class ItemEngagementRing extends ItemWeddingRing {\n    public boolean handle(EntityPlayer player, EntityVillagerMCA villager) {\n        return super.handle(player, villager);\n    }\n\n    @SideOnly(Side.CLIENT)\n    public void addInformation(ItemStack stack, @Nullable World worldIn, List<String> tooltip, ITooltipFlag flagIn) {\n        tooltip.add(\"Halves the hearts required to marry someone.\");\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/items/ItemGuideBook.java",
    "content": "package mca.items;\n\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport mca.core.minecraft.ItemsMCA;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.entity.player.EntityPlayerMP;\nimport net.minecraft.inventory.Slot;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.item.ItemWrittenBook;\nimport net.minecraft.nbt.NBTTagCompound;\nimport net.minecraft.nbt.NBTTagList;\nimport net.minecraft.nbt.NBTTagString;\nimport net.minecraft.network.play.server.SPacketSetSlot;\nimport net.minecraft.util.ActionResult;\nimport net.minecraft.util.EnumActionResult;\nimport net.minecraft.util.EnumHand;\nimport net.minecraft.util.text.ITextComponent;\nimport net.minecraft.util.text.TextComponentString;\nimport net.minecraft.util.text.TextComponentUtils;\nimport net.minecraft.world.World;\n\npublic class ItemGuideBook extends ItemWrittenBook {\n\n    public ItemGuideBook() {\n        super();\n    }\n\n    @Override\n    public void onUpdate(ItemStack itemStack, World world, Entity entity, int unknownInt, boolean unknownBoolean) {\n        super.onUpdate(itemStack, world, entity, unknownInt, unknownBoolean);\n\n        if (!world.isRemote && !itemStack.hasTagCompound()) ItemsMCA.setBookNBT(itemStack);\n    }\n\n    @Override\n    public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) {\n        ItemStack itemstack = playerIn.getHeldItem(handIn);\n        if (worldIn.isRemote) {\n            playerIn.openGui(MCA.getInstance(), Constants.GUI_ID_GUIDEBOOK, worldIn, (int)playerIn.posX, (int)playerIn.posY, (int)playerIn.posZ);\n        }\n        return new ActionResult(EnumActionResult.SUCCESS, itemstack);\n    }\n\n    private void resolveContents(ItemStack stack, EntityPlayer player) {\n        if (stack.getTagCompound() != null) {\n            NBTTagCompound nbttagcompound = stack.getTagCompound();\n\n            if (!nbttagcompound.getBoolean(\"resolved\")) {\n                nbttagcompound.setBoolean(\"resolved\", true);\n\n                if (validBookTagContents(nbttagcompound)) {\n                    NBTTagList nbttaglist = nbttagcompound.getTagList(\"pages\", 8);\n\n                    for (int i = 0; i < nbttaglist.tagCount(); ++i) {\n                        String s = nbttaglist.getStringTagAt(i);\n                        ITextComponent itextcomponent;\n\n                        try {\n                            itextcomponent = ITextComponent.Serializer.fromJsonLenient(s);\n                            itextcomponent = TextComponentUtils.processComponent(player, itextcomponent, player);\n                        } catch (Exception var9) {\n                            itextcomponent = new TextComponentString(s);\n                        }\n                        nbttaglist.set(i, new NBTTagString(ITextComponent.Serializer.componentToJson(itextcomponent)));\n                    }\n                    nbttagcompound.setTag(\"pages\", nbttaglist);\n\n                    if (player instanceof EntityPlayerMP && player.getHeldItemMainhand() == stack) {\n                        Slot slot = player.openContainer.getSlotFromInventory(player.inventory, player.inventory.currentItem);\n                        ((EntityPlayerMP)player).connection.sendPacket(new SPacketSetSlot(0, slot.slotNumber, stack));\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "src/main/java/mca/items/ItemMatchmakersRing.java",
    "content": "package mca.items;\n\nimport com.google.common.base.Optional;\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumMarriageState;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.EnumParticleTypes;\n\nimport java.util.Comparator;\nimport java.util.List;\n\npublic class ItemMatchmakersRing extends ItemSpecialCaseGift {\n    public boolean handle(EntityPlayer player, EntityVillagerMCA villager) {\n        // ensure two rings are in the inventory\n        if (player.inventory.getStackInSlot(player.inventory.currentItem).getCount() < 2) {\n            villager.say(Optional.of(player), \"interaction.matchmaker.fail.needtwo\");\n            return false;\n        }\n\n        // ensure our target isn't married already\n        if (villager.isMarried()) {\n            villager.say(Optional.of(player), \"interaction.matchmaker.fail.married\");\n            return false;\n        }\n\n        List<EntityVillagerMCA> villagers = villager.world.getEntities(EntityVillagerMCA.class, v -> v != null && !v.isMarried() && !v.isChild() && v.getDistance(villager) < 3.0D && v != villager);\n        java.util.Optional<EntityVillagerMCA> target = villagers.stream().min(Comparator.comparingDouble(villager::getDistance));\n\n        // ensure we found a nearby villager\n        if (!target.isPresent()) {\n            villager.say(Optional.of(player), \"interaction.matchmaker.fail.novillagers\");\n            return false;\n        }\n\n        // setup the marriage by assigning spouse UUIDs\n        EntityVillagerMCA spouse = target.get();\n        villager.set(EntityVillagerMCA.SPOUSE_UUID, Optional.of(target.get().getUniqueID()));\n        villager.set(EntityVillagerMCA.MARRIAGE_STATE, EnumMarriageState.MARRIED.getId());\n        villager.set(EntityVillagerMCA.SPOUSE_NAME, spouse.get(EntityVillagerMCA.VILLAGER_NAME));\n        spouse.set(EntityVillagerMCA.SPOUSE_UUID, Optional.of(villager.getUniqueID()));\n        spouse.set(EntityVillagerMCA.MARRIAGE_STATE, EnumMarriageState.MARRIED.getId());\n        spouse.set(EntityVillagerMCA.SPOUSE_NAME, villager.get(EntityVillagerMCA.VILLAGER_NAME));\n\n        // spawn hearts to show something happened\n        villager.spawnParticles(EnumParticleTypes.HEART);\n        target.get().spawnParticles(EnumParticleTypes.HEART);\n\n        // remove the rings for survival mode\n        if (!player.isCreative()) player.inventory.setInventorySlotContents(player.inventory.currentItem, ItemStack.EMPTY);\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/items/ItemSpawnEgg.java",
    "content": "package mca.items;\n\nimport com.google.common.base.Optional;\nimport mca.entity.EntityVillagerMCA;\nimport mca.enums.EnumGender;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.EnumActionResult;\nimport net.minecraft.util.EnumFacing;\nimport net.minecraft.util.EnumHand;\nimport net.minecraft.util.math.BlockPos;\nimport net.minecraft.world.World;\n\npublic class ItemSpawnEgg extends Item {\n    private boolean isMale;\n\n    public ItemSpawnEgg(boolean isMale) {\n        this.isMale = isMale;\n        this.setMaxStackSize(1);\n    }\n\n    @Override\n    public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) {\n        int posX = pos.getX();\n        int posY = pos.getY() + 1;\n        int posZ = pos.getZ();\n\n        if (!world.isRemote) {\n            EntityVillagerMCA villager = new EntityVillagerMCA(world, Optional.absent(), Optional.of(isMale ? EnumGender.MALE : EnumGender.FEMALE));\n            villager.setPosition(posX + 0.5D, posY, posZ + 0.5D);\n            villager.finalizeMobSpawn(world.getDifficultyForLocation(villager.getPos()), null, false);\n            world.spawnEntity(villager);\n\n            if (!player.capabilities.isCreativeMode) player.inventory.setInventorySlotContents(player.inventory.currentItem, ItemStack.EMPTY);\n        }\n\n        return EnumActionResult.PASS;\n    }\n}"
  },
  {
    "path": "src/main/java/mca/items/ItemSpecialCaseGift.java",
    "content": "package mca.items;\n\nimport mca.entity.EntityVillagerMCA;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.Item;\n\npublic abstract class ItemSpecialCaseGift extends Item {\n    public abstract boolean handle(EntityPlayer player, EntityVillagerMCA villager);\n}\n"
  },
  {
    "path": "src/main/java/mca/items/ItemStaffOfLife.java",
    "content": "package mca.items;\n\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport net.minecraft.client.util.ITooltipFlag;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.ActionResult;\nimport net.minecraft.util.EnumHand;\nimport net.minecraft.util.text.TextComponentString;\nimport net.minecraft.world.World;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\nimport org.lwjgl.input.Keyboard;\n\nimport javax.annotation.Nullable;\nimport java.util.List;\n\npublic class ItemStaffOfLife extends Item {\n    public ItemStaffOfLife() {\n        super();\n        maxStackSize = 1;\n        setUnlocalizedName(\"staff_of_life\");\n        setMaxDamage(4);\n    }\n\n    @Override\n    public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) {\n        if (!MCA.getConfig().enableRevivals)\n            playerIn.sendMessage(new TextComponentString(MCA.getLocalizer().localize(\"notify.revival.disabled\")));\n\n        playerIn.openGui(MCA.getInstance(), Constants.GUI_ID_STAFFOFLIFE, playerIn.world, 0, 0, 0);\n        return super.onItemRightClick(worldIn, playerIn, handIn);\n    }\n\n    @Override\n    public void addInformation(ItemStack itemStack, @Nullable World worldIn, List<String> tooltip, ITooltipFlag flagIn) {\n        tooltip.add(\"Uses left: \" + (itemStack.getMaxDamage() - itemStack.getItemDamage() + 1));\n        if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) {\n            tooltip.add(\"Use to revive a previously dead\");\n            tooltip.add(\"villager, but all of their memories\");\n            tooltip.add(\"will be forgotten.\");\n        } else tooltip.add(\"Hold \" + Constants.Color.YELLOW + \"SHIFT\" + Constants.Color.GRAY + \" for info.\");\n    }\n\n    @SideOnly(Side.CLIENT)\n    @Override\n    public boolean hasEffect(ItemStack itemStack) {\n        return true;\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/items/ItemVillagerEditor.java",
    "content": "package mca.items;\n\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemStack;\nimport net.minecraftforge.fml.relauncher.Side;\nimport net.minecraftforge.fml.relauncher.SideOnly;\n\npublic class ItemVillagerEditor extends Item {\n\n    public ItemVillagerEditor() {\n        super();\n\n        maxStackSize = 1;\n        setUnlocalizedName(\"villager_editor\");\n    }\n\n    @SideOnly(Side.CLIENT)\n    @Override\n    public boolean hasEffect(ItemStack itemStack) {\n        return true;\n    }\n}"
  },
  {
    "path": "src/main/java/mca/items/ItemWeddingRing.java",
    "content": "package mca.items;\n\nimport com.google.common.base.Optional;\nimport mca.core.MCA;\nimport mca.entity.EntityVillagerMCA;\nimport mca.entity.data.PlayerHistory;\nimport mca.entity.data.PlayerSaveData;\nimport mca.enums.EnumDialogueType;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.util.EnumParticleTypes;\n\npublic class ItemWeddingRing extends ItemSpecialCaseGift {\n    public boolean handle(EntityPlayer player, EntityVillagerMCA villager) {\n        PlayerSaveData playerData = PlayerSaveData.get(player);\n        PlayerHistory history = villager.getPlayerHistoryFor(player.getUniqueID());\n        String response;\n\n        if (villager.isMarriedTo(player.getUniqueID()))\n            response = \"interaction.marry.fail.marriedtogiver\";\n        else if (villager.isMarried())\n            response = \"interaction.marry.fail.marriedtoother\";\n        else if (playerData.isMarriedOrEngaged())\n            response = \"interaction.marry.fail.marriedtoother\";\n        else if (this instanceof ItemEngagementRing && history.getHearts() < MCA.getConfig().marriageHeartsRequirement / 2)\n            response = \"interaction.marry.fail.lowhearts\";\n        else if (!(this instanceof ItemEngagementRing) && history.getHearts() < MCA.getConfig().marriageHeartsRequirement)\n            response = \"interaction.marry.fail.lowhearts\";\n        else {\n            response = \"interaction.marry.success\";\n            playerData.marry(villager.getUniqueID(), villager.get(EntityVillagerMCA.VILLAGER_NAME));\n            villager.getPlayerHistoryFor(player.getUniqueID()).setDialogueType(EnumDialogueType.SPOUSE);\n            villager.spawnParticles(EnumParticleTypes.HEART);\n            villager.marry(player);\n        }\n\n        villager.say(Optional.of(player), response);\n        return false;\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/items/ItemWhistle.java",
    "content": "package mca.items;\n\nimport java.util.List;\n\nimport mca.core.Constants;\nimport mca.core.MCA;\nimport net.minecraft.client.util.ITooltipFlag;\nimport net.minecraft.entity.player.EntityPlayer;\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemStack;\nimport net.minecraft.util.ActionResult;\nimport net.minecraft.util.EnumHand;\nimport net.minecraft.world.World;\n\npublic class ItemWhistle extends Item {\n    public ItemWhistle() {\n        super();\n        maxStackSize = 1;\n    }\n\n    @Override\n    public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {\n        player.openGui(MCA.getInstance(), Constants.GUI_ID_WHISTLE, world, (int)player.posX, (int)player.posY, (int)player.posZ);\n        return super.onItemRightClick(world, player, hand);\n    }\n\n    @Override\n    public void addInformation(ItemStack stack, World worldIn, List<String> tooltip, ITooltipFlag flagIn) {\n        super.addInformation(stack, worldIn, tooltip, flagIn);\n        tooltip.add(\"Allows you to call your family to your current location.\");\n    }\n}"
  },
  {
    "path": "src/main/java/mca/server/ServerMessageHandler.java",
    "content": "package mca.server;\n\nimport mca.core.forge.NetMCA;\nimport mca.core.minecraft.VillageHelper;\nimport net.minecraft.entity.player.EntityPlayerMP;\nimport net.minecraft.util.text.TextComponentString;\n\npublic class ServerMessageHandler {\n\n    public static void handleMessage(EntityPlayerMP player, NetMCA.ButtonAction message) {\n        switch (message.getButtonId()) {\n            case \"gui.button.debug.startraid\":\n                startRaid(player);\n                break;\n            case \"gui.button.debug.spawnguards\":\n                spawnGuards(player);\n                break;\n            case \"gui.button.debug.rebuildvillage\":\n                rebuildVillage(player);\n                break;\n        }\n    }\n\n    private static void startRaid(EntityPlayerMP player) {\n        player.sendMessage(new TextComponentString(\"Starting raid on village...\"));\n        VillageHelper.forceRaid(player);\n    }\n\n    private static void spawnGuards(EntityPlayerMP player) {\n        player.sendMessage(new TextComponentString(\"Spawning village guards...\"));\n        VillageHelper.tick(player.world);\n    }\n\n    private static void rebuildVillage(EntityPlayerMP player) {\n        player.sendMessage(new TextComponentString(\"Rebuilding annihilated village...\"));\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/util/ItemStackCache.java",
    "content": "package mca.util;\n\nimport net.minecraft.item.Item;\nimport net.minecraft.item.ItemStack;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class ItemStackCache {\n    private static Map<Item, ItemStack> cache = new HashMap<>();\n\n    public static ItemStack get(Item item) {\n        if (!cache.containsKey(item)) cache.put(item, new ItemStack(item, 1));\n        return cache.get(item);\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/util/ResourceLocationCache.java",
    "content": "package mca.util;\n\nimport net.minecraft.util.ResourceLocation;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class ResourceLocationCache {\n    private static Map<String, ResourceLocation> cache = new HashMap<>();\n\n    public static ResourceLocation getResourceLocationFor(String location) {\n        if (cache.containsKey(location)) {\n            return cache.get(location);\n        } else {\n            ResourceLocation rLoc = new ResourceLocation(location);\n            cache.put(location, rLoc);\n            return rLoc;\n        }\n    }\n}\n"
  },
  {
    "path": "src/main/java/mca/util/Util.java",
    "content": "package mca.util;\n\nimport com.google.common.base.Optional;\nimport com.google.gson.Gson;\nimport mca.core.MCA;\nimport net.minecraft.block.Block;\nimport net.minecraft.entity.Entity;\nimport net.minecraft.init.Blocks;\nimport net.minecraft.util.math.BlockPos;\nimport net.minecraft.world.World;\nimport org.apache.commons.io.IOUtils;\n\nimport javax.annotation.Nullable;\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.UUID;\n\nimport static org.apache.http.protocol.HTTP.USER_AGENT;\n\npublic class Util {\n    private static final String RESOURCE_PREFIX = \"assets/mca/\";\n\n    /**\n     * Finds a y position given an x,y,z coordinate triple that is assumed to be the world's \"ground\".\n     *\n     * @param world\tThe world in which blocks will be tested\n     * @param x\t\t\tX coordinate\n     * @param y\t\t\tY coordinate, used as the starting height for finding ground.\n     * @param z\t\t\tZ coordinate\n     * @return Integer representing the air block above the first non-air block given the provided ordered triples.\n     */\n    public static int getSpawnSafeTopLevel(World world, int x, int y, int z)\n    {\n        Block block = Blocks.AIR;\n        while (block == Blocks.AIR && y > 0) {\n            y--;\n            block = world.getBlockState(new BlockPos(x, y, z)).getBlock();\n        }\n\n        return y + 1;\n    }\n\n    public static String readResource(String path) {\n        String data;\n        String location = RESOURCE_PREFIX + path;\n\n        try {\n            data = IOUtils.toString(new InputStreamReader(MCA.class.getClassLoader().getResourceAsStream(location)));\n        } catch (IOException e) {\n            throw new RuntimeException(\"Failed to read resource from JAR: \" + location);\n        }\n\n        return data;\n    }\n\n    public static <T> T readResourceAsJSON(String path, Class<T> type) {\n        Gson gson = new Gson();\n        T data = gson.fromJson(Util.readResource(path), type);\n        return data;\n    }\n\n    public static Optional<Entity> getEntityByUUID(World world, UUID uuid) {\n        for (Entity entity : world.loadedEntityList) {\n            if (entity.getUniqueID().equals(uuid)) {\n                return Optional.of(entity);\n            }\n        }\n        return Optional.absent();\n    }\n\n    public static <T extends Entity> Optional<T> getEntityByUUID(World world, UUID uuid, Class<? extends T> clazz) {\n        for (Entity entity : world.loadedEntityList) {\n            if (entity.getClass().isAssignableFrom(clazz) && entity.getUniqueID().equals(uuid)) {\n                return Optional.of((T) entity);\n            }\n        }\n        return Optional.absent();\n    }\n\n    public static List<BlockPos> getNearbyBlocks(BlockPos origin, World world, @Nullable Class filter, int xzDist, int yDist) {\n        final List<BlockPos> pointsList = new ArrayList<>();\n        for (int x = -xzDist; x <= xzDist; x++) {\n            for (int y = -yDist; y <= yDist; y++) {\n                for (int z = -xzDist; z <= xzDist; z++) {\n                    if (x != 0 || y != 0 || z != 0) {\n                        BlockPos pos = new BlockPos(origin.getX() + x, origin.getY() + y, origin.getZ() + z);\n                        if (filter != null && filter.isAssignableFrom(world.getBlockState(pos).getBlock().getClass())) {\n                            pointsList.add(pos);\n                        } else if (filter == null) {\n                            pointsList.add(pos);\n                        }\n                    }\n                }\n            }\n        }\n        return pointsList;\n    }\n\n    public static BlockPos getNearestPoint(BlockPos origin, List<BlockPos> blocks) {\n        double closest = 100.0D;\n        BlockPos returnPoint = null;\n        for (BlockPos point : blocks) {\n            double distance = origin.getDistance(point.getX(), point.getY(), point.getZ());\n            if (distance < closest) {\n                closest = distance;\n                returnPoint = point;\n            }\n        }\n\n        return returnPoint;\n    }\n\n    public static String httpGet(String url) {\n        try {\n            URL obj = new URL(url);\n            HttpURLConnection con = (HttpURLConnection) obj.openConnection();\n            con.setRequestMethod(\"GET\");\n            con.setRequestProperty(\"User-Agent\", USER_AGENT);\n\n            BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));\n            String inputLine;\n            StringBuffer response = new StringBuffer();\n\n            while ((inputLine = in.readLine()) != null) {\n                response.append(inputLine);\n            }\n            in.close();\n            return response.toString();\n        } catch (IOException ignored) {\n            MCA.getLog().error(\"Failed to GET from: \" + url);\n        }\n        return \"\";\n    }\n}\n"
  },
  {
    "path": "src/main/resources/assets/mca/api/gifts.json",
    "content": "[\n  {\"type\":\"item\", \"name\":\"minecraft:wooden_sword\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:wooden_axe\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:wooden_hoe\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:wooden_shovel\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:stone_sword\", \"value\":6},\n  {\"type\":\"item\", \"name\":\"minecraft:stone_axe\", \"value\":6},\n  {\"type\":\"item\", \"name\":\"minecraft:stone_hoe\", \"value\":6},\n  {\"type\":\"item\", \"name\":\"minecraft:stone_shovel\", \"value\":6},\n  {\"type\":\"item\", \"name\":\"minecraft:wooden_pickaxe\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:beef\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:chicken\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:porkchop\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:leather\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:leather_chestplate\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:leather_helmet\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:leather_leggings\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:leather_boots\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:reeds\", \"value\":2},\n  {\"type\":\"item\", \"name\":\"minecraft:wheat_seeds\", \"value\":1},\n  {\"type\":\"item\", \"name\":\"minecraft:wheat\", \"value\":1},\n  {\"type\":\"item\", \"name\":\"minecraft:bread\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:coal\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:sugar\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:clay_ball\", \"value\":0},\n  {\"type\":\"item\", \"name\":\"minecraft:dye\", \"value\":1},\n  {\"type\":\"item\", \"name\":\"minecraft:cooked_beef\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:cooked_chicken\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:cooked_porkchop\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:cookie\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:melon\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:melon_seeds\", \"value\":1},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_helmet\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_chestplate\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_leggings\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_boots\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:cake\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_sword\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_axe\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_hoe\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_pickaxe\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_shovel\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:fishing_rod\", \"value\":1},\n  {\"type\":\"item\", \"name\":\"minecraft:bow\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:book\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:bucket\", \"value\":0},\n  {\"type\":\"item\", \"name\":\"minecraft:milk_bucket\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:water_bucket\", \"value\":0},\n  {\"type\":\"item\", \"name\":\"minecraft:lava_bucket\", \"value\":0},\n  {\"type\":\"item\", \"name\":\"minecraft:mushroom_stew\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:pumpkin_seeds\", \"value\":2},\n  {\"type\":\"item\", \"name\":\"minecraft:flint_and_steel\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:redstone\", \"value\":2},\n  {\"type\":\"item\", \"name\":\"minecraft:boat\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_door\", \"value\":0},\n  {\"type\":\"item\", \"name\":\"minecraft:minecart\", \"value\":0},\n  {\"type\":\"item\", \"name\":\"minecraft:flint\", \"value\":0},\n  {\"type\":\"item\", \"name\":\"minecraft:gold_nugget\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:gold_ingot\", \"value\":8},\n  {\"type\":\"item\", \"name\":\"minecraft:iron_ingot\", \"value\":4},\n  {\"type\":\"item\", \"name\":\"minecraft:diamond\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:map\", \"value\":0},\n  {\"type\":\"item\", \"name\":\"minecraft:clock\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:compass\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:blaze_rod\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:blaze_powder\", \"value\":6},\n  {\"type\":\"item\", \"name\":\"minecraft:diamond_sword\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:diamond_axe\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:diamond_shovel\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:diamond_hoe\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:diamond_helmet\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:diamond_chestplate\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:diamond_leggings\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:diamond_boots\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:painting\", \"value\":10},\n  {\"type\":\"item\", \"name\":\"minecraft:ender_pearl\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:ender_eye\", \"value\":25},\n  {\"type\":\"item\", \"name\":\"minecraft:slime_ball\", \"value\":0},\n  {\"type\":\"item\", \"name\":\"minecraft:saddle\", \"value\":3},\n  {\"type\":\"item\", \"name\":\"minecraft:gunpowder\", \"value\":5},\n  {\"type\":\"item\", \"name\":\"minecraft:golden_apple\", \"value\":25},\n  {\"type\":\"item\", \"name\":\"minecraft:record_11\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:record_13\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:record_wait\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:record_cat\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:record_chirp\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:record_far\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:record_mall\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:record_mellohi\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:record_stal\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:record_strad\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:record_ward\", \"value\":15},\n  {\"type\":\"item\", \"name\":\"minecraft:emerald\", \"value\":25},\n  {\"type\":\"block\",\"name\":\"minecraft:red_flower\",\"value\":2},\n  {\"type\":\"block\",\"name\":\"minecraft:yellow_flower\",\"value\":2},\n  {\"type\":\"block\",\"name\":\"minecraft:planks\",\"value\":1},\n  {\"type\":\"block\",\"name\":\"minecraft:log\",\"value\":1},\n  {\"type\":\"block\",\"name\":\"minecraft:pumpkin\",\"value\":3},\n  {\"type\":\"block\",\"name\":\"minecraft:chest\",\"value\":6},\n  {\"type\":\"block\",\"name\":\"minecraft:wool\",\"value\":3},\n  {\"type\":\"block\",\"name\":\"minecraft:iron_ore\",\"value\":3},\n  {\"type\":\"block\",\"name\":\"minecraft:gold_ore\",\"value\":5},\n  {\"type\":\"block\",\"name\":\"minecraft:redstone_ore\",\"value\":3},\n  {\"type\":\"block\",\"name\":\"minecraft:rail\",\"value\":5},\n  {\"type\":\"block\",\"name\":\"minecraft:detector_rail\",\"value\":7},\n  {\"type\":\"block\",\"name\":\"minecraft:activator_rail\",\"value\":7},\n  {\"type\":\"block\",\"name\":\"minecraft:furnace\",\"value\":5},\n  {\"type\":\"block\",\"name\":\"minecraft:crafting_table\",\"value\":3},\n  {\"type\":\"block\",\"name\":\"minecraft:lapis_block\",\"value\":15},\n  {\"type\":\"block\",\"name\":\"minecraft:bookshelf\",\"value\":5},\n  {\"type\":\"block\",\"name\":\"minecraft:gold_block\",\"value\":15},\n  {\"type\":\"block\",\"name\":\"minecraft:iron_block\",\"value\":10},\n  {\"type\":\"block\",\"name\":\"minecraft:diamond_block\",\"value\":25},\n  {\"type\":\"block\",\"name\":\"minecraft:brewing_stand\",\"value\":5},\n  {\"type\":\"block\",\"name\":\"minecraft:enchanting_table\",\"value\":5},\n  {\"type\":\"block\",\"name\":\"minecraft:brick_block\",\"value\":3},\n  {\"type\":\"block\",\"name\":\"minecraft:obsidian\",\"value\":9},\n  {\"type\":\"block\",\"name\":\"minecraft:piston\",\"value\":6},\n  {\"type\":\"block\",\"name\":\"minecraft:glowstone\",\"value\":5},\n  {\"type\":\"block\",\"name\":\"minecraft:emerald_block\",\"value\":25},\n  {\"type\":\"block\",\"name\":\"minecraft:redstone_block\",\"value\":15},\n  {\"type\":\"block\",\"name\":\"mca:rose_gold_block\",\"value\":10},\n  {\"type\":\"block\",\"name\":\"mca:rose_gold_ore\",\"value\":10}\n]"
  },
  {
    "path": "src/main/resources/assets/mca/api/gui/debug.json",
    "content": "[\n    {\n      \"id\": 1,\n      \"identifier\": \"gui.button.debug.startraid\",\n      \"x\": 120,\n      \"y\": -115,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": true,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 2,\n      \"identifier\": \"gui.button.debug.spawnguards\",\n      \"x\": 120,\n      \"y\": -93,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": true,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 3,\n      \"identifier\": \"gui.button.debug.selectnearestvillager\",\n      \"x\": 120,\n      \"y\": -71,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": false,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 4,\n      \"identifier\": \"gui.button.debug.startmining\",\n      \"x\": 120,\n      \"y\": -49,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 5,\n      \"identifier\": \"gui.button.debug.startfishing\",\n      \"x\": 120,\n      \"y\": -27,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 6,\n      \"identifier\": \"gui.button.debug.startchopping\",\n      \"x\": 120,\n      \"y\": -5,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 7,\n      \"identifier\": \"gui.button.debug.starthunting\",\n      \"x\": 120,\n      \"y\": 17,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 8,\n      \"identifier\": \"gui.button.debug.startharvesting\",\n      \"x\": 120,\n      \"y\": 39,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 9,\n      \"identifier\": \"gui.button.debug.zombify\",\n      \"x\": 10,\n      \"y\": -115,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 10,\n      \"identifier\": \"gui.button.debug.unzombify\",\n      \"x\": 10,\n      \"y\": -93,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 11,\n      \"identifier\": \"gui.button.debug.marrytoplayer\",\n      \"x\": 10,\n      \"y\": -71,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 12,\n      \"identifier\": \"gui.button.debug.rebuildvillage\",\n      \"x\": 10,\n      \"y\": -49,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": true,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 13,\n      \"identifier\": \"gui.button.debug.openinventory\",\n      \"x\": 10,\n      \"y\": -27,\n      \"width\": 85,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    }\n]"
  },
  {
    "path": "src/main/resources/assets/mca/api/gui/editor.json",
    "content": "[\n  {\n    \"id\": 1,\n    \"identifier\": \"gui.button.random\",\n    \"x\": -50,\n    \"y\": -95,\n    \"width\": 60,\n    \"height\": 20,\n    \"notifyServer\": true\n  },\n  {\n    \"id\": 2,\n    \"identifier\": \"gui.button.gender\",\n    \"x\": -190,\n    \"y\": -40,\n    \"width\": 175,\n    \"height\": 20,\n    \"notifyServer\": true\n  },\n  {\n    \"id\": 3,\n    \"identifier\": \"gui.button.texture.set\",\n    \"x\": 70,\n    \"y\": -15,\n    \"width\": 60,\n    \"height\": 20\n  },\n  {\n    \"id\": 4,\n    \"identifier\": \"gui.button.texture.randomize\",\n    \"x\": 140,\n    \"y\": -15,\n    \"width\": 60,\n    \"height\": 20,\n    \"notifyServer\": true\n  },\n  {\n    \"id\": 5,\n    \"identifier\": \"gui.button.profession.set\",\n    \"x\": 70,\n    \"y\": 10,\n    \"width\": 60,\n    \"height\": 20\n  },\n  {\n    \"id\": 6,\n    \"identifier\": \"gui.button.profession.randomize\",\n    \"x\": 140,\n    \"y\": 10,\n    \"width\": 60,\n    \"height\": 20,\n    \"notifyServer\": true\n  },\n  {\n    \"id\": 7,\n    \"identifier\": \"gui.button.infected\",\n    \"x\": -190,\n    \"y\": 35,\n    \"width\": 175,\n    \"height\": 20,\n    \"notifyServer\": true\n  },\n  {\n    \"id\": 8,\n    \"identifier\": \"gui.button.done\",\n    \"x\": -65,\n    \"y\": 85,\n    \"width\": 75,\n    \"height\": 20\n  },\n  {\n    \"id\": 9,\n    \"identifier\": \"gui.button.copyuuid\",\n    \"x\": 25,\n    \"y\": 85,\n    \"width\": 75,\n    \"height\": 20\n  }\n]"
  },
  {
    "path": "src/main/resources/assets/mca/api/gui/interact.json",
    "content": "[\n    {\n      \"id\": 1,\n      \"identifier\": \"gui.button.backarrow\",\n      \"x\": 120,\n      \"y\": -115,\n      \"width\": 15,\n      \"height\": 20,\n      \"notifyServer\": false,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 1,\n      \"identifier\": \"gui.button.chat\",\n      \"x\": 140,\n      \"y\": -115,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\",\n      \"isInteraction\": true\n    },\n    {\n      \"id\": 2,\n      \"identifier\": \"gui.button.joke\",\n      \"x\": 140,\n      \"y\": -93,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\",\n      \"isInteraction\": true\n    },\n    {\n      \"id\": 3,\n      \"identifier\": \"gui.button.gift\",\n      \"x\": 140,\n      \"y\": -71,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": false,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 4,\n      \"identifier\": \"gui.button.shakehand\",\n      \"x\": 140,\n      \"y\": -49,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\",\n      \"isInteraction\": true\n    },\n    {\n      \"id\": 5,\n      \"identifier\": \"gui.button.tellstory\",\n      \"x\": 140,\n      \"y\": -27,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\",\n      \"isInteraction\": true\n    },\n    {\n      \"id\": 6,\n      \"identifier\": \"gui.button.flirt\",\n      \"x\": 140,\n      \"y\": -5,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"adults\",\n      \"isInteraction\": true\n    },\n    {\n      \"id\": 7,\n      \"identifier\": \"gui.button.hug\",\n      \"x\": 140,\n      \"y\": 17,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"adults\",\n      \"isInteraction\": true\n    },\n    {\n      \"id\": 8,\n      \"identifier\": \"gui.button.kiss\",\n      \"x\": 140,\n      \"y\": 39,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"adults\",\n      \"isInteraction\": true\n    }\n]"
  },
  {
    "path": "src/main/resources/assets/mca/api/gui/location.json",
    "content": "[\n  {\n    \"id\": 1,\n    \"identifier\": \"gui.button.backarrow\",\n    \"x\": 140,\n    \"y\": -115,\n    \"width\": 65,\n    \"height\": 20,\n    \"notifyServer\": false,\n    \"targetServer\": false,\n    \"constraints\": \"\"\n  },\n  {\n    \"id\": 2,\n    \"identifier\": \"gui.button.sethome\",\n    \"x\": 140,\n    \"y\": -93,\n    \"width\": 65,\n    \"height\": 20,\n    \"notifyServer\": true,\n    \"targetServer\": false,\n    \"constraints\": \"\"\n  },\n  {\n    \"id\": 3,\n    \"identifier\": \"gui.button.setworkplace\",\n    \"x\": 140,\n    \"y\": -71,\n    \"width\": 65,\n    \"height\": 20,\n    \"notifyServer\": true,\n    \"targetServer\": false,\n    \"constraints\": \"\"\n  },\n  {\n    \"id\": 4,\n    \"identifier\": \"gui.button.sethangout\",\n    \"x\": 140,\n    \"y\": -49,\n    \"width\": 65,\n    \"height\": 20,\n    \"notifyServer\": true,\n    \"targetServer\": false,\n    \"constraints\": \"\"\n  }\n]"
  },
  {
    "path": "src/main/resources/assets/mca/api/gui/main.json",
    "content": "[\n    {\n      \"id\": 1,\n      \"identifier\": \"gui.button.interact\",\n      \"x\": 140,\n      \"y\": -115,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": false,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 2,\n      \"identifier\": \"gui.button.follow\",\n      \"x\": 140,\n      \"y\": -93,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 3,\n      \"identifier\": \"gui.button.stay\",\n      \"x\": 140,\n      \"y\": -71,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 4,\n      \"identifier\": \"gui.button.move\",\n      \"x\": 140,\n      \"y\": -49,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 5,\n      \"identifier\": \"gui.button.trade\",\n      \"x\": 140,\n      \"y\": -27,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"notfamily|hideonfail\"\n    },\n    {\n      \"id\": 12,\n      \"identifier\": \"gui.button.inventory\",\n      \"x\": 140,\n      \"y\": -27,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"family|hideonfail\"\n    },\n    {\n      \"id\": 6,\n      \"identifier\": \"gui.button.location\",\n      \"x\": 140,\n      \"y\": -5,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": false,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 7,\n      \"identifier\": \"gui.button.gohome\",\n      \"x\": 140,\n      \"y\": 17,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"spouseOnly\": false,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 8,\n      \"identifier\": \"gui.button.ridehorse\",\n      \"x\": 140,\n      \"y\": 39,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 9,\n      \"identifier\": \"gui.button.work\",\n      \"x\": 140,\n      \"y\": 61,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": false,\n      \"targetServer\": false,\n      \"constraints\": \"family|hideonfail\"\n    },\n    {\n      \"id\": 10,\n      \"identifier\": \"gui.button.procreate\",\n      \"x\": 140,\n      \"y\": 83,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"spouse|hideonfail\"\n    }\n]"
  },
  {
    "path": "src/main/resources/assets/mca/api/gui/work.json",
    "content": "[\n    {\n      \"id\": 1,\n      \"identifier\": \"gui.button.backarrow\",\n      \"x\": 140,\n      \"y\": -115,\n      \"width\": 15,\n      \"height\": 20,\n      \"notifyServer\": false,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 2,\n      \"identifier\": \"gui.button.fishing\",\n      \"x\": 140,\n      \"y\": -115,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 3,\n      \"identifier\": \"gui.button.harvesting\",\n      \"x\": 140,\n      \"y\": -93,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 4,\n      \"identifier\": \"gui.button.hunting\",\n      \"x\": 140,\n      \"y\": -71,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 5,\n      \"identifier\": \"gui.button.prospecting\",\n      \"x\": 140,\n      \"y\": -49,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 5,\n      \"identifier\": \"gui.button.chopping\",\n      \"x\": 140,\n      \"y\": -27,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    },\n    {\n      \"id\": 6,\n      \"identifier\": \"gui.button.stopworking\",\n      \"x\": 140,\n      \"y\": -5,\n      \"width\": 65,\n      \"height\": 20,\n      \"notifyServer\": true,\n      \"targetServer\": false,\n      \"constraints\": \"\"\n    }\n]"
  },
  {
    "path": "src/main/resources/assets/mca/api/skins.json",
    "content": "[\n  {\n    \"gender\": \"male\",\n    \"profession\": \"minecraft:farmer\",\n    \"paths\": [\n        \"mca:skins/male/farmer/farmerm1_converted.png\",\n        \"mca:skins/male/farmer/farmerm2_converted.png\",\n        \"mca:skins/male/farmer/farmerm3_converted.png\",\n        \"mca:skins/male/farmer/farmerm4_converted.png\",\n        \"mca:skins/male/farmer/farmerm5_converted.png\",\n        \"mca:skins/male/farmer/farmerm6_converted.png\",\n        \"mca:skins/male/farmer/farmerm7_converted.png\",\n        \"mca:skins/male/farmer/farmerm8_converted.png\",\n        \"mca:skins/male/farmer/farmerm9_converted.png\",\n        \"mca:skins/male/farmer/farmerm10_converted.png\",\n        \"mca:skins/male/farmer/farmerm11_converted.png\",\n        \"mca:skins/male/farmer/farmerm12_converted.png\",\n        \"mca:skins/male/farmer/farmerm13_converted.png\",\n        \"mca:skins/male/farmer/farmerm14_converted.png\",\n        \"mca:skins/male/farmer/farmerm15_converted.png\",\n        \"mca:skins/male/farmer/farmerm16_converted.png\",\n        \"mca:skins/male/farmer/farmerm17_converted.png\",\n        \"mca:skins/male/farmer/farmerm18_converted.png\",\n        \"mca:skins/male/farmer/farmerm19_converted.png\",\n        \"mca:skins/male/farmer/farmerm20_converted.png\",\n        \"mca:skins/male/farmer/farmerm21_converted.png\",\n        \"mca:skins/male/farmer/farmerm23_converted.png\",\n        \"mca:skins/male/farmer/farmerm25_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"female\",\n    \"profession\": \"minecraft:farmer\",\n    \"paths\": [\n        \"mca:skins/female/farmer/farmerf1_converted.png\",\n        \"mca:skins/female/farmer/farmerf2_converted.png\",\n        \"mca:skins/female/farmer/farmerf3_converted.png\",\n        \"mca:skins/female/farmer/farmerf4_converted.png\",\n        \"mca:skins/female/farmer/farmerf5_converted.png\",\n        \"mca:skins/female/farmer/farmerf6_converted.png\",\n        \"mca:skins/female/farmer/farmerf7_converted.png\",\n        \"mca:skins/female/farmer/farmerf8_converted.png\",\n        \"mca:skins/female/farmer/farmerf9_converted.png\",\n        \"mca:skins/female/farmer/farmerf10_converted.png\",\n        \"mca:skins/female/farmer/farmerf11_converted.png\",\n        \"mca:skins/female/farmer/farmerf12_converted.png\",\n        \"mca:skins/female/farmer/farmerf13_converted.png\",\n        \"mca:skins/female/farmer/farmerf14_converted.png\",\n        \"mca:skins/female/farmer/farmerf15_converted.png\",\n        \"mca:skins/female/farmer/farmerf16_converted.png\",\n        \"mca:skins/female/farmer/farmerf17_converted.png\",\n        \"mca:skins/female/farmer/farmerf18_converted.png\",\n        \"mca:skins/female/farmer/farmerf19_converted.png\",\n        \"mca:skins/female/farmer/farmerf20_converted.png\",\n        \"mca:skins/female/farmer/farmerf21_converted.png\",\n        \"mca:skins/female/farmer/farmerf22_converted.png\",\n        \"mca:skins/female/farmer/farmerf23_converted.png\",\n        \"mca:skins/female/farmer/farmerf24_converted.png\",\n        \"mca:skins/female/farmer/farmerf25_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"male\",\n    \"profession\": \"minecraft:librarian\",\n    \"paths\": [\n      \"mca:skins/male/librarian/librarianm1_converted.png\",\n      \"mca:skins/male/librarian/librarianm2_converted.png\",\n      \"mca:skins/male/librarian/librarianm3_converted.png\",\n      \"mca:skins/male/librarian/librarianm4_converted.png\",\n      \"mca:skins/male/librarian/librarianm5_converted.png\",\n      \"mca:skins/male/librarian/librarianm6_converted.png\",\n      \"mca:skins/male/librarian/librarianm7_converted.png\",\n      \"mca:skins/male/librarian/librarianm8_converted.png\",\n      \"mca:skins/male/librarian/librarianm9_converted.png\",\n      \"mca:skins/male/librarian/librarianm10_converted.png\",\n      \"mca:skins/male/librarian/librarianm11_converted.png\",\n      \"mca:skins/male/librarian/librarianm12_converted.png\",\n      \"mca:skins/male/librarian/librarianm13_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"female\",\n    \"profession\": \"minecraft:librarian\",\n    \"paths\": [\n      \"mca:skins/female/librarian/librarianf1_converted.png\",\n      \"mca:skins/female/librarian/librarianf2_converted.png\",\n      \"mca:skins/female/librarian/librarianf3_converted.png\",\n      \"mca:skins/female/librarian/librarianf4_converted.png\",\n      \"mca:skins/female/librarian/librarianf5_converted.png\",\n      \"mca:skins/female/librarian/librarianf6_converted.png\",\n      \"mca:skins/female/librarian/librarianf7_converted.png\",\n      \"mca:skins/female/librarian/librarianf8_converted.png\",\n      \"mca:skins/female/librarian/librarianf9_converted.png\",\n      \"mca:skins/female/librarian/librarianf10_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"male\",\n    \"profession\": \"minecraft:priest\",\n    \"paths\": [\n      \"mca:skins/male/priest/priestm1_converted.png\",\n      \"mca:skins/male/priest/priestm2_converted.png\",\n      \"mca:skins/male/priest/priestm3_converted.png\",\n      \"mca:skins/male/priest/priestm4_converted.png\",\n      \"mca:skins/male/priest/priestm5_converted.png\",\n      \"mca:skins/male/priest/priestm6_converted.png\",\n      \"mca:skins/male/priest/priestm7_converted.png\",\n      \"mca:skins/male/priest/priestm8_converted.png\",\n      \"mca:skins/male/priest/priestm9_converted.png\",\n      \"mca:skins/male/priest/priestm10_converted.png\",\n      \"mca:skins/male/priest/priestm11_converted.png\",\n      \"mca:skins/male/priest/priestm12_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"female\",\n    \"profession\": \"minecraft:priest\",\n    \"paths\": [\n      \"mca:skins/female/priest/priestf1_converted.png\",\n      \"mca:skins/female/priest/priestf2_converted.png\",\n      \"mca:skins/female/priest/priestf3_converted.png\",\n      \"mca:skins/female/priest/priestf4_converted.png\",\n      \"mca:skins/female/priest/priestf5_converted.png\",\n      \"mca:skins/female/priest/priestf6_converted.png\",\n      \"mca:skins/female/priest/priestf7_converted.png\",\n      \"mca:skins/female/priest/priestf8_converted.png\",\n      \"mca:skins/female/priest/priestf9_converted.png\",\n      \"mca:skins/female/priest/priestf10_converted.png\",\n      \"mca:skins/female/priest/priestf11_converted.png\",\n      \"mca:skins/female/priest/priestf12_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"male\",\n    \"profession\": \"minecraft:smith\",\n    \"paths\": [\n      \"mca:skins/male/smith/smithm1_converted.png\",\n      \"mca:skins/male/smith/smithm2_converted.png\",\n      \"mca:skins/male/smith/smithm3_converted.png\",\n      \"mca:skins/male/smith/smithm4_converted.png\",\n      \"mca:skins/male/smith/smithm5_converted.png\",\n      \"mca:skins/male/smith/smithm6_converted.png\",\n      \"mca:skins/male/smith/smithm7_converted.png\",\n      \"mca:skins/male/smith/smithm8_converted.png\",\n      \"mca:skins/male/smith/smithm9_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"female\",\n    \"profession\": \"minecraft:smith\",\n    \"paths\": [\n      \"mca:skins/female/smith/smithf1_converted.png\",\n      \"mca:skins/female/smith/smithf2_converted.png\",\n      \"mca:skins/female/smith/smithf3_converted.png\",\n      \"mca:skins/female/smith/smithf4_converted.png\",\n      \"mca:skins/female/smith/smithf5_converted.png\",\n      \"mca:skins/female/smith/smithf6_converted.png\",\n      \"mca:skins/female/smith/smithf7_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"male\",\n    \"profession\": \"minecraft:butcher\",\n    \"paths\": [\n      \"mca:skins/male/butcher/butcherm1_converted.png\",\n      \"mca:skins/male/butcher/butcherm2_converted.png\",\n      \"mca:skins/male/butcher/butcherm3_converted.png\",\n      \"mca:skins/male/butcher/butcherm4_converted.png\",\n      \"mca:skins/male/butcher/butcherm5_converted.png\",\n      \"mca:skins/male/butcher/butcherm6_converted.png\",\n      \"mca:skins/male/butcher/butcherm7_converted.png\",\n      \"mca:skins/male/butcher/butcherm8_converted.png\",\n      \"mca:skins/male/butcher/butcherm9_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"female\",\n    \"profession\": \"minecraft:butcher\",\n    \"paths\": [\n      \"mca:skins/female/butcher/butcherf1_converted.png\",\n      \"mca:skins/female/butcher/butcherf2_converted.png\",\n      \"mca:skins/female/butcher/butcherf3_converted.png\",\n      \"mca:skins/female/butcher/butcherf4_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"male\",\n    \"profession\": \"mca:baker\",\n    \"paths\": [\n      \"mca:skins/male/baker/bakerm1_converted.png\",\n      \"mca:skins/male/baker/bakerm2_converted.png\",\n      \"mca:skins/male/baker/bakerm3_converted.png\",\n      \"mca:skins/male/baker/bakerm4_converted.png\",\n      \"mca:skins/male/baker/bakerm5_converted.png\",\n      \"mca:skins/male/baker/bakerm6_converted.png\",\n      \"mca:skins/male/baker/bakerm7_converted.png\",\n      \"mca:skins/male/baker/bakerm8_converted.png\",\n      \"mca:skins/male/baker/bakerm9_converted.png\",\n      \"mca:skins/male/baker/bakerm10_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"female\",\n    \"profession\": \"mca:baker\",\n    \"paths\": [\n      \"mca:skins/female/baker/bakerf1_converted.png\",\n      \"mca:skins/female/baker/bakerf2_converted.png\",\n      \"mca:skins/female/baker/bakerf3_converted.png\",\n      \"mca:skins/female/baker/bakerf4_converted.png\",\n      \"mca:skins/female/baker/bakerf5_converted.png\",\n      \"mca:skins/female/baker/bakerf6_converted.png\",\n      \"mca:skins/female/baker/bakerf7_converted.png\",\n      \"mca:skins/female/baker/bakerf8_converted.png\",\n      \"mca:skins/female/baker/bakerf9_converted.png\",\n      \"mca:skins/female/baker/bakerf10_converted.png\",\n      \"mca:skins/female/baker/bakerf11_converted.png\",\n      \"mca:skins/female/baker/bakerf12_converted.png\",\n      \"mca:skins/female/baker/bakerf13_converted.png\"\n    ]\n  },\n  {\n  \"gender\": \"male\",\n  \"profession\": \"mca:miner\",\n  \"paths\": [\n    \"mca:skins/male/miner/minerm1_converted.png\",\n    \"mca:skins/male/miner/minerm2_converted.png\",\n    \"mca:skins/male/miner/minerm3_converted.png\",\n    \"mca:skins/male/miner/minerm4_converted.png\",\n    \"mca:skins/male/miner/minerm5_converted.png\",\n    \"mca:skins/male/miner/minerm6_converted.png\",\n    \"mca:skins/male/miner/minerm7_converted.png\",\n    \"mca:skins/male/miner/minerm8_converted.png\",\n    \"mca:skins/male/miner/minerm9_converted.png\",\n    \"mca:skins/male/miner/minerm10_converted.png\",\n    \"mca:skins/male/miner/minerm11_converted.png\",\n    \"mca:skins/male/miner/minerm12_converted.png\",\n    \"mca:skins/male/miner/minerm13_converted.png\",\n    \"mca:skins/male/miner/minerm14_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"female\",\n    \"profession\": \"mca:miner\",\n    \"paths\": [\n      \"mca:skins/female/miner/minerf1_converted.png\",\n      \"mca:skins/female/miner/minerf2_converted.png\",\n      \"mca:skins/female/miner/minerf3_converted.png\",\n      \"mca:skins/female/miner/minerf4_converted.png\",\n      \"mca:skins/female/miner/minerf5_converted.png\",\n      \"mca:skins/female/miner/minerf6_converted.png\",\n      \"mca:skins/female/miner/minerf7_converted.png\",\n      \"mca:skins/female/miner/minerf8_converted.png\",\n      \"mca:skins/female/miner/minerf9_converted.png\",\n      \"mca:skins/female/miner/minerf10_converted.png\",\n      \"mca:skins/female/miner/minerf11_converted.png\",\n      \"mca:skins/female/miner/minerf12_converted.png\",\n      \"mca:skins/female/miner/minerf13_converted.png\",\n      \"mca:skins/female/miner/minerf14_converted.png\",\n      \"mca:skins/female/miner/minerf15_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"male\",\n    \"profession\": \"mca:guard\",\n    \"paths\": [\n      \"mca:skins/male/warrior/warriorm1_converted.png\",\n      \"mca:skins/male/warrior/warriorm2_converted.png\",\n      \"mca:skins/male/warrior/warriorm3_converted.png\",\n      \"mca:skins/male/warrior/warriorm4_converted.png\",\n      \"mca:skins/male/warrior/warriorm5_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"female\",\n    \"profession\": \"mca:guard\",\n    \"paths\": [\n      \"mca:skins/female/warrior/warriorf1_converted.png\",\n      \"mca:skins/female/warrior/warriorf2_converted.png\",\n      \"mca:skins/female/warrior/warriorf3_converted.png\",\n      \"mca:skins/female/warrior/warriorf4_converted.png\",\n      \"mca:skins/female/warrior/warriorf5_converted.png\",\n      \"mca:skins/female/warrior/warriorf6_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"male\",\n    \"profession\": \"mca:child\",\n    \"paths\": [\n      \"mca:skins/male/child/childm1_converted.png\",\n      \"mca:skins/male/child/childm2_converted.png\",\n      \"mca:skins/male/child/childm3_converted.png\",\n      \"mca:skins/male/child/childm4_converted.png\",\n      \"mca:skins/male/child/childm5_converted.png\",\n      \"mca:skins/male/child/childm6_converted.png\",\n      \"mca:skins/male/child/childm7_converted.png\",\n      \"mca:skins/male/child/childm8_converted.png\",\n      \"mca:skins/male/child/childm9_converted.png\",\n      \"mca:skins/male/child/childm10_converted.png\",\n      \"mca:skins/male/child/childm11_converted.png\",\n      \"mca:skins/male/child/childm12_converted.png\",\n      \"mca:skins/male/child/childm13_converted.png\",\n      \"mca:skins/male/child/childm14_converted.png\",\n      \"mca:skins/male/child/childm15_converted.png\",\n      \"mca:skins/male/child/childm16_converted.png\",\n      \"mca:skins/male/child/childm17_converted.png\",\n      \"mca:skins/male/child/childm18_converted.png\",\n      \"mca:skins/male/child/childm19_converted.png\",\n      \"mca:skins/male/child/childm20_converted.png\",\n      \"mca:skins/male/child/childm21_converted.png\",\n      \"mca:skins/male/child/childm22_converted.png\",\n      \"mca:skins/male/child/childm23_converted.png\",\n      \"mca:skins/male/child/childm24_converted.png\",\n      \"mca:skins/male/child/childm25_converted.png\",\n      \"mca:skins/male/child/childm26_converted.png\",\n      \"mca:skins/male/child/childm27_converted.png\"\n    ]\n  },\n  {\n    \"gender\": \"female\",\n    \"profession\": \"mca:child\",\n    \"paths\": [\n      \"mca:skins/female/child/childf1_converted.png\",\n      \"mca:skins/female/child/childf2_converted.png\",\n      \"mca:skins/female/child/childf3_converted.png\",\n      \"mca:skins/female/child/childf4_converted.png\",\n      \"mca:skins/female/child/childf5_converted.png\",\n      \"mca:skins/female/child/childf6_converted.png\",\n      \"mca:skins/female/child/childf7_converted.png\",\n      \"mca:skins/female/child/childf8_converted.png\",\n      \"mca:skins/female/child/childf9_converted.png\",\n      \"mca:skins/female/child/childf10_converted.png\",\n      \"mca:skins/female/child/childf11_converted.png\",\n      \"mca:skins/female/child/childf12_converted.png\",\n      \"mca:skins/female/child/childf13_converted.png\",\n      \"mca:skins/female/child/childf14_converted.png\",\n      \"mca:skins/female/child/childf15_converted.png\",\n      \"mca:skins/female/child/childf16_converted.png\",\n      \"mca:skins/female/child/childf17_converted.png\",\n      \"mca:skins/female/child/childf18_converted.png\",\n      \"mca:skins/female/child/childf19_converted.png\",\n      \"mca:skins/female/child/childf20_converted.png\",\n      \"mca:skins/female/child/childf21_converted.png\"\n    ]\n  }\n]"
  },
  {
    "path": "src/main/resources/assets/mca/blockstates/rose_gold_block.json",
    "content": "{\n\t\"forge_marker\": 1,\n\t\"defaults\": {\n\t\t\"model\": \"mca:rose_gold_block\"\n\t},\n\t\"variants\": {\n\t\t\"normal\": [{}],\n\t\t\"inventory\": [{}]\n\t}\n}"
  },
  {
    "path": "src/main/resources/assets/mca/blockstates/rose_gold_ore.json",
    "content": "{\n\t\"forge_marker\": 1,\n\t\"defaults\": {\n\t\t\"model\": \"mca:rose_gold_ore\"\n\t},\n\t\"variants\": {\n\t\t\"normal\": [{}],\n\t\t\"inventory\": [{}]\n\t}\n}"
  },
  {
    "path": "src/main/resources/assets/mca/blockstates/villager_spawner.json",
    "content": "{\n\t\"forge_marker\": 1,\n\t\"defaults\": {\n\t\t\"model\": \"mca:villager_spawner\"\n\t},\n\t\"variants\": {\n\t\t\"normal\": [{}],\n\t\t\"inventory\": [{}]\n\t}\n}"
  },
  {
    "path": "src/main/resources/assets/mca/lang/en_us.lang",
    "content": "#X-Generator: crowdin.com\nitemGroup.MCA=Minecraft Comes Alive\n\nenum.agestate.baby=Baby\nenum.agestate.toddler=Toddler\nenum.agestate.child=Child\nenum.agestate.teen=Teen\nenum.agestate.adult=Adult\nentity.Villager.marauder=Marauder\nentity.Villager.outlaw=Outlaw\nentity.Villager.pillager=Pillager\nentity.Villager.miner=Miner\nentity.Villager.baker=Baker\nentity.Villager.warrior=Warrior\nentity.Villager.archer=Archer\nentity.Villager.hero=Hero\nentity.Villager.child=Child\n\n##############################\n# Items & Blocks\n##############################\nitem.wedding_ring.name=Wedding Ring\nitem.wedding_ring_rg.name=Rose Gold Wedding Ring\nitem.engagement_ring.name=Engagement Ring\nitem.engagement_ring_rg.name=Rose Gold Engagement Ring\nitem.matchmakers_ring.name=Matchmaker's Ring\nitem.baby_boy.name=Baby Boy\nitem.baby_girl.name=Baby Girl\nitem.egg_male.name=Spawn Male Villager\nitem.egg_female.name=Spawn Female Villager\nitem.divorce_papers.name=Divorce Papers\nitem.rose_gold_ingot.name=Rose Gold Ingot\nitem.new_outfit.name=New Outfit\nitem.tombstone.name=Tombstone\nitem.rose_gold_dust.name=Rose Gold Dust\nitem.gold_dust.name=Gold Dust\nitem.whistle.name=Whistle\nitem.villager_editor.name=Villager Editor\nitem.egg_grim_reaper.name=Spawn Grim Reaper\nitem.staff_of_life.name=Staff of Life\nitem.book_death.name=Death, and How to Cure It!\nitem.book_romance.name=Relationships and You\nitem.book_family.name=Managing Your Family Vol. XI\nitem.book_rose_gold.name=On Rose Gold\nitem.book_infection.name=Beware the Infection!\ntile.rose_gold_ore.name=Rose Gold Ore\ntile.rose_gold_block.name=Rose Gold Block\ntile.mca:villager_spawner.name=Villager Spawner\ntile.mca:rose_gold_block.name=Rose Gold Block\ntile.mca:rose_gold_ore.name=Rose Gold Ore\n\n################################\n# Relations\n################################\nrelation.spouse=Spouse\nrelation.daughter=Daughter\nrelation.son=Son\n\n##########################\n# Reactions\n##########################\nreaction.onhit1=Ow\\! That hurt\\!\nreaction.onhit2=I'll get you for that\\!\nreaction.onhit3=Ouch\\! Why did you hit me?\nreaction.onhit4=That hurts, stop it\\!\nreaction.onhit5=Agh\\! That really hurt\\!\nreaction.onhit6=Hey\\! What do you think you're doing?\\!\nreaction.onhit7=*Oof*\\! That better have been an accident\\!\n\nreaction.ranaway1=That's right, you'd better run\\!\nreaction.ranaway2=If you come back, I'm calling the guards\\!\nreaction.ranaway3=Come back and fight like a man\\!\nreaction.ranaway4=If I see you again, I'm going to punch you\\!\nreaction.ranaway5=I knew you were afraid of me\\!\nreaction.ranaway6=Why are you running? Get back here so I can hit you\\!\nreaction.ranaway7=I'm going to hit you if I see you again\\!\nreaction.ranaway8=I'll get my friends and beat you up\\!\n\nreaction.drawnweapon1=No\\! Please don't hurt me\\!\nreaction.drawnweapon2=Stop\\! No\\!\nreaction.drawnweapon3=Someone help me\\!\nreaction.drawnweapon4=They're going to kill me\\! Someone help\\!\nreaction.drawnweapon5=You can take whatever you want, just please don't hurt me\\!\nreaction.drawnweapon6=I don't want to die\\! Stay away\\!\nreaction.drawnweapon7=Mother Notch, please help me\\!\n\n#########################\n# Messages for chores\n#########################\nmining.search.none=There's no %v1% nearby.\nmining.search.nearby=There's some %v1% nearby...\nmining.search.value=There's some %v1% %a2% blocks away.\n\nfarming.nohoe=I'll need to have a hoe in order to farm.\n\nfishing.norod=I don't have a fishing rod!\nfishing.nowater=I don't see any water nearby...\nfishing.finished=I've finished fishing.\n\ncooking.nofood=I don't have any food to cook.\ncooking.nofuel=I don't have any fuel.\ncooking.nofurnace=There's no furnace nearby.\n\n#################\n# GUI\n################################\ngui.button.debug.startraid=Start Raid\ngui.button.debug.spawnguards=Spawn Guards\ngui.button.debug.selectnearestvillager=Get Nearest Villager\ngui.button.debug.startmining=Start Mining\ngui.button.debug.startfishing=Start Fishing\ngui.button.debug.startchopping=Start Chopping\ngui.button.debug.starthunting=Start Hunting\ngui.button.debug.startharvesting=Start Harvest\ngui.button.debug.unzombify=Unzombify\ngui.button.debug.zombify=Zombify\ngui.button.debug.marrytoplayer=Marry to Player\ngui.button.debug.rebuildvillage=Rebuild Village\ngui.button.debug.openinventory=Open Inventory\ngui.button.yes=Yes\ngui.button.no=No\ngui.button.ok=Ok\ngui.button.done=Done\ngui.button.random=Random\ngui.button.interact=Interact\ngui.button.follow=Follow Me\ngui.button.stay=Stay Here\ngui.button.move=Move Freely\ngui.button.trade=Trade\ngui.button.sethome=Home\ngui.button.gohome=Go Home\ngui.button.setworkplace=Workplace\ngui.button.sethangout=Hangout\ngui.button.location=Locations\ngui.button.ridehorse=Ride Horse\ngui.button.special=Special\ngui.button.procreate=Procreate\ngui.button.work=Work\ngui.button.inventory=Inventory\ngui.button.chat=Chat\ngui.button.joke=Joke\ngui.button.gift=Gift\ngui.button.shakehand=Shake Hand\ngui.button.tellstory=Tell Story\ngui.button.flirt=Flirt\ngui.button.hug=Hug\ngui.button.kiss=Kiss\ngui.button.prospecting=Prospecting\ngui.button.hunting=Hunting\ngui.button.cooking=Cooking\ngui.button.fishing=Fishing\ngui.button.chopping=Chopping\ngui.button.harvesting=Harvesting\ngui.button.start=Start\ngui.button.stop=Stop\ngui.button.havebaby=Have Baby\ngui.button.divorce=Divorce\ngui.button.asktomarry=Ask to Marry\ngui.button.hire=Hire\ngui.button.hired=Hired\ngui.button.accept=Accept\ngui.button.combat=Combat\ngui.button.extend=Extend\ngui.button.dismiss=Dismiss\ngui.button.divorcespouse=Divorce Spouse\ngui.button.resetbaby=Reset Baby\ngui.button.exit=Exit\ngui.button.back=Back\ngui.button.backarrow=<<\ngui.button.adoptbaby=Adopt Baby\ngui.button.revive=Revive\ngui.button.infected=Change Infection\ngui.button.gender=Change Gender\ngui.button.texture.set=Set Skin\ngui.button.texture.randomize=Randomize\ngui.button.profession.set=Set Career\ngui.button.profession.randomize=Randomize\ngui.button.stopworking=Stop Work\ngui.button.copyuuid=Copy UUID\ngui.button.call=Call\ngui.title.namebaby.male=It's a boy\\!\ngui.title.namebaby.female=It's a girl\\!\ngui.title.namebaby=Name your baby\\:\ngui.title.tombstone=Enter tombstone text\\:\ngui.title.editor=Villager Editor\ngui.title.whistle=Call Family Member\ngui.title.staffoflife=Select a Villager to Revive\n\ngui.label.you=You\ngui.label.readytogrow=Ready to grow!\ngui.label.owner=Owner\ngui.label.infected=Infected!\ngui.label.name=Name:\ngui.label.age=Age:\ngui.label.unnamed=Unnamed\ngui.label.rightclicktoname=Right-click to name\ngui.label.minute=Minute\ngui.label.minutes=Minutes\ngui.label.parent=Parent:\ngui.label.male=Male\ngui.label.female=Female\ngui.label.prospecting=Prospecting\ngui.label.harvesting=Harvesting\ngui.label.chopping=Chopping\ngui.label.hunting=Hunting\ngui.label.fishing=Fishing\ngui.label.staying=Staying\ngui.label.following=Following\n\ngui.info.gift.line1=Gift Available\ngui.info.gift.line2=(Click to take)\n\nspouse.chore.mining.orenotify=There's some %v2% nearby...\nspouse.chore.mining.nopick=I forgot my pickaxe, dear, did you bring an extra one?\nspouse.chore.chopping.noaxe=Oh, I thought we were going for a picnic. I didn't bring an axe...\nspouse.chore.fishing.norod=I'd love to! But, I can't find my fishing rod.\nspouse.chore.hunting.nosword=I broke my sword yesterday. Do you have another one?\nspouse.chore.harvesting.nohoe=Do you have an extra hoe I could use?\n\nchildp.chore.mining.orenotify=I think there's some %v2% nearby...\nchildp.chore.mining.nopick=I can't do that without a pickaxe!\nchildp.chore.chopping.noaxe=I can't chop wood without an axe...\nchildp.chore.fishing.norod=I can't fish without a fishing rod!\nchildp.chore.hunting.nosword=Can you give me a sword first?\nchildp.chore.harvesting.nohoe=I don't have a hoe to harvest with.\n\nchild.chore.mining.orenotify=I think there's some %v2% nearby...\nchild.chore.mining.nopick=I can't do that without a pickaxe!\nchild.chore.chopping.noaxe=I can't chop wood without an axe...\nchild.chore.fishing.norod=I can't fish without a fishing rod!\nchild.chore.hunting.nosword=Can you give me a sword first?\nchild.chore.harvesting.nohoe=I don't have a hoe to harvest with.\n\nadult.chore.mining.orenotify=Found something! There's some %v2% nearby.\nadult.chore.mining.nopick=I don't have a pickaxe anymore.\nadult.chore.chopping.noaxe=I don't have an axe anymore.\nadult.chore.fishing.norod=I don't have a fishing rod anymore.\nadult.chore.hunting.nosword=I lost my sword! Do you have another?\nadult.chore.harvesting.nohoe=I don't have a hoe to harvest with.\n\ngui.interact.label.married=Married to %v1%\ngui.interact.label.engaged=Engaged to %v1%\ngui.interact.label.notmarried=Not married\ngui.interact.label.parents=Parents: %v1% and %v2%\ngui.interact.label.gift=Gift available. Click to claim.\n\nspouse.interaction.marry.fail.marriedtogiver1=It's a pretty ring, but I am already married to you, silly.\nspouse.interaction.marry.fail.marriedtogiver2=We are already married. Did you forget?\n\nadult.interaction.marry.fail.marriedtoother1=I'm sorry, no...I'm already married.\nadult.interaction.marry.fail.marriedtoother2=Oh, I thought you knew...I'm already married to someone.\nadult.interaction.marry.fail.marriedtoother3=What?\\! I'm already married\\!\n\nadult.interaction.marry.fail.playermarried1=Uh...I see that ring on your finger. You're already married\\!\nadult.interaction.marry.fail.playermarried2=Just what are you trying to do? You're already married\\!\nadult.interaction.marry.fail.playermarried3=What? Really? I think you're married to someone else, aren't you?\nadult.interaction.marry.fail.playermarried4=I'm appalled\\! You already have a spouse.\n\nadult.interaction.marry.fail.lowhearts1=What? No\\! I don't like you\\!\nadult.interaction.marry.fail.lowhearts2=Oh, pretty ring\\! Oh wait...it's for me? Um...no.\nadult.interaction.marry.fail.lowhearts3=Is that for me? Sorry, I just don't know you enough.\nadult.interaction.marry.fail.lowhearts4=I'm flattered, but I don't really know you.\n\nspouse.interaction.engage.success1=Yes\\! I will marry you\\! I love you\\!\nspouse.interaction.engage.success2=Of course I'll marry you\\!\nspouse.interaction.engage.success3=About time...just kidding\\! Love you\\!\nspouse.interaction.engage.success4=Is...is this real? I mean, this moment, not the ring. But the ring is real, right?\n\nspouse.interaction.marry.success1=It's a dream come true\\! I'll love you forever\\!\nspouse.interaction.marry.success2=We're finally married\\! Now what?\nspouse.interaction.marry.success3=I'm happy to be married to you, %v1%.\nspouse.interaction.marry.success4=I can't wait to start our life together\\!\n\nadult.interaction.matchmaker.fail.married1=I am already married to someone.\nadult.interaction.matchmaker.fail.married2=I'm happily married, I do not want another spouse.\nadult.interaction.matchmaker.fail.married3=I don't want that - I'm already married.\n\nadult.interaction.matchmaker.fail.engaged1=I am engaged to someone already, I can't take that ring.\nadult.interaction.matchmaker.fail.engaged2=I've promised to marry someone else.\nadult.interaction.matchmaker.fail.engaged3=Oh, thanks but I think I'm okay. I'm already engaged to someone.\n\nadult.interaction.matchmaker.fail.needtwo1=Don't you need two rings to arrange a marriage?\nadult.interaction.matchmaker.fail.needtwo2=Oh, okay\\! But you need two rings first.\nadult.interaction.matchmaker.fail.needtwo3=My spouse and I will both need a ring, but you only have one.\n\nadult.interaction.matchmaker.fail.novillagers1=I don't see anyone close by. Who did you want me to marry?\nadult.interaction.matchmaker.fail.novillagers2=I just don't know...move me closer to the one you think is right for me.\nadult.interaction.matchmaker.fail.novillagers3=Oh, but there doesn't seem to be anyone close by. Who should I marry?\n\nadult.interaction.sethome.success1=Okay, this will be my new home point.\nadult.interaction.sethome.success2=I understand, I'll be sleeping here at night.\nadult.interaction.sethome.success3=Sure thing, %v1%.\nspouse.interaction.sethome.success1=I really like this place, good job %v1%!\nspouse.interaction.sethome.success2=This is like a dream home!\nchildp.interaction.sethome.success1=Okay fine, where's my room?\nchildp.interaction.sethome.success2=This is cool I guess. Can I go play now?\nchildp.interaction.sethome.success3=Okay, but I want the biggest room!\nchild.interaction.sethome.success2=This is cool I guess.\n\nadult.interaction.sethome.fail1=This doesn't look like a safe home point for me. There's some %v1% in the way.\nadult.interaction.sethome.fail2=Is there another place nearby? There's some %v1% in the way.\nadult.interaction.sethome.fail3=I can't have my home point here. There's some %v1% in the way.\n\nadult.interaction.setworkplace.success1=Sure thing, %v1%.\nspouse.interaction.setworkplace.success1=I really like this place.\nchild.interaction.setworkplace.success1=Okay fine!\nchildp.interaction.setworkplace.success1=Okay fine!\n\nadult.interaction.sethangout.success1=This is my favorite spot. I'm often here in the evening.\nspouse.interaction.sethangout.success1=I really like this place.\nchild.interaction.sethangout.success1=Okay fine! I will play here before bedtime.\nchildp.interaction.sethangout.success1=Okay fine! I will play here before bedtime.\n\nadult.interaction.gohome.success1=Alright, I'll go there immediately!\nadult.interaction.gohome.success2=Sure, I'll go home now.\nadult.interaction.gohome.success3=I'm going home. Goodbye!\nspouse.interaction.gohome.success1=Sure, dear, I'll head home now.\nspouse.interaction.gohome.success2=See you there, dear!\nchildp.interaction.gohome.success1=See ya!\nchildp.interaction.gohome.success2=Okay! Bye!\nchild.interaction.gohome.success1=Okay! I think I remember where I live...\n\nadult.interaction.gohome.fail.nohome=I don't have a home...\nspouse.interaction.gohome.fail.nohome=Remind me again where our house was?\nchild.interaction.gohome.fail.nohome=I don't remember where I live...\nchildp.interaction.gohome.fail.nohome=I don't remember where home is! We move too much!\n\nchild.interaction.ridehorse.fail.notnearby=Where are the horses? I want to ride!\nchildp.interaction.ridehorse.fail.notnearby=Where is my horse? I hope I didn't lose it again...\nadult.interaction.ridehorse.fail.notnearby=I don't see any rideable horses nearby.\nspouse.interaction.ridehorse.fail.notnearby=Where is my horse, dear? I can't find it.\n\nspouse.interaction.procreate.fail.hasbaby1=We already have a baby...you didn't lose it did you?!\nspouse.interaction.procreate.fail.hasbaby2=...you lost baby Joby didn't you? Wait...was his name Joby?\nspouse.interaction.procreate.fail.lowhearts1=Spend more time with me! I'm not ready for a child.\nspouse.interaction.procreate.fail.lowhearts2=Hmm...not just yet. I think we need to spend more time together first.\n\nnotify.spouseendedmarriage=%Name% has ended their marriage with you.\nnotify.spousedied=Your spouse %v1% has died by %v2%\nnotify.childdied=Your child %v1% has died by %v2%\nnotify.child.grownup=%v1% has grown into an adult!\nnotify.revival.disabled=Revivals have been disabled by the server administrator.\nnotify.trading.disabled=Trading is disabled by the server administrator.\ngift.cake.fail=I will only eat cake if my spouse is nearby...please find them!\n\n##################################\n# Responses to interactions\n##################################\nadult.gift.fail1=This isn't a good gift...\nadult.gift.fail2=What made you think that I would like this?\nadult.gift.fail3=No thanks.\nadult.gift.fail4=I don't want that, why would I?\nadult.gift.fail5=Why are you giving me that?\nadult.gift.fail6=Is this supposed to be a gift? No thanks.\nadult.gift.good1=How considerate\\! Thank you.\nadult.gift.good2=Thanks\\!\nadult.gift.good3=How thoughtful\\!\nadult.gift.good4=Oh, I love these\\!\nadult.gift.good5=A gift? For me? How nice\\!\nadult.gift.better1=Hey, this is pretty cool\\!\nadult.gift.better2=Thanks, friend\\!\nadult.gift.better3=%v1%, you're such a good friend\\!\nadult.gift.better4=Oh wow, I actually needed one of these\\!\nadult.gift.better5=This is a pretty good gift\\!\nadult.gift.best1=I...I don't know what to say. Thank you so much, %v1%\\!\nadult.gift.best2=How did you...nevermind, this is amazing\\!\nadult.gift.best3=Oh wow, I've always wanted one of these\\!\nadult.gift.best4=This is fantastic\\! I'll put it to good use.\nadult.gift.best5=Thank you so much. I will remember this forever.\nadult.chat.success1=Man, cookies and milk does sound delicious right now.\nadult.chat.success2=Yes, I suppose the weather is nice today.\nadult.chat.success3=I'm doing just fine\\! Hit my toe when I woke up, though.\nadult.chat.success4=An apple a day keeps the zombies away\\!\nadult.chat.success5=My dream is to build my own village, but I'm so lazy.\nadult.chat.success6=I think I saw %Supporter% the other day in Diamond armor.\nadult.chat.success7=My friend %Supporter% told me that they found a chest full of diamonds yesterday!\nadult.chat.fail1=Did you seriously just say that?\nadult.chat.fail2=I don't believe it exploded on its own.\nadult.chat.fail3=You know, you're not that cool.\nadult.chat.fail4=Show off.\nadult.chat.fail5=You should be thrown in a dungeon\\!\nadult.joke.success1=Haha\\! Serves that Skelly right\\!\nadult.joke.success2=*Laughs* That's hilarious\\!\nadult.joke.success3=That's funny\\! Did you hear the one about the cows?\nadult.joke.success4=Unfortunate for the sheep to lose its wool, but funny\\!\nadult.joke.success5=That's the best I have ever heard\\!\nadult.joke.success6=You might be funnier than %Supporter%\\!\nadult.joke.fail1=Don't speak about my pig like that\\!\nadult.joke.fail2=Ha. Ha. Not funny.\nadult.joke.fail3=Ah, you're not the funniest in town.\nadult.joke.fail4=That's low.\nadult.joke.fail5=You shouldn't joke about that.\nadult.shakehand.success1=You have a nice grip\\!\nadult.shakehand.success2=Your grip shows me you have great power\\!\nadult.shakehand.success3=Wow, you're so polite\\!\nadult.shakehand.success4=Good day\\!\nadult.shakehand.success5=Why, hello there\\!\nadult.shakehand.fail1=Seriously? After you slaughtered the cow?\nadult.shakehand.fail2=Um, no that's okay.\nadult.shakehand.fail3=I'm not a stranger, you don't have to be so polite.\nadult.shakehand.fail4=Wow really? This isn't like you.\nadult.shakehand.fail5=Go away.\nadult.tellstory.success1=Really? I can't believe that all happened\\!\nadult.tellstory.success2=I wish I was brave enough to take on a creeper.\nadult.tellstory.success3=That was a really good story\\! Is it original?\nadult.tellstory.success4=All of that happened yesterday? No way\\!\nadult.tellstory.success5=I was near there yesterday, I can't believe I didn't hear this already.\nadult.tellstory.success6=Haha! That definitely sounds like %Supporter%! Such an awesome person.\nadult.tellstory.success7=I've heard the Legend of %Supporter% almost a million times. Tell me again!\nadult.tellstory.fail1=*Ahem* That's my mother you're talking about.\nadult.tellstory.fail2=This is why the village talks about you.\nadult.tellstory.fail3=I don't get it...\nadult.tellstory.fail4=You're terrible\\! Creepers have feelings too\\!\nadult.tellstory.fail5=How could you kill a poor sheep?\\!\nadult.flirt.success1=You're sooo brave\\!\nadult.flirt.success2=Oh, you\\! Stop being so cute\\!\nadult.flirt.success3=*Blushes* Do you mean it?\nadult.flirt.success4=Oh, my...\nadult.flirt.success5=That was so adorable\\! You had me at \"hello\"\\!\nadult.flirt.fail1=If you mean that, then prove it.\nadult.flirt.fail2=Aw.... Wait, you told the baker the same thing\\!\nadult.flirt.fail3=Not in a million years.\nadult.flirt.fail4=Pathetic much?\nadult.flirt.fail5=A zombie has a better chance than you.\nadult.hug.success1=Long time no see\\!\nadult.hug.success2=Thank you, I needed that.\nadult.hug.success3=At least one thing made my day today.\nadult.hug.success4=You're as snuggly as a sheep\\!\nadult.hug.fail1=You're covered in soot and mud\\!\nadult.hug.fail2=No thanks.\nadult.hug.fail3=Uh, why?\nadult.hug.fail4=After you called me a dinosaur last week? No.\nadult.hug.fail5=Quite frankly, you don't deserve a hug after you did that.\nadult.kiss.success1=I wish this moment would last forever.\nadult.kiss.success2=I think I love you...\nadult.kiss.success3=Mmm, tastes like pumpkin pie\\!\nadult.kiss.fail1=Not if someone can see.\nadult.kiss.fail2=You call that a kiss?\nadult.kiss.fail3=Ash kisses better than you.\nadult.kiss.fail4=Two words... breath mints\\!\nadult.kiss.fail5=Thank you?\nadult.greeting1=Why, hello there\\!\nadult.greeting2=Hey\\! How are you today?\nadult.greeting3=Hey, good to see you\\!\nadult.greeting4=What's going on with you today?\nadult.greeting5=How are you today?\n\nchild.chat.success1=I heard stories about you\\! Are you a hero?\nchild.chat.success2=Hi. I was going to go try and climb to the roof.\nchild.chat.success3=Do you wanna go burn stuff with me?\nchild.chat.success4=I'm going to be a hunter like you and kill many things\\!\nchild.chat.success5=Hi\\! What are you doing today? I'm going swimmin'\\!\nchild.chat.fail1=If you don't give me cookies I'll hold my breath.\nchild.chat.fail2=My parents said not to talk to you, that you're bad.\nchild.chat.fail3=*Laughs* You look smelly\\!\nchild.chat.fail4=Oh yeah? Well I'm gonna egg your house\\!\nchild.chat.fail5=Lalala, I'm not listening\\! Lalala.\nchild.joke.success1=You're funnier than daddy\\!\nchild.joke.success2=Tell me another one\\!\nchild.joke.success3=You're the funniest person alive\\!\nchild.joke.success4=I'm tellin' my momma that one\\! *Laughs*\nchild.joke.success5=It should eat a leaf\\!\nchild.joke.fail1=I don't get it.\nchild.joke.fail2=You're not funny. Really.\nchild.joke.fail3=You need to stop...\nchild.joke.fail4=But, who's apple?\nchild.joke.fail5=Don't be mean\\!\nchild.shakehand.success1=Hiya\\! Someone I know likes you...\nchild.shakehand.success2=Dad said this is a very nice thing to do.\nchild.shakehand.success3=Now high five\\! Down low... too slow\\!\nchild.shakehand.success4=Hi stranger\\!\nchild.shakehand.success5=*Giggles* I just cleaned a cow with this hand.\nchild.shakehand.fail1=Stranger danger...\nchild.shakehand.fail2=Mom, dad\\! This person is trying to kidnap me\\!\nchild.shakehand.fail3=Don't touch me I'm famous\\!\nchild.shakehand.fail4=Ew, your hand has black stuff on it.\nchild.shakehand.fail5=I'll only shake your hand if you give me a diamond.\nchild.tellstory.success1=Wow\\! You're a beast\\!\nchild.tellstory.success2=I want to be just like you when I grow up. Shh, don't tell dad.\nchild.tellstory.success3=Can you adopt me?\\! You're awesome\\!\nchild.tellstory.success4=I went fishing and almost drowned.\nchild.tellstory.success5=Does this mean I can take whatever I want? I mean, \"borrow?\"\nchild.tellstory.success6=Tell me again about %Supporter%!!\nchild.tellstory.fail1=You're a meanie\\!\nchild.tellstory.fail2=I'm telling my mom what you said about her...\nchild.tellstory.fail3=I believe you're speaking about my grandpa...\nchild.tellstory.fail4=You're nothing but a scaredycat like dad said\\!\nchild.tellstory.fail5=How could you kill a poor chicken?\nchild.greeting1=Hi, who are you?\nchild.greeting2=Hi, what's your name?\nchild.greeting3=Eek\\! You look scary\\!\nchild.gift.fail1=Ew, I don't like this\\!\nchild.gift.fail2=Yuck\\! I don't want this.\nchild.gift.fail3=Why did you bring me this? It's dumb\\!\nchild.gift.fail4=I don't even know what this is\\!\nchild.gift.good1=Is it...is it all mine?\nchild.gift.good2=Is this really for me?\nchild.gift.good3=This is cool\\!\nchild.gift.better1=Awesome\\! I'm going to show this to all my friends.\nchild.gift.better2=You found it\\! I lost this a few minutes ago.\nchild.gift.better3=My friend stole one of these from me. Did you beat him up for me?\nchild.gift.best1=%v1%, you give the best presents\\!\nchild.gift.best2=Finally\\! My friend will stop bragging now.\nchild.gift.best3=Wow\\! Where did you get this thing?\nchild.gift.best4=My Dad has one of these. Now I have one too\\!\n\nchildp.chat.success1=Oh, I was just going to go explorin' later.\nchildp.chat.success2=Can we go camping? Please?\\!\nchildp.chat.success3=Hi, can you make me a cake?\nchildp.chat.success4=Can I have my own room away from our house? That would be cool\\!\nchildp.chat.success5=Let's move into a cave\\! That sounds so fun\\!\nchildp.chat.fail2=I don't think I'd like that very much.\nchildp.chat.fail3=Is that why I've heard so much about \"divorce\"? What does that mean?\nchildp.chat.fail4=I want a new daddy.\nchildp.chat.fail5=I don't want a baby sister.\nchildp.joke.success1=*Laughs* Tell that one again\\!\nchildp.joke.success2=I've got to tell my friend that one\\!\nchildp.joke.success3=How did the creeper explode?\\!\nchildp.joke.success4=*Laughs*Why is there no longer 3 of them?\nchildp.joke.success5=*Laughs* ... *Laughs*... *Laughs*\nchildp.joke.fail1=I thought you were funny, though...\nchildp.joke.fail2=I like knock knock jokes better.\nchildp.joke.fail3=I don't get it, that was dumb.\nchildp.joke.fail4=*Yawn* My friend's dad is cooler and funnier than you.\nchildp.joke.fail5=I'd rather have cake.\nchildp.shakehand.success1=Why do I need to learn this stuff?\nchildp.shakehand.success2=I heard that this is a polite thing to do.\nchildp.shakehand.success3=I'm gonna be just like you when I grow up\\!\nchildp.shakehand.success4=Can I have cake now?\nchildp.shakehand.success5=I don't get it, but okay\\!\nchildp.shakehand.fail1=I spit on my hand.\nchildp.shakehand.fail2=You're such an old person.\nchildp.shakehand.fail3=Only losers shake hands.\nchildp.shakehand.fail4=I'll shake your hand if you give me cake.\nchildp.shakehand.fail5=No, you'll slip and hit me.\nchildp.tellstory.success1=What!? You really did that?\\! But...what happened to your friend?\nchildp.tellstory.success2=I want to explore a cave, too\\! Let's go\\!\nchildp.tellstory.success3=One day I'll kill more creepers than you\\!\nchildp.tellstory.success4=Oh, oh, oh\\! Can we climb a tree, too?\\!\nchildp.tellstory.success5=Did the lava hurt?\nchildp.tellstory.fail1=I don't want to hear about grandma.\nchildp.tellstory.fail2=You always say that. I just want a pet.\nchildp.tellstory.fail3=You're just fibbing. I don't belive that.\nchildp.tellstory.fail4=You said you didn't eat the cake and cookies...\nchildp.tellstory.fail5=Someone said you were a bad person, and I believe them\\!\nchildp.hug.success1=*Kisses* You're the best ever\\!\nchildp.hug.success2=I'm going to be as strong as you are one day\\!\nchildp.hug.success3=hug anymore?\nchildp.hug.success4=I love hugs\\! You're soft and warm\\!\nchildp.hug.fail1=I'm too old for hugs\\!\nchildp.hug.fail2=Stop it\\! I don't want people to see\\!\nchildp.hug.fail3=Go away, you're so annoying\\!\nchildp.hug.fail4=Just leave me alone or give me some cookies\\!\nchildp.hug.fail5=I'd rather hug a skeleton.\nchildp.greeting1=Hey there\\!\nchildp.greeting2=Hey, what's going on?\nchildp.greeting3=What are you doing?\nchildp.greeting4=Where are you going?\nchildp.gift.fail1=This...is a really bad gift.\nchildp.gift.fail2=Ew, I've gotten so much better before!\nchildp.gift.fail3=Didn't you give me this like, last year?\nchildp.gift.fail4=I could get this easily, no thanks.\nchildp.gift.good1=Oh, cool\\! Thank you!\nchildp.gift.good2=Is it my birthday? This is awesome!\nchildp.gift.good3=This is much better than the last gift I got\\!\nchildp.gift.good4=Woo hoo\\! It's mine, all mine\\!\nchildp.gift.good5=Can I...can I eat it?\nchildp.gift.better1=For me? For free?\\!\nchildp.gift.better2=Ooh\\! Shiny\\!\nchildp.gift.better3=I really like this one, can I have another?\nchildp.gift.better4=All of my friends will be jealous now\\!\nchildp.gift.better5=This is so cool! I've wanted one of these forever!\nchildp.gift.best1=This must have cost a fortune\\!\nchildp.gift.best2=I knew you would get me one of these. I just knew it\\!\nchildp.gift.best3=Yay\\! I have the best parents in the world\\!\nchildp.gift.best4=This is so amazing\\! I can't believe this is all mine\\!\nchildp.gift.best5=Thank you so much\\! You're the best ever\\!\n\nspouse.chat.success1=I cleaned the entire house. How was your day?\nspouse.chat.success2=Honey, let's go camping sometime. Doesn't that sound like fun?\nspouse.chat.success3=So today I saw a spider. It was huge so I ran away.\nspouse.chat.success4=We should build a new house together\\!\nspouse.chat.success5=I almost walked into a lava pit the other day. That wouldn't have been good\\!\nspouse.chat.fail1=I know we're not the poorest family, but...\nspouse.chat.fail2=I love being around you but I need some space.\nspouse.chat.fail3=Sometimes I wish I had my own \"cave\" to escape from you and everyone.\nspouse.chat.fail4=Go away, I'm not in the mood.\nspouse.chat.fail5=Where have you been? Are you seeing someone behind my back?\nspouse.joke.success1=*Laughs* I married you for your humor\\!\nspouse.joke.success2=You should throw an egg at him next time\\!\nspouse.joke.success3=Then the wolf fell in love with the sheep.\nspouse.joke.success4=That never gets old\\!\nspouse.joke.success5=Here's one for you... How many chickens does a creeper blow up?\nspouse.joke.fail1=Lame...\nspouse.joke.fail2=Sweetheart, you're not funny.\nspouse.joke.fail3=Ha...Ha...Ha...Not funny.\nspouse.joke.fail4=You need to erase that from your mind.\nspouse.joke.fail5=Okay...\nspouse.shakehand.success1=Your hand is so soft\\!\nspouse.shakehand.success2=Our hands fit perfectly together.\nspouse.shakehand.success3=One day people will forget to shake hands.\nspouse.shakehand.success4=Our children will need to be this polite.\nspouse.shakehand.success5=*Continues to shake hand* Tell me when to stop\\!\nspouse.shakehand.fail1=shakehand? How about a kiss, instead?\nspouse.shakehand.fail2=*Squeezes hand hard*\nspouse.shakehand.fail3=Your hand is nasty, no way.\nspouse.shakehand.fail4=They have germs on them.\nspouse.shakehand.fail5=Why don't you get a decent job instead of shaking my hand?\nspouse.tellstory.success1=Let's not tell our children that one...\nspouse.tellstory.success2=You were so rebellious\\! I love it\\!\nspouse.tellstory.success3=Did you ever tell your parents about losing their rings?\nspouse.tellstory.success4=It was that moment when I fell in love with you\\!\nspouse.tellstory.success5=Wow, you're the best hunter ever\\!\nspouse.tellstory.fail1=Talk to me when you kill something other than a harmless cow.\nspouse.tellstory.fail2=Don't do something that reckless\\!\nspouse.tellstory.fail3=You have a family to think about\\!\nspouse.tellstory.fail4=...If you liked them why didn't you marry them, instead?\nspouse.tellstory.fail5=Why did you wear the pink fluffy underwear? Whose were they?\nspouse.flirt.success1=*Blushes* Well, how about we do something like that, then\\!\nspouse.flirt.success2=Aw, you said that when we first met.\nspouse.flirt.success3=Baby, you're so cute\\!\nspouse.flirt.success4=You bet I am\\!\nspouse.flirt.success5=*Winks* You still got it\\!\nspouse.flirt.fail1=*Sighs*\nspouse.flirt.fail2=This one is getting old... like you.\nspouse.flirt.fail3=We're married, we don't have to do this anymore.\nspouse.flirt.fail4=Talk to the tree, it cares more.\nspouse.flirt.fail5=Yeah, yeah... What was it you were saying?\nspouse.hug.success1=I love being entangled in your arms\\!\nspouse.hug.success2=Wait, don't leave... you're warm.\nspouse.hug.success3=Would you rather only being able to hug or kiss?\nspouse.hug.success4=*Kisses*\nspouse.hug.success5=Let's stay like this forever\\!\nspouse.hug.fail1=Why don't you go hug your ex?\nspouse.hug.fail2=No thanks.\nspouse.hug.fail3=Man, you stink.\nspouse.hug.fail4=What do you want?\nspouse.hug.fail5=Huge someone else.\nspouse.kiss.success1=I fall in love all over again when our lips meet\\!\nspouse.kiss.success2=Time stops ticking when I'm with you.\nspouse.kiss.success3=Sweet as cake\\!\nspouse.kiss.success4=I love you, baby\\!\nspouse.kiss.success5=I wouldn't trade you for anyone in the world\\!\nspouse.kiss.fail1=Not where someone can see us...\nspouse.kiss.fail2=We don't have to if you don't want to.\nspouse.kiss.fail3=Your breath smells like wolf kibble.\nspouse.kiss.fail4=Go take a drink from the lake.\nspouse.kiss.fail5=Now that we're married I can tell you how lousy you are at kissing.\nspouse.greeting1=Hi honey, where have you been?\nspouse.greeting2=Hello dear, how is your day going?\nspouse.greeting3=Oh, %v1%\\! You look tired.\nspouse.greeting4=Hey %v1%\\! You look hungry. Would you like me to cook something?\nspouse.greeting5=%v1%, you're back\\! I missed you.\nspouse.lowhearts.greeting1=There you are. Where did you go? You never tell me anything anymore.\nspouse.lowhearts.greeting2=Are you going to say hi to me this time?\nspouse.lowhearts.greeting3=Um, hi! I still exist, you know!\nspouse.lowhearts.greeting4=%v1%, are you ignoring me on purpose?\nspouse.lowhearts.greeting5=I'm starting to feel like you don't pay attention to me.\nspouse.endmarriage1=I've had it. You don't treat me well enough. I'm leaving you!\nspouse.endmarriage2=I'm leaving. Forever! Don't look for me.\nspouse.endmarriage3=I'm sorry - I thought we could work things out, but it's not working for me. Goodbye.\nspouse.endmarriage4=%v1%, this is goodbye. Don't try to follow me.\nspouse.gift.fail1=Oh honey...this is just terrible.\nspouse.gift.fail2=Um, is this supposed to be a gift for me?\nspouse.gift.fail3=Throw away your own junk\\! Oh, this was a gift?...sorry.\nspouse.gift.fail4=I thought you knew me better than that. I hate these.\nspouse.gift.good1=%v1%, you're so sweet.\nspouse.gift.good2=Ah\\! You're too good to me.\nspouse.gift.good3=This is unexpected, thank you, dear\\!\nspouse.gift.good4=Aw, how sweet of you.\nspouse.gift.good5=Thanks, hun\\!\nspouse.gift.better1=Oh wow, this is actually really nice\\!\nspouse.gift.better2=I love it\\! Thank you\\!\nspouse.gift.better3=This is amazing, dear\\!\nspouse.gift.better4=You got this for me? How sweet\\!\nspouse.gift.better5=Oh, thank you %v1%\\!\nspouse.gift.best1=Oh %v1%, I love you\\!\nspouse.gift.best2=You are *way* too good to me\\!\nspouse.gift.best3=This must have been extremely expensive\\! Thank you\\!\nspouse.gift.best4=I...can't believe you'd get me something so thoughtful\\!"
  },
  {
    "path": "src/main/resources/assets/mca/lang/names.lang",
    "content": "name.male1=Aaron\nname.male2=Abdul\nname.male3=Abe\nname.male4=Abel\nname.male5=Abraham\nname.male6=Abram\nname.male7=Adalberto\nname.male8=Adam\nname.male9=Adan\nname.male10=Adolfo\nname.male11=Adolph\nname.male12=Adrian\nname.male13=Agustin\nname.male14=Ahmad\nname.male15=Ahmed\nname.male16=Alan\nname.male17=Alaric\nname.male18=Albert\nname.male19=Alberto\nname.male20=Alden\nname.male21=Aldo\nname.male22=Alec\nname.male23=Alejandro\nname.male24=Alex\nname.male25=Alexander\nname.male26=Alexis\nname.male27=Alfonso\nname.male28=Alfonzo\nname.male29=Alfred\nname.male30=Alfredo\nname.male31=Ali\nname.male32=Allan\nname.male33=Allen\nname.male34=Alonso\nname.male35=Alonzo\nname.male36=Alphonse\nname.male37=Alphonso\nname.male38=Alton\nname.male39=Alva\nname.male40=Alvaro\nname.male41=Alvin\nname.male42=Amado\nname.male43=Ambrose\nname.male44=Amos\nname.male45=Anderson\nname.male46=Andre\nname.male47=Andrea\nname.male48=Andreas\nname.male49=Andres\nname.male50=Andrew\nname.male51=Andy\nname.male52=Angel\nname.male53=Angelo\nname.male54=Anibal\nname.male55=Anthony\nname.male56=Antoine\nname.male57=Anton\nname.male58=Antone\nname.male59=Antonia\nname.male60=Antonio\nname.male61=Antony\nname.male62=Antwan\nname.male63=Archie\nname.male64=Arden\nname.male65=Ariel\nname.male66=Arlen\nname.male67=Arlie\nname.male68=Armand\nname.male69=Armando\nname.male70=Armon\nname.male71=Arnold\nname.male72=Arnoldo\nname.male73=Arnulfo\nname.male74=Aron\nname.male75=Arron\nname.male76=Art\nname.male77=Arthur\nname.male78=Arturo\nname.male79=Asa\nname.male80=Ashley\nname.male81=Aubrey\nname.male82=August\nname.male83=Augustine\nname.male84=Augustus\nname.male85=Aurelio\nname.male86=Austin\nname.male87=Avery\nname.male88=Ayden\nname.male89=Bailey\nname.male90=Barney\nname.male91=Barrett\nname.male92=Barry\nname.male93=Bart\nname.male94=Barton\nname.male95=Basil\nname.male96=Beau\nname.male97=Ben\nname.male98=Benedict\nname.male99=Benito\nname.male100=Benjamin\nname.male101=Bennett\nname.male102=Bennie\nname.male103=Benny\nname.male104=Benton\nname.male105=Bernard\nname.male106=Bernardo\nname.male107=Bernie\nname.male108=Berry\nname.male109=Bert\nname.male110=Bertram\nname.male111=Bill\nname.male112=Billie\nname.male113=Billy\nname.male114=Blaine\nname.male115=Blair\nname.male116=Blake\nname.male117=Bob\nname.male118=Bobbie\nname.male119=Bobby\nname.male120=Booker\nname.male121=Boris\nname.male122=Boyce\nname.male123=Boyd\nname.male124=Bracken\nname.male125=Brad\nname.male126=Bradford\nname.male127=Bradley\nname.male128=Bradly\nname.male129=Brady\nname.male130=Brain\nname.male131=Branden\nname.male132=Brandon\nname.male133=Brant\nname.male134=Brayden\nname.male135=Brendan\nname.male136=Brendon\nname.male137=Brent\nname.male138=Brenton\nname.male139=Bret\nname.male140=Brett\nname.male141=Brian\nname.male142=Brice\nname.male143=Britt\nname.male144=Brock\nname.male145=Broderick\nname.male146=Brooks\nname.male147=Bruce\nname.male148=Bruno\nname.male149=Bryan\nname.male150=Bryant\nname.male151=Bryce\nname.male152=Bryon\nname.male153=Bryson\nname.male154=Buck\nname.male155=Bud\nname.male156=Buddy\nname.male157=Buford\nname.male158=Burl\nname.male159=Burt\nname.male160=Burton\nname.male161=Buster\nname.male162=Byron\nname.male163=Caleb\nname.male164=Calvin\nname.male165=Cameron\nname.male166=Carey\nname.male167=Carl\nname.male168=Carlo\nname.male169=Carlos\nname.male170=Carlton\nname.male171=Carmelo\nname.male172=Carmen\nname.male173=Carmine\nname.male174=Carol\nname.male175=Carrol\nname.male176=Carroll\nname.male177=Carson\nname.male178=Carter\nname.male179=Cary\nname.male180=Casey\nname.male181=Cason\nname.male182=Cecil\nname.male183=Cedric\nname.male184=Cedrick\nname.male185=Cesar\nname.male186=Chad\nname.male187=Chadwick\nname.male188=Chance\nname.male189=Chancey\nname.male190=Chang\nname.male191=Charles\nname.male192=Charley\nname.male193=Charlie\nname.male194=Chas\nname.male195=Chase\nname.male196=Chauncey\nname.male197=Chester\nname.male198=Chet\nname.male199=Chi\nname.male200=Chong\nname.male201=Chris\nname.male202=Christian\nname.male203=Christop\nname.male204=Christoper\nname.male205=Christopher\nname.male206=Chuck\nname.male207=Chung\nname.male208=Clair\nname.male209=Clarence\nname.male210=Clark\nname.male211=Claud\nname.male212=Claude\nname.male213=Claudio\nname.male214=Clay\nname.male215=Clayton\nname.male216=Clement\nname.male217=Clemente\nname.male218=Cleo\nname.male219=Cletus\nname.male220=Cleveland\nname.male221=Cliff\nname.male222=Clifford\nname.male223=Clifton\nname.male224=Clint\nname.male225=Clinton\nname.male226=Clyde\nname.male227=Cody\nname.male228=Colby\nname.male229=Cole\nname.male230=Coleman\nname.male231=Colin\nname.male232=Collin\nname.male233=Colton\nname.male234=Columbus\nname.male235=Connie\nname.male236=Connor\nname.male237=Conrad\nname.male238=Cordell\nname.male239=Corey\nname.male240=Coriander\nname.male241=Cornelius\nname.male242=Cornell\nname.male243=Cortez\nname.male244=Cory\nname.male245=Courtney\nname.male246=Coy\nname.male247=Craig\nname.male248=Cristobal\nname.male249=Cristopher\nname.male250=Cruz\nname.male251=Curt\nname.male252=Curtis\nname.male253=Cyril\nname.male254=Cyrus\nname.male255=Dale\nname.male256=Dallas\nname.male257=Dallis\nname.male258=Dalton\nname.male259=Damian\nname.male260=Damien\nname.male261=Damion\nname.male262=Damon\nname.male263=Dan\nname.male264=Dana\nname.male265=Dane\nname.male266=Danial\nname.male267=Daniel\nname.male268=Danilo\nname.male269=Dannie\nname.male270=Danny\nname.male271=Dante\nname.male272=Darell\nname.male273=Daren\nname.male274=Darin\nname.male275=Dario\nname.male276=Darius\nname.male277=Darnell\nname.male278=Daron\nname.male279=Darrel\nname.male280=Darrell\nname.male281=Darren\nname.male282=Darrick\nname.male283=Darrin\nname.male284=Darron\nname.male285=Darryl\nname.male286=Darwin\nname.male287=Daryl\nname.male288=Dave\nname.male289=David\nname.male290=Davis\nname.male291=Dean\nname.male292=Deandre\nname.male293=Deangelo\nname.male294=Dee\nname.male295=Del\nname.male296=Delbert\nname.male297=Delmar\nname.male298=Delmer\nname.male299=Demarcus\nname.male300=Demetrius\nname.male301=Denis\nname.male302=Dennis\nname.male303=Denny\nname.male304=Denver\nname.male305=Deon\nname.male306=Derek\nname.male307=Derick\nname.male308=Derrick\nname.male309=Deshawn\nname.male310=Desmond\nname.male311=Devin\nname.male312=Devon\nname.male313=Dewayne\nname.male314=Dewey\nname.male315=Dewitt\nname.male316=Dexter\nname.male317=Dick\nname.male318=Diego\nname.male319=Dillon\nname.male320=Dino\nname.male321=Dion\nname.male322=Dirk\nname.male323=Domenic\nname.male324=Domingo\nname.male325=Dominic\nname.male326=Dominick\nname.male327=Dominique\nname.male328=Don\nname.male329=Donald\nname.male330=Dong\nname.male331=Donn\nname.male332=Donnell\nname.male333=Donnie\nname.male334=Donny\nname.male335=Donovan\nname.male336=Donte\nname.male337=Dorian\nname.male338=Dorsey\nname.male339=Doug\nname.male340=Douglas\nname.male341=Douglass\nname.male342=Doyle\nname.male343=Draven\nname.male344=Drew\nname.male345=Duane\nname.male346=Dudley\nname.male347=Duncan\nname.male348=Dustin\nname.male349=Dusty\nname.male350=Dwain\nname.male351=Dwayne\nname.male352=Dwight\nname.male353=Dylan\nname.male354=Earl\nname.male355=Earle\nname.male356=Earnest\nname.male357=Eddie\nname.male358=Eddy\nname.male359=Edgar\nname.male360=Edgardo\nname.male361=Edison\nname.male362=Edmond\nname.male363=Edmund\nname.male364=Edmundo\nname.male365=Eduardo\nname.male366=Edward\nname.male367=Edwardo\nname.male368=Edwin\nname.male369=Efrain\nname.male370=Efren\nname.male371=Elbert\nname.male372=Elden\nname.male373=Eldon\nname.male374=Eldridge\nname.male375=Eli\nname.male376=Elias\nname.male377=Elijah\nname.male378=Eliseo\nname.male379=Elisha\nname.male380=Elliot\nname.male381=Elliott\nname.male382=Ellis\nname.male383=Ellsworth\nname.male384=Elmer\nname.male385=Elmo\nname.male386=Eloy\nname.male387=Elroy\nname.male388=Elton\nname.male389=Elvin\nname.male390=Elvis\nname.male391=Elwood\nname.male392=Emanuel\nname.male393=Emerson\nname.male394=Emery\nname.male395=Emil\nname.male396=Emile\nname.male397=Emilio\nname.male398=Emit\nname.male399=Emmanuel\nname.male400=Emmett\nname.male401=Emmitt\nname.male402=Emory\nname.male403=Enoch\nname.male404=Enrique\nname.male405=Erasmo\nname.male406=Eric\nname.male407=Erich\nname.male408=Erick\nname.male409=Erik\nname.male410=Erin\nname.male411=Ernest\nname.male412=Ernesto\nname.male413=Ernie\nname.male414=Errol\nname.male415=Ervin\nname.male416=Erwin\nname.male417=Esteban\nname.male418=Ethan\nname.male419=Eugene\nname.male420=Eugenio\nname.male421=Eusebio\nname.male422=Evan\nname.male423=Everett\nname.male424=Everette\nname.male425=Ezekiel\nname.male426=Ezequiel\nname.male427=Ezra\nname.male428=Fabian\nname.male429=Faustino\nname.male430=Fausto\nname.male431=Federico\nname.male432=Felipe\nname.male433=Felix\nname.male434=Felton\nname.male435=Ferdinand\nname.male436=Fermin\nname.male437=Fernando\nname.male438=Fidel\nname.male439=Filiberto\nname.male440=Fletcher\nname.male441=Florencio\nname.male442=Florentino\nname.male443=Floyd\nname.male444=Ford\nname.male445=Forest\nname.male446=Forrest\nname.male447=Foster\nname.male448=Frances\nname.male449=Francesco\nname.male450=Francis\nname.male451=Francisco\nname.male452=Frank\nname.male453=Frankie\nname.male454=Franklin\nname.male455=Franklyn\nname.male456=Fred\nname.male457=Freddie\nname.male458=Freddy\nname.male459=Frederic\nname.male460=Frederick\nname.male461=Fredric\nname.male462=Fredrick\nname.male463=Freeman\nname.male464=Fritz\nname.male465=Gabriel\nname.male466=Gage\nname.male467=Gail\nname.male468=Gale\nname.male469=Galen\nname.male470=Garfield\nname.male471=Garland\nname.male472=Garret\nname.male473=Garrett\nname.male474=Garry\nname.male475=Garth\nname.male476=Gary\nname.male477=Gaston\nname.male478=Gavin\nname.male479=Gayle\nname.male480=Gaylord\nname.male481=Genaro\nname.male482=Gene\nname.male483=Geoffrey\nname.male484=George\nname.male485=Gerald\nname.male486=Geraldo\nname.male487=Gerard\nname.male488=Gerardo\nname.male489=German\nname.male490=Gerry\nname.male491=Gil\nname.male492=Gilbert\nname.male493=Gilberto\nname.male494=Gino\nname.male495=Giovanni\nname.male496=Giuseppe\nname.male497=Glen\nname.male498=Glenn\nname.male499=Gonzalo\nname.male500=Gordon\nname.male501=Grady\nname.male502=Graham\nname.male503=Graig\nname.male504=Grant\nname.male505=Granville\nname.male506=Grayson\nname.male507=Greg\nname.male508=Gregg\nname.male509=Gregorio\nname.male510=Gregory\nname.male511=Grover\nname.male512=Guadalupe\nname.male513=Guillermo\nname.male514=Gus\nname.male515=Gustavo\nname.male516=Guy\nname.male517=Hai\nname.male518=Hal\nname.male519=Hank\nname.male520=Hans\nname.male521=Harlan\nname.male522=Harland\nname.male523=Harley\nname.male524=Harold\nname.male525=Harris\nname.male526=Harrison\nname.male527=Harry\nname.male528=Harvey\nname.male529=Hassan\nname.male530=Hayden\nname.male531=Haywood\nname.male532=Heath\nname.male533=Hector\nname.male534=Henry\nname.male535=Herb\nname.male536=Herbert\nname.male537=Heriberto\nname.male538=Herman\nname.male539=Herschel\nname.male540=Hershel\nname.male541=Hilario\nname.male542=Hilton\nname.male543=Hipolito\nname.male544=Hiram\nname.male545=Hobert\nname.male546=Hollis\nname.male547=Homer\nname.male548=Hong\nname.male549=Horace\nname.male550=Horacio\nname.male551=Hosea\nname.male552=Houston\nname.male553=Howard\nname.male554=Hoyt\nname.male555=Hubert\nname.male556=Huey\nname.male557=Hugh\nname.male558=Hugo\nname.male559=Humberto\nname.male560=Hung\nname.male561=Hunter\nname.male562=Hyman\nname.male563=Ian\nname.male564=Ignacio\nname.male565=Ike\nname.male566=Ira\nname.male567=Irvin\nname.male568=Irving\nname.male569=Irwin\nname.male570=Isaac\nname.male571=Isaiah\nname.male572=Isaias\nname.male573=Isiah\nname.male574=Isidro\nname.male575=Ismael\nname.male576=Israel\nname.male577=Isreal\nname.male578=Issac\nname.male579=Ivan\nname.male580=Ivory\nname.male581=Jacinto\nname.male582=Jack\nname.male583=Jackie\nname.male584=Jackson\nname.male585=Jacob\nname.male586=Jacques\nname.male587=Jae\nname.male588=Jaime\nname.male589=Jake\nname.male590=Jamaal\nname.male591=Jamal\nname.male592=Jamar\nname.male593=Jame\nname.male594=Jamel\nname.male595=James\nname.male596=Jamey\nname.male597=Jamie\nname.male598=Jamison\nname.male599=Jan\nname.male600=Jared\nname.male601=Jarod\nname.male602=Jarred\nname.male603=Jarrett\nname.male604=Jarrod\nname.male605=Jarvis\nname.male606=Jason\nname.male607=Jasper\nname.male608=Javier\nname.male609=Jaxon\nname.male610=Jay\nname.male611=Jaylen\nname.male612=Jaylon\nname.male613=Jayson\nname.male614=Jean\nname.male615=Jed\nname.male616=Jeferson\nname.male617=Jeff\nname.male618=Jefferey\nname.male619=Jefferson\nname.male620=Jeffery\nname.male621=Jeffrey\nname.male622=Jeffry\nname.male623=Jerald\nname.male624=Jeramy\nname.male625=Jere\nname.male626=Jeremiah\nname.male627=Jeremy\nname.male628=Jerimiah\nname.male629=Jermaine\nname.male630=Jerold\nname.male631=Jerome\nname.male632=Jeromy\nname.male633=Jerrell\nname.male634=Jerrod\nname.male635=Jerrold\nname.male636=Jerry\nname.male637=Jess\nname.male638=Jesse\nname.male639=Jessie\nname.male640=Jesus\nname.male641=Jewel\nname.male642=Jewell\nname.male643=Jim\nname.male644=Jimmie\nname.male645=Jimmy\nname.male646=Joan\nname.male647=Joaquin\nname.male648=Jody\nname.male649=Joe\nname.male650=Joel\nname.male651=Joesph\nname.male652=Joey\nname.male653=John\nname.male654=Johnathan\nname.male655=Johnathon\nname.male656=Johnie\nname.male657=Johnnie\nname.male658=Johnny\nname.male659=Johnson\nname.male660=Jon\nname.male661=Jonah\nname.male662=Jonas\nname.male663=Jonathan\nname.male664=Jonathon\nname.male665=Jordan\nname.male666=Jordon\nname.male667=Jorge\nname.male668=Jose\nname.male669=Josef\nname.male670=Joseph\nname.male671=Josh\nname.male672=Joshua\nname.male673=Josiah\nname.male674=Jospeh\nname.male675=Josue\nname.male676=Juan\nname.male677=Jude\nname.male678=Judson\nname.male679=Jules\nname.male680=Julian\nname.male681=Julio\nname.male682=Julius\nname.male683=Junior\nname.male684=Justin\nname.male685=Kareem\nname.male686=Karl\nname.male687=Kasey\nname.male688=Keenan\nname.male689=Keith\nname.male690=Kelley\nname.male691=Kelly\nname.male692=Kelvin\nname.male693=Ken\nname.male694=Kendall\nname.male695=Kendrick\nname.male696=Keneth\nname.male697=Kenneth\nname.male698=Kennith\nname.male699=Kenny\nname.male700=Kent\nname.male701=Kenton\nname.male702=Kermit\nname.male703=Kerry\nname.male704=Keven\nname.male705=Kevin\nname.male706=Kieth\nname.male707=Kim\nname.male708=King\nname.male709=Kip\nname.male710=Kirby\nname.male711=Kirk\nname.male712=Korey\nname.male713=Kory\nname.male714=Kraig\nname.male715=Kris\nname.male716=Kristofer\nname.male717=Kristopher\nname.male718=Kurt\nname.male719=Kurtis\nname.male720=Kyle\nname.male721=Lacy\nname.male722=Lamar\nname.male723=Lamont\nname.male724=Lance\nname.male725=Landon\nname.male726=Lane\nname.male727=Lanny\nname.male728=Larry\nname.male729=Latyn\nname.male730=Lauren\nname.male731=Laurence\nname.male732=Lavern\nname.male733=Laverne\nname.male734=Lawerence\nname.male735=Lawrence\nname.male736=Lazaro\nname.male737=Leandro\nname.male738=Lee\nname.male739=Leif\nname.male740=Leigh\nname.male741=Leland\nname.male742=Lemuel\nname.male743=Len\nname.male744=Lenard\nname.male745=Lenny\nname.male746=Leo\nname.male747=Leon\nname.male748=Leonard\nname.male749=Leonardo\nname.male750=Leonel\nname.male751=Leopoldo\nname.male752=Leroy\nname.male753=Les\nname.male754=Lesley\nname.male755=Leslie\nname.male756=Lester\nname.male757=Levi\nname.male758=Lewis\nname.male759=Liam\nname.male760=Lincoln\nname.male761=Linden\nname.male762=Lindsay\nname.male763=Lindsey\nname.male764=Linel\nname.male765=Lino\nname.male766=Linwood\nname.male767=Lionel\nname.male768=Lloyd\nname.male769=Logan\nname.male770=Lon\nname.male771=Long\nname.male772=Lonnie\nname.male773=Lonny\nname.male774=Loren\nname.male775=Lorenzo\nname.male776=Lou\nname.male777=Louie\nname.male778=Louis\nname.male779=Lowell\nname.male780=Loyd\nname.male781=Lucas\nname.male782=Luciano\nname.male783=Lucien\nname.male784=Lucio\nname.male785=Lucius\nname.male786=Luigi\nname.male787=Luis\nname.male788=Luke\nname.male789=Lupe\nname.male790=Luther\nname.male791=Lyle\nname.male792=Lyman\nname.male793=Lyndon\nname.male794=Lynn\nname.male795=Lynwood\nname.male796=Mac\nname.male797=Mack\nname.male798=Major\nname.male799=Malcolm\nname.male800=Malcom\nname.male801=Malik\nname.male802=Man\nname.male803=Manual\nname.male804=Manuel\nname.male805=Marc\nname.male806=Marcel\nname.male807=Marcelino\nname.male808=Marcellus\nname.male809=Marcelo\nname.male810=March\nname.male811=Marco\nname.male812=Marcos\nname.male813=Marcus\nname.male814=Margarito\nname.male815=Maria\nname.male816=Mariano\nname.male817=Mario\nname.male818=Marion\nname.male819=Mark\nname.male820=Markus\nname.male821=Marlin\nname.male822=Marlon\nname.male823=Marquis\nname.male824=Marshall\nname.male825=Martin\nname.male826=Marty\nname.male827=Marvin\nname.male828=Mary\nname.male829=Mason\nname.male830=Mathew\nname.male831=Matt\nname.male832=Matthew\nname.male833=Maurice\nname.male834=Mauricio\nname.male835=Mauro\nname.male836=Maverick\nname.male837=Max\nname.male838=Maximo\nname.male839=Maxwell\nname.male840=Maynard\nname.male841=Mckinley\nname.male842=Mel\nname.male843=Melvin\nname.male844=Merle\nname.male845=Merlin\nname.male846=Merrill\nname.male847=Mervin\nname.male848=Micah\nname.male849=Michael\nname.male850=Michal\nname.male851=Michale\nname.male852=Micheal\nname.male853=Michel\nname.male854=Mickey\nname.male855=Miguel\nname.male856=Mike\nname.male857=Mikel\nname.male858=Milan\nname.male859=Miles\nname.male860=Milford\nname.male861=Millard\nname.male862=Milo\nname.male863=Milton\nname.male864=Minh\nname.male865=Miquel\nname.male866=Mitch\nname.male867=Mitchel\nname.male868=Mitchell\nname.male869=Modesto\nname.male870=Mohamed\nname.male871=Mohammad\nname.male872=Mohammed\nname.male873=Moises\nname.male874=Monroe\nname.male875=Monte\nname.male876=Monty\nname.male877=Morgan\nname.male878=Morris\nname.male879=Morton\nname.male880=Mose\nname.male881=Moses\nname.male882=Moshe\nname.male883=Murray\nname.male884=Myles\nname.male885=Myron\nname.male886=Napoleon\nname.male887=Narcissus\nname.male888=Nathan\nname.male889=Nathanael\nname.male890=Nathanial\nname.male891=Nathaniel\nname.male892=Neal\nname.male893=Ned\nname.male894=Neil\nname.male895=Nelson\nname.male896=Nestor\nname.male897=Neville\nname.male898=Newton\nname.male899=Nicholas\nname.male900=Nick\nname.male901=Nickolas\nname.male902=Nicky\nname.male903=Nicolas\nname.male904=Nigel\nname.male905=Noah\nname.male906=Noble\nname.male907=Noe\nname.male908=Noel\nname.male909=Nolan\nname.male910=Norbert\nname.male911=Norberto\nname.male912=Norman\nname.male913=Normand\nname.male914=Norris\nname.male915=Numbers\nname.male916=Octavio\nname.male917=Odell\nname.male918=Odis\nname.male919=Olen\nname.male920=Olin\nname.male921=Oliver\nname.male922=Ollie\nname.male923=Omar\nname.male924=Omer\nname.male925=Oren\nname.male926=Orlando\nname.male927=Orval\nname.male928=Orville\nname.male929=Oscar\nname.male930=Osvaldo\nname.male931=Oswaldo\nname.male932=Otha\nname.male933=Otis\nname.male934=Otto\nname.male935=Owen\nname.male936=Pablo\nname.male937=Palmer\nname.male938=Paris\nname.male939=Parker\nname.male940=Pasquale\nname.male941=Pat\nname.male942=Patricia\nname.male943=Patrick\nname.male944=Paul\nname.male945=Pedro\nname.male946=Percy\nname.male947=Perry\nname.male948=Pete\nname.male949=Peter\nname.male950=Phil\nname.male951=Philip\nname.male952=Phillip\nname.male953=Pierre\nname.male954=Porfirio\nname.male955=Porter\nname.male956=Preston\nname.male957=Prince\nname.male958=Quentin\nname.male959=Quincy\nname.male960=Quinn\nname.male961=Quintin\nname.male962=Quinton\nname.male963=Rafael\nname.male964=Raleigh\nname.male965=Ralph\nname.male966=Ramiro\nname.male967=Ramon\nname.male968=Ramsay\nname.male969=Randal\nname.male970=Randall\nname.male971=Randell\nname.male972=Randolph\nname.male973=Randy\nname.male974=Raphael\nname.male975=Rashad\nname.male976=Raul\nname.male977=Ray\nname.male978=Rayford\nname.male979=Raymon\nname.male980=Raymond\nname.male981=Raymundo\nname.male982=Reed\nname.male983=Reese\nname.male984=Refugio\nname.male985=Reggie\nname.male986=Reginald\nname.male987=Reid\nname.male988=Reinaldo\nname.male989=Renaldo\nname.male990=Renato\nname.male991=Rene\nname.male992=Reuben\nname.male993=Rex\nname.male994=Rey\nname.male995=Reyes\nname.male996=Reynaldo\nname.male997=Rhett\nname.male998=Ricardo\nname.male999=Rich\nname.male1000=Richard\nname.male1001=Richie\nname.male1002=Rick\nname.male1003=Rickey\nname.male1004=Rickie\nname.male1005=Ricky\nname.male1006=Rico\nname.male1007=Rigoberto\nname.male1008=Riley\nname.male1009=Rob\nname.male1010=Robbie\nname.male1011=Robby\nname.male1012=Robert\nname.male1013=Roberto\nname.male1014=Robin\nname.male1015=Robt\nname.male1016=Rocco\nname.male1017=Rocky\nname.male1018=Rod\nname.male1019=Roderick\nname.male1020=Rodger\nname.male1021=Rodney\nname.male1022=Rodolfo\nname.male1023=Rodrick\nname.male1024=Rodrigo\nname.male1025=Rogelio\nname.male1026=Roger\nname.male1027=Roland\nname.male1028=Rolando\nname.male1029=Rolf\nname.male1030=Rolland\nname.male1031=Roman\nname.male1032=Romeo\nname.male1033=Ron\nname.male1034=Ronald\nname.male1035=Ronnie\nname.male1036=Ronny\nname.male1037=Roosevelt\nname.male1038=Rory\nname.male1039=Rosario\nname.male1040=Roscoe\nname.male1041=Rosendo\nname.male1042=Ross\nname.male1043=Roxas\nname.male1044=Roy\nname.male1045=Royal\nname.male1046=Royce\nname.male1047=Ruben\nname.male1048=Rubin\nname.male1049=Rudolf\nname.male1050=Rudolph\nname.male1051=Rudy\nname.male1052=Rueben\nname.male1053=Rufus\nname.male1054=Rupert\nname.male1055=Russ\nname.male1056=Russel\nname.male1057=Russell\nname.male1058=Rusty\nname.male1059=Ryan\nname.male1060=Rye\nname.male1061=Rylan\nname.male1062=Sal\nname.male1063=Salvador\nname.male1064=Salvatore\nname.male1065=Sam\nname.male1066=Sammie\nname.male1067=Sammy\nname.male1068=Samual\nname.male1069=Samuel\nname.male1070=Sandy\nname.male1071=Sanford\nname.male1072=Sang\nname.male1073=Santiago\nname.male1074=Santo\nname.male1075=Santos\nname.male1076=Sasha\nname.male1077=Saul\nname.male1078=Sawyer\nname.male1079=Scot\nname.male1080=Scott\nname.male1081=Scottie\nname.male1082=Scotty\nname.male1083=Sean\nname.male1084=Sebastian\nname.male1085=Sergio\nname.male1086=Seth\nname.male1087=Seymore\nname.male1088=Seymour\nname.male1089=Shad\nname.male1090=Shane\nname.male1091=Shannon\nname.male1092=Shaun\nname.male1093=Shawn\nname.male1094=Shayne\nname.male1095=Shelby\nname.male1096=Sheldon\nname.male1097=Shelton\nname.male1098=Sherman\nname.male1099=Sherwood\nname.male1100=Shirley\nname.male1101=Shon\nname.male1102=Sid\nname.male1103=Sidney\nname.male1104=Silas\nname.male1105=Simon\nname.male1106=Snake\nname.male1107=Sol\nname.male1108=Solomon\nname.male1109=Son\nname.male1110=Sonny\nname.male1111=Soren\nname.male1112=Sorrel\nname.male1113=Spencer\nname.male1114=Stacey\nname.male1115=Stacy\nname.male1116=Stan\nname.male1117=Stanford\nname.male1118=Stanley\nname.male1119=Stanton\nname.male1120=Stefan\nname.male1121=Stephan\nname.male1122=Stephen\nname.male1123=Sterling\nname.male1124=Steve\nname.male1125=Steven\nname.male1126=Stevie\nname.male1127=Stewart\nname.male1128=Stuart\nname.male1129=Sung\nname.male1130=Sydney\nname.male1131=Sylvester\nname.male1132=Tad\nname.male1133=Tanner\nname.male1134=Taylor\nname.male1135=Ted\nname.male1136=Teddy\nname.male1137=Teodoro\nname.male1138=Terence\nname.male1139=Terrance\nname.male1140=Terrell\nname.male1141=Terrence\nname.male1142=Terry\nname.male1143=Thad\nname.male1144=Thaddeus\nname.male1145=Thanh\nname.male1146=Theo\nname.male1147=Theodore\nname.male1148=Theron\nname.male1149=Thomas\nname.male1150=Thorn\nname.male1151=Thurman\nname.male1152=Tim\nname.male1153=Timmy\nname.male1154=Timon\nname.male1155=Timonthy\nname.male1156=Timothy\nname.male1157=Titus\nname.male1158=Tobias\nname.male1159=Toby\nname.male1160=Tod\nname.male1161=Todd\nname.male1162=Tom\nname.male1163=Tomas\nname.male1164=Tommie\nname.male1165=Tommy\nname.male1166=Toney\nname.male1167=Tony\nname.male1168=Tory\nname.male1169=Tracey\nname.male1170=Tracy\nname.male1171=Travis\nname.male1172=Trent\nname.male1173=Trenton\nname.male1174=Trevor\nname.male1175=Trey\nname.male1176=Trinidad\nname.male1177=Tristan\nname.male1178=Troy\nname.male1179=Truman\nname.male1180=Tuan\nname.male1181=Tyler\nname.male1182=Tyree\nname.male1183=Tyrell\nname.male1184=Tyron\nname.male1185=Tyrone\nname.male1186=Tyson\nname.male1187=Ulysses\nname.male1188=Val\nname.male1189=Valentin\nname.male1190=Valentine\nname.male1191=Van\nname.male1192=Vance\nname.male1193=Vaughn\nname.male1194=Vern\nname.male1195=Vernon\nname.male1196=Vicente\nname.male1197=Victor\nname.male1198=Vince\nname.male1199=Vincent\nname.male1200=Vincenzo\nname.male1201=Virgil\nname.male1202=Virgilio\nname.male1203=Vito\nname.male1204=Von\nname.male1205=Wade\nname.male1206=Waldo\nname.male1207=Walker\nname.male1208=Wallace\nname.male1209=Wallis\nname.male1210=Wally\nname.male1211=Walter\nname.male1212=Walton\nname.male1213=Ward\nname.male1214=Warner\nname.male1215=Warren\nname.male1216=Waylon\nname.male1217=Wayne\nname.male1218=Weldon\nname.male1219=Wendell\nname.male1220=Werner\nname.male1221=Wes\nname.male1222=Wesley\nname.male1223=Wesley\nname.male1224=Weston\nname.male1225=Weston\nname.male1226=Whit\nname.male1227=Whit\nname.male1228=Whitney\nname.male1229=Whitney\nname.male1230=Wilber\nname.male1231=Wilber\nname.male1232=Wilbert\nname.male1233=Wilbert\nname.male1234=Wilbur\nname.male1235=Wilbur\nname.male1236=Wilburn\nname.male1237=Wilburn\nname.male1238=Wiley\nname.male1239=Wiley\nname.male1240=Wilford\nname.male1241=Wilford\nname.male1242=Wilfred\nname.male1243=Wilfred\nname.male1244=Wilfredo\nname.male1245=Wilfredo\nname.male1246=Will\nname.male1247=Will\nname.male1248=Willard\nname.male1249=Willard\nname.male1250=William\nname.male1251=William\nname.male1252=Williams\nname.male1253=Williams\nname.male1254=Willian\nname.male1255=Willian\nname.male1256=Willie\nname.male1257=Willie\nname.male1258=Willis\nname.male1259=Willis\nname.male1260=Willy\nname.male1261=Willy\nname.male1262=Wilmer\nname.male1263=Wilmer\nname.male1264=Wilson\nname.male1265=Wilson\nname.male1266=Wilton\nname.male1267=Wilton\nname.male1268=Winford\nname.male1269=Winford\nname.male1270=Winfred\nname.male1271=Winfred\nname.male1272=Winston\nname.male1273=Winston\nname.male1274=Woodrow\nname.male1275=Woodrow\nname.male1276=Wyatt\nname.male1277=Wyatt\nname.male1278=Wyatt\nname.male1279=Xavier\nname.male1280=Xavier\nname.male1281=Yong\nname.male1282=Yong\nname.male1283=Young\nname.male1284=Young\nname.male1285=Yustin\nname.male1286=Yustin\nname.male1287=Zach\nname.male1288=Zach\nname.male1289=Zachariah\nname.male1290=Zachariah\nname.male1291=Zachary\nname.male1292=Zachary\nname.male1293=Zachery\nname.male1294=Zachery\nname.male1295=Zack\nname.male1296=Zack\nname.male1297=Zackary\nname.male1298=Zackary\nname.male1299=Zane\nname.male1300=Zane\nname.male1301=Zephyr\nname.male1302=Zephyr\n\nname.female1=Aaron\nname.female2=Abbey\nname.female3=Abbie\nname.female4=Abby\nname.female5=Abigail\nname.female6=Ada\nname.female7=Adah\nname.female8=Adaline\nname.female9=Adam\nname.female10=Addie\nname.female11=Addison\nname.female12=Adel\nname.female13=Adela\nname.female14=Adelaida\nname.female15=Adelaide\nname.female16=Adele\nname.female17=Adelia\nname.female18=Adelina\nname.female19=Adeline\nname.female20=Adella\nname.female21=Adelle\nname.female22=Adena\nname.female23=Adina\nname.female24=Adria\nname.female25=Adrian\nname.female26=Adriana\nname.female27=Adriane\nname.female28=Adrianna\nname.female29=Adrianne\nname.female30=Adrien\nname.female31=Adriene\nname.female32=Adrienne\nname.female33=Adrina\nname.female34=Afton\nname.female35=Agatha\nname.female36=Agnes\nname.female37=Agnus\nname.female38=Agripina\nname.female39=Agueda\nname.female40=Agustina\nname.female41=Aida\nname.female42=Aide\nname.female43=Aiko\nname.female44=Aileen\nname.female45=Ailene\nname.female46=Aimee\nname.female47=Aisha\nname.female48=Akiko\nname.female49=Akilah\nname.female50=Alahondra\nname.female51=Alaina\nname.female52=Alaine\nname.female53=Alana\nname.female54=Alane\nname.female55=Alanna\nname.female56=Alayna\nname.female57=Alba\nname.female58=Albert\nname.female59=Alberta\nname.female60=Albertha\nname.female61=Albertina\nname.female62=Albertine\nname.female63=Albina\nname.female64=Alda\nname.female65=Alease\nname.female66=Alecia\nname.female67=Aleen\nname.female68=Aleida\nname.female69=Aleisha\nname.female70=Alejandra\nname.female71=Alejandrina\nname.female72=Alena\nname.female73=Alene\nname.female74=Alesha\nname.female75=Aleshia\nname.female76=Alesia\nname.female77=Alessandra\nname.female78=Aleta\nname.female79=Aletha\nname.female80=Alethea\nname.female81=Alethia\nname.female82=Alex\nname.female83=Alexa\nname.female84=Alexander\nname.female85=Alexandra\nname.female86=Alexandria\nname.female87=Alexia\nname.female88=Alexis\nname.female89=Alfreda\nname.female90=Alfredia\nname.female91=Ali\nname.female92=Alia\nname.female93=Alica\nname.female94=Alice\nname.female95=Alicia\nname.female96=Alida\nname.female97=Alina\nname.female98=Aline\nname.female99=Alisa\nname.female100=Alise\nname.female101=Alisha\nname.female102=Alishia\nname.female103=Alisia\nname.female104=Alison\nname.female105=Alissa\nname.female106=Alita\nname.female107=Alix\nname.female108=Aliza\nname.female109=Alla\nname.female110=Alleen\nname.female111=Allegra\nname.female112=Allen\nname.female113=Allena\nname.female114=Allene\nname.female115=Allie\nname.female116=Alline\nname.female117=Allison\nname.female118=Allyn\nname.female119=Allyson\nname.female120=Alma\nname.female121=Almeda\nname.female122=Almeta\nname.female123=Alona\nname.female124=Alpha\nname.female125=Alta\nname.female126=Altagracia\nname.female127=Altha\nname.female128=Althea\nname.female129=Alva\nname.female130=Alvera\nname.female131=Alverta\nname.female132=Alvina\nname.female133=Alyce\nname.female134=Alycia\nname.female135=Alysa\nname.female136=Alyse\nname.female137=Alysha\nname.female138=Alysia\nname.female139=Alyson\nname.female140=Alyssa\nname.female141=Amada\nname.female142=Amal\nname.female143=Amalia\nname.female144=Amanda\nname.female145=Amaryllis\nname.female146=Amber\nname.female147=Amberly\nname.female148=Amee\nname.female149=Amelia\nname.female150=America\nname.female151=Amethyst\nname.female152=Ami\nname.female153=Amie\nname.female154=Amiee\nname.female155=Amina\nname.female156=Amira\nname.female157=Ammie\nname.female158=Amparo\nname.female159=Amy\nname.female160=Ana\nname.female161=Anabel\nname.female162=Analisa\nname.female163=Anamaria\nname.female164=Anastacia\nname.female165=Anastasia\nname.female166=Andera\nname.female167=Andra\nname.female168=Andre\nname.female169=Andrea\nname.female170=Andree\nname.female171=Andrew\nname.female172=Andria\nname.female173=Anette\nname.female174=Angel\nname.female175=Angela\nname.female176=Angele\nname.female177=Angelena\nname.female178=Angeles\nname.female179=Angelia\nname.female180=Angelic\nname.female181=Angelica\nname.female182=Angelika\nname.female183=Angelina\nname.female184=Angeline\nname.female185=Angelique\nname.female186=Angelita\nname.female187=Angella\nname.female188=Angelo\nname.female189=Angelyn\nname.female190=Angie\nname.female191=Angila\nname.female192=Angla\nname.female193=Angle\nname.female194=Anglea\nname.female195=Anh\nname.female196=Anika\nname.female197=Anisa\nname.female198=Anisha\nname.female199=Anissa\nname.female200=Anita\nname.female201=Anitra\nname.female202=Anja\nname.female203=Anjanette\nname.female204=Anjelica\nname.female205=Ann\nname.female206=Anna\nname.female207=Annabel\nname.female208=Annabell\nname.female209=Annabelle\nname.female210=Annabellie\nname.female211=Annalee\nname.female212=Annalisa\nname.female213=Annamae\nname.female214=Annamaria\nname.female215=Annamarie\nname.female216=Anne\nname.female217=Anneliese\nname.female218=Annelle\nname.female219=Annemarie\nname.female220=Annett\nname.female221=Annetta\nname.female222=Annette\nname.female223=Annice\nname.female224=Annie\nname.female225=Annika\nname.female226=Annis\nname.female227=Annita\nname.female228=Annmarie\nname.female229=Anthony\nname.female230=Antionette\nname.female231=Antoinette\nname.female232=Antonetta\nname.female233=Antonette\nname.female234=Antonia\nname.female235=Antonietta\nname.female236=Antonina\nname.female237=Antonio\nname.female238=Anya\nname.female239=Apolonia\nname.female240=April\nname.female241=Apryl\nname.female242=Ara\nname.female243=Araceli\nname.female244=Aracelis\nname.female245=Aracely\nname.female246=Arcelia\nname.female247=Ardath\nname.female248=Ardelia\nname.female249=Ardell\nname.female250=Ardella\nname.female251=Ardelle\nname.female252=Ardis\nname.female253=Ardith\nname.female254=Areona\nname.female255=Aretha\nname.female256=Argelia\nname.female257=Argentina\nname.female258=Ariana\nname.female259=Ariane\nname.female260=Arianna\nname.female261=Arianne\nname.female262=Arica\nname.female263=Arie\nname.female264=Ariel\nname.female265=Arielle\nname.female266=Arla\nname.female267=Arlean\nname.female268=Arleen\nname.female269=Arlena\nname.female270=Arlene\nname.female271=Arletha\nname.female272=Arletta\nname.female273=Arlette\nname.female274=Arlinda\nname.female275=Arline\nname.female276=Arlyne\nname.female277=Armanda\nname.female278=Armandina\nname.female279=Armida\nname.female280=Arminda\nname.female281=Arnetta\nname.female282=Arnette\nname.female283=Arnita\nname.female284=Arthur\nname.female285=Artie\nname.female286=Arvilla\nname.female287=Asha\nname.female288=Ashanti\nname.female289=Ashely\nname.female290=Ashlea\nname.female291=Ashlee\nname.female292=Ashleigh\nname.female293=Ashley\nname.female294=Ashli\nname.female295=Ashlie\nname.female296=Ashly\nname.female297=Ashlyn\nname.female298=Ashton\nname.female299=Asia\nname.female300=Asley\nname.female301=Assunta\nname.female302=Astrid\nname.female303=Asuncion\nname.female304=Athena\nname.female305=Aubrey\nname.female306=Audie\nname.female307=Audra\nname.female308=Audrea\nname.female309=Audrey\nname.female310=Audria\nname.female311=Audrie\nname.female312=Audry\nname.female313=August\nname.female314=Augusta\nname.female315=Augustina\nname.female316=Augustine\nname.female317=Aundrea\nname.female318=Aura\nname.female319=Aurea\nname.female320=Aurelia\nname.female321=Aurora\nname.female322=Aurore\nname.female323=Austin\nname.female324=Autumn\nname.female325=Ava\nname.female326=Avelina\nname.female327=Avery\nname.female328=Avis\nname.female329=Avril\nname.female330=Awilda\nname.female331=Ayako\nname.female332=Ayana\nname.female333=Ayanna\nname.female334=Ayesha\nname.female335=Azalea\nname.female336=Azalee\nname.female337=Azucena\nname.female338=Azzie\nname.female339=Babara\nname.female340=Babette\nname.female341=Bailey\nname.female342=Bambi\nname.female343=Bao\nname.female344=Barabara\nname.female345=Barb\nname.female346=Barbar\nname.female347=Barbara\nname.female348=Barbara-Anne\nname.female349=Barbera\nname.female350=Barbie\nname.female351=Barbra\nname.female352=Bari\nname.female353=Barrie\nname.female354=Basilia\nname.female355=Bea\nname.female356=Beata\nname.female357=Beatrice\nname.female358=Beatris\nname.female359=Beatriz\nname.female360=Beaulah\nname.female361=Bebe\nname.female362=Becki\nname.female363=Beckie\nname.female364=Becky\nname.female365=Bee\nname.female366=Belen\nname.female367=Belia\nname.female368=Belinda\nname.female369=Belkis\nname.female370=Bell\nname.female371=Bella\nname.female372=Belle\nname.female373=Belva\nname.female374=Benita\nname.female375=Bennie\nname.female376=Berenice\nname.female377=Berna\nname.female378=Bernadette\nname.female379=Bernadine\nname.female380=Bernarda\nname.female381=Bernardina\nname.female382=Bernardine\nname.female383=Berneice\nname.female384=Bernetta\nname.female385=Bernice\nname.female386=Bernie\nname.female387=Berniece\nname.female388=Bernita\nname.female389=Berry\nname.female390=Berta\nname.female391=Bertha\nname.female392=Bertie\nname.female393=Beryl\nname.female394=Bess\nname.female395=Bessie\nname.female396=Beth\nname.female397=Bethanie\nname.female398=Bethann\nname.female399=Bethany\nname.female400=Bethel\nname.female401=Betsey\nname.female402=Betsy\nname.female403=Bette\nname.female404=Bettie\nname.female405=Bettina\nname.female406=Betty\nname.female407=Bettyann\nname.female408=Bettye\nname.female409=Beula\nname.female410=Beulah\nname.female411=Bev\nname.female412=Beverlee\nname.female413=Beverley\nname.female414=Beverly\nname.female415=Bianca\nname.female416=Bibi\nname.female417=Billi\nname.female418=Billie\nname.female419=Billy\nname.female420=Billye\nname.female421=Birdie\nname.female422=Birgit\nname.female423=Blair\nname.female424=Blake\nname.female425=Blanca\nname.female426=Blanch\nname.female427=Blanche\nname.female428=Blondell\nname.female429=Blossom\nname.female430=Blythe\nname.female431=Bobbi\nname.female432=Bobbie\nname.female433=Bobby\nname.female434=Bobbye\nname.female435=Bobette\nname.female436=Bok\nname.female437=Bong\nname.female438=Bonita\nname.female439=Bonnie\nname.female440=Bonny\nname.female441=Branda\nname.female442=Brande\nname.female443=Brandee\nname.female444=Brandi\nname.female445=Brandie\nname.female446=Brandon\nname.female447=Brandy\nname.female448=Breana\nname.female449=Breann\nname.female450=Breanna\nname.female451=Breanne\nname.female452=Bree\nname.female453=Brenda\nname.female454=Brenna\nname.female455=Brett\nname.female456=Brian\nname.female457=Briana\nname.female458=Brianna\nname.female459=Brianne\nname.female460=Briar\nname.female461=Bridget\nname.female462=Bridgett\nname.female463=Bridgette\nname.female464=Brielle\nname.female465=Brigette\nname.female466=Brigid\nname.female467=Brigida\nname.female468=Brigitte\nname.female469=Brinda\nname.female470=Britany\nname.female471=Britney\nname.female472=Britni\nname.female473=Britt\nname.female474=Britta\nname.female475=Brittaney\nname.female476=Brittani\nname.female477=Brittanie\nname.female478=Brittany\nname.female479=Britteny\nname.female480=Brittney\nname.female481=Brittni\nname.female482=Brittny\nname.female483=Bronwyn\nname.female484=Brook\nname.female485=Brooke\nname.female486=Bruna\nname.female487=Brunilda\nname.female488=Bryanna\nname.female489=Brynn\nname.female490=Buena\nname.female491=Buffy\nname.female492=Bula\nname.female493=Bulah\nname.female494=Bunny\nname.female495=Burma\nname.female496=Caitlin\nname.female497=Caitlyn\nname.female498=Calandra\nname.female499=Calista\nname.female500=Calla\nname.female501=Callie\nname.female502=Camelia\nname.female503=Camellia\nname.female504=Cameron\nname.female505=Cami\nname.female506=Camie\nname.female507=Camila\nname.female508=Camilla\nname.female509=Camille\nname.female510=Cammie\nname.female511=Cammy\nname.female512=Candace\nname.female513=Candance\nname.female514=Candelaria\nname.female515=Candi\nname.female516=Candice\nname.female517=Candida\nname.female518=Candie\nname.female519=Candis\nname.female520=Candra\nname.female521=Candy\nname.female522=Candyce\nname.female523=Caprice\nname.female524=Cara\nname.female525=Caren\nname.female526=Carey\nname.female527=Cari\nname.female528=Caridad\nname.female529=Carie\nname.female530=Carin\nname.female531=Carina\nname.female532=Carisa\nname.female533=Carissa\nname.female534=Carita\nname.female535=Carl\nname.female536=Carla\nname.female537=Carlee\nname.female538=Carleen\nname.female539=Carlena\nname.female540=Carlene\nname.female541=Carletta\nname.female542=Carley\nname.female543=Carli\nname.female544=Carlie\nname.female545=Carline\nname.female546=Carlita\nname.female547=Carlos\nname.female548=Carlota\nname.female549=Carlotta\nname.female550=Carly\nname.female551=Carlyn\nname.female552=Carma\nname.female553=Carman\nname.female554=Carmel\nname.female555=Carmela\nname.female556=Carmelia\nname.female557=Carmelina\nname.female558=Carmelita\nname.female559=Carmella\nname.female560=Carmen\nname.female561=Carmina\nname.female562=Carmon\nname.female563=Carol\nname.female564=Carola\nname.female565=Carolann\nname.female566=Carole\nname.female567=Carolee\nname.female568=Carolin\nname.female569=Carolina\nname.female570=Caroline\nname.female571=Caroll\nname.female572=Carolyn\nname.female573=Carolyne\nname.female574=Carolynn\nname.female575=Caron\nname.female576=Caroyln\nname.female577=Carri\nname.female578=Carrie\nname.female579=Carrol\nname.female580=Carroll\nname.female581=Carry\nname.female582=Cary\nname.female583=Caryl\nname.female584=Carylon\nname.female585=Caryn\nname.female586=Casandra\nname.female587=Casey\nname.female588=Casie\nname.female589=Casimira\nname.female590=Cassandra\nname.female591=Cassaundra\nname.female592=Cassey\nname.female593=Cassi\nname.female594=Cassidy\nname.female595=Cassie\nname.female596=Cassondra\nname.female597=Cassy\nname.female598=Catalina\nname.female599=Catarina\nname.female600=Caterina\nname.female601=Catharine\nname.female602=Catherin\nname.female603=Catherina\nname.female604=Catherine\nname.female605=Cathern\nname.female606=Catheryn\nname.female607=Cathey\nname.female608=Cathi\nname.female609=Cathie\nname.female610=Cathleen\nname.female611=Cathrine\nname.female612=Cathryn\nname.female613=Cathy\nname.female614=Catina\nname.female615=Catrice\nname.female616=Catrina\nname.female617=Cayla\nname.female618=Cecelia\nname.female619=Cecil\nname.female620=Cecila\nname.female621=Cecile\nname.female622=Cecilia\nname.female623=Cecille\nname.female624=Cecily\nname.female625=Celena\nname.female626=Celesta\nname.female627=Celeste\nname.female628=Celestina\nname.female629=Celestine\nname.female630=Celia\nname.female631=Celina\nname.female632=Celinda\nname.female633=Celine\nname.female634=Celsa\nname.female635=Ceola\nname.female636=Chae\nname.female637=Chan\nname.female638=Chana\nname.female639=Chanda\nname.female640=Chandra\nname.female641=Chanel\nname.female642=Chanell\nname.female643=Chanelle\nname.female644=Chang\nname.female645=Chantal\nname.female646=Chantay\nname.female647=Chante\nname.female648=Chantel\nname.female649=Chantell\nname.female650=Chantelle\nname.female651=Chara\nname.female652=Chariisa\nname.female653=Charis\nname.female654=Charise\nname.female655=Charissa\nname.female656=Charisse\nname.female657=Charita\nname.female658=Charity\nname.female659=Charla\nname.female660=Charleen\nname.female661=Charlena\nname.female662=Charlene\nname.female663=Charles\nname.female664=Charlesetta\nname.female665=Charlette\nname.female666=Charlie\nname.female667=Charline\nname.female668=Charlott\nname.female669=Charlotte\nname.female670=Charlsie\nname.female671=Charlyn\nname.female672=Charmain\nname.female673=Charmaine\nname.female674=Charolette\nname.female675=Chasidy\nname.female676=Chasity\nname.female677=Chassidy\nname.female678=Chassity\nname.female679=Chastity\nname.female680=Chau\nname.female681=Chaya\nname.female682=Chelsea\nname.female683=Chelsey\nname.female684=Chelsie\nname.female685=Cher\nname.female686=Chere\nname.female687=Cheree\nname.female688=Cherelle\nname.female689=Cheri\nname.female690=Cherie\nname.female691=Cherilyn\nname.female692=Cherise\nname.female693=Cherish\nname.female694=Cherly\nname.female695=Cherlyn\nname.female696=Cherri\nname.female697=Cherrie\nname.female698=Cherry\nname.female699=Cherryl\nname.female700=Chery\nname.female701=Cheryl\nname.female702=Cheryle\nname.female703=Cheryll\nname.female704=Cheyenne\nname.female705=Chi\nname.female706=Chia\nname.female707=Chieko\nname.female708=Chin\nname.female709=China\nname.female710=Ching\nname.female711=Chiquita\nname.female712=Chloe\nname.female713=Chong\nname.female714=Chris\nname.female715=Chrissy\nname.female716=Christa\nname.female717=Christal\nname.female718=Christeen\nname.female719=Christel\nname.female720=Christen\nname.female721=Christena\nname.female722=Christene\nname.female723=Christi\nname.female724=Christia\nname.female725=Christian\nname.female726=Christiana\nname.female727=Christiane\nname.female728=Christie\nname.female729=Christin\nname.female730=Christina\nname.female731=Christine\nname.female732=Christinia\nname.female733=Christopher\nname.female734=Christy\nname.female735=Chrystal\nname.female736=Chu\nname.female737=Chun\nname.female738=Chung\nname.female739=Ciara\nname.female740=Cicely\nname.female741=Ciera\nname.female742=Cierra\nname.female743=Cinda\nname.female744=Cinderella\nname.female745=Cindi\nname.female746=Cindie\nname.female747=Cindy\nname.female748=Cinthia\nname.female749=Cira\nname.female750=Clair\nname.female751=Claire\nname.female752=Clara\nname.female753=Clare\nname.female754=Clarence\nname.female755=Claretha\nname.female756=Claretta\nname.female757=Claribel\nname.female758=Clarice\nname.female759=Clarinda\nname.female760=Clarine\nname.female761=Claris\nname.female762=Clarisa\nname.female763=Clarissa\nname.female764=Clarita\nname.female765=Classie\nname.female766=Claude\nname.female767=Claudette\nname.female768=Claudia\nname.female769=Claudie\nname.female770=Claudine\nname.female771=Clelia\nname.female772=Clemencia\nname.female773=Clementina\nname.female774=Clementine\nname.female775=Clemmie\nname.female776=Cleo\nname.female777=Cleopatra\nname.female778=Cleora\nname.female779=Cleotilde\nname.female780=Cleta\nname.female781=Clora\nname.female782=Clorinda\nname.female783=Clotilde\nname.female784=Clover\nname.female785=Clyde\nname.female786=Codi\nname.female787=Cody\nname.female788=Colby\nname.female789=Coleen\nname.female790=Colene\nname.female791=Coletta\nname.female792=Colette\nname.female793=Colleen\nname.female794=Collen\nname.female795=Collene\nname.female796=Collette\nname.female797=Concepcion\nname.female798=Conception\nname.female799=Concetta\nname.female800=Concha\nname.female801=Conchita\nname.female802=Connie\nname.female803=Constance\nname.female804=Consuela\nname.female805=Consuelo\nname.female806=Contessa\nname.female807=Cora\nname.female808=Coral\nname.female809=Coralee\nname.female810=Coralie\nname.female811=Corazon\nname.female812=Cordelia\nname.female813=Cordia\nname.female814=Cordie\nname.female815=Coreen\nname.female816=Corene\nname.female817=Coretta\nname.female818=Corey\nname.female819=Cori\nname.female820=Corie\nname.female821=Corina\nname.female822=Corine\nname.female823=Corinna\nname.female824=Corinne\nname.female825=Corliss\nname.female826=Cornelia\nname.female827=Corrie\nname.female828=Corrin\nname.female829=Corrina\nname.female830=Corrine\nname.female831=Corrinne\nname.female832=Cortney\nname.female833=Cory\nname.female834=Courtney\nname.female835=Creola\nname.female836=Cris\nname.female837=Criselda\nname.female838=Crissy\nname.female839=Crista\nname.female840=Cristal\nname.female841=Cristen\nname.female842=Cristi\nname.female843=Cristie\nname.female844=Cristin\nname.female845=Cristina\nname.female846=Cristine\nname.female847=Cristy\nname.female848=Cruz\nname.female849=Crysta\nname.female850=Crystal\nname.female851=Crystle\nname.female852=Curtis\nname.female853=Cyndi\nname.female854=Cyndy\nname.female855=Cynthia\nname.female856=Cyrstal\nname.female857=Cythia\nname.female858=Dacia\nname.female859=Dagmar\nname.female860=Dagny\nname.female861=Dahlia\nname.female862=Daina\nname.female863=Daine\nname.female864=Daisey\nname.female865=Daisy\nname.female866=Daisy-Mae\nname.female867=Dakota\nname.female868=Dale\nname.female869=Dalene\nname.female870=Dalia\nname.female871=Dalie\nname.female872=Dalila\nname.female873=Dallas\nname.female874=Dallis\nname.female875=Damaris\nname.female876=Dan\nname.female877=Dana\nname.female878=Danae\nname.female879=Danelle\nname.female880=Danette\nname.female881=Dani\nname.female882=Dania\nname.female883=Danica\nname.female884=Daniel\nname.female885=Daniela\nname.female886=Daniele\nname.female887=Daniell\nname.female888=Daniella\nname.female889=Danielle\nname.female890=Danika\nname.female891=Danille\nname.female892=Danita\nname.female893=Dann\nname.female894=Danna\nname.female895=Dannette\nname.female896=Dannie\nname.female897=Dannielle\nname.female898=Danuta\nname.female899=Danyel\nname.female900=Danyell\nname.female901=Danyelle\nname.female902=Daphine\nname.female903=Daphne\nname.female904=Dara\nname.female905=Darby\nname.female906=Darcel\nname.female907=Darcey\nname.female908=Darci\nname.female909=Darcie\nname.female910=Darcy\nname.female911=Daria\nname.female912=Darla\nname.female913=Darleen\nname.female914=Darlena\nname.female915=Darlene\nname.female916=Darline\nname.female917=Darnell\nname.female918=Daryl\nname.female919=David\nname.female920=Davida\nname.female921=Davina\nname.female922=Dawn\nname.female923=Dawna\nname.female924=Dawne\nname.female925=Dayle\nname.female926=Dayna\nname.female927=Daysi\nname.female928=Deadra\nname.female929=Dean\nname.female930=Deana\nname.female931=Deandra\nname.female932=Deandrea\nname.female933=Deane\nname.female934=Deann\nname.female935=Deanna\nname.female936=Deanne\nname.female937=Deb\nname.female938=Debbi\nname.female939=Debbie\nname.female940=Debbra\nname.female941=Debby\nname.female942=Debera\nname.female943=Debi\nname.female944=Debie\nname.female945=Debora\nname.female946=Deborah\nname.female947=Debra\nname.female948=Debrah\nname.female949=Debroah\nname.female950=Dede\nname.female951=Dedra\nname.female952=Dee\nname.female953=Deeann\nname.female954=Deeanna\nname.female955=Deedee\nname.female956=Deedra\nname.female957=Deena\nname.female958=Deetta\nname.female959=Deidra\nname.female960=Deidre\nname.female961=Deirdre\nname.female962=Deja\nname.female963=Delaine\nname.female964=Delana\nname.female965=Delaney\nname.female966=Delcie\nname.female967=Delena\nname.female968=Delfina\nname.female969=Delia\nname.female970=Delicia\nname.female971=Delila\nname.female972=Delilah\nname.female973=Delinda\nname.female974=Delisa\nname.female975=Dell\nname.female976=Della\nname.female977=Delma\nname.female978=Delmy\nname.female979=Delois\nname.female980=Deloise\nname.female981=Delora\nname.female982=Deloras\nname.female983=Delores\nname.female984=Deloris\nname.female985=Delorse\nname.female986=Delpha\nname.female987=Delphia\nname.female988=Delphine\nname.female989=Delsie\nname.female990=Delta\nname.female991=Demetra\nname.female992=Demetria\nname.female993=Demetrice\nname.female994=Demetrius\nname.female995=Dena\nname.female996=Denae\nname.female997=Deneen\nname.female998=Denese\nname.female999=Denice\nname.female1000=Denise\nname.female1001=Denisha\nname.female1002=Denisse\nname.female1003=Denita\nname.female1004=Denna\nname.female1005=Dennis\nname.female1006=Dennise\nname.female1007=Denny\nname.female1008=Denyse\nname.female1009=Deon\nname.female1010=Deonna\nname.female1011=Desirae\nname.female1012=Desire\nname.female1013=Desiree\nname.female1014=Despina\nname.female1015=Dessi\nname.female1016=Dessie\nname.female1017=Destiny\nname.female1018=Detra\nname.female1019=Devin\nname.female1020=Devon\nname.female1021=Devona\nname.female1022=Devora\nname.female1023=Devorah\nname.female1024=Dia\nname.female1025=Diamond\nname.female1026=Dian\nname.female1027=Diana\nname.female1028=Diane\nname.female1029=Diann\nname.female1030=Dianna\nname.female1031=Dianne\nname.female1032=Diedra\nname.female1033=Diedre\nname.female1034=Dierdre\nname.female1035=Digna\nname.female1036=Dimple\nname.female1037=Dina\nname.female1038=Dinah\nname.female1039=Dinorah\nname.female1040=Dion\nname.female1041=Dione\nname.female1042=Dionna\nname.female1043=Dionne\nname.female1044=Divina\nname.female1045=Dixie\nname.female1046=Dodie\nname.female1047=Dollie\nname.female1048=Dolly\nname.female1049=Dolores\nname.female1050=Doloris\nname.female1051=Domenica\nname.female1052=Dominga\nname.female1053=Dominica\nname.female1054=Dominique\nname.female1055=Dominque\nname.female1056=Domitila\nname.female1057=Domonique\nname.female1058=Dona\nname.female1059=Donald\nname.female1060=Donella\nname.female1061=Donetta\nname.female1062=Donette\nname.female1063=Dong\nname.female1064=Donita\nname.female1065=Donna\nname.female1066=Donna-Jo\nname.female1067=Donnetta\nname.female1068=Donnette\nname.female1069=Donnie\nname.female1070=Donya\nname.female1071=Dora\nname.female1072=Dorathy\nname.female1073=Dorcas\nname.female1074=Doreatha\nname.female1075=Doreen\nname.female1076=Dorene\nname.female1077=Doretha\nname.female1078=Dorethea\nname.female1079=Doretta\nname.female1080=Dori\nname.female1081=Doria\nname.female1082=Dorian\nname.female1083=Dorie\nname.female1084=Dorinda\nname.female1085=Dorine\nname.female1086=Doris\nname.female1087=Dorla\nname.female1088=Dorotha\nname.female1089=Dorothea\nname.female1090=Dorothy\nname.female1091=Dorris\nname.female1092=Dortha\nname.female1093=Dorthea\nname.female1094=Dorthey\nname.female1095=Dorthy\nname.female1096=Dot\nname.female1097=Dottie\nname.female1098=Dotty\nname.female1099=Dovie\nname.female1100=Dreama\nname.female1101=Drema\nname.female1102=Drew\nname.female1103=Drucilla\nname.female1104=Drusilla\nname.female1105=Dulce\nname.female1106=Dulcie\nname.female1107=Dung\nname.female1108=Dusti\nname.female1109=Dusty\nname.female1110=Dwana\nname.female1111=Dyan\nname.female1112=Earlean\nname.female1113=Earleen\nname.female1114=Earlene\nname.female1115=Earlie\nname.female1116=Earline\nname.female1117=Earnestine\nname.female1118=Eartha\nname.female1119=Easter\nname.female1120=Eboni\nname.female1121=Ebonie\nname.female1122=Ebony\nname.female1123=Echo\nname.female1124=Eda\nname.female1125=Edda\nname.female1126=Eddie\nname.female1127=Edelmira\nname.female1128=Eden\nname.female1129=Edie\nname.female1130=Edith\nname.female1131=Edna\nname.female1132=Edra\nname.female1133=Edris\nname.female1134=Edward\nname.female1135=Edwina\nname.female1136=Edyth\nname.female1137=Edythe\nname.female1138=Effie\nname.female1139=Ehtel\nname.female1140=Eileen\nname.female1141=Eilene\nname.female1142=Ela\nname.female1143=Eladia\nname.female1144=Elaina\nname.female1145=Elaine\nname.female1146=Elana\nname.female1147=Elane\nname.female1148=Elanor\nname.female1149=Elayne\nname.female1150=Elba\nname.female1151=Elda\nname.female1152=Eldora\nname.female1153=Eleanor\nname.female1154=Eleanora\nname.female1155=Eleanore\nname.female1156=Elease\nname.female1157=Elena\nname.female1158=Elene\nname.female1159=Eleni\nname.female1160=Elenor\nname.female1161=Elenora\nname.female1162=Elenore\nname.female1163=Eleonor\nname.female1164=Eleonora\nname.female1165=Eleonore\nname.female1166=Elfreda\nname.female1167=Elfrieda\nname.female1168=Elfriede\nname.female1169=Elia\nname.female1170=Eliana\nname.female1171=Elicia\nname.female1172=Elida\nname.female1173=Elidia\nname.female1174=Elin\nname.female1175=Elina\nname.female1176=Elinor\nname.female1177=Elinore\nname.female1178=Elisa\nname.female1179=Elisabeth\nname.female1180=Elise\nname.female1181=Elisha\nname.female1182=Elissa\nname.female1183=Eliz\nname.female1184=Eliza\nname.female1185=Elizabet\nname.female1186=Elizabeth\nname.female1187=Elizbeth\nname.female1188=Elizebeth\nname.female1189=Elke\nname.female1190=Ella\nname.female1191=Ellamae\nname.female1192=Ellan\nname.female1193=Ellen\nname.female1194=Ellena\nname.female1195=Elli\nname.female1196=Ellie\nname.female1197=Ellis\nname.female1198=Elly\nname.female1199=Ellyn\nname.female1200=Elma\nname.female1201=Elmer\nname.female1202=Elmira\nname.female1203=Elna\nname.female1204=Elnora\nname.female1205=Elodia\nname.female1206=Elois\nname.female1207=Eloisa\nname.female1208=Eloise\nname.female1209=Elouise\nname.female1210=Elsa\nname.female1211=Else\nname.female1212=Elsie\nname.female1213=Elsy\nname.female1214=Elva\nname.female1215=Elvera\nname.female1216=Elvia\nname.female1217=Elvie\nname.female1218=Elvina\nname.female1219=Elvira\nname.female1220=Elwanda\nname.female1221=Elyse\nname.female1222=Elza\nname.female1223=Ema\nname.female1224=Emelda\nname.female1225=Emelia\nname.female1226=Emelina\nname.female1227=Emeline\nname.female1228=Emely\nname.female1229=Emerald\nname.female1230=Emerita\nname.female1231=Emiko\nname.female1232=Emilee\nname.female1233=Emilia\nname.female1234=Emilie\nname.female1235=Emily\nname.female1236=Emma\nname.female1237=Emmaline\nname.female1238=Emmie\nname.female1239=Emmy\nname.female1240=Emogene\nname.female1241=Ena\nname.female1242=Enda\nname.female1243=Enedina\nname.female1244=Eneida\nname.female1245=Enid\nname.female1246=Enola\nname.female1247=Enriqueta\nname.female1248=Epifania\nname.female1249=Era\nname.female1250=Eric\nname.female1251=Erica\nname.female1252=Ericka\nname.female1253=Erika\nname.female1254=Erin\nname.female1255=Erinn\nname.female1256=Erlene\nname.female1257=Erlinda\nname.female1258=Erline\nname.female1259=Erma\nname.female1260=Ermelinda\nname.female1261=Erminia\nname.female1262=Erna\nname.female1263=Ernestina\nname.female1264=Ernestine\nname.female1265=Eryn\nname.female1266=Esmeralda\nname.female1267=Esperanza\nname.female1268=Essie\nname.female1269=Esta\nname.female1270=Estefana\nname.female1271=Estela\nname.female1272=Estell\nname.female1273=Estella\nname.female1274=Estelle\nname.female1275=Ester\nname.female1276=Esther\nname.female1277=Estrella\nname.female1278=Etha\nname.female1279=Ethel\nname.female1280=Ethelene\nname.female1281=Ethelyn\nname.female1282=Ethyl\nname.female1283=Etsuko\nname.female1284=Etta\nname.female1285=Ettie\nname.female1286=Eufemia\nname.female1287=Eugena\nname.female1288=Eugene\nname.female1289=Eugenia\nname.female1290=Eugenie\nname.female1291=Eula\nname.female1292=Eulah\nname.female1293=Eulalia\nname.female1294=Eun\nname.female1295=Euna\nname.female1296=Eunice\nname.female1297=Eura\nname.female1298=Eusebia\nname.female1299=Eustolia\nname.female1300=Eva\nname.female1301=Evadne\nname.female1302=Evalyn\nname.female1303=Evan\nname.female1304=Evangelina\nname.female1305=Evangeline\nname.female1306=Eve\nname.female1307=Evelia\nname.female1308=Evelin\nname.female1309=Evelina\nname.female1310=Eveline\nname.female1311=Evelyn\nname.female1312=Evelyne\nname.female1313=Evelynn\nname.female1314=Evette\nname.female1315=Evia\nname.female1316=Evie\nname.female1317=Evita\nname.female1318=Evon\nname.female1319=Evonne\nname.female1320=Ewa\nname.female1321=Exie\nname.female1322=Fabiola\nname.female1323=Fae\nname.female1324=Fairy\nname.female1325=Faith\nname.female1326=Fall\nname.female1327=Fallon\nname.female1328=Fannie\nname.female1329=Fanny\nname.female1330=Farah\nname.female1331=Farrah\nname.female1332=Fatima\nname.female1333=Fatimah\nname.female1334=Faustina\nname.female1335=Faviola\nname.female1336=Fawn\nname.female1337=Fay\nname.female1338=Faye\nname.female1339=Felecia\nname.female1340=Felica\nname.female1341=Felice\nname.female1342=Felicia\nname.female1343=Felicidad\nname.female1344=Felicita\nname.female1345=Felicitas\nname.female1346=Felipa\nname.female1347=Felisa\nname.female1348=Felisha\nname.female1349=Fermina\nname.female1350=Fern\nname.female1351=Fernanda\nname.female1352=Fernande\nname.female1353=Ferne\nname.female1354=Fidela\nname.female1355=Fidelia\nname.female1356=Filomena\nname.female1357=Fiona\nname.female1358=Flavia\nname.female1359=Fleta\nname.female1360=Flo\nname.female1361=Flor\nname.female1362=Flora\nname.female1363=Florance\nname.female1364=Florence\nname.female1365=Florencia\nname.female1366=Florene\nname.female1367=Florentina\nname.female1368=Floretta\nname.female1369=Floria\nname.female1370=Florida\nname.female1371=Florinda\nname.female1372=Florine\nname.female1373=Florrie\nname.female1374=Flossie\nname.female1375=Floy\nname.female1376=Fonda\nname.female1377=Fran\nname.female1378=France\nname.female1379=Francene\nname.female1380=Frances\nname.female1381=Francesca\nname.female1382=Franchesca\nname.female1383=Francie\nname.female1384=Francina\nname.female1385=Francine\nname.female1386=Francis\nname.female1387=Francisca\nname.female1388=Francisco\nname.female1389=Francoise\nname.female1390=Frank\nname.female1391=Frankie\nname.female1392=Fransisca\nname.female1393=Fred\nname.female1394=Freda\nname.female1395=Fredda\nname.female1396=Freddie\nname.female1397=Frederica\nname.female1398=Fredericka\nname.female1399=Fredia\nname.female1400=Fredricka\nname.female1401=Freeda\nname.female1402=Freida\nname.female1403=Frida\nname.female1404=Frieda\nname.female1405=Fumiko\nname.female1406=Gabriel\nname.female1407=Gabriela\nname.female1408=Gabriele\nname.female1409=Gabriella\nname.female1410=Gabrielle\nname.female1411=Gail\nname.female1412=Gala\nname.female1413=Gale\nname.female1414=Galina\nname.female1415=Garnet\nname.female1416=Garnett\nname.female1417=Gary\nname.female1418=Gaye\nname.female1419=Gayla\nname.female1420=Gayle\nname.female1421=Gaylene\nname.female1422=Gaynell\nname.female1423=Gaynelle\nname.female1424=Gearldine\nname.female1425=Gema\nname.female1426=Gemma\nname.female1427=Gena\nname.female1428=Gene\nname.female1429=Genesis\nname.female1430=Geneva\nname.female1431=Genevie\nname.female1432=Genevieve\nname.female1433=Genevive\nname.female1434=Genia\nname.female1435=Genie\nname.female1436=Genna\nname.female1437=Gennie\nname.female1438=Genny\nname.female1439=Genoveva\nname.female1440=Georgann\nname.female1441=George\nname.female1442=Georgeann\nname.female1443=Georgeanna\nname.female1444=Georgene\nname.female1445=Georgetta\nname.female1446=Georgette\nname.female1447=Georgia\nname.female1448=Georgiana\nname.female1449=Georgiann\nname.female1450=Georgianna\nname.female1451=Georgianne\nname.female1452=Georgie\nname.female1453=Georgina\nname.female1454=Georgine\nname.female1455=Gerald\nname.female1456=Geraldine\nname.female1457=Geralyn\nname.female1458=Gerda\nname.female1459=Geri\nname.female1460=Germaine\nname.female1461=Gerri\nname.female1462=Gerry\nname.female1463=Gertha\nname.female1464=Gertie\nname.female1465=Gertrud\nname.female1466=Gertrude\nname.female1467=Gertrudis\nname.female1468=Gertude\nname.female1469=Ghislaine\nname.female1470=Gia\nname.female1471=Gianna\nname.female1472=Gidget\nname.female1473=Gigi\nname.female1474=Gilberte\nname.female1475=Gilda\nname.female1476=Gillian\nname.female1477=Gilma\nname.female1478=Gina\nname.female1479=Ginette\nname.female1480=Ginger\nname.female1481=Ginny\nname.female1482=Giovanna\nname.female1483=Gisela\nname.female1484=Gisele\nname.female1485=Giselle\nname.female1486=Gita\nname.female1487=Giuseppina\nname.female1488=Gladis\nname.female1489=Glady\nname.female1490=Gladys\nname.female1491=Glayds\nname.female1492=Glenda\nname.female1493=Glendora\nname.female1494=Glenn\nname.female1495=Glenna\nname.female1496=Glennie\nname.female1497=Glennis\nname.female1498=Glinda\nname.female1499=Gloria\nname.female1500=Glory\nname.female1501=Glynda\nname.female1502=Glynis\nname.female1503=Golda\nname.female1504=Golden\nname.female1505=Goldie\nname.female1506=Grace\nname.female1507=Gracia\nname.female1508=Gracie\nname.female1509=Graciela\nname.female1510=Grayce\nname.female1511=Grazyna\nname.female1512=Gregoria\nname.female1513=Gregory\nname.female1514=Greta\nname.female1515=Gretchen\nname.female1516=Gretta\nname.female1517=Gricelda\nname.female1518=Grisel\nname.female1519=Griselda\nname.female1520=Guadalupe\nname.female1521=Gudrun\nname.female1522=Guillermina\nname.female1523=Gurpreet\nname.female1524=Gussie\nname.female1525=Gwen\nname.female1526=Gwenda\nname.female1527=Gwendolyn\nname.female1528=Gwenn\nname.female1529=Gwyn\nname.female1530=Gwyneth\nname.female1531=Hae\nname.female1532=Hailey\nname.female1533=Haley\nname.female1534=Halina\nname.female1535=Halley\nname.female1536=Hallie\nname.female1537=Han\nname.female1538=Hana\nname.female1539=Hang\nname.female1540=Hanh\nname.female1541=Hanna\nname.female1542=Hannah\nname.female1543=Hannelore\nname.female1544=Harmony\nname.female1545=Harold\nname.female1546=Harriet\nname.female1547=Harriett\nname.female1548=Harriette\nname.female1549=Hassie\nname.female1550=Hattie\nname.female1551=Haydee\nname.female1552=Hayley\nname.female1553=Haylie-Anne\nname.female1554=Hazel\nname.female1555=Heather\nname.female1556=Hedwig\nname.female1557=Hedy\nname.female1558=Heide\nname.female1559=Heidi\nname.female1560=Heidy\nname.female1561=Heike\nname.female1562=Helaine\nname.female1563=Helen\nname.female1564=Helena\nname.female1565=Helene\nname.female1566=Helga\nname.female1567=Hellen\nname.female1568=Henrietta\nname.female1569=Henriette\nname.female1570=Henry\nname.female1571=Herlinda\nname.female1572=Herma\nname.female1573=Hermelinda\nname.female1574=Hermila\nname.female1575=Hermina\nname.female1576=Hermine\nname.female1577=Herminia\nname.female1578=Herta\nname.female1579=Hertha\nname.female1580=Hester\nname.female1581=Hettie\nname.female1582=Hiedi\nname.female1583=Hien\nname.female1584=Hilaria\nname.female1585=Hilary\nname.female1586=Hilda\nname.female1587=Hilde\nname.female1588=Hildegard\nname.female1589=Hildegarde\nname.female1590=Hildred\nname.female1591=Hillary\nname.female1592=Hilma\nname.female1593=Hiroko\nname.female1594=Hisako\nname.female1595=Hoa\nname.female1596=Holley\nname.female1597=Holli\nname.female1598=Hollie\nname.female1599=Hollis\nname.female1600=Holly\nname.female1601=Honey\nname.female1602=Hong\nname.female1603=Hope\nname.female1604=Hortencia\nname.female1605=Hortense\nname.female1606=Hortensia\nname.female1607=Hsiu\nname.female1608=Hue\nname.female1609=Hui\nname.female1610=Hulda\nname.female1611=Huong\nname.female1612=Hyacinth\nname.female1613=Hyo\nname.female1614=Hyon\nname.female1615=Hyun\nname.female1616=Ida\nname.female1617=Idalia\nname.female1618=Idell\nname.female1619=Idella\nname.female1620=Iesha\nname.female1621=Ignacia\nname.female1622=Ila\nname.female1623=Ilana\nname.female1624=Ilda\nname.female1625=Ileana\nname.female1626=Ileen\nname.female1627=Ilene\nname.female1628=Iliana\nname.female1629=Illa\nname.female1630=Ilona\nname.female1631=Ilse\nname.female1632=Iluminada\nname.female1633=Ima\nname.female1634=Imelda\nname.female1635=Imogen\nname.female1636=Imogene\nname.female1637=Ina\nname.female1638=India\nname.female1639=Indigo\nname.female1640=Indira\nname.female1641=Inell\nname.female1642=Ines\nname.female1643=Inez\nname.female1644=Inga\nname.female1645=Inge\nname.female1646=Ingeborg\nname.female1647=Inger\nname.female1648=Ingrid\nname.female1649=Inocencia\nname.female1650=Iola\nname.female1651=Iona\nname.female1652=Ione\nname.female1653=Ira\nname.female1654=Iraida\nname.female1655=Irena\nname.female1656=Irene\nname.female1657=Irina\nname.female1658=Iris\nname.female1659=Irish\nname.female1660=Irma\nname.female1661=Irmgard\nname.female1662=Isa\nname.female1663=Isabel\nname.female1664=Isabell\nname.female1665=Isabella\nname.female1666=Isabelle\nname.female1667=Isadora\nname.female1668=Isaura\nname.female1669=Isela\nname.female1670=Isidra\nname.female1671=Isis\nname.female1672=Isobel\nname.female1673=Iva\nname.female1674=Ivana\nname.female1675=Ivelisse\nname.female1676=Ivette\nname.female1677=Ivey\nname.female1678=Ivonne\nname.female1679=Ivory\nname.female1680=Ivy\nname.female1681=Izetta\nname.female1682=Izola\nname.female1683=Jacalyn\nname.female1684=Jacelyn\nname.female1685=Jacinda\nname.female1686=Jacinta\nname.female1687=Jack\nname.female1688=Jackeline\nname.female1689=Jackelyn\nname.female1690=Jacki\nname.female1691=Jackie\nname.female1692=Jacklyn\nname.female1693=Jackqueline\nname.female1694=Jaclyn\nname.female1695=Jacqualine\nname.female1696=Jacque\nname.female1697=Jacquelin\nname.female1698=Jacqueline\nname.female1699=Jacquelyn\nname.female1700=Jacquelyne\nname.female1701=Jacquelynn\nname.female1702=Jacquetta\nname.female1703=Jacqui\nname.female1704=Jacquie\nname.female1705=Jacquiline\nname.female1706=Jacquline\nname.female1707=Jacqulyn\nname.female1708=Jada\nname.female1709=Jade\nname.female1710=Jadwiga\nname.female1711=Jae\nname.female1712=Jaime\nname.female1713=Jaimee\nname.female1714=Jaimie\nname.female1715=Jaleesa\nname.female1716=Jalisa\nname.female1717=Jama\nname.female1718=Jame\nname.female1719=Jamee\nname.female1720=James\nname.female1721=Jamey\nname.female1722=Jami\nname.female1723=Jamie\nname.female1724=Jamika\nname.female1725=Jamila\nname.female1726=Jammie\nname.female1727=Jan\nname.female1728=Jana\nname.female1729=Janae\nname.female1730=Janay\nname.female1731=Jane\nname.female1732=Janean\nname.female1733=Janee\nname.female1734=Janeen\nname.female1735=Janel\nname.female1736=Janell\nname.female1737=Janella\nname.female1738=Janelle\nname.female1739=Janene\nname.female1740=Janessa\nname.female1741=Janet\nname.female1742=Janeth\nname.female1743=Janett\nname.female1744=Janetta\nname.female1745=Janette\nname.female1746=Janey\nname.female1747=Jani\nname.female1748=Janice\nname.female1749=Janie\nname.female1750=Janiece\nname.female1751=Janina\nname.female1752=Janine\nname.female1753=Janis\nname.female1754=Janise\nname.female1755=Janita\nname.female1756=Jann\nname.female1757=Janna\nname.female1758=Jannet\nname.female1759=Jannette\nname.female1760=Jannie\nname.female1761=January\nname.female1762=Janyce\nname.female1763=Jaqueline\nname.female1764=Jaquelyn\nname.female1765=Jasmin\nname.female1766=Jasmine\nname.female1767=Jason\nname.female1768=Jassie\nname.female1769=Jaunita\nname.female1770=Jay\nname.female1771=Jaye\nname.female1772=Jayme\nname.female1773=Jaymie\nname.female1774=Jayna\nname.female1775=Jayne\nname.female1776=Jazmin\nname.female1777=Jazmine\nname.female1778=Jean\nname.female1779=Jeana\nname.female1780=Jeane\nname.female1781=Jeanelle\nname.female1782=Jeanene\nname.female1783=Jeanett\nname.female1784=Jeanetta\nname.female1785=Jeanette\nname.female1786=Jeanice\nname.female1787=Jeanie\nname.female1788=Jeanine\nname.female1789=Jeanmarie\nname.female1790=Jeanna\nname.female1791=Jeanne\nname.female1792=Jeannetta\nname.female1793=Jeannette\nname.female1794=Jeannie\nname.female1795=Jeannine\nname.female1796=Jeffie\nname.female1797=Jeffrey\nname.female1798=Jen\nname.female1799=Jena\nname.female1800=Jenae\nname.female1801=Jene\nname.female1802=Jenee\nname.female1803=Jenell\nname.female1804=Jenelle\nname.female1805=Jenette\nname.female1806=Jeneva\nname.female1807=Jeni\nname.female1808=Jenice\nname.female1809=Jenifer\nname.female1810=Jeniffer\nname.female1811=Jenine\nname.female1812=Jenise\nname.female1813=Jenna\nname.female1814=Jennefer\nname.female1815=Jennell\nname.female1816=Jennette\nname.female1817=Jenni\nname.female1818=Jennie\nname.female1819=Jennifer\nname.female1820=Jenniffer\nname.female1821=Jennine\nname.female1822=Jenny\nname.female1823=Jeraldine\nname.female1824=Jeremy\nname.female1825=Jeri\nname.female1826=Jerica\nname.female1827=Jerilyn\nname.female1828=Jerlene\nname.female1829=Jerri\nname.female1830=Jerrica\nname.female1831=Jerrie\nname.female1832=Jerry\nname.female1833=Jesenia\nname.female1834=Jesica\nname.female1835=Jesse\nname.female1836=Jessenia\nname.female1837=Jessi\nname.female1838=Jessia\nname.female1839=Jessica\nname.female1840=Jessie\nname.female1841=Jessika\nname.female1842=Jessimine\nname.female1843=Jestine\nname.female1844=Jesus\nname.female1845=Jesusa\nname.female1846=Jesusita\nname.female1847=Jetta\nname.female1848=Jettie\nname.female1849=Jewel\nname.female1850=Jewell\nname.female1851=Jill\nname.female1852=Jillian\nname.female1853=Jimmie\nname.female1854=Jimmy\nname.female1855=Jin\nname.female1856=Jina\nname.female1857=Jinny\nname.female1858=Joan\nname.female1859=Joana\nname.female1860=Joane\nname.female1861=Joanie\nname.female1862=Joann\nname.female1863=Joanna\nname.female1864=Joanne\nname.female1865=Joannie\nname.female1866=Joaquina\nname.female1867=Jocelyn\nname.female1868=Jodee\nname.female1869=Jodi\nname.female1870=Jodie\nname.female1871=Jody\nname.female1872=Joeann\nname.female1873=Joel\nname.female1874=Joella\nname.female1875=Joelle\nname.female1876=Joellen\nname.female1877=Joetta\nname.female1878=Joette\nname.female1879=Joey\nname.female1880=Johana\nname.female1881=Johanna\nname.female1882=Johanne\nname.female1883=John\nname.female1884=Johna\nname.female1885=Johnetta\nname.female1886=Johnette\nname.female1887=Johnie\nname.female1888=Johnna\nname.female1889=Johnnie\nname.female1890=Johnny\nname.female1891=Johnsie\nname.female1892=Joie\nname.female1893=Jolanda\nname.female1894=Joleen\nname.female1895=Jolene\nname.female1896=Jolie\nname.female1897=Joline\nname.female1898=Jolyn\nname.female1899=Jolynn\nname.female1900=Jona\nname.female1901=Jone\nname.female1902=Jonell\nname.female1903=Jonelle\nname.female1904=Jong\nname.female1905=Joni\nname.female1906=Jonie\nname.female1907=Jonna\nname.female1908=Jonnie\nname.female1909=Jordan\nname.female1910=Jose\nname.female1911=Josefa\nname.female1912=Josefina\nname.female1913=Josefine\nname.female1914=Joselyn\nname.female1915=Joseph\nname.female1916=Josephina\nname.female1917=Josephine\nname.female1918=Josette\nname.female1919=Joshua\nname.female1920=Josie\nname.female1921=Joslyn\nname.female1922=Josphine\nname.female1923=Jovan\nname.female1924=Jovita\nname.female1925=Joy\nname.female1926=Joya\nname.female1927=Joyce\nname.female1928=Joycelyn\nname.female1929=Joye\nname.female1930=Juan\nname.female1931=Juana\nname.female1932=Juanita\nname.female1933=Jubilee\nname.female1934=Jude\nname.female1935=Judi\nname.female1936=Judie\nname.female1937=Judith\nname.female1938=Judy\nname.female1939=Jule\nname.female1940=Julee\nname.female1941=Julene\nname.female1942=Juli\nname.female1943=Julia\nname.female1944=Julian\nname.female1945=Juliana\nname.female1946=Juliane\nname.female1947=Juliann\nname.female1948=Julianna\nname.female1949=Julianne\nname.female1950=Julie\nname.female1951=Julieann\nname.female1952=Julienne\nname.female1953=Juliet\nname.female1954=Julieta\nname.female1955=Julietta\nname.female1956=Juliette\nname.female1957=Julio\nname.female1958=Julissa\nname.female1959=June\nname.female1960=Jung\nname.female1961=Junie\nname.female1962=Junita\nname.female1963=Junko\nname.female1964=Justa\nname.female1965=Justin\nname.female1966=Justina\nname.female1967=Justine\nname.female1968=Jutta\nname.female1969=Kacey\nname.female1970=Kaci\nname.female1971=Kacie\nname.female1972=Kacy\nname.female1973=Kai\nname.female1974=Kaila\nname.female1975=Kaitlin\nname.female1976=Kaitlyn\nname.female1977=Kala\nname.female1978=Kaleigh\nname.female1979=Kaley\nname.female1980=Kali\nname.female1981=Kallie\nname.female1982=Kalyn\nname.female1983=Kamala\nname.female1984=Kami\nname.female1985=Kamilah\nname.female1986=Kandace\nname.female1987=Kandi\nname.female1988=Kandice\nname.female1989=Kandis\nname.female1990=Kandra\nname.female1991=Kandy\nname.female1992=Kanesha\nname.female1993=Kanisha\nname.female1994=Kara\nname.female1995=Kara-May\nname.female1996=Karan\nname.female1997=Kareen\nname.female1998=Karen\nname.female1999=Karena\nname.female2000=Karey\nname.female2001=Kari\nname.female2002=Karie\nname.female2003=Karima\nname.female2004=Karin\nname.female2005=Karina\nname.female2006=Karine\nname.female2007=Karisa\nname.female2008=Karissa\nname.female2009=Karl\nname.female2010=Karla\nname.female2011=Karleen\nname.female2012=Karlene\nname.female2013=Karly\nname.female2014=Karlyn\nname.female2015=Karma\nname.female2016=Karmen\nname.female2017=Karol\nname.female2018=Karole\nname.female2019=Karoline\nname.female2020=Karolyn\nname.female2021=Karon\nname.female2022=Karren\nname.female2023=Karri\nname.female2024=Karrie\nname.female2025=Karry\nname.female2026=Kary\nname.female2027=Karyl\nname.female2028=Karyn\nname.female2029=Kasandra\nname.female2030=Kasey\nname.female2031=Kasha\nname.female2032=Kasi\nname.female2033=Kasie\nname.female2034=Kassandra\nname.female2035=Kassie\nname.female2036=Kate\nname.female2037=Katelin\nname.female2038=Katelyn\nname.female2039=Katelynn\nname.female2040=Katerine\nname.female2041=Kathaleen\nname.female2042=Katharina\nname.female2043=Katharine\nname.female2044=Katharyn\nname.female2045=Kathe\nname.female2046=Katheleen\nname.female2047=Katherin\nname.female2048=Katherina\nname.female2049=Katherine\nname.female2050=Kathern\nname.female2051=Katheryn\nname.female2052=Kathey\nname.female2053=Kathi\nname.female2054=Kathie\nname.female2055=Kathleen\nname.female2056=Kathlene\nname.female2057=Kathline\nname.female2058=Kathlyn\nname.female2059=Kathrin\nname.female2060=Kathrine\nname.female2061=Kathryn\nname.female2062=Kathryne\nname.female2063=Kathy\nname.female2064=Kathyrn\nname.female2065=Kati\nname.female2066=Katia\nname.female2067=Katie\nname.female2068=Katina\nname.female2069=Katlyn\nname.female2070=Katrice\nname.female2071=Katrina\nname.female2072=Kattie\nname.female2073=Katy\nname.female2074=Kay\nname.female2075=Kayce\nname.female2076=Kaycee\nname.female2077=Kaye\nname.female2078=Kayla\nname.female2079=Kaylee\nname.female2080=Kayleen\nname.female2081=Kayleigh\nname.female2082=Kaylene\nname.female2083=Kazuko\nname.female2084=Kecia\nname.female2085=Keeley\nname.female2086=Keely\nname.female2087=Keena\nname.female2088=Keesha\nname.female2089=Keiko\nname.female2090=Keila\nname.female2091=Keira\nname.female2092=Keisha\nname.female2093=Keith\nname.female2094=Keitha\nname.female2095=Keli\nname.female2096=Kelle\nname.female2097=Kellee\nname.female2098=Kelley\nname.female2099=Kelli\nname.female2100=Kellie\nname.female2101=Kelly\nname.female2102=Kellye\nname.female2103=Kelsey\nname.female2104=Kelsi\nname.female2105=Kelsie\nname.female2106=Kemberly\nname.female2107=Kena\nname.female2108=Kenda\nname.female2109=Kendal\nname.female2110=Kendall\nname.female2111=Kendra\nname.female2112=Kenia\nname.female2113=Kenisha\nname.female2114=Kenna\nname.female2115=Kenneth\nname.female2116=Kenya\nname.female2117=Kenyatta\nname.female2118=Kenyetta\nname.female2119=Kera\nname.female2120=Keren\nname.female2121=Keri\nname.female2122=Kerri\nname.female2123=Kerrie\nname.female2124=Kerry\nname.female2125=Kerstin\nname.female2126=Kesha\nname.female2127=Keshia\nname.female2128=Keturah\nname.female2129=Keva\nname.female2130=Kevin\nname.female2131=Khadijah\nname.female2132=Khalilah\nname.female2133=Kia\nname.female2134=Kiana\nname.female2135=Kiara\nname.female2136=Kiera\nname.female2137=Kiersten\nname.female2138=Kiesha\nname.female2139=Kiley\nname.female2140=Kim\nname.female2141=Kimber\nname.female2142=Kimberely\nname.female2143=Kimberlee\nname.female2144=Kimberley\nname.female2145=Kimberli\nname.female2146=Kimberlie\nname.female2147=Kimberly\nname.female2148=Kimbery\nname.female2149=Kimbra\nname.female2150=Kimi\nname.female2151=Kimiko\nname.female2152=Kina\nname.female2153=Kindra\nname.female2154=Kira\nname.female2155=Kirby\nname.female2156=Kirsten\nname.female2157=Kirstie\nname.female2158=Kirstin\nname.female2159=Kisha\nname.female2160=Kit\nname.female2161=Kittie\nname.female2162=Kitty\nname.female2163=Kiyoko\nname.female2164=Kizzie\nname.female2165=Kizzy\nname.female2166=Klara\nname.female2167=Kori\nname.female2168=Kortney\nname.female2169=Kourtney\nname.female2170=Kris\nname.female2171=Krishna\nname.female2172=Krissy\nname.female2173=Krista\nname.female2174=Kristal\nname.female2175=Kristan\nname.female2176=Kristeen\nname.female2177=Kristel\nname.female2178=Kristen\nname.female2179=Kristi\nname.female2180=Kristian\nname.female2181=Kristie\nname.female2182=Kristin\nname.female2183=Kristina\nname.female2184=Kristine\nname.female2185=Kristle\nname.female2186=Kristy\nname.female2187=Kristyn\nname.female2188=Krysta\nname.female2189=Krystal\nname.female2190=Krysten\nname.female2191=Krystin\nname.female2192=Krystina\nname.female2193=Krystle\nname.female2194=Krystyna\nname.female2195=Kyla\nname.female2196=Kyle\nname.female2197=Kylee\nname.female2198=Kylie\nname.female2199=Kymberly\nname.female2200=Kyoko\nname.female2201=Kyong\nname.female2202=Kyra\nname.female2203=Kyung\nname.female2204=Lacey\nname.female2205=Lachelle\nname.female2206=Laci\nname.female2207=Lacie\nname.female2208=Lacresha\nname.female2209=Lacy\nname.female2210=Ladawn\nname.female2211=Ladonna\nname.female2212=Lady\nname.female2213=Lael\nname.female2214=Lahoma\nname.female2215=Lai\nname.female2216=Laila\nname.female2217=Laine\nname.female2218=Lajuana\nname.female2219=Lakeesha\nname.female2220=Lakeisha\nname.female2221=Lakendra\nname.female2222=Lakenya\nname.female2223=Lakesha\nname.female2224=Lakeshia\nname.female2225=Lakia\nname.female2226=Lakiesha\nname.female2227=Lakisha\nname.female2228=Lakita\nname.female2229=Lala\nname.female2230=Lamonica\nname.female2231=Lan\nname.female2232=Lana\nname.female2233=Lane\nname.female2234=Lanell\nname.female2235=Lanelle\nname.female2236=Lanette\nname.female2237=Lang\nname.female2238=Lani\nname.female2239=Lanie\nname.female2240=Lanita\nname.female2241=Lannie\nname.female2242=Lanora\nname.female2243=Laquanda\nname.female2244=Laquita\nname.female2245=Lara\nname.female2246=Larae\nname.female2247=Laraine\nname.female2248=Laree\nname.female2249=Larhonda\nname.female2250=Larisa\nname.female2251=Larissa\nname.female2252=Larita\nname.female2253=Laronda\nname.female2254=Larraine\nname.female2255=Larry\nname.female2256=Larue\nname.female2257=Lasandra\nname.female2258=Lashanda\nname.female2259=Lashandra\nname.female2260=Lashaun\nname.female2261=Lashaunda\nname.female2262=Lashawn\nname.female2263=Lashawna\nname.female2264=Lashawnda\nname.female2265=Lashay\nname.female2266=Lashell\nname.female2267=Lashon\nname.female2268=Lashonda\nname.female2269=Lashunda\nname.female2270=Lasonya\nname.female2271=Latanya\nname.female2272=Latarsha\nname.female2273=Latasha\nname.female2274=Latashia\nname.female2275=Latesha\nname.female2276=Latia\nname.female2277=Laticia\nname.female2278=Latina\nname.female2279=Latisha\nname.female2280=Latonia\nname.female2281=Latonya\nname.female2282=Latoria\nname.female2283=Latosha\nname.female2284=Latoya\nname.female2285=Latoyia\nname.female2286=Latrice\nname.female2287=Latricia\nname.female2288=Latrina\nname.female2289=Latrisha\nname.female2290=Launa\nname.female2291=Laura\nname.female2292=Lauralee\nname.female2293=Lauran\nname.female2294=Laure\nname.female2295=Laureen\nname.female2296=Laurel\nname.female2297=Lauren\nname.female2298=Laurena\nname.female2299=Laurence\nname.female2300=Laurene\nname.female2301=Lauretta\nname.female2302=Laurette\nname.female2303=Lauri\nname.female2304=Laurice\nname.female2305=Laurie\nname.female2306=Laurinda\nname.female2307=Laurine\nname.female2308=Lauryn\nname.female2309=Lavada\nname.female2310=Lavelle\nname.female2311=Lavenia\nname.female2312=Lavera\nname.female2313=Lavern\nname.female2314=Laverna\nname.female2315=Laverne\nname.female2316=Laveta\nname.female2317=Lavette\nname.female2318=Lavina\nname.female2319=Lavinia\nname.female2320=Lavon\nname.female2321=Lavona\nname.female2322=Lavonda\nname.female2323=Lavone\nname.female2324=Lavonia\nname.female2325=Lavonna\nname.female2326=Lavonne\nname.female2327=Lawana\nname.female2328=Lawanda\nname.female2329=Lawanna\nname.female2330=Lawrence\nname.female2331=Layla\nname.female2332=Layne\nname.female2333=Lea\nname.female2334=Leah\nname.female2335=Lean\nname.female2336=Leana\nname.female2337=Leandra\nname.female2338=Leann\nname.female2339=Leanna\nname.female2340=Leanne\nname.female2341=Leanora\nname.female2342=Leatha\nname.female2343=Leatrice\nname.female2344=Lecia\nname.female2345=Leda\nname.female2346=Lee\nname.female2347=Leeann\nname.female2348=Leeanna\nname.female2349=Leeanne\nname.female2350=Leena\nname.female2351=Leesa\nname.female2352=Leia\nname.female2353=Leida\nname.female2354=Leigh\nname.female2355=Leigha\nname.female2356=Leighann\nname.female2357=Leila\nname.female2358=Leilani\nname.female2359=Leisa\nname.female2360=Leisha\nname.female2361=Lekisha\nname.female2362=Lela\nname.female2363=Lelah\nname.female2364=Lelia\nname.female2365=Lena\nname.female2366=Lenita\nname.female2367=Lenna\nname.female2368=Lennie\nname.female2369=Lenora\nname.female2370=Lenore\nname.female2371=Leola\nname.female2372=Leoma\nname.female2373=Leon\nname.female2374=Leona\nname.female2375=Leonarda\nname.female2376=Leone\nname.female2377=Leonia\nname.female2378=Leonida\nname.female2379=Leonie\nname.female2380=Leonila\nname.female2381=Leonor\nname.female2382=Leonora\nname.female2383=Leonore\nname.female2384=Leontine\nname.female2385=Leora\nname.female2386=Leota\nname.female2387=Lera\nname.female2388=Lesa\nname.female2389=Lesha\nname.female2390=Lesia\nname.female2391=Leslee\nname.female2392=Lesley\nname.female2393=Lesli\nname.female2394=Leslie\nname.female2395=Leslie-Annie\nname.female2396=Lessie\nname.female2397=Lester\nname.female2398=Leta\nname.female2399=Letha\nname.female2400=Leticia\nname.female2401=Letisha\nname.female2402=Letitia\nname.female2403=Lettie\nname.female2404=Letty\nname.female2405=Lewis\nname.female2406=Lexie\nname.female2407=Lezlie\nname.female2408=Lia\nname.female2409=Liana\nname.female2410=Liane\nname.female2411=Lianne\nname.female2412=Libbie\nname.female2413=Libby\nname.female2414=Liberty\nname.female2415=Librada\nname.female2416=Lida\nname.female2417=Lidia\nname.female2418=Lidya\nname.female2419=Lien\nname.female2420=Lieselotte\nname.female2421=Ligia\nname.female2422=Lila\nname.female2423=Lili\nname.female2424=Lilia\nname.female2425=Lilian\nname.female2426=Liliana\nname.female2427=Lilith\nname.female2428=Lilla\nname.female2429=Lilli\nname.female2430=Lillia\nname.female2431=Lilliam\nname.female2432=Lillian\nname.female2433=Lilliana\nname.female2434=Lillie\nname.female2435=Lilly\nname.female2436=Lily\nname.female2437=Lin\nname.female2438=Lina\nname.female2439=Linda\nname.female2440=Lindsay\nname.female2441=Lindsey\nname.female2442=Lindsy\nname.female2443=Lindy\nname.female2444=Linette\nname.female2445=Ling\nname.female2446=Linh\nname.female2447=Linn\nname.female2448=Linnea\nname.female2449=Linnie\nname.female2450=Linsey\nname.female2451=Lisa\nname.female2452=Lisabeth\nname.female2453=Lisandra\nname.female2454=Lisbeth\nname.female2455=Lise\nname.female2456=Lisette\nname.female2457=Lisha\nname.female2458=Lissa\nname.female2459=Lissette\nname.female2460=Lita\nname.female2461=Livia\nname.female2462=Liz\nname.female2463=Liza\nname.female2464=Lizabeth\nname.female2465=Lizbeth\nname.female2466=Lizeth\nname.female2467=Lizette\nname.female2468=Lizzette\nname.female2469=Lizzie\nname.female2470=Lizzy\nname.female2471=Loan\nname.female2472=Logan\nname.female2473=Loida\nname.female2474=Lois\nname.female2475=Loise\nname.female2476=Lola\nname.female2477=Lolita\nname.female2478=Loma\nname.female2479=Lona\nname.female2480=Londa\nname.female2481=London\nname.female2482=Loni\nname.female2483=Lonna\nname.female2484=Lonnie\nname.female2485=Lora\nname.female2486=Loraine\nname.female2487=Loralee\nname.female2488=Lore\nname.female2489=Lorean\nname.female2490=Loree\nname.female2491=Loreen\nname.female2492=Lorelei\nname.female2493=Loren\nname.female2494=Lorena\nname.female2495=Lorene\nname.female2496=Lorenza\nname.female2497=Loreta\nname.female2498=Loretta\nname.female2499=Lorette\nname.female2500=Lori\nname.female2501=Loria\nname.female2502=Loriann\nname.female2503=Lorie\nname.female2504=Lorilee\nname.female2505=Lorina\nname.female2506=Lorinda\nname.female2507=Lorine\nname.female2508=Loris\nname.female2509=Lorita\nname.female2510=Lorna\nname.female2511=Lorraine\nname.female2512=Lorretta\nname.female2513=Lorri\nname.female2514=Lorriane\nname.female2515=Lorrie\nname.female2516=Lorrine\nname.female2517=Lory\nname.female2518=Lottie\nname.female2519=Lotus\nname.female2520=Louann\nname.female2521=Louanne\nname.female2522=Louella\nname.female2523=Louetta\nname.female2524=Louie\nname.female2525=Louis\nname.female2526=Louisa\nname.female2527=Louise\nname.female2528=Loura\nname.female2529=Lourdes\nname.female2530=Lourie\nname.female2531=Louvenia\nname.female2532=Love\nname.female2533=Lovella\nname.female2534=Lovetta\nname.female2535=Lovie\nname.female2536=Loyce\nname.female2537=Luana\nname.female2538=Luann\nname.female2539=Luanna\nname.female2540=Luanne\nname.female2541=Luba\nname.female2542=Luci\nname.female2543=Lucia\nname.female2544=Luciana\nname.female2545=Lucie\nname.female2546=Lucienne\nname.female2547=Lucila\nname.female2548=Lucile\nname.female2549=Lucilla\nname.female2550=Lucille\nname.female2551=Lucina\nname.female2552=Lucinda\nname.female2553=Lucine\nname.female2554=Lucrecia\nname.female2555=Lucretia\nname.female2556=Lucy\nname.female2557=Ludie\nname.female2558=Ludivina\nname.female2559=Lue\nname.female2560=Luella\nname.female2561=Luetta\nname.female2562=Luis\nname.female2563=Luisa\nname.female2564=Luise\nname.female2565=Lula\nname.female2566=Lulu\nname.female2567=Luna\nname.female2568=Lupe\nname.female2569=Lupita\nname.female2570=Lura\nname.female2571=Lurlene\nname.female2572=Lurline\nname.female2573=Luvenia\nname.female2574=Lyda\nname.female2575=Lydia\nname.female2576=Lyla\nname.female2577=Lyn\nname.female2578=Lynda\nname.female2579=Lyndia\nname.female2580=Lyndsay\nname.female2581=Lyndsey\nname.female2582=Lynell\nname.female2583=Lynelle\nname.female2584=Lynetta\nname.female2585=Lynette\nname.female2586=Lynn\nname.female2587=Lynna\nname.female2588=Lynne\nname.female2589=Lynnette\nname.female2590=Lynsey\nname.female2591=Lyric\nname.female2592=Mabel\nname.female2593=Mabelle\nname.female2594=Mable\nname.female2595=Macey\nname.female2596=Machelle\nname.female2597=Maci\nname.female2598=Macie\nname.female2599=Mackenzie\nname.female2600=Macy\nname.female2601=Madalene\nname.female2602=Madaline\nname.female2603=Madalyn\nname.female2604=Maddie\nname.female2605=Madelaine\nname.female2606=Madeleine\nname.female2607=Madelene\nname.female2608=Madeline\nname.female2609=Madelyn\nname.female2610=Madge\nname.female2611=Madie\nname.female2612=Madison\nname.female2613=Madlyn\nname.female2614=Madonna\nname.female2615=Mae\nname.female2616=Maegan\nname.female2617=Mafalda\nname.female2618=Magali\nname.female2619=Magaly\nname.female2620=Magan\nname.female2621=Magaret\nname.female2622=Magda\nname.female2623=Magdalen\nname.female2624=Magdalena\nname.female2625=Magdalene\nname.female2626=Magen\nname.female2627=Maggie\nname.female2628=Magnolia\nname.female2629=Mahalia\nname.female2630=Mai\nname.female2631=Maia\nname.female2632=Maida\nname.female2633=Maile\nname.female2634=Maira\nname.female2635=Maire\nname.female2636=Maisha\nname.female2637=Maisie\nname.female2638=Majorie\nname.female2639=Makeda\nname.female2640=Malana\nname.female2641=Malena\nname.female2642=Malia\nname.female2643=Malika\nname.female2644=Malinda\nname.female2645=Malisa\nname.female2646=Malissa\nname.female2647=Malka\nname.female2648=Mallie\nname.female2649=Mallory\nname.female2650=Malorie\nname.female2651=Malvina\nname.female2652=Mamie\nname.female2653=Mammie\nname.female2654=Mana\nname.female2655=Manda\nname.female2656=Mandi\nname.female2657=Mandie\nname.female2658=Mandy\nname.female2659=Manie\nname.female2660=Manuela\nname.female2661=Many\nname.female2662=Mao\nname.female2663=Maple\nname.female2664=Mara\nname.female2665=Maragaret\nname.female2666=Maragret\nname.female2667=Maranda\nname.female2668=Marcela\nname.female2669=Marcelene\nname.female2670=Marcelina\nname.female2671=Marceline\nname.female2672=Marcell\nname.female2673=Marcella\nname.female2674=Marcelle\nname.female2675=Marcene\nname.female2676=Marchelle\nname.female2677=Marci\nname.female2678=Marcia\nname.female2679=Marcie\nname.female2680=Marcy\nname.female2681=Mardell\nname.female2682=Maren\nname.female2683=Marg\nname.female2684=Margaret\nname.female2685=Margareta\nname.female2686=Margarete\nname.female2687=Margarett\nname.female2688=Margaretta\nname.female2689=Margarette\nname.female2690=Margarita\nname.female2691=Margarite\nname.female2692=Margart\nname.female2693=Marge\nname.female2694=Margene\nname.female2695=Margeret\nname.female2696=Margert\nname.female2697=Margery\nname.female2698=Marget\nname.female2699=Margherita\nname.female2700=Margie\nname.female2701=Margit\nname.female2702=Margo\nname.female2703=Margorie\nname.female2704=Margot\nname.female2705=Margret\nname.female2706=Margrett\nname.female2707=Marguerita\nname.female2708=Marguerite\nname.female2709=Margurite\nname.female2710=Margy\nname.female2711=Marhta\nname.female2712=Mari\nname.female2713=Maria\nname.female2714=Mariah\nname.female2715=Mariam\nname.female2716=Marian\nname.female2717=Mariana\nname.female2718=Marianela\nname.female2719=Mariann\nname.female2720=Marianna\nname.female2721=Marianne\nname.female2722=Maribel\nname.female2723=Maribeth\nname.female2724=Marica\nname.female2725=Maricela\nname.female2726=Maricruz\nname.female2727=Marie\nname.female2728=Mariel\nname.female2729=Mariela\nname.female2730=Mariella\nname.female2731=Marielle\nname.female2732=Marietta\nname.female2733=Mariette\nname.female2734=Mariko\nname.female2735=Marilee\nname.female2736=Marilou\nname.female2737=Marilu\nname.female2738=Marilyn\nname.female2739=Marilynn\nname.female2740=Marin\nname.female2741=Marina\nname.female2742=Marinda\nname.female2743=Marine\nname.female2744=Mario\nname.female2745=Marion\nname.female2746=Marioth\nname.female2747=Maris\nname.female2748=Marisa\nname.female2749=Marisela\nname.female2750=Marisha\nname.female2751=Marisol\nname.female2752=Marissa\nname.female2753=Marita\nname.female2754=Maritza\nname.female2755=Marivel\nname.female2756=Marjorie\nname.female2757=Marjory\nname.female2758=Mark\nname.female2759=Marketta\nname.female2760=Markita\nname.female2761=Marla\nname.female2762=Marlana\nname.female2763=Marleen\nname.female2764=Marlen\nname.female2765=Marlena\nname.female2766=Marlene\nname.female2767=Marlin\nname.female2768=Marline\nname.female2769=Marlo\nname.female2770=Marlyn\nname.female2771=Marlys\nname.female2772=Marna\nname.female2773=Marni\nname.female2774=Marnie\nname.female2775=Marquerite\nname.female2776=Marquetta\nname.female2777=Marquita\nname.female2778=Marquitta\nname.female2779=Marry\nname.female2780=Marsha\nname.female2781=Marshall\nname.female2782=Marta\nname.female2783=Marth\nname.female2784=Martha\nname.female2785=Marti\nname.female2786=Martin\nname.female2787=Martina\nname.female2788=Martine\nname.female2789=Marty\nname.female2790=Marva\nname.female2791=Marvel\nname.female2792=Marvella\nname.female2793=Marvis\nname.female2794=Marx\nname.female2795=Mary\nname.female2796=Mary-Anne\nname.female2797=Marya\nname.female2798=Maryalice\nname.female2799=Maryam\nname.female2800=Maryann\nname.female2801=Maryanna\nname.female2802=Maryanne\nname.female2803=Marybelle\nname.female2804=Marybeth\nname.female2805=Maryellen\nname.female2806=Maryetta\nname.female2807=Maryjane\nname.female2808=Maryjo\nname.female2809=Maryland\nname.female2810=Marylee\nname.female2811=Marylin\nname.female2812=Maryln\nname.female2813=Marylou\nname.female2814=Marylouise\nname.female2815=Marylyn\nname.female2816=Marylynn\nname.female2817=Maryrose\nname.female2818=Masako\nname.female2819=Matha\nname.female2820=Mathilda\nname.female2821=Mathilde\nname.female2822=Matilda\nname.female2823=Matilde\nname.female2824=Matthew\nname.female2825=Mattie\nname.female2826=Maud\nname.female2827=Maude\nname.female2828=Maudie\nname.female2829=Maura\nname.female2830=Maureen\nname.female2831=Maurice\nname.female2832=Maurine\nname.female2833=Maurita\nname.female2834=Mavis\nname.female2835=Maxie\nname.female2836=Maxima\nname.female2837=Maximina\nname.female2838=Maxine\nname.female2839=May\nname.female2840=Maya\nname.female2841=Maybell\nname.female2842=Maybelle\nname.female2843=Mayberry\nname.female2844=Maye\nname.female2845=Mayflower\nname.female2846=Mayme\nname.female2847=Mayola\nname.female2848=Mayra\nname.female2849=Mazie\nname.female2850=Mckenzie\nname.female2851=Meagan\nname.female2852=Meaghan\nname.female2853=Mechelle\nname.female2854=Meda\nname.female2855=Meg\nname.female2856=Megan\nname.female2857=Meggan\nname.female2858=Meghan\nname.female2859=Meghann\nname.female2860=Mei\nname.female2861=Melaine\nname.female2862=Melani\nname.female2863=Melania\nname.female2864=Melanie\nname.female2865=Melany\nname.female2866=Melba\nname.female2867=Melda\nname.female2868=Melia\nname.female2869=Melida\nname.female2870=Melina\nname.female2871=Melinda\nname.female2872=Melisa\nname.female2873=Melissa\nname.female2874=Melissia\nname.female2875=Melita\nname.female2876=Mellie\nname.female2877=Mellisa\nname.female2878=Mellissa\nname.female2879=Melodee\nname.female2880=Melodi\nname.female2881=Melodie\nname.female2882=Melody\nname.female2883=Melonie\nname.female2884=Melony\nname.female2885=Melva\nname.female2886=Melvin\nname.female2887=Melvina\nname.female2888=Melynda\nname.female2889=Mendy\nname.female2890=Mercedes\nname.female2891=Mercedez\nname.female2892=Mercy\nname.female2893=Meredith\nname.female2894=Meri\nname.female2895=Merideth\nname.female2896=Meridith\nname.female2897=Merilyn\nname.female2898=Merissa\nname.female2899=Merle\nname.female2900=Merlene\nname.female2901=Merlyn\nname.female2902=Merna\nname.female2903=Merri\nname.female2904=Merrie\nname.female2905=Merrilee\nname.female2906=Merrill\nname.female2907=Merry\nname.female2908=Mertie\nname.female2909=Meryl\nname.female2910=Meta\nname.female2911=Mia\nname.female2912=Mica\nname.female2913=Micaela\nname.female2914=Micah\nname.female2915=Micha\nname.female2916=Michael\nname.female2917=Michaela\nname.female2918=Michaele\nname.female2919=Michal\nname.female2920=Micheal\nname.female2921=Michel\nname.female2922=Michele\nname.female2923=Michelina\nname.female2924=Micheline\nname.female2925=Michell\nname.female2926=Michelle\nname.female2927=Michiko\nname.female2928=Mickey\nname.female2929=Micki\nname.female2930=Mickie\nname.female2931=Miesha\nname.female2932=Migdalia\nname.female2933=Mignon\nname.female2934=Miguelina\nname.female2935=Mika\nname.female2936=Mikaela\nname.female2937=Mike\nname.female2938=Miki\nname.female2939=Mikki\nname.female2940=Mila\nname.female2941=Milagro\nname.female2942=Milagros\nname.female2943=Milda\nname.female2944=Mildred\nname.female2945=Milissa\nname.female2946=Millicent\nname.female2947=Millie\nname.female2948=Milly\nname.female2949=Mimi\nname.female2950=Min\nname.female2951=Mina\nname.female2952=Minda\nname.female2953=Mindi\nname.female2954=Mindy\nname.female2955=Minerva\nname.female2956=Ming\nname.female2957=Minh\nname.female2958=Minna\nname.female2959=Minnie\nname.female2960=Minta\nname.female2961=Mira\nname.female2962=Miranda\nname.female2963=Mireille\nname.female2964=Mirella\nname.female2965=Mireya\nname.female2966=Miriam\nname.female2967=Mirian\nname.female2968=Mirna\nname.female2969=Mirta\nname.female2970=Mirtha\nname.female2971=Misha\nname.female2972=Miss\nname.female2973=Missy\nname.female2974=Misti\nname.female2975=Mistie\nname.female2976=Misty\nname.female2977=Mitchell\nname.female2978=Mitsue\nname.female2979=Mitsuko\nname.female2980=Mittie\nname.female2981=Mitzi\nname.female2982=Mitzie\nname.female2983=Miyoko\nname.female2984=Modesta\nname.female2985=Moira\nname.female2986=Mollie\nname.female2987=Molly\nname.female2988=Mona\nname.female2989=Monet\nname.female2990=Monica\nname.female2991=Monika\nname.female2992=Monique\nname.female2993=Monnie\nname.female2994=Monserrate\nname.female2995=Moon\nname.female2996=Mora\nname.female2997=Morgan\nname.female2998=Morgana\nname.female2999=Moriah\nname.female3000=Mozell\nname.female3001=Mozella\nname.female3002=Mozelle\nname.female3003=Mui\nname.female3004=Muoi\nname.female3005=Muriel\nname.female3006=Mya\nname.female3007=Myesha\nname.female3008=Myong\nname.female3009=Myra\nname.female3010=Myriam\nname.female3011=Myrl\nname.female3012=Myrle\nname.female3013=Myrna\nname.female3014=Myrta\nname.female3015=Myrtice\nname.female3016=Myrtie\nname.female3017=Myrtis\nname.female3018=Myrtle\nname.female3019=Myung\nname.female3020=Nada\nname.female3021=Nadene\nname.female3022=Nadia\nname.female3023=Nadine\nname.female3024=Naida\nname.female3025=Nakesha\nname.female3026=Nakia\nname.female3027=Nakisha\nname.female3028=Nakita\nname.female3029=Nam\nname.female3030=Nan\nname.female3031=Nana\nname.female3032=Nancee\nname.female3033=Nancey\nname.female3034=Nanci\nname.female3035=Nancie\nname.female3036=Nancy\nname.female3037=Nanette\nname.female3038=Nani\nname.female3039=Nannette\nname.female3040=Nannie\nname.female3041=Naoma\nname.female3042=Naomi\nname.female3043=Narcisa\nname.female3044=Natacha\nname.female3045=Natalia\nname.female3046=Natalie\nname.female3047=Natalya\nname.female3048=Natasha\nname.female3049=Natashia\nname.female3050=Nathalie\nname.female3051=Natisha\nname.female3052=Natividad\nname.female3053=Natosha\nname.female3054=Necole\nname.female3055=Neda\nname.female3056=Nedra\nname.female3057=Neely\nname.female3058=Neida\nname.female3059=Nelda\nname.female3060=Nelia\nname.female3061=Nelida\nname.female3062=Nell\nname.female3063=Nella\nname.female3064=Nelle\nname.female3065=Nellie\nname.female3066=Nelly\nname.female3067=Nena\nname.female3068=Nenita\nname.female3069=Neoma\nname.female3070=Neomi\nname.female3071=Nereida\nname.female3072=Nerissa\nname.female3073=Nery\nname.female3074=Neta\nname.female3075=Nettie\nname.female3076=Neva\nname.female3077=Nevada\nname.female3078=Ngan\nname.female3079=Ngoc\nname.female3080=Nguyet\nname.female3081=Nia\nname.female3082=Nichelle\nname.female3083=Nichol\nname.female3084=Nichole\nname.female3085=Nicholle\nname.female3086=Nicki\nname.female3087=Nickie\nname.female3088=Nickole\nname.female3089=Nicky\nname.female3090=Nicol\nname.female3091=Nicola\nname.female3092=Nicolasa\nname.female3093=Nicole\nname.female3094=Nicolette\nname.female3095=Nicolle\nname.female3096=Nida\nname.female3097=Nidia\nname.female3098=Niesha\nname.female3099=Nieves\nname.female3100=Niki\nname.female3101=Nikia\nname.female3102=Nikita\nname.female3103=Nikki\nname.female3104=Nikole\nname.female3105=Nila\nname.female3106=Nilda\nname.female3107=Nilsa\nname.female3108=Nina\nname.female3109=Ninfa\nname.female3110=Nisha\nname.female3111=Nita\nname.female3112=Nobuko\nname.female3113=Noel\nname.female3114=Noelia\nname.female3115=Noella\nname.female3116=Noelle\nname.female3117=Noemi\nname.female3118=Nohemi\nname.female3119=Nola\nname.female3120=Noma\nname.female3121=Nona\nname.female3122=Nora\nname.female3123=Norah\nname.female3124=Noreen\nname.female3125=Norene\nname.female3126=Noriko\nname.female3127=Norine\nname.female3128=Norma\nname.female3129=Norman\nname.female3130=Nova\nname.female3131=Novella\nname.female3132=Nubia\nname.female3133=Numbers\nname.female3134=Nydia\nname.female3135=Nyla\nname.female3136=Obdulia\nname.female3137=Ocie\nname.female3138=Octavia\nname.female3139=Oda\nname.female3140=Odelia\nname.female3141=Odell\nname.female3142=Odessa\nname.female3143=Odette\nname.female3144=Odilia\nname.female3145=Ofelia\nname.female3146=Ola\nname.female3147=Olene\nname.female3148=Oleta\nname.female3149=Olevia\nname.female3150=Olga\nname.female3151=Olimpia\nname.female3152=Olinda\nname.female3153=Oliva\nname.female3154=Olive\nname.female3155=Olivia\nname.female3156=Ollie\nname.female3157=Olympia\nname.female3158=Oma\nname.female3159=Omega\nname.female3160=Ona\nname.female3161=Oneida\nname.female3162=Onie\nname.female3163=Onita\nname.female3164=Opal\nname.female3165=Ophelia\nname.female3166=Ora\nname.female3167=Oralee\nname.female3168=Oralia\nname.female3169=Oretha\nname.female3170=Orpha\nname.female3171=Oscar\nname.female3172=Ossie\nname.female3173=Otelia\nname.female3174=Otha\nname.female3175=Otilia\nname.female3176=Ouida\nname.female3177=Ozell\nname.female3178=Ozella\nname.female3179=Ozie\nname.female3180=Page\nname.female3181=Paige\nname.female3182=Palma\nname.female3183=Palmira\nname.female3184=Pam\nname.female3185=Pamala\nname.female3186=Pamela\nname.female3187=Pamela-May\nname.female3188=Pamelia\nname.female3189=Pamella\nname.female3190=Pamila\nname.female3191=Pamula\nname.female3192=Pandora\nname.female3193=Pansy\nname.female3194=Paola\nname.female3195=Paris\nname.female3196=Parthenia\nname.female3197=Particia\nname.female3198=Pasty\nname.female3199=Pat\nname.female3200=Patience\nname.female3201=Patria\nname.female3202=Patrica\nname.female3203=Patrice\nname.female3204=Patricia\nname.female3205=Patrick\nname.female3206=Patrina\nname.female3207=Patsy\nname.female3208=Patti\nname.female3209=Pattie\nname.female3210=Patty\nname.female3211=Paul\nname.female3212=Paula\nname.female3213=Paulene\nname.female3214=Pauletta\nname.female3215=Paulette\nname.female3216=Paulina\nname.female3217=Pauline\nname.female3218=Paulita\nname.female3219=Paysley\nname.female3220=Paz\nname.female3221=Pearl\nname.female3222=Pearle\nname.female3223=Pearlene\nname.female3224=Pearlie\nname.female3225=Pearline\nname.female3226=Pearly\nname.female3227=Peg\nname.female3228=Peggie\nname.female3229=Peggy\nname.female3230=Pei\nname.female3231=Penelope\nname.female3232=Penney\nname.female3233=Penni\nname.female3234=Pennie\nname.female3235=Penny\nname.female3236=Peony\nname.female3237=Perla\nname.female3238=Perry\nname.female3239=Petal\nname.female3240=Peter\nname.female3241=Petra\nname.female3242=Petrina\nname.female3243=Petronila\nname.female3244=Petunia\nname.female3245=Phebe\nname.female3246=Phillis\nname.female3247=Philomena\nname.female3248=Phoebe\nname.female3249=Phung\nname.female3250=Phuong\nname.female3251=Phylicia\nname.female3252=Phylis\nname.female3253=Phyliss\nname.female3254=Phyllis\nname.female3255=Pia\nname.female3256=Piedad\nname.female3257=Pilar\nname.female3258=Ping\nname.female3259=Pinkie\nname.female3260=Piper\nname.female3261=Pok\nname.female3262=Polly\nname.female3263=Poppy\nname.female3264=Porsche\nname.female3265=Porsha\nname.female3266=Portia\nname.female3267=Precious\nname.female3268=Presley\nname.female3269=Pricilla\nname.female3270=Princess\nname.female3271=Priscila\nname.female3272=Priscilla\nname.female3273=Providencia\nname.female3274=Prudence\nname.female3275=Pura\nname.female3276=Qiana\nname.female3277=Queen\nname.female3278=Queenie\nname.female3279=Quiana\nname.female3280=Quinn\nname.female3281=Quyen\nname.female3282=Rachael\nname.female3283=Rachal\nname.female3284=Racheal\nname.female3285=Rachel\nname.female3286=Rachele\nname.female3287=Rachell\nname.female3288=Rachelle\nname.female3289=Racquel\nname.female3290=Rae\nname.female3291=Raeann\nname.female3292=Raelene\nname.female3293=Rafaela\nname.female3294=Raguel\nname.female3295=Raina\nname.female3296=Raisa\nname.female3297=Ramona\nname.female3298=Ramonita\nname.female3299=Rana\nname.female3300=Ranae\nname.female3301=Randa\nname.female3302=Randee\nname.female3303=Randi\nname.female3304=Randy\nname.female3305=Ranee\nname.female3306=Raquel\nname.female3307=Rasheeda\nname.female3308=Rashida\nname.female3309=Raven\nname.female3310=Ray\nname.female3311=Ray-Annie\nname.female3312=Raye\nname.female3313=Raylene\nname.female3314=Raymond\nname.female3315=Raymonde\nname.female3316=Rayna\nname.female3317=Rayne\nname.female3318=Reagan\nname.female3319=Reanna\nname.female3320=Reatha\nname.female3321=Reba\nname.female3322=Rebbeca\nname.female3323=Rebbecca\nname.female3324=Rebeca\nname.female3325=Rebecca\nname.female3326=Rebecka\nname.female3327=Rebekah\nname.female3328=Reda\nname.female3329=Reena\nname.female3330=Refugia\nname.female3331=Refugio\nname.female3332=Regan\nname.female3333=Regena\nname.female3334=Regenia\nname.female3335=Regina\nname.female3336=Regine\nname.female3337=Reginia\nname.female3338=Reiko\nname.female3339=Reina\nname.female3340=Reita\nname.female3341=Rema\nname.female3342=Remedios\nname.female3343=Remona\nname.female3344=Rena\nname.female3345=Renae\nname.female3346=Renata\nname.female3347=Renate\nname.female3348=Renay\nname.female3349=Renda\nname.female3350=Rene\nname.female3351=Renea\nname.female3352=Renee\nname.female3353=Renetta\nname.female3354=Renita\nname.female3355=Renna\nname.female3356=Ressie\nname.female3357=Reta\nname.female3358=Retha\nname.female3359=Retta\nname.female3360=Reva\nname.female3361=Reyna\nname.female3362=Reynalda\nname.female3363=Rhea\nname.female3364=Rheba\nname.female3365=Rhiannon\nname.female3366=Rhoda\nname.female3367=Rhona\nname.female3368=Rhonda\nname.female3369=Ria\nname.female3370=Ricarda\nname.female3371=Richard\nname.female3372=Richelle\nname.female3373=Ricki\nname.female3374=Rickie\nname.female3375=Rikki\nname.female3376=Rima\nname.female3377=Rina\nname.female3378=Risa\nname.female3379=Rita\nname.female3380=Riva\nname.female3381=Rivka\nname.female3382=Robbi\nname.female3383=Robbie\nname.female3384=Robbin\nname.female3385=Robbyn\nname.female3386=Robena\nname.female3387=Robert\nname.female3388=Roberta\nname.female3389=Roberto\nname.female3390=Robin\nname.female3391=Robyn\nname.female3392=Rochel\nname.female3393=Rochell\nname.female3394=Rochelle\nname.female3395=Rocio\nname.female3396=Rolanda\nname.female3397=Rolande\nname.female3398=Roma\nname.female3399=Romaine\nname.female3400=Romana\nname.female3401=Romelia\nname.female3402=Romona\nname.female3403=Rona\nname.female3404=Ronald\nname.female3405=Ronda\nname.female3406=Roni\nname.female3407=Ronna\nname.female3408=Ronni\nname.female3409=Ronnie\nname.female3410=Rory\nname.female3411=Rosa\nname.female3412=Rosalba\nname.female3413=Rosalee\nname.female3414=Rosalia\nname.female3415=Rosalie\nname.female3416=Rosalina\nname.female3417=Rosalind\nname.female3418=Rosalinda\nname.female3419=Rosaline\nname.female3420=Rosalva\nname.female3421=Rosalyn\nname.female3422=Rosamaria\nname.female3423=Rosamond\nname.female3424=Rosana\nname.female3425=Rosann\nname.female3426=Rosanna\nname.female3427=Rosanne\nname.female3428=Rosaria\nname.female3429=Rosario\nname.female3430=Rosaura\nname.female3431=Rose\nname.female3432=Roseann\nname.female3433=Roseanna\nname.female3434=Roseanne\nname.female3435=Roselee\nname.female3436=Roselia\nname.female3437=Roseline\nname.female3438=Rosella\nname.female3439=Roselle\nname.female3440=Roselyn\nname.female3441=Rosemarie\nname.female3442=Rosemary\nname.female3443=Rosena\nname.female3444=Rosenda\nname.female3445=Rosetta\nname.female3446=Rosette\nname.female3447=Rosia\nname.female3448=Rosie\nname.female3449=Rosina\nname.female3450=Rosio\nname.female3451=Rosita\nname.female3452=Roslyn\nname.female3453=Rossana\nname.female3454=Rossie\nname.female3455=Rosy\nname.female3456=Rowena\nname.female3457=Roxana\nname.female3458=Roxane\nname.female3459=Roxann\nname.female3460=Roxanna\nname.female3461=Roxanne\nname.female3462=Roxie\nname.female3463=Roxy\nname.female3464=Roy\nname.female3465=Royce\nname.female3466=Rozanne\nname.female3467=Rozella\nname.female3468=Rubi\nname.female3469=Rubie\nname.female3470=Ruby\nname.female3471=Rubye\nname.female3472=Rudy\nname.female3473=Rufina\nname.female3474=Russell\nname.female3475=Ruth\nname.female3476=Rutha\nname.female3477=Ruthann\nname.female3478=Ruthanne\nname.female3479=Ruthe\nname.female3480=Ruthie\nname.female3481=Ryan\nname.female3482=Ryann\nname.female3483=Sabina\nname.female3484=Sabine\nname.female3485=Sabra\nname.female3486=Sabrina\nname.female3487=Sacha\nname.female3488=Sachiko\nname.female3489=Sade\nname.female3490=Sadie\nname.female3491=Sadye\nname.female3492=Saffron\nname.female3493=Sage\nname.female3494=Salena\nname.female3495=Salina\nname.female3496=Salley\nname.female3497=Sallie\nname.female3498=Sally\nname.female3499=Salome\nname.female3500=Sam\nname.female3501=Samantha\nname.female3502=Samara\nname.female3503=Samatha\nname.female3504=Samella\nname.female3505=Samira\nname.female3506=Sammie\nname.female3507=Sammy\nname.female3508=Samuel\nname.female3509=Sana\nname.female3510=Sanda\nname.female3511=Sandee\nname.female3512=Sandi\nname.female3513=Sandie\nname.female3514=Sandra\nname.female3515=Sandy\nname.female3516=Sang\nname.female3517=Sanjuana\nname.female3518=Sanjuanita\nname.female3519=Sanora\nname.female3520=Santa\nname.female3521=Santana\nname.female3522=Santina\nname.female3523=Santos\nname.female3524=Sapphire\nname.female3525=Sara\nname.female3526=Sarah\nname.female3527=Sarai\nname.female3528=Saran\nname.female3529=Sari\nname.female3530=Sarina\nname.female3531=Sarita\nname.female3532=Sasha\nname.female3533=Saturnina\nname.female3534=Sau\nname.female3535=Saundra\nname.female3536=Savanna\nname.female3537=Savannah\nname.female3538=Scarlet\nname.female3539=Scarlett\nname.female3540=Scott\nname.female3541=Scottie\nname.female3542=Sean\nname.female3543=Season\nname.female3544=Sebrina\nname.female3545=Seema\nname.female3546=Selena\nname.female3547=Selene\nname.female3548=Selina\nname.female3549=Selma\nname.female3550=Sena\nname.female3551=Senaida\nname.female3552=September\nname.female3553=Serafina\nname.female3554=Serena\nname.female3555=Serina\nname.female3556=Serita\nname.female3557=Setsuko\nname.female3558=Sha\nname.female3559=Shae\nname.female3560=Shaina\nname.female3561=Shakia\nname.female3562=Shakira\nname.female3563=Shakita\nname.female3564=Shala\nname.female3565=Shalanda\nname.female3566=Shalon\nname.female3567=Shalonda\nname.female3568=Shameka\nname.female3569=Shamika\nname.female3570=Shan\nname.female3571=Shana\nname.female3572=Shanae\nname.female3573=Shanda\nname.female3574=Shandi\nname.female3575=Shandra\nname.female3576=Shane\nname.female3577=Shaneka\nname.female3578=Shanel\nname.female3579=Shanell\nname.female3580=Shanelle\nname.female3581=Shani\nname.female3582=Shanice\nname.female3583=Shanika\nname.female3584=Shaniqua\nname.female3585=Shanita\nname.female3586=Shanna\nname.female3587=Shannan\nname.female3588=Shannon\nname.female3589=Shanon\nname.female3590=Shanta\nname.female3591=Shantae\nname.female3592=Shantay\nname.female3593=Shante\nname.female3594=Shantel\nname.female3595=Shantell\nname.female3596=Shantelle\nname.female3597=Shanti\nname.female3598=Shaquana\nname.female3599=Shaquita\nname.female3600=Shara\nname.female3601=Sharan\nname.female3602=Sharda\nname.female3603=Sharee\nname.female3604=Sharell\nname.female3605=Sharen\nname.female3606=Shari\nname.female3607=Sharice\nname.female3608=Sharie\nname.female3609=Sharika\nname.female3610=Sharilyn\nname.female3611=Sharita\nname.female3612=Sharla\nname.female3613=Sharleen\nname.female3614=Sharlene\nname.female3615=Sharmaine\nname.female3616=Sharolyn\nname.female3617=Sharon\nname.female3618=Sharonda\nname.female3619=Sharri\nname.female3620=Sharron\nname.female3621=Sharyl\nname.female3622=Sharyn\nname.female3623=Shasta\nname.female3624=Shaun\nname.female3625=Shauna\nname.female3626=Shaunda\nname.female3627=Shaunna\nname.female3628=Shaunta\nname.female3629=Shaunte\nname.female3630=Shavon\nname.female3631=Shavonda\nname.female3632=Shavonne\nname.female3633=Shawana\nname.female3634=Shawanda\nname.female3635=Shawanna\nname.female3636=Shawn\nname.female3637=Shawna\nname.female3638=Shawnda\nname.female3639=Shawnee\nname.female3640=Shawnna\nname.female3641=Shawnta\nname.female3642=Shawny\nname.female3643=Shay\nname.female3644=Shayla\nname.female3645=Shayna\nname.female3646=Shayne\nname.female3647=Shea\nname.female3648=Sheba\nname.female3649=Sheena\nname.female3650=Sheila\nname.female3651=Sheilah\nname.female3652=Shela\nname.female3653=Shelba\nname.female3654=Shelby\nname.female3655=Shelia\nname.female3656=Shella\nname.female3657=Shelley\nname.female3658=Shelli\nname.female3659=Shellie\nname.female3660=Shelly\nname.female3661=Shemeka\nname.female3662=Shemika\nname.female3663=Shena\nname.female3664=Shenika\nname.female3665=Shenita\nname.female3666=Shenna\nname.female3667=Shera\nname.female3668=Sheree\nname.female3669=Sherell\nname.female3670=Sheri\nname.female3671=Sherice\nname.female3672=Sheridan\nname.female3673=Sherie\nname.female3674=Sherika\nname.female3675=Sherill\nname.female3676=Sherilyn\nname.female3677=Sherise\nname.female3678=Sherita\nname.female3679=Sherlene\nname.female3680=Sherley\nname.female3681=Sherly\nname.female3682=Sherlyn\nname.female3683=Sheron\nname.female3684=Sherrell\nname.female3685=Sherri\nname.female3686=Sherrie\nname.female3687=Sherril\nname.female3688=Sherrill\nname.female3689=Sherron\nname.female3690=Sherry\nname.female3691=Sherryl\nname.female3692=Shery\nname.female3693=Sheryl\nname.female3694=Sheryll\nname.female3695=Shiela\nname.female3696=Shila\nname.female3697=Shiloh\nname.female3698=Shin\nname.female3699=Shira\nname.female3700=Shirely\nname.female3701=Shirl\nname.female3702=Shirlee\nname.female3703=Shirleen\nname.female3704=Shirlene\nname.female3705=Shirley\nname.female3706=Shirly\nname.female3707=Shizue\nname.female3708=Shizuko\nname.female3709=Shona\nname.female3710=Shonda\nname.female3711=Shondra\nname.female3712=Shonna\nname.female3713=Shonta\nname.female3714=Shoshana\nname.female3715=Shu\nname.female3716=Shyla\nname.female3717=Sibyl\nname.female3718=Sidney\nname.female3719=Sierra\nname.female3720=Signe\nname.female3721=Sigrid\nname.female3722=Silva\nname.female3723=Silvana\nname.female3724=Silvia\nname.female3725=Sima\nname.female3726=Simona\nname.female3727=Simone\nname.female3728=Simonne\nname.female3729=Sina\nname.female3730=Sindy\nname.female3731=Siobhan\nname.female3732=Sirena\nname.female3733=Siu\nname.female3734=Sixta\nname.female3735=Skye\nname.female3736=Slyvia\nname.female3737=Socorro\nname.female3738=Sofia\nname.female3739=Soila\nname.female3740=Sol\nname.female3741=Solange\nname.female3742=Soledad\nname.female3743=Somer\nname.female3744=Sommer\nname.female3745=Son\nname.female3746=Sona\nname.female3747=Sondra\nname.female3748=Song\nname.female3749=Sonia\nname.female3750=Sonja\nname.female3751=Sonya\nname.female3752=Soo\nname.female3753=Sook\nname.female3754=Soon\nname.female3755=Sophia\nname.female3756=Sophie\nname.female3757=Soraya\nname.female3758=Sparkle\nname.female3759=Spring\nname.female3760=Stacee\nname.female3761=Stacey\nname.female3762=Staci\nname.female3763=Stacia\nname.female3764=Stacie\nname.female3765=Stacy\nname.female3766=Star\nname.female3767=Starla\nname.female3768=Starling\nname.female3769=Starr\nname.female3770=Stasia\nname.female3771=Stefani\nname.female3772=Stefania\nname.female3773=Stefanie\nname.female3774=Stefany\nname.female3775=Steffanie\nname.female3776=Stella\nname.female3777=Stepanie\nname.female3778=Stephaine\nname.female3779=Stephane\nname.female3780=Stephani\nname.female3781=Stephania\nname.female3782=Stephanie\nname.female3783=Stephany\nname.female3784=Stephen\nname.female3785=Stephenie\nname.female3786=Stephine\nname.female3787=Stephnie\nname.female3788=Steven\nname.female3789=Stevie\nname.female3790=Stormy\nname.female3791=Suanne\nname.female3792=Sudie\nname.female3793=Sue\nname.female3794=Sueann\nname.female3795=Suellen\nname.female3796=Suk\nname.female3797=Sulema\nname.female3798=Sumiko\nname.female3799=Summer\nname.female3800=Sun\nname.female3801=Sunday\nname.female3802=Sung\nname.female3803=Sunni\nname.female3804=Sunny\nname.female3805=Sunshine\nname.female3806=Susan\nname.female3807=Susana\nname.female3808=Susann\nname.female3809=Susanna\nname.female3810=Susannah\nname.female3811=Susanne\nname.female3812=Susie\nname.female3813=Susy\nname.female3814=Suzan\nname.female3815=Suzann\nname.female3816=Suzanna\nname.female3817=Suzanne\nname.female3818=Suzette\nname.female3819=Suzi\nname.female3820=Suzie\nname.female3821=Suzy\nname.female3822=Svetlana\nname.female3823=Sybil\nname.female3824=Syble\nname.female3825=Sydney\nname.female3826=Sylvia\nname.female3827=Sylvie\nname.female3828=Synthia\nname.female3829=Syreeta\nname.female3830=Tabatha\nname.female3831=Tabetha\nname.female3832=Tabitha\nname.female3833=Tai\nname.female3834=Taina\nname.female3835=Taisha\nname.female3836=Tajuana\nname.female3837=Takako\nname.female3838=Takisha\nname.female3839=Talia\nname.female3840=Talisha\nname.female3841=Talitha\nname.female3842=Tally\nname.female3843=Tam\nname.female3844=Tama\nname.female3845=Tamala\nname.female3846=Tamar\nname.female3847=Tamara\nname.female3848=Tamatha\nname.female3849=Tambra\nname.female3850=Tameika\nname.female3851=Tameka\nname.female3852=Tamekia\nname.female3853=Tamela\nname.female3854=Tamera\nname.female3855=Tamesha\nname.female3856=Tami\nname.female3857=Tamica\nname.female3858=Tamie\nname.female3859=Tamika\nname.female3860=Tamiko\nname.female3861=Tamisha\nname.female3862=Tammara\nname.female3863=Tammera\nname.female3864=Tammi\nname.female3865=Tammie\nname.female3866=Tammy\nname.female3867=Tamra\nname.female3868=Tana\nname.female3869=Tandra\nname.female3870=Tandy\nname.female3871=Taneka\nname.female3872=Tanesha\nname.female3873=Tangela\nname.female3874=Tania\nname.female3875=Tanika\nname.female3876=Tanisha\nname.female3877=Tanja\nname.female3878=Tanna\nname.female3879=Tansy\nname.female3880=Tanya\nname.female3881=Tara\nname.female3882=Tarah\nname.female3883=Taren\nname.female3884=Tari\nname.female3885=Tarra\nname.female3886=Tarsha\nname.female3887=Taryn\nname.female3888=Tasha\nname.female3889=Tashia\nname.female3890=Tashina\nname.female3891=Tasia\nname.female3892=Tatiana\nname.female3893=Tatum\nname.female3894=Tatyana\nname.female3895=Taunya\nname.female3896=Tawana\nname.female3897=Tawanda\nname.female3898=Tawanna\nname.female3899=Tawna\nname.female3900=Tawny\nname.female3901=Tawnya\nname.female3902=Taylor\nname.female3903=Tayna\nname.female3904=Teena\nname.female3905=Tegan\nname.female3906=Teisha\nname.female3907=Telma\nname.female3908=Temeka\nname.female3909=Temika\nname.female3910=Tempie\nname.female3911=Temple\nname.female3912=Tena\nname.female3913=Tenesha\nname.female3914=Tenisha\nname.female3915=Tennie\nname.female3916=Tennille\nname.female3917=Teodora\nname.female3918=Teofila\nname.female3919=Tequila\nname.female3920=Tera\nname.female3921=Tereasa\nname.female3922=Teresa\nname.female3923=Terese\nname.female3924=Teresia\nname.female3925=Teresita\nname.female3926=Teressa\nname.female3927=Teri\nname.female3928=Terica\nname.female3929=Terina\nname.female3930=Terisa\nname.female3931=Terra\nname.female3932=Terrell\nname.female3933=Terresa\nname.female3934=Terri\nname.female3935=Terrie\nname.female3936=Terrilyn\nname.female3937=Terry\nname.female3938=Tesha\nname.female3939=Tess\nname.female3940=Tessa\nname.female3941=Tessie\nname.female3942=Thalia\nname.female3943=Thanh\nname.female3944=Thao\nname.female3945=Thea\nname.female3946=Theda\nname.female3947=Thelma\nname.female3948=Theo\nname.female3949=Theodora\nname.female3950=Theola\nname.female3951=Theresa\nname.female3952=Therese\nname.female3953=Theresia\nname.female3954=Theressa\nname.female3955=Thersa\nname.female3956=Thi\nname.female3957=Thomas\nname.female3958=Thomasena\nname.female3959=Thomasina\nname.female3960=Thomasine\nname.female3961=Thora\nname.female3962=Thresa\nname.female3963=Thuy\nname.female3964=Tia\nname.female3965=Tiana\nname.female3966=Tianna\nname.female3967=Tiara\nname.female3968=Tien\nname.female3969=Tiera\nname.female3970=Tierra\nname.female3971=Tiesha\nname.female3972=Tifany\nname.female3973=Tiff\nname.female3974=Tiffaney\nname.female3975=Tiffani\nname.female3976=Tiffanie\nname.female3977=Tiffany\nname.female3978=Tiffiny\nname.female3979=Tijuana\nname.female3980=Tilda\nname.female3981=Tillie\nname.female3982=Timika\nname.female3983=Timothy\nname.female3984=Tina\nname.female3985=Tinisha\nname.female3986=Tiny\nname.female3987=Tisa\nname.female3988=Tish\nname.female3989=Tisha\nname.female3990=Tobi\nname.female3991=Tobie\nname.female3992=Toby\nname.female3993=Toccara\nname.female3994=Toi\nname.female3995=Tomasa\nname.female3996=Tomeka\nname.female3997=Tomi\nname.female3998=Tomika\nname.female3999=Tomiko\nname.female4000=Tommie\nname.female4001=Tommy\nname.female4002=Tommye\nname.female4003=Tomoko\nname.female4004=Tona\nname.female4005=Tonda\nname.female4006=Tonette\nname.female4007=Toni\nname.female4008=Tonia\nname.female4009=Tonie\nname.female4010=Tonisha\nname.female4011=Tonita\nname.female4012=Tonja\nname.female4013=Tony\nname.female4014=Tonya\nname.female4015=Topaz\nname.female4016=Tora\nname.female4017=Tori\nname.female4018=Torie\nname.female4019=Torri\nname.female4020=Torrie\nname.female4021=Tory\nname.female4022=Tosha\nname.female4023=Toshia\nname.female4024=Toshiko\nname.female4025=Tova\nname.female4026=Towanda\nname.female4027=Toya\nname.female4028=Tracee\nname.female4029=Tracey\nname.female4030=Traci\nname.female4031=Tracie\nname.female4032=Tracy\nname.female4033=Tran\nname.female4034=Trang\nname.female4035=Travis\nname.female4036=Treasa\nname.female4037=Treena\nname.female4038=Trena\nname.female4039=Tresa\nname.female4040=Tressa\nname.female4041=Tressie\nname.female4042=Treva\nname.female4043=Tricia\nname.female4044=Trina\nname.female4045=Trinh\nname.female4046=Trinidad\nname.female4047=Trinity\nname.female4048=Trish\nname.female4049=Trisha\nname.female4050=Trista\nname.female4051=Tristan\nname.female4052=Troy\nname.female4053=Trudi\nname.female4054=Trudie\nname.female4055=Trudy\nname.female4056=Trula\nname.female4057=Tula\nname.female4058=Tuyet\nname.female4059=Twana\nname.female4060=Twanda\nname.female4061=Twanna\nname.female4062=Twila\nname.female4063=Twyla\nname.female4064=Tyesha\nname.female4065=Tyisha\nname.female4066=Tyler\nname.female4067=Tynisha\nname.female4068=Tyra\nname.female4069=Ula\nname.female4070=Ulrike\nname.female4071=Una\nname.female4072=Unique\nname.female4073=Ursula\nname.female4074=Usha\nname.female4075=Vada\nname.female4076=Val\nname.female4077=Valarie\nname.female4078=Valda\nname.female4079=Valencia\nname.female4080=Valene\nname.female4081=Valentina\nname.female4082=Valentine\nname.female4083=Valeri\nname.female4084=Valeria\nname.female4085=Valerie\nname.female4086=Valery\nname.female4087=Vallie\nname.female4088=Valorie\nname.female4089=Valrie\nname.female4090=Van\nname.female4091=Vanda\nname.female4092=Vanesa\nname.female4093=Vanessa\nname.female4094=Vanetta\nname.female4095=Vania\nname.female4096=Vanita\nname.female4097=Vanna\nname.female4098=Vannesa\nname.female4099=Vannessa\nname.female4100=Vashti\nname.female4101=Vasiliki\nname.female4102=Veda\nname.female4103=Velda\nname.female4104=Velia\nname.female4105=Vella\nname.female4106=Velma\nname.female4107=Velva\nname.female4108=Velvet\nname.female4109=Vena\nname.female4110=Venessa\nname.female4111=Venetta\nname.female4112=Venice\nname.female4113=Venita\nname.female4114=Vennie\nname.female4115=Venus\nname.female4116=Veola\nname.female4117=Vera\nname.female4118=Verda\nname.female4119=Verdell\nname.female4120=Verdie\nname.female4121=Verena\nname.female4122=Vergie\nname.female4123=Verla\nname.female4124=Verlene\nname.female4125=Verlie\nname.female4126=Verline\nname.female4127=Verna\nname.female4128=Vernell\nname.female4129=Vernetta\nname.female4130=Vernia\nname.female4131=Vernice\nname.female4132=Vernie\nname.female4133=Vernita\nname.female4134=Vernon\nname.female4135=Verona\nname.female4136=Veronica\nname.female4137=Veronika\nname.female4138=Veronique\nname.female4139=Versie\nname.female4140=Vertie\nname.female4141=Vesta\nname.female4142=Veta\nname.female4143=Vicenta\nname.female4144=Vickey\nname.female4145=Vicki\nname.female4146=Vickie\nname.female4147=Vicky\nname.female4148=Victor\nname.female4149=Victoria\nname.female4150=Victorina\nname.female4151=Vida\nname.female4152=Viki\nname.female4153=Vikki\nname.female4154=Vilma\nname.female4155=Vina\nname.female4156=Vincenza\nname.female4157=Vinita\nname.female4158=Vinnie\nname.female4159=Viola\nname.female4160=Violet\nname.female4161=Violeta\nname.female4162=Violette\nname.female4163=Virgen\nname.female4164=Virgie\nname.female4165=Virgil\nname.female4166=Virgina\nname.female4167=Virginia\nname.female4168=Vita\nname.female4169=Viva\nname.female4170=Vivan\nname.female4171=Vivian\nname.female4172=Viviana\nname.female4173=Vivien\nname.female4174=Vivienne\nname.female4175=Voncile\nname.female4176=Vonda\nname.female4177=Vonnie\nname.female4178=Wai\nname.female4179=Walter\nname.female4180=Waltraud\nname.female4181=Wan\nname.female4182=Wanda\nname.female4183=Waneta\nname.female4184=Wanetta\nname.female4185=Wanita\nname.female4186=Wava\nname.female4187=Wei\nname.female4188=Wen\nname.female4189=Wendi\nname.female4190=Wendie\nname.female4191=Wendolyn\nname.female4192=Wendy\nname.female4193=Wenona\nname.female4194=Wesley\nname.female4195=Whitley\nname.female4196=Whitney\nname.female4197=Wilda\nname.female4198=Wilhelmina\nname.female4199=Wilhemina\nname.female4200=Willa\nname.female4201=Willena\nname.female4202=Willene\nname.female4203=Willetta\nname.female4204=Willette\nname.female4205=Willia\nname.female4206=William\nname.female4207=Willie\nname.female4208=Williemae\nname.female4209=Willodean\nname.female4210=Willow\nname.female4211=Wilma\nname.female4212=Windy\nname.female4213=Winifred\nname.female4214=Winnie\nname.female4215=Winnifred\nname.female4216=Winona\nname.female4217=Winter\nname.female4218=Wonda\nname.female4219=Wynell\nname.female4220=Wynona\nname.female4221=Xenia\nname.female4222=Xiao\nname.female4223=Xiomara\nname.female4224=Xochitl\nname.female4225=Xuan\nname.female4226=Yadira\nname.female4227=Yaeko\nname.female4228=Yael\nname.female4229=Yahaira\nname.female4230=Yajaira\nname.female4231=Yan\nname.female4232=Yang\nname.female4233=Yanira\nname.female4234=Yasmin\nname.female4235=Yasmine\nname.female4236=Yasuko\nname.female4237=Yelena\nname.female4238=Yen\nname.female4239=Yesenia\nname.female4240=Yessenia\nname.female4241=Yetta\nname.female4242=Yevette\nname.female4243=Ying\nname.female4244=Yoko\nname.female4245=Yolanda\nname.female4246=Yolande\nname.female4247=Yolando\nname.female4248=Yolonda\nname.female4249=Yon\nname.female4250=Yong\nname.female4251=Yoshie\nname.female4252=Yoshiko\nname.female4253=Youlanda\nname.female4254=Young\nname.female4255=Yuette\nname.female4256=Yuk\nname.female4257=Yuki\nname.female4258=Yukiko\nname.female4259=Yuko\nname.female4260=Yulanda\nname.female4261=Yun\nname.female4262=Yung\nname.female4263=Yuonne\nname.female4264=Yuri\nname.female4265=Yuriko\nname.female4266=Yvette\nname.female4267=Yvone\nname.female4268=Yvonne\nname.female4269=Zada\nname.female4270=Zaida\nname.female4271=Zana\nname.female4272=Zandra\nname.female4273=Zelda\nname.female4274=Zella\nname.female4275=Zelma\nname.female4276=Zena\nname.female4277=Zenaida\nname.female4278=Zenia\nname.female4279=Zenobia\nname.female4280=Zetta\nname.female4281=Zina\nname.female4282=Zinnia\nname.female4283=Zita\nname.female4284=Zoe\nname.female4285=Zofia\nname.female4286=Zoila\nname.female4287=Zola\nname.female4288=Zona\nname.female4289=Zonia\nname.female4290=Zora\nname.female4291=Zoraida\nname.female4292=Zula\nname.female4293=Zulema\nname.female4294=Zulma"
  },
  {
    "path": "src/main/resources/assets/mca/models/block/rose_gold_block.json",
    "content": "{\n\t\"parent\": \"block/cube_all\",\n\t\"textures\": {\n\t\t\"all\": \"mca:blocks/rose_gold_block\"\n\t}\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/block/rose_gold_ore.json",
    "content": "{\n\t\"parent\": \"block/cube_all\",\n\t\"textures\": {\n\t\t\"all\": \"mca:blocks/rose_gold_ore\"\n\t}\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/block/villager_spawner.json",
    "content": "{\n\t\"parent\": \"block/cube_all\",\n\t\"textures\": {\n\t\t\"all\": \"mca:blocks/villager_spawner\"\n\t}\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/baby_boy.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/baby_boy\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/baby_girl.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/baby_girl\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/book_death.json",
    "content": "{\n\t\"parent\": \"item/generated\",\n\t\"textures\": {\n\t\t\"layer0\": \"mca:items/book_death\"\n\t}\n}\n"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/book_family.json",
    "content": "{\n\t\"parent\": \"item/generated\",\n\t\"textures\": {\n\t\t\"layer0\": \"mca:items/book_family\"\n\t}\n}\n"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/book_infection.json",
    "content": "{\n\t\"parent\": \"item/generated\",\n\t\"textures\": {\n\t\t\"layer0\": \"mca:items/book_infection\"\n\t}\n}\n"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/book_romance.json",
    "content": "{\n\t\"parent\": \"item/generated\",\n\t\"textures\": {\n\t\t\"layer0\": \"mca:items/book_romance\"\n\t}\n}\n"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/book_rose_gold.json",
    "content": "{\n\t\"parent\": \"item/generated\",\n\t\"textures\": {\n\t\t\"layer0\": \"mca:items/book_rose_gold\"\n\t}\n}\n"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/egg_female.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/egg_female\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/egg_male.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/egg_male\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/engagement_ring.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/engagement_ring\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/engagement_ring_rg.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/engagement_ring_rg\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/gold_dust.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/gold_dust\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/matchmakers_ring.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/matchmakers_ring\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/rose_gold_block.json",
    "content": "{\n  \"parent\": \"mca:block/rose_gold_block\",\n  \"display\": {\n    \"thirdperson\": {\n      \"rotation\": [ 10, -45, 170 ],\n      \"translation\": [ 0, 1.5, -2.75 ],\n      \"scale\": [ 0.375, 0.375, 0.375 ]\n    }\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/rose_gold_dust.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/rose_gold_dust\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/rose_gold_ingot.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/rose_gold_ingot\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/staff_of_life.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/staff_of_life\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/villager_editor.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/villager_editor\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/wedding_ring.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/wedding_ring\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/wedding_ring_rg.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/wedding_ring_rg\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/models/item/whistle.json",
    "content": "{\n  \"parent\": \"item/generated\",\n  \"textures\": {\n    \"layer0\": \"mca:items/whistle\"\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/engagement_ring.json",
    "content": "\n{\n  \"type\": \"minecraft:crafting_shaped\",\n  \"pattern\": [\n    \"GDG\",\n    \"G G\",\n    \"GGG\"\n  ],\n  \"key\": {\n    \"G\": [\n      {\n        \"item\": \"minecraft:gold_ingot\"\n      }\n    ],\n    \"D\": [\n      {\n        \"item\": \"minecraft:diamond\"\n      }\n    ]\n  },\n  \"result\": {\n    \"item\": \"mca:engagement_ring\",\n    \"count\": 1\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/engagement_ring_rg.json",
    "content": "{\n  \"type\": \"minecraft:crafting_shaped\",\n  \"pattern\": [\n    \"GDG\",\n    \"G G\",\n    \"GGG\"\n  ],\n  \"key\": {\n    \"G\": [\n      {\n        \"item\": \"mca:rose_gold_ingot\"\n      }\n    ],\n    \"D\": [\n      {\n        \"item\": \"minecraft:diamond\"\n      }\n    ]\n  },\n  \"result\": {\n    \"item\": \"mca:engagement_ring_rg\",\n    \"count\": 1\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/gold_dust.json",
    "content": "{\n  \"type\": \"minecraft:crafting_shapeless\",\n  \"ingredients\": [\n    {\n      \"item\": \"mca:rose_gold_dust\"\n    },\n    {\n      \"item\": \"minecraft:water_bucket\"\n    }\n  ],\n  \"result\": {\n    \"item\": \"mca:gold_dust\",\n    \"count\": 6\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/gold_nugget_from_dust.json",
    "content": "{\n  \"type\": \"minecraft:crafting_shaped\",\n  \"pattern\": [\n    \"GGG\",\n    \"GGG\",\n    \"GGG\"\n  ],\n  \"key\": {\n    \"G\": [\n      {\n        \"item\": \"mca:gold_dust\"\n      }\n    ]\n  },\n  \"result\": {\n    \"item\": \"minecraft:gold_nugget\",\n    \"count\": 1\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/matchmakers_ring.json",
    "content": "{\n  \"type\": \"minecraft:crafting_shaped\",\n  \"pattern\": [\n    \"III\",\n    \"I I\",\n    \"III\"\n  ],\n  \"key\": {\n    \"I\": [\n      {\n        \"item\": \"minecraft:iron_ingot\"\n      }\n    ]\n  },\n  \"result\": {\n    \"item\": \"mca:matchmakers_ring\",\n    \"count\": 1\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/rose_gold_block.json",
    "content": "{\n  \"type\": \"minecraft:crafting_shaped\",\n  \"pattern\": [\n    \"III\",\n    \"III\",\n    \"III\"\n  ],\n  \"key\": {\n    \"I\": [\n      {\n        \"item\": \"mca:rose_gold_ingot\"\n      }\n    ]\n  },\n  \"result\": {\n    \"item\": \"mca:rose_gold_block\",\n    \"count\": 1\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/rose_gold_dust_from_ingot.json",
    "content": "{\n  \"type\": \"minecraft:crafting_shapeless\",\n  \"ingredients\": [\n    {\n      \"item\": \"mca:rose_gold_ingot\"\n    }\n  ],\n  \"result\": {\n    \"item\": \"mca:rose_gold_dust\",\n    \"count\": 1\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/rose_gold_ingot_from_dust.json",
    "content": "{\n  \"type\": \"minecraft:crafting_shaped\",\n  \"pattern\": [\n    \"GGG\",\n    \"GGG\",\n    \"GGG\"\n  ],\n  \"key\": {\n    \"G\": [\n      {\n        \"item\": \"mca:rose_gold_dust\"\n      }\n    ]\n  },\n  \"result\": {\n    \"item\": \"mca:rose_gold_ingot\",\n    \"count\": 1\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/wedding_ring.json",
    "content": "{\n  \"type\": \"minecraft:crafting_shaped\",\n  \"pattern\": [\n    \"GGG\",\n    \"G G\",\n    \"GGG\"\n  ],\n  \"key\": {\n    \"G\": [\n      {\n        \"item\": \"minecraft:gold_ingot\"\n      }\n    ]\n  },\n  \"result\": {\n    \"item\": \"mca:wedding_ring\",\n    \"count\": 1\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/wedding_ring_rg.json",
    "content": "{\n  \"type\": \"minecraft:crafting_shaped\",\n  \"pattern\": [\n    \"GGG\",\n    \"G G\",\n    \"GGG\"\n  ],\n  \"key\": {\n    \"G\": [\n      {\n        \"item\": \"mca:rose_gold_ingot\"\n      }\n    ]\n  },\n  \"result\": {\n    \"item\": \"mca:wedding_ring_rg\",\n    \"count\": 1\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/recipes/whistle.json",
    "content": "{\n  \"type\": \"minecraft:crafting_shaped\",\n  \"pattern\": [\n    \" W#\",\n    \"###\"\n  ],\n  \"key\": {\n    \"#\": [\n      {\n        \"item\": \"minecraft:iron_ingot\",\n        \"data\": 0\n      }\n    ],\n    \"W\": [\n      {\n        \"item\": \"minecraft:planks\",\n        \"data\": 0\n      },\n      {\n        \"item\": \"minecraft:planks\",\n        \"data\": 1\n      },\n      {\n        \"item\": \"minecraft:planks\",\n        \"data\": 2\n      },\n      {\n        \"item\": \"minecraft:planks\",\n        \"data\": 3\n      },\n      {\n        \"item\": \"minecraft:planks\",\n        \"data\": 4\n      },\n      {\n        \"item\": \"minecraft:planks\",\n        \"data\": 5\n      }\n    ]\n  },\n  \"result\": {\n    \"item\": \"mca:whistle\",\n    \"count\": 1\n  }\n}"
  },
  {
    "path": "src/main/resources/assets/mca/sounds.json",
    "content": "{\n    \"reaper.scythe.out\": { \"category\": \"hostile\", \"subtitle\": \"Draws scythe\", \"sounds\": [ \"mca:reaper-scythe-out\" ] },\n    \"reaper.scythe.swing\": { \"category\": \"hostile\", \"subtitle\": \"Swings scythe\", \"sounds\": [ \"mca:reaper-scythe-swing\" ] },\n    \"reaper.idle\": { \"category\": \"hostile\", \"subtitle\": \"Evil laughter\", \"sounds\": [ \"mca:reaper-idle\" ] },\n    \"reaper.death\": { \"category\": \"hostile\", \"subtitle\": \"Reaper death\", \"sounds\": [ \"mca:reaper-death\" ] },\n    \"reaper.block\": { \"category\": \"hostile\", \"subtitle\": \"Blocked attack\", \"sounds\": [ \"mca:reaper-block\" ] },\n    \"reaper.summon\": { \"category\": \"hostile\", \"subtitle\": \"Evil laughter\", \"sounds\": [ \"mca:reaper-summon\" ] }\n}"
  },
  {
    "path": "src/main/resources/mcmod.info",
    "content": "[\n{\n  \"modid\": \"mca\",\n  \"name\": \"Minecraft Comes Alive\",\n  \"description\": \"Replaces villagers with humans, adds marriage, children, and more!\",\n  \"version\": \"${version}\",\n  \"mcversion\": \"${mcversion}\",\n  \"url\": \"https://minecraftcomesalive.com/\",\n  \"updateUrl\": \"\",\n  \"authorList\": [\"WildBamaBoy\", \"SheWolfDeadly\"],\n  \"credits\": \"Mezzodrinker, The_Nanobots, numerous others.\",\n  \"logoFile\": \"mca.png\",\n  \"screenshots\": [],\n  \"dependencies\": []\n}\n]\n"
  },
  {
    "path": "src/main/resources/pack.mcmeta",
    "content": "{\n    \"pack\": {\n        \"description\": \"Minecraft Comes Alive resources\",\n        \"pack_format\": 3\n    }\n}\n"
  }
]