From 59fedc8fdfb69787a39768c81a7c44384bf6a3ec Mon Sep 17 00:00:00 2001 From: jascotty2 Date: Tue, 3 Sep 2019 16:08:30 -0500 Subject: [PATCH] merge core update --- pom.xml | 44 ++- .../listeners/DeathListeners.java | 11 +- .../lootables/LootablesManager.java | 74 ++--- .../utils/settings/Setting.java | 303 ------------------ .../command/commands/CommandSettings.class | Bin 2282 -> 0 bytes 5 files changed, 43 insertions(+), 389 deletions(-) delete mode 100644 src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java delete mode 100644 target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class diff --git a/pom.xml b/pom.xml index e2207f9..6902b13 100644 --- a/pom.xml +++ b/pom.xml @@ -32,7 +32,7 @@ false - com.songoda:songodaupdater + com.songoda:SongodaCore com.songoda:Lootables com.zaxxer:HikariCP org.slf4j:slf4j-api @@ -49,6 +49,16 @@ + + + com.songoda.core + ${project.groupId}.ultimatestacker.core + + + com.songoda.lootables + ${project.groupId}.ultimatestacker.lootables + + @@ -66,20 +76,11 @@ - - com.gmail.filoghost.holographicdisplays - holographicdisplays-api - 2.3.2 - org.spigotmc - spigot - 1.14.1 - - - com.songoda - songodaupdater - 1 + spigot-api + 1.14.4-R0.1-SNAPSHOT + provided com.songoda @@ -87,25 +88,16 @@ 1.0.3 - net.milkbowl - vault - 1.7.1 + com.songoda + SongodaCore + LATEST + compile com.gamingmesh jobs 4.10.3 - - com.bgsoftware - WildStacker - 2-9-0 - - - uk.antiperson - stackmob - 4-0-2 - me.minebuilders Clearlag diff --git a/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java b/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java index b31fc4e..fa5394b 100644 --- a/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java +++ b/src/main/java/com/songoda/ultimatestacker/listeners/DeathListeners.java @@ -1,11 +1,12 @@ package com.songoda.ultimatestacker.listeners; +import com.songoda.core.compatibility.ServerProject; +import com.songoda.core.compatibility.ServerVersion; import com.songoda.lootables.loot.Drop; import com.songoda.ultimatestacker.UltimateStacker; import com.songoda.ultimatestacker.entity.EntityStack; +import com.songoda.ultimatestacker.settings.Setting; import com.songoda.ultimatestacker.utils.DropUtils; -import com.songoda.ultimatestacker.utils.ServerVersion; -import com.songoda.ultimatestacker.utils.settings.Setting; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.ChestedHorse; @@ -62,14 +63,14 @@ public class DeathListeners implements Listener { if (entity.getEquipment() != null && entity.getEquipment().getArmorContents().length != 0) { List items = new ArrayList<>(Arrays.asList(entity.getEquipment().getArmorContents())); items.add(entity.getEquipment().getItemInHand()); - if (instance.isServerVersionAtLeast(ServerVersion.V1_9)) + if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) items.add(entity.getEquipment().getItemInOffHand()); for (ItemStack item : items) { if (item.getType() == material) return true; } } - if (instance.isServerVersionAtLeast(ServerVersion.V1_11) && entity instanceof ChestedHorse) { + if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11) && entity instanceof ChestedHorse) { if (((ChestedHorse) entity).getInventory().contains(material)) return true; } @@ -115,7 +116,7 @@ public class DeathListeners implements Listener { Player player = (Player) event.getDamager(); ItemStack tool = player.getInventory().getItemInMainHand(); if (tool.getType().getMaxDurability() < 1 || (tool.getItemMeta() != null && (tool.getItemMeta().isUnbreakable() - || tool.getItemMeta().spigot().isUnbreakable()))) + || (ServerProject.isServer(ServerProject.SPIGOT, ServerProject.PAPER) && tool.getItemMeta().spigot().isUnbreakable())))) return; int unbreakingLevel = tool.getEnchantmentLevel(Enchantment.DURABILITY); diff --git a/src/main/java/com/songoda/ultimatestacker/lootables/LootablesManager.java b/src/main/java/com/songoda/ultimatestacker/lootables/LootablesManager.java index 8e3c6eb..2c48a5e 100644 --- a/src/main/java/com/songoda/ultimatestacker/lootables/LootablesManager.java +++ b/src/main/java/com/songoda/ultimatestacker/lootables/LootablesManager.java @@ -6,6 +6,7 @@ import com.songoda.lootables.Lootables; import com.songoda.lootables.Modify; import com.songoda.lootables.loot.*; import com.songoda.ultimatestacker.UltimateStacker; +import com.songoda.ultimatestacker.settings.Setting; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.*; @@ -87,8 +88,6 @@ public class LootablesManager { } public void createDefaultLootables() { - UltimateStacker plugin = UltimateStacker.getInstance(); - if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_14)) { // Add Trader Llama. lootManager.addLootable(new Lootable("TRADER_LLAMA", @@ -210,68 +209,39 @@ public class LootablesManager { } - Loot fish1 = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ? new LootBuilder() - .addChildLoot(new LootBuilder() - .setMaterial(Material.COD) - .setBurnedMaterial(Material.COOKED_COD) - .setChance(50).build(), - new LootBuilder() - .setMaterial(Material.PRISMARINE_CRYSTALS) - .setChance(33).build()) - .build() - : - new LootBuilder() + Loot fish1 = new LootBuilder() .addChildLoot(new LootBuilder() - .setMaterial(Material.valueOf("RAW_FISH")) - .setBurnedMaterial(Material.valueOf("COOKED_FISH")) + .setMaterial(LegacyMaterials.COD.getMaterial()) + .setBurnedMaterial(LegacyMaterials.COOKED_COD.getMaterial()) .setChance(50).build(), new LootBuilder() .setMaterial(Material.PRISMARINE_CRYSTALS) .setChance(33).build()) .build(); - Loot fish2 = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ? new LootBuilder() + Loot fish2 = new LootBuilder() .setChance(2.5) .addChildLoot(new LootBuilder() - .setMaterial(Material.COD) + .setMaterial(LegacyMaterials.COD.getMaterial()) + .setData(LegacyMaterials.COD.getData()) .setChance(60) .setAllowLootingEnchant(false).build(), new LootBuilder() - .setMaterial(Material.SALMON) + .setMaterial(LegacyMaterials.SALMON.getMaterial()) + .setData(LegacyMaterials.SALMON.getData()) .setChance(25) .setAllowLootingEnchant(false).build(), new LootBuilder() - .setMaterial(Material.PUFFERFISH) + .setMaterial(LegacyMaterials.PUFFERFISH.getMaterial()) + .setData(LegacyMaterials.PUFFERFISH.getData()) .setChance(13) .setAllowLootingEnchant(false).build(), new LootBuilder() - .setMaterial(Material.TROPICAL_FISH) + .setMaterial(LegacyMaterials.TROPICAL_FISH.getMaterial()) + .setData(LegacyMaterials.TROPICAL_FISH.getData()) .setChance(2) .setAllowLootingEnchant(false).build()) - .addOnlyDropFors(EntityType.PLAYER).build() - : - new LootBuilder() - .setChance(2.5) - .addChildLoot(new LootBuilder() - .setMaterial(Material.valueOf("RAW_FISH")) - .setChance(60) - .setAllowLootingEnchant(false).build(), - new LootBuilder() - .setMaterial(Material.valueOf("RAW_FISH")) - .setData(1) - .setChance(25) - .setAllowLootingEnchant(false).build(), - new LootBuilder() - .setMaterial(Material.valueOf("RAW_FISH")) - .setData(3) - .setChance(13) - .setAllowLootingEnchant(false).build(), - new LootBuilder() - .setMaterial(Material.valueOf("RAW_FISH")) - .setData(2) - .setChance(2) - .setAllowLootingEnchant(false).build()) - .addOnlyDropFors(EntityType.PLAYER).build(); + .addOnlyDropFors(EntityType.PLAYER).build(); if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) { // Add Zombie Villager. @@ -336,15 +306,9 @@ public class LootablesManager { .setMin(0) .setMax(2).build())); - Loot witherSkull = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13) ? - new LootBuilder() - .setMaterial(Material.WITHER_SKELETON_SKULL) - .setChance(2.5) - .addOnlyDropFors(EntityType.PLAYER).build() - : - new LootBuilder() - .setMaterial(Material.valueOf("SKULL_ITEM")) - .setData(1) + Loot witherSkull = new LootBuilder() + .setMaterial(LegacyMaterials.WITHER_SKELETON_SKULL.getMaterial()) + .setData(LegacyMaterials.WITHER_SKELETON_SKULL.getData()) .setChance(2.5) .addOnlyDropFors(EntityType.PLAYER).build(); @@ -423,8 +387,8 @@ public class LootablesManager { .setMin(0) .setMax(2).build(), new LootBuilder() - .setMaterial(LegacyMaterials.COD.getMaterial()) - .setData(LegacyMaterials.COD.getData()) + .setMaterial(LegacyMaterials.SALMON.getMaterial()) + .setData(LegacyMaterials.SALMON.getData()) .setChance(25) .setMin(0) .setMax(2).build())); diff --git a/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java b/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java deleted file mode 100644 index 9ec7c2f..0000000 --- a/src/main/java/com/songoda/ultimatestacker/utils/settings/Setting.java +++ /dev/null @@ -1,303 +0,0 @@ -package com.songoda.ultimatestacker.utils.settings; - -import com.songoda.ultimatestacker.UltimateStacker; -import com.songoda.ultimatestacker.entity.Check; -import com.songoda.ultimatestacker.entity.Split; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -public enum Setting { - - STACK_SEARCH_TICK_SPEED("Main.Stack Search Tick Speed", 5, - "The speed in which a new stacks will be created.", - "It is advised to keep this number low."), - - DISABLED_WORLDS("Main.Disabled Worlds", Arrays.asList("World1", "World2", "World3"), - "Worlds that stacking doesn't happen in."), - - STACK_ENTITIES("Entities.Enabled", true, - "Should entities be stacked?"), - - NAME_FORMAT_ENTITY("Entities.Name Format", "&f{TYPE} &6{AMT}x", - "The text displayed above an entities head where {TYPE} refers to", - "The entities type and {AMT} is the amount currently stacked."), - - SEARCH_RADIUS("Entities.Search Radius", 5, - "The distance entities must be to each other in order to stack."), - - MAX_STACK_ENTITIES("Entities.Max Stack Size", 15, - "The max amount of entities in a single stack."), - - MIN_STACK_ENTITIES("Entities.Min Stack Amount", 5, - "The minimum amount required before a stack can be formed.", - "Do not set this to lower than 2."), - - MAX_PER_TYPE_STACKS_PER_CHUNK("Entities.Max Per Type Stacks Per Chunk", -1, - "The maximum amount of each entity type stack allowed in a chunk."), - - STACK_WHOLE_CHUNK("Entities.Stack Whole Chunk", false, - "Should all qualifying entities in each chunk be stacked?", - "This will override the stacking radius."), - - ENTITY_HOLOGRAMS("Entities.Holograms Enabled", true, - "Should holograms be displayed above stacked entities?"), - - HOLOGRAMS_ON_LOOK_ENTITY("Entities.Only Show Holograms On Look", false, - "Only show nametags above an entities head when looking directly at them."), - - CUSTOM_DROPS("Entities.Custom Drops.Enabled", true, - "Should custom drops be enabled?"), - - REROLL("Entities.Custom Drops.Reroll", true, - "Increases chance of uncommon drops by making a second attempt to", - "drop if the original attempt failed (Requires the looting enchantment).", - "This is a default Minecraft mechanic."), - - KILL_WHOLE_STACK_ON_DEATH("Entities.Kill Whole Stack On Death", false, - "Should killing a stack of entities kill the whole stack or", - "just one out of the stack? If you want only certain entities to be", - "effected by this you can configure it in the entities.yml"), - - CLEAR_LAG("Entities.Clear Lag", false, - "When enabled, the plugin will hook into ClearLag and extend the", - "clear task to include stacked entities from this plugin. If this is enabled", - "the built in task will not run."), - - INSTANT_KILL("Entities.Instant Kill", Arrays.asList("FALL", "DROWNING", "LAVA", "VOID"), - "Events that will trigger an entire stack to be killed.", - "It should be noted that this is useless if the above setting is true.", - "Any of the following can be added to the list:", - "CONTACT, ENTITY_ATTACK, ENTITY_SWEEP_ATTACK, PROJECTILE", - "SUFFOCATION, FALL, FIRE, FIRE_TICK", - "MELTING, LAVA, DROWNING, BLOCK_EXPLOSION", - "ENTITY_EXPLOSION, VOID, LIGHTNING, SUICIDE", - "STARVATION, POISON, MAGIC, WITHER", - "FALLING_BLOCK, THORNS, DRAGON_BREATH, CUSTOM", - "FLY_INTO_WALL, HOT_FLOOR, CRAMMING, DRYOUT"), - - NO_EXP_INSTANT_KILL("Entities.No Exp For Instant Kills", false, - "Should no experience be dropped when an instant kill is performed?"), - - STACK_CHECKS("Entities.Stack Checks", Arrays.asList(Check.values()).stream() - .filter(Check::isEnabledByDefault).map(Check::name).collect(Collectors.toList()), - "These are checks that are processed before an entity is stacked.", - "You can add and remove from the list at will.", - "The acceptable check options are:", - "SPAWN_REASON, NERFED, AGE, TICK_AGE, PHANTOM_SIZE", - "IS_TAMED, ANIMAL_OWNER, SKELETON_TYPE", - "ZOMBIE_BABY, SLIME_SIZE, PIG_SADDLE, SHEEP_SHEERED", - "SHEEP_COLOR, WOLF_COLLAR_COLOR, OCELOT_TYPE, HORSE_COLOR", - "HORSE_STYLE, HORSE_CARRYING_CHEST, HORSE_HAS_ARMOR", - "HORSE_HAS_SADDLE, HORSE_JUMP, RABBIT_TYPE, VILLAGER_PROFESSION", - "LLAMA_COLOR, LLAMA_STRENGTH, PARROT_TYPE, PUFFERFISH_STATE", - "TROPICALFISH_PATTERN, TROPICALFISH_BODY_COLOR, TROPICALFISH_PATTERN_COLOR"), - - SPLIT_CHECKS("Entities.Split Checks", Arrays.asList(Split.values()).stream() - .map(Split::name).collect(Collectors.toList()), - "These are checks that when achieved will break separate a single entity", - "from a stack."), - - KEEP_FIRE("Entities.Keep Fire", true, - "Should fire ticks persist to the next entity when an entity dies?"), - - KEEP_POTION("Entities.Keep Potion Effects", true, - "Should potion effects persist to the next entity when an entity dies?"), - - CARRY_OVER_LOWEST_HEALTH("Entities.Carry Over Lowest Health", false, - "Should the lowest health be carried over when stacked?", - "This should not be used in collaboration with 'Stack Entity Health'.", - "If it is used this setting will be overrode."), - - ONLY_STACK_FROM_SPAWNERS("Entities.Only Stack From Spawners", false, - "Should entities only be stacked if they originate from a spawner?", - "It should be noted that the identifier that tells the plugin", - "if the entity originated from a spawner or not is wiped on", - "server restart."), - - STACK_REASONS("Entities.Stack Reasons", Arrays.asList(), - "This will limit mob stacking to mobs who spawned via the listed reasons.", - "This list is ignored if Only Stack From Spawners = true.", - "The following reasons can be added to the list:", - "NATURAL, JOCKEY, CHUNK_GEN, SPAWNER, EGG, SPAWNER_EGG, LIGHTNING, BUILD_SNOWMAN, ", - "BUILD_IRONGOLEM, BUILD_WITHER, VILLAGE_DEFENSE, VILLAGE_INVASION, BREEDING,", - "SLIME_SPLIT, REINFORCEMENTS, NETHER_PORTAL, DISPENSE_EGG, INFECTION,", - "CURED, OCELOT_BABY, SILVERFISH_BLOCK, MOUNT, TRAP, ENDER_PEARL, ", - "SHOULDER_ENTITY, DROWNED, SHEARED, EXPLOSION" - ), - - CARRY_OVER_METADATA_ON_DEATH("Entities.Carry Over Metadata On Death", true, - "With this enabled any metadata assigned from supported plugins such", - "as EpicSpawners and mcMMO will be preserved when the entity is killed."), - - ONLY_STACK_ON_SURFACE("Entities.Only Stack On Surface", true, - "Should entities only be stacked if they are touching the ground", - "or swimming? This does not effect flying entities."), - - STACK_ENTITY_HEALTH("Entities.Stack Entity Health", true, - "Should entity health be stacked? When enabled Entity stacks will", - "remember the health of all entities inside of the stack. This", - "works the best with 'Only Stack On Surface enabled' as entities", - "falling out of grinders may stack before hitting the ground."), - - ONLY_STACK_FLYING_DOWN("Entities.Only Stack Flying Down", true, - "Should entities that fly only stack with entities that are lower on the", - "Y axis. This is important for grinders so that flying entities don't continuously", - "stack upwards to a higher up entity."), - - REALISTIC_DAMAGE("Entities.Use Realistic Weapon Damage", true, - "Should weapons take damage based on the amount of entites in the stack?"), - - STACK_ITEMS("Items.Enabled", true, - "Should items be stacked?"), - - ITEM_HOLOGRAMS("Items.Holograms Enabled", true, - "Should holograms be displayed above stacked items?"), - - ITEM_HOLOGRAM_SINGLE("Items.Show Hologram For Single", true, - "Should holograms be displayed above items when there is only a single", - "item in the stack?"), - - ITEM_HOLOGRAM_BLACKLIST("Items.Show Holograms For Blacklisted Items", true, - "Should items that are blacklisted display holograms?"), - - MAX_STACK_ITEMS("Items.Max Stack Size", 512, - "The max stack size for items.", - "Currently this can only be set to a max of 120."), - - NAME_FORMAT_ITEM("Items.Name Format", "&f{TYPE} &r[&6{AMT}x]", - "The text displayed above a dropped item."), - - NAME_FORMAT_RESET("Items.Name Format Reset", true, - "Should color codes in dropped item names be removed?", - "This is added only because it looks smoother in game. This is only visual and", - "doesn't actually effect the item."), - - ITEM_BLACKLIST("Items.Blacklist", Collections.singletonList("EGG"), - "Items included in this list will stack to default Minecraft amounts.", - "Material list: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html", - "Leave this empty by using \"blacklist: []\" if you do not wish to disable", - "stacking for any items."), - - ITEM_WHITELIST("Items.Whitelist", new ArrayList(), - "Items included in this whitelist will be stacked.", - "Material list: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html", - "Leave this empty by using \"whitelist: []\" if you want everything to be stacked.", - "Items not in this list will act as if they are blacklisted."), - - SHOW_STACK_SIZE_SINGLE("Items.Show Stack Size For Single", false, - "When enabled stack sizes for a stack with a single item will", - "not display the stack size. The stack size will be added", - "for stacks containing two or more items."), - - SPAWNERS_ENABLED("Spawners.Enabled", true, - "Should spawners be stacked?"), - - SPAWNER_HOLOGRAMS("Spawners.Holograms Enabled", true, - "Should holograms be displayed above stacked spawners?"), - - EGGS_CONVERT_SPAWNERS("Spawners.Eggs Convert Spawners", true, - "Should eggs convert spawners? If enabled you will", - "still need to give perms for it to work."), - - MAX_STACK_SPAWNERS("Spawners.Max Stack Size", 5, - "What should the max a spawner can stack to be?"), - - SNEAK_FOR_STACK("Spawners.Sneak To Receive A Stacked Spawner", true, - "Toggle ability to receive a stacked spawner when breaking a spawner while sneaking."), - - SPAWNERS_DONT_EXPLODE("Spawners.Prevent Spawners From Exploding", false, - "Should spawners not break when blown up?"), - - EXPLOSION_DROP_CHANCE_TNT("Spawners.Chance On TNT Explosion", "100%", - "Chance of a TNT explosion dropping a spawner."), - - EXPLOSION_DROP_CHANCE_CREEPER("Spawners.Chance On Creeper Explosion", "100%", - "Chance of a creeper explosion dropping a spawner."), - - NAME_FORMAT_SPAWNER("Spawners.Name Format", "&f{TYPE} Spawner &6{AMT}x", - "The text displayed above a stacked spawner where {TYPE} refers to", - "The entities type and {AMT} is the amount currently stacked."), - - LANGUGE_MODE("System.Language Mode", "en_US", - "The enabled language file.", - "More language files (if available) can be found in the plugins data folder."), - - MYSQL_ENABLED("MySQL.Enabled", false, "Set to 'true' to use MySQL instead of SQLite for data storage."), - MYSQL_HOSTNAME("MySQL.Hostname", "localhost"), - MYSQL_PORT("MySQL.Port", 3306), - MYSQL_DATABASE("MySQL.Database", "your-database"), - MYSQL_USERNAME("MySQL.Username", "user"), - MYSQL_PASSWORD("MySQL.Password", "pass"), - MYSQL_USE_SSL("MySQL.Use SSL", false); - - private String setting; - private Object option; - private String[] comments; - - Setting(String setting, Object option, String... comments) { - this.setting = setting; - this.option = option; - this.comments = comments; - } - - Setting(String setting, Object option) { - this.setting = setting; - this.option = option; - this.comments = null; - } - - public static Setting getSetting(String setting) { - List settings = Arrays.stream(values()).filter(setting1 -> setting1.setting.equals(setting)).collect(Collectors.toList()); - if (settings.isEmpty()) return null; - return settings.get(0); - } - - public String getSetting() { - return setting; - } - - public Object getOption() { - return option; - } - - public String[] getComments() { - return comments; - } - - public List getIntegerList() { - return UltimateStacker.getInstance().getConfig().getIntegerList(setting); - } - - public List getStringList() { - return UltimateStacker.getInstance().getConfig().getStringList(setting); - } - - public boolean getBoolean() { - return UltimateStacker.getInstance().getConfig().getBoolean(setting); - } - - public int getInt() { - return UltimateStacker.getInstance().getConfig().getInt(setting); - } - - public long getLong() { - return UltimateStacker.getInstance().getConfig().getLong(setting); - } - - public String getString() { - return UltimateStacker.getInstance().getConfig().getString(setting); - } - - public char getChar() { - return UltimateStacker.getInstance().getConfig().getString(setting).charAt(0); - } - - public double getDouble() { - return UltimateStacker.getInstance().getConfig().getDouble(setting); - } - -} \ No newline at end of file diff --git a/target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class b/target/classes/com/songoda/ultimatestacker/command/commands/CommandSettings.class deleted file mode 100644 index 5ceb7ca63dafd04b704f9cc98cb4c0c2a5085c54..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2282 zcmc&#TW=CU6#izxE=4RYZEd|&v0i$i?Rvj~*oqo8*cjKEs80h-=vbI-b_ZkMeej3) z1JnmiOf)|Gql{-^OL0ML`k*}QGBf9V=bP_b_Q%gJ-vC@h!9*s8g*XyejAIFwiL-H> z!}&o>;6e-+W4IK7qGGnuI-NtkSGPSpq=C2us=>Kiu zm0h{1$&bp^b{cM3+?9TZjkT+))fY>?8VtkX;-b>nZk+@U;JS%y0y*4ZnCvK3YA30; ztVcDzC0rBv1a4wEffd|h7!OT^C0?mZqLZ*1UfK)VlB(xUMe4L(7wJ%mrMKfRG33g- zm^5VLPn@pSXSlE%_fWsnz}bUWM|Uw4``1#yw`)Q^@6jXv)Xenb6B3U`sb3O-$`85X zRlim9R6hMs{I2kI<@o(pfU|3DJe`*!KwoA7Q?ytxnJsks57+&bQ3l zph+CTQ34|fOyO8FWD>`bMuY;Lz%=dn^dFFoAIM-k*!~59$qrnjjcc@VjW(_k;GXnx zaEiQ7;|x80{6%{EXpvMb9AK&$AkjJw0x-<