From fa65df2d8031380c98ac99cf6f110707b6c6befc Mon Sep 17 00:00:00 2001 From: Lizbeth Rika Date: Sun, 19 Apr 2015 19:56:16 +0100 Subject: [PATCH] Added the Corporea Interceptor. --- .../botania/api/corporea/CorporeaHelper.java | 13 ++- .../api/corporea/ICorporeaInterceptor.java | 38 +++++++ .../botania/common/block/ModBlocks.java | 5 + .../corporea/BlockCorporeaInterceptor.java | 78 ++++++++++++++ .../tile/corporea/TileCorporeaFunnel.java | 5 + .../corporea/TileCorporeaInterceptor.java | 98 ++++++++++++++++++ .../common/core/BotaniaCreativeTab.java | 1 + .../botania/common/lib/LibBlockNames.java | 1 + .../resources/assets/botania/lang/en_US.lang | 1 + .../textures/blocks/corporeaInterceptor0.png | Bin 19482 -> 16997 bytes .../textures/blocks/corporeaInterceptor1.png | Bin 16997 -> 19482 bytes 11 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 src/main/java/vazkii/botania/api/corporea/ICorporeaInterceptor.java create mode 100644 src/main/java/vazkii/botania/common/block/corporea/BlockCorporeaInterceptor.java create mode 100644 src/main/java/vazkii/botania/common/block/tile/corporea/TileCorporeaInterceptor.java diff --git a/src/main/java/vazkii/botania/api/corporea/CorporeaHelper.java b/src/main/java/vazkii/botania/api/corporea/CorporeaHelper.java index 6677100ca..3b0a90533 100644 --- a/src/main/java/vazkii/botania/api/corporea/CorporeaHelper.java +++ b/src/main/java/vazkii/botania/api/corporea/CorporeaHelper.java @@ -165,13 +165,21 @@ public final class CorporeaHelper { public static List requestItem(Object matcher, int itemCount, ICorporeaSpark spark, boolean checkNBT, boolean doit) { List inventories = getInventoriesOnNetwork(spark); List stacks = new ArrayList(); - + Map interceptors = new HashMap(); + lastRequestMatches = 0; lastRequestExtractions = 0; int count = itemCount; for(IInventory inv : inventories) { ICorporeaSpark invSpark = getSparkForInventory(inv); + + if(inv instanceof ICorporeaInterceptor) { + ICorporeaInterceptor interceptor = (ICorporeaInterceptor) inv; + interceptor.interceptRequest(matcher, itemCount, invSpark, spark, stacks, inventories, doit); + interceptors.put(interceptor, invSpark); + } + for(int i = inv.getSizeInventory() - 1; i >= 0; i--) { if(!isValidSlot(inv, i)) continue; @@ -198,6 +206,9 @@ public final class CorporeaHelper { } } } + + for(ICorporeaInterceptor interceptor : interceptors.keySet()) + interceptor.interceptRequestLast(matcher, itemCount, interceptors.get(interceptor), spark, stacks, inventories, doit); return stacks; } diff --git a/src/main/java/vazkii/botania/api/corporea/ICorporeaInterceptor.java b/src/main/java/vazkii/botania/api/corporea/ICorporeaInterceptor.java new file mode 100644 index 000000000..530c7133f --- /dev/null +++ b/src/main/java/vazkii/botania/api/corporea/ICorporeaInterceptor.java @@ -0,0 +1,38 @@ +/** + * This class was created by . It's distributed as + * part of the Botania Mod. Get the Source Code in github: + * https://github.com/Vazkii/Botania + * + * Botania is Open Source and distributed under the + * Botania License: http://botaniamod.net/license.php + * + * File Created @ [Apr 19, 2015, 6:23:31 PM (GMT)] + */ +package vazkii.botania.api.corporea; + +import java.util.List; + +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; + +/** + * A TileEntity that implements this will be able to intercept corporea + * requests case there is a Corporea Spark on top. + */ +public interface ICorporeaInterceptor { + + /** + * Intercepts a request as it goes. The list of inventories has all the inventories + * at this point, but the list of stacks is not complete. The request parameter can + * be either a String or ItemStack. + */ + public void interceptRequest(Object request, int count, ICorporeaSpark spark, ICorporeaSpark source, List stacks, List inventories, boolean doit); + + /** + * Intercepts a request after all the stacks have been found and processed. Both the + * list of inventories and stacks is complete at this point. The request parameter can + * be either a String or ItemStack. + */ + public void interceptRequestLast(Object request, int count, ICorporeaSpark spark, ICorporeaSpark source, List stacks, List inventories, boolean doit); + +} diff --git a/src/main/java/vazkii/botania/common/block/ModBlocks.java b/src/main/java/vazkii/botania/common/block/ModBlocks.java index b0a8bdce0..141193f1f 100644 --- a/src/main/java/vazkii/botania/common/block/ModBlocks.java +++ b/src/main/java/vazkii/botania/common/block/ModBlocks.java @@ -21,6 +21,7 @@ import vazkii.botania.api.BotaniaAPI; import vazkii.botania.client.lib.LibResources; import vazkii.botania.common.block.corporea.BlockCorporeaFunnel; import vazkii.botania.common.block.corporea.BlockCorporeaIndex; +import vazkii.botania.common.block.corporea.BlockCorporeaInterceptor; import vazkii.botania.common.block.decor.BlockBlaze; import vazkii.botania.common.block.decor.BlockBuriedPetals; import vazkii.botania.common.block.decor.BlockCustomBrick; @@ -129,6 +130,7 @@ import vazkii.botania.common.block.tile.TileTinyPlanet; import vazkii.botania.common.block.tile.TileTinyPotato; import vazkii.botania.common.block.tile.corporea.TileCorporeaFunnel; import vazkii.botania.common.block.tile.corporea.TileCorporeaIndex; +import vazkii.botania.common.block.tile.corporea.TileCorporeaInterceptor; import vazkii.botania.common.block.tile.mana.TileDistributor; import vazkii.botania.common.block.tile.mana.TileManaDetector; import vazkii.botania.common.block.tile.mana.TileManaVoid; @@ -216,6 +218,7 @@ public final class ModBlocks { public static Block doubleFlower2; public static Block fakeAir; public static Block blazeBlock; + public static Block corporeaInterceptor; public static void init() { flower = new BlockModFlower(); @@ -284,6 +287,7 @@ public final class ModBlocks { doubleFlower2 = new BlockModDoubleFlower(true); fakeAir = new BlockFakeAir(); blazeBlock = new BlockBlaze(); + corporeaInterceptor = new BlockCorporeaInterceptor(); ModFluffBlocks.init(); @@ -368,6 +372,7 @@ public final class ModBlocks { registerTile(TileCorporeaFunnel.class, LibBlockNames.CORPOREA_FUNNEL); registerTile(TilePump.class, LibBlockNames.PUMP); registerTile(TileFakeAir.class, LibBlockNames.FAKE_AIR); + registerTile(TileCorporeaInterceptor.class, LibBlockNames.CORPOREA_INTERCEPTOR); BotaniaAPI.registerSubTile(LibBlockNames.SUBTILE_PUREDAISY, SubTilePureDaisy.class); BotaniaAPI.registerSubTile(LibBlockNames.SUBTILE_MANASTAR, SubTileManastar.class); diff --git a/src/main/java/vazkii/botania/common/block/corporea/BlockCorporeaInterceptor.java b/src/main/java/vazkii/botania/common/block/corporea/BlockCorporeaInterceptor.java new file mode 100644 index 000000000..a36bc6e57 --- /dev/null +++ b/src/main/java/vazkii/botania/common/block/corporea/BlockCorporeaInterceptor.java @@ -0,0 +1,78 @@ +/** + * This class was created by . It's distributed as + * part of the Botania Mod. Get the Source Code in github: + * https://github.com/Vazkii/Botania + * + * Botania is Open Source and distributed under the + * Botania License: http://botaniamod.net/license.php + * + * File Created @ [Apr 19, 2015, 6:18:03 PM (GMT)] + */ +package vazkii.botania.common.block.corporea; + +import java.util.Random; + +import vazkii.botania.api.lexicon.LexiconEntry; +import vazkii.botania.client.core.helper.IconHelper; +import vazkii.botania.common.block.tile.corporea.TileCorporeaBase; +import vazkii.botania.common.block.tile.corporea.TileCorporeaFunnel; +import vazkii.botania.common.block.tile.corporea.TileCorporeaInterceptor; +import vazkii.botania.common.lexicon.LexiconData; +import vazkii.botania.common.lib.LibBlockNames; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; + +public class BlockCorporeaInterceptor extends BlockCorporeaBase { + + IIcon[] icons; + + public BlockCorporeaInterceptor() { + super(Material.iron, LibBlockNames.CORPOREA_INTERCEPTOR); + setHardness(5.5F); + setStepSound(soundTypeMetal); + } + + @Override + public void registerBlockIcons(IIconRegister par1IconRegister) { + icons = new IIcon[2]; + for(int i = 0; i < icons.length; i++) + icons[i] = IconHelper.forBlock(par1IconRegister, this, i); + } + + @Override + public IIcon getIcon(int par1, int par2) { + return icons[par1 > 1 ? 1 : 0]; + } + + @Override + public void updateTick(World world, int x, int y, int z, Random rand) { + world.setBlockMetadataWithNotify(x, y, z, 0, 1 | 2); + } + + @Override + public boolean canProvidePower() { + return true; + } + + @Override + public int isProvidingWeakPower(IBlockAccess world, int x, int y, int z, int side) { + return world.getBlockMetadata(x, y, z) != 0 ? 15 : 0; + } + + @Override + public int tickRate(World p_149738_1_) { + return 2; + } + + @Override + public TileCorporeaBase createNewTileEntity(World world, int meta) { + return new TileCorporeaInterceptor(); + } + +} diff --git a/src/main/java/vazkii/botania/common/block/tile/corporea/TileCorporeaFunnel.java b/src/main/java/vazkii/botania/common/block/tile/corporea/TileCorporeaFunnel.java index 122819042..6e5f716ea 100644 --- a/src/main/java/vazkii/botania/common/block/tile/corporea/TileCorporeaFunnel.java +++ b/src/main/java/vazkii/botania/common/block/tile/corporea/TileCorporeaFunnel.java @@ -74,6 +74,11 @@ public class TileCorporeaFunnel extends TileCorporeaBase { return filter; } + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return false; + } + @Override public int getSizeInventory() { return 1; diff --git a/src/main/java/vazkii/botania/common/block/tile/corporea/TileCorporeaInterceptor.java b/src/main/java/vazkii/botania/common/block/tile/corporea/TileCorporeaInterceptor.java new file mode 100644 index 000000000..c40f67ead --- /dev/null +++ b/src/main/java/vazkii/botania/common/block/tile/corporea/TileCorporeaInterceptor.java @@ -0,0 +1,98 @@ +/** + * This class was created by . It's distributed as + * part of the Botania Mod. Get the Source Code in github: + * https://github.com/Vazkii/Botania + * + * Botania is Open Source and distributed under the + * Botania License: http://botaniamod.net/license.php + * + * File Created @ [Apr 19, 2015, 6:21:08 PM (GMT)] + */ +package vazkii.botania.common.block.tile.corporea; + +import java.util.ArrayList; +import java.util.List; + +import net.minecraft.block.Block; +import net.minecraft.entity.item.EntityItemFrame; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.AxisAlignedBB; +import net.minecraftforge.common.util.ForgeDirection; +import vazkii.botania.api.corporea.CorporeaHelper; +import vazkii.botania.api.corporea.ICorporeaInterceptor; +import vazkii.botania.api.corporea.ICorporeaSpark; +import vazkii.botania.common.lib.LibBlockNames; +import vazkii.botania.common.lib.LibMisc; + +public class TileCorporeaInterceptor extends TileCorporeaBase implements ICorporeaInterceptor { + + @Override + public boolean isItemValidForSlot(int i, ItemStack itemstack) { + return false; + } + + @Override + public int getSizeInventory() { + return 1; + } + + @Override + public String getInventoryName() { + return LibBlockNames.CORPOREA_INTERCEPTOR; + } + + @Override + public void interceptRequest(Object request, int count, ICorporeaSpark spark, ICorporeaSpark source, List stacks, List inventories, boolean doit) { + // NO-OP + } + + @Override + public void interceptRequestLast(Object request, int count, ICorporeaSpark spark, ICorporeaSpark source, List stacks, List inventories, boolean doit) { + List filter = getFilter(); + for(ItemStack stack : filter) + if(requestMatches(request, stack)) { + int missing = count; + for(ItemStack stack_ : stacks) + missing -= stack_.stackSize; + + if(missing > 0 && getBlockMetadata() == 0) { + worldObj.setBlockMetadataWithNotify(xCoord, yCoord, zCoord, 1, 1 | 2); + worldObj.scheduleBlockUpdate(xCoord, yCoord, zCoord, getBlockType(), 2); + return; + } + } + + } + + public boolean requestMatches(Object request, ItemStack filter) { + if(request instanceof ItemStack) { + ItemStack stack = (ItemStack) request; + return stack.isItemEqual(filter) && ItemStack.areItemStacksEqual(filter, stack); + } + + String name = (String) request; + return CorporeaHelper.stacksMatch(filter, name); + } + + public List getFilter() { + List filter = new ArrayList(); + + final int[] orientationToDir = new int[] { + 3, 4, 2, 5 + }; + + for(ForgeDirection dir : LibMisc.CARDINAL_DIRECTIONS) { + List frames = worldObj.getEntitiesWithinAABB(EntityItemFrame.class, AxisAlignedBB.getBoundingBox(xCoord + dir.offsetX, yCoord + dir.offsetY, zCoord + dir.offsetZ, xCoord + dir.offsetX + 1, yCoord + dir.offsetY + 1, zCoord + dir.offsetZ + 1)); + for(EntityItemFrame frame : frames) { + int orientation = frame.hangingDirection; + if(orientationToDir[orientation] == dir.ordinal()) + filter.add(frame.getDisplayedItem()); + } + } + + return filter; + } + + +} diff --git a/src/main/java/vazkii/botania/common/core/BotaniaCreativeTab.java b/src/main/java/vazkii/botania/common/core/BotaniaCreativeTab.java index 47e4dacdd..9e99e9359 100644 --- a/src/main/java/vazkii/botania/common/core/BotaniaCreativeTab.java +++ b/src/main/java/vazkii/botania/common/core/BotaniaCreativeTab.java @@ -237,6 +237,7 @@ public final class BotaniaCreativeTab extends CreativeTabs { addItem(ModItems.corporeaSpark); addBlock(ModBlocks.corporeaIndex); addBlock(ModBlocks.corporeaFunnel); + addBlock(ModBlocks.corporeaInterceptor); // FLUFF diff --git a/src/main/java/vazkii/botania/common/lib/LibBlockNames.java b/src/main/java/vazkii/botania/common/lib/LibBlockNames.java index a0dd6fa35..a1b905d7e 100644 --- a/src/main/java/vazkii/botania/common/lib/LibBlockNames.java +++ b/src/main/java/vazkii/botania/common/lib/LibBlockNames.java @@ -81,6 +81,7 @@ public final class LibBlockNames { public static final String STONE = "stone"; public static final String FAKE_AIR = "fakeAir"; public static final String BLAZE_BLOCK = "blazeBlock"; + public static final String CORPOREA_INTERCEPTOR = "corporeaInterceptor"; public static final String SUBTILE_PUREDAISY = "puredaisy"; public static final String SUBTILE_MANASTAR = "manastar"; diff --git a/src/main/resources/assets/botania/lang/en_US.lang b/src/main/resources/assets/botania/lang/en_US.lang index 9257e72e3..a3790c4a1 100644 --- a/src/main/resources/assets/botania/lang/en_US.lang +++ b/src/main/resources/assets/botania/lang/en_US.lang @@ -903,6 +903,7 @@ tile.botania:stone9Slab.name=Basalt Brick Slab tile.botania:stone10Slab.name=Diorite Brick Slab tile.botania:stone11Slab.name=Granite Brick Slab tile.botania:blazeBlock.name=Blaze Lamp +tile.botania:corporeaInterceptor.name=Corporea Interceptor # FLOWER NAMES tile.botania:flower..name=Botania Flower diff --git a/src/main/resources/assets/botania/textures/blocks/corporeaInterceptor0.png b/src/main/resources/assets/botania/textures/blocks/corporeaInterceptor0.png index b15cda2824853bc94f6e5a7bf947d4de58a6daed..6fbe2626702e0cff4abb885b2f26984504bbd3c2 100644 GIT binary patch delta 1085 zcma)*T}YEr7{|ByI<*j&AIqt0mQrfIZTfEQ#b%VvVr)qz8p$9hTLku@MS_vNu%alD zMY|EBYoQON7SRV*7ukmpNH;~0MIb>pU3S;M_kV0-qni#Kp7WmPJiq5W|Mxjllg8zX z#%rpn{rSDNW2V$kQ?XHUw<+p%sYBS*Zt1(JKH`ZEY*k|}+0_#D$}NgJCJ(f_qq6si z$E`*pO3b4u$^8Z13KU-cU)e2{7+4{~Ub(j1wCm-&) zq9vU7p%piRHX+}}Y2RGV+P!8+W`D4097DEKFx)f@q0e^{RQ9A1vFp%23ulTSnhGGEw6#Nk{*)*3^r-wg1~eTO^KYqY?6Jz|wj^ z)Ib1Z(f|z&W!r^DBvg((M#bR^u=>OB8%+pH`LK0{Q63%>KB_?#7?UO-V2g@PIof_hyBbA)D{$>`;A`2wnL&&5*U-Y z0xKe5LYIg#Zm@4g!y`b|)u4>Z9B{6*DkCESD=KJN%|HT0<{-s>c?ngsztI~1n)55! zDNN2pH!aSP06RhVELCPyF8`wsUm|u0-as{nU4PWAG3otRsaA1 delta 1840 zcmb_bdr(w$6b3|Djc}In0Xi4~varit?!I^L(k44B%42~+B_f;g?%sQ0mEF6-icFf@ zNZI-r5pN|}KC&@K@rCGQqvoT~)fr22GBYc6#Oxm%Uw_nuUwbbvXPPGd==aa>-rqUr zJLmh(Iel+OZ)uO-XpWg3=%VUlVjBaMtZ*}Cs<1vx(XnPqM+%>f zu}dG_{bPQO$*?dMozBR(2-0mf5+;k@MYv3)o6xX~#X^!=x5nfaWO1ep&TTfhS=vZ& zj73A3bP-3|MOp}!G3bmMi(pme3gIky=VaQl!2{$d5lQq{tj&8MeXGB-F}O)qc8x_Ob!Cq0#2%eNAjb zfMrs-2Hu~GtO1L#Xe^kW8as_q#_*f04(FxZ0bHmZ3i6c!6t0PF(?IPSRJxf>^14D4E z$z?F>%|m-|3_Z#Fn#6VWhQ!LZ%p(C(bY@w8ScX_q5@ka zg_`j&)MzGn5b4?Q38~MVL3CaS#m$P7l2W|zO@?Y_1S(Tcc>s zYQyvwtY}pqL@UvW#=Mhg%{@H)t&`ipXNH6>+mzr(>w1x_eg(G9yO^$-htlOY;GBP1 zx~obrB1Kt(GX6Z$)1278{t9aH_F~DDC5YM@DRUOYD=8>(|azGKDAt;*wdEx6w_O6HO)Dx&8B~0a7 zBwNQgnPi*ezXnhC8VMjM>G+m%E2_&+pz7EoOsx&!r5<3`wkrs1yFGw%;sK0jfF!mB z#fKlE#(5HN)*l!tAvej1c7GTZ!Q&uz+(yPHSFmD3FA^g1O)RK}V(*X0+LMKBeyBSiBC*(otj-&l+5Q!@ws}ZD@fWD@Q>Z$B zM$sGJgUa-dlpyw192mLI4!XM!(<|$cwf_NBXZ}P^Pe11GyN9I6+oG#akw8!qfKMMB z90qZkcC=rDF0BIP&fS=~xd+~kK9utpFily68LAR2+Hw=xFZ+@HVOa8^loeRr{0u;| z@&i;`cOo;r6feKuhcfm%%%B#a)c3VC(@73Dth?{S(DfLqEGHIFyBzQ+Ru7O^7gdGD z%5`9?FJig#405t7C5={OZx**j+9J`OBezKJ;+9n|JR)wHFwR~w$#d5J?uJ(R>8Qvl Ma+DPuurFNoH=1cCu>b%7 diff --git a/src/main/resources/assets/botania/textures/blocks/corporeaInterceptor1.png b/src/main/resources/assets/botania/textures/blocks/corporeaInterceptor1.png index 6fbe2626702e0cff4abb885b2f26984504bbd3c2..b15cda2824853bc94f6e5a7bf947d4de58a6daed 100644 GIT binary patch delta 1840 zcmb_bdr(w$6b3|Djc}In0Xi4~varit?!I^L(k44B%42~+B_f;g?%sQ0mEF6-icFf@ zNZI-r5pN|}KC&@K@rCGQqvoT~)fr22GBYc6#Oxm%Uw_nuUwbbvXPPGd==aa>-rqUr zJLmh(Iel+OZ)uO-XpWg3=%VUlVjBaMtZ*}Cs<1vx(XnPqM+%>f zu}dG_{bPQO$*?dMozBR(2-0mf5+;k@MYv3)o6xX~#X^!=x5nfaWO1ep&TTfhS=vZ& zj73A3bP-3|MOp}!G3bmMi(pme3gIky=VaQl!2{$d5lQq{tj&8MeXGB-F}O)qc8x_Ob!Cq0#2%eNAjb zfMrs-2Hu~GtO1L#Xe^kW8as_q#_*f04(FxZ0bHmZ3i6c!6t0PF(?IPSRJxf>^14D4E z$z?F>%|m-|3_Z#Fn#6VWhQ!LZ%p(C(bY@w8ScX_q5@ka zg_`j&)MzGn5b4?Q38~MVL3CaS#m$P7l2W|zO@?Y_1S(Tcc>s zYQyvwtY}pqL@UvW#=Mhg%{@H)t&`ipXNH6>+mzr(>w1x_eg(G9yO^$-htlOY;GBP1 zx~obrB1Kt(GX6Z$)1278{t9aH_F~DDC5YM@DRUOYD=8>(|azGKDAt;*wdEx6w_O6HO)Dx&8B~0a7 zBwNQgnPi*ezXnhC8VMjM>G+m%E2_&+pz7EoOsx&!r5<3`wkrs1yFGw%;sK0jfF!mB z#fKlE#(5HN)*l!tAvej1c7GTZ!Q&uz+(yPHSFmD3FA^g1O)RK}V(*X0+LMKBeyBSiBC*(otj-&l+5Q!@ws}ZD@fWD@Q>Z$B zM$sGJgUa-dlpyw192mLI4!XM!(<|$cwf_NBXZ}P^Pe11GyN9I6+oG#akw8!qfKMMB z90qZkcC=rDF0BIP&fS=~xd+~kK9utpFily68LAR2+Hw=xFZ+@HVOa8^loeRr{0u;| z@&i;`cOo;r6feKuhcfm%%%B#a)c3VC(@73Dth?{S(DfLqEGHIFyBzQ+Ru7O^7gdGD z%5`9?FJig#405t7C5={OZx**j+9J`OBezKJ;+9n|JR)wHFwR~w$#d5J?uJ(R>8Qvl Ma+DPuurFNoH=1cCu>b%7 delta 1085 zcma)*T}YEr7{|ByI<*j&AIqt0mQrfIZTfEQ#b%VvVr)qz8p$9hTLku@MS_vNu%alD zMY|EBYoQON7SRV*7ukmpNH;~0MIb>pU3S;M_kV0-qni#Kp7WmPJiq5W|Mxjllg8zX z#%rpn{rSDNW2V$kQ?XHUw<+p%sYBS*Zt1(JKH`ZEY*k|}+0_#D$}NgJCJ(f_qq6si z$E`*pO3b4u$^8Z13KU-cU)e2{7+4{~Ub(j1wCm-&) zq9vU7p%piRHX+}}Y2RGV+P!8+W`D4097DEKFx)f@q0e^{RQ9A1vFp%23ulTSnhGGEw6#Nk{*)*3^r-wg1~eTO^KYqY?6Jz|wj^ z)Ib1Z(f|z&W!r^DBvg((M#bR^u=>OB8%+pH`LK0{Q63%>KB_?#7?UO-V2g@PIof_hyBbA)D{$>`;A`2wnL&&5*U-Y z0xKe5LYIg#Zm@4g!y`b|)u4>Z9B{6*DkCESD=KJN%|HT0<{-s>c?ngsztI~1n)55! zDNN2pH!aSP06RhVELCPyF8`wsUm|u0-as{nU4PWAG3otRsaA1