From 3c2ddf4d645dcb01078c383bbdff493866ecba72 Mon Sep 17 00:00:00 2001 From: Boblet Date: Thu, 13 Mar 2025 16:58:15 +0100 Subject: [PATCH] *vomits* --- changelog | 4 +- .../java/api/hbm/energymk2/PowerNetMK2.java | 11 --- .../java/api/hbm/fluidmk2/FluidNetMK2.java | 80 ++++++++++++++++++ .../api/hbm/fluidmk2/IFluidProviderMK2.java | 2 + .../api/hbm/fluidmk2/IFluidReceiverMK2.java | 2 + .../fluidmk2/IFluidStandardReceiverMK2.java | 15 ++++ .../hbm/fluidmk2/IFluidStandardSenderMK2.java | 15 ++++ .../java/api/hbm/fluidmk2/IFluidUserMK2.java | 3 + .../com/hbm/inventory/fluid/FluidType.java | 2 +- .../items/weapon/sedna/mags/MagazineBelt.java | 1 + .../networkproviders/FluidNetProvider.java | 9 +- .../gui/machine/gui_weapon_modifier.png | Bin 0 -> 6764 bytes 12 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 src/main/resources/assets/hbm/textures/gui/machine/gui_weapon_modifier.png diff --git a/changelog b/changelog index d4a2c8ae3..3ba8a629b 100644 --- a/changelog +++ b/changelog @@ -32,4 +32,6 @@ * Fixed all missing texture errors that appear in the startup log * Potentially fixed a crash with mekanism during the recipe change phase * Removed the coke to heavy oil recipe for allowing infinite oil loops - * Coke to syngas and coalgas recipes should be fine though, so they stay \ No newline at end of file + * Coke to syngas and coalgas recipes should be fine though, so they stay +* Potentially fixed another issue regarding NPCs firing belt-fed guns +* Chunk-loading drones may or may not be fixed \ No newline at end of file diff --git a/src/main/java/api/hbm/energymk2/PowerNetMK2.java b/src/main/java/api/hbm/energymk2/PowerNetMK2.java index b46b66635..24be5194a 100644 --- a/src/main/java/api/hbm/energymk2/PowerNetMK2.java +++ b/src/main/java/api/hbm/energymk2/PowerNetMK2.java @@ -1,7 +1,6 @@ package api.hbm.energymk2; import java.util.ArrayList; -import java.util.Comparator; import java.util.Iterator; import java.util.List; @@ -154,14 +153,4 @@ public class PowerNetMK2 extends NodeNet { - - @Override - public int compare(IEnergyReceiverMK2 o1, IEnergyReceiverMK2 o2) { - return o2.getPriority().ordinal() - o1.getPriority().ordinal(); - } - } } diff --git a/src/main/java/api/hbm/fluidmk2/FluidNetMK2.java b/src/main/java/api/hbm/fluidmk2/FluidNetMK2.java index b5c70dd75..640f7cbab 100644 --- a/src/main/java/api/hbm/fluidmk2/FluidNetMK2.java +++ b/src/main/java/api/hbm/fluidmk2/FluidNetMK2.java @@ -1,13 +1,93 @@ package api.hbm.fluidmk2; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; + +import com.hbm.inventory.fluid.FluidType; import com.hbm.uninos.NodeNet; +import com.hbm.util.Tuple.Pair; + +import api.hbm.energymk2.IEnergyReceiverMK2.ConnectionPriority; public class FluidNetMK2 extends NodeNet { public long fluidTracker = 0L; + protected static int timeout = 3_000; + protected static long currentTime = 0; + protected FluidType type; + + public FluidNetMK2(FluidType type) { + this.type = type; + for(int i = 0; i < IFluidUserMK2.HIGHEST_VALID_PRESSURE + 1; i++) providers[i] = new ArrayList(); + for(int i = 0; i < IFluidUserMK2.HIGHEST_VALID_PRESSURE + 1; i++) for(int j = 0; j < ConnectionPriority.values().length; j++) receivers[i][j] = new ArrayList(); + } + + @Override public void resetTrackers() { this.fluidTracker = 0; } + @Override public void update() { + if(providerEntries.isEmpty()) return; + if(receiverEntries.isEmpty()) return; + currentTime = System.currentTimeMillis(); + + setupFluidProviders(); + setupFluidReceivers(); + + cleanUp(); + } + + //this sucks ass, but it makes the code just a smidge more structured + public long[] fluidAvailable = new long[IFluidUserMK2.HIGHEST_VALID_PRESSURE + 1]; + public List>[] providers = new ArrayList[IFluidUserMK2.HIGHEST_VALID_PRESSURE + 1]; + public long[][] fluidDemand = new long[IFluidUserMK2.HIGHEST_VALID_PRESSURE + 1][ConnectionPriority.values().length]; + public List>[][] receivers = new ArrayList[IFluidUserMK2.HIGHEST_VALID_PRESSURE + 1][ConnectionPriority.values().length]; + + public void setupFluidProviders() { + Iterator> iterator = providerEntries.entrySet().iterator(); + + while(iterator.hasNext()) { + Entry entry = iterator.next(); + if(currentTime - entry.getValue() > timeout) { iterator.remove(); continue; } + IFluidProviderMK2 provider = entry.getKey(); + int[] pressureRange = provider.getProvidingPressureRange(type); + for(int p = pressureRange[0]; p <= pressureRange[1]; p++) { + long available = Math.min(provider.getFluidAvailable(type, p), provider.getProviderSpeed(type, p)); + providers[p].add(new Pair(provider, available)); + fluidAvailable[p] += available; + } + } + } + + public void setupFluidReceivers() { + Iterator> iterator = receiverEntries.entrySet().iterator(); + + while(iterator.hasNext()) { + Entry entry = iterator.next(); + if(currentTime - entry.getValue() > timeout) { iterator.remove(); continue; } + IFluidReceiverMK2 receiver = entry.getKey(); + int[] pressureRange = receiver.getReceivingPressureRange(type); + for(int p = pressureRange[0]; p <= pressureRange[1]; p++) { + long required = Math.min(receiver.getDemand(type, p), receiver.getReceiverSpeed(type, p)); + int priority = receiver.getFluidPriority().ordinal(); + receivers[p][priority].add(new Pair(receiver, required)); + fluidDemand[p][priority] += required; + } + } + } + + public void cleanUp() { + for(int i = 0; i < IFluidUserMK2.HIGHEST_VALID_PRESSURE + 1; i++) { + fluidAvailable[i] = 0; + providers[i].clear(); + + for(int j = 0; j < ConnectionPriority.values().length; j++) { + fluidDemand[i][j] = 0; + receivers[i][j].clear(); + } + } } } diff --git a/src/main/java/api/hbm/fluidmk2/IFluidProviderMK2.java b/src/main/java/api/hbm/fluidmk2/IFluidProviderMK2.java index dc50f6e28..190ed8a9b 100644 --- a/src/main/java/api/hbm/fluidmk2/IFluidProviderMK2.java +++ b/src/main/java/api/hbm/fluidmk2/IFluidProviderMK2.java @@ -7,4 +7,6 @@ public interface IFluidProviderMK2 extends IFluidUserMK2 { public void useUpFluid(FluidType type, int pressure, long amount); public default long getProviderSpeed(FluidType type, int pressure) { return 1_000_000_000; } public long getFluidAvailable(FluidType type, int pressure); + + public default int[] getProvidingPressureRange(FluidType type) { return DEFAULT_PRESSURE_RANGE; } } diff --git a/src/main/java/api/hbm/fluidmk2/IFluidReceiverMK2.java b/src/main/java/api/hbm/fluidmk2/IFluidReceiverMK2.java index 551d12e66..55bdb1372 100644 --- a/src/main/java/api/hbm/fluidmk2/IFluidReceiverMK2.java +++ b/src/main/java/api/hbm/fluidmk2/IFluidReceiverMK2.java @@ -22,6 +22,8 @@ public interface IFluidReceiverMK2 extends IFluidUserMK2 { public default long getReceiverSpeed(FluidType type, int pressure) { return 1_000_000_000; } public long getDemand(FluidType type, int pressure); + public default int[] getReceivingPressureRange(FluidType type) { return DEFAULT_PRESSURE_RANGE; } + public default void trySubscribe(FluidType type, World world, DirPos pos) { trySubscribe(type, world, pos.getX(), pos.getY(), pos.getZ(), pos.getDir()); } public default void trySubscribe(FluidType type, World world, int x, int y, int z, ForgeDirection dir) { diff --git a/src/main/java/api/hbm/fluidmk2/IFluidStandardReceiverMK2.java b/src/main/java/api/hbm/fluidmk2/IFluidStandardReceiverMK2.java index 6516c9808..68bab697f 100644 --- a/src/main/java/api/hbm/fluidmk2/IFluidStandardReceiverMK2.java +++ b/src/main/java/api/hbm/fluidmk2/IFluidStandardReceiverMK2.java @@ -46,6 +46,21 @@ public interface IFluidStandardReceiverMK2 extends IFluidReceiverMK2 { return amount; } + @Override + public default int[] getReceivingPressureRange(FluidType type) { + int lowest = HIGHEST_VALID_PRESSURE; + int highest = 0; + + for(FluidTank tank : getReceivingTanks()) { + if(tank.getTankType() == type) { + if(tank.getPressure() < lowest) lowest = tank.getPressure(); + if(tank.getPressure() > highest) highest = tank.getPressure(); + } + } + + return lowest <= highest ? new int[] {lowest, highest} : DEFAULT_PRESSURE_RANGE; + } + @Override public default long getReceiverSpeed(FluidType type, int pressure) { return 1_000_000_000; diff --git a/src/main/java/api/hbm/fluidmk2/IFluidStandardSenderMK2.java b/src/main/java/api/hbm/fluidmk2/IFluidStandardSenderMK2.java index ca2fa6b77..2a1a3ce43 100644 --- a/src/main/java/api/hbm/fluidmk2/IFluidStandardSenderMK2.java +++ b/src/main/java/api/hbm/fluidmk2/IFluidStandardSenderMK2.java @@ -108,6 +108,21 @@ public interface IFluidStandardSenderMK2 extends IFluidProviderMK2 { } } + @Override + public default int[] getProvidingPressureRange(FluidType type) { + int lowest = HIGHEST_VALID_PRESSURE; + int highest = 0; + + for(FluidTank tank : getSendingTanks()) { + if(tank.getTankType() == type) { + if(tank.getPressure() < lowest) lowest = tank.getPressure(); + if(tank.getPressure() > highest) highest = tank.getPressure(); + } + } + + return lowest <= highest ? new int[] {lowest, highest} : DEFAULT_PRESSURE_RANGE; + } + @Override public default long getProviderSpeed(FluidType type, int pressure) { return 1_000_000_000; diff --git a/src/main/java/api/hbm/fluidmk2/IFluidUserMK2.java b/src/main/java/api/hbm/fluidmk2/IFluidUserMK2.java index b989e99cf..a39f40889 100644 --- a/src/main/java/api/hbm/fluidmk2/IFluidUserMK2.java +++ b/src/main/java/api/hbm/fluidmk2/IFluidUserMK2.java @@ -4,6 +4,9 @@ import com.hbm.inventory.fluid.tank.FluidTank; public interface IFluidUserMK2 extends IFluidConnectorMK2 { + public static final int HIGHEST_VALID_PRESSURE = 5; + public static final int[] DEFAULT_PRESSURE_RANGE = new int[] {0, 0}; + public static final boolean particleDebug = false; public FluidTank[] getAllTanks(); diff --git a/src/main/java/com/hbm/inventory/fluid/FluidType.java b/src/main/java/com/hbm/inventory/fluid/FluidType.java index 91bf70786..6f01bf1f0 100644 --- a/src/main/java/com/hbm/inventory/fluid/FluidType.java +++ b/src/main/java/com/hbm/inventory/fluid/FluidType.java @@ -256,7 +256,7 @@ public class FluidType { return this.stringId; } - protected INetworkProvider NETWORK_PROVIDER = new FluidNetProvider(); + protected INetworkProvider NETWORK_PROVIDER = new FluidNetProvider(this); public INetworkProvider getNetworkProvider() { return NETWORK_PROVIDER; diff --git a/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineBelt.java b/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineBelt.java index 46c91c4ba..957b1b4b3 100644 --- a/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineBelt.java +++ b/src/main/java/com/hbm/items/weapon/sedna/mags/MagazineBelt.java @@ -28,6 +28,7 @@ public class MagazineBelt implements IMagazine { @Override public void useUpAmmo(ItemStack stack, IInventory inventory, int amount) { + if(inventory == null) return; BulletConfig first = this.getFirstConfig(stack, inventory); diff --git a/src/main/java/com/hbm/uninos/networkproviders/FluidNetProvider.java b/src/main/java/com/hbm/uninos/networkproviders/FluidNetProvider.java index 95fa480a8..a4f5e4918 100644 --- a/src/main/java/com/hbm/uninos/networkproviders/FluidNetProvider.java +++ b/src/main/java/com/hbm/uninos/networkproviders/FluidNetProvider.java @@ -1,13 +1,20 @@ package com.hbm.uninos.networkproviders; +import com.hbm.inventory.fluid.FluidType; import com.hbm.uninos.INetworkProvider; import api.hbm.fluidmk2.FluidNetMK2; public class FluidNetProvider implements INetworkProvider { + + protected FluidType type; + + public FluidNetProvider(FluidType type) { + this.type = type; + } @Override public FluidNetMK2 provideNetwork() { - return new FluidNetMK2(); + return new FluidNetMK2(type); } } diff --git a/src/main/resources/assets/hbm/textures/gui/machine/gui_weapon_modifier.png b/src/main/resources/assets/hbm/textures/gui/machine/gui_weapon_modifier.png new file mode 100644 index 0000000000000000000000000000000000000000..076e7a978b19be88a2695729c33baca5456eb8d6 GIT binary patch literal 6764 zcmbuEcT|(ln#bP+ga|=G5d)$LRhkr~i9qNIs6gN+2q;~^NEMJs3ng?AQF=!yf^-N? zAaoR@NFYnfz2@$=65N!y zzPfDVj3WYYfM0wE;EDQLp&*7%bPN;F$-O%MohhuwDr}EgKbghfRmhs}&nM=KzDYv8 zUQbObZ(CGXiyBl4>nduphJaY;??%qU=%tA1ext7v>X}EEEa~`hoWHYoD4NK}4UGzo z4fF?|kMG}4R0%sX^hNcz4?UgcYH+m$B?`5^8VhT(I9(k$kt4!P*jPUtdAvTDOhVC= zcQy!qTzJlX!@U|oQT^R~JlAPB-egZdb+Yh)kw9A-wbtDFS#O@>U@8qZlx+>bZbXAr z<|XNXSM6{>E2o2GO z(?E)M;);Ux1ze966yOb$0>Zhw0Hiyd=6^CYEg8-D>+7`c`FTIG-;3v0jpz596wPg| zng!1!n#ulTv^W9-DiD?MqtAL0il^Y%OB7Ai^B9Mjr^�t&0RhC;0Nwk^QXjnW&Ef zNV_TBgUR5m&iQ%%OyBM9;~ztwxo^O6VVT>Cw9U*a$h(H`6g2azPBxHC@0eJCFlARr zz&7fn@Yty(b^Rv6<}l;Byyx~;rtejlD|s3fMjibbhC=6~#ue(%lfZ7d22h%(69guQ z8dovP4|o|mHHZnuDjHvNaK_aPRZvjiwmq-i*Vp%Zr(_8D>0Br8)<;itb2e_PRL-;SW%%;6O*=<;V4a+T%VWm}7mgL-rBM{w$PbK3O z&*;6#Q+Ol+~7e``wqL#0&ippGwl07VqmzBrLgU;qEa@+Y{ zqGNK08U!SKUU8s3-;7}CW_39!aZyTHA%s68c!+Cn%10uAz`4m& z&TBohZEnt*(tIE9f+ubRl3kX**4)o8ePp|$=g|Nz;iE5!G!r@Rv;)pi7)lMlRiT__L60gjG6rw#!v z2-60>6p94K6=|W8MwbK0K0+M22k?>ERG~+Su7Vl%{^G3XneTCqT=C<+CP}?x`22A(|PaJ zn>`w^;jAjw^5c?FuggW7)YJG(%7E;V!-E!>!D1o5?(p?qvrW-z z$|UTy!)b&C1Z&B}z?;m3>0WooRH7{%IrC=Ji;_@xEF_BYnf|c)VhoXgCpk5>?MTrW zle;=n3yik}ptyG727Iko&17?o#LfS#PgkNvk?Sk!7co|qcIWFGhwbTpXg+>GSMAK` z;ZKiD2w5pg#un$izKvIdKmyU6`Z}^^oCk{dKHI@pk9L(9d1geJU0M$4u9Zyioj%Ba zCD@cRauv!5=epc}G^rVV_o*tkM7Ftj*`b04*?1Z}Lky%Tyk9(M$_J%!DDk1|+SZx) z>pEVgn1fL`$EYA)L^!7*bq(9{ai@;#QyF7u5GO5` zBt0W%wstH!B{xY2=j6KrWt=ZG&GbaA?TAl3Rn8jf*v$+7XuQ~ zBZ%T_ICe`TBuI0Wg8nXf>rFolwUc6&bw_<}x@dbihgl8Q1TQ-}&fBmjwJ>AM9=?W} z+OKaxgh3@ct*SQA6$3hnYDu7)l$@4E?a6eH;9L1&Bt|Gv2Y%_&z!gnl{2h$9KP2s| zzDR;WiP*ztbq%uNG&uWF*;^x#)*VF?8#lMdrN_za;L75;n&vZRiE_VoNZ=O)i%;A4 z)mQCLFjK6OBtXr1c` z_ngoZ#Eo(iF&V0D9)@N`VYknw%b#r5oCx<=`7z=?l8a}tm#byNb7{3FIpK}oTfAH` zg?>I>UIZm%k{xGaqJp1AiOih5^Yp!u-<9fNW7f{j=L+<)y6DLV$c<(SGFM3JeR{1) zgL?LEBbo9g1;=8ksVsrq)E5egLn9;j*kxVR=g+_i9F2P$WXBB&#Ki5_@C*G}?Q4Db z$91-GYCMsvLUat;yI?We+(Ngz@dI6z$BXvPZdW@Vc?ivb7b`@1W$S~ zYH&>A7Z})^6`*_jwmm$TefK*wdiE92AnT{ZP;MZ4tP{(PJ%hInpKxiR*)@f}XAjEW z+4?K7=(crCMFk6O4s#yAmR7H1O6$=PYjtc+5Kxoy4AyQVbUw21FHtgOx8`2j$g8W7 zId~)1PBegldaaK~J|lmux4IXXn|5njkFFs_k>Qze*4{n7R zN%Q`fT(^Y{#KP)!N+&8@rXTh7nRjgc>~=dj!iF!_)2m?M>^;${@ukX!uO{1pI-LQf zJ;jX%$~}!;TJ3aRh~K;S&U**Oxo+=os{Qn3XF=Bvh9tH}4rWFFC5*-cgUpZ3@u-s*b;$N6 z2iC| zH%_rp@BKkfC=SEkEj1_K6~T6;{Q0!gxZkR{*j1yU!fuFK%Tijy?lW5tKfT#e1@)%; z>Kt<4e*~d0L`MFV z8ak?Mux{bu`L5WyZi65#I}iX1#S(5sXu-V;Wvu~@1?zC4F2*uauW$rR1x@6hqAL|uxX{URg2>g=y@=~%3St_Qc{Y{zA zt&kn5EkhL&2<(FkmGQ74ZPyEHzmw{;|oaDSPCGGr(Cz+j43;{8}OT`b!q?iTuF`4MY|0mCe}`; zc158AII~XY>~|tiDXNKfgDL%EbiRAM`T2ym==Td(lpY`nvJ>Gz z5mtVPaN5RkU`i91l~t0=87x1P{9Pe-Y`|4z@UJ!SB(T(<(fxLMpQArRDNGW|LVMuJ ztTfO*WE?vi5pbg1pA~T7rT=l6>wJ$v2p*Q_ewL4~U6M2thT7+8KCYb(G$IbVvgEk~ zQP5ExrYJ_;LZg-Nx3mULpum3c`#iP5jmP_$8gTD$LndKbyJoyoTlcF1a z!gRXi(wrf2<&lWB$5UFHpM3CX=^*)7{bJcT4TERv9lq&S6(k&aK{x%1W2pQn#E<#A z?QL|7yA+Nr91Xotfmzi+pf0Ukpd&JQ&5ar+*SoR+n}{-QGq<$7PJyHSPXWO&aP5>A zhH}EMy;+8OQFQEdHBSRZJMP;{i-g9%5U`l9yMdFJeS-qmKvni)Ts^2u1q*?%@E z>frt7us`H^Ty`)V@N+%cJXo{U}N;*HW6@Y-}Q=UE)e;cU({;B`hDZyA9Uos*~#cu-)wveHm9uP9)v3ACl ze*UVL&v9rMvFtPG=mhO&(b^y!4ot=4)87;fd(@%%=B+-x`@j`p( z&zlur_FGL02$q{l?@v<1T(WaG`S8`oB+b}s+8E-?tepyiL1@aFQY*;|V-MocmV5kH z=<7qM!!*T+iHWHRTpXjXbyzju0A006fv4qpE8 zv$tPN>n*5VgQI$UL-9=fz&Ekp5x zw`P3CKe+++lEC5eT1wUaCqq={an=dD^F&qSQiapRl?t0~uRD5Kt(_^l0B&o`je9@g zSbl3o`0JCJ%=N1{#;OcA9BIb7=z51EU7oEnkI<($ey+|SW)q|inzngN(K>G6!nmU8 zMoQ70;HZoy<(uErp}z;ozMz29ag^1I!;C*RdZ%kQxKUo*I>NqdKM|c_D0d0*k3Jw2 zcBMcx(Q{*1F<-Eo$4R7tjLI|R)3P6X+T8Nx%)n+q%N|X-@^Myi z;`PR_ob)}{Mw&Ga(O1>#;lQ%Fl<=lv@*)Oq!=rJs-eT0-eV*XNWe3RPK;^26r;`J2 zhhH(h8%or}>*m*%lbe+vo}ZabsO|!p8egm=fn^auA2VZ7zra_10K;;H3y*Z+>3H8Y z?#faXC9{^EPK>DSFFC%L$Akx!2U2A<<9xFIy^?DCrW7C9%&lhQ`E%Ut4*rfSoQpZRfPHfL2r>$J1rZx{jT9 zQ)z9y?LlC0EJ)IFP8u&Oi$V|y1BaTqGE}ONqDoRqv>dt&ed35fG7ej&$Q))Hu@!@$@_HTp3YdyW;Oy{ckVxh))_b)M!D4&**dl2JvdLW;B3gz2k>0atMi& zhRDOW03McBk6)w-Fo@^#JTYf0;Yu|se0`1N{Z;NJaeFQaR2sonySUl+onIybeU*8Op^ZT zJ{ueZlEi&@a9n8}Q+K^eLc8iu1IXb~RpC;+Eyu%`BS>oiiX0lXttGXAZ(INP=;vwo zuvdoR*J3LGSGlkxx~YT@LIA)@4BX)R!Qx&!ENr8Jri)9OOX_6(*98SV0!KxEH*DJt z+zW$SLUADJMw8ApYtPZ{?yl}lVrEkudTu!HhQ_Cn5A(5e20*t^-X_K3gmsu7k7h`d z)0?UFr^wwHUlJk!+&ed0C})fk6F0jgrqyPa*l_2j{I2{VPlt^?GV`lo;krXzz}vzV z&&JrBw{~4}On-T>h>VI*5k@=U3Tp(;33Kf9`pc}uWKu3%;Ha=$9ks~9Ir~#z`nu|A z!U$#B6aP(3x-Wn9I^0!WKflXHRgPquuHeaKp>PD#x^;^sl;@n^43g^gLM+0kX1ei~ zA5jYERy+ts{Omp5l|0$kYaagiw62rw^vKUhB*CA|wF{ylN_D|~DK0Hh?)A~=_u=*R zSli-sMUCK>pqWC`60dKg_#P#0n!kaV58a?MvFbi_+;Z!o}O07-LLf!wFdq_VcdTJz0O6t!6l<7)c%UOO;KRn z@pp?OVZe3vOoQ+dl^+AR+5jv^&nfeW%-=BG<^16%CnMh-cC*%&nvXdB>pTo+;l$n5 zlg+garJIKYJ`LmGga9Y8Q^3jMPtfv8#Wowu-xtqcDQCxPn~)6(>9o~a-=&1tCNi;Vws$sCWi`y^Uq;tI%=hmMrH~GHS>GGg{&l>t z-fx==uA14q?dJnc`a>ncM8PG9SkV73sQ$Ct!NdBwNEMBXEXK5^H~%hBOXVRwe+541 z*AlWnC?ZyS)rm;{$2eSH9G5fxukR%OZchJojq$UHC}!WDq`n$f3?8{leUx4L8^N4K zN)}NiOw2f#+PHm|Um`;Mm5u3DU~B7Tz{j$iY92E3K%H!20FEHxqw2A1au5;zPm2Tc aI6&Gjs34)wBcFPG1ZZpC(