From fa6495ceebf072ccd0dff3e80a2fdafe0e129e50 Mon Sep 17 00:00:00 2001 From: Anuken Date: Tue, 26 Sep 2017 17:03:17 -0400 Subject: [PATCH] More balancing --- .gitignore | 1 + .../io/anuke/mindustry/AndroidLauncher.java | 20 ++++++++++++------ core/src/io/anuke/mindustry/Control.java | 15 ++++++++----- core/src/io/anuke/mindustry/Mindustry.java | 16 ++++++++++++++ core/src/io/anuke/mindustry/UI.java | 4 +--- core/src/io/anuke/mindustry/Vars.java | 2 +- .../anuke/mindustry/entities/BulletType.java | 4 ++-- .../entities/enemies/BlastEnemy.java | 2 +- .../mindustry/entities/enemies/Enemy.java | 12 +++++++---- core/src/io/anuke/mindustry/io/Formatter.java | 8 +++++++ core/src/io/anuke/mindustry/io/SaveIO.java | 16 +++++--------- .../io/anuke/mindustry/resource/Recipe.java | 12 +++++------ .../io/anuke/mindustry/ui/UpgradeDialog.java | 3 +++ .../io/anuke/mindustry/world/Generator.java | 2 +- .../world/blocks/ProductionBlocks.java | 6 +++--- .../mindustry/world/blocks/WeaponBlocks.java | 15 +++++++------ desktop/mindustry-saves/0.mins | Bin 6955 -> 10994 bytes desktop/mindustry-saves/1.mins | Bin 1357 -> 11100 bytes desktop/mindustry-saves/3.mins | Bin 0 -> 12697 bytes .../mindustry/desktop/DesktopLauncher.java | 16 +++++++++----- gradle.properties | 2 +- .../anuke/mindustry/client/HtmlLauncher.java | 18 +++++++++++----- 22 files changed, 112 insertions(+), 62 deletions(-) create mode 100644 core/src/io/anuke/mindustry/io/Formatter.java create mode 100644 desktop/mindustry-saves/3.mins diff --git a/.gitignore b/.gitignore index bafe066cda..b77615b838 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /deploy/ /desktop/packr-out/ /desktop/packr-export/ +/core/lib/ ## Java diff --git a/android/src/io/anuke/mindustry/AndroidLauncher.java b/android/src/io/anuke/mindustry/AndroidLauncher.java index f847e53a79..24f61c1e50 100644 --- a/android/src/io/anuke/mindustry/AndroidLauncher.java +++ b/android/src/io/anuke/mindustry/AndroidLauncher.java @@ -1,15 +1,14 @@ package io.anuke.mindustry; +import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.Locale; import com.badlogic.gdx.backends.android.AndroidApplication; import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration; - +import android.annotation.SuppressLint; import android.os.Bundle; -import io.anuke.mindustry.io.SaveIO; -import io.anuke.mindustry.io.SaveIO.FormatProvider; +import io.anuke.mindustry.io.Formatter; public class AndroidLauncher extends AndroidApplication { @Override @@ -18,13 +17,20 @@ public class AndroidLauncher extends AndroidApplication { AndroidApplicationConfiguration config = new AndroidApplicationConfiguration(); config.useImmersiveMode = true; - SaveIO.setFormatProvider(new FormatProvider(){ - SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss", Locale.ENGLISH); + Mindustry.formatter = new Formatter(){ + @SuppressLint("SimpleDateFormat") + SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm"); + @Override public String format(Date date){ return format.format(date); } - }); + + @Override + public String format(int number){ + return NumberFormat.getIntegerInstance().format(number); + } + }; initialize(new Mindustry(), config); } diff --git a/core/src/io/anuke/mindustry/Control.java b/core/src/io/anuke/mindustry/Control.java index b828f521c2..488570801a 100644 --- a/core/src/io/anuke/mindustry/Control.java +++ b/core/src/io/anuke/mindustry/Control.java @@ -95,8 +95,8 @@ public class Control extends Module{ spawns = Array.with( new EnemySpawn(Enemy.class){{ - scaling = 2; - tierscaleback = 4; + scaling = 3; + tierscaleback = 3; }}, new EnemySpawn(FastEnemy.class){{ after = 2; @@ -114,7 +114,8 @@ public class Control extends Module{ }}, new EnemySpawn(RapidEnemy.class){{ after = 7; - spacing = 4; + spacing = 3; + scaling = 3; }}, new EnemySpawn(TankEnemy.class){{ after = 4; @@ -129,13 +130,13 @@ public class Control extends Module{ ); - /* + //TODO remove this debugging for(int i = 1; i < 60; i ++){ UCore.log("\n\n--WAVE " + i); printEnemies(i); } - */ + } public void reset(){ @@ -250,13 +251,17 @@ public class Control extends Module{ } void printEnemies(int wave){ + int total = 0; for(EnemySpawn spawn : spawns){ int spawnamount = spawn.evaluate(wave, 0); + total += spawnamount; if(spawnamount > 0){ UCore.log(ClassReflection.getSimpleName(spawn.type) + " t" + spawn.tier(wave, 0) + " x" + spawnamount); } } + + UCore.log("Total: " + total); } public void enemyDeath(){ diff --git a/core/src/io/anuke/mindustry/Mindustry.java b/core/src/io/anuke/mindustry/Mindustry.java index c98842a851..ba9a7a05f7 100644 --- a/core/src/io/anuke/mindustry/Mindustry.java +++ b/core/src/io/anuke/mindustry/Mindustry.java @@ -1,12 +1,28 @@ package io.anuke.mindustry; +import java.util.Date; + import io.anuke.mindustry.GameState.State; +import io.anuke.mindustry.io.Formatter; import io.anuke.ucore.core.Inputs; import io.anuke.ucore.core.Timers; import io.anuke.ucore.modules.ModuleCore; public class Mindustry extends ModuleCore { public static String[] args = {}; + public static Formatter formatter = new Formatter(){ + + @Override + public String format(Date date){ + return "invalid date"; + } + + @Override + public String format(int number){ + return number + ""; + } + + }; @Override public void init(){ diff --git a/core/src/io/anuke/mindustry/UI.java b/core/src/io/anuke/mindustry/UI.java index 9bbe03a06a..793745e5be 100644 --- a/core/src/io/anuke/mindustry/UI.java +++ b/core/src/io/anuke/mindustry/UI.java @@ -3,8 +3,6 @@ package io.anuke.mindustry; import static io.anuke.mindustry.Vars.*; import static io.anuke.ucore.scene.actions.Actions.*; -import java.text.NumberFormat; - import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; @@ -701,7 +699,7 @@ public class UI extends SceneModule{ for(Item stack : Inventory.getItemTypes()){ Image image = new Image(Draw.region("icon-" + stack.name())); - Label label = new Label("" + NumberFormat.getIntegerInstance().format(Inventory.getAmount(stack))); + Label label = new Label("" + Mindustry.formatter.format(Inventory.getAmount(stack))); label.setFontScale(fontscale*1.5f); itemtable.add(image).size(8*3).units(Unit.dp); itemtable.add(label).left(); diff --git a/core/src/io/anuke/mindustry/Vars.java b/core/src/io/anuke/mindustry/Vars.java index 7da5cbb7f1..382a12fc0e 100644 --- a/core/src/io/anuke/mindustry/Vars.java +++ b/core/src/io/anuke/mindustry/Vars.java @@ -14,7 +14,7 @@ public class Vars{ //respawn time in frames public static final float respawnduration = 60*4; //time between waves in frames - public static final float wavespace = 25*60*(android ? 1 : 1); + public static final float wavespace = 30*60*(android ? 1 : 1); //waves can last no longer than 6 minutes, otherwise the next one spawns public static final float maxwavespace = 60*60*6; //how far away from spawn points the player can't place blocks diff --git a/core/src/io/anuke/mindustry/entities/BulletType.java b/core/src/io/anuke/mindustry/entities/BulletType.java index 40ddf23f25..24c364168b 100644 --- a/core/src/io/anuke/mindustry/entities/BulletType.java +++ b/core/src/io/anuke/mindustry/entities/BulletType.java @@ -31,7 +31,7 @@ public abstract class BulletType extends BaseBulletType{ Draw.reset(); } }, - sniper = new BulletType(3f, 20){ + sniper = new BulletType(3f, 23){ public void draw(Bullet b){ Draw.color(Color.LIGHT_GRAY); Draw.thick(1f); @@ -45,7 +45,7 @@ public abstract class BulletType extends BaseBulletType{ } } }, - shell = new BulletType(1.1f, 80){ + shell = new BulletType(1.1f, 85){ { lifetime = 110f; hitsize = 8f; diff --git a/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java b/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java index 1e1dc26315..2142dbbf23 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/BlastEnemy.java @@ -7,7 +7,7 @@ public class BlastEnemy extends Enemy{ public BlastEnemy(int spawn) { super(spawn); - maxhealth = 15; + maxhealth = 30; speed = 0.65f; bullet = null; turretrotatespeed = 0f; diff --git a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java index 332667fa3e..0c4a934ce6 100644 --- a/core/src/io/anuke/mindustry/entities/enemies/Enemy.java +++ b/core/src/io/anuke/mindustry/entities/enemies/Enemy.java @@ -23,7 +23,7 @@ public class Enemy extends DestructibleEntity{ public final static int maxtier = 4; protected float speed = 0.3f; - protected float reload = 40; + protected float reload = 32; protected float range = 60; protected float length = 4; protected float rotatespeed = 7f; @@ -47,7 +47,7 @@ public class Enemy extends DestructibleEntity{ hitsize = 5; - maxhealth = 50; + maxhealth = 60; heal(); } @@ -104,17 +104,21 @@ public class Enemy extends DestructibleEntity{ } node = cindex; + + //node = 0; + + //set(World.spawnpoints.get(spawn).worldx(), World.spawnpoints.get(spawn).worldy()); } @Override public void added(){ if(bullet != null){ - damage = (int)(bullet.damage * (1 + (tier - 1) * 0.5f)); + damage = (int)(bullet.damage * (1 + (tier - 1) * 1f)); } maxhealth *= tier; speed += 0.04f*tier + Mathf.range(0.1f); - reload /= Math.max(tier /1.5f, 1f); + reload /= Math.max(tier / 1.5f, 1f); range += tier*5; heal(); diff --git a/core/src/io/anuke/mindustry/io/Formatter.java b/core/src/io/anuke/mindustry/io/Formatter.java new file mode 100644 index 0000000000..d6dc1278dd --- /dev/null +++ b/core/src/io/anuke/mindustry/io/Formatter.java @@ -0,0 +1,8 @@ +package io.anuke.mindustry.io; + +import java.util.Date; + +public interface Formatter{ + public String format(Date date); + public String format(int number); +} diff --git a/core/src/io/anuke/mindustry/io/SaveIO.java b/core/src/io/anuke/mindustry/io/SaveIO.java index 5f360e9841..980141f3eb 100644 --- a/core/src/io/anuke/mindustry/io/SaveIO.java +++ b/core/src/io/anuke/mindustry/io/SaveIO.java @@ -15,6 +15,7 @@ import com.badlogic.gdx.utils.TimeUtils; import com.badlogic.gdx.utils.reflect.ClassReflection; import io.anuke.mindustry.Inventory; +import io.anuke.mindustry.Mindustry; import io.anuke.mindustry.Vars; import io.anuke.mindustry.entities.enemies.*; import io.anuke.mindustry.resource.Item; @@ -85,8 +86,6 @@ public class SaveIO{ /**Save file version ID. Should be incremented every breaking release.*/ private static final int fileVersionID = 7; - private static FormatProvider provider = null; - //TODO automatic registration of types? private static final Array> enemyIDs = Array.with( Enemy.class, @@ -126,7 +125,7 @@ public class SaveIO{ try(DataInputStream stream = new DataInputStream(fileFor(slot).read())){ stream.readInt(); Date date = new Date(stream.readLong()); - return provider.format(date); + return Mindustry.formatter.format(date); }catch (IOException e){ throw new RuntimeException(e); } @@ -147,10 +146,6 @@ public class SaveIO{ return Gdx.files.local("mindustry-saves/" + slot + ".mins"); } - public static void setFormatProvider(FormatProvider prov){ - provider = prov; - } - public static void write(FileHandle file){ try(DataOutputStream stream = new DataOutputStream(file.write(false))){ @@ -290,6 +285,9 @@ public class SaveIO{ //weapons + Vars.control.getWeapons().clear(); + Vars.control.getWeapons().add(Weapon.blaster); + int weapons = stream.readByte(); for(int i = 0; i < weapons; i ++){ @@ -400,8 +398,4 @@ public class SaveIO{ throw new RuntimeException(e); } } - - public static interface FormatProvider{ - public String format(Date date); - } } diff --git a/core/src/io/anuke/mindustry/resource/Recipe.java b/core/src/io/anuke/mindustry/resource/Recipe.java index 335be66618..7b81c9cb4e 100644 --- a/core/src/io/anuke/mindustry/resource/Recipe.java +++ b/core/src/io/anuke/mindustry/resource/Recipe.java @@ -21,10 +21,10 @@ public enum Recipe{ router(distribution, ProductionBlocks.router, stack(Item.stone, 2)), junction(distribution, ProductionBlocks.junction, stack(Item.iron, 2)), - turret(defense, WeaponBlocks.turret, stack(Item.stone, 3)), - dturret(defense, WeaponBlocks.doubleturret, stack(Item.stone, 6)), - machineturret(defense, WeaponBlocks.machineturret, stack(Item.iron, 7), stack(Item.stone, 10)), - shotgunturret(defense, WeaponBlocks.shotgunturret, stack(Item.iron, 9), stack(Item.stone, 10)), + turret(defense, WeaponBlocks.turret, stack(Item.stone, 4)), + dturret(defense, WeaponBlocks.doubleturret, stack(Item.stone, 7)), + machineturret(defense, WeaponBlocks.machineturret, stack(Item.iron, 8), stack(Item.stone, 10)), + shotgunturret(defense, WeaponBlocks.shotgunturret, stack(Item.iron, 10), stack(Item.stone, 10)), flameturret(defense, WeaponBlocks.flameturret, stack(Item.iron, 12), stack(Item.steel, 9)), sniperturret(defense, WeaponBlocks.sniperturret, stack(Item.iron, 15), stack(Item.steel, 10)), laserturret(defense, WeaponBlocks.laserturret, stack(Item.steel, 10), stack(Item.titanium, 10)), @@ -32,8 +32,8 @@ public enum Recipe{ teslaturret(defense, WeaponBlocks.teslaturret, stack(Item.steel, 10), stack(Item.titanium, 15), stack(Item.dirium, 15)), plasmaturret(defense, WeaponBlocks.plasmaturret, stack(Item.steel, 10), stack(Item.titanium, 10), stack(Item.dirium, 15)), - healturret(defense, WeaponBlocks.repairturret, stack(Item.iron, 25)), - megahealturret(defense, WeaponBlocks.megarepairturret, stack(Item.iron, 15), stack(Item.steel, 25)), + healturret(defense, WeaponBlocks.repairturret, stack(Item.iron, 30)), + megahealturret(defense, WeaponBlocks.megarepairturret, stack(Item.iron, 20), stack(Item.steel, 30)), drill(production, ProductionBlocks.stonedrill, stack(Item.stone, 16)), irondrill(production, ProductionBlocks.irondrill, stack(Item.stone, 25)), diff --git a/core/src/io/anuke/mindustry/ui/UpgradeDialog.java b/core/src/io/anuke/mindustry/ui/UpgradeDialog.java index 3adf08de73..223f177c4a 100644 --- a/core/src/io/anuke/mindustry/ui/UpgradeDialog.java +++ b/core/src/io/anuke/mindustry/ui/UpgradeDialog.java @@ -60,6 +60,9 @@ public class UpgradeDialog extends Dialog{ button.setColor(Color.GRAY); }else if(!Inventory.hasItems(weapon.requirements)){ button.setDisabled(true); + }else{ + button.setDisabled(false); + button.setColor(Color.WHITE); } }); diff --git a/core/src/io/anuke/mindustry/world/Generator.java b/core/src/io/anuke/mindustry/world/Generator.java index c5bd03ee2f..60f89f5bba 100644 --- a/core/src/io/anuke/mindustry/world/Generator.java +++ b/core/src/io/anuke/mindustry/world/Generator.java @@ -58,7 +58,7 @@ public class Generator{ floor = Blocks.iron; } - if(Noise.nnoise(x, y, 6, 1) > 0.24){ + if(Noise.nnoise(x, y, 6, 1) > 0.238){ floor = Blocks.coal; } diff --git a/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java b/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java index c9e75ba886..4665fde7f9 100644 --- a/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java +++ b/core/src/io/anuke/mindustry/world/blocks/ProductionBlocks.java @@ -122,7 +122,7 @@ public class ProductionBlocks{ liquidAmount = 19.99f; output = Item.coal; health = 50; - purifyTime = 80; + purifyTime = 70; } @Override @@ -135,11 +135,11 @@ public class ProductionBlocks{ { formalName = "titanium\nextractor"; input = Item.iron; - inputAmount = 11; + inputAmount = 6; inputLiquid = Liquid.water; liquidAmount = 40f; liquidCapacity = 41f; - purifyTime = 90; + purifyTime = 80; output = Item.titanium; health = 70; } diff --git a/core/src/io/anuke/mindustry/world/blocks/WeaponBlocks.java b/core/src/io/anuke/mindustry/world/blocks/WeaponBlocks.java index 23286e2abc..d49786fe43 100644 --- a/core/src/io/anuke/mindustry/world/blocks/WeaponBlocks.java +++ b/core/src/io/anuke/mindustry/world/blocks/WeaponBlocks.java @@ -98,10 +98,10 @@ public class WeaponBlocks{ { formalName = "railgun turret"; range = 120; - reload = 60f; + reload = 50f; bullet = BulletType.sniper; ammo = Item.steel; - health = 60; + health = 70; } }, @@ -111,7 +111,7 @@ public class WeaponBlocks{ rotatespeed = 0.1f; formalName = "flak turret"; range = 120; - reload = 120f; + reload = 100f; bullet = BulletType.shell; ammo = Item.coal; ammoMultiplier = 5; @@ -128,9 +128,10 @@ public class WeaponBlocks{ formalName = "laser turret"; range = 60; reload = 4f; - damage = 9; + damage = 10; ammo = Item.coal; health = 110; + ammoMultiplier = 60; } }, @@ -139,7 +140,7 @@ public class WeaponBlocks{ { formalName = "tesla turret"; range = 70; - reload = 20f; + reload = 15f; bullet = BulletType.shell; ammo = Item.coal; health = 140; @@ -151,7 +152,7 @@ public class WeaponBlocks{ Angles.translation(entity.rotation, 4); new TeslaOrb(tile.worldx() + Angles.x(), tile.worldy() + Angles.y(), - 70, (int)(8*Vars.multiplier)).add(); + 70, (int)(9*Vars.multiplier)).add(); } }, @@ -161,7 +162,7 @@ public class WeaponBlocks{ inaccuracy = 7f; formalName = "plasma turret"; range = 60f; - reload = 3f; + reload = 2f; bullet = BulletType.plasmaflame; ammo = Item.coal; health = 180; diff --git a/desktop/mindustry-saves/0.mins b/desktop/mindustry-saves/0.mins index 4646b8f1e13663757ac19e098492831f69a8d721..dc050ee814c221015975d38ed6d2ec0f5cbd44b8 100644 GIT binary patch literal 10994 zcmZQzU|?rpV2sR1A_`9 z0|VoHCI$uuE|7W#CYJ!48!ni~ILEINa{hRY6~bk5v5yyXzEv0l;&L%C zI5&S^<^06%G>B`&z~tiohr{`^RS$&A;2d_@-$hXN6@<&=5|F0kBJWlQ;W9Xfa(!_T z{mBC1GP1_ldhkO)5mgMbW_p#o+IFfeG$ z0f`7OFc^Rt{0t1T^FSi}3=GC#h9Coj`h2K}_#!AnUK!+gSrAVML@+Qg$S(#9fnrVr zB*e%N+`zz~08t1MRe*?cgG3Q()j*;Q3=E10g<$Or3=A5|AUQz>26<2_U;x_&mSbd) zYG7cHUjnjF6=bvqhy_xt09L6AVj{#K>QKZKv8a<*1(||u%V&@+OF85rc%P^B3d z7-W}&gmgiK8zYEhU|?XJz`!7<4&s2-Yk@^_$;1msscTgJ90gJ&xNEV_5#+3te5ypdT z1ZzMDu`|>(fU=T)0|R#h!>a~{6AcV)4Gau2Ye5Dh)Pd{*Cq+~th$@(UAdkvHRKbN9 z89^CU4ox8=V^A&wgFHknNE;}A85kK<8yFY_^-!&5WVBhvz#zB|EDAT5fq_8?tPnK< zg}};C14$UH4#nY;>p+(BGcd@2)uYJCVk(zM6Jlhz338}D*hwIhAkJqz3=&-r5=C`^ z5Ee0E4BhUaa0jbIbq|_CP%L5!2^xT`MbRj@0VIUx5-eiEXj&N=K`s$D0C@})L|`po zlfhXB5~H$cnwS{f8yG>+CkN9fkEViwfkDs^NUSurgWX z6d_>IPNMIXC4l+xO6BroeArf%q3=9k=+dw=}vu!)r$siusLPo|yP;f&;k)0s} z5kgYP2ugq8hA1K&m>BFDz}2uKnsNpP1|_gs)U2(%9b_QL9Xrt7@fYL{h$!40j7*@? zNd_Vc(g}4l$SHDQQIu>iZ-Htk0|SEsL={LJ7MhA+RnpM-;bLG=1gk-K3gmXM8dSF{ zft8_(DTCFaXcgEAvJ4>v31RV_Am1eI!M&3KY|oz-myvq6Ah3 z&Ze-CQU)tS(J8PCLkt3=9eo70`fVVPH@Ms{nVxpa}r1LItD((wAUk&|qLt0xLt5 z7NA59R)`{`jHyasH#q*_4rO3q5Z(>q2{15-p~*2afjTDRwR)rEU0((GVg~(4#jEoJ8_Zk=&#Ly%_me_#Qg8P=B zAW#IWfOD0QWI^gc!yHOTN?>9}d!UgguoonRWHob9Gb5;07PJLRz=N8R5tP0KA<7Y= zOrQpd5QbV%r%VW4E!a!KXlj|6&o?lxY+wZSL4?tCFfcHPpebi$0#y+rXbKq_Kvje& znp!3XUr1gRMN`hic)o#U0w{dZbTBi;HZWQ?FoJTS7@8(VW+ zgTMihI)weKjG2uL;En+kV*?{7j77jI;FgIxfHc4@6NSiv#6Wh7A!I>~A2C!}afmG3 z-C$X5Fc)M1h`~6Sfk6UQnFLrF+(t>TEZhT<2SC~c7#K7iKny_!2F`;Zh5!QtuOo;d z$iN_Q5M(^UlS~YmjS#gPC3KL%E!RoX?E{2GKat6p_V6||MiGh`&1hF_o1xP0-&4`0lpe2Jj z3=9$oWyTB)3=&{vaC0TWvT)xig2sy(1Q-~sU<`r7AU7j?$HJJ|$mrg{q6$gYg3cgm zByWPcwqPx&VnPsgAjNQR3PIF?#J~fGpi){GT^$z#gD^rJT(1a39mw+tF^D>Z7!w17 zC|Dg@DvRC5V11E6au&mnJces$7`9Gem^y=@!IXhP6l?;z>Usw26$}y+7=HRP+}y^n z)0JUbI734U1A`dYY_v4FkbyxAYzjO9iG!7)MjfgO35W_%K)~{k1XzU#NC;HENP<P(-R80cjIpU{C`y1Q{5NT%aNXM?rcZQ3zszgauteEU*}O;2SK4u8xs`K?tG_ zq!^wZguv<$jY=kl#6CvL1_lOUEQ*D}iXjaskSU;X0TGBgkezTtMIh=BV$2K-qF{B1 z1jPj^$)iIUtoAa9=Q4bq!*IQZVVgC>)T0ayu?!7G3=E=RL(nv2wJ>oYQXvUe0nceNM?qRa^`a|?A;`d>1!jPzkzi8hUvsLCY3%HZZof@R?zS3CwX4&+}qD8m%Y5MW>sIu3F?!keIWIy0yO++!?Jva z36mKb3>g^2z(%5_iUkY|Vqk;d9utQs133-RCYZs%AP!cB8ZQz!)JlNW!i#iCurfqg z9S0dM$iTqw0c8lC0C^MC zDFb^06n?%SwGg*~xR@$r!9rlCp<3q$G6xi!=RigvtOK>-{XjzCf)6}F2T}=gq9j-; zSR5s0q`=~cHasZMz(OV z5T;us{6R{Q8X7DN3=%lhN`lp5njr~Rk7NcD1A`PcwTl@Tq`+!Xd?gJQ0{b1-2#^8m zMyO(h%oLpmg{&Y0gCdv#iVW}y85EC71b{q*#gSlf@PwreBPa(jfY#hFFi3)pKvNHL zC|Dff1W+V_jX@>{3QX6ObsHa!^)5Cl(CDHVNrmMgjza%nW>py&mwf>;TQOBqaMGGJxsb9M}% ztjoo~pc)8rp8x}cbPzc5K*C`6fKtFE3?bfNkaAEd24hGEVN|~i~>y!UIytC zU|>*%F^s_sK?Vlt5V&f%#UUWof(#5YS5W1cnD#X=frjQ(!74y0@hV6u$o-+HNqcs2vM?~nL)3!IK$O!{7#OU>p&k&w0cA)>fE1zF zEqwzl1WKLoK!K=25yDg@i>XQutO}(hln1Lq^T#{}2H8lkwaCd!_9j>e*;+Y>Dik41 zRkBeajVRX2-U11sSqob91r|pM0L5FNz!6|zkd4N!NA@;I94W{_3&n7#l>@6qG2bW} zWIkx1(-Ajv~ifdY*KWD%%n zh=p5(Xcf$6V358G5=ZhHCj)~FLMmj)G4Ne40b z85pEqKp83-P=*#*M1X<81k4a*U@!$s2{JIKzJ#h#2Qvg27_4(ZA_5Ey7H^>pj`tvj LAOnMWA(#OG4ZBSI delta 2818 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 literal 1357 zcmZQzU|?flV2s<%ledL|fq}(kcLRe92Lpri@&gPE3=Am@Y|IRDEe(tyf(1mdf(Ql> z!2}{07#R2&7@V~fU0v!x8W@Zi7+u(IO2K(dE`hi9yHxAtFfcF}F)%o*i*JX^F}kp+ z@W6RYE^&U$f4F15?2FfcI4F*3TauixrY>-q-FV{!@Hn(R_}>pY0Z zz~HPpJp^tFqYG=`TR0D5W-Y%d)J)BfiBLI^nQSJ}a2}IO;4@B_>M4y7GZ~e785kI{ z85nfMLEhqLU@(C(6lX(4)TE&d4H!dp4oF0Rfk6Yt(31g)@G~%&!x*~rpduFYK@33# z1|0`;&P9UxI zh`=cjLy&=i?=*-Zz`!7L7RnGk2W5!+gBT!PFoqJCA;7>O9|V;$g)xLKgG2-v7^Gng zm0+ldDOg01fkEX8NJNl~p$tPXLx6$7 z;5Jl5>JF44b{E6|NyS1LQgI*#D9-MK7y=9o3JD+vKLdmI0}w-yfk7l0%8+^tV(>FC zs6B-;bW=eL0R{%H=THVOj3NC3B*M?YUNa4Lu)z`&p- z24!eYhcb+2fEfG?3<@(D85kJAS_2pu7!+rM#03}_-h+tq~P{1NI3#1C6 z8>|A(RRwv5fuDgvP8y^P#W1h{4ampr#ID2rw{+uK+Rl85m?&fDBRt5%7d1rvc)cfU+7ak;{XH zWI>uh*$qTXt^|=FBQ!CT%dP|o>3~dd1SeNeGM>o5AO}{e1`-DuBL`LnHdPa37y|=? zJXi%-2&4ieDi2nr3f2TN79^$)wj7j)!5Re_7-Y3TaylSMgq8Cd7-Uz0#L;2_tQO)7 znDgYo>QF5PD?=3mt3q{)%xaLOpn%W@S%t+3t3l#uP5`R~N1!c8I|BoQ99S8ubzoJf zLSR*>E|Ap$TL2Cr1_lP%H7Hy;Fc;Mjum%(%SzVAORH3zCA(*iYjEuh<7#QRr3Xwz^ zK%!`BK~V`&2=W~`Dj6B78Wm?8L)b=95|7HLIzX0ELfEZ$OZ7kj;0FgaD9*(uyJ7TfE>OaB!ucB zAuM9Tm|A7P%1}&`#Z)DaCIoef0mxbuy@DG+LTE0*A|{NfRonm;USRbo#>!$UmxC#n z$CMK^1i1oX0wZH7D8@IUih`mStPst)n978~%4CrfhJ+!^wV29fA<97tz%j(c$k4!e zr-6Y%7Od73BoPH7K#3DgEdv7s-zJb8KLdlH5!k^X0&ET_rZ<6j;93ACBm_|f(gPM^ zWQ?s~U=V^RM0T~14`17ho}OX0agWZsK7RmAqcO7BHIis1UHV65#%F5h(aV$P`M|Bp_XMg z1A`PqEy#`9Ap2OD>KmA%bD30S-!-kPJi>$SrUouquRO z8JWL9_?uNy=B8nOo1_nj28WeMsz-mwfO$n?FRZJPI4n?cL zPLO2?Atpx22F5oH3=E=R301H^K}s077#PGXK`b;eBz2%(+fI-U0R{#susFEEslf;e z8c;R{iy@5*3Zw!epok*C%D|uq)`H>;C9oRQ&{6^`Ly3H4urd^#0=qzAf)HY46aj^v707-; z1_m)SX;2VZfptJ#3{uA+4pD_HB!Q_)5=|8+GpJZO%3vADAi0A1&rFs(8yNQGGt75p zZYX77kU}#6qIv>@}+6|mBZ4I$-p3mZZ=bW14HyI2HR!Ka;F&n zEM~af$+EM7d8RKzLmC5vG@98=4D}5x(G3g?(rCtjA{|XFBSQ+P-a=Ez$dJ;*z#t0| z1;sEtHK1t+wUi;M;GxCHGyzn7Vk(peE0ls72TB`YHL%3O!N8yZQ2{jyl)Jzxz&%b4 z@OXqGScM8m1*A*P%%H}=pafQiQsydw6`}|!W2zF^4UT+Jtb={X$hfkBfkAjTNI-yr zK@3eAlw7PqI>6b%38adFfk6_i3Z-%d7E z9?VK$3DjCmU_Yv2M#h~D3=AS*Q4x@rK*NHf_8>(FE~=~;s;n5QtTjs~}{J zL0qsbT(LMr7VcKCELyv2Is=0Qsxk?%GPogI70I4{{nLp^Gpuh=SE2JPB3;_ly`=7A4%oAu2$I zfD)cKSOr?#&SGGYKqvzx5DBm{xVe&GS$IZJJOnaMfPujZ#t=9Raw@_{jNoV#bOwnc zc?#6|0;@z76N0D%DTa6yG=ugC>lnnAFnkGMxU!gGi#x;AK8EO33=QWP8X6cH{1_Ts7#KvsMj^Cu zgS5r3XRrxnkh#q8cO}EEN`_qx471KKH0)()C}n8a#=sy3whApZ&SGE?1Dgd;I^tku zs1b;&LIR=!6eO@7galZH2uLUp)OY}^fJc_bVUV8%7#Pf)p$q{RkWxq#fJO<9fVc?n zFf#hgU|%0p9R$T6Gk%$lx5JgGBc)vdp1iz1qhmQCI`8!S!BGM# z!6hKFpl}8$mW0T{%6HWxAZ-E+3~FG8AOnMu3sgklC`b<^sz5A|u%Ii51r`I3>x0Fx zs1t&y11W~*0wJ(EL@Sb!u^!Yq#iCLetP;`=0vQ3aMFgS_#DtqD0#Sz|CJI)ENIT$s z6}^tZx|cz^pW)91hMVUYb|x~+G63g}K8A)f3=PE$45DD85Zd@a`6|nR!FvgV<|zj5 zeGG527*20sSXIO@VG2WoEklDRLxVm;!y<-;H4F@5U^~$=*dzu9F|eWFXafbkI9M4d ziWp$oM;xL8amOn1UIg(g&;&uF@Q=5!}Op&5xLaRTzSDMILNGfpIYdg9WBi3$RkSVM5120fQ2L z!tNjk2rw{+faOqpF6s_e4kEzCKBOsO%V4vSK{A$sVHN{}C|DDEN=#$$)@RVDV_@IL z@WO!M^BE?jGc>e=tA|F0hJJ>ILXqaRvi}7}!vF(1}Boft-nGcuZtq z5C}5o1Xvl^MvyK^uq@p5MkheVfs!Uz8C={PtPC}H zz$#GsqZXK|EWoPZ<_Mhx`3)&hn7cuN;t91?1S}1&rbRtLsu5gNSus>uF;rP`uq-^F z#lf<0t^`CDWIQMoBp|Xdt|V9%?r15nESxKiDl3gDD}yR4gDNYFDl3aBD~FI(VqjoU zMsPs|i888U6;xSsG%l)Q3shMPR9T@@AfF>*g^5wFf%#Db1A`P;0^xHnusTp=feQ%+ z1_o)c3Y75{8L%ppw4wx71vf_-tO7h$?gX2QW}L*ppbS<97DvoyPhenB0jozb(Htyf z0Pf4d3PuKD1_pDm5oqFU3=9?!^`OiQFGv}f85nrILB0`SU=TVD_8Z7Ru-_P2KqGci z5K)jCuqepK-e83wli)&NRcbK3GGG-DF4%iq3=FbhCE6e*h>{J|(Fcp8cug6i9c%$i zyE0fA(%di?1A{qOojgPx$Y4+<3RZ_IW&u$LQUNK)7#J8V!0HS@dJ)0F#K6Go1M(^; zIDA09)Bq{aU<9o=0#(UpKw^kw!oa{F1rY*if(HgzC&c%l-~y|FaACfYL5P8d-(E?-C&(4cAJBh!k6z@fK`AOV}V8<`20W?gF^Wn$W9cU5`G{da7_uG zk_V||oWsB%304XgMHbeITR2LB+^)xPgJe9IO@LL9in5G&v$Yon&CJ04tLNB_nf?@t{<69^^rU zpP87I8yGJ&FffRNCD42bs?hyG8jxDuTnr2n*wjv9V2}i>MKc2=4pxt9h7>lniy0WC zz-mzfN*XK#4o+C>KnAQEMU~8XkQW6R7!<(_0R{$hh$48{fpRF=C`7=4RiI4MTYy!_ zfi%Ix>;fnV(83Hf%P$cCl0ftC1O^64usC=ng$*Mp^g&JF`3ww_V1v-qgHjP#9N`;A zM$ozyX|O3M?L=v?LVb{tZg7KVGcd@2l_FY)pwtCciZB!8d59{I*T88BBm`E4RuWk< zFj#<0~O=F2nuviUb+Yh3Pc!zX37G=LLkS&tP_T)LKYH1Q^g4G zri)-I6h$ZmPnv;K?qW~}8ci)DGbr@L5Xx0RZUl`nA{4@e#4%NgBUFK%&BzS0L;|5u z0%RN$V^{-30-+q7tQZ+VlTwmk<>0WAfUF(>g#`n&D3?U&0b2no%E21Ig#la$Q*%F^s_sK?VjZumLExNQYn;AQJ*IK#+k!<_dj_fUv5Ly>+F$04fSRBPyilEixp!krE#-e9B1A{C!@x=@bvbRC%QM=l5*wij! zV2}f=MX}c?8XD4qcc2W>7!U)rIN}b-WHi@LU|^7r0g0p9D2+|+dY3=GnDv53!MV35J49#q+3Q$LA;K^B|(2@DLf*wjy8V30$oN14sj zzY7X7K?VlVdr*e-J&+4g!$>9$ix?JlvRKr~Vo@iDMV-)nkOM#k!+nrtXhFA-fk6he zCxHP?d?Evb3^w(k2uuJO2x=oe1Tpv-7{nfd7=jE8HeiMT0|Q?wNCdRd8O#u5V9-m0 zim0T682k(jQZJwkl?*6D3oIhQz+eJq2r@93f~5o*7*t