From 45463225bc097d2139e2a9c0923135f3aca6a99f Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 07:49:46 +0100 Subject: [PATCH 01/14] Add Calibrator, programmable profiles, vertical-range sensors, mooring posts and optional Create support (0.2.0) --- .github/workflows/neoforge-1.21.1.yml | 22 +- .gitignore | 2 + build.gradle | 9 +- .../streamcontrol/ControlCommands.java | 26 +-- .../streamcontrol/ControlConfig.java | 13 +- .../streamcontrol/ControlNetwork.java | 72 ++++-- .../streamcontrol/ControllerEntity.java | 65 +----- .../streamcontrol/ControllerSettings.java | 143 ++++++++++++ .../streamcontrol/EngineeringBlockItem.java | 13 ++ .../streamcontrol/FlowController.java | 25 ++ .../streamcontrol/FlowHeading.java | 4 + .../streamcontrol/FlowProfile.java | 38 +++ .../streamcontrol/FlowSensorEntity.java | 79 +++++++ .../streamcontrol/FlowWand.java | 148 +++++++----- .../streamcontrol/MooringEntity.java | 76 ++++++ .../streamcontrol/StreamControl.java | 16 +- .../streamcontrol/UtilityAccess.java | 8 + .../streamcontrol/UtilityBlock.java | 63 +++++ .../client/ControllerScreen.java | 80 +++++-- .../client/EngineeringClient.java | 100 ++++++++ .../client/EngineeringWidgets.java | 54 +++++ .../streamcontrol/client/UtilityScreen.java | 63 +++++ .../compat/create/CreateClient.java | 19 ++ .../compat/create/CreateIntegration.java | 22 ++ .../compat/create/MechanicalCurrentBlock.java | 52 +++++ .../create/MechanicalCurrentEntity.java | 21 ++ .../resources/META-INF/neoforge.mods.toml | 11 +- .../blockstates/flow_sensor.json | 7 + .../mechanical_current_generator.json | 36 +++ .../blockstates/mooring_post.json | 7 + .../assets/streamcontrol/lang/en_us.json | 86 ++++++- .../models/block/flow_sensor.json | 12 + .../block/mechanical_current_generator.json | 147 ++++++++++++ ...mechanical_current_generator_diagonal.json | 147 ++++++++++++ .../models/block/mooring_post.json | 218 ++++++++++++++++++ .../models/item/flow_sensor.json | 3 + .../item/mechanical_current_generator.json | 216 +++++++++++++++++ .../models/item/mooring_post.json | 3 + .../textures/block/flow_sensor_bottom.png | Bin 0 -> 661 bytes .../textures/block/flow_sensor_side.png | Bin 0 -> 645 bytes .../textures/block/flow_sensor_top.png | Bin 0 -> 703 bytes .../textures/block/mooring_post_bottom.png | Bin 0 -> 658 bytes .../textures/block/mooring_post_side.png | Bin 0 -> 620 bytes .../textures/block/mooring_post_top.png | Bin 0 -> 683 bytes .../textures/gui/automation_controller.png | Bin 0 -> 1336 bytes .../minecraft/tags/block/mineable/axe.json | 6 + .../tags/block/mineable/pickaxe.json | 7 +- .../loot_table/blocks/flow_sensor.json | 19 ++ .../blocks/mechanical_current_generator.json | 25 ++ .../loot_table/blocks/mooring_post.json | 19 ++ .../streamcontrol/recipe/flow_sensor.json | 26 +++ .../recipe/mechanical_current_generator.json | 29 +++ .../streamcontrol/recipe/mooring_post.json | 23 ++ tools/fetch_create.py | 23 ++ 54 files changed, 2117 insertions(+), 186 deletions(-) create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/ControllerSettings.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringBlockItem.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/FlowController.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/FlowProfile.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/FlowSensorEntity.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/MooringEntity.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/UtilityAccess.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/UtilityBlock.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/client/EngineeringClient.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/client/EngineeringWidgets.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/client/UtilityScreen.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateClient.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateIntegration.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentBlock.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentEntity.java create mode 100644 src/main/resources/assets/streamcontrol/blockstates/flow_sensor.json create mode 100644 src/main/resources/assets/streamcontrol/blockstates/mechanical_current_generator.json create mode 100644 src/main/resources/assets/streamcontrol/blockstates/mooring_post.json create mode 100644 src/main/resources/assets/streamcontrol/models/block/flow_sensor.json create mode 100644 src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator.json create mode 100644 src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator_diagonal.json create mode 100644 src/main/resources/assets/streamcontrol/models/block/mooring_post.json create mode 100644 src/main/resources/assets/streamcontrol/models/item/flow_sensor.json create mode 100644 src/main/resources/assets/streamcontrol/models/item/mechanical_current_generator.json create mode 100644 src/main/resources/assets/streamcontrol/models/item/mooring_post.json create mode 100644 src/main/resources/assets/streamcontrol/textures/block/flow_sensor_bottom.png create mode 100644 src/main/resources/assets/streamcontrol/textures/block/flow_sensor_side.png create mode 100644 src/main/resources/assets/streamcontrol/textures/block/flow_sensor_top.png create mode 100644 src/main/resources/assets/streamcontrol/textures/block/mooring_post_bottom.png create mode 100644 src/main/resources/assets/streamcontrol/textures/block/mooring_post_side.png create mode 100644 src/main/resources/assets/streamcontrol/textures/block/mooring_post_top.png create mode 100644 src/main/resources/assets/streamcontrol/textures/gui/automation_controller.png create mode 100644 src/main/resources/data/minecraft/tags/block/mineable/axe.json create mode 100644 src/main/resources/data/streamcontrol/loot_table/blocks/flow_sensor.json create mode 100644 src/main/resources/data/streamcontrol/loot_table/blocks/mechanical_current_generator.json create mode 100644 src/main/resources/data/streamcontrol/loot_table/blocks/mooring_post.json create mode 100644 src/main/resources/data/streamcontrol/recipe/flow_sensor.json create mode 100644 src/main/resources/data/streamcontrol/recipe/mechanical_current_generator.json create mode 100644 src/main/resources/data/streamcontrol/recipe/mooring_post.json create mode 100644 tools/fetch_create.py diff --git a/.github/workflows/neoforge-1.21.1.yml b/.github/workflows/neoforge-1.21.1.yml index 6b08a85..d783e18 100644 --- a/.github/workflows/neoforge-1.21.1.yml +++ b/.github/workflows/neoforge-1.21.1.yml @@ -4,16 +4,24 @@ on: push: branches: - "gui/**" + - "feature/**" - main - fix/neoforge-1.21.1-stillwater-render pull_request: branches: - main + - gui/controller-layout workflow_dispatch: jobs: build: + strategy: + fail-fast: false + matrix: + flavor: [standalone, create] runs-on: ubuntu-latest + env: + CREATE_ARGS: ${{ matrix.flavor == 'create' && '-PwithCreate' || '' }} permissions: contents: read steps: @@ -35,14 +43,16 @@ jobs: sha256sum --check <<'HASH' 70930ad6b943d9a359ddb573450f5114a6a54a676e32c1895f6eb4d2cd634a33 libs/StreamsReflowing-1.21.1-neoforge-2.16.2.jar HASH + - name: Fetch verified optional Create compile fixture + run: python3 tools/fetch_create.py - name: Compile and package addon run: | chmod +x gradlew - ./gradlew --no-daemon clean build + ./gradlew --no-daemon $CREATE_ARGS clean build - name: Upload test JAR uses: actions/upload-artifact@v4 with: - name: flow-control-0.1.7-neoforge-1.21.1 + name: flow-control-0.2.0-neoforge-1.21.1-${{ matrix.flavor }} path: build/libs/flow-control-*.jar if-no-files-found: error @@ -52,7 +62,7 @@ jobs: echo 'eula=true' > run/eula.txt echo 'forceBakedFluid=true' > run/config/streamsreflowing.properties printf 'level-type=minecraft:flat\ngenerate-structures=false\nonline-mode=false\nview-distance=2\nsimulation-distance=2\n' > run/server.properties - timeout 300 ./gradlew --no-daemon -Dstreamcontrol.integrationTest=true runServer + timeout 300 ./gradlew --no-daemon -Dstreamcontrol.integrationTest=true $CREATE_ARGS runServer python3 - <<'CHECK' import json data=json.load(open('run/streamcontrol-integration-results.json')) @@ -63,7 +73,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: flow-control-0.1.7-neoforge-1.21.1-checks + name: flow-control-0.2.0-neoforge-1.21.1-${{ matrix.flavor }}-checks path: | run/streamcontrol-integration-results.json run/logs/latest.log @@ -72,7 +82,7 @@ jobs: run: | mkdir -p run-client printf 'onboardAccessibility:false\nguiScale:3\nfullscreen:false\n' > run-client/options.txt - timeout 360 xvfb-run -a ./gradlew --no-daemon -Dstreamcontrol.uiPreview=true runClient + timeout 360 xvfb-run -a ./gradlew --no-daemon -Dstreamcontrol.uiPreview=true $CREATE_ARGS runClient test -s run-client/screenshots/flow-control-current-generator.png test -s run-client/screenshots/flow-control-stillwater-anchor.png test -s run-client/screenshots/flow-control-redstone-paused.png @@ -80,7 +90,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: flow-control-0.1.7-client-preview + name: flow-control-0.2.0-${{ matrix.flavor }}-client-preview path: | run-client/screenshots/*.png run-client/logs/latest.log diff --git a/.gitignore b/.gitignore index 2d2c650..461be13 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ validation/ Thumbs.db run-client/ + +libs/create-compile/ diff --git a/build.gradle b/build.gradle index 8a75322..242cb1f 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'java-library' id 'net.neoforged.moddev' version '2.0.148' } -version = '0.1.7' +version = '0.2.0' group = 'nl.townsandkingdoms.streamcontrol' base.archivesName = 'flow-control' java.toolchain.languageVersion = JavaLanguageVersion.of(21) @@ -31,6 +31,11 @@ neoForge { } dependencies { implementation files('libs/StreamsReflowing-1.21.1-neoforge-2.16.2.jar') + compileOnly files('libs/create-1.21.1-6.0.10.jar') + compileOnly fileTree('libs/create-compile') { include '*.jar' } + if (providers.gradleProperty('withCreate').isPresent()) { + runtimeOnly files('libs/create-1.21.1-6.0.10.jar') + } // Optional local compatibility test fixtures, never included in the published jar. if (providers.gradleProperty('withUtf').isPresent()) { runtimeOnly files('libs/ultraterraforged-1.0.2+1.21.1-neoforge.jar', @@ -40,4 +45,4 @@ dependencies { tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8'; options.release = 21 } tasks.named('jar') { from('LICENSE') } -tasks.named("jar") { archiveFileName = "flow-control-0.1.7-neoforge-1.21.1.jar" } +tasks.named("jar") { archiveFileName = "flow-control-0.2.0-neoforge-1.21.1.jar" } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ControlCommands.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ControlCommands.java index a4e20d4..f813f7c 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ControlCommands.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ControlCommands.java @@ -1,30 +1,18 @@ package nl.townsandkingdoms.streamcontrol; -import com.mojang.brigadier.arguments.*; import net.minecraft.commands.Commands; -import net.minecraft.core.component.DataComponents; import net.minecraft.network.chat.Component; -import net.minecraft.world.item.component.CustomData; import net.neoforged.neoforge.event.RegisterCommandsEvent; public final class ControlCommands { public static void register(RegisterCommandsEvent e) { e.getDispatcher().register(Commands.literal("streamcontrol") - .then(Commands.literal("radius").then(Commands.argument("blocks",IntegerArgumentType.integer(1,32)).executes(c -> { - var p = c.getSource().getPlayerOrException(); var s = p.getMainHandItem(); - if (!s.is(StreamControl.WAND.get())) return 0; - var n = FlowWand.settings(s); n.putInt("Radius",ControlConfig.radius(IntegerArgumentType.getInteger(c,"blocks"))); s.set(DataComponents.CUSTOM_DATA,CustomData.of(n)); return 1; - }))) - .then(Commands.literal("strength").then(Commands.argument("value",DoubleArgumentType.doubleArg(0.05,2)).executes(c -> { - var p = c.getSource().getPlayerOrException(); var s = p.getMainHandItem(); if (!s.is(StreamControl.WAND.get())) return 0; - var n = FlowWand.settings(s); n.putDouble("Strength",ControlConfig.strength(DoubleArgumentType.getDouble(c,"value"))); s.set(DataComponents.CUSTOM_DATA,CustomData.of(n)); return 1; - }))) - .then(Commands.literal("status").executes(c -> { - var p = net.minecraft.core.BlockPos.containing(c.getSource().getPosition()); var data = ControlData.get(c.getSource().getLevel()); var r = data.at(p.getX(),p.getY(),p.getZ()); - c.getSource().sendSuccess(() -> Component.literal("Flow Control: " + data.all().size() + " regions; here=" + (r == null ? "natural" : r.still() ? "still" : "directed")),false); return 1; + .then(Commands.literal("status").executes(c->{ + var p=net.minecraft.core.BlockPos.containing(c.getSource().getPosition());var data=ControlData.get(c.getSource().getLevel());var r=data.at(p.getX(),p.getY(),p.getZ()); + c.getSource().sendSuccess(()->Component.literal("Flow Control: "+data.all().size()+" regions; here="+(r==null?"natural":r.still()?"still":"directed")),false);return 1; })) - .then(Commands.literal("clear").requires(s -> s.hasPermission(2)).executes(c -> { - var level = c.getSource().getLevel(); var data = ControlData.get(level); int count = 0; - for (var r : data.all()) if (!r.controller()) { data.remove(level,r.key()); count++; } - final int removed = count; c.getSource().sendSuccess(() -> Component.literal("Removed " + removed + " wand regions in this dimension."),true); return count; + .then(Commands.literal("clear").requires(s->s.hasPermission(2)).executes(c->{ + var level=c.getSource().getLevel();var data=ControlData.get(level);int count=0; + for(var r:data.all()) if(!r.controller()) { data.remove(level,r.key());count++; } + final int removed=count;c.getSource().sendSuccess(()->Component.literal("Removed "+removed+" legacy wand regions in this dimension."),true);return count; }))); } } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ControlConfig.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ControlConfig.java index 6c2622a..6dd847f 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ControlConfig.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ControlConfig.java @@ -3,8 +3,8 @@ public final class ControlConfig { public static final ModConfigSpec SPEC; public static final ModConfigSpec.BooleanValue ENABLED, WAND_ENABLED, OP_ONLY, PARTICLES; - public static final ModConfigSpec.IntValue MAX_RADIUS, DEFAULT_RADIUS, VERTICAL, MAX_REGIONS, MAX_PLAYER_REGIONS; - public static final ModConfigSpec.DoubleValue SPEED, MAX_SPEED; + public static final ModConfigSpec.IntValue MAX_RADIUS, DEFAULT_RADIUS, VERTICAL, MAX_REGIONS, MAX_PLAYER_REGIONS, MAX_VERTICAL, LINK_RANGE, SENSOR_MAX_RADIUS, SENSOR_MAX_VERTICAL, SENSOR_INTERVAL, MOORING_MAX_RADIUS, MOORING_MAX_VERTICAL; + public static final ModConfigSpec.DoubleValue SPEED, MAX_SPEED, RPM_FULL_STRENGTH, KINETIC_STRESS; static { var b = new ModConfigSpec.Builder(); ENABLED = b.comment("Master switch. Overrides remain saved when disabled.").define("enabled", true); @@ -18,6 +18,15 @@ public final class ControlConfig { MAX_SPEED = b.defineInRange("maxStrength", 2.0, 0.05, 2.0); MAX_REGIONS = b.defineInRange("maxRegionsPerDimension", 2048, 1, 8192); MAX_PLAYER_REGIONS = b.defineInRange("maxWandRegionsPerPlayer", 256, 1, 2048); + MAX_VERTICAL = b.defineInRange("maxControllerVerticalReach",16,0,16); + LINK_RANGE = b.defineInRange("maxControllerLinkDistance",64,1,256); + SENSOR_MAX_RADIUS = b.defineInRange("maxSensorRadius",16,1,16); + SENSOR_MAX_VERTICAL = b.defineInRange("maxSensorVerticalReach",16,0,16); + SENSOR_INTERVAL = b.defineInRange("sensorSampleIntervalTicks",20,5,200); + MOORING_MAX_RADIUS = b.defineInRange("maxMooringRadius",8,1,16); + MOORING_MAX_VERTICAL = b.defineInRange("maxMooringVerticalReach",8,0,16); + RPM_FULL_STRENGTH = b.defineInRange("kineticRpmForFullStrength",128.0,1.0,1024.0); + KINETIC_STRESS = b.defineInRange("kineticStressImpact",4.0,0.0,256.0); SPEC = b.build(); } public static int radius(int value) { return Math.clamp(value, 1, MAX_RADIUS.get()); } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ControlNetwork.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ControlNetwork.java index 64e41e6..a606c30 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ControlNetwork.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ControlNetwork.java @@ -14,39 +14,61 @@ public final class ControlNetwork { /** Server-authoritative snapshot used to open the controller's client GUI. */ public record Open(long pos, int radius, int vertical, double strength, double maxStrength, - int maxRadius, boolean connectedOnly, boolean still, boolean powered, int facing) + int maxRadius, boolean connectedOnly, boolean still, boolean powered, int facing, CompoundTag settings) implements CustomPacketPayload { - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(StreamControl.ID, "open_controller_v2")); + public Open(long pos,int radius,int vertical,double strength,double maxStrength,int maxRadius,boolean connectedOnly,boolean still,boolean powered,int facing) { + this(pos,radius,vertical,strength,maxStrength,maxRadius,connectedOnly,still,powered,facing,new CompoundTag()); + } + public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(StreamControl.ID, "open_controller_v3")); public static final StreamCodec CODEC = new StreamCodec<>() { public Open decode(RegistryFriendlyByteBuf b) { return new Open(b.readLong(), b.readVarInt(), b.readVarInt(), b.readDouble(), b.readDouble(), - b.readVarInt(), b.readBoolean(), b.readBoolean(), b.readBoolean(), b.readVarInt()); + b.readVarInt(), b.readBoolean(), b.readBoolean(), b.readBoolean(), b.readVarInt(), b.readNbt()); } public void encode(RegistryFriendlyByteBuf b, Open p) { b.writeLong(p.pos); b.writeVarInt(p.radius); b.writeVarInt(p.vertical); b.writeDouble(p.strength); b.writeDouble(p.maxStrength); b.writeVarInt(p.maxRadius); b.writeBoolean(p.connectedOnly); - b.writeBoolean(p.still); b.writeBoolean(p.powered); b.writeVarInt(p.facing); + b.writeBoolean(p.still); b.writeBoolean(p.powered); b.writeVarInt(p.facing); b.writeNbt(p.settings); } }; @Override public Type type() { return TYPE; } } /** Never trust client-supplied dimensions, speed or access rights. */ - public record Configure(long pos, int radius, double strength, boolean connectedOnly, int facing) + public record Configure(long pos, int radius, double strength, boolean connectedOnly, int facing, CompoundTag settings) implements CustomPacketPayload { - public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(StreamControl.ID, "configure_controller_v2")); + public Configure(long pos,int radius,double strength,boolean connectedOnly,int facing) { + this(pos,radius,strength,connectedOnly,facing,new CompoundTag()); + } + public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(StreamControl.ID, "configure_controller_v3")); public static final StreamCodec CODEC = new StreamCodec<>() { public Configure decode(RegistryFriendlyByteBuf b) { - return new Configure(b.readLong(), b.readVarInt(), b.readDouble(), b.readBoolean(), b.readVarInt()); + return new Configure(b.readLong(), b.readVarInt(), b.readDouble(), b.readBoolean(), b.readVarInt(), b.readNbt()); } public void encode(RegistryFriendlyByteBuf b, Configure p) { b.writeLong(p.pos); b.writeVarInt(p.radius); b.writeDouble(p.strength); - b.writeBoolean(p.connectedOnly); b.writeVarInt(p.facing); + b.writeBoolean(p.connectedOnly); b.writeVarInt(p.facing); b.writeNbt(p.settings); } }; @Override public Type type() { return TYPE; } } + public record UtilityOpen(long pos,CompoundTag settings) implements CustomPacketPayload { + public static final Type TYPE=new Type<>(ResourceLocation.fromNamespaceAndPath(StreamControl.ID,"open_utility")); + public static final StreamCodec CODEC=new StreamCodec<>() { + public UtilityOpen decode(RegistryFriendlyByteBuf b) { return new UtilityOpen(b.readLong(),b.readNbt()); } + public void encode(RegistryFriendlyByteBuf b,UtilityOpen p) { b.writeLong(p.pos);b.writeNbt(p.settings); } + }; + @Override public Type type() { return TYPE; } + } + public record UtilityConfigure(long pos,CompoundTag settings) implements CustomPacketPayload { + public static final Type TYPE=new Type<>(ResourceLocation.fromNamespaceAndPath(StreamControl.ID,"configure_utility")); + public static final StreamCodec CODEC=new StreamCodec<>() { + public UtilityConfigure decode(RegistryFriendlyByteBuf b) { return new UtilityConfigure(b.readLong(),b.readNbt()); } + public void encode(RegistryFriendlyByteBuf b,UtilityConfigure p) { b.writeLong(p.pos);b.writeNbt(p.settings); } + }; + @Override public Type type() { return TYPE; } + } public record Update(String dimension, boolean reset, CompoundTag region, long remove) implements CustomPacketPayload { public static final Type TYPE = new Type<>(ResourceLocation.fromNamespaceAndPath(StreamControl.ID, "region")); public static final StreamCodec CODEC = new StreamCodec<>() { @@ -56,7 +78,15 @@ public record Update(String dimension, boolean reset, CompoundTag region, long r @Override public Type type() { return TYPE; } } public static void register(RegisterPayloadHandlersEvent event) { - var registrar = event.registrar("3"); + var registrar = event.registrar("4"); + registrar.playToClient(UtilityOpen.TYPE,UtilityOpen.CODEC,(p,context)->context.enqueueWork(()-> + nl.townsandkingdoms.streamcontrol.client.UtilityScreen.open(p))); + registrar.playToServer(UtilityConfigure.TYPE,UtilityConfigure.CODEC,(p,context)->context.enqueueWork(()->{ + Player player=context.player();BlockPos pos=BlockPos.of(p.pos()); + if(!(player.level() instanceof ServerLevel level) || !level.hasChunkAt(pos) || player.blockPosition().distSqr(pos)>64 + || !player.mayBuild() || !level.mayInteract(player,pos) || p.settings()==null) return; + if(level.getBlockEntity(pos) instanceof UtilityAccess utility) utility.configure(p.settings()); + })); registrar.playToClient(Update.TYPE, Update.CODEC, (p, context) -> context.enqueueWork(() -> { nl.townsandkingdoms.streamcontrol.client.ClientUpdates.apply(p); })); @@ -67,18 +97,26 @@ public static void register(RegisterPayloadHandlersEvent event) { BlockPos pos = BlockPos.of(p.pos()); if (!(player.level() instanceof ServerLevel) || player.blockPosition().distSqr(pos) > 64 || !player.mayBuild() || !player.level().mayInteract(player, pos)) return; - if (!(player.level().getBlockEntity(pos) instanceof ControllerEntity be)) return; + if (!(player.level().getBlockEntity(pos) instanceof FlowController be)) return; FlowHeading d = FlowHeading.fromId(p.facing()); if (d == null) return; - be.configure(d, ControlConfig.radius(p.radius()), ControlConfig.strength(p.strength()), p.connectedOnly()); + if (p.settings()!=null && p.settings().contains("ProfileA") && p.settings().contains("ProfileB")) be.controls().configure(p.settings()); + else be.configure(d,ControlConfig.radius(p.radius()),ControlConfig.strength(p.strength()),p.connectedOnly()); })); } - public static void open(ServerPlayer player, ControllerEntity be) { - var state = be.getBlockState(); - PacketDistributor.sendToPlayer(player, new Open(be.getBlockPos().asLong(), be.radius(), - ControlConfig.VERTICAL.get(), be.strength(), ControlConfig.MAX_SPEED.get(), - ControlConfig.MAX_RADIUS.get(), be.connectedOnly(), ((ControllerBlock)state.getBlock()).still, - state.getValue(ControllerBlock.POWERED), be.heading().id())); + public static void open(ServerPlayer player, FlowController be) { + var state = be.blockEntity().getBlockState(); + PacketDistributor.sendToPlayer(player, new Open(be.blockEntity().getBlockPos().asLong(), be.radius(), + be.controls().a().vertical(), be.strength(), ControlConfig.MAX_SPEED.get(), + ControlConfig.MAX_RADIUS.get(), be.connectedOnly(), be.isStill(), + state.getValue(ControllerBlock.POWERED), be.heading().id(), snapshot(be))); + } + private static CompoundTag snapshot(FlowController controller) { + var n=controller.controls().save();n.putBoolean("Kinetic",!Float.isNaN(controller.rpm())); + n.putFloat("RPM",Float.isFinite(controller.rpm())?controller.rpm():0);n.putInt("MaxVertical",ControlConfig.MAX_VERTICAL.get());return n; + } + public static void openUtility(ServerPlayer player,UtilityAccess be) { + PacketDistributor.sendToPlayer(player,new UtilityOpen(be.blockEntity().getBlockPos().asLong(),be.settings())); } public static void update(ServerLevel level, FlowRegion r) { PacketDistributor.sendToPlayersInDimension(level, new Update(level.dimension().location().toString(), false, r.save(), 0)); } public static void remove(ServerLevel level, long key) { PacketDistributor.sendToPlayersInDimension(level, new Update(level.dimension().location().toString(), false, null, key)); } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerEntity.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerEntity.java index dec879b..18a2f8a 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerEntity.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerEntity.java @@ -1,62 +1,17 @@ package nl.townsandkingdoms.streamcontrol; -import java.util.UUID; -import java.util.Arrays; import net.minecraft.core.*; import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -public final class ControllerEntity extends BlockEntity { - private int radius = -1; - private double strength = -1; - private boolean connectedOnly; - private boolean connectivityDirty = true; - private boolean initialized; - public ControllerEntity(BlockPos p, BlockState s) { super(StreamControl.CONTROLLER.get(), p, s); } - public int radius() { return ControlConfig.radius(radius < 1 ? ControlConfig.DEFAULT_RADIUS.get() : radius); } - public double strength() { return ControlConfig.strength(strength < 0 ? ControlConfig.SPEED.get() : strength); } - public FlowHeading heading() { return FlowHeading.fromState(getBlockState()); } - public boolean connectedOnly() { return connectedOnly; } - public void setRadius(int r) { radius = ControlConfig.radius(r); connectivityDirty = true; setChanged(); refresh(); } - public void configure(Direction d, int r, double speed) { configure(d, r, speed, connectedOnly); } - public void configure(Direction d, int r, double speed, boolean onlyConnected) { - configure(FlowHeading.fromDirection(d), r, speed, onlyConnected); - } - public void configure(FlowHeading heading, int r, double speed, boolean onlyConnected) { - radius = ControlConfig.radius(r); strength = ControlConfig.strength(speed); - connectedOnly = onlyConnected; - connectivityDirty = true; - if (level != null) level.setBlock(worldPosition, heading.apply(getBlockState()),3); - setChanged(); refresh(); - } - @Override protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registry) { super.saveAdditional(tag,registry); tag.putInt("Radius",radius); tag.putDouble("Strength",strength); tag.putBoolean("ConnectedOnly",connectedOnly); } - @Override protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registry) { super.loadAdditional(tag,registry); radius = tag.contains("Radius") ? tag.getInt("Radius") : -1; strength = tag.contains("Strength") ? tag.getDouble("Strength") : -1; connectedOnly = tag.getBoolean("ConnectedOnly"); connectivityDirty = true; } - public void waterChanged() { connectivityDirty = true; refresh(); } - public static void tick(Level l, BlockPos p, BlockState s, ControllerEntity be) { - if (!be.initialized || l.getGameTime() % 20 == 0) { be.initialized = true; be.refresh(); } - } - public void refresh() { - if (!(level instanceof ServerLevel server)) return; - var data = ControlData.get(server); long key = worldPosition.asLong(); - if (getBlockState().getValue(ControllerBlock.POWERED) || !ControlConfig.ENABLED.get()) { data.remove(server,key); return; } - FlowHeading heading = heading(); - Direction d = heading.cardinal(); - boolean still = ((ControllerBlock)getBlockState().getBlock()).still; - double sp = strength(); - var old = data.byKey(key); - long[] mask = new long[0]; - if (connectedOnly) { - boolean rebuild = connectivityDirty || old == null || !old.connectedOnly() - || old.radius() != radius() || old.vertical() != ControlConfig.VERTICAL.get() - || server.getGameTime() % 100 == 0; - mask = rebuild ? ConnectedWater.scan(server, worldPosition, d, radius(), ControlConfig.VERTICAL.get()) : old.connectedMask(); - } - connectivityDirty = false; - if (old != null && old.radius() == radius() && old.vertical() == ControlConfig.VERTICAL.get() - && old.dx() == heading.dx() && old.dz() == heading.dz() && old.strength() == sp && old.still() == still - && old.connectedOnly() == connectedOnly && Arrays.equals(old.connectedMask(), mask)) return; - data.put(server, new FlowRegion(key, worldPosition.immutable(), radius(), ControlConfig.VERTICAL.get(), - heading.dx(), heading.dz(), sp, still, true, new UUID(0,0), data.next(), connectedOnly, mask)); - } +public final class ControllerEntity extends BlockEntity implements FlowController { + private final ControllerSettings controls = new ControllerSettings(this); + public ControllerEntity(BlockPos p, BlockState s) { super(StreamControl.CONTROLLER.get(),p,s); } + @Override public BlockEntity blockEntity() { return this; } + @Override public ControllerSettings controls() { return controls; } + @Override protected void saveAdditional(CompoundTag n,HolderLookup.Provider registry) { super.saveAdditional(n,registry); n.merge(controls.save()); } + @Override protected void loadAdditional(CompoundTag n,HolderLookup.Provider registry) { super.loadAdditional(n,registry); controls.load(n); } + @Override public net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket getUpdatePacket() { return net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket.create(this); } + @Override public CompoundTag getUpdateTag(HolderLookup.Provider r) { return saveWithoutMetadata(r); } + public static void tick(Level l,BlockPos p,BlockState s,ControllerEntity be) { be.controls.tick(); } } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerSettings.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerSettings.java new file mode 100644 index 0000000..1acdb5d --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerSettings.java @@ -0,0 +1,143 @@ +package nl.townsandkingdoms.streamcontrol; + +import java.util.*; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.entity.BlockEntity; + +/** Persistent profiles and shared execution for normal and optional kinetic controllers. */ +public final class ControllerSettings { + public enum Redstone { PAUSE, IGNORE, ANALOG, REVERSE, SWITCH; + public static Redstone from(int id) { return values()[Math.clamp(id,0,values().length-1)]; } + } + private final FlowController host; + private FlowProfile a, b; + private Redstone redstone = Redstone.PAUSE; + private BlockPos source; + private boolean dirty = true; + private boolean initialized; + public ControllerSettings(FlowController host) { this.host = host; } + public FlowProfile a() { if (a == null) a = new FlowProfile(ControlConfig.DEFAULT_RADIUS.get(),ControlConfig.VERTICAL.get(),ControlConfig.SPEED.get(),host.heading(),false,host.isStill()?FlowProfile.Action.CALM:FlowProfile.Action.CURRENT); return a; } + public FlowProfile b() { + if (b == null) b = new FlowProfile(a().radius(),a().vertical(),a().strength(),a().heading(),a().connectedOnly(), + host.isStill() ? FlowProfile.Action.RELEASE : FlowProfile.Action.REVERSE); + return b; + } + public Redstone redstone() { return redstone; } + public BlockPos source() { return source; } + private static FlowProfile bounded(FlowProfile p) { + return new FlowProfile(ControlConfig.radius(p.radius()),Math.clamp(p.vertical(),0,ControlConfig.MAX_VERTICAL.get()), + ControlConfig.strength(p.strength()),p.heading(),p.connectedOnly(),p.action()); + } + private void changed() { + var be=host.blockEntity();be.setChanged(); + if(be.getLevel() instanceof ServerLevel l) l.sendBlockUpdated(be.getBlockPos(),be.getBlockState(),be.getBlockState(),2); + } + public void invalidate() { dirty = true; } + public void setA(FlowProfile profile) { + a = bounded(profile.forAnchor(host.isStill())); + var be = host.blockEntity(); + if (be.getLevel() != null) be.getLevel().setBlock(be.getBlockPos(),a.heading().apply(be.getBlockState()),3); + dirty = true; changed(); refresh(); + } + public CompoundTag save() { + var n = new CompoundTag(); n.put("ProfileA",a().save()); n.put("ProfileB",b().save()); + n.putInt("RedstoneMode",redstone.ordinal()); if (source != null) n.putLong("LinkedSource",source.asLong()); + // Older world data keys remain readable for migration and diagnostics. + n.putInt("Radius",a().radius()); n.putDouble("Strength",a().strength()); n.putBoolean("ConnectedOnly",a().connectedOnly()); + return n; + } + public void load(CompoundTag n) { + a = n.contains("ProfileA") ? FlowProfile.load(n.getCompound("ProfileA"),host.isStill()) : + new FlowProfile(n.contains("Radius") && n.getInt("Radius") > 0 ? n.getInt("Radius") : ControlConfig.DEFAULT_RADIUS.get(), + ControlConfig.VERTICAL.get(), n.contains("Strength") && n.getDouble("Strength") >= 0 ? n.getDouble("Strength") : ControlConfig.SPEED.get(), + host.heading(), n.getBoolean("ConnectedOnly"),host.isStill() ? FlowProfile.Action.CALM : FlowProfile.Action.CURRENT); + b = n.contains("ProfileB") ? FlowProfile.load(n.getCompound("ProfileB"),host.isStill()) : null; + redstone = Redstone.from(n.getInt("RedstoneMode")); + source = n.contains("LinkedSource") ? BlockPos.of(n.getLong("LinkedSource")) : null; dirty = true; + } + /** Client edits may change profiles and clear a link, never forge a link to an arbitrary position. */ + public void configure(CompoundTag n) { + a = FlowProfile.load(n.getCompound("ProfileA"),host.isStill()); + b = bounded(FlowProfile.load(n.getCompound("ProfileB"),host.isStill())); + redstone = Redstone.from(n.getInt("RedstoneMode")); + if (!n.contains("LinkedSource")) source = null; + setA(a); + } + public CompoundTag clipboard() { var n = save(); n.remove("LinkedSource"); return n; } + public void paste(CompoundTag n) { source = null; configure(n); } + public void unlink() { source = null; dirty = true; changed(); refresh(); } + public boolean link(BlockPos pos) { + var be = host.blockEntity(); + if (!(be.getLevel() instanceof ServerLevel level) || pos.equals(be.getBlockPos()) + || pos.distSqr(be.getBlockPos()) > (long)ControlConfig.LINK_RANGE.get()*ControlConfig.LINK_RANGE.get()) return false; + Set seen = new HashSet<>(); seen.add(be.getBlockPos()); BlockPos current = pos; + for (int i=0;i<16;i++) { + if (!seen.add(current) || !level.hasChunkAt(current) + || !(level.getBlockEntity(current) instanceof FlowController controller)) return false; + if (controller.controls().source == null) { + source = pos.immutable(); dirty = true; changed(); refresh(); return true; + } + current = controller.controls().source; + } + return false; + } + private ControllerSettings resolved(ServerLevel level) { + ControllerSettings settings = this; Set seen = new HashSet<>(); seen.add(host.blockEntity().getBlockPos()); + for (int i=0;settings.source!=null && i<16;i++) { + var pos = settings.source; + if (!seen.add(pos) || !level.hasChunkAt(pos) || !(level.getBlockEntity(pos) instanceof FlowController next)) return null; + settings = next.controls(); + } + return settings.source == null ? settings : null; + } + public void tick() { + var level = host.blockEntity().getLevel(); + if (level != null && (!initialized || level.getGameTime()%10 == 0)) { initialized = true; refresh(); } + } + public void refresh() { + BlockEntity be = host.blockEntity(); if (!(be.getLevel() instanceof ServerLevel level) || be.isRemoved()) return; + var data = ControlData.get(level); var pos = be.getBlockPos(); long key = pos.asLong(); + ControllerSettings settings = resolved(level); + if (!ControlConfig.ENABLED.get() || settings == null) { data.remove(level,key); return; } + int signal = level.getBestNeighborSignal(pos); + // Read the block property too: preserves explicit powered states and structure/test placements. + boolean powered = signal > 0 || be.getBlockState().getValue(ControllerBlock.POWERED); + Redstone mode = settings.redstone; + if (mode == Redstone.PAUSE && powered) { data.remove(level,key); return; } + FlowProfile p = mode == Redstone.SWITCH && powered ? settings.b() : settings.a(); + p = bounded(p.forAnchor(host.isStill())); + if (p.action() == FlowProfile.Action.RELEASE) { data.remove(level,key); return; } + FlowHeading heading = mode != Redstone.SWITCH || !powered ? settings.host.heading() : p.heading(); + boolean reverse = p.action() == FlowProfile.Action.REVERSE; + boolean still = host.isStill() || p.action() == FlowProfile.Action.CALM; + double speed = p.strength(); + if (mode == Redstone.REVERSE && powered) reverse = !reverse; + if (mode == Redstone.ANALOG) { + if (host.isStill() && signal == 0) { data.remove(level,key); return; } + speed *= signal/15.0; + if (signal == 0) still = true; + } + float rpm = host.rpm(); + if (!Float.isNaN(rpm)) { + if (!Float.isFinite(rpm) || Math.abs(rpm) < 0.001f) { data.remove(level,key); return; } + speed *= Math.abs(rpm)/ControlConfig.RPM_FULL_STRENGTH.get(); + if (rpm < 0) reverse = !reverse; + } + speed = ControlConfig.strength(speed); + if (reverse) heading = heading.rotate(net.minecraft.world.level.block.Rotation.CLOCKWISE_180); + var old = data.byKey(key); long[] mask = new long[0]; + if (p.connectedOnly()) { + boolean rebuild = dirty || old == null || !old.connectedOnly() || old.radius()!=p.radius() || old.vertical()!=p.vertical() + || level.getGameTime()%100 == 0; + mask = rebuild ? ConnectedWater.scan(level,pos,heading.cardinal(),p.radius(),p.vertical()) : old.connectedMask(); + } + dirty = false; + if (old != null && old.radius()==p.radius() && old.vertical()==p.vertical() && old.dx()==heading.dx() + && old.dz()==heading.dz() && old.strength()==speed && old.still()==still + && old.connectedOnly()==p.connectedOnly() && Arrays.equals(old.connectedMask(),mask)) return; + data.put(level,new FlowRegion(key,pos.immutable(),p.radius(),p.vertical(),heading.dx(),heading.dz(),speed,still,true, + new UUID(0,0),data.next(),p.connectedOnly(),mask)); + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringBlockItem.java b/src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringBlockItem.java new file mode 100644 index 0000000..ffda32f --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringBlockItem.java @@ -0,0 +1,13 @@ +package nl.townsandkingdoms.streamcontrol; +import java.util.List; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.*; +import net.minecraft.world.level.block.Block; +public final class EngineeringBlockItem extends BlockItem { + public EngineeringBlockItem(Block block,Properties p) { super(block,p); } + @Override public void appendHoverText(ItemStack stack,TooltipContext context,List lines,TooltipFlag flag) { + super.appendHoverText(stack,context,lines,flag); + lines.add(Component.translatable(getDescriptionId()+".tip").withStyle(net.minecraft.ChatFormatting.GRAY)); + lines.add(Component.translatable("engineering.streamcontrol.configure_tip").withStyle(net.minecraft.ChatFormatting.DARK_GRAY)); + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/FlowController.java b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowController.java new file mode 100644 index 0000000..0135f72 --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowController.java @@ -0,0 +1,25 @@ +package nl.townsandkingdoms.streamcontrol; + +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.entity.BlockEntity; + +/** Shared controller contract; the base mod never loads Create classes. */ +public interface FlowController { + BlockEntity blockEntity(); + ControllerSettings controls(); + default boolean isStill() { return blockEntity().getBlockState().getBlock() instanceof ControllerBlock b && b.still; } + /** NaN means a normal controller. A kinetic controller returns signed RPM. */ + default float rpm() { return Float.NaN; } + default int radius() { return controls().a().radius(); } + default double strength() { return controls().a().strength(); } + default boolean connectedOnly() { return controls().a().connectedOnly(); } + default FlowHeading heading() { return FlowHeading.fromState(blockEntity().getBlockState()); } + default void configure(FlowHeading heading, int radius, double strength, boolean connected) { + controls().setA(new FlowProfile(radius,controls().a().vertical(),strength,heading,connected,controls().a().action())); + } + default void configure(Direction d, int r, double speed, boolean connected) { configure(FlowHeading.fromDirection(d),r,speed,connected); } + default void configure(Direction d, int r, double speed) { configure(d,r,speed,connectedOnly()); } + default void setRadius(int r) { configure(heading(),r,strength(),connectedOnly()); } + default void refresh() { controls().refresh(); } + default void waterChanged() { controls().invalidate(); refresh(); } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/FlowHeading.java b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowHeading.java index e71cc42..1d6433c 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/FlowHeading.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowHeading.java @@ -28,6 +28,10 @@ public String abbreviation(){return switch(this){ case NORTH -> "n";case NORTH_EAST -> "ne";case EAST -> "e";case SOUTH_EAST -> "se"; case SOUTH -> "s";case SOUTH_WEST -> "sw";case WEST -> "w";case NORTH_WEST -> "nw"; };} + public static FlowHeading fromVector(double x,double z) { + if(!Double.isFinite(x) || !Double.isFinite(z) || Math.hypot(x,z)<1e-6) return null; + return VALUES[Math.floorMod((int)Math.round(Math.atan2(x,-z)/(Math.PI/4)),8)]; + } public static FlowHeading fromId(int id){return id>=0 && id NORTH;case EAST -> EAST;case SOUTH -> SOUTH;case WEST -> WEST; diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/FlowProfile.java b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowProfile.java new file mode 100644 index 0000000..eeec8d5 --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowProfile.java @@ -0,0 +1,38 @@ +package nl.townsandkingdoms.streamcontrol; + +import net.minecraft.nbt.CompoundTag; + +/** A bounded, portable controller preset. No world coordinates or permissions are copied. */ +public record FlowProfile(int radius, int vertical, double strength, FlowHeading heading, + boolean connectedOnly, Action action) { + public enum Action { CURRENT, REVERSE, CALM, RELEASE; + public static Action from(int id) { return values()[Math.clamp(id, 0, values().length-1)]; } + } + public FlowProfile { + radius = Math.clamp(radius,1,32); + vertical = Math.clamp(vertical,0,16); + strength = Double.isFinite(strength) ? Math.clamp(strength,0.05,2.0) : 1.0; + if (heading == null) heading = FlowHeading.NORTH; + if (action == null) action = Action.CURRENT; + } + public static FlowProfile defaults(boolean still) { + return new FlowProfile(4,4,1.0, FlowHeading.NORTH, false, still ? Action.CALM : Action.CURRENT); + } + public FlowProfile forAnchor(boolean anchor) { + return anchor && action != Action.RELEASE ? new FlowProfile(radius,vertical,strength,heading,connectedOnly,Action.CALM) : this; + } + public FlowProfile withHeading(FlowHeading h) { return new FlowProfile(radius,vertical,strength,h,connectedOnly,action); } + public CompoundTag save() { + var n = new CompoundTag(); n.putInt("Radius",radius); n.putInt("Vertical",vertical); + n.putDouble("Strength",strength); n.putInt("Heading",heading.id()); + n.putBoolean("ConnectedOnly",connectedOnly); n.putInt("Action",action.ordinal()); return n; + } + public static FlowProfile load(CompoundTag n, boolean still) { + var d = defaults(still); + return new FlowProfile(n.contains("Radius") ? n.getInt("Radius") : d.radius, + n.contains("Vertical") ? n.getInt("Vertical") : d.vertical, + n.contains("Strength") ? n.getDouble("Strength") : d.strength, + n.contains("Heading") ? FlowHeading.fromId(n.getInt("Heading")) : d.heading, + n.getBoolean("ConnectedOnly"), n.contains("Action") ? Action.from(n.getInt("Action")) : d.action).forAnchor(still); + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/FlowSensorEntity.java b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowSensorEntity.java new file mode 100644 index 0000000..29854cb --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowSensorEntity.java @@ -0,0 +1,79 @@ +package nl.townsandkingdoms.streamcontrol; + +import net.minecraft.core.*; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; + +/** Bounded, staggered sampling of loaded chunks; vertical reach is independent of horizontal range. */ +public final class FlowSensorEntity extends BlockEntity implements UtilityAccess { + public enum Mode { SPEED, DIRECTION, BOATS; + public static Mode from(int id) { return values()[Math.clamp(id,0,values().length-1)]; } + } + private int radius=4, vertical=4, output; + private Mode mode=Mode.SPEED; + private boolean emptyOnly; + private double measuredSpeed; + private FlowHeading measuredHeading; + public FlowSensorEntity(BlockPos p,BlockState s) { super(StreamControl.SENSOR_ENTITY.get(),p,s); } + @Override public BlockEntity blockEntity() { return this; } + public int output() { return output; } + public int radius() { return Math.clamp(radius,1,ControlConfig.SENSOR_MAX_RADIUS.get()); } + public int vertical() { return Math.clamp(vertical,0,ControlConfig.SENSOR_MAX_VERTICAL.get()); } + public Mode mode() { return mode; } + @Override public CompoundTag settings() { + var n=new CompoundTag();n.putString("Kind","sensor");n.putInt("Radius",radius());n.putInt("Vertical",vertical()); + n.putInt("MaxRadius",ControlConfig.SENSOR_MAX_RADIUS.get());n.putInt("MaxVertical",ControlConfig.SENSOR_MAX_VERTICAL.get()); + n.putInt("Mode",mode.ordinal());n.putInt("Output",output);n.putBoolean("EmptyOnly",emptyOnly); + n.putDouble("MeasuredSpeed",measuredSpeed);n.putInt("MeasuredHeading",measuredHeading==null?-1:measuredHeading.id());return n; + } + @Override public void configure(CompoundTag n) { + radius=Math.clamp(n.getInt("Radius"),1,ControlConfig.SENSOR_MAX_RADIUS.get()); + vertical=Math.clamp(n.getInt("Vertical"),0,ControlConfig.SENSOR_MAX_VERTICAL.get()); + mode=Mode.from(n.getInt("Mode"));emptyOnly=n.getBoolean("EmptyOnly");setChanged();sample(); + } + @Override protected void saveAdditional(CompoundTag n,HolderLookup.Provider r) { super.saveAdditional(n,r);n.putInt("Radius",radius);n.putInt("Vertical",vertical);n.putInt("Mode",mode.ordinal());n.putBoolean("EmptyOnly",emptyOnly);n.putInt("Output",output); } + @Override protected void loadAdditional(CompoundTag n,HolderLookup.Provider r) { super.loadAdditional(n,r);radius=n.contains("Radius")?n.getInt("Radius"):4;vertical=n.contains("Vertical")?n.getInt("Vertical"):4;mode=Mode.from(n.getInt("Mode"));emptyOnly=n.getBoolean("EmptyOnly");output=Math.clamp(n.getInt("Output"),0,15); } + @Override public ClientboundBlockEntityDataPacket getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this); } + @Override public CompoundTag getUpdateTag(HolderLookup.Provider r) { return saveWithoutMetadata(r); } + public static void tick(Level l,BlockPos p,BlockState s,FlowSensorEntity be) { + int interval=ControlConfig.SENSOR_INTERVAL.get(); + if(Math.floorMod(l.getGameTime()+p.asLong(),interval)==0) be.sample(); + } + public static int speedSignal(double speed) { return speed<=1e-6 || !Double.isFinite(speed) ? 0 : Math.clamp((int)Math.ceil(speed/ControlConfig.MAX_SPEED.get()*15),1,15); } + public void sample() { + if(!(level instanceof ServerLevel server)) return; + int result=0;double best=0;FlowHeading heading=null;int r=radius(),v=vertical(); + if(ControlConfig.ENABLED.get()) { + if(mode==Mode.BOATS) { + AABB box=new AABB(worldPosition).inflate(r,v,r); + result=Math.min(15,server.getEntitiesOfClass(Boat.class,box,b->b.isAlive() && (!emptyOnly || !b.isVehicle()) + && inside(b.getX(),b.getY(),b.getZ(),r,v)).size()); + } else { + var p=new BlockPos.MutableBlockPos(); + for(int x=-r;x<=r;x++) for(int z=-r;z<=r;z++) { + if(x*x+z*z>r*r) continue; + for(int y=-v;y<=v;y++) { + p.setWithOffset(worldPosition,x,y,z);if(!server.hasChunkAt(p)) continue; + var fluid=server.getFluidState(p);if(!fluid.is(FluidTags.WATER)) continue; + var flow=fluid.getFlow(server,p);double speed=Math.hypot(flow.x,flow.z); + if(Double.isFinite(speed) && speed>best+1e-6) { best=speed;heading=FlowHeading.fromVector(flow.x,flow.z); } + } + } + result=mode==Mode.SPEED ? speedSignal(best) : heading==null?0:heading.id()+1; + } + } + measuredSpeed=best;measuredHeading=heading; + if(output!=result) { output=result;setChanged();server.updateNeighbourForOutputSignal(worldPosition,getBlockState().getBlock());server.sendBlockUpdated(worldPosition,getBlockState(),getBlockState(),2); } + } + private boolean inside(double x,double y,double z,int r,int v) { + double dx=x-worldPosition.getX()-.5,dz=z-worldPosition.getZ()-.5; + return dx*dx+dz*dz<=r*r && y>=worldPosition.getY()-v && y use(Level world, Player p, InteractionHand hand) { - ItemStack stack = p.getItemInHand(hand); - if (world.isClientSide) return InteractionResultHolder.success(stack); - var hit = getPlayerPOVHitResult(world, p, ClipContext.Fluid.ANY); - var n = settings(stack); - int mode = Math.floorMod(n.getInt("Mode"), 3); - int radius = ControlConfig.radius(n.contains("Radius") ? n.getInt("Radius") : ControlConfig.DEFAULT_RADIUS.get()); - if (hit.getType() == HitResult.Type.MISS) { - if (p.isShiftKeyDown()) { mode = (mode + 1) % 3; n.putInt("Mode", mode); message(p, "message.streamcontrol.mode", Component.translatable("mode.streamcontrol." + mode)); } - else { radius = radius % ControlConfig.MAX_RADIUS.get() + 1; n.putInt("Radius", radius); message(p, "message.streamcontrol.radius", radius); } - stack.set(DataComponents.CUSTOM_DATA, CustomData.of(n)); return InteractionResultHolder.success(stack); + @Override public InteractionResult useOn(UseOnContext c) { + var player=c.getPlayer();if(player==null) return InteractionResult.PASS; + var be=c.getLevel().getBlockEntity(c.getClickedPos()); + if(!(be instanceof FlowController) && !(be instanceof UtilityAccess)) return InteractionResult.PASS; + if(c.getLevel().isClientSide) return InteractionResult.SUCCESS; + if(!(player instanceof ServerPlayer server) || !allowed(player,c.getClickedPos(),c.getItemInHand())) return InteractionResult.FAIL; + operate(server,c.getClickedPos(),c.getItemInHand());return InteractionResult.CONSUME; + } + public static boolean operate(ServerPlayer player,BlockPos pos,ItemStack stack) { + var level=player.serverLevel(); + if(!level.hasChunkAt(pos) || !allowed(player,pos,stack)) return false; + var be=level.getBlockEntity(pos);var n=settings(stack);Mode mode=mode(stack); + if(mode==Mode.INSPECT) { + if(be instanceof FlowController controller) ControlNetwork.open(player,controller); + else if(be instanceof UtilityAccess utility) ControlNetwork.openUtility(player,utility); + else inspect(player,pos); + return true; + } + if(mode==Mode.COPY) { + CompoundTag clipboard; + if(be instanceof FlowController controller) { clipboard=controller.controls().clipboard();clipboard.putString("Kind","controller"); } + else if(be instanceof UtilityAccess utility) clipboard=utility.settings(); + else { message(player,"controller_required");return false; } + n.put("Calibration",clipboard);store(stack,n);message(player,"copied");return true; } - BlockPos pos = hit.getBlockPos(); - if (!world.getFluidState(pos).is(FluidTags.WATER)) return InteractionResultHolder.pass(stack); - if (!allowed(p, pos, stack)) { message(p, "message.streamcontrol.denied"); return InteractionResultHolder.fail(stack); } - var server = (ServerLevel)world; var data = ControlData.get(server); - if (mode == 2) { - var old = data.at(pos.getX(), pos.getY(), pos.getZ()); - if (old == null) { message(p, "message.streamcontrol.none"); return InteractionResultHolder.success(stack); } - if (old.controller()) { message(p, "message.streamcontrol.remove_block"); return InteractionResultHolder.fail(stack); } - if (!old.owner().equals(p.getUUID()) && !p.hasPermissions(2)) { message(p, "message.streamcontrol.denied"); return InteractionResultHolder.fail(stack); } - data.remove(server, old.key()); message(p, "message.streamcontrol.restored"); - } else { - long key = pos.asLong() ^ Long.MIN_VALUE; - var existing = data.byKey(key); - if (existing != null && !existing.owner().equals(p.getUUID()) && !p.hasPermissions(2)) { message(p, "message.streamcontrol.denied"); return InteractionResultHolder.fail(stack); } - if (existing == null && data.owned(p.getUUID()) >= ControlConfig.MAX_PLAYER_REGIONS.get()) { message(p, "message.streamcontrol.limit"); return InteractionResultHolder.fail(stack); } - var look = p.getLookAngle(); double len = Math.hypot(look.x, look.z); - double dx = len > 1e-4 ? look.x / len : p.getDirection().getStepX(); - double dz = len > 1e-4 ? look.z / len : p.getDirection().getStepZ(); - var region = new FlowRegion(key, pos.immutable(), radius, ControlConfig.VERTICAL.get(), dx, dz, - ControlConfig.strength(n.contains("Strength") ? n.getDouble("Strength") : ControlConfig.SPEED.get()), mode == 1, false, p.getUUID(), data.next()); - if (!data.put(server, region)) { message(p, "message.streamcontrol.limit"); return InteractionResultHolder.fail(stack); } - message(p, "message.streamcontrol.applied", Component.translatable("mode.streamcontrol." + mode), radius); + if(mode==Mode.PASTE) { + var clipboard=n.getCompound("Calibration");String kind=clipboard.getString("Kind"); + if("controller".equals(kind) && be instanceof FlowController controller) controller.controls().paste(clipboard); + else if(be instanceof UtilityAccess utility && utility.settings().getString("Kind").equals(kind)) utility.configure(clipboard); + else { message(player,"incompatible");return false; } + message(player,"pasted");return true; } - world.playSound(null, pos, SoundEvents.AMETHYST_BLOCK_CHIME, SoundSource.PLAYERS, 0.6f, 1.2f); - if (ControlConfig.PARTICLES.get()) for (int i = 0; i < 32; i++) { - double a = i * Math.PI / 16; - server.sendParticles(ParticleTypes.END_ROD, pos.getX()+0.5+Math.cos(a)*radius, pos.getY()+1.05, pos.getZ()+0.5+Math.sin(a)*radius, 1, 0, 0, 0, 0); + if(mode==Mode.LINK) { + if(!(be instanceof FlowController controller)) { message(player,"controller_required");return false; } + if(player.isShiftKeyDown()) { controller.controls().unlink();n.remove("LinkPos");n.remove("LinkDimension");store(stack,n);message(player,"unlinked");return true; } + if(!n.contains("LinkPos")) { + n.putLong("LinkPos",pos.asLong());n.putString("LinkDimension",level.dimension().location().toString());store(stack,n);message(player,"source_selected");return true; + } + BlockPos source=BlockPos.of(n.getLong("LinkPos")); + if(!level.dimension().location().toString().equals(n.getString("LinkDimension")) || !level.hasChunkAt(source) + || !allowed(player,source,stack) || !controller.controls().link(source)) { message(player,"invalid_link");return false; } + message(player,"linked");return true; + } + var data=ControlData.get(level);var old=data.at(pos.getX(),pos.getY(),pos.getZ()); + if(old==null || old.controller()) { message(player,"no_legacy_edit");return false; } + if(!old.owner().equals(player.getUUID()) && !player.hasPermissions(2)) { message(player,"denied");return false; } + data.remove(level,old.key());message(player,"restored");return true; + } + private static void inspect(ServerPlayer player,BlockPos pos) { + var level=player.serverLevel();var flow=level.getFluidState(pos).getFlow(level,pos); + FlowHeading heading=FlowHeading.fromVector(flow.x,flow.z);var region=ControlData.get(level).at(pos.getX(),pos.getY(),pos.getZ()); + String direction=heading==null?"Still":heading.key();String source=region==null?"Natural":region.controller()?"Controller":"Legacy edit"; + player.displayClientMessage(Component.literal(String.format(Locale.ROOT,"%s | %s | %.0f%%",source,direction,Math.hypot(flow.x,flow.z)*100)),true); + } + @Override public InteractionResultHolder use(Level world,Player player,InteractionHand hand) { + ItemStack stack=player.getItemInHand(hand);if(world.isClientSide) return InteractionResultHolder.success(stack); + var hit=getPlayerPOVHitResult(world,player,ClipContext.Fluid.ANY); + if(hit.getType()==HitResult.Type.MISS) { + var n=settings(stack); + if(player.isShiftKeyDown()) { + int next=(mode(stack).ordinal()+1)%Mode.values().length;n.putInt("CalibratorMode",next); + n.remove("LinkPos");n.remove("LinkDimension");message(player,"mode",Component.translatable(Mode.values()[next].key())); + } else { n.putBoolean("HideBounds",!n.getBoolean("HideBounds"));message(player,n.getBoolean("HideBounds")?"bounds_off":"bounds_on"); } + store(stack,n);return InteractionResultHolder.success(stack); } - p.getCooldowns().addCooldown(this, 5); return InteractionResultHolder.success(stack); + if(!(player instanceof ServerPlayer server) || !allowed(player,hit.getBlockPos(),stack)) return InteractionResultHolder.fail(stack); + if(!world.getFluidState(hit.getBlockPos()).is(FluidTags.WATER)) return InteractionResultHolder.pass(stack); + return operate(server,hit.getBlockPos(),stack)?InteractionResultHolder.success(stack):InteractionResultHolder.fail(stack); } - @Override public void appendHoverText(ItemStack stack, TooltipContext context, List lines, TooltipFlag flag) { - var n = settings(stack); lines.add(Component.translatable("tooltip.streamcontrol.mode", Component.translatable("mode.streamcontrol." + Math.floorMod(n.getInt("Mode"), 3)))); - lines.add(Component.translatable("tooltip.streamcontrol.wand")); lines.add(Component.translatable("tooltip.streamcontrol.wand_air")); + @Override public void appendHoverText(ItemStack stack,TooltipContext context,List lines,TooltipFlag flag) { + lines.add(Component.translatable("calibrator.streamcontrol.mode",Component.translatable(mode(stack).key()))); + lines.add(Component.translatable("calibrator.streamcontrol.tooltip")); + lines.add(Component.translatable("calibrator.streamcontrol.tooltip_cycle")); + lines.add(Component.translatable("calibrator.streamcontrol.tooltip_bounds")); + if(settings(stack).contains("Calibration")) lines.add(Component.translatable("calibrator.streamcontrol.clipboard_ready")); + if(settings(stack).contains("LinkPos")) lines.add(Component.translatable("calibrator.streamcontrol.source_ready")); } } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/MooringEntity.java b/src/main/java/nl/townsandkingdoms/streamcontrol/MooringEntity.java new file mode 100644 index 0000000..80193bc --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/MooringEntity.java @@ -0,0 +1,76 @@ +package nl.townsandkingdoms.streamcontrol; + +import java.util.*; +import net.minecraft.core.*; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; + +/** Holds one empty boat in place without loading chunks or pulling occupied boats. */ +public final class MooringEntity extends BlockEntity implements UtilityAccess { + private static final Map> CLAIMS=new WeakHashMap<>(); + private int radius=4, vertical=2, cooldown; + private boolean enabled=true; + private UUID boatId; + private double moorX,moorZ; + public MooringEntity(BlockPos p,BlockState s) { super(StreamControl.MOORING_ENTITY.get(),p,s); } + @Override public BlockEntity blockEntity() { return this; } + public UUID boatId() { return boatId; } + public int radius() { return Math.clamp(radius,1,ControlConfig.MOORING_MAX_RADIUS.get()); } + public int vertical() { return Math.clamp(vertical,0,ControlConfig.MOORING_MAX_VERTICAL.get()); } + @Override public CompoundTag settings() { + var n=new CompoundTag();n.putString("Kind","mooring");n.putInt("Radius",radius());n.putInt("Vertical",vertical()); + n.putInt("MaxRadius",ControlConfig.MOORING_MAX_RADIUS.get());n.putInt("MaxVertical",ControlConfig.MOORING_MAX_VERTICAL.get()); + n.putBoolean("Enabled",enabled);n.putBoolean("Secured",boatId!=null);n.putBoolean("Powered",getBlockState().getValue(UtilityBlock.POWERED));return n; + } + @Override public void configure(CompoundTag n) { + radius=Math.clamp(n.getInt("Radius"),1,ControlConfig.MOORING_MAX_RADIUS.get());vertical=Math.clamp(n.getInt("Vertical"),0,ControlConfig.MOORING_MAX_VERTICAL.get()); + enabled=n.getBoolean("Enabled");release();setChanged(); + } + @Override protected void saveAdditional(CompoundTag n,HolderLookup.Provider r) { + super.saveAdditional(n,r);n.putInt("Radius",radius);n.putInt("Vertical",vertical);n.putBoolean("Enabled",enabled); + if(boatId!=null) { n.putUUID("Boat",boatId);n.putDouble("MoorX",moorX);n.putDouble("MoorZ",moorZ); } + } + @Override protected void loadAdditional(CompoundTag n,HolderLookup.Provider r) { + super.loadAdditional(n,r);radius=n.contains("Radius")?n.getInt("Radius"):4;vertical=n.contains("Vertical")?n.getInt("Vertical"):2;enabled=!n.contains("Enabled")||n.getBoolean("Enabled"); + boatId=n.hasUUID("Boat")?n.getUUID("Boat"):null;moorX=n.getDouble("MoorX");moorZ=n.getDouble("MoorZ"); + } + public void release() { + if(level instanceof ServerLevel server && boatId!=null) CLAIMS.computeIfAbsent(server,s->new HashMap<>()).remove(boatId,worldPosition); + if(boatId!=null) { boatId=null;setChanged(); } cooldown=40; + } + @Override public void setRemoved() { release();super.setRemoved(); } + private boolean inRange(Boat boat) { + double dx=boat.getX()-worldPosition.getX()-.5,dz=boat.getZ()-worldPosition.getZ()-.5; + return dx*dx+dz*dz<=radius()*radius() && boat.getY()>=worldPosition.getY()-vertical() && boat.getY()new HashMap<>());BlockPos other=map.get(boat.getUUID()); + if(other!=null && !other.equals(worldPosition) && server.hasChunkAt(other) + && server.getBlockEntity(other) instanceof MooringEntity post && boat.getUUID().equals(post.boatId)) return false; + map.put(boat.getUUID(),worldPosition.immutable());return true; + } + public static void tick(Level l,BlockPos p,BlockState s,MooringEntity be) { be.tick(); } + public void tick() { + if(!(level instanceof ServerLevel server)) return; + if(!ControlConfig.ENABLED.get() || !enabled || getBlockState().getValue(UtilityBlock.POWERED)) { if(boatId!=null) release();return; } + if(cooldown>0) { cooldown--;return; } + if(boatId!=null) { + var entity=server.getEntity(boatId); + if(!(entity instanceof Boat boat) || !boat.isAlive() || boat.isVehicle() || !inRange(boat) + || Math.hypot(boat.getX()-moorX,boat.getZ()-moorZ)>1.5 || !claim(server,boat)) { release();return; } + // Preserve vertical bobbing; horizontal momentum is canceled while moored. + var velocity=boat.getDeltaMovement();boat.setDeltaMovement(0,velocity.y,0);boat.setPos(moorX,boat.getY(),moorZ);boat.hasImpulse=true; + return; + } + if(Math.floorMod(server.getGameTime()+worldPosition.asLong(),10)!=0) return; + var candidates=server.getEntitiesOfClass(Boat.class,new AABB(worldPosition).inflate(radius(),vertical(),radius()), + boat->boat.isAlive() && !boat.isVehicle() && inRange(boat)); + candidates.sort(Comparator.comparingDouble(b->b.distanceToSqr(worldPosition.getX()+.5,worldPosition.getY()+.5,worldPosition.getZ()+.5))); + for(Boat boat:candidates) if(claim(server,boat)) { boatId=boat.getUUID();moorX=boat.getX();moorZ=boat.getZ();setChanged();break; } + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/StreamControl.java b/src/main/java/nl/townsandkingdoms/streamcontrol/StreamControl.java index 996509e..9305e47 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/StreamControl.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/StreamControl.java @@ -22,12 +22,22 @@ public final class StreamControl { public static final DeferredRegister TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, ID); public static final DeferredBlock GENERATOR = BLOCKS.register("current_generator", () -> new ControllerBlock(false, BlockBehaviour.Properties.ofFullCopy(Blocks.COPPER_BLOCK).strength(3))); public static final DeferredBlock ANCHOR = BLOCKS.register("stillwater_anchor", () -> new ControllerBlock(true, BlockBehaviour.Properties.ofFullCopy(Blocks.PRISMARINE).strength(3))); + public static final DeferredBlock SENSOR = BLOCKS.register("flow_sensor", () -> new UtilityBlock(true,BlockBehaviour.Properties.ofFullCopy(Blocks.COPPER_BLOCK).strength(3))); + public static final DeferredBlock MOORING = BLOCKS.register("mooring_post", () -> new UtilityBlock(false,BlockBehaviour.Properties.ofFullCopy(Blocks.OAK_PLANKS).strength(3).noOcclusion())); + public static final DeferredItem SENSOR_ITEM = ITEMS.register("flow_sensor",()->new EngineeringBlockItem(SENSOR.get(),new Item.Properties())); + public static final DeferredItem MOORING_ITEM = ITEMS.register("mooring_post",()->new EngineeringBlockItem(MOORING.get(),new Item.Properties())); + public static final java.util.function.Supplier> SENSOR_ENTITY = ENTITIES.register("flow_sensor", () -> BlockEntityType.Builder.of(FlowSensorEntity::new,SENSOR.get()).build(null)); + public static final java.util.function.Supplier> MOORING_ENTITY = ENTITIES.register("mooring_post", () -> BlockEntityType.Builder.of(MooringEntity::new,MOORING.get()).build(null)); + public static final java.util.List> OPTIONAL_ITEMS = new java.util.ArrayList<>(); public static final DeferredItem WAND = ITEMS.register("flow_wand", () -> new FlowWand(new Item.Properties().stacksTo(1))); - public static final DeferredItem GENERATOR_ITEM = ITEMS.registerSimpleBlockItem(GENERATOR); - public static final DeferredItem ANCHOR_ITEM = ITEMS.registerSimpleBlockItem(ANCHOR); + public static final DeferredItem GENERATOR_ITEM = ITEMS.register("current_generator",()->new EngineeringBlockItem(GENERATOR.get(),new Item.Properties())); + public static final DeferredItem ANCHOR_ITEM = ITEMS.register("stillwater_anchor",()->new EngineeringBlockItem(ANCHOR.get(),new Item.Properties())); public static final java.util.function.Supplier> CONTROLLER = ENTITIES.register("controller", () -> BlockEntityType.Builder.of(ControllerEntity::new, GENERATOR.get(), ANCHOR.get()).build(null)); - static { TABS.register("flow_control", () -> CreativeModeTab.builder().title(Component.translatable("itemGroup.streamcontrol")).icon(() -> new ItemStack(WAND.get())).displayItems((params, output) -> { output.accept(WAND.get()); output.accept(GENERATOR.get()); output.accept(ANCHOR.get()); }).build()); } + static { TABS.register("flow_control", () -> CreativeModeTab.builder().title(Component.translatable("itemGroup.streamcontrol")).icon(() -> new ItemStack(WAND.get())).displayItems((params, output) -> { output.accept(WAND.get()); output.accept(GENERATOR.get()); output.accept(ANCHOR.get()); output.accept(SENSOR.get()); output.accept(MOORING.get()); OPTIONAL_ITEMS.forEach(item -> output.accept(item.get())); }).build()); } public StreamControl(IEventBus bus, ModContainer container) { + if (net.neoforged.fml.ModList.get().isLoaded("create")) nl.townsandkingdoms.streamcontrol.compat.create.CreateIntegration.register(); + if (net.neoforged.fml.loading.FMLEnvironment.dist == net.neoforged.api.distmarker.Dist.CLIENT) + nl.townsandkingdoms.streamcontrol.client.EngineeringClient.register(bus); BLOCKS.register(bus); ITEMS.register(bus); ENTITIES.register(bus); TABS.register(bus); container.registerConfig(ModConfig.Type.SERVER, ControlConfig.SPEC); bus.addListener(ControlNetwork::register); diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/UtilityAccess.java b/src/main/java/nl/townsandkingdoms/streamcontrol/UtilityAccess.java new file mode 100644 index 0000000..b41a64f --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/UtilityAccess.java @@ -0,0 +1,8 @@ +package nl.townsandkingdoms.streamcontrol; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.block.entity.BlockEntity; +public interface UtilityAccess { + BlockEntity blockEntity(); + CompoundTag settings(); + void configure(CompoundTag n); +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/UtilityBlock.java b/src/main/java/nl/townsandkingdoms/streamcontrol/UtilityBlock.java new file mode 100644 index 0000000..975155d --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/UtilityBlock.java @@ -0,0 +1,63 @@ +package nl.townsandkingdoms.streamcontrol; + +import com.mojang.serialization.MapCodec; +import net.minecraft.core.*; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.*; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.*; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.entity.*; +import net.minecraft.world.level.block.state.*; +import net.minecraft.world.level.block.state.properties.*; +import net.minecraft.world.level.material.*; +import net.minecraft.world.phys.BlockHitResult; + +/** Same waterlogged model family as the original controllers. */ +public final class UtilityBlock extends BaseEntityBlock implements SimpleWaterloggedBlock { + public static final MapCodec SENSOR_CODEC = simpleCodec(p -> new UtilityBlock(true,p)); + public static final MapCodec MOORING_CODEC = simpleCodec(p -> new UtilityBlock(false,p)); + public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED, POWERED = BlockStateProperties.POWERED; + public final boolean sensor; + public UtilityBlock(boolean sensor,Properties p) { + super(p);this.sensor=sensor; + registerDefaultState(stateDefinition.any().setValue(WATERLOGGED,false).setValue(POWERED,false)); + } + @Override protected MapCodec codec() { return sensor ? SENSOR_CODEC : MOORING_CODEC; } + @Override protected void createBlockStateDefinition(StateDefinition.Builder b) { b.add(WATERLOGGED,POWERED); } + @Override public BlockState getStateForPlacement(BlockPlaceContext c) { return defaultBlockState().setValue(WATERLOGGED,c.getLevel().getFluidState(c.getClickedPos()).is(FluidTags.WATER)).setValue(POWERED,c.getLevel().hasNeighborSignal(c.getClickedPos())); } + @Override protected RenderShape getRenderShape(BlockState s) { return RenderShape.MODEL; } + @Override public BlockEntity newBlockEntity(BlockPos p,BlockState s) { return sensor ? new FlowSensorEntity(p,s) : new MooringEntity(p,s); } + @Override public BlockEntityTicker getTicker(Level l,BlockState s,BlockEntityType t) { + if (l.isClientSide) return null; + return sensor ? createTickerHelper(t,StreamControl.SENSOR_ENTITY.get(),FlowSensorEntity::tick) + : createTickerHelper(t,StreamControl.MOORING_ENTITY.get(),MooringEntity::tick); + } + @Override protected FluidState getFluidState(BlockState s) { return s.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(s); } + @Override protected BlockState updateShape(BlockState s,Direction d,BlockState other,LevelAccessor l,BlockPos p,BlockPos q) { + if(s.getValue(WATERLOGGED)) l.scheduleTick(p,Fluids.WATER,Fluids.WATER.getTickDelay(l));return super.updateShape(s,d,other,l,p,q); + } + @Override protected void neighborChanged(BlockState s,Level l,BlockPos p,Block b,BlockPos q,boolean moving) { + if(!l.isClientSide) { + boolean on=l.hasNeighborSignal(p); + if(on!=s.getValue(POWERED)) l.setBlock(p,s.setValue(POWERED,on),3); + if(l.getBlockEntity(p) instanceof MooringEntity mooring && on) mooring.release(); + } + } + @Override protected InteractionResult useWithoutItem(BlockState s,Level l,BlockPos p,Player player,BlockHitResult hit) { + if(!player.mayBuild() || !l.mayInteract(player,p)) return InteractionResult.FAIL; + if(player instanceof ServerPlayer server && l.getBlockEntity(p) instanceof UtilityAccess utility) ControlNetwork.openUtility(server,utility); + return InteractionResult.sidedSuccess(l.isClientSide); + } + @Override protected boolean hasAnalogOutputSignal(BlockState s) { return sensor; } + @Override protected int getAnalogOutputSignal(BlockState s,Level l,BlockPos p) { return l.getBlockEntity(p) instanceof FlowSensorEntity be ? be.output() : 0; } + @Override protected void onRemove(BlockState old,Level l,BlockPos p,BlockState next,boolean moving) { + if(!old.is(next.getBlock())) { + if(l.getBlockEntity(p) instanceof MooringEntity m) m.release(); + if(sensor) l.updateNeighbourForOutputSignal(p,this); + } + super.onRemove(old,l,p,next,moving); + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerScreen.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerScreen.java index c5deda1..c9b3da8 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerScreen.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerScreen.java @@ -12,6 +12,9 @@ import net.minecraft.resources.ResourceLocation; import net.neoforged.neoforge.network.PacketDistributor; import nl.townsandkingdoms.streamcontrol.ControlNetwork; +import nl.townsandkingdoms.streamcontrol.FlowProfile; +import nl.townsandkingdoms.streamcontrol.ControllerSettings; +import net.minecraft.nbt.CompoundTag; /** Slate/copper TNK menu artwork, with native input, focus, tooltips and narration. */ public final class ControllerScreen extends Screen { @@ -30,6 +33,11 @@ private static ResourceLocation texture(String name) { private boolean connected; private FlowHeading facing; private int left, top; + private final CompoundTag settings; + private FlowProfile profileA, profileB; + private int editProfile, vertical; + private FlowProfile.Action action; + private boolean automation; public static void open(ControlNetwork.Open packet) { Minecraft.getInstance().setScreen(new ControllerScreen(packet)); @@ -37,22 +45,58 @@ public static void open(ControlNetwork.Open packet) { private ControllerScreen(ControlNetwork.Open packet) { super(Component.translatable(packet.still() ? "block.streamcontrol.stillwater_anchor" - : "block.streamcontrol.current_generator")); + : packet.settings()!=null && packet.settings().getBoolean("Kinetic") ? "block.streamcontrol.mechanical_current_generator" : "block.streamcontrol.current_generator")); snapshot = packet; radius = Math.max(1, Math.min(packet.maxRadius(), packet.radius())); speed = Math.max(0.05, Math.min(packet.maxStrength(), packet.strength())); connected = packet.connectedOnly(); facing = FlowHeading.fromId(packet.facing()); if (facing == null) facing = FlowHeading.NORTH; + settings = packet.settings()==null ? new CompoundTag() : packet.settings().copy(); + profileA = settings.contains("ProfileA") ? FlowProfile.load(settings.getCompound("ProfileA"),packet.still()) : + new FlowProfile(radius,packet.vertical(),speed,facing,connected,packet.still()?FlowProfile.Action.CALM:FlowProfile.Action.CURRENT); + profileB = settings.contains("ProfileB") ? FlowProfile.load(settings.getCompound("ProfileB"),packet.still()) : + new FlowProfile(radius,packet.vertical(),speed,facing,connected,packet.still()?FlowProfile.Action.RELEASE:FlowProfile.Action.REVERSE); + readProfile(); } private static Component tr(String key, Object... args) { return Component.translatable("gui.streamcontrol." + key, args); } + private Component engineering(String key,Object...args) { return Component.translatable("engineering.streamcontrol."+key,args); } + private void readProfile() { + var p=editProfile==0?profileA:profileB;radius=p.radius();vertical=p.vertical();speed=p.strength();facing=p.heading();connected=p.connectedOnly();action=p.action(); + } + private void storeProfile() { + var p=new FlowProfile(radius,vertical,speed,facing,connected,action); + if(editProfile==0) profileA=p;else profileB=p; + } + private void rebuild() { clearWidgets();init(); } + private void changeProfile(int selected) { storeProfile();editProfile=selected;readProfile();rebuild(); } + private EngineeringWidgets.ActionButton actionButton(int x,int y,int w,int h,Component label,Button.OnPress press,java.util.function.BooleanSupplier selected) { + return addRenderableWidget(new EngineeringWidgets.ActionButton(left+x,top+y,w,h,label,press,selected)); + } @Override protected void init() { left = (width - PANEL_W) / 2; top = (height - PANEL_H) / 2; + actionButton(16,29,138,16,engineering("settings_tab",editProfile==0?"A":"B"),b->{automation=false;rebuild();},()->!automation); + actionButton(162,29,138,16,engineering("automation_tab"),b->{automation=true;rebuild();},()->automation); + if(automation) { + actionButton(26,56,264,22,engineering("redstone_"+settings.getInt("RedstoneMode")),b->{ + int next=(settings.getInt("RedstoneMode")+1)%ControllerSettings.Redstone.values().length; + settings.putInt("RedstoneMode",next);b.setMessage(engineering("redstone_"+next)); + },()->false); + actionButton(26,84,100,20,engineering("profile_a"),b->changeProfile(0),()->editProfile==0); + actionButton(134,84,100,20,engineering("profile_b"),b->changeProfile(1),()->editProfile==1); + var unlink=actionButton(242,84,48,20,engineering("unlink"),b->{settings.remove("LinkedSource");rebuild();},()->false); + unlink.active=settings.contains("LinkedSource"); + actionButton(26,111,264,22,engineering("action_"+action.ordinal()),b->{ + action=snapshot.still()?(action==FlowProfile.Action.CALM?FlowProfile.Action.RELEASE:FlowProfile.Action.CALM):FlowProfile.Action.values()[(action.ordinal()+1)%4]; + b.setMessage(engineering("action_"+action.ordinal())); + },()->false); + addRenderableWidget(new EngineeringWidgets.RangeSlider(left+26,top+154,264,0,settings.contains("MaxVertical")?settings.getInt("MaxVertical"):16,vertical,"vertical",n->vertical=n)); + } else { var radiusSlider = addRenderableWidget(new RadiusSlider(left + (snapshot.still() ? 26 : 182), top + (snapshot.still() ? 156 : 83), snapshot.still() ? 264 : 108)); radiusSlider.active = snapshot.maxRadius() > 1; @@ -72,6 +116,7 @@ private static Component tr(String key, Object... args) { addRenderableWidget(button); } } + } var waterToggle = new SlateButton(left + 14, top + 176, 286, 22, tr("connected", tr(connected ? "on" : "off")), b -> { connected = !connected; @@ -95,8 +140,9 @@ private static Component tr(String key, Object... args) { } private void apply() { - PacketDistributor.sendToServer(new ControlNetwork.Configure(snapshot.pos(), radius, speed, - connected, facing.id())); + storeProfile();settings.put("ProfileA",profileA.save());settings.put("ProfileB",profileB.save()); + PacketDistributor.sendToServer(new ControlNetwork.Configure(snapshot.pos(),profileA.radius(),profileA.strength(), + profileA.connectedOnly(),profileA.heading().id(),settings)); onClose(); } @@ -110,16 +156,18 @@ private void apply() { drawPanel(g); Component heading = title.copy().withStyle(style -> style.withFont(MENU_FONT)); centered(g, heading, left + PANEL_W / 2, top + 12, CREAM); - centered(g, tr(snapshot.still() ? "calm_subtitle" : "current_subtitle"), - left + PANEL_W / 2, top + 32, MUTED); + if(automation) { + g.drawString(font,engineering("vertical_range"),left+26,top+141,INK,false); + right(g,Component.literal("+/- "+vertical),left+290,top+141,TEAL); + } else { drawWaterPreview(g); if (snapshot.still()) { - centered(g, tr("calm_area"), left + 158, top + 54, INK); + centered(g, tr(action==FlowProfile.Action.RELEASE?"released_area":"calm_area"), left + 158, top + 54, INK); centered(g, tr("diameter_label"), left + 66, top + 82, MUTED); centered(g, tr("blocks", radius * 2 + 1), left + 66, top + 98, INK); centered(g, tr("height_label"), left + 250, top + 82, MUTED); - centered(g, Component.literal("+/- " + snapshot.vertical()), left + 250, top + 98, INK); - centered(g, tr("zero_flow"), left + 158, top + 129, TEAL); + centered(g, Component.literal("+/- " + vertical), left + 250, top + 98, INK); + centered(g, tr(action==FlowProfile.Action.RELEASE?"release_flow":"zero_flow"), left + 158, top + 129, TEAL); g.drawString(font, tr("radius_label"), left + 26, top + 144, INK, false); right(g, tr("blocks", radius), left + 290, top + 144, TEAL); } else { @@ -131,16 +179,19 @@ private void apply() { centered(g, Component.literal(String.format(Locale.ROOT, "%d%%", Math.round(speed * 100))), left + 236, top + 120, TEAL); centered(g, tr("preview_diameter", radius * 2 + 1), left + 236, top + 151, INK); - centered(g, tr("preview_height", snapshot.vertical()), left + 236, top + 162, MUTED); + centered(g, tr("preview_height", vertical), left + 236, top + 162, MUTED); + } } // Keep status within the frame, including when redstone disables the controller. - centered(g, tr(snapshot.powered() ? "powered_status" : "apply_hint"), - left + PANEL_W / 2, top + 222, snapshot.powered() ? 0xFFFFB093 : MUTED); + boolean paused=snapshot.powered() && settings.getInt("RedstoneMode")==0; + Component status=settings.contains("LinkedSource")?engineering("linked_source",net.minecraft.core.BlockPos.of(settings.getLong("LinkedSource")).toShortString()): + settings.getBoolean("Kinetic")?engineering("drive_rpm",Math.round(settings.getFloat("RPM"))):tr(paused?"powered_status":"apply_hint"); + centered(g,status,left+PANEL_W/2,top+222,paused?0xFFFFB093:MUTED); super.render(g, mouseX, mouseY, partialTick); } private void drawPanel(GuiGraphics g) { - g.blit(snapshot.still() ? STILL_BACKGROUND : CURRENT_BACKGROUND, left, top, + g.blit(automation ? texture("automation_controller") : snapshot.still() ? STILL_BACKGROUND : CURRENT_BACKGROUND, left, top, 0f, 0f, PANEL_W, PANEL_H, PANEL_W, PANEL_H); } @@ -211,9 +262,8 @@ protected void drawLabel(GuiGraphics g, int color) { @Override public void renderWidget(GuiGraphics g, int mx, int my, float partialTick) { boolean highlight = isHoveredOrFocused(); int state = !active ? 4 : primary || selected() ? (highlight ? 3 : 2) : (highlight ? 1 : 0); - String name = getWidth() == 26 ? "compass" : getWidth() == 286 ? "toggle" - : getWidth() == 174 ? "apply" : "cancel"; - control(g, name, getX(), getY(), getWidth(), getHeight(), state); + if(getWidth()==26) control(g,"compass",getX(),getY(),getWidth(),getHeight(),state); + else EngineeringWidgets.button(g,getX(),getY(),getWidth(),getHeight(),state); if (highlight) { int x = getX(), y = getY(), w = getWidth(), h = getHeight(); g.fill(x, y, x + w, y + 1, CREAM); diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/EngineeringClient.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/EngineeringClient.java new file mode 100644 index 0000000..15c9d7d --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/EngineeringClient.java @@ -0,0 +1,100 @@ +package nl.townsandkingdoms.streamcontrol.client; + +import java.util.*; +import com.mojang.blaze3d.vertex.*; +import net.minecraft.client.*; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.*; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.phys.*; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.ModList; +import net.neoforged.neoforge.client.event.*; +import net.neoforged.neoforge.common.NeoForge; +import nl.townsandkingdoms.streamcontrol.*; + +/** Local inspection of already synchronized data. No per-frame packets or chunk scans. */ +public final class EngineeringClient { + private record Readout(BlockPos center,int radius,int vertical,List lines,boolean bounds) {} + private static Readout readout; + private static long lastTick=Long.MIN_VALUE; + public static void register(IEventBus bus) { + bus.addListener(EngineeringClient::layers); + if(ModList.get().isLoaded("create")) bus.addListener(nl.townsandkingdoms.streamcontrol.compat.create.CreateClient::renderers); + NeoForge.EVENT_BUS.addListener(EngineeringClient::world); + } + private static Component tr(String key,Object...args) { return Component.translatable("engineering.streamcontrol."+key,args); } + private static ItemStack tool(Minecraft mc) { + if(mc.player==null) return ItemStack.EMPTY; + if(mc.player.getMainHandItem().is(StreamControl.WAND.get())) return mc.player.getMainHandItem(); + if(mc.player.getOffhandItem().is(StreamControl.WAND.get())) return mc.player.getOffhandItem();return ItemStack.EMPTY; + } + private static void update() { + var mc=Minecraft.getInstance();var stack=tool(mc); + if(mc.level==null || stack.isEmpty() || mc.screen!=null || mc.options.hideGui) { readout=null;lastTick=Long.MIN_VALUE;return; } + long tick=mc.level.getGameTime();if(tick==lastTick) return;lastTick=tick; + var start=mc.player.getEyePosition();var end=start.add(mc.player.getLookAngle().scale(mc.player.blockInteractionRange())); + var hit=mc.level.clip(new ClipContext(start,end,ClipContext.Block.OUTLINE,ClipContext.Fluid.ANY,mc.player)); + List lines=new ArrayList<>();lines.add(Component.translatable("calibrator.streamcontrol.mode",Component.translatable(FlowWand.mode(stack).key()))); + if(hit.getType()!=HitResult.Type.BLOCK) { readout=new Readout(mc.player.blockPosition(),0,0,lines,false);return; } + var pos=hit.getBlockPos();var be=mc.level.getBlockEntity(pos);int radius=0,vertical=0;BlockPos center=pos; + FlowRegion region=FlowOverrides.clientAt(pos.getX(),pos.getY(),pos.getZ()); + if(be instanceof FlowController controller) { + var override=FlowOverrides.clientByKey(pos.asLong()); + radius=override==null?controller.radius():override.radius();vertical=override==null?controller.controls().a().vertical():override.vertical(); + lines.add(be.getBlockState().getBlock().getName()); + if(controller.controls().source()!=null) lines.add(tr("linked_source",controller.controls().source().toShortString())); + if(!Float.isNaN(controller.rpm())) lines.add(tr("drive_rpm",Math.round(controller.rpm()))); + } else if(be instanceof FlowSensorEntity sensor) { + radius=sensor.radius();vertical=sensor.vertical();lines.add(tr("sensor_output",sensor.output())); + lines.add(tr("sensor_mode",tr("sensor_mode_"+sensor.mode().ordinal()))); + } else if(be instanceof MooringEntity mooring) { + radius=mooring.radius();vertical=mooring.vertical();lines.add(tr(mooring.boatId()==null?"mooring_waiting":"mooring_secured")); + } else if(mc.level.getFluidState(pos).is(net.minecraft.tags.FluidTags.WATER)) { + var flow=mc.level.getFluidState(pos).getFlow(mc.level,pos);var heading=FlowHeading.fromVector(flow.x,flow.z); + lines.add(tr("readout_speed",Math.round(Math.hypot(flow.x,flow.z)*100))); + lines.add(tr("readout_direction",heading==null?tr("still"):Component.translatable("gui.streamcontrol."+heading.key()))); + lines.add(tr(region==null?"source_natural":region.controller()?"source_controller":"source_legacy")); + if(region!=null) { radius=region.radius();vertical=region.vertical();center=region.center(); } + } + if(radius>0) lines.add(tr("readout_range",radius,vertical)); + readout=new Readout(center,radius,vertical,lines,radius>0 && !FlowWand.settings(stack).getBoolean("HideBounds")); + } + private static void layers(RegisterGuiLayersEvent e) { + e.registerAboveAll(ResourceLocation.fromNamespaceAndPath(StreamControl.ID,"calibrator"),(g,delta)->hud(g)); + } + private static void hud(GuiGraphics g) { + update();if(readout==null) return;var mc=Minecraft.getInstance();int widest=0; + for(var line:readout.lines) widest=Math.max(widest,mc.font.width(line)); + int w=widest+16,x=mc.getWindow().getGuiScaledWidth()-w-8,y=8; + g.fill(x,y,x+w,y+readout.lines.size()*11+12,0xE620293F); + g.fill(x,y,x+2,y+readout.lines.size()*11+12,0xFFC09473); + for(int i=0;imin; + } + private int current() { return min+(int)Math.round(value*(max-min)); } + @Override protected void updateMessage() { setMessage(Component.translatable("engineering.streamcontrol."+key,current())); } + @Override protected void applyValue() { setter.accept(current());updateMessage(); } + @Override public void renderWidget(GuiGraphics g,int mx,int my,float tick) { + int x=getX(),y=getY(),w=getWidth(); + // Reuse the generated native wide track at its exact width. + g.blit(texture("track_wide"),x,y+4,0f,0f,w,8,w,8); + int handle=x+3+(int)Math.round(value*(w-12));g.fill(x+3,y+7,handle+4,y+9,TEAL); + int state=!active?4:isHoveredOrFocused()?3:2; + g.blit(texture("handle"),handle,y+1,0f,state*14,9,14,9,70); + } + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/UtilityScreen.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/UtilityScreen.java new file mode 100644 index 0000000..cbcc07f --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/UtilityScreen.java @@ -0,0 +1,63 @@ +package nl.townsandkingdoms.streamcontrol.client; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.neoforged.neoforge.network.PacketDistributor; +import nl.townsandkingdoms.streamcontrol.*; +import static nl.townsandkingdoms.streamcontrol.client.EngineeringWidgets.*; + +public final class UtilityScreen extends Screen { + private final ControlNetwork.UtilityOpen snapshot; + private final CompoundTag options; + private final boolean sensor; + private int radius,vertical,mode,left,top; + private boolean toggle; + public static void open(ControlNetwork.UtilityOpen packet) { Minecraft.getInstance().setScreen(new UtilityScreen(packet)); } + private UtilityScreen(ControlNetwork.UtilityOpen packet) { + super(Component.translatable("block.streamcontrol."+("sensor".equals(packet.settings().getString("Kind"))?"flow_sensor":"mooring_post"))); + snapshot=packet;options=packet.settings().copy();sensor="sensor".equals(options.getString("Kind")); + radius=options.getInt("Radius");vertical=options.getInt("Vertical");mode=Math.clamp(options.getInt("Mode"),0,2); + toggle=options.getBoolean(sensor?"EmptyOnly":"Enabled"); + } + private Component tr(String key,Object...args) { return Component.translatable("engineering.streamcontrol."+key,args); } + @Override protected void init() { + left=(width-316)/2;top=(height-238)/2; + addRenderableWidget(new RangeSlider(left+26,top+72,264,1,Math.max(1,options.getInt("MaxRadius")),radius,"radius",n->radius=n)); + addRenderableWidget(new RangeSlider(left+26,top+112,264,0,Math.max(0,options.getInt("MaxVertical")),vertical,"vertical",n->vertical=n)); + var select=new ActionButton(left+26,top+138,264,22,sensor?modeLabel():tr("mooring_automatic"),b->{ mode=(mode+1)%3;b.setMessage(modeLabel()); },()->false); + select.active=sensor;addRenderableWidget(select); + addRenderableWidget(new ActionButton(left+14,top+176,286,22,toggleLabel(),b->{toggle=!toggle;b.setMessage(toggleLabel());},()->toggle)); + addRenderableWidget(new ActionButton(left+14,top+200,174,20,Component.translatable("gui.streamcontrol.apply"),b->apply(),()->true)); + addRenderableWidget(new ActionButton(left+196,top+200,104,20,Component.translatable("gui.streamcontrol.cancel"),b->onClose(),()->false)); + } + private Component modeLabel() { return tr("sensor_mode",tr("sensor_mode_"+mode)); } + private Component toggleLabel() { return tr(sensor?"empty_boats":"auto_moor",Component.translatable("gui.streamcontrol."+(toggle?"on":"off"))); } + private void apply() { + options.putInt("Radius",radius);options.putInt("Vertical",vertical);options.putInt("Mode",mode);options.putBoolean(sensor?"EmptyOnly":"Enabled",toggle); + PacketDistributor.sendToServer(new ControlNetwork.UtilityConfigure(snapshot.pos(),options));onClose(); + } + @Override public boolean isPauseScreen() { return false; } + @Override public void renderBackground(GuiGraphics g,int x,int y,float t) {} + @Override public void render(GuiGraphics g,int mx,int my,float tick) { + g.fill(0,0,width,height,0xA0141C2E); + g.blit(texture("automation_controller"),left,top,0f,0f,316,238,316,238); + var menu=net.minecraft.resources.ResourceLocation.fromNamespaceAndPath("streamcontrol","menu"); + text(g,title.copy().withStyle(s->s.withFont(menu)),left+158,top+12,TEXT); + text(g,tr(sensor?"sensor_subtitle":"mooring_subtitle"),left+158,top+32,MUTED); + g.drawString(font,tr("horizontal_range"),left+26,top+57,TEXT,false); + right(g,tr("blocks",radius),left+290,top+57); + g.drawString(font,tr("vertical_range"),left+26,top+97,TEXT,false); + right(g,Component.literal("+/- "+vertical),left+290,top+97); + Component detail=sensor ? tr("sensor_hint_"+mode) : tr("mooring_release_hint"); + text(g,detail,left+158,top+164,MUTED); + Component status=sensor?tr("sensor_output",options.getInt("Output")): + tr(options.getBoolean("Powered")?"mooring_powered":options.getBoolean("Secured")?"mooring_secured":"mooring_waiting"); + if(minecraft!=null && minecraft.level!=null && minecraft.level.getBlockEntity(net.minecraft.core.BlockPos.of(snapshot.pos())) instanceof FlowSensorEntity be) + status=tr("sensor_output",be.output()); + text(g,status,left+158,top+222,TEAL);super.render(g,mx,my,tick); + } + private void right(GuiGraphics g,Component s,int x,int y) { g.drawString(font,s,x-font.width(s),y,TEAL,false); } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateClient.java b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateClient.java new file mode 100644 index 0000000..c6bae86 --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateClient.java @@ -0,0 +1,19 @@ +package nl.townsandkingdoms.streamcontrol.compat.create; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer; +import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.core.Direction; +import net.neoforged.neoforge.client.event.EntityRenderersEvent; + +public final class CreateClient { + public static void renderers(EntityRenderersEvent.RegisterRenderers event) { event.registerBlockEntityRenderer(CreateIntegration.ENTITY.get(),ShaftRenderer::new); } + private static final class ShaftRenderer extends KineticBlockEntityRenderer { + ShaftRenderer(BlockEntityRendererProvider.Context context) { super(context); } + @Override protected void renderSafe(MechanicalCurrentEntity be,float partial,PoseStack pose,MultiBufferSource buffers,int light,int overlay) { + // Always render this un-instanced consumer's shaft, including when Flywheel is active. + renderRotatingKineticBlock(be,shaft(Direction.Axis.Y),pose,buffers.getBuffer(RenderType.solid()),light); + } + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateIntegration.java b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateIntegration.java new file mode 100644 index 0000000..0580fef --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateIntegration.java @@ -0,0 +1,22 @@ +package nl.townsandkingdoms.streamcontrol.compat.create; + +import java.util.function.Supplier; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.neoforged.neoforge.registries.*; +import nl.townsandkingdoms.streamcontrol.StreamControl; + +/** Loaded only after ModList confirms Create is installed. */ +public final class CreateIntegration { + public static DeferredBlock BLOCK; + public static DeferredItem ITEM; + public static Supplier> ENTITY; + public static void register() { + BLOCK=StreamControl.BLOCKS.register("mechanical_current_generator",()->new MechanicalCurrentBlock(BlockBehaviour.Properties.ofFullCopy(Blocks.COPPER_BLOCK).strength(3).noOcclusion())); + ITEM=StreamControl.ITEMS.register("mechanical_current_generator",()->new nl.townsandkingdoms.streamcontrol.EngineeringBlockItem(BLOCK.get(),new net.minecraft.world.item.Item.Properties())); + ENTITY=StreamControl.ENTITIES.register("mechanical_current_generator",()->BlockEntityType.Builder.of(MechanicalCurrentEntity::new,BLOCK.get()).build(null)); + StreamControl.OPTIONAL_ITEMS.add(BLOCK); + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentBlock.java b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentBlock.java new file mode 100644 index 0000000..019b082 --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentBlock.java @@ -0,0 +1,52 @@ +package nl.townsandkingdoms.streamcontrol.compat.create; + +import com.mojang.serialization.MapCodec; +import com.simibubi.create.content.kinetics.base.KineticBlock; +import com.simibubi.create.foundation.block.IBE; +import net.minecraft.core.*; +import net.minecraft.server.level.*; +import net.minecraft.world.*; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.*; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.*; +import net.minecraft.world.level.material.*; +import net.minecraft.world.phys.BlockHitResult; +import nl.townsandkingdoms.streamcontrol.*; +import static nl.townsandkingdoms.streamcontrol.ControllerBlock.*; + +/** A real kinetic consumer with a bottom shaft, not an adjacent-block RPM probe. */ +public final class MechanicalCurrentBlock extends KineticBlock implements IBE, SimpleWaterloggedBlock { + private static final MapCodec CODEC=simpleCodec(MechanicalCurrentBlock::new); + public MechanicalCurrentBlock(Properties p) { super(p);registerDefaultState(stateDefinition.any().setValue(FACING,Direction.NORTH).setValue(DIAGONAL,false).setValue(POWERED,false).setValue(WATERLOGGED,false)); } + @Override protected MapCodec codec() { return CODEC; } + @Override protected void createBlockStateDefinition(StateDefinition.Builder b) { b.add(FACING,DIAGONAL,POWERED,WATERLOGGED); } + @Override public BlockState getStateForPlacement(BlockPlaceContext c) { return defaultBlockState().setValue(FACING,c.getHorizontalDirection()).setValue(WATERLOGGED,c.getLevel().getFluidState(c.getClickedPos()).is(net.minecraft.tags.FluidTags.WATER)).setValue(POWERED,c.getLevel().hasNeighborSignal(c.getClickedPos())); } + @Override public Class getBlockEntityClass() { return MechanicalCurrentEntity.class; } + @Override public BlockEntityType getBlockEntityType() { return CreateIntegration.ENTITY.get(); } + @Override public Direction.Axis getRotationAxis(BlockState state) { return Direction.Axis.Y; } + @Override public boolean hasShaftTowards(LevelReader l,BlockPos p,BlockState s,Direction face) { return face==Direction.DOWN; } + @Override protected FluidState getFluidState(BlockState s) { return s.getValue(WATERLOGGED)?Fluids.WATER.getSource(false):super.getFluidState(s); } + @Override public BlockState updateShape(BlockState s,Direction d,BlockState n,LevelAccessor l,BlockPos p,BlockPos q) { + if(s.getValue(WATERLOGGED)) l.scheduleTick(p,Fluids.WATER,Fluids.WATER.getTickDelay(l));return super.updateShape(s,d,n,l,p,q); + } + @Override public void neighborChanged(BlockState s,Level l,BlockPos p,Block b,BlockPos q,boolean moving) { + if(!l.isClientSide) { + boolean on=l.hasNeighborSignal(p);if(on!=s.getValue(POWERED)) l.setBlock(p,s.setValue(POWERED,on),3); + if(l.getBlockEntity(p) instanceof FlowController controller) controller.waterChanged(); + } + } + @Override protected InteractionResult useWithoutItem(BlockState s,Level l,BlockPos p,Player player,BlockHitResult hit) { + if(!player.mayBuild() || !l.mayInteract(player,p)) return InteractionResult.FAIL; + if(player instanceof ServerPlayer server && l.getBlockEntity(p) instanceof FlowController controller) ControlNetwork.open(server,controller); + return InteractionResult.sidedSuccess(l.isClientSide); + } + @Override public void onRemove(BlockState old,Level l,BlockPos p,BlockState next,boolean moving) { + if(!old.is(next.getBlock()) && l instanceof ServerLevel server) ControlData.get(server).remove(server,p.asLong()); + super.onRemove(old,l,p,next,moving); + } + @Override public BlockState rotate(BlockState s,Rotation r) { return FlowHeading.fromState(s).rotate(r).apply(s); } + @Override public BlockState mirror(BlockState s,Mirror m) { return FlowHeading.fromState(s).mirror(m).apply(s); } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentEntity.java b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentEntity.java new file mode 100644 index 0000000..d2ce921 --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentEntity.java @@ -0,0 +1,21 @@ +package nl.townsandkingdoms.streamcontrol.compat.create; + +import com.simibubi.create.content.kinetics.base.KineticBlockEntity; +import net.minecraft.core.*; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import nl.townsandkingdoms.streamcontrol.*; + +public final class MechanicalCurrentEntity extends KineticBlockEntity implements FlowController { + private final ControllerSettings controls=new ControllerSettings(this); + public MechanicalCurrentEntity(BlockPos p,BlockState s) { super(CreateIntegration.ENTITY.get(),p,s); } + @Override public BlockEntity blockEntity() { return this; } + @Override public ControllerSettings controls() { return controls; } + @Override public float rpm() { return getSpeed(); } + @Override public void tick() { super.tick();if(level!=null && !level.isClientSide) controls.tick(); } + @Override public void onSpeedChanged(float previous) { super.onSpeedChanged(previous);if(controls!=null) controls.refresh(); } + @Override public float calculateStressApplied() { return lastStressApplied=ControlConfig.KINETIC_STRESS.get().floatValue(); } + @Override protected void write(CompoundTag n,HolderLookup.Provider r,boolean packet) { super.write(n,r,packet);n.put("FlowControl",controls.save()); } + @Override protected void read(CompoundTag n,HolderLookup.Provider r,boolean packet) { super.read(n,r,packet);if(n.contains("FlowControl")) controls.load(n.getCompound("FlowControl")); } +} diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml index 5a80b2c..cf01997 100644 --- a/src/main/resources/META-INF/neoforge.mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -4,11 +4,11 @@ license="GPL-3.0-only" issueTrackerURL="https://github.com/Mikaaah/Streams-Flow-Control/issues" [[mods]] modId="streamcontrol" -version="0.1.7" +version="0.2.0" displayName="Streams Flow Control" authors="Mikaaah / Towns & Kingdoms" displayURL="https://github.com/Mikaaah/Streams-Flow-Control" -description="Shape water currents with a Flow Wand, Current Generator and Stillwater Anchor. Persistent, height-bounded controls for Streams Reflowing." +description="Calibrate currents, automate controller profiles, monitor water and secure boats. Optional Create-powered current generation." [[mixins]] config="streamcontrol.mixins.json" [[dependencies.streamcontrol]] @@ -29,3 +29,10 @@ type="required" versionRange="[2.16.2,2.16.3)" ordering="AFTER" side="BOTH" + +[[dependencies.streamcontrol]] +modId="create" +type="optional" +versionRange="[6.0.10,6.1)" +ordering="AFTER" +side="BOTH" diff --git a/src/main/resources/assets/streamcontrol/blockstates/flow_sensor.json b/src/main/resources/assets/streamcontrol/blockstates/flow_sensor.json new file mode 100644 index 0000000..4c3bd3d --- /dev/null +++ b/src/main/resources/assets/streamcontrol/blockstates/flow_sensor.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "streamcontrol:block/flow_sensor" + } + } +} diff --git a/src/main/resources/assets/streamcontrol/blockstates/mechanical_current_generator.json b/src/main/resources/assets/streamcontrol/blockstates/mechanical_current_generator.json new file mode 100644 index 0000000..1f4798c --- /dev/null +++ b/src/main/resources/assets/streamcontrol/blockstates/mechanical_current_generator.json @@ -0,0 +1,36 @@ +{ + "variants": { + "facing=north,diagonal=false": { + "model": "streamcontrol:block/mechanical_current_generator", + "y": 270 + }, + "facing=north,diagonal=true": { + "model": "streamcontrol:block/mechanical_current_generator_diagonal", + "y": 270 + }, + "facing=east,diagonal=false": { + "model": "streamcontrol:block/mechanical_current_generator", + "y": 0 + }, + "facing=east,diagonal=true": { + "model": "streamcontrol:block/mechanical_current_generator_diagonal", + "y": 0 + }, + "facing=south,diagonal=false": { + "model": "streamcontrol:block/mechanical_current_generator", + "y": 90 + }, + "facing=south,diagonal=true": { + "model": "streamcontrol:block/mechanical_current_generator_diagonal", + "y": 90 + }, + "facing=west,diagonal=false": { + "model": "streamcontrol:block/mechanical_current_generator", + "y": 180 + }, + "facing=west,diagonal=true": { + "model": "streamcontrol:block/mechanical_current_generator_diagonal", + "y": 180 + } + } +} diff --git a/src/main/resources/assets/streamcontrol/blockstates/mooring_post.json b/src/main/resources/assets/streamcontrol/blockstates/mooring_post.json new file mode 100644 index 0000000..c3399fe --- /dev/null +++ b/src/main/resources/assets/streamcontrol/blockstates/mooring_post.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "streamcontrol:block/mooring_post" + } + } +} diff --git a/src/main/resources/assets/streamcontrol/lang/en_us.json b/src/main/resources/assets/streamcontrol/lang/en_us.json index 0056679..cd1c280 100644 --- a/src/main/resources/assets/streamcontrol/lang/en_us.json +++ b/src/main/resources/assets/streamcontrol/lang/en_us.json @@ -1,6 +1,6 @@ { - "itemGroup.streamcontrol": "Streams Flow Control", - "item.streamcontrol.flow_wand": "Flow Wand", + "itemGroup.streamcontrol": "Flow Control", + "item.streamcontrol.flow_wand": "Flow Calibrator", "block.streamcontrol.current_generator": "Current Generator", "block.streamcontrol.stillwater_anchor": "Stillwater Anchor", "mode.streamcontrol.0": "Direct flow", @@ -73,5 +73,85 @@ "gui.streamcontrol.short_nw": "NW", "gui.streamcontrol.calm_area": "CALM WATER", "gui.streamcontrol.diameter_label": "DIAMETER", - "gui.streamcontrol.height_label": "HEIGHT" + "gui.streamcontrol.height_label": "HEIGHT", + "block.streamcontrol.flow_sensor": "Flow Sensor", + "block.streamcontrol.mooring_post": "Mooring Post", + "block.streamcontrol.mechanical_current_generator": "Mechanical Current Generator", + "block.streamcontrol.current_generator.tip": "Programmable currents with two profiles and redstone control.", + "block.streamcontrol.stillwater_anchor.tip": "Calm water around docks; switch profiles with redstone.", + "block.streamcontrol.flow_sensor.tip": "Measure speed, compass direction or boats with comparator output.", + "block.streamcontrol.mooring_post.tip": "Secure one empty boat; boarding or redstone releases it.", + "block.streamcontrol.mechanical_current_generator.tip": "Bottom shaft input. RPM controls strength; reversing reverses flow.", + "calibrator.streamcontrol.inspect": "Inspect", + "calibrator.streamcontrol.copy": "Copy settings", + "calibrator.streamcontrol.paste": "Paste settings", + "calibrator.streamcontrol.link": "Link controllers", + "calibrator.streamcontrol.restore": "Remove legacy edit", + "calibrator.streamcontrol.mode": "Calibrator: %s", + "calibrator.streamcontrol.tooltip": "Inspect water and configure controllers; copy, paste or link in other modes.", + "calibrator.streamcontrol.tooltip_cycle": "Sneak-use the air to cycle modes; Link: source first, target second.", + "calibrator.streamcontrol.tooltip_bounds": "Use the air to toggle range outlines. Sneak-use a linked controller to unlink.", + "calibrator.streamcontrol.clipboard_ready": "Controller settings copied.", + "calibrator.streamcontrol.source_ready": "Link source selected.", + "calibrator.streamcontrol.controller_required": "Use this mode on a controller.", + "calibrator.streamcontrol.copied": "Settings copied. Switch to Paste to apply them.", + "calibrator.streamcontrol.pasted": "Settings applied.", + "calibrator.streamcontrol.incompatible": "Copy compatible controller, sensor or mooring settings first.", + "calibrator.streamcontrol.unlinked": "Controller unlinked.", + "calibrator.streamcontrol.source_selected": "Source selected. Use another controller to link it.", + "calibrator.streamcontrol.invalid_link": "Link rejected: check dimension, distance, loaded source and loops.", + "calibrator.streamcontrol.linked": "Controller linked. The source profiles are followed while loaded.", + "calibrator.streamcontrol.no_legacy_edit": "No old wand edit here. Controller regions are removed by their blocks.", + "calibrator.streamcontrol.denied": "You cannot remove this player's edit.", + "calibrator.streamcontrol.restored": "Old wand edit removed; natural flow restored.", + "calibrator.streamcontrol.bounds_off": "Calibrator outlines hidden.", + "calibrator.streamcontrol.bounds_on": "Calibrator outlines shown.", + "engineering.streamcontrol.settings_tab": "Settings %s", + "engineering.streamcontrol.automation_tab": "Automation", + "engineering.streamcontrol.redstone_0": "Redstone: pause when powered", + "engineering.streamcontrol.redstone_1": "Redstone: always active", + "engineering.streamcontrol.redstone_2": "Redstone: analog strength 0-15", + "engineering.streamcontrol.redstone_3": "Redstone: reverse when powered", + "engineering.streamcontrol.redstone_4": "Redstone: switch Profile A / B", + "engineering.streamcontrol.profile_a": "Profile A", + "engineering.streamcontrol.profile_b": "Profile B", + "engineering.streamcontrol.unlink": "Unlink", + "engineering.streamcontrol.action_0": "Profile action: directed current", + "engineering.streamcontrol.action_1": "Profile action: reversed current", + "engineering.streamcontrol.action_2": "Profile action: calm water", + "engineering.streamcontrol.action_3": "Profile action: natural flow", + "engineering.streamcontrol.horizontal_range": "HORIZONTAL RADIUS", + "engineering.streamcontrol.vertical_range": "VERTICAL REACH", + "engineering.streamcontrol.radius": "Horizontal radius: %s blocks", + "engineering.streamcontrol.vertical": "Vertical reach: +/- %s blocks", + "engineering.streamcontrol.blocks": "%s blocks", + "engineering.streamcontrol.linked_source": "Linked source: %s", + "engineering.streamcontrol.drive_rpm": "Drive: %s RPM", + "engineering.streamcontrol.sensor_subtitle": "Read the water above and below", + "engineering.streamcontrol.mooring_subtitle": "A secure berth for an empty boat", + "engineering.streamcontrol.sensor_mode": "Measure: %s", + "engineering.streamcontrol.sensor_mode_0": "Current strength", + "engineering.streamcontrol.sensor_mode_1": "Compass direction", + "engineering.streamcontrol.sensor_mode_2": "Nearby boats", + "engineering.streamcontrol.sensor_hint_0": "Comparator: 0 = still, 15 = maximum strength", + "engineering.streamcontrol.sensor_hint_1": "Comparator: N=1, NE=2, E=3 ... NW=8", + "engineering.streamcontrol.sensor_hint_2": "Comparator: one level for each boat, up to 15", + "engineering.streamcontrol.sensor_output": "Comparator output: %s / 15", + "engineering.streamcontrol.empty_boats": "Count empty boats only: %s", + "engineering.streamcontrol.auto_moor": "Automatic mooring: %s", + "engineering.streamcontrol.mooring_automatic": "Automatic empty-boat mooring", + "engineering.streamcontrol.mooring_release_hint": "Board the boat or power the post to release", + "engineering.streamcontrol.mooring_powered": "Redstone powered - boat released", + "engineering.streamcontrol.mooring_secured": "Boat secured", + "engineering.streamcontrol.mooring_waiting": "Waiting for an empty boat", + "engineering.streamcontrol.readout_speed": "Current strength: %s%%", + "engineering.streamcontrol.readout_direction": "Direction: %s", + "engineering.streamcontrol.still": "Still water", + "engineering.streamcontrol.source_natural": "Source: natural water", + "engineering.streamcontrol.source_controller": "Source: controller", + "engineering.streamcontrol.source_legacy": "Source: old wand edit", + "engineering.streamcontrol.readout_range": "Radius: %s | Vertical: +/- %s", + "engineering.streamcontrol.configure_tip": "Right-click to configure. Calibrator: inspect, copy and paste.", + "gui.streamcontrol.released_area": "NATURAL WATER", + "gui.streamcontrol.release_flow": "Controller override released" } diff --git a/src/main/resources/assets/streamcontrol/models/block/flow_sensor.json b/src/main/resources/assets/streamcontrol/models/block/flow_sensor.json new file mode 100644 index 0000000..7e7d3b8 --- /dev/null +++ b/src/main/resources/assets/streamcontrol/models/block/flow_sensor.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "down": "streamcontrol:block/flow_sensor_bottom", + "up": "streamcontrol:block/flow_sensor_top", + "north": "streamcontrol:block/flow_sensor_side", + "south": "streamcontrol:block/flow_sensor_side", + "east": "streamcontrol:block/flow_sensor_side", + "west": "streamcontrol:block/flow_sensor_side", + "particle": "streamcontrol:block/flow_sensor_side" + } +} diff --git a/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator.json b/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator.json new file mode 100644 index 0000000..a6c97d9 --- /dev/null +++ b/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator.json @@ -0,0 +1,147 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "body": "streamcontrol:block/current_generator_side", + "top": "streamcontrol:block/current_generator_top", + "casing": "create:block/andesite_casing", + "particle": "streamcontrol:block/current_generator_side" + }, + "elements": [ + { + "from": [ + 0, + 2, + 0 + ], + "to": [ + 16, + 6, + 16 + ], + "faces": { + "down": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "up": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "north": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "west": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + } + } + }, + { + "from": [ + 0, + 6, + 0 + ], + "to": [ + 16, + 16, + 16 + ], + "faces": { + "down": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "up": { + "texture": "#top", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "north": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "south": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "east": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "west": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + } + } + } + ] +} diff --git a/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator_diagonal.json b/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator_diagonal.json new file mode 100644 index 0000000..ae034f3 --- /dev/null +++ b/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator_diagonal.json @@ -0,0 +1,147 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "body": "streamcontrol:block/current_generator_side", + "top": "streamcontrol:block/current_generator_top_diagonal", + "casing": "create:block/andesite_casing", + "particle": "streamcontrol:block/current_generator_side" + }, + "elements": [ + { + "from": [ + 0, + 2, + 0 + ], + "to": [ + 16, + 6, + 16 + ], + "faces": { + "down": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "up": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "north": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "west": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + } + } + }, + { + "from": [ + 0, + 6, + 0 + ], + "to": [ + 16, + 16, + 16 + ], + "faces": { + "down": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "up": { + "texture": "#top", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "north": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "south": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "east": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "west": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + } + } + } + ] +} diff --git a/src/main/resources/assets/streamcontrol/models/block/mooring_post.json b/src/main/resources/assets/streamcontrol/models/block/mooring_post.json new file mode 100644 index 0000000..25c3e28 --- /dev/null +++ b/src/main/resources/assets/streamcontrol/models/block/mooring_post.json @@ -0,0 +1,218 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "down": "streamcontrol:block/mooring_post_bottom", + "up": "streamcontrol:block/mooring_post_top", + "north": "streamcontrol:block/mooring_post_side", + "south": "streamcontrol:block/mooring_post_side", + "east": "streamcontrol:block/mooring_post_side", + "west": "streamcontrol:block/mooring_post_side", + "particle": "streamcontrol:block/mooring_post_side" + }, + "elements": [ + { + "from": [ + 1, + 0, + 1 + ], + "to": [ + 15, + 3, + 15 + ], + "faces": { + "down": { + "texture": "#down", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "up": { + "texture": "#up", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "north": { + "texture": "#north", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "south": { + "texture": "#south", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "east": { + "texture": "#east", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "west": { + "texture": "#west", + "uv": [ + 0, + 0, + 16, + 16 + ] + } + } + }, + { + "from": [ + 3, + 3, + 3 + ], + "to": [ + 13, + 13, + 13 + ], + "faces": { + "down": { + "texture": "#down", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "up": { + "texture": "#up", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "north": { + "texture": "#north", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "south": { + "texture": "#south", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "east": { + "texture": "#east", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "west": { + "texture": "#west", + "uv": [ + 0, + 0, + 16, + 16 + ] + } + } + }, + { + "from": [ + 1, + 13, + 1 + ], + "to": [ + 15, + 16, + 15 + ], + "faces": { + "down": { + "texture": "#down", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "up": { + "texture": "#up", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "north": { + "texture": "#north", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "south": { + "texture": "#south", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "east": { + "texture": "#east", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "west": { + "texture": "#west", + "uv": [ + 0, + 0, + 16, + 16 + ] + } + } + } + ] +} diff --git a/src/main/resources/assets/streamcontrol/models/item/flow_sensor.json b/src/main/resources/assets/streamcontrol/models/item/flow_sensor.json new file mode 100644 index 0000000..96dc116 --- /dev/null +++ b/src/main/resources/assets/streamcontrol/models/item/flow_sensor.json @@ -0,0 +1,3 @@ +{ + "parent": "streamcontrol:block/flow_sensor" +} diff --git a/src/main/resources/assets/streamcontrol/models/item/mechanical_current_generator.json b/src/main/resources/assets/streamcontrol/models/item/mechanical_current_generator.json new file mode 100644 index 0000000..8526ea4 --- /dev/null +++ b/src/main/resources/assets/streamcontrol/models/item/mechanical_current_generator.json @@ -0,0 +1,216 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "body": "streamcontrol:block/current_generator_side", + "top": "streamcontrol:block/current_generator_top", + "casing": "create:block/andesite_casing", + "particle": "streamcontrol:block/current_generator_side", + "shaft": "create:block/axis" + }, + "elements": [ + { + "from": [ + 5, + 0, + 5 + ], + "to": [ + 11, + 2, + 11 + ], + "faces": { + "down": { + "texture": "#shaft", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "up": { + "texture": "#shaft", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "north": { + "texture": "#shaft", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "south": { + "texture": "#shaft", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "east": { + "texture": "#shaft", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "west": { + "texture": "#shaft", + "uv": [ + 0, + 0, + 16, + 16 + ] + } + } + }, + { + "from": [ + 0, + 2, + 0 + ], + "to": [ + 16, + 6, + 16 + ], + "faces": { + "down": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "up": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "north": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "west": { + "texture": "#casing", + "uv": [ + 0, + 0, + 16, + 16 + ] + } + } + }, + { + "from": [ + 0, + 6, + 0 + ], + "to": [ + 16, + 16, + 16 + ], + "faces": { + "down": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "up": { + "texture": "#top", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "north": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "south": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "east": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + }, + "west": { + "texture": "#body", + "uv": [ + 0, + 0, + 16, + 16 + ] + } + } + } + ] +} diff --git a/src/main/resources/assets/streamcontrol/models/item/mooring_post.json b/src/main/resources/assets/streamcontrol/models/item/mooring_post.json new file mode 100644 index 0000000..b91b93f --- /dev/null +++ b/src/main/resources/assets/streamcontrol/models/item/mooring_post.json @@ -0,0 +1,3 @@ +{ + "parent": "streamcontrol:block/mooring_post" +} diff --git a/src/main/resources/assets/streamcontrol/textures/block/flow_sensor_bottom.png b/src/main/resources/assets/streamcontrol/textures/block/flow_sensor_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..6b9be84b7152ba19490c5553322f3eac3617a2eb GIT binary patch literal 661 zcmV;G0&4w~M=>lA>#?+l<7y=>!)*+%vl7w=7 zhjO(h0a%~k1;A!Gsj-x+HA-Y5-$qsxxICZ9N+HHtY?hN(E0QEZ$=t#XG2EQqW3!CG zd(3rfV~hyEVSB|G!zaW!{f;mU#2C>!<_DUI1{|Z7HhN;^@1U!F%-e zB*rlUFnG^2P1O4x^=^wCcH7xG299;j{_29FS`%ZO#}$TUGV>-Lku+s{@h`?$HCgpoX}~y5C`wE&XJcDzVCVX=*hgwI<-q6$NGSE4xP?rCn`ZH zVelT&dRgb&kimBt>v;I+2>`$S`T=bWF3VYM&X=-%-}BF3fAZkVZ$1_1+7`}OzHd|S vxmSM9YI9DKB-gVq@qIsU;PpEIrG)&u5q>eJ00000NkvXXu0mjf#6CaX literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/streamcontrol/textures/block/flow_sensor_side.png b/src/main/resources/assets/streamcontrol/textures/block/flow_sensor_side.png new file mode 100644 index 0000000000000000000000000000000000000000..de4d89ddebffb18aeb99ed247b794f96379b4625 GIT binary patch literal 645 zcmV;00($+4P)|BT15rXjm1rcLKSpV7wtxH;nt1d#y`!4xG7?(E(-MlJ{F<~ zt&t|JrY&s}Cru{F%w$|la%1&_3->(kckcPlF>c;jNf}{rX_?m1A?4X~yx(|962|}t zDY>z<%;B#+X3t;b&HD546J#7mbb^4Bc0lXskXmIM<>aYVw($x+0G)Qg-24Ld-73m< zs8zNoPEF(bJ|+N$0l@LWK0&KNy|$w(q+}ng?^X$#4eGm9gtPz{CPR$5>kDbnY>=j! z=fC^kFpP=Mab4uS2amAxE5mEw%Ze-%iP%O{jPnAa+=)`}KlEjgo#CR&>n3NJZHpY1S>IKnYpl#F4 zYAD;G-wV0Da#zRVI3E8X!{*v5Qd+oPfns@@^6XhkGiNB2rikMRuUKMpZFMXs08$8{ z351j=$H8$uEX&gVD2lM1JYlzkrIgMEkeRZE7S9xdoKkpx5ouY(QN%DA((SZ~q5)y& zWR#m}Gm&-Frw{_qFX9$_J;r_*VhWQ%zfUMnCMzz)=@y3R5GU{A7JOXKM>!dRlolA! zZZ(NVmBAoM63p>(Byo%s62mmPeDxY%KD;F=pga0x3dD4Aa2L zyR1KZ!u^Mj30jS;mYHefm&yofomwdQ>GcLj2X%5vkq$G~`Ndm&|N8m#exl-OhD$no-e7of{E5xke00000NkvXXu0mjf!(=YV literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/streamcontrol/textures/block/flow_sensor_top.png b/src/main/resources/assets/streamcontrol/textures/block/flow_sensor_top.png new file mode 100644 index 0000000000000000000000000000000000000000..d599501615cd0a538f045790add98a0414e46b75 GIT binary patch literal 703 zcmV;w0zmzVP)Ki=v_!ftm)5qS2TTO*rB~F8&GL{Rg~x_u#>!H&33?s0q<1 zM9?Z42nPtCQW5$=x7+>lPlBB3YqSFTO_=_=V%|c-6UZoX_}pMbmg$D{m6k3Dv4wYtFe!fGBHwSTOcIZb`w=q zDQ|5c6oG9w5sCmsiA1(H*APMlK$RMaWD=Q7nd~$zIyz#wu0y`}IRC@);uqox1JCm! zS0V_4h!Ad+H`h_6jK)G~mfdgVHYo`3eGkuds8#lm^;#9*_p$9JzTXze^&aESz56W9 zmm=|x)34Eu|Xsc*N(q8HUbY0HD86WNE%cf1$|j@lmRKy8uWj zaa|XAa_|hU>k^CW0DPXCVe!*@0EW(9U}?U@lSdEPUS9*CIC2@M)gq?r>{lx&eW!mFHk!-&PjdK$o2$!F9w7n(gi!H)kA>1K zp64Mo4FD06R8=J)Af0Jv0T7GpNKHf24&eJ9*<25f(?V6-ZERW%gp`tWwmZt;P%e*x zf|))0Sk&FR~Wl_i%CVW_;K!!XPi1S l%=PgJo;`WYhqtey^&fx23#QF6vQYp4002ovPDHLkV1nHNN16Zt literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/streamcontrol/textures/block/mooring_post_bottom.png b/src/main/resources/assets/streamcontrol/textures/block/mooring_post_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..a6ae5afbf62317fb4906e96272d62406f526486f GIT binary patch literal 658 zcmV;D0&V??P)08|hdbVYs zH}S)FUvU@R=#kn9@BZ82j0T{e0$X4TiB01GXb&U%-UDzLJpB{^sGT6)7zi=(>!0r_ ztsqL#9!9h(_;@=k-BQi~yngczBZ_C=d<;7dR{Z?p+Z5}Vo~Ry0;LAtpl1h*n4P zG?g{;m|78H;{F;gb{(}7YA38Khn#IH_Wi`*VN+XD&h%qoT{(&Zj8^!VFrom1(F&ys z?yoDhs}copwy6PFRhH5Sr|S|cY5@ZrIpn0atSifQRU*1TDl4oi%eE;|MS+!hg*%`R za~?yaafZ=HYB#SIVnzV2ZhAsWp8<2`$b2Nkj5V5lKePW~KX6i6HjP6r+m5-&z_xKq z$A0n*K2jP1GU?c0^pTurMXvWfa&Lku|(&?Fgx|o@sOz^C#ZgEeYbMCbsuQm&YSX*gw)CpOfuJHQf9%+^Xprqi@YLorn z0XOEVynMesYC*+mPABZs3Huy%LcSfG;2X`?gA?k$0iYZ9xwpK)ZmWxDG@A#<%vL?> zzCi$3)`0ED@fqzPVyD$%jDf)2R)_X!#BQsDmJ)z0FR<<}Un~9u5k)a3x_rI}%Np0F zTpRUl?GCc6T3cz-4kG3oUip}2IZ6sF ztf7gbtc@^N^O&i+j4S^^K|zvb{Y!w&rn-cNY?V5xjd z(tJ|E`o#ozFYJhI=?b0qh-h0r>L0O#xi3d;9}M9NhS;N3#L|0000D{lpIM-m60QX2Y_GhVVxSQu@|MZTUBOG4%2Q`=^iGuTUB(N z0bq)YhN-}a|=(HQG ze%)qyagM6;SYDhf!2V}qx>>Q^gM`2@0dTc5#g%gttUOy|d2xgVK^K zIclMfivtiI^!$~%38ehD8}1-s@V6UVA;(z(SR5(Ijp5a&pBQ6{hDF;Rs%5O+(*i*G zCCaX(>^kJeFxjY(W;sru!G4q?ORi*mBtY~vm}~@qpf!8~<+;?9M?LTXXblhHNXcZQ z!as!Z$xO8@myG!SJ`1}Je*1i|-e*xYk67I{( Ry5|4@002ovPDHLkV1oNoL#zM* literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/streamcontrol/textures/gui/automation_controller.png b/src/main/resources/assets/streamcontrol/textures/gui/automation_controller.png new file mode 100644 index 0000000000000000000000000000000000000000..f2423d517e178660098c0dd812d995efd44bcfec GIT binary patch literal 1336 zcmeAS@N?(olHy`uVBq!ia0y~yV6*|U-*K=3$t5kjr!g?F{P%Qm45^s&_RhhqkaUTL zhw+^cT3@&c#E6`c-I2H6A?lWIcx)waT*K^XPVX1IzT*&B5GeIREv{ohg8AGs1LKnx z>62y}zyG}E&A&S3cHjKa&~r1df}4Ndym!?s9+lspeck7N){5Kjx$&LDy3pjHbaGF8-QU{#$_Fm~{I`4kciThf zDl!;TIOHZMRyedhV3cfPPs#Z+!%qVzae|s(Ck2&oQ-X4wZ?~wbK1*w*hQGkpKCOkAI}xpQOn2A zV8p_ILcm7B`9lNGL1tn(YV#}hyn9p85IehS*Uu*pYCm7z9(UpFw_n4T*i=d-K*`|bXC-<>iKx^3&fmc7nax8L&P^VW8;18*ye zeq~(x`tBh(C{e<7l*5ji&}beY$4*``2gQeYF~gl5o(HS{y?VRu8N-gkX!iF9FJF#5 z$5`Utui_mt4i1%sTH%B*#=G_88jL)cnu<`1SDd^JVt32Y4gmu7t7X zKXvXdoh^4@;V!+hbP0l+XkK Date: Tue, 3 Nov 2026 07:53:38 +0100 Subject: [PATCH 02/14] Verify profiles, Calibrator operations, sensor height limits, mooring and actual Create motor behavior --- .github/workflows/neoforge-1.21.1.yml | 5 + .../streamcontrol/EngineeringChecks.java | 119 ++++++++++++++++++ .../streamcontrol/IntegrationChecks.java | 1 + .../client/ControllerPreview.java | 62 +++++---- .../client/ModelPreviewScreen.java | 35 ++++++ .../compat/create/CreateChecks.java | 33 +++++ 6 files changed, 231 insertions(+), 24 deletions(-) create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringChecks.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/client/ModelPreviewScreen.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateChecks.java diff --git a/.github/workflows/neoforge-1.21.1.yml b/.github/workflows/neoforge-1.21.1.yml index d783e18..48fff85 100644 --- a/.github/workflows/neoforge-1.21.1.yml +++ b/.github/workflows/neoforge-1.21.1.yml @@ -86,6 +86,11 @@ jobs: test -s run-client/screenshots/flow-control-current-generator.png test -s run-client/screenshots/flow-control-stillwater-anchor.png test -s run-client/screenshots/flow-control-redstone-paused.png + test -s run-client/screenshots/flow-control-automation.png + test -s run-client/screenshots/flow-control-flow-sensor.png + test -s run-client/screenshots/flow-control-mooring-post.png + test -s run-client/screenshots/flow-control-block-models.png + test -s run-client/screenshots/flow-control-mechanical-controller.png - name: Upload GUI screenshots if: always() uses: actions/upload-artifact@v4 diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringChecks.java new file mode 100644 index 0000000..b100c77 --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringChecks.java @@ -0,0 +1,119 @@ +package nl.townsandkingdoms.streamcontrol; + +import java.util.*; +import com.mojang.authlib.GameProfile; +import io.netty.buffer.Unpooled; +import net.minecraft.core.*; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.CustomData; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.neoforged.neoforge.common.util.FakePlayerFactory; + +/** Opt-in server scenarios. Runs in the disposable integration world only. */ +public final class EngineeringChecks { + private static void check(boolean value,String reason) { if(!value) throw new AssertionError(reason); } + private static CompoundTag options(FlowProfile a,FlowProfile b,ControllerSettings.Redstone redstone) { + var n=new CompoundTag();n.put("ProfileA",a.save());n.put("ProfileB",b.save());n.putInt("RedstoneMode",redstone.ordinal());return n; + } + private static void toolMode(ItemStack tool,FlowWand.Mode mode) { + var n=FlowWand.settings(tool);n.putInt("CalibratorMode",mode.ordinal());tool.set(DataComponents.CUSTOM_DATA,CustomData.of(n)); + } + public static void run(ServerLevel level,Map results) { + BlockPos p=new BlockPos(256,120,256),q=p.east(10);var data=ControlData.get(level); + level.setBlock(p,StreamControl.GENERATOR.get().defaultBlockState(),3); + level.setBlock(q,StreamControl.GENERATOR.get().defaultBlockState(),3); + var a=(ControllerEntity)level.getBlockEntity(p);var b=(ControllerEntity)level.getBlockEntity(q); + var first=new FlowProfile(3,2,1,FlowHeading.EAST,false,FlowProfile.Action.CURRENT); + var second=new FlowProfile(2,1,.5,FlowHeading.SOUTH,false,FlowProfile.Action.CURRENT); + a.controls().configure(options(first,second,ControllerSettings.Redstone.ANALOG)); + check(data.byKey(p.asLong()).still(),"Analog zero must stop its controlled current"); + level.setBlock(p.west(),Blocks.REDSTONE_BLOCK.defaultBlockState(),3);a.refresh(); + check(data.byKey(p.asLong()).dx()>.99 && data.byKey(p.asLong()).strength()==1,"Analog full signal"); + a.controls().configure(options(first,second,ControllerSettings.Redstone.REVERSE)); + check(data.byKey(p.asLong()).dx()<-.99,"Powered reverse mode"); + level.removeBlock(p.west(),false);a.refresh();check(data.byKey(p.asLong()).dx()>.99,"Unpowered reverse mode"); + a.controls().configure(options(first,second,ControllerSettings.Redstone.SWITCH)); + level.setBlock(p.west(),Blocks.REDSTONE_BLOCK.defaultBlockState(),3);a.refresh(); + check(data.byKey(p.asLong()).dz()>.99 && data.byKey(p.asLong()).radius()==2 && data.byKey(p.asLong()).vertical()==1 + && data.byKey(p.asLong()).strength()==.5,"Switch must use every saved Profile B field"); + var release=new FlowProfile(2,1,.5,FlowHeading.SOUTH,false,FlowProfile.Action.RELEASE); + a.controls().configure(options(first,release,ControllerSettings.Redstone.SWITCH));check(data.byKey(p.asLong())==null,"Profile release must restore underlying water"); + level.removeBlock(p.west(),false);a.controls().configure(options(first,second,ControllerSettings.Redstone.IGNORE)); + var saved=a.saveWithoutMetadata(level.registryAccess());var loaded=new ControllerEntity(p,a.getBlockState());loaded.loadWithComponents(saved,level.registryAccess()); + check(loaded.controls().a().equals(first) && loaded.controls().b().equals(second) && loaded.controls().redstone()==ControllerSettings.Redstone.IGNORE,"Controller profiles save/load"); + var old=new CompoundTag();old.putInt("Radius",7);old.putDouble("Strength",.75);old.putBoolean("ConnectedOnly",true); + loaded.loadWithComponents(old,level.registryAccess());check(loaded.radius()==7 && loaded.strength()==.75 && loaded.connectedOnly(),"0.1.x controller settings migration"); + results.put("profileModesPersistenceAndMigration",true); + check(b.controls().link(p),"Valid controller link rejected");b.refresh(); + check(data.byKey(q.asLong()).radius()==3 && data.byKey(q.asLong()).dx()>.99,"Linked controller did not follow source"); + a.configure(FlowHeading.NORTH_WEST,5,.65,false);b.refresh(); + check(data.byKey(q.asLong()).radius()==5 && data.byKey(q.asLong()).dx()<0 && data.byKey(q.asLong()).dz()<0,"Linked changes did not propagate"); + check(!a.controls().link(q) && !b.controls().link(q),"Link cycles and self-links must be rejected"); + check(!b.controls().link(q.east(300)),"Out-of-range link accepted"); + level.removeBlock(p,false);b.refresh();check(data.byKey(q.asLong())==null,"Missing linked source must pause without chunk loading"); + b.controls().unlink();check(data.byKey(q.asLong())!=null,"Unlink did not restore local profile"); + results.put("controllerLinkPropagationCycleAndMissingSource",true); + var player=FakePlayerFactory.get(level,new GameProfile(UUID.randomUUID(),"FlowChecks"));player.getAbilities().mayBuild=true; + var tool=new ItemStack(StreamControl.WAND.get());player.setItemInHand(net.minecraft.world.InteractionHand.MAIN_HAND,tool); + toolMode(tool,FlowWand.Mode.COPY);check(FlowWand.operate(player,q,tool),"Calibrator copy failed"); + level.setBlock(p,StreamControl.GENERATOR.get().defaultBlockState(),3);a=(ControllerEntity)level.getBlockEntity(p); + toolMode(tool,FlowWand.Mode.PASTE);check(FlowWand.operate(player,p,tool),"Calibrator paste failed"); + check(a.controls().a().equals(b.controls().a()) && a.controls().b().equals(b.controls().b()),"Calibrator did not copy both profiles"); + toolMode(tool,FlowWand.Mode.LINK);check(FlowWand.operate(player,p,tool) && FlowWand.operate(player,q,tool),"Calibrator linking failed"); + check(p.equals(b.controls().source()),"Calibrator stored wrong source"); + var legacyPos=p.north(20);level.setBlock(legacyPos,Blocks.WATER.defaultBlockState(),3); + data.put(level,new FlowRegion(87654,legacyPos,2,1,1,0,1,false,false,player.getUUID(),data.next())); + toolMode(tool,FlowWand.Mode.RESTORE);check(FlowWand.operate(player,legacyPos,tool) && data.byKey(87654)==null,"Calibrator cannot remove legacy wand edit"); + results.put("calibratorCopyPasteLinkAndLegacyCleanup",true); + var sensorPos=p.east(64);level.setBlock(sensorPos,StreamControl.SENSOR.get().defaultBlockState(),3); + var sensor=(FlowSensorEntity)level.getBlockEntity(sensorPos);var water=sensorPos.offset(2,3,0); + level.setBlock(water,Blocks.WATER.defaultBlockState(),3);data.put(level,new FlowRegion(87655,water,1,0,1,0,1,false,true,player.getUUID(),data.next())); + var sensorOptions=sensor.settings();sensorOptions.putInt("Radius",4);sensorOptions.putInt("Vertical",2);sensor.configure(sensorOptions); + check(sensor.output()==0,"Sensor detected flow above its vertical range"); + sensorOptions.putInt("Vertical",3);sensor.configure(sensorOptions);check(sensor.output()==8,"Sensor did not detect elevated flow"); + check(level.getBlockState(sensorPos).hasAnalogOutputSignal() && level.getBlockState(sensorPos).getAnalogOutputSignal(level,sensorPos)==8,"Comparator output unavailable"); + sensorOptions.putInt("Mode",1);sensor.configure(sensorOptions);check(sensor.output()==3,"East must be direction output 3"); + sensorOptions.putInt("Radius",1);sensor.configure(sensorOptions);check(sensor.output()==0,"Sensor ignored horizontal range"); + sensorOptions.putInt("Radius",4);sensorOptions.putInt("Mode",2);sensorOptions.putBoolean("EmptyOnly",true); + var sensedBoat=new Boat(level,sensorPos.getX()+.5,sensorPos.getY()+3.5,sensorPos.getZ()+.5);level.addFreshEntity(sensedBoat); + sensor.configure(sensorOptions);check(sensor.output()==1,"Boat count ignored vertical range"); + sensorOptions.putInt("Vertical",2);sensor.configure(sensorOptions);check(sensor.output()==0,"Boat below/above range was counted"); + sensorOptions.putInt("Vertical",3);sensor.configure(sensorOptions);player.startRiding(sensedBoat,true);sensor.sample();check(sensor.output()==0,"Empty-only sensor counted occupied boat"); + sensorOptions.putBoolean("EmptyOnly",false);sensor.configure(sensorOptions);check(sensor.output()==1,"All-boats sensor omitted occupied boat"); + player.stopRiding();sensedBoat.discard(); + var reloadedSensor=new FlowSensorEntity(sensorPos,sensor.getBlockState());reloadedSensor.loadWithComponents(sensor.saveWithoutMetadata(level.registryAccess()),level.registryAccess()); + check(reloadedSensor.vertical()==3 && reloadedSensor.radius()==4 && reloadedSensor.mode()==FlowSensorEntity.Mode.BOATS,"Sensor range/mode persistence"); + results.put("sensorVerticalHorizontalDirectionBoatAndComparator",true); + var mooringPos=p.south(64); + while(Math.floorMod(level.getGameTime()+mooringPos.asLong(),10)!=0) mooringPos=mooringPos.above(); + level.setBlock(mooringPos,StreamControl.MOORING.get().defaultBlockState(),3);var mooring=(MooringEntity)level.getBlockEntity(mooringPos); + var boat=new Boat(level,mooringPos.getX()+1.5,mooringPos.getY()+1,mooringPos.getZ()+.5);level.addFreshEntity(boat); + mooring.tick();check(boat.getUUID().equals(mooring.boatId()),"Mooring did not secure empty boat"); + double x=boat.getX(),z=boat.getZ();boat.setPos(x+.2,boat.getY(),z+.2);boat.setDeltaMovement(.2,.03,.2);mooring.tick(); + check(boat.getX()==x && boat.getZ()==z && boat.getDeltaMovement().x==0 && boat.getDeltaMovement().z==0 && boat.getDeltaMovement().y==.03,"Mooring did not hold horizontal position and preserve bobbing"); + player.startRiding(boat,true);mooring.tick();check(mooring.boatId()==null,"Boarding did not immediately release boat");player.stopRiding(); + for(int i=0;i<42;i++) mooring.tick();check(mooring.boatId()!=null,"Mooring did not resume after release cooldown"); + level.setBlock(mooringPos,mooring.getBlockState().setValue(UtilityBlock.POWERED,true),2);mooring.tick();check(mooring.boatId()==null,"Redstone did not release boat"); + level.removeBlock(mooringPos,false);boat.discard();results.put("mooringHoldBoardingRedstoneAndCooldown",true); + var buf=new RegistryFriendlyByteBuf(Unpooled.buffer(),level.registryAccess()); + try { + var configure=new ControlNetwork.Configure(p.asLong(),3,1,false,FlowHeading.EAST.id(),options(first,second,ControllerSettings.Redstone.SWITCH)); + ControlNetwork.Configure.CODEC.encode(buf,configure);check(configure.equals(ControlNetwork.Configure.CODEC.decode(buf)),"Profile packet round trip");buf.clear(); + var utility=new ControlNetwork.UtilityConfigure(sensorPos.asLong(),sensorOptions);ControlNetwork.UtilityConfigure.CODEC.encode(buf,utility); + check(utility.equals(ControlNetwork.UtilityConfigure.CODEC.decode(buf)),"Sensor packet round trip"); + } finally { buf.release(); } + results.put("engineeringPacketRoundTrips",true); + boolean create=net.neoforged.fml.ModList.get().isLoaded("create"); + boolean registered=net.minecraft.core.registries.BuiltInRegistries.BLOCK.containsKey(net.minecraft.resources.ResourceLocation.fromNamespaceAndPath(StreamControl.ID,"mechanical_current_generator")); + check(create==registered,"Create block registration is not optional"); + if(create) nl.townsandkingdoms.streamcontrol.compat.create.CreateChecks.run(level,results); + else results.put("standaloneWithoutCreate",true); + level.removeBlock(p,false);level.removeBlock(q,false);level.removeBlock(sensorPos,false);data.remove(level,87655); + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/IntegrationChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/IntegrationChecks.java index 599c277..bf1f5a9 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/IntegrationChecks.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/IntegrationChecks.java @@ -137,6 +137,7 @@ private static void run(ServerStartedEvent event) { results.put("controllerRedstoneAndRemoval",true); check(server.getCommands().getDispatcher().execute("streamcontrol status",server.createCommandSourceStack())==1,"Status command"); HeadingRegressionChecks.run(level); results.put("eightHeadingPhysicsPersistenceAndPackets",true); + EngineeringChecks.run(level,results); results.put("passed",true); } catch (Throwable t) { results.put("passed",false);results.put("error",t.toString()); t.printStackTrace(); } finally { data.remove(level,101);data.remove(level,102);data.remove(level,103); } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerPreview.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerPreview.java index f3b0ff7..84751a1 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerPreview.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerPreview.java @@ -3,41 +3,55 @@ import java.io.File; import net.minecraft.client.Minecraft; import net.minecraft.client.Screenshot; +import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.screens.TitleScreen; -import nl.townsandkingdoms.streamcontrol.FlowHeading; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import nl.townsandkingdoms.streamcontrol.*; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.client.event.ClientTickEvent; -import nl.townsandkingdoms.streamcontrol.ControlNetwork; -/** Opt-in CI capture of the actual client screen. Inactive in normal games. */ -@EventBusSubscriber(modid = "streamcontrol", value = Dist.CLIENT) +/** Opt-in CI capture and interaction check. Inactive in normal games. */ +@EventBusSubscriber(modid="streamcontrol",value=Dist.CLIENT) public final class ControllerPreview { - private static int phase, ticks; + private static int phase,ticks; private static boolean captured; - private static final String[] NAMES = {"current-generator", "stillwater-anchor", "redstone-paused"}; + private static final String[] NAMES={"current-generator","stillwater-anchor","redstone-paused","automation","flow-sensor","mooring-post","block-models","mechanical-controller"}; @SubscribeEvent public static void tick(ClientTickEvent.Post event) { - if (!Boolean.getBoolean("streamcontrol.uiPreview")) return; - var mc = Minecraft.getInstance(); - if (phase == 0) { - if (!(mc.screen instanceof TitleScreen) || mc.getOverlay() != null) return; - open(); phase = 1; ticks = 0; + if(!Boolean.getBoolean("streamcontrol.uiPreview")) return; + var mc=Minecraft.getInstance(); + if(phase==0) { + if(!(mc.screen instanceof TitleScreen) || mc.getOverlay()!=null) return; + open();phase=1;ticks=0; } - if (++ticks < 25) return; - String name = "flow-control-" + NAMES[phase - 1] + ".png"; - if (!captured) { - Screenshot.grab(mc.gameDirectory, name, mc.getMainRenderTarget(), message -> {}); - captured = true; - return; - } - if (!new File(mc.gameDirectory, "screenshots/" + name).isFile()) return; - if (phase == NAMES.length) { mc.stop(); return; } - phase++; ticks = 0; captured = false; open(); + if(++ticks<25) return; + String name="flow-control-"+NAMES[phase-1]+".png"; + if(!captured) { Screenshot.grab(mc.gameDirectory,name,mc.getMainRenderTarget(),message->{});captured=true;return; } + if(!new File(mc.gameDirectory,"screenshots/"+name).isFile()) return; + if(phase==NAMES.length) { mc.stop();return; } + phase++;ticks=0;captured=false;open(); } private static void open() { - boolean still = phase == 2; - ControllerScreen.open(new ControlNetwork.Open(0, still ? 6 : 4, 4, 0.75, 2, 16, - phase != 0 && phase != 1, still, phase == 3, FlowHeading.NORTH_EAST.id())); + var mc=Minecraft.getInstance();String name=NAMES[phase==0?0:phase-1]; + if(name.equals("block-models")) { mc.setScreen(new ModelPreviewScreen());return; } + if(name.equals("flow-sensor") || name.equals("mooring-post")) { + var n=new CompoundTag();n.putString("Kind",name.equals("flow-sensor")?"sensor":"mooring");n.putInt("Radius",4);n.putInt("Vertical",4); + n.putInt("MaxRadius",16);n.putInt("MaxVertical",16);n.putBoolean("Enabled",true);n.putInt("Output",8); + UtilityScreen.open(new ControlNetwork.UtilityOpen(0,n));return; + } + boolean still=name.equals("stillwater-anchor");var n=new CompoundTag();n.putInt("MaxVertical",16); + n.putBoolean("Kinetic",name.equals("mechanical-controller"));n.putFloat("RPM",128); + n.put("ProfileA",new FlowProfile(4,4,.75,FlowHeading.NORTH_EAST,false,still?FlowProfile.Action.CALM:FlowProfile.Action.CURRENT).save()); + n.put("ProfileB",new FlowProfile(6,3,.5,FlowHeading.SOUTH_WEST,true,still?FlowProfile.Action.RELEASE:FlowProfile.Action.REVERSE).save()); + n.putInt("RedstoneMode",name.equals("automation")?4:0); + ControllerScreen.open(new ControlNetwork.Open(0,4,4,.75,2,16,false,still,name.equals("redstone-paused"),FlowHeading.NORTH_EAST.id(),n)); + if(name.equals("automation")) { + var button=mc.screen.children().stream().filter(c->c instanceof Button b && b.getMessage().equals(Component.translatable("engineering.streamcontrol.automation_tab"))) + .map(c->(Button)c).findFirst().orElseThrow();button.onPress(); + var profile=mc.screen.children().stream().filter(c->c instanceof Button b && b.getMessage().equals(Component.translatable("engineering.streamcontrol.profile_b"))) + .map(c->(Button)c).findFirst().orElseThrow();profile.onPress(); + } } } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ModelPreviewScreen.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ModelPreviewScreen.java new file mode 100644 index 0000000..716011b --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ModelPreviewScreen.java @@ -0,0 +1,35 @@ +package nl.townsandkingdoms.streamcontrol.client; + +import java.util.*; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import nl.townsandkingdoms.streamcontrol.StreamControl; + +/** Opt-in verification gallery of Minecraft's real baked item models. */ +final class ModelPreviewScreen extends Screen { + private final List items=new ArrayList<>(); + ModelPreviewScreen() { + super(Component.literal("Flow Control - Block Models")); + items.add(new ItemStack(StreamControl.GENERATOR.get()));items.add(new ItemStack(StreamControl.ANCHOR.get())); + items.add(new ItemStack(StreamControl.SENSOR.get()));items.add(new ItemStack(StreamControl.MOORING.get())); + StreamControl.OPTIONAL_ITEMS.forEach(item->items.add(new ItemStack(item.get()))); + } + @Override public void renderBackground(GuiGraphics g,int x,int y,float t) {} + @Override public void render(GuiGraphics g,int mx,int my,float tick) { + int left=(width-316)/2,top=(height-238)/2; + g.fill(0,0,width,height,0xFF151C2E);g.blit(EngineeringWidgets.texture("automation_controller"),left,top,0f,0f,316,238,316,238); + g.fill(left+16,top+49,left+300,top+219,0xFF446077); + EngineeringWidgets.text(g,title,left+158,top+12,EngineeringWidgets.TEXT); + EngineeringWidgets.text(g,Component.literal("Actual Minecraft item renders"),left+158,top+32,EngineeringWidgets.MUTED); + for(int i=0;i results) { + var pos=new BlockPos(400,120,400);var motorPos=pos.below(); + level.setBlock(motorPos,AllBlocks.CREATIVE_MOTOR.getDefaultState().setValue(BlockStateProperties.AXIS,Direction.Axis.Y),3); + var motor=(CreativeMotorBlockEntity)level.getBlockEntity(motorPos);motor.initialize(); + level.setBlock(pos,CreateIntegration.BLOCK.get().defaultBlockState(),3);var be=(MechanicalCurrentEntity)level.getBlockEntity(pos);be.initialize(); + be.configure(FlowHeading.EAST,4,1,false); + for(var direction:Direction.values()) check(CreateIntegration.BLOCK.get().hasShaftTowards(level,pos,be.getBlockState(),direction)==(direction==Direction.DOWN),"Unexpected kinetic connection: "+direction); + motor.generatedSpeed.setValue(128);motor.updateGeneratedRotation();for(int i=0;i<10;i++) { motor.tick();be.tick(); } + check(Math.abs(be.getSpeed())==128 && be.hasNetwork(),"Mechanical controller did not join the motor network: "+be.getSpeed());be.refresh(); + var region=ControlData.get(level).byKey(pos.asLong());check(region!=null && region.strength()==1,"128 RPM did not produce configured strength"); + double originalX=region.dx();motor.generatedSpeed.setValue(-128);motor.updateGeneratedRotation();for(int i=0;i<10;i++) { motor.tick();be.tick(); }be.refresh(); + region=ControlData.get(level).byKey(pos.asLong());check(region!=null && region.dx()==-originalX,"Motor reversal did not reverse flow"); + check(be.calculateStressApplied()==ControlConfig.KINETIC_STRESS.get().floatValue(),"Kinetic stress consumer value"); + be.updateFromNetwork(0,512,2);be.refresh();check(ControlData.get(level).byKey(pos.asLong())==null,"Overstressed drive left an active flow override"); + motor.generatedSpeed.setValue(0);motor.updateGeneratedRotation();for(int i=0;i<10;i++) { motor.tick();be.tick(); }be.refresh(); + check(ControlData.get(level).byKey(pos.asLong())==null,"Stopped motor left an active override"); + level.removeBlock(pos,false);level.removeBlock(motorPos,false);results.put("createRealNetworkRpmReverseStressAndStop",true); + } +} From 155421a1b68f27b55f3531e6587a6380d43b4ad2 Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 07:57:18 +0100 Subject: [PATCH 03/14] Preserve low-RPM current strength and test occupied boats with a real passenger fixture --- .../streamcontrol/ControllerSettings.java | 8 ++++++-- .../streamcontrol/EngineeringChecks.java | 13 +++++++++---- .../townsandkingdoms/streamcontrol/FlowRegion.java | 2 +- .../streamcontrol/compat/create/CreateChecks.java | 6 +++++- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerSettings.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerSettings.java index 1acdb5d..0e94edb 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerSettings.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerSettings.java @@ -42,6 +42,7 @@ public void setA(FlowProfile profile) { dirty = true; changed(); refresh(); } public CompoundTag save() { + a=a().withHeading(host.heading()); var n = new CompoundTag(); n.put("ProfileA",a().save()); n.put("ProfileB",b().save()); n.putInt("RedstoneMode",redstone.ordinal()); if (source != null) n.putLong("LinkedSource",source.asLong()); // Older world data keys remain readable for migration and diagnostics. @@ -65,7 +66,10 @@ public void configure(CompoundTag n) { if (!n.contains("LinkedSource")) source = null; setA(a); } - public CompoundTag clipboard() { var n = save(); n.remove("LinkedSource"); return n; } + public CompoundTag clipboard() { + ControllerSettings effective=host.blockEntity().getLevel() instanceof ServerLevel level ? resolved(level) : this; + var n=(effective==null?this:effective).save();n.remove("LinkedSource");return n; + } public void paste(CompoundTag n) { source = null; configure(n); } public void unlink() { source = null; dirty = true; changed(); refresh(); } public boolean link(BlockPos pos) { @@ -125,7 +129,7 @@ public void refresh() { speed *= Math.abs(rpm)/ControlConfig.RPM_FULL_STRENGTH.get(); if (rpm < 0) reverse = !reverse; } - speed = ControlConfig.strength(speed); + speed = Double.isFinite(speed) ? Math.clamp(speed,0,ControlConfig.MAX_SPEED.get()) : 0; if (reverse) heading = heading.rotate(net.minecraft.world.level.block.Rotation.CLOCKWISE_180); var old = data.byKey(key); long[] mask = new long[0]; if (p.connectedOnly()) { diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringChecks.java index b100c77..2512b2a 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringChecks.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/EngineeringChecks.java @@ -83,10 +83,11 @@ public static void run(ServerLevel level,Map results) { sensorOptions.putInt("Radius",4);sensorOptions.putInt("Mode",2);sensorOptions.putBoolean("EmptyOnly",true); var sensedBoat=new Boat(level,sensorPos.getX()+.5,sensorPos.getY()+3.5,sensorPos.getZ()+.5);level.addFreshEntity(sensedBoat); sensor.configure(sensorOptions);check(sensor.output()==1,"Boat count ignored vertical range"); + var rider=new net.minecraft.world.entity.animal.Pig(net.minecraft.world.entity.EntityType.PIG,level);level.addFreshEntity(rider); sensorOptions.putInt("Vertical",2);sensor.configure(sensorOptions);check(sensor.output()==0,"Boat below/above range was counted"); - sensorOptions.putInt("Vertical",3);sensor.configure(sensorOptions);player.startRiding(sensedBoat,true);sensor.sample();check(sensor.output()==0,"Empty-only sensor counted occupied boat"); + sensorOptions.putInt("Vertical",3);sensor.configure(sensorOptions);check(rider.startRiding(sensedBoat,true),"Sensor passenger fixture failed to board");sensor.sample();check(sensor.output()==0,"Empty-only sensor counted occupied boat"); sensorOptions.putBoolean("EmptyOnly",false);sensor.configure(sensorOptions);check(sensor.output()==1,"All-boats sensor omitted occupied boat"); - player.stopRiding();sensedBoat.discard(); + rider.stopRiding();sensedBoat.discard(); var reloadedSensor=new FlowSensorEntity(sensorPos,sensor.getBlockState());reloadedSensor.loadWithComponents(sensor.saveWithoutMetadata(level.registryAccess()),level.registryAccess()); check(reloadedSensor.vertical()==3 && reloadedSensor.radius()==4 && reloadedSensor.mode()==FlowSensorEntity.Mode.BOATS,"Sensor range/mode persistence"); results.put("sensorVerticalHorizontalDirectionBoatAndComparator",true); @@ -97,10 +98,10 @@ public static void run(ServerLevel level,Map results) { mooring.tick();check(boat.getUUID().equals(mooring.boatId()),"Mooring did not secure empty boat"); double x=boat.getX(),z=boat.getZ();boat.setPos(x+.2,boat.getY(),z+.2);boat.setDeltaMovement(.2,.03,.2);mooring.tick(); check(boat.getX()==x && boat.getZ()==z && boat.getDeltaMovement().x==0 && boat.getDeltaMovement().z==0 && boat.getDeltaMovement().y==.03,"Mooring did not hold horizontal position and preserve bobbing"); - player.startRiding(boat,true);mooring.tick();check(mooring.boatId()==null,"Boarding did not immediately release boat");player.stopRiding(); + check(rider.startRiding(boat,true),"Mooring passenger fixture failed to board");mooring.tick();check(mooring.boatId()==null,"Boarding did not immediately release boat");rider.stopRiding(); for(int i=0;i<42;i++) mooring.tick();check(mooring.boatId()!=null,"Mooring did not resume after release cooldown"); level.setBlock(mooringPos,mooring.getBlockState().setValue(UtilityBlock.POWERED,true),2);mooring.tick();check(mooring.boatId()==null,"Redstone did not release boat"); - level.removeBlock(mooringPos,false);boat.discard();results.put("mooringHoldBoardingRedstoneAndCooldown",true); + level.removeBlock(mooringPos,false);boat.discard();rider.discard();results.put("mooringHoldBoardingRedstoneAndCooldown",true); var buf=new RegistryFriendlyByteBuf(Unpooled.buffer(),level.registryAccess()); try { var configure=new ControlNetwork.Configure(p.asLong(),3,1,false,FlowHeading.EAST.id(),options(first,second,ControllerSettings.Redstone.SWITCH)); @@ -112,6 +113,10 @@ public static void run(ServerLevel level,Map results) { boolean create=net.neoforged.fml.ModList.get().isLoaded("create"); boolean registered=net.minecraft.core.registries.BuiltInRegistries.BLOCK.containsKey(net.minecraft.resources.ResourceLocation.fromNamespaceAndPath(StreamControl.ID,"mechanical_current_generator")); check(create==registered,"Create block registration is not optional"); + boolean recipe=level.getRecipeManager().byKey(net.minecraft.resources.ResourceLocation.fromNamespaceAndPath(StreamControl.ID,"mechanical_current_generator")).isPresent(); + check(create==recipe,"Mechanical recipe condition does not match optional Create presence"); + check(level.getRecipeManager().byKey(net.minecraft.resources.ResourceLocation.fromNamespaceAndPath(StreamControl.ID,"flow_sensor")).isPresent(),"Flow sensor recipe missing"); + check(level.getRecipeManager().byKey(net.minecraft.resources.ResourceLocation.fromNamespaceAndPath(StreamControl.ID,"mooring_post")).isPresent(),"Mooring recipe missing"); if(create) nl.townsandkingdoms.streamcontrol.compat.create.CreateChecks.run(level,results); else results.put("standaloneWithoutCreate",true); level.removeBlock(p,false);level.removeBlock(q,false);level.removeBlock(sensorPos,false);data.remove(level,87655); diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/FlowRegion.java b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowRegion.java index b07dcae..38af0a4 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/FlowRegion.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowRegion.java @@ -57,7 +57,7 @@ public static FlowRegion load(CompoundTag n) { double speed = n.getDouble("Strength"); return new FlowRegion(n.getLong("Key"), BlockPos.of(n.getLong("Pos")), Math.clamp(n.getInt("Radius"), 1, 32), Math.clamp(n.getInt("Vertical"), 0, 16), dx / length, dz / length, - Double.isFinite(speed) ? Math.clamp(speed, 0.05, 2) : 1, n.getBoolean("Still"), n.getBoolean("Controller"), + Double.isFinite(speed) ? Math.clamp(speed, 0, 2) : 1, n.getBoolean("Still"), n.getBoolean("Controller"), n.hasUUID("Owner") ? n.getUUID("Owner") : new UUID(0, 0), n.getLong("Sequence"), n.getBoolean("ConnectedOnly"), n.getLongArray("WaterMask")); } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateChecks.java index 9f460c9..6ca8531 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateChecks.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateChecks.java @@ -22,7 +22,11 @@ public static void run(ServerLevel level,Map results) { motor.generatedSpeed.setValue(128);motor.updateGeneratedRotation();for(int i=0;i<10;i++) { motor.tick();be.tick(); } check(Math.abs(be.getSpeed())==128 && be.hasNetwork(),"Mechanical controller did not join the motor network: "+be.getSpeed());be.refresh(); var region=ControlData.get(level).byKey(pos.asLong());check(region!=null && region.strength()==1,"128 RPM did not produce configured strength"); - double originalX=region.dx();motor.generatedSpeed.setValue(-128);motor.updateGeneratedRotation();for(int i=0;i<10;i++) { motor.tick();be.tick(); }be.refresh(); + double originalX=region.dx(); + motor.generatedSpeed.setValue(1);motor.updateGeneratedRotation();for(int i=0;i<10;i++) { motor.tick();be.tick(); }be.refresh(); + var slow=ControlData.get(level).byKey(pos.asLong());check(slow!=null && Math.abs(slow.strength()-1.0/128)<1e-8,"Low RPM was clamped to manual minimum strength"); + var loaded=FlowRegion.load(slow.save());check(loaded.strength()==slow.strength(),"Sub-5-percent flow did not survive sync/persistence"); + motor.generatedSpeed.setValue(-128);motor.updateGeneratedRotation();for(int i=0;i<10;i++) { motor.tick();be.tick(); }be.refresh(); region=ControlData.get(level).byKey(pos.asLong());check(region!=null && region.dx()==-originalX,"Motor reversal did not reverse flow"); check(be.calculateStressApplied()==ControlConfig.KINETIC_STRESS.get().floatValue(),"Kinetic stress consumer value"); be.updateFromNetwork(0,512,2);be.refresh();check(ControlData.get(level).byKey(pos.asLong())==null,"Overstressed drive left an active flow override"); From 69056a64d69ba46f6c22cdfc9421b5f978ffae7e Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 08:00:55 +0100 Subject: [PATCH 04/14] Synchronize mooring/sensor status and correct the actual Create motor fixture orientation --- .../streamcontrol/ControlConfig.java | 4 ++-- .../streamcontrol/FlowSensorEntity.java | 1 + .../streamcontrol/MooringEntity.java | 16 +++++++++++----- .../streamcontrol/client/ControllerScreen.java | 4 ++-- .../streamcontrol/client/EngineeringClient.java | 2 +- .../streamcontrol/client/UtilityScreen.java | 3 +++ .../compat/create/CreateChecks.java | 2 +- 7 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ControlConfig.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ControlConfig.java index 6dd847f..fe32669 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ControlConfig.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ControlConfig.java @@ -8,9 +8,9 @@ public final class ControlConfig { static { var b = new ModConfigSpec.Builder(); ENABLED = b.comment("Master switch. Overrides remain saved when disabled.").define("enabled", true); - WAND_ENABLED = b.define("wandEnabled", true); + WAND_ENABLED = b.comment("Enable the Flow Calibrator; legacy config key retained.").define("wandEnabled", true); OP_ONLY = b.define("wandRequiresOperator", false); - PARTICLES = b.define("showWandFeedbackParticles", true); + PARTICLES = b.comment("Show Calibrator range outlines; legacy config key retained.").define("showWandFeedbackParticles", true); MAX_RADIUS = b.defineInRange("maxRadius", 16, 1, 32); DEFAULT_RADIUS = b.defineInRange("defaultRadius", 4, 1, 32); VERTICAL = b.comment("Blocks above and below the selected water or controller that can be affected.").defineInRange("verticalReach", 4, 0, 16); diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/FlowSensorEntity.java b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowSensorEntity.java index 29854cb..fa4afb7 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/FlowSensorEntity.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/FlowSensorEntity.java @@ -37,6 +37,7 @@ public enum Mode { SPEED, DIRECTION, BOATS; radius=Math.clamp(n.getInt("Radius"),1,ControlConfig.SENSOR_MAX_RADIUS.get()); vertical=Math.clamp(n.getInt("Vertical"),0,ControlConfig.SENSOR_MAX_VERTICAL.get()); mode=Mode.from(n.getInt("Mode"));emptyOnly=n.getBoolean("EmptyOnly");setChanged();sample(); + if(level instanceof ServerLevel server) server.sendBlockUpdated(worldPosition,getBlockState(),getBlockState(),2); } @Override protected void saveAdditional(CompoundTag n,HolderLookup.Provider r) { super.saveAdditional(n,r);n.putInt("Radius",radius);n.putInt("Vertical",vertical);n.putInt("Mode",mode.ordinal());n.putBoolean("EmptyOnly",emptyOnly);n.putInt("Output",output); } @Override protected void loadAdditional(CompoundTag n,HolderLookup.Provider r) { super.loadAdditional(n,r);radius=n.contains("Radius")?n.getInt("Radius"):4;vertical=n.contains("Vertical")?n.getInt("Vertical"):4;mode=Mode.from(n.getInt("Mode"));emptyOnly=n.getBoolean("EmptyOnly");output=Math.clamp(n.getInt("Output"),0,15); } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/MooringEntity.java b/src/main/java/nl/townsandkingdoms/streamcontrol/MooringEntity.java index 80193bc..383f3f6 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/MooringEntity.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/MooringEntity.java @@ -29,7 +29,7 @@ public final class MooringEntity extends BlockEntity implements UtilityAccess { } @Override public void configure(CompoundTag n) { radius=Math.clamp(n.getInt("Radius"),1,ControlConfig.MOORING_MAX_RADIUS.get());vertical=Math.clamp(n.getInt("Vertical"),0,ControlConfig.MOORING_MAX_VERTICAL.get()); - enabled=n.getBoolean("Enabled");release();setChanged(); + enabled=n.getBoolean("Enabled");release();changed(); } @Override protected void saveAdditional(CompoundTag n,HolderLookup.Provider r) { super.saveAdditional(n,r);n.putInt("Radius",radius);n.putInt("Vertical",vertical);n.putBoolean("Enabled",enabled); @@ -39,11 +39,17 @@ public final class MooringEntity extends BlockEntity implements UtilityAccess { super.loadAdditional(n,r);radius=n.contains("Radius")?n.getInt("Radius"):4;vertical=n.contains("Vertical")?n.getInt("Vertical"):2;enabled=!n.contains("Enabled")||n.getBoolean("Enabled"); boatId=n.hasUUID("Boat")?n.getUUID("Boat"):null;moorX=n.getDouble("MoorX");moorZ=n.getDouble("MoorZ"); } - public void release() { + private void changed() { + setChanged();if(level instanceof ServerLevel server && !isRemoved()) server.sendBlockUpdated(worldPosition,getBlockState(),getBlockState(),2); + } + @Override public net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket getUpdatePacket() { return net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket.create(this); } + @Override public CompoundTag getUpdateTag(HolderLookup.Provider r) { return saveWithoutMetadata(r); } + public void release() { release(true); } + private void release(boolean notify) { if(level instanceof ServerLevel server && boatId!=null) CLAIMS.computeIfAbsent(server,s->new HashMap<>()).remove(boatId,worldPosition); - if(boatId!=null) { boatId=null;setChanged(); } cooldown=40; + if(boatId!=null) { boatId=null;if(notify) changed(); } cooldown=40; } - @Override public void setRemoved() { release();super.setRemoved(); } + @Override public void setRemoved() { release(false);super.setRemoved(); } private boolean inRange(Boat boat) { double dx=boat.getX()-worldPosition.getX()-.5,dz=boat.getZ()-worldPosition.getZ()-.5; return dx*dx+dz*dz<=radius()*radius() && boat.getY()>=worldPosition.getY()-vertical() && boat.getY()boat.isAlive() && !boat.isVehicle() && inRange(boat)); candidates.sort(Comparator.comparingDouble(b->b.distanceToSqr(worldPosition.getX()+.5,worldPosition.getY()+.5,worldPosition.getZ()+.5))); - for(Boat boat:candidates) if(claim(server,boat)) { boatId=boat.getUUID();moorX=boat.getX();moorZ=boat.getZ();setChanged();break; } + for(Boat boat:candidates) if(claim(server,boat)) { boatId=boat.getUUID();moorX=boat.getX();moorZ=boat.getZ();changed();break; } } } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerScreen.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerScreen.java index c9b3da8..3fef065 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerScreen.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ControllerScreen.java @@ -80,8 +80,8 @@ private EngineeringWidgets.ActionButton actionButton(int x,int y,int w,int h,Com @Override protected void init() { left = (width - PANEL_W) / 2; top = (height - PANEL_H) / 2; - actionButton(16,29,138,16,engineering("settings_tab",editProfile==0?"A":"B"),b->{automation=false;rebuild();},()->!automation); - actionButton(162,29,138,16,engineering("automation_tab"),b->{automation=true;rebuild();},()->automation); + actionButton(16,29,138,14,engineering("settings_tab",editProfile==0?"A":"B"),b->{automation=false;rebuild();},()->!automation); + actionButton(162,29,138,14,engineering("automation_tab"),b->{automation=true;rebuild();},()->automation); if(automation) { actionButton(26,56,264,22,engineering("redstone_"+settings.getInt("RedstoneMode")),b->{ int next=(settings.getInt("RedstoneMode")+1)%ControllerSettings.Redstone.values().length; diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/EngineeringClient.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/EngineeringClient.java index 15c9d7d..62d2f61 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/client/EngineeringClient.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/EngineeringClient.java @@ -62,7 +62,7 @@ private static void update() { if(region!=null) { radius=region.radius();vertical=region.vertical();center=region.center(); } } if(radius>0) lines.add(tr("readout_range",radius,vertical)); - readout=new Readout(center,radius,vertical,lines,radius>0 && !FlowWand.settings(stack).getBoolean("HideBounds")); + readout=new Readout(center,radius,vertical,lines,radius>0 && ControlConfig.PARTICLES.get() && !FlowWand.settings(stack).getBoolean("HideBounds")); } private static void layers(RegisterGuiLayersEvent e) { e.registerAboveAll(ResourceLocation.fromNamespaceAndPath(StreamControl.ID,"calibrator"),(g,delta)->hud(g)); diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/UtilityScreen.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/UtilityScreen.java index cbcc07f..e0ce71a 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/client/UtilityScreen.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/UtilityScreen.java @@ -57,6 +57,9 @@ private void apply() { tr(options.getBoolean("Powered")?"mooring_powered":options.getBoolean("Secured")?"mooring_secured":"mooring_waiting"); if(minecraft!=null && minecraft.level!=null && minecraft.level.getBlockEntity(net.minecraft.core.BlockPos.of(snapshot.pos())) instanceof FlowSensorEntity be) status=tr("sensor_output",be.output()); + if(minecraft!=null && minecraft.level!=null && minecraft.level.getBlockEntity(net.minecraft.core.BlockPos.of(snapshot.pos())) instanceof MooringEntity be) { + var live=be.settings();status=tr(live.getBoolean("Powered")?"mooring_powered":live.getBoolean("Secured")?"mooring_secured":"mooring_waiting"); + } text(g,status,left+158,top+222,TEAL);super.render(g,mx,my,tick); } private void right(GuiGraphics g,Component s,int x,int y) { g.drawString(font,s,x-font.width(s),y,TEAL,false); } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateChecks.java index 6ca8531..0a7f3bf 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateChecks.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateChecks.java @@ -14,7 +14,7 @@ public final class CreateChecks { private static void check(boolean b,String why) { if(!b) throw new AssertionError(why); } public static void run(ServerLevel level,Map results) { var pos=new BlockPos(400,120,400);var motorPos=pos.below(); - level.setBlock(motorPos,AllBlocks.CREATIVE_MOTOR.getDefaultState().setValue(BlockStateProperties.AXIS,Direction.Axis.Y),3); + level.setBlock(motorPos,AllBlocks.CREATIVE_MOTOR.getDefaultState().setValue(BlockStateProperties.FACING,Direction.UP),3); var motor=(CreativeMotorBlockEntity)level.getBlockEntity(motorPos);motor.initialize(); level.setBlock(pos,CreateIntegration.BLOCK.get().defaultBlockState(),3);var be=(MechanicalCurrentEntity)level.getBlockEntity(pos);be.initialize(); be.configure(FlowHeading.EAST,4,1,false); From 4f41f1ce936a031dc1c0a5568d04d1154ca941e1 Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 08:47:44 +0100 Subject: [PATCH 05/14] Document water engineering controls and publish verified 0.2.0 JAR, checksum and validation results [skip ci] --- CHANGELOG.md | 16 ++++ README.md | 53 +++++-------- docs/WATER-ENGINEERING.md | 73 ++++++++++++++++++ docs/validation-0.2.0.json | 60 ++++++++++++++ downloads/SHA256SUMS-0.2.0.txt | 1 + .../flow-control-0.2.0-neoforge-1.21.1.jar | Bin 0 -> 225778 bytes 6 files changed, 170 insertions(+), 33 deletions(-) create mode 100644 docs/WATER-ENGINEERING.md create mode 100644 docs/validation-0.2.0.json create mode 100644 downloads/SHA256SUMS-0.2.0.txt create mode 100644 downloads/flow-control-0.2.0-neoforge-1.21.1.jar diff --git a/CHANGELOG.md b/CHANGELOG.md index 5623832..dfc788e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ ![Flow Control](https://i.imgur.com/JGT2lvz.png) +## 0.2.0 — Water Engineering + +- Repurposed the Flow Wand as the Flow Calibrator: inspect currents, show horizontal/vertical reach, copy and paste settings, and link controllers. +- Preserved the existing tool registry ID, controller settings and legacy wand regions; added a cleanup mode for old edits. +- Added two saved controller profiles with directed, reversed, calm and natural-flow actions. +- Added analog redstone strength, powered reversal, profile switching and an always-active mode alongside the original power-to-pause behavior. +- Added configurable vertical reach to controller profiles. +- Added Flow Sensors with independent horizontal and vertical ranges, comparator output for strength/direction/boats, and empty-boat filtering. +- Added Mooring Posts that secure one empty boat and release it when boarded, powered, disabled or removed. +- Added optional Create support: Mechanical Current Generator, real bottom-shaft input, RPM-based strength, reversal and stress handling. +- Reused the existing block model family and pixel patterns; added steel-blue sensors, wooden mooring posts and an andesite base for the Create variant. +- Added matching Automation, sensor and mooring screens, live utility status, survival recipes and item descriptions. +- Updated networking for the new settings. Client and server must use matching 0.2.0 builds. +- Verified NeoForge 1.21.1 / Java 21 / Streams Reflowing 2.16.2, both with and without Create 6.0.10. Other ports are unchanged. + + ## 0.1.7 - Removed the header corner rivets. diff --git a/README.md b/README.md index 34f399f..9a487b6 100644 --- a/README.md +++ b/README.md @@ -8,47 +8,34 @@ Shape currents and create calm water around docks, canals and builds. An addon for **Streams Reflowing**, available for NeoForge, Forge and Fabric. -## Versions and downloads +## Water Engineering — 0.2.0 -The **0.1.7 preview for NeoForge 1.21.1** updates compatibility to **Streams Reflowing 2.16.2** and gives both controllers a distinct slate-and-copper layout. The Current Generator has a centered eight-way navigation chart; the Stillwater Anchor has a central anchor chart and symmetric range readouts. Header rivets are removed. The preview source and its build checks are on [`gui/controller-layout`](https://github.com/Mikaaah/Flow-Control/tree/gui/controller-layout). +Turn waterways into configurable transport and docking systems. The Flow Calibrator inspects currents, displays reach, copies settings and links controllers. Two saved profiles add analog redstone control, reversal and automatic switching. Flow Sensors detect current strength, direction or boats through configurable horizontal and vertical ranges. Mooring Posts secure empty boats and release them when boarded or powered. -The published **0.1.5** downloads below remain available for all eight versions and require Streams Reflowing **2.15.2**. +With **Create** installed, the **Mechanical Current Generator** accepts a bottom shaft: RPM sets strength, rotation direction reverses flow, and stopped or overstressed drives release their override. The standard controllers, sensors, posts and Calibrator work without Create. -| Minecraft | Loader | Streams Reflowing | Java | Download | -| --- | --- | --- | --- | --- | -| 1.21.1 | NeoForge | 2.15.2 | 21 | [JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/main/downloads/flow-control-0.1.5-neoforge-1.21.1.jar) | -| 1.20.1 | Fabric | 2.15.2 | 17 | [JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/fabric/1.20.1/downloads/flow-control-0.1.5-fabric-1.20.1.jar) | -| 1.21.1 | Fabric | 2.15.2 | 21 | [JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/fabric/1.21.1/downloads/flow-control-0.1.5-fabric-1.21.1.jar) | -| 26.1.2 | Fabric | 2.15.2 | 25 | [JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/fabric/26.1.2/downloads/flow-control-0.1.5-fabric-26.1.2.jar) | -| 1.20.1 | Forge | 2.15.2 | 17 | [JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/forge/1.20.1/downloads/flow-control-0.1.5-forge-1.20.1.jar) | -| 1.21.11 | NeoForge | 2.15.2 | 21 | [JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/neoforge/1.21.11/downloads/flow-control-0.1.5-neoforge-1.21.11.jar) | -| 26.1.2 | NeoForge | 2.15.2 | 25 | [JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/neoforge/26.1.2/downloads/flow-control-0.1.5-neoforge-26.1.2.jar) | -| 26.3 | NeoForge | 2.15.2 | 25 | [JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/neoforge/26.3/downloads/flow-control-0.1.5-neoforge-26.3.jar) | +The existing controller model family is retained, with steel-blue sensor colors, wooden mooring posts and an andesite base for the mechanical variant. Existing Flow Wands become Calibrators; saved controller settings and old edits are preserved. -Install matching JARs on client and server. Fabric also requires Fabric API. -All eight builds and dedicated-server regression suites passed, including eight-way flow, equal diagonal speed, persistence and packet checks; the NeoForge 1.21.1 client was launched and all three controller-screen states were visually checked. +| Minecraft | Loader | Java | Streams Reflowing | Optional Create | Download | +| --- | --- | --- | --- | --- | --- | +| 1.21.1 | NeoForge 21.1.219+ within 21.1 | 21 | 2.16.2 | Tested with 6.0.10 | [0.2.0 JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/feature/water-engineering/downloads/flow-control-0.2.0-neoforge-1.21.1.jar) | -## Make water work for your build - -| Item | What it does | -| --- | --- | -| **Flow Wand** | Direct flow, still water or restore natural flow in a chosen area. | -| **Current Generator** | Maintain a directional current; rotate its top arrow to steer the flow. | -| **Stillwater Anchor** | Calm currents around a dock or mooring. | - -All three items have survival recipes. Right-click either controller to open its settings screen: adjust radius (with diameter and vertical reach), choose connected-water-only behavior, and set flow speed and direction on the Current Generator. Redstone power disables a controller. Break it to restore the underlying current. - -## Install and start +[Controls and behavior](docs/WATER-ENGINEERING.md) · [Feature branch](https://github.com/Mikaaah/Flow-Control/tree/feature/water-engineering) · [Build and regression checks](https://github.com/Mikaaah/Flow-Control/actions/runs/41593515484) -Choose a matching Minecraft and loader build from the table above, then install this addon and **Streams Reflowing 2.15.2** on client and server. Use the Java version listed for that build; Fabric also requires Fabric API. **UltraTerraForged is not required.** +The 0.2.0 feature update currently targets NeoForge 1.21.1. Earlier downloads and other loader branches remain unchanged. Use matching client/server versions. -For a dock, place a Stillwater Anchor under or beside the water within four blocks of the boats. Right-click to adjust its radius; if there are multiple nearby ponds, enable *Connected water only*. Use the Flow Wand for temporary or shaped areas. - -Flow changes velocity rather than moving water blocks or changing river terrain. Calm water removes current-induced drift; it does not prevent steering, collisions or momentum. - -## Guides +## Make water work for your build -[Items and controls](https://github.com/Mikaaah/Flow-Control/wiki/Items-and-Controls) · [Overlapping areas](https://github.com/Mikaaah/Flow-Control/wiki/Overlapping-Areas) · [Configuration](https://github.com/Mikaaah/Flow-Control/wiki/Configuration) · [Troubleshooting](https://github.com/Mikaaah/Flow-Control/wiki/Troubleshooting) +| Tool or block | Purpose | +| --- | --- | +| Flow Calibrator | Inspect currents, preview reach, copy/paste settings and link controllers. | +| Current Generator | Maintain an eight-way current with configurable profiles and redstone behavior. | +| Stillwater Anchor | Calm water around docks and switch between calm and natural water. | +| Flow Sensor | Measure strength, compass direction or boats above, below and around the sensor. | +| Mooring Post | Secure one empty boat; release it when boarded or powered. | +| Mechanical Current Generator | Optional Create shaft-driven variant with RPM and stress support. | + +Right-click blocks to configure them. Sneak-use the Calibrator in the air to switch modes. All tools and blocks have survival recipes; the mechanical recipe is available only with Create. ## Credits and license diff --git a/docs/WATER-ENGINEERING.md b/docs/WATER-ENGINEERING.md new file mode 100644 index 0000000..87985e7 --- /dev/null +++ b/docs/WATER-ENGINEERING.md @@ -0,0 +1,73 @@ +# Flow Control 0.2.0 — Water Engineering + +| Minecraft | Loader | Java | Required | Optional integration tested | +| --- | --- | --- | --- | --- | +| 1.21.1 | NeoForge 21.1.219+ within 21.1 | 21 | Streams Reflowing 2.16.2 | Create 6.0.10 | + +The same Flow Control JAR works with and without Create. The Mechanical Current Generator and its crafting recipe are available only when Create is installed. Other loader/version branches have not received this feature update. + +## Flow Calibrator + +Existing Flow Wands become Calibrators automatically because their registry ID is retained. Calibrators inspect and configure water engineering; freehand current painting is left to Streams Reflowing's own tool. Existing wand-made regions remain in the world. + +| Input or mode | Action | +| --- | --- | +| Hold the Calibrator and aim at water | Read direction, current strength and whether the source is natural, a controller or a legacy edit. | +| Aim at a controller, sensor or mooring post | Read its range; a cylinder outline shows horizontal and vertical reach. | +| Use while aiming at empty air | Toggle range outlines. | +| Sneak-use while aiming at empty air | Cycle Inspect, Copy, Paste, Link and Remove legacy edit. | +| Inspect: use a controller or utility block | Open its settings. | +| Copy, then Paste | Copy both controller profiles or compatible sensor/mooring settings. Paste does not copy links. | +| Link: use source, then target controller | Target follows the source's profiles and redstone mode. Each target reads its own local redstone signal and, if mechanical, its own drive. | +| Link: sneak-use a controller | Unlink it and clear the selected source. | +| Remove legacy edit: use edited water | Remove your old wand region. Operators can also remove other players' old edits. | + +Links are restricted to the same dimension and default to a maximum of 64 blocks. Self-links and loops are rejected. A linked controller pauses if the source is unloaded or missing; linking never keeps chunks loaded. Unlinking restores its own saved profiles. The outline shows the reach cylinder; connected-water filtering can exclude water inside it. + +## Controller profiles + +The Settings tab edits radius, current strength, direction and connected-water filtering for the selected profile. In Automation, select Profile A or B, choose its action and vertical reach, and select the redstone mode. Changes are saved only with Apply changes. + +| Redstone mode | Behavior | +| --- | --- | +| Pause when powered | Original behavior: power releases the controller's override. This is the migration default. | +| Always active | Ignore the redstone signal. | +| Analog strength 0–15 | Scale the selected strength by signal / 15. Signal 0 calms a Current Generator's region. On a Stillwater Anchor, 0 releases the override and positive signals calm the region. | +| Reverse when powered | Reverse the selected current while powered. | +| Switch Profile A / B | No power uses A; positive power uses B. Each profile saves its own settings. | + +Profile actions are directed current, reversed current, calm water or natural flow. Stillwater Anchors offer calm water and natural flow. Natural flow releases this controller's override, allowing underlying controls or natural currents to resume. Eight compass headings keep equal cardinal and diagonal strength. + +## Flow Sensor + +Horizontal radius and vertical reach are independent. Defaults are radius 4 and height ±4; server limits default to 16 for each. The sensor samples a cylinder, skips unloaded chunks and updates periodically rather than scanning every tick. Place a comparator against it to read the result. + +| Measurement | Comparator output | +| --- | --- | +| Current strength | Strongest horizontal current in range. 0 means still; 15 means the configured maximum current strength. At the default maximum of 200%, a 100% current gives output 8. | +| Compass direction | Direction of the strongest sampled current: N=1, NE=2, E=3, SE=4, S=5, SW=6, W=7, NW=8. Still water gives 0. | +| Nearby boats | Boat count, capped at 15. The empty-boats option excludes boats with passengers in this mode. | + +Vertical reach applies to both water sampling and boat detection. Comparator output and range/mode settings persist; live status is synchronized to clients. + +## Mooring Post + +A post automatically secures one empty boat already inside its configured cylinder. It holds horizontal position while preserving vertical bobbing. It does not pull boats from outside its range or keep an occupied boat captive. + +Boarding, redstone power, disabling automatic mooring or breaking the post releases the boat. A short cooldown prevents immediate recapture. Multiple posts cannot hold the same boat. Defaults are radius 4 and vertical reach ±2; both are configurable in the GUI within server limits. + +## Optional Create support + +The Mechanical Current Generator uses the original Current Generator body above an andesite casing base, with a rotating shaft input on its bottom face. Its recipe uses a Current Generator, Andesite Casing and Shaft. + +Connect a real Create shaft or drive below it. The default calibration is 128 RPM for 100% of the configured profile strength; 64 RPM gives half strength and 256 RPM gives double, limited by the server maximum. Negative RPM reverses the current. Low RPM remains proportionally weak rather than jumping to the manual 5% minimum. The default stress impact is 4 SU per RPM. + +A stopped or overstressed drive releases its override. The controller supports the same profiles, connected-water filtering, links and redstone modes as the standard generator. Create is optional; its own dependencies are supplied by Create rather than bundled in Flow Control. + +## Migration and validation + +Existing controller settings are loaded into Profile A. Old wand regions remain editable through the cleanup mode and `/streamcontrol clear` for operators. `/streamcontrol status` remains available. The old wand radius/strength commands are replaced by GUI profile editing. + +Use matching Flow Control 0.2.0 versions on client and server because the settings packet protocol changed. The original `wandEnabled`, `wandRequiresOperator` and `showWandFeedbackParticles` configuration keys are retained for compatibility; they now control the Calibrator and its range outlines. + +Both standalone and Create 6.0.10 builds passed compilation and the dedicated-server suite. Tests cover legacy flow behavior, profiles and migration, linking and loop rejection, Calibrator copy/paste/link/cleanup, sensor vertical and horizontal limits, comparator output, occupied boats, mooring release and cooldown, packet round trips, optional registration/recipes, and a real Create motor network including reversal, low RPM, stress and stopping. Actual Minecraft screenshots cover eight GUI/model states with and without Create. This is not a full TNK pack or interactive client-world playtest. diff --git a/docs/validation-0.2.0.json b/docs/validation-0.2.0.json new file mode 100644 index 0000000..7fd53ac --- /dev/null +++ b/docs/validation-0.2.0.json @@ -0,0 +1,60 @@ +{ + "source_commit": "69056a64d69ba46f6c22cdfc9421b5f978ffae7e", + "workflow_run": "https://github.com/Mikaaah/Flow-Control/actions/runs/41593515484", + "jar_sha256": "6fb829305e9382af6f5a28efaa786e4ac2eee0a481b859f72b50cbb6d45fc1cd", + "checks": { + "standalone": { + "vanillaWaterAndVesselFlow": true, + "manualDirectionRetainsPriorityOverDownhillGuard": true, + "bakedWaterStillnessAndOverlap": true, + "mooredBoatTwentyTicks": true, + "savedDataRoundTrip": true, + "connectedWaterIsolationAndPersistence": true, + "networkCodecRoundTrip": true, + "dimensionIsolation": true, + "masterSwitch": true, + "controllerRedstoneAndRemoval": true, + "eightHeadingPhysicsPersistenceAndPackets": true, + "profileModesPersistenceAndMigration": true, + "controllerLinkPropagationCycleAndMissingSource": true, + "calibratorCopyPasteLinkAndLegacyCleanup": true, + "sensorVerticalHorizontalDirectionBoatAndComparator": true, + "mooringHoldBoardingRedstoneAndCooldown": true, + "engineeringPacketRoundTrips": true, + "standaloneWithoutCreate": true, + "passed": true + }, + "create_6_0_10": { + "vanillaWaterAndVesselFlow": true, + "manualDirectionRetainsPriorityOverDownhillGuard": true, + "bakedWaterStillnessAndOverlap": true, + "mooredBoatTwentyTicks": true, + "savedDataRoundTrip": true, + "connectedWaterIsolationAndPersistence": true, + "networkCodecRoundTrip": true, + "dimensionIsolation": true, + "masterSwitch": true, + "controllerRedstoneAndRemoval": true, + "eightHeadingPhysicsPersistenceAndPackets": true, + "profileModesPersistenceAndMigration": true, + "controllerLinkPropagationCycleAndMissingSource": true, + "calibratorCopyPasteLinkAndLegacyCleanup": true, + "sensorVerticalHorizontalDirectionBoatAndComparator": true, + "mooringHoldBoardingRedstoneAndCooldown": true, + "engineeringPacketRoundTrips": true, + "createRealNetworkRpmReverseStressAndStop": true, + "passed": true + } + }, + "client_captures": [ + "current-generator", + "stillwater-anchor", + "redstone-paused", + "automation", + "flow-sensor", + "mooring-post", + "block-models", + "mechanical-controller" + ], + "full_modpack_playtest": false +} diff --git a/downloads/SHA256SUMS-0.2.0.txt b/downloads/SHA256SUMS-0.2.0.txt new file mode 100644 index 0000000..9c26097 --- /dev/null +++ b/downloads/SHA256SUMS-0.2.0.txt @@ -0,0 +1 @@ +6fb829305e9382af6f5a28efaa786e4ac2eee0a481b859f72b50cbb6d45fc1cd flow-control-0.2.0-neoforge-1.21.1.jar diff --git a/downloads/flow-control-0.2.0-neoforge-1.21.1.jar b/downloads/flow-control-0.2.0-neoforge-1.21.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..1551889322cb7158bd8a62ebd6d5825e54f0a2d4 GIT binary patch literal 225778 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

T|jLKpqYpXK^*HE3|X#7ZKGTd4* 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

  • 49)8!bpJk#yqcb>J2+xg4`xVM{WijM)}eOd@(rWWfOzFAL_bhky`FlwLN9 zsH4#!1?`@P&|qDeM`)%1Ipzo-f+y(_=N9W2GD#Eb*o+ck@Zeciea9;A01M0%rFUW3 zQ)s!}ZstgD88aMJEw~EqL{xJYub*R@EfNSJT@+|~hU1Kq9Bs1ajYVGnJymQKWvB;# zhfB^BPj{#nry$5Fo(st1b*C(dPLBNbV}(RL5Tk#EW8|h%h+5$D3ZVVng#CY8 zxBtv&DnM2K7K|PLgz=QLiX!T;z(W_ujot>wZuF!K_3>AMoUEv3cITbuobeQ+5P_PS_fzUY_q=mwONqDaI#K>M!L<405?Q_Iq%R(^xJ&8y*TG=|_-REYM*HvIi+P=sm6U-E z+BU&3Nkt_?Nj?eqUJ!*4N-=*&f+B*6pE#qBO$H?6O3J1rkOV;b>z^CuU{};(6g6n8 zn#m!|+NvJmlLOy7XM-3-(`mH6dD-b1dwiU6+_1>1b=%I)GpX*QG5I&58`D|XE-gpJ z7sQTKkx4N-8vkyeE>O0lc^CJqh<2gk)yn zD@s8u@=ZPP#1_*o35dargBt35vP9{wG4@=Fge~pFHj!@#HrMa9ywd6XV$W`6WjzM` z>sUIqkpw8B_@G~jG+dSiu~A@1__wbqt^Mb7S57CQpdFB_o!T{-tZJJz3hmEpdd9hWt>BHTv-@ z`|y4Xg5u19<9^0cfkFwFMx&P5=+n(~u3mcrxkj&k1+bHD`S(Cbh!KKdP|Fz@5}fwg z)a9dkaj(V)n7W#ocfB3RTXFubssI3zj*_pw4%}G}#Z^e_jfTmGMGqTy>FeLz9HUs_ zX%jbu25mf#hy{z%$fRB=pt=+I1e7)^nRw(~7i^7iUDFO~g<1PTn5-qb& zs>6eQ!mR3nCTGIT5%rf9yhIDH)k22??Gi@%ZU(5;p;x%m75#!D)}HkHx56p_u8phu z`nHXWXFXbvqofkF(>8W<8h)yB4~qaQ;OQ-J$`0=E0k-mnREy1Z91S!82^4W*wrN2u ztmd+3!#3|`I58>62c?RWYw7T{Zh(90nNt93lbIuy6sZA?t4AhCmkZrlKa?UoxoVxPD;K73J zn#qedJ(`QzUx&%hqeFS^5W}m$*z4cgY27EN`Kf!rZl37Cks_GjgTk>HExLtfEn&&> zMK1+cCaww&5L>9HH&DuODE;GIXG>)vi&(YX7`Z_R*{EQC7h!F9l_Mb~QA(X$^}Nia zAI%_RKy@EB*F<8T!e_{l>j3JPE3ZDlsL(+o;!>K-{yLNT;|UPQ|M(yQe*Uj{pnuun zfp1Wy%>>vWO&@49e{YI^w0ihM^40&8|NJiwGvouO5&XwthMXwx8UWxE`M;t6OlQn- zj}UI4`sqXeUT-Hk6>vNRKZJj0TC&qb8ay48Ly9Nx1%YSK7b6tJE z6S=XG;8U{u3uRC|p(xnOb+gT?){n_U^&sLjb+GcdtFb5VyB_h=n^#E4t^1%?Ct1UH zyIAia?dvAsz+Uss2hbAJmoM2?U&?&qb3t$YJzMC&m@{CO8C@V$NScRfbn)Y6qLPKx z%%m2B7>bfzUBm@h3?}Vt!uKoDH7Feg^0A(eH>^MDB$U8)B`d95tjzI>c#^FLao^N+ z;w2WG6{wgt(J*`NGxaum_i1eOh+XYjBDsTXpm=|z1gcrm(X|Yido8Sd79r$Cyu15%`5cWPmfmxw*Z)6T_5BR|cIeM{OfY6O%?aG3rxxqaLiP>0D(&r)c^Y_&Lfj}78G>j!5 z!<}m`?x(41G5e8 z&aHn(F@YznipU_f0gL^X**NVkP5u%?3b8Y5jVtwe)6{)3%VNN>D!hc-lZPFjHCE-p zL@qH0Sa95Lt9x!@p9;Z7g6kUN{m~QziTzH)!ud`@Ck51Jg;$7t&rIc@M#TN{;x)w< z?GIJ=d$%-$0j8f2g|)_fMtLyQ9+eEaxxMo4Rgk)Y^BG^}W$G~<{P8)^UeBT{&$-T=DUt)A%gXtz5Jv%g}4bgjn}*kCyt*l#on>7_`0;mwWpLBz1L8I z&|BZ*6poq#m)q8iCN(3$Z&m^*UQm&)>Iq>oZLY`Kesm|Bz~pf|tZV+`WY4sYTtS7U z;SL@n(0h05i|miJB+cD|Yu^uU^kZD-9>G24ei&ndYn?_tGx$?`b|bAxfkk(=&eJph z;g`1)4QoQmVpAH#eJ_Qy!uDz|Gr0q|!1tP#_WU+|@8{0t*)6>9hMVE{%rrPq*2T8l z&=~s__^7vC^VjMRcPdMSYWEtI=gnZcC({fhl~DKK6_<2;>xGxHSOFoH&wA^_mv~5h zhApMMSzKD0d(;em=E-`l6GexVVf(4x@!dhy81rvb(AK@XOcO_=rbi9(riDI!gV82I zRgGo~3>!Dq__btn^hRP5ES!tqcnLR#VmOn3irU#XOTqL^Nyv80BOYW1;wLgXrm;YF%{~%$D)h&&5}*YPr93OT^|o z^)}Avfwe~7#O7W z&id7`D!tIEw|XS3^$%;ym7J_|(mV zSLGtfN6cF&0}z&qnguc*ykqL0sQXOESWyhV;sgM6YtmdU_~FLP1;ZCK{AoJU3Wh;@RKAaPeo()N~pf825*L4kwT2!4O+$$4zE6NLl~5G4HL zTmN`j3-YUkTRpn9HyQ#ipMSxF{_*6`^`02`{=Z)D&0Q@1Q=Q3JlQ#<%@Q5fK(EiWM z{U0+J+S^-u{OdEJC;prvLGWKj7oAoa85w=9oE_lG(r@n1-%qzh6O0M+at z@?d-^+$n8MttcjK+mG39$<;_KE1qb9fW0 z2(F3_u}dOREdpWesoE)7=epJ#DurMxnF4b-S6!po`<4~jN%mwwhvOspj zQQZWoN=D0LFJ!E9;#mwOnP)^wZA&^7i>yv;UWg&#X;^cXvQcGuTx zcYGhR7H_mtE?HY{b&5PJ8a~^P>reN=f3-r-8*sg}m3bZ9^+U{4FnxWJ(Ro>@@{-TH zT=Lm{;8-VMLjKw+UsKtSjAs_p#BXbder18{$sNdqtONPcc0krd2pg~laIXHMd{;Bf zZSeyk5;4V>|7HJ4=2^(-IS7g-ent1 z1ZVrTPQHb-`}6FEz1=fWbO(-nP5Ms}Ifw|*SSLq1wBYp!P36UdqO_iHW*{V6a7$eR z(t{i~bV!suY17<`k3)20INbtM>#uKi?9)>^**Cg^l7ukX;HkL0xE^D>CrMFh>b1;r zdI`-Cm@GaI4N9a*cehPd*&bKVriY-5fdk1jAtQ#-#Pq|xO;l$9iRy{$pjtslZWE@Y z$zf3T3lxPfpVh(Pb+1SVAfXKn5u9_9k9OE7e{u(Q=S1~%bxw6nH0b^KQz z2dr0U0Qs@$Pzy3bM%P}##8~_K@b5l1*;^U!91$9Jm4m3I-vT`lo}I9s(7Zu(oNDK8 zO=hRle`+Cjfzi>mi==@>c_&O)Z7dY{w8jj!n}mLpWQN`S(Qz;hw~Jj6nJ4BuwU>c~ zjgL{ZX~)LA2;6xy=l*zlCWK%bv*k9hBs2-uX6nGu)e4b6Rr zm+}k}PrK#f6a}KCfc^%)cOI2c>-)vc8D~o@)NH6DzWpbMhdf}*UyRW6 z1!JF&-|~}2w&Gp&Vp)UEZfO{A0uNtLK8nx$&^rxi>0^DIP9-J{4OfHt>nGb$MwnD1 z_(EOT*gjYUeEGazy)!ybK{mo$XbdZ#8JX?QT?hQa0=I6KjT=u_08OuLH znQLdq_9JoM@u;K(R&IXvR>-Jh&!5P`DpWJL+IsyV^cQrH_ z=Xn@RD=*vq9XoERXY)h3^#|kL6PoBQO_nQ*{WMNBpLFf`uZ|r`&EqqQuI}br7rS1$ zSA9iQnXLC4s=OZPWS=()775%Z@1Ah-$}|&_(AiFnJic973T;qTK#$U@EAg-sAb+`V zviV`cjB-dfhn(2@`!RYqc-%6|2MPc_L*Zrc*81sH~pu| z%7|{~-na-q)lJxto$MNx?;bGH4~w^<}wrvXLd%vuTae zavZ_3UiXc+-9iQCVHZ!ebgS&S_f}f35B8fsoX;dV^lVU@b?aopT2X$3rY3iVvIKti z*Gu|nm)#SyBEyQPvTIl?pOIrvK*zA?k2DMd^4&RBD>0N+5NhAXi}r(z;ZJ& z>_NNl#tSbKHHWeAUiV4M)vZ{q;JLSAc&c4JBUlc_BafU{X#O}Dj^yVWOYD>ZI`)q# zoi(@ybj+n;Q>9xCsrSm9_K1rSux|1RH)_5ZU}q&BExLhbE3fH0@{G)NNRju=0~en% zR`cg4cU9fkexuoe#l=%wIQh1s?S7{knPkauCZ%%Ht>lGZTmES07u zAfK+52?aF*;tg_CAb+rGD6~fr*V-~Xl$1CVG%PioJuGs8@@o{#x9=zpUt~z2tmoPx zxOfUB&piSQ&AD;U2XDMDURrOg05U^nHsBRn+#GO_BN*4jUu?M`{h6?`8gD{)Um#0} z6-bebTROvzUJW!;4}WS`iIXBj#D}ci!MijNR>fL3&b-yk|j&HRO?l_`#SlRG($6f{wm3>0%GjTZ3t#vNf%B?QxUc$xa^!boJE05i5*wl z=yk9mvB5BV=9Ki67qkWcqG=&C<@ay((yC8ora49umR8?c+lGcqDCeT`t+}Z{tF6(R}2PkC}y(fKMz4y%k?Y;2xehzC!!Fyx66=(|}s+!3V zDf|}yAt%=b2z`Ca`6k@!3jB}$#g?O+Q|#^u4gfd+);BZ$O$7aO4zsSV$%(UqE+;%e zS5Op5NI8sTbdGFnAu9&2syzKoML`AINyV}BJS$xrTvY^_l{B0?EWHH# zxcFh4e?9EQTmQcKL2FZQQ_t${Wc4HOtEs~c?=Tv$;e-9gz|u4jk;IrUF6`(-&oE(A zhD#N)aCbILpPYZ}JC#I8`)EhGtjPLgc&K3=sGAnZ*J04$4`a5$u9-0eAdkJb+9PED zj==HYH8jcVb7DxqGBLjtk0Pa?WH2_TFcqCFZwPU`{u0qX_2v8)?MV1?L==B)!)F}# zJ)hBim-SdKb9f{wrU^bKrZ4ET2NJ;FX2f!9PUeyK^lOAUNbu^&Sw!apV-FaB8JDTj zXd+`@KOOAhOx)1O?j@4(3vYdToYkHhab`{mftaKWB@_?J_ZuVN6{3N-mz*~x7*L92 z=z!c3H-?^fBNEhw9mI#2ufVsBrSRyEZ(qbUq-wKy9IckH>m zhm=2iM8LTCNvbk(|;``h> zJ_+OfIzEF8uu06+cKJ%i0^;?-FJtgZ$!Jc)=jH4im*`4RYxT)IifCtT%&yFDrdK#g zo6%6ZL%0L&KT&yRmRd~pSh;Jm3)n3s%$^we)){fTj_s%~m2D6z-gpji#YYuyNb1uV zi`IcR!R-}y5{yA?yElAsQ&j7f%B^>C!eo%Dq+~!(UX5AZ)LHala8|UqPN3Y|?6P4Q zJk+sKM7bDRaM%kuczVBehgxae@g2bY`53hzt`c;6u1G}u#hR|m9;GKa($W-xPYw%5({<|_#3ZG`z<8Pj%X*6QvtfgP7OKHry?mL^>&&B& zSqG7f;kA+MY=!)z)<`-<^k%(cJja&N^vD2413JC|9G?Gm7s8*i2|7Od%tUGz)Zv7x zp6DF|Y}J>N+=IV-?h`mC#>zP&nG62xhFJHz3onn(nF7Da{Lr3n_n^sm$=hc2gMB8LMSO5_MtgpB0K7HrpfKLMbFD;+1Rt?C*>rX!I^FWS9K}Vtnh1i zKQ8CbH`PAv$H7gdFI%ja#HM{+l-kDUP;3P2LH_0RYBP80rF+*`SDBN^vGu#0tnJZt z9Skd6&M3OZM~{k5>1MjM+gW!m^Z?T{oeM#pdvsbfGhGOZQCib8`B*;iLog5UlHysn z(jKt{8YnWf#{z(&)ANFJL%B^*|K6 zs~_}qq*%xzO3J{1QD0BsyMc~HHS$SC+0_3y@P?FGjYQF2te35-iu=CSkk-p(_Ny(cX{{vb1*@Msdi_urb<$CG<3IgpW`GS+U8_00s_#ZKHb!mxw6TBlQ>-wKM|1&$gE zXLFdSKn8_{EvP{=%U^ckwWc|V+Fc=K!ppH>kB6B@Oon~!0okjdpX1-div`yyI7?l* z_`u1$wP~gDvXicQ-OV|>$*w><`uUFv zbct06iC^>*VeLwta5TK8-%7{UI*7GOchWkC^K$FwR;48U($gB zr+J1JURnpovUgH<_j`lnqPnv}!hfUPV|er6a<+Q*$*;O7vN(jl&@rHeFsw-P-xSt0 z8~%(ZkU9iqsxPV#UKz3rzv5 zm!Xnp&3ZB{6z^HyzoCqsR5Op~ip}ega*U8IWUf!_a4(EGD-Ek=%jnh|Dd!`M7pX8A?HL9t=()V#51Z+F4rAAp=?~6``@}ERQ)t|GxI-uJgz>pO5 z8TgqlsTc5_l~AUrC%#552A#McjB&J}kvX+A=XQ@Ibcs>E>*NT#IZKZ=I+$pwGU__c zBo}4e%7s6XXb4_L9Gc5+J)u!E4z+t056U}62!q-EZnm6T@n*j&d%v^~ZvRr|p(eip z7zwks+lyS0<$I)nw)-9s*z(9SZxo^wkjR(1Rz_em1eVY50&FPqN3ikZR~Ww+`J`~$tIw9Y2457`U$l-u?o_avO~j4ac-+nf?D4-- z$w2C=g&^)D*d8G>V)D_Jv3XP^Q3X#*w`OA_Mp{8%b%vNjL>cR#dt%Hks2qF+<0?fm z-BxzD#Cj^_%yG07W>>d2nClX-bO`+!)g|vAA=J#n?M2HUD?KhN5an;I!}Y7W8-J{c z(r$!9t048#Bx{9b+W16BYOV5qZc{0X1zSspUfSW82ajUX;n$GM!1VB%7&^a)rz!*7 z@5z9GOVS^a-#VPu38M`MeNG}`#*HkdCY|WK&85k7x)U;vm}S4EkLFt2QsByPl7$gJk?H^)AF3DKX`RKK;fNJRDy!MxoI8S%ZkcR6 z{A+@xQO??2HodG;zGCN8R+TM?HY$^LR=PcLdK$l=yC&Uie;IZyWf2 zV92n(aL7IPiEMxO;`Mdk`owzH4qI-%%$uo!THYJD65$tTsr3Emn);C^bHg#d7QqtcQsGInaY3Jy-Ux!`x2BHqK|g#a7dLu zIyZK86iBozxor_r6*tUJxjaB`4tMjiEy4+b+gkWLUa*VUh67?(XG8Y}XL z@m4>+NA`wYvnHZrNA|y_9c;sO-4rXXdTRy}GN4xQks3~Tc{(9&4UHOX296_DLLx%M z7s!KP*S~gSZ@Ezt7tov|P`n7=!~iNg!DojAmV?>^*rYUg1YU95cD7|B)?P^QV!z+& zA1);BgL`KYsi9ZvUe%T`&PCoWV{wGB=P#VlOL~3mBD|Y7_)v(XF}l0l@Nytks9`s> zm6xX5{Op^?OGYNIM8gPEYinWO)`jeK-JbZ=8QfwX@&-Nf$_eGV_r##?(O)K(FzH^) zLI5ZvuQyv-{SiXs5L7FU|LPz7&SJocQ!FU_X`^@A4)B=-wjUd;x#R=%e=oY`-?Ip8 z1hT^8KvwwweDe1XR`|~bHvhMju-yH>Q^K)^P0p?3S7CR2GLbV5u{-rS2vF|0>5U%Z zQ_GUY(oOF2@?0rCMv;0Z$#d1rQ@e4gia05X(bf`o0*fBH62YRb*-lps!ec^u6HI^b{Z@X z=bPH22-^4zwp~S)PQ@{AKckv$4saeaYwArM%U(Zh`Z*9T78?mV^n9DmA01T;w3iPl>37t^F zvi)zuAR-!17~a}U%x_jykn%u;dH9|M1X7ImW8TDp+ zI2~qpzwK-4iJ`ot6-oyRWS!+u`CPy@Yjr7(y+lR3IVH8spEGp(-JHL!GZ@=>bM`$L zxtd&5Rxvoq+Td-nE={Z@-bwFGUPU#V`=s!@CDq+${?xO58sEQRab@|CT1IQtw0>do zxJVnZTao%+^qJO9U4WlGE8;^_H{?c6VlYsNy_e6`BMR|#MRNq;>hk#o83ZS!2{JmA z_Vp`%A5r6Dz4gbb+mBbAA4Z#p>-Cjed3G^kk&lgIf86mjLRa!O}U&O zMQnd?{<`*4vM>+7P}62Lxc9FQM)KsV85myhZ5g}-oyFHuSQlQ+tJlZ8pFRf~54u81 zW}F>)AB}bU`>82CQmMYU-aJ&n)vvR&yuOV3{oWQ^UJKQy?NQ47D^AV|8d`G$$j2=M z?e7uSUx97ytpCxM2V@z9{9jRWz}BSyPRZftb(H}rx%_{lJuA@i@0_eZ3bg zJpg}IpVHG3NWn4EL}84OqxP1W$8xI1BgYUY6vO(5ZBp=>QV3_yXI`~(4LIQ>+FD%gPxhq1J}oR)7* z6eeDD-X4TkN5{AKc2wM6NZ=(kNpW=PBp{sMtcwJau6rLRKCgFy+y>O64Tfv^q{Cq~ntc#u;mw*t9 z>lAuYa&yvitS5oI<$>N(@y%H)MAj|dJgs_8Qr1GsZFfaZo^6B08^L?T9kW}bX$dnE z=V`O1p;taTJNx@aibu4-IRSsmqmJb0jvX9aYohud3TR=KpPh@{PxsvOu6duZ)~1+1 zZBO@*>(k@@=48BLXL(<5X-)Hq!=M#uyASgYLMYujd6&I3x}I-ltaueR+ORWUNWp4VHr+=p|LBJ2z%-8eQT;x>R?zLe=TOKzxxuV4QvRF*zIlS<++0{Gka}(RJshfaz&`sbgYvU?K zS%tDz*gRQvwJM7fiZBSnDi5_p2~p0&p4mJv;H_T!V)Hs7_2m0f;TV&O#`Umk z_t4$B@Y><`+$GPkb9|_4)Hm1c+AVjo$Y2-i+g0Sfg<7&U+uuAEP{tWeVk^Nn|#f|Uh zGxPrH=Iofy(~_IDy0)(*weMJ1SQy?n^T9IjbyDH6{9}g>YabDId4Y@?LrZpcx7>PM z@VYN;Dvk?~eBE8EPU)XnXPdeZUhL1kH(6)`g4_8HmetuCIofa9Z9Zta4htJ-KB6?+ zlltT%tX6eQHd2@_hUW5>t%^EX^SYkzsLsX~tq$LPv?g(99_#KF5+S?1nBkn#e%NU| zRMV)ja8?RG)iv1!ZNSy73tdo~TvQpFbu45JY23*AX)VXNeDY&S1C6qQkXIK-bCH9V z{SOL{j)&5vcW zdU>I??QyYWuJL3cEZA|Bs)M7PbGT2yaNBrDg7y{k7!4jBG9wN!cyrySUn7~qH+=<4 zzxNPOP#e*?d!xk^urIjZjj!_lhF|lN8F028STX>WP$h1||^50$ylaz8pSOWT{sNt1y){fDt$ zqk1EccjyQj%{WmrCUh;3^#XN=;%@=N+8BGp7l?3)f^|-Or+8WF{VCb2`1_3JW$8UG z_cs*#4|e+fw1#yXVZ9h%4aJpIC*ap>r&sU@uJt9@WU`UbpWjGcP9`eUj#fYP6RkYA zde=YfTx)*pL=2Y~AYk+R zr#?9Zft@{_poF-*-q0@&2dr^kZB~p4YB$#yr!4hOG7$LQl{D2piW~%1IR0p282mPX z<@MY@k8PGdJke14n*Q#t)ZcgfF-#5;axh*~5uN47V3e}pO#rb$KqZ5h7T{XNGkRG% zFk~1@D!}QO?_dEJ&6aOW8}LXL_;R;(D51_LugwPK%R5MX=}vtZDCg$(p(~+Y6)E7y zz>&HtcywN(J-kpkx?++Gy@#femR9AdTHgfBcG%cEhF4-cc{8w1RgFL}TI zG<6fb>qlNY&Lc`HU>%9Xu25@+kZ_D4-WSgHqFpwQg+vp+A^scUh*Dl)AG>F6Cut#rnSN~W_26dgf90#I7)ZQ(z<|FAw7+-w z&e`#g+kO8yYrP2|{P-7IY%y>usDEg&PPxHHz%Ppb)MAMc`UH{0x0{2(43P3O*)5b- zVQ&#|K>{T1{s(Jc0hYzK{Y`g+v~)_hfOL0vNWFA-BOTIRQX&$9l%#YcA>AF)NVj~$ zssGjMIrp4b5L3sE6&FZyhX0L@*vO{MHSA+2!n#(+(nCvP0OPXT3x>nAW`}IO< z&Wr)v7c_L@qNYY$yv79*7FGle5<$m`5C(bgaBXb3UorV7h>{Fq&K4VTBhSw{wCIU& z_GRnzuvlb)m8XUfe+hsNzdaV%+`TgRun=U8esp_W#d{!98}?Zp84SjmG2R33ddM5x z;fSJnqOJ7`xZ*!~@Yr!fkv0zebpiPNX%Xr_ihn$;n15l`b0-@^>pywPgIjQ*4S2}| zl==qWe;h*rrzbXoyN?zg9v&R0=2pP2waZjT>8pm2mX=w9nkVg2vL%;z{Rt!qS7zj?#q8ML`d(vb=1y*lnJa?!<;gy(P?;zciBee-`d&T z$q;u=3Y-4CN`@6bwQ$eLS@jII;ZL9Lccig->;mlB0zQB5+3c?@a{H4ipMd{g2dm@; z{6B@2aUNH!_Tg`@!N`d%<{CVpKS0m|?Dx>^8L}WuXr>`>=#!T=5Cp6&|&S+h$C=(+DPyHtRk2L0S*7 zYvaYoRFW@gd@={UzDqd!d1SF(Nu+J03kqM~UZvCvq-CsezeoE^p=Zb+rWnHtgGvKda7V!BKlA>VDgLiSIbhH~#@_!gHHh(O z;&%X%89DH98~R^CikuMNhN`e$+_~S?H@koiF}6cE;)a*%d{&jh7C(A#zP$e;EiG`j z(#ZZL_xi&9OY_WgpvCpIwRFbvBxux{b=zVnvRcm1o4P>E+XC!Znkrw6nbz`f^ywSs z;PBiImZQDN*(rWOL@{Yya%n;lk!QDoxZapf@h47>j{;bol?Qb<0;W%KU!FN1SVI6zoU{yEYR1a1t z1X-3#!N&EWj)J8YtTrpzBViKq3@+gG(w(RA8oH77Deo?i*iQNu-ri)bBDi$AKSki3 zNMNQO9;>u8LPY85*%+G)t8~ICa7kxQq|NjY9?C83@2j73h}BYj$jh&$`H*^FbVZ*7 zkMuV*1z3lHnHV}7{@Y8{|Ef-?zkkWb!WLxgXlVNHO;!K(>sbH(b!S7fziwpo@czv& z*YST4zl`~L@$7#^d(ibiANeqyp^-J{-{?~rL6v!^6e$CI9^%&Dn8MH<^h+`OUyG1S zGxSQy%Bxi>OUew;%1?lYCsA%D7GOgL=lMS)Y5BebE|)+H4I2|*Gw^#+_(GE8l4Qgm zOz&uORxAj(j0@oN&>P@yT#mhkvDNRF#Ld*JAB8^1s( z{7rx2Gm*5D*0do?W8(=w+yY)~`<9u(o0Y+=)~NB%UFj~R!sSMNY6vmYqBK+PuVo=V zNaB98(8fH0Num($-jL0xw^pLv)tL55Po>KE`ucqk;(Ac)k+p=tnYont^~ast@{bK2 zO+OF>(C~*l!u*|}@7qKF=zjin$U{-~UwH8S5NkU-=jYBp73jZ?ru>hif6=RdS4rst zB)l|Wupr<8A6|6+>r41;lHc!Yf8T4|C;Fi|7SN)IKiK^Mr12b-xT?!(Vo6Z|dVRWJ z26A~EtS5X7q`H3C%1?YL6}5|($uwEHCUIiUa~mdP!}xJ7bYW<}Xup)*D)HXogeFS} zWNPT4v-e)Z4cIxCWzS_zgO@GWw9T7xrFilslvk9bL$Y|EKD*40yMJ_|qT`ZU+SvDG zJ&uY?h-f+O+2(`*KgQhnORk+B1yuNt89!S4SS zo&T|~g->i7O5iU-hTfj}RMy;Ii3{_J9MTdYouS)}I6j<_u@UY1!s>oA`w1yYvuBX_ z3pS!hpLDFtlE)!;-ppXm#5R0Ug=5*^>XYUC^wv}Dvjk^duGce22?ER!p(eAB&S~&* zN<3l~)HB_=4Kj9#)us5U2`Y2B63KD6{g<~_di_!s`WfcE_w~ihOK*eyCD@G2k7jfb zWbVyXOVw(iVw}kj%CA;*0(4Yp%E=eBA>vI>g^RF6M5iN*>pg#9lRU}bn+J8^ z1=z&-x7qY#!-${hLk+!}hBJY-@Hf7H(Fclr)!XQtNL3=pY4-VPUBa2r(Gt9HUB-iY zLS=auZ0@*{V<|fXD0#SF^&t>Rf13{z=6TuxJd9n@Err=LrFQ#6a*#T5wt&vm6Rd9$ zkyziV%?Ip~Ze_`%W4+wPBs|Vygp3+_SYH0nl+3W-4fh{g`oG+a{Fm0~57f3lG$Zqg z7(HRszj(qbUW)$Gf^GC^QiWSBU70+L{;!sT~CpI0pCKh)`qJY33q^@yyf9G)olL3GSVtkCqq3-6%O- z%)UA64aTJm=|AfdPT0$gh8$%7tkF(Xm&Z_jwuu6Z3thFew=7HZF!<_c{K|JuF@~O^_m~ zn$RFxiqz1Z?|?2A44aOyVY+rBGi3iVn12+SU$db_+kn1P=IoCwYjCgVt_28=1_*!h zmxTZ55rbn`Py?9Jf-k-yjLvi=ePDxp*BuLkViQ!OAA?JA>lRaBY2UhWTz1jy)ud&T zmfsgRz{ZV>h`bYhtQplbzEaFreOx~KkqV-E@0r6V)M90a_DcHxT2*N&^)J2i21fUp zRK$Hzq`1DquP$D2^zg)w)Z`~k@P~bdam21stVdmth&r7o>uNzo(SJ=93Xch&1ZTLn z?Nwx2j+#zAPS2XYYAMuw87)-8v9`iR|6 z8Hn8b>PE0BB9i-Wt>!p#afq<|C^E31UUh(KVd~wQNFb^!uA)KK%;)_H6m+irJk5pt zX?P^T?{3!55-L7JZ8k(O3*KSSlmxqefLLMR&gjr$nH?PO-=&w8*p!w#8hlej&Xx>~k z=Wt5*2yU@PTJI2;S8l){dfruxU>kJHw%^7pV(h%L1O>i@)KA2AF6CQt$N6UbK9e_* zgt^Oqd_O1%?^1nYCWYB!tcq`qN5=}U_ntbw zMlBUHqu(6}y;xov6nEyzSvIISY@RbnQJ*#8Z)7#ZSIPPu7KuuTk@W4&!s@UT4>y(F z7pUgPuj46d=Vo!Z)$34(SAKA;v~|Wb?*P6%bg%m(vHq!>`PV97zorqfEU1AbXu)p2 z(1r)26BB(=O%_OPB^Vnd_9)$#ONgpAdJVB|ZikJq?;@RqUcxFl7$OIt?1-sxBcIz4 zCWgw-R}RvV!KG%#s20H3xu;RkT6sv*iYX7bN0w9EU#GFZl?^5>pHjpmtf3u`qbbfEBZ)!{66qB2k8K6juxF{2-AnjssTw1A?KZ|WSd-)3*-9pBgWAq-F?%6 zX+Aq60p7e=FFH14n z>e4QhcIRjpPxhhw7csS@P42uhy8U+&B45`VWOr{kk3zj zwUJ78tXBea4&-JeY)|E0z&shg|Fn6-$+9hj^z#KNCRKLR6yaO-vmY`@Fg~*sMPSV$ z7Y+sn3-CZzN<>UvMXbw5$B959{=n-l0^ws=uO)$U!C2}6MEp^-yNja6w=+Sjeq-!dgFK9KSSJn|IN&J57acr)wNboWtQ^gR^}$x zVQ6t`_ki0f^G@+XEz9Nfe4Md(BKYo0!LI8*(~?iE?G%p7$>qZP?xAems`nNXc^`PE ztY4Nn)$dz2=55%hZ*VfrmeD5re4*!S%!jVMG+xm*-uATlB_C67tdv82lcn3 zt8GoEoDXP4bQ@f7a6C390x_#-2KSFN}yPT9Zea+a?VbHIdYuMk5b90lc z*@<}6*2biB%i(5oq**_YHrcR8!1pb4f4}*F0EYg3ZL3-15gm&*A?Xk;)MWD<=Be70 zi47OWLUvYNA&dE5-U6f{=pux5#J}0nVB8Gb?R##LshC`nkK7 z^PF^BwDdR*a03Q$c~&+{qtZ~|TdLYQ|OwojUnjhysOCfVVoVjVz(AD)2v^GXSx_fkl7p>;48MQL$%M}tQcN17>I zOMfedHXu6c}yvyTqHEc6?(S`BDWxs-t=R#<$+ndYwFFRW{Xy3 zsiXls}za|Fq*KWYY2 z_;KsTw6-7GZzZC&l6i}F55Q`Fx{I@Mqb$9_fU;?s6^*7Iw;@z#IaSeM7Ef*5pWQaB zz0|6OMfi)%8s7|R3UT2e`QJ&wUELmKI!*HH{PuNidFjboHoTeroas5u_g>Khj z(Z{dIn=FPFGl9j*{I2Fy*fF#tObTK@|IJFKy*!!l7Gi)@+R`&@g{%YV3(0o>54NAA z^(PM4n}oCvc$1^0X;vmHtcc{#A}-Y8F8YZ>H<*YMqU*@GXJT)i{Pv{b+}7;!9P+ZH z+&Mo}dQm}#c#`NbnygXAWrz7Kjt9xt$k}`!hd^ddWmQ>k@F%sIxO!>yro~8 zyqzMup8-J=`jZ(eWKA7{GA}d9R_QyH`SoNI<{3tprO}EUJSdD<-cBJQKe!u~#e-c2 z@>0#maqY3#j*JHUidy_6A;ki4^*@P?Nu;6XGYd;vnr^qafL;gWIamQmbqrqZWB z1xoYMpPKlGRfY(@USimmE-6!_FJTa>gH&N=zx0xa%G@BKGr~>Pfq2AluIg^O!El$M zX}PfG3h9sv$2%hYsiEJB4xNj>0YGxMZ!WbcsS#8X6x*VS@|RmX+$2^#INgmf08!aiSt3;6)2*GxVm z&208*H0nv&^`~$!mCEZq5e&wjShWtbIG(9XJ`J^1yBFujo7Z=%h7L|X zF`+FjBrY|KPiEqlvY%1#n38SMF1`PfM+`~)s=6JNyR0tXxxCmADgWqnVYf1ej;6{i zY1c@3Ok8BCzub&XZA6%2s|Gq&^c_4%yj$bNTwG&Mn0#AE6!H0hCPe$B260rOid~U; zROsTYhj_*|`6}Kfx1PtRC*AUr8}eI4;myml@Xz}w@HsF8tWhl`L4<8G&5r7i?i0kk zG1KHkDaXhlGD!NphOGVCbNZ_uS3UNf2FZOn1V6+z!pl2(x3C-`YABp9u}g*ztJ1}6 z*re>z4nu!i*B=XChfyL*$@i*}NlSp)9@@N#-X9+NnUWD^a9=Aw&By0mlO*?6l_vKH zs77n2w1A(HSLY}d8(wz96bq)qGFUBpvR9Pyihj6+;KS?FVer1?gT1)vGqhpu1b8p_ zJYp?6ll8aDZyTsN70NFLSYx5XrhA?D(K4YVb_LV(A8++k8dwG%s;XMehZx7vK=mA3 zbSZT5l9`gQ+`&2%+{Ngez3P6}deV(3MG*P)_ECuYQDS&-G;iaCQvjOeNeUlr2Z_Xh zV07k@p#?Wzfm|>Gx4Sg%jEZ_9QZeqKY0o?(%oB8dM4hlsOEJ0*vE@$z{5}{Lfts5$ zNuWCT_K^gF1l~)mXYbX8pF(_s(J=JVn|*OPQM#h@LhKDup*w9*u!1$4YEW5Zlt%qj zXA%I7-M3xtbk#@ZqZ5CVqc<~0#F&$wq^_z7XB2hLLw zcqj-P*I?cSlr$K5-8F>tjmSq{i&{U1+X!zgNlEF8R$JkC!cfidq-O`86AD7tN_nG= zHoyjqY!!`WGCHJUbApL0hoK8v>PiA{d!XB-5MxS3Vbs;*F!k1uSr zG!fK2koCC`Oy8?RDZ9={K7Mqd#Y6>#`Wo!{JMPOzhyLs~bRpn2bStF%6zE`DWA$)f z9>3fuv|<$@oKxtUc@#O;MS?;`7NRlB(<4t0Wh~-nV~$J}$%V5{S-$H5KQ*>{E43OU zKdvU<6_*MPhY%O}TEGt0F>6hyJ(;#DB6LKEc7gu>Qw1QvxLO0R-l1-$bY!SQKG}(P zef#a?49!_2%9lz|j%|MA7u7EwQ*|?{_Zq68otj9S8Vp{?ITPLO5tF2p4qb%l%kn+Z zNYe~Ae62pfn|vBTVS1zX+>~^-1{zzOLwJ>+^`sGO3Yxq zTGz|xWQ!wwja;INpQr*AGs0X|iwFndHb!#zRcq68bgpP)G3r@dwiAzsE1kldkLT(o zgvD?~9EA=;*XMV1&S`|dshmF#3X;LlaCy|e+NKqt8bJka(;Abp?yz~Z!EI5v2_I06 zp(6uTlD>s*;DQ041bY*37Cw$fg@L$4gn{xr6-)wK%w63@*(*o!9Szn9B})+8GZG_X zDsmbsX-!UJC-iYZ7Hx+g&rNGIp*(VGmh-$gU( zxkn_Yco$BJe#_p-C|y%L>j@o|h1j@b(@)G{^xixLt)74_#U$QQ**Jo;Z*;%J`emnT zJr_uc^xfq7rx*BkkD%;Y*$~OuqXI0ZZ7o0Yh;as|IwI0h4D*;q+dTK6PF~O>4dyUH zlws}598-KDWhhx`9<<>4LVuW~=j#*FZ;2rRGlwGea-YCIbbD|LQdDmW;t(r-tmtTh zox__s0BMH2<4N|y$R-7k>~()OgNk#mHyLlzfQ%Ae7sqyt$T5A}tM&0V47^Kp`+hI# zX(v&R4GP3aEr09qk%6YabHrQiOl-SP@Oq>?i5V2G{ynv2C!|s>0ubFMbgj07y_SNX z13T7z)Uf9utdNYS^=k+{eReYA$Ar%t=MngHD=OKGQ2S6yzI~iW9cj}pk3~#ODmage zbeEh>-oPk%h7$cqZ>flZ2!}X32Fq1VAi?Q&Yu%*#ZTRGRCQkfVz?(iOsBiB5(j&t* zqT7xFr|?$+-1kDJ$H^jVf{~sOtK%rG(yTP=vt%hW-7a6v#+WgSnla9m3fxwl7LnH2 z@>J5>fj&lIAx`l`_#Cqm8B?Tg1?-cPBzSQha3I@CYC|53*}ZmT8?9rS{^q0{!eo*< z%{;mgiX^x+iTIH(b(0tx@AEV#Ta|>1_`gW<;5mS_+uTvid*q=~S)Y0my86#sB2)~k ziok_L@dVR1v=6e_NTOBQi9}LDJ33p4$2=*bMcGDW7NT#%sdmnIr>l_Ea;1S0NHUKX zMGBEf%f^~5C;VEf)r*dP?Xh=woRqJ^@yrS?V+<^H{}CzO>eNZ9_Fa+HM~i-fI)B+=owoZ)>h8r zal!}dp)-vVU#kC{wKojXc!Cbpv+HT^ zq4-9WOlHfX(&Z%Q+>qr8jZLrHQe^^k2L}>v26bBuguSMq5w*6P@{yYTXwr}iDe%N? z>%=~!7tZUXyCjF{(72G1_psw-B7a3kNeE2>K~UUEZ{*=r7JjlQXn5bA89mkf=p#akY@ zzT0CqX~*tfR=a!=;ErBsQo~si052|fjDFTDO31qL0k5jCP*^VVy|l?^dkn_BZBcLlbt>YPE^K0 z!XB!n#U)0J=DUR{Gd*cRh6zE>#@85(e#{fY?`Qp`$oso4nIB6FqE%3>qgP?wo!6z7 z%|7P7jZfUTwMQ~0)q|w{Y%4f}a^zXc=EX97HtFqT8%iLO$eW8J)chLPIt!YlK|gnDP+<&x6oi%elzjUrjjscDo|N!YmvIi*--24 zq^>%TaB=z6Zp_c0;uA3{7kiZ>PvQHQ6>HxkgRn-@^%0QZ*YLo1C4GeF4qZ8d^f4iW zE8IyYgP7s`6vFotYWK%kzwyac#}qO~of6{~TiQfI8n=C699Jg%m|uZIj3rYv`4Y}7 zAbk1#xm^#9`k1c#7`u0_O>wVp9Fm^vPLHpuh%L~ zl|AqJWX4~$P9~ETGzBel=l4RZLH0lgK)YhK2%NSl>w4O8&}I&tr&q4WiC@`q$R87a#uLAX%7{MIjJuA)0vC=GC}gL9E7Psvj+Qpf0Z z4_s-U7V=~>6NltZp9N3oOQnY)zZF^-Y5i`$LLBxija&Zg;R z*GL2QPSL}2Cu*azT;SP2x1fy;DHO>!Q5lO(Y{NEWVm3JA(r{xiqu?tB#f9USQ}!XP z-{0kv$zpiw7|G_nnxY9ZN^@f;T()qX(9iK0|vZ;0fq_(mqO-30VdL1FqsoiJ2$b}(rQt~MvuT9c% zLZ^txAbkVZh8~vUourVy>i+%n;mmMFtK}9ABWQUB8J~)CNz{aGFkhj&iA7LUkZpp5 zs1wx@wVmvNs1Ap+5ksm}q%1tWlp;A{@Bnt6%Bq(|F_wK5 zE|o3hMfTHh?+{E`R31sk8*7y`z%nTb$Q}%6XiCDw7ric?fDXsb9Caeo3ta?xx@eEY z=}wdKSq85sh?hn~q|VxFg)2`+4!+Dg6QYF2nkrG7tOQXV&?xWp8jzHeJWBqmR1pzF z_m*<6rw!*Zek%24oFj&Z(Kd2tcJc@#Pur!;S$FEIjcBa9__UR$d@2^<`J*#+rq2)7 zbY*4Q3?h}OYrm}qmq<{iy+jh^%ymxlqs?H0{`zFMIc_UQF_5O%fV#+-*&OeZ&YA1@ z1tzy8-ZM=xmEYatKQwm!6HK~p4ayM|GQLS|EH(4?fGE~h)@O_r_DuFK? zn(l?=R%3LZh07?8Uu`{i=v^UuwCduJ>l=yk+V(Pr5f`hEb}mvQN!be5IXE9l!6-%1 zoy(qWnsrpfRxE zc}KZnhqhNvgS%zEQTIv5?-h@~ung>i9p}Zn`%^$X#z}%Zh&E{ttrw!t#o`Hr9{nUk zJ?c7$Ao5fkF`vAW4b@lT z=g>ps9sN2$c%-h)94MWk`u;jpD#cW1v`(cO-Ny2o_iCYDLH~mi5Fa@@r1Dj?n#!bgZ;U5Ac%g0H z=|*?9s@}9#8!h-cc?rFTYbGn(hqleC=5at1+6kVIt10c+3VGi{00swdQW<#hhPs;1 zW~3h6Jq#hOMxrQ>paf5j(^YIj1o!mOCnXMVV?jLnA>mK%wBaG++R`{5)I>X91Vyat zDyMf84Zbnv@=Ha9*q~S1tQ@SCbgm$x7%7HSN((V+`m7OyIwz&gRNAj)#Z_A8PwQ%I zqiD1*^9B3Llr)@nhxtT@GPCdz`7S#TeunQf4DLKtzjk#c&xk`?_1JastKI9oIoQVW zFxbI2Ps}7bGDP5X)T2)^wc77rL-!03su?;S7<$iN)B z=eLLv2X&2C&P4sm%9oe|JL4m$bf>Ir+U-tS4ViA+hP;m44Z}n%LKnP2v2QqqodgD| z;%p#@(${G`W&Fzuq@_2(`25pf3g}=(kUbSlJL30Gzo}m*^OgO#Fzd!kV$LK>`K z20S#8kI2>3si=!7GLGZ-B@fsrDwMJ9T41>Qj&5Mf}Ydy6G3s`k#%abuxvfhD}#?!uk%t8b-sSnEQ4{TZSm$AZ0kLWL}qj zY`h?plDyFus?HUFG!VwJU@Hi37S;~JJcLuU1kzgV$kJ@4J^D=$Q6_4keEd>36zpsp zeoFGZGIZl2ZK_Pin%NzU#OUAd7!yQw#S0(q}S~ z=#ew{3Umfd0~r9LNa z*addJ_#I!dISUko=Yw5UTy@gl<}@22Dq#2~C+g66#f=x{(8-!CFEsI@?V=J8>pbhN zIVMYYIOEn5Y63Di50h1E9K9f47nE~U4m(lWwhR0%gNDAIJcJ>ed@X1J*ZHherIk?f zpsLQ?NBAW&%%=l3UN#tfNQSuJ6o_jnt4haC4TMeB&t`VnDU_1x+=)BDnAK{M{3JcI z&GhoQ(7l~e?dN-6y^bu$G9jCRFd|T!;8-76c318xJb-fLbZBE@@lTlVL$D#^0D4)^~Fp?oc?zV(fnU^ zUz8Txz))ArN_20{t~JcQ9WL5TjL&_&8)9nA8f#f*FlEo;`!wRk=f@<=&ii%4Uk$*_)pC3gxw`^U>if*X<(J^tG`!fMvrY&YB3-(C4FpEk1vzlsuU% zB--cGDABrqmR@K)7;R0_^%D@y9W5c zuA!G+3|pDdW4#Mh48lQ}9yKkXO^HN9xP)OZv=^-Fz{6-qyXI+(mX`0OFH6lE5UMmb zpn)aub5)E@`l`UUSy;qXSZ$(**--)Xj&wif)WBnHkMd)%!lYg(Abo^C`2&K(K@-AqMB&a{abd8 zgM!vgai4p7@@XQY+{Oj^dqrGZV$#E2X}3qgvyoFCrUw=Gz~pS;qW9o*g7b5=!6gM% ziidFLh!077j7JkXtEts%eQM1P>ohc0*n@_dFl7}tz_%)Kc6j~recy@cISgbehZ*g# zxbxS6oKhJZ+-N%EkX&}8`_rbunPM$BPt5rkbjef9s~QetpU*+3DY51l6jWwBPviXp z6_o2ZxnEwLRLO31BUWHeiUsy38||(>Ysr~co%}pXP1}7j7UAPbboZ1EhKuv@J5M?0 zZZ$|>KiMOz>eay38R#CZ7xBybiKv&m;4#RM+@$Yt>M?K;WkZ(V%dfxS=Y60-t zu8K`aRxnR*dY~olUFRF16hxwwikAO{tqH?=J zeiCnVvGz_oZhjy?kyloRo1S~!oIhhAJ-F99;-$gyD;U3cFfMpa1k@0&idfX~l@1uK zR^`!F42TG-~_ej7^EX8wWG@svXBS zJX8g`&na)pGF1)FT!ZQDY-cOqDN`UD%Y^v6ML9Ob>bqL9Kz;Y&niN&2x#y6bC>}y@ z6Oyg5yK1PnKhfh_ePYLHkEfiD-Hxo#0#S#pws}NcWru6tT8PuEXPOXOOeFeiY)dk- zw80qPLE?-ISzpLlQFA#bRTJ zx`bMF`Jy|;oam5-k+5;nhC!%x)iMtA8V;;VDMX~PyYQ(7L#ang^@S}2$W)WbEjc?2 zo>B27kX2fDHj-JuW1?L)yIE6Q$L!b1-i6)=UIHLVRB@3)74y+M@*blGTb08qWj2tD zvM}|64tg>R;agL>{V`1AS*WLkAXDM@ri%0f;cuo!VQ4Rg9~IrQQTu#Wo+VceIGuUz zwkl^-xZ9y*@P!4D^--y)kyx>5K}BU;Plef=A%R6lmjv;q(Omm!YHWTBjlK*nob$<; z52xf`o`myE4tC-!M#_qRRSny6RA@!#^3BgrXmbv=uW6 zo|j{Q!BwCbdgPTGYVy^DFeD*QuSzx6F7P>l@-s$-0tbq#ag!AbdhI8mW{VnS@=#mY z2vu31`?;biEZnRfi?;RdnPn>DvVeL5?e;;#zEe+GLPEwwA`7{fQE{vsVf}?dTWn*F z;|U}VtKqOOqL3(uZ+f&nWA+#bZAM$^h-pxq(sslqHz-iNUj{$o|5)rKp6eEnX-b5d zFV$PNAtBthOQPCZ6cTryDdS}p#KY3g8f_JH1exkNoyc8a30-ueZMuo1dmws>8vYdu zxxJ2=bu?hN(mthsOL>1tmyw>Rr@2=(0!J2OMi13Df|(+AqftOT+eX}XX(*HG3q0(eI^kH!P0|Is=7tm`$Rp94Ak<&?bG%B@4XEWcN2~7 zqxUY>i)Hb-uZ)qKy6-l^ozK_nBR{bKJ^WD*5@qZ!8w~{t;*J4cfeG)m3g%?)A5mfB|FO_Q&qsI2Bg2Rv=wHY`ixv< z*HCCZpUc8~J{D`uYUu$donC_Ul_Dhpi>1?`Ay!e$o}Jd`4B3c!NZL$r0DUaZ#qq1q`vJr2Y6F?*?$(rd)&&rWY0a5O80Q9vtMy7cXe zWf^41)8}beCgC%(J@4iXWS=Bjanl!*^A+GQR5GN&#Pam+HRc9XUo>O$}E0g$P(ACG|TPw;A70F7ht2G+QWv zMOZxP-8~vElFRxCCu;8^O;6w4L``AOS?@@s!zw+7d`~9joq6zr*L&He-$sh|DiWGs zftoK7p+o+oza*kqwf09Rsxv3(nDapqcPa6^wW%+8&tii}p4N3KNk1#Oou2d;>$o8A zJpF1jTbdG{`HHW-HC+ zOm+E?aR{N5huXyAQhXn7Yn^&2fHqIvJ>|T5LVdV9?$fxn0d?Ssi z+Vxqez3|f9x8IE5V-8;N zWzFOfO!J3#3^hJ8pl`e^%0+I>X;x?$U&)od-{O)z@;<#xFHQ-p^Tz+C1a^eXM&!$i z^2j3%Zrl-!X|vPE?Ui>ULJgzGDQ@oS-BV6~VMNn%cZ{qzwUVvYm`QfxZ&GL9hzyS6xyiGZgI>@@=p*xc-9k+5EtH^lM=l?lC$B%x-y^=wNRM^DiQDy8FN>>eGD-FO+7R%P zQVa^dIs&JZIOX6;Zc2;ZG_M4gto{ALs2x*OJGtOkksZ1;s04+?%9-P?6`M8EqAgY6 zyod>#HJkJmWb3w{M=R-ydpXKbD1wbZ87gMHtC&iVt$wLCk`j}vE!Z0@^wnU($CQ+Q zA`<*&?K(j*_~CL$&eR@M3Ryt}X_5WikcCBWU$5!kVyeZo1>_!o3R-n61wWfKpdn4h z33;qXuA7ElMuk5qhAA598FI*TjC9-k1}Q{U*=dh4{3!EsJ(_2}Ij3L593tqLJB$S? z3&SYKS&)lrbkNXHw|oX#q1-hT_pD&i0wZF>xI}Kh3dlc24V5|aXc?{~jZXC! z;HBMN?n5rFR5%>FaCQbu?cog0l#Hn?KA0?Y?&u~=-cg^4sPVazvtWsDVl*Uw0Bhh^ zUTIJEmpodQ|5{NErU94nE(KgEqWtDYj0PD;`8uy_g>037=y223!S21?UdqhE!rt{t z$(_AZsKE4GW5&{fX?DT+N{C<9{f(jToq^pKw`^=w)RT+z1r4^wrY3FOp+&vH{fRxq z=FHQ>PgnbacgGICHg@H=DP4E-ivj~*+gE3O>vf*dm-($hGuhd;EHe1sTpI8%>NaIB z9pMx=zh1Z!^Wtsv(i}Jh?>T&Vae_s~o3?;Cjd=q)`g*i^A_BHJ@0}yoJnP3$wxqD{ z-G(@L@8iYQ(n1YpzTZV1;4bf{tNUEv$5)|TcAr;!<$AMCpJB`7bh=}3+EZ`?HQWl8C@^AIX&~?YM~Nki5X;M5?DfS zS%Lp3^m*Qo3Po4INbhvpsy?1wrXezM~`a+jRe#`k|z^YQ=;TOcK8aV!NbegZ< za-=BL^sfZBf}?StX`;Y!CohGP5-VE}v}{p_C}UGGXiQ9mBS;N8 z(1OU}6R!)qXM!m%OXMpVj&_hOsZ5qvWUskxTaq+KHq!o7!#E-^9GK8``yxvJ*&`6d zOc{cI5 zL?^z>QQ)?+$CSytCtx=5LZgS*ss_LO;> zj%UG}W*F4oge);Gf>*fN6)}V)@QPs*&CeDySLrIN^Q*|mZ=Z@uTh@Jy@8j6Z&@=K1 zdBzM3*q{6Cs+QmS$Snt~eYUCT9szT3_u3_(T4Gw^*#uBwsCEjb1^3K>AjVG6D+VZ$YG9VSJ{N@^C2~-&FX5|3`>2~ zm80e(T>V=lCIaO5UesA6>h6807qmzY33uZ(>*UG}C`p4I{S9M?ySnuz*jk-$>H;iBoPTkjPUA%^9aaFx z+f}bZOh+wWisym3Jo8S0*M_#e!svt9^Ia#V_vz)g4c_xfI2pD&qZ_vZiZb93SdhTp zYB)IHC3_*@^MBj9;D7nw!#`+X`@j52PE1vZK}uen>BnJ}eh>!)z!&j=&%;LT-;aEM zTHwb&hRF%ZONooAs4~il|2V_L2#DW?0R?(~J05@^O77cQ{~P4PH+~=Re~=FY9yZ_s z1Dx&LY@L95a8?$!W+rwvPJcNA*~4_d91k-L0zdt1hVM6={78c5{z#Gnz(x+VUw1kF zHX&HPKPs?+<3G7pIjqW`da_xB^;e-`5(f!LZ_nEf2WGQ;5v z7ZFevKx^23pC35q`#%PL^S9{`1&R#(9AK)uif9f{q&|Qx!ruXeQ2he{d62W4oud^6 zARB-d7e^2U%g^!X#qd$ufVu~-0iFqdht~$|@%!5Z{TtrT(fD=G;<J#4q<_G+DfIr9CnI}HE0SJQuJTRaNe;oP#_(1;g zpUq3m)(j{j19AjN`b9`m&LEqgBMG&R+(ZxqTVDaQ<^BWbfrWOj{vncxImp=RPl7)1 zI2ddl(1#;HAHG*?#iqXlBW`Wy1~{ePn=<}X=WNnyB?ckDz~F&E`F&y$*8X=fBteEI z0Mq^~T)8d<-!1})g*Q-);QPd)uT)J01B=kM@OKv z*q?~v+~k86JfK_FfYE%f!{oDn7edj|&eXyhL?LAS&@S`mq?G!rs!#x)S{m?Y-}5R6 zs3rHGb@)N#zv28GVDbXOG7N~YeLzkJ*yA5ZzW>$6-vv+xnf)mN$QFsBXMjFw0*v}T zijSQ9-T75OwoZ1Azxpr=IXja-@hg)XRv)aNZuTf z%J<5(1_%B(C87Z&_J2W0sHg-Z4-Oa@2+*vDP36BIfa5~`ClEg;VC4Xs+Yks{2oygi zad{MfXZGK$8xXo9$jJ#1{9n1OubpkfYmb3U1IVMk_lyQW6U_gtzf!i&0FL2I#7<_Kf}oVTFB5oXR=m>JP0J;5KASsEpVzmIj-T=D$>&>HIc?RSrum3AF6=O%xpRYwP(=RTv05*mL zZ2TTBxZr<*WBoaGrY{MEL;!ER1yCpZhcY~ma8dwtxyEp^+^Up~J7pPlM12{|$1fcJM!9V=Zz<))tf74_( z(u0Nk8*oeg{{(Cg0-5|3aO+b3Vgm&jSd8|M5sSU~e*peDdv6umUVj5LN(fM3$?xPU zv-S_b{$=s-t4jbDMTRDJF3vwkm7Dh(QY8e|$f7^`g!fhv6El#r({H)#U#YKMZqbnoV67>D-N^lc{9v)WaQ_>& zvZ1XR=&$r>k~sgO2{73uVDa(2Z~BD#KSBST%a^(sO=(2y{{-+OP~yqS5k-M2Xo^h}w=YD?N-|0X}Fc+v=G z%c1y2r^jHVs5VhPd2=x+cOJgPJKck=WXNoF+W%V3kfC62L9C{=^-Z`lcE0mf{@C2S z2DAF^9&9S}MpnFhy1hT2G->S5IdiZbzXgw{7yqUyv6E(d+^9|Db-R3-WuXwZh!%U$ z?A-qT*AYq9U>ipVvE6h22WG2th<=s~QT>X{63Hz>?e{M51`M;~*J-C)Phn1Pg;I2` z?6(+DGh9WUJd$$ACM5hplN!>?ufj9eBQnwnfnEjT@<-OxEM#absOml+yE*`+Dxee{ zfb)vPsh;$edGm5h5mRh5JCibN{o`0w$6&_O*D#|Yh5aEkGBQLb8=~yZmoKEkgjJYu znW_trCGv=&!Hnu7g;OgM9L1!7gx~G=l)Bhk*Vg2!jI;RfMI9nn+)7U=yayerTj7zip-bd1 z53(@6ZfTq90nr5WVxdqUDSY(B1nrhQ;0fjjLj|6Z{vd8>OM`wN3q*RtV)8>iju&~z zG~EYFM!(T-)d_)A*Xg3xiPFU|kx3tgH(5cD-wx=xNadv==8_wT65`;-3-|>u`Fcoz zIR<;s_Z%}t;P{_~Wz~MR^V#`Nfn+AyXjNw7&(mKPkU1X#$5|rh2)Sdrv`fN(U4ZS2 zxtT%1H;KU8e&v%@r>=42eo5m{}My;I%^p$AiDVAlct@V#c zZD4Wcd0hp;fXl~qguyAFOkD<=kDwHNbCJGAgw8H(+@I8Q)EHnFW22Husq?^E5&W3r zMz=$ut&f1P0)+H-cIVr7N@#7$0;%s0kf47u$|>x7uu@4&OsWcD`)yenWsqXRZq ziV(yevy#;jBNOnecdc3Ek~XZ+`x*vcCbNY!I?mqvo&cP|ow;5-JEzY|k|!q~Os{<# zL`dwMxW~j!<7WffhlW#<`rvZ^eE}V0_;TD#g`HdwWX zlfOL*hI%wQ^bY(ub{3OiI&h&d8!^^_#g#d)kJ~LqqK_yRHY>kW`XzBY9~ylLK73Cc zL}o_oURQP3E>K_`n4!5|7YB`r)yyMA`(7~?L!7iQoq2@lw?AGsGyAQ+*>yYeCk{Uv z9U;mO#>-`5L=qIhB0t)xhy?BlN9?G$$E?SWJ^fi8vNKM!VNqc6Lkce!1C-BOoVY?j z6iEk=f5;D!H06Yyq@<1|8-`ETEqu5a!u<#|TG07Ic&_4NUj;AdZmpa;xhp_ZVF5b( z_I-nhpsq43Qu2!?PPclq&Lc`|8h7O!OmY!zxMC3el)~waB1CRf5c0@HJz3j4n4g^0 ziv83zv=J1t2f116x{k!wZgQ`J7c)4+SfBdDjkbI6O9|MjX?H8~3GlQSwEEg02R-d4 z?~+>Bz5%wU7lq$12%$$3?ly)mN=lk}9;P{qMjO8Ek_Zd3`+1RC(X8Rw>hy~3rEu~U z5oBFNv-Tafz_mt{)ht4!mAhtDV9W7p$Sqfekd@-REHGQTRs-&TO&C}!WNUzD%D!sw znJwb*N)cEVouDbvYoG!xCsGz(w?pTi3E4`i3Z@jU7X#EzRGfLF7Z+10`jB9|{boX> z3X_$Fcc4KF`ETsZ#}-RI3mOxfY?)03RSF*xg%nGxu+=R!qMCNDA$4|$%C0*PakC$6 zVM&c*!{34wF=s&7DvcWF;aj4dcDXvXK%&M`jk7wZ1fbD$y7f?3F44-r=-Bb$Z7xx? z>>7)+gQ-%e3H+TUj+iI0r2sYb#(%A(v~wS}#-4`zwIh*d=BW1C0zxY8v9@4~*J-E? z9js7e_C&VYn?}?z(UQo{{n(0X8gQE>u%OQ|HOn;g8yyps3T8QzJK<&>7i{ Date: Tue, 3 Nov 2026 09:03:09 +0100 Subject: [PATCH 06/14] Refine mooring barrel and full Create casing body beneath original lid (0.2.1) --- .github/workflows/neoforge-1.21.1.yml | 6 +- CHANGELOG.md | 9 + README.md | 8 +- build.gradle | 4 +- docs/WATER-ENGINEERING.md | 8 +- .../resources/META-INF/neoforge.mods.toml | 2 +- .../block/mechanical_current_generator.json | 316 +++++++++++++-- ...mechanical_current_generator_diagonal.json | 316 +++++++++++++-- .../models/block/mooring_post.json | 205 +++++----- .../item/mechanical_current_generator.json | 367 +++++++++++++++--- .../textures/block/mooring_post_bottom.png | Bin 658 -> 0 bytes .../textures/block/mooring_post_side.png | Bin 620 -> 0 bytes .../textures/block/mooring_post_top.png | Bin 683 -> 0 bytes 13 files changed, 1032 insertions(+), 209 deletions(-) delete mode 100644 src/main/resources/assets/streamcontrol/textures/block/mooring_post_bottom.png delete mode 100644 src/main/resources/assets/streamcontrol/textures/block/mooring_post_side.png delete mode 100644 src/main/resources/assets/streamcontrol/textures/block/mooring_post_top.png diff --git a/.github/workflows/neoforge-1.21.1.yml b/.github/workflows/neoforge-1.21.1.yml index 48fff85..83118a2 100644 --- a/.github/workflows/neoforge-1.21.1.yml +++ b/.github/workflows/neoforge-1.21.1.yml @@ -52,7 +52,7 @@ jobs: - name: Upload test JAR uses: actions/upload-artifact@v4 with: - name: flow-control-0.2.0-neoforge-1.21.1-${{ matrix.flavor }} + name: flow-control-0.2.1-neoforge-1.21.1-${{ matrix.flavor }} path: build/libs/flow-control-*.jar if-no-files-found: error @@ -73,7 +73,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: flow-control-0.2.0-neoforge-1.21.1-${{ matrix.flavor }}-checks + name: flow-control-0.2.1-neoforge-1.21.1-${{ matrix.flavor }}-checks path: | run/streamcontrol-integration-results.json run/logs/latest.log @@ -95,7 +95,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: flow-control-0.2.0-${{ matrix.flavor }}-client-preview + name: flow-control-0.2.1-${{ matrix.flavor }}-client-preview path: | run-client/screenshots/*.png run-client/logs/latest.log diff --git a/CHANGELOG.md b/CHANGELOG.md index dfc788e..ad73976 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ ![Flow Control](https://i.imgur.com/JGT2lvz.png) +## 0.2.1 — Barrel and Create Model Refinement + +- Kept the original control lid on the Mechanical Current Generator and replaced its entire body with native Create Andesite Casing textures. +- Added a recessed bottom shaft socket and matched the inventory shaft to Create's actual shaft geometry and end texture. +- Rebuilt the Mooring Post as a compact barrel with straight staves, native barrel hoops, a wooden lid and subtly chamfered corners. +- Removed the old recolored machine textures from the Mooring Post. +- Preserved all water-control, sensor, mooring and Create behavior. + + ## 0.2.0 — Water Engineering - Repurposed the Flow Wand as the Flow Calibrator: inspect currents, show horizontal/vertical reach, copy and paste settings, and link controllers. diff --git a/README.md b/README.md index 9a487b6..8b01174 100644 --- a/README.md +++ b/README.md @@ -8,21 +8,21 @@ Shape currents and create calm water around docks, canals and builds. An addon for **Streams Reflowing**, available for NeoForge, Forge and Fabric. -## Water Engineering — 0.2.0 +## Water Engineering — 0.2.1 Turn waterways into configurable transport and docking systems. The Flow Calibrator inspects currents, displays reach, copies settings and links controllers. Two saved profiles add analog redstone control, reversal and automatic switching. Flow Sensors detect current strength, direction or boats through configurable horizontal and vertical ranges. Mooring Posts secure empty boats and release them when boarded or powered. With **Create** installed, the **Mechanical Current Generator** accepts a bottom shaft: RPM sets strength, rotation direction reverses flow, and stopped or overstressed drives release their override. The standard controllers, sensors, posts and Calibrator work without Create. -The existing controller model family is retained, with steel-blue sensor colors, wooden mooring posts and an andesite base for the mechanical variant. Existing Flow Wands become Calibrators; saved controller settings and old edits are preserved. +The existing controller model family is retained, with steel-blue sensor colors, barrel-style mooring posts and a full andesite casing body beneath the original mechanical control lid. Existing Flow Wands become Calibrators; saved controller settings and old edits are preserved. | Minecraft | Loader | Java | Streams Reflowing | Optional Create | Download | | --- | --- | --- | --- | --- | --- | -| 1.21.1 | NeoForge 21.1.219+ within 21.1 | 21 | 2.16.2 | Tested with 6.0.10 | [0.2.0 JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/feature/water-engineering/downloads/flow-control-0.2.0-neoforge-1.21.1.jar) | +| 1.21.1 | NeoForge 21.1.219+ within 21.1 | 21 | 2.16.2 | Tested with 6.0.10 | [0.2.1 JAR](https://github.com/Mikaaah/Flow-Control/raw/refs/heads/feature/water-engineering/downloads/flow-control-0.2.1-neoforge-1.21.1.jar) | [Controls and behavior](docs/WATER-ENGINEERING.md) · [Feature branch](https://github.com/Mikaaah/Flow-Control/tree/feature/water-engineering) · [Build and regression checks](https://github.com/Mikaaah/Flow-Control/actions/runs/41593515484) -The 0.2.0 feature update currently targets NeoForge 1.21.1. Earlier downloads and other loader branches remain unchanged. Use matching client/server versions. +The 0.2.1 feature update currently targets NeoForge 1.21.1. Earlier downloads and other loader branches remain unchanged. Use matching client/server versions. ## Make water work for your build diff --git a/build.gradle b/build.gradle index 242cb1f..c962d22 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'java-library' id 'net.neoforged.moddev' version '2.0.148' } -version = '0.2.0' +version = '0.2.1' group = 'nl.townsandkingdoms.streamcontrol' base.archivesName = 'flow-control' java.toolchain.languageVersion = JavaLanguageVersion.of(21) @@ -45,4 +45,4 @@ dependencies { tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8'; options.release = 21 } tasks.named('jar') { from('LICENSE') } -tasks.named("jar") { archiveFileName = "flow-control-0.2.0-neoforge-1.21.1.jar" } +tasks.named("jar") { archiveFileName = "flow-control-0.2.1-neoforge-1.21.1.jar" } diff --git a/docs/WATER-ENGINEERING.md b/docs/WATER-ENGINEERING.md index 87985e7..2438565 100644 --- a/docs/WATER-ENGINEERING.md +++ b/docs/WATER-ENGINEERING.md @@ -1,4 +1,4 @@ -# Flow Control 0.2.0 — Water Engineering +# Flow Control 0.2.1 — Water Engineering | Minecraft | Loader | Java | Required | Optional integration tested | | --- | --- | --- | --- | --- | @@ -52,13 +52,13 @@ Vertical reach applies to both water sampling and boat detection. Comparator out ## Mooring Post -A post automatically secures one empty boat already inside its configured cylinder. It holds horizontal position while preserving vertical bobbing. It does not pull boats from outside its range or keep an occupied boat captive. +The barrel-style post uses native wooden staves and barrel hoops. It automatically secures one empty boat already inside its configured cylinder. It holds horizontal position while preserving vertical bobbing. It does not pull boats from outside its range or keep an occupied boat captive. Boarding, redstone power, disabling automatic mooring or breaking the post releases the boat. A short cooldown prevents immediate recapture. Multiple posts cannot hold the same boat. Defaults are radius 4 and vertical reach ±2; both are configurable in the GUI within server limits. ## Optional Create support -The Mechanical Current Generator uses the original Current Generator body above an andesite casing base, with a rotating shaft input on its bottom face. Its recipe uses a Current Generator, Andesite Casing and Shaft. +The Mechanical Current Generator keeps the original control lid over a fully Create-textured Andesite Casing body, with a recessed rotating shaft input on its bottom face. Its recipe uses a Current Generator, Andesite Casing and Shaft. Connect a real Create shaft or drive below it. The default calibration is 128 RPM for 100% of the configured profile strength; 64 RPM gives half strength and 256 RPM gives double, limited by the server maximum. Negative RPM reverses the current. Low RPM remains proportionally weak rather than jumping to the manual 5% minimum. The default stress impact is 4 SU per RPM. @@ -68,6 +68,6 @@ A stopped or overstressed drive releases its override. The controller supports t Existing controller settings are loaded into Profile A. Old wand regions remain editable through the cleanup mode and `/streamcontrol clear` for operators. `/streamcontrol status` remains available. The old wand radius/strength commands are replaced by GUI profile editing. -Use matching Flow Control 0.2.0 versions on client and server because the settings packet protocol changed. The original `wandEnabled`, `wandRequiresOperator` and `showWandFeedbackParticles` configuration keys are retained for compatibility; they now control the Calibrator and its range outlines. +Use matching Flow Control 0.2.1 versions on client and server because the settings packet protocol changed. The original `wandEnabled`, `wandRequiresOperator` and `showWandFeedbackParticles` configuration keys are retained for compatibility; they now control the Calibrator and its range outlines. Both standalone and Create 6.0.10 builds passed compilation and the dedicated-server suite. Tests cover legacy flow behavior, profiles and migration, linking and loop rejection, Calibrator copy/paste/link/cleanup, sensor vertical and horizontal limits, comparator output, occupied boats, mooring release and cooldown, packet round trips, optional registration/recipes, and a real Create motor network including reversal, low RPM, stress and stopping. Actual Minecraft screenshots cover eight GUI/model states with and without Create. This is not a full TNK pack or interactive client-world playtest. diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml index cf01997..279b31d 100644 --- a/src/main/resources/META-INF/neoforge.mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -4,7 +4,7 @@ license="GPL-3.0-only" issueTrackerURL="https://github.com/Mikaaah/Streams-Flow-Control/issues" [[mods]] modId="streamcontrol" -version="0.2.0" +version="0.2.1" displayName="Streams Flow Control" authors="Mikaaah / Towns & Kingdoms" displayURL="https://github.com/Mikaaah/Streams-Flow-Control" diff --git a/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator.json b/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator.json index a6c97d9..9e62e4f 100644 --- a/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator.json +++ b/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator.json @@ -1,10 +1,10 @@ { "parent": "minecraft:block/block", "textures": { - "body": "streamcontrol:block/current_generator_side", + "lid": "streamcontrol:block/current_generator_side", "top": "streamcontrol:block/current_generator_top", "casing": "create:block/andesite_casing", - "particle": "streamcontrol:block/current_generator_side" + "particle": "create:block/andesite_casing" }, "elements": [ { @@ -15,17 +15,44 @@ ], "to": [ 16, - 6, + 12, 16 ], "faces": { - "down": { + "north": { "texture": "#casing", "uv": [ 0, + 4, + 16, + 14 + ] + }, + "south": { + "texture": "#casing", + "uv": [ 0, + 4, 16, - 16 + 14 + ] + }, + "west": { + "texture": "#casing", + "uv": [ + 0, + 4, + 16, + 14 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 0, + 4, + 16, + 14 ] }, "up": { @@ -37,7 +64,7 @@ 16 ] }, - "north": { + "down": { "texture": "#casing", "uv": [ 0, @@ -45,31 +72,72 @@ 16, 16 ] + } + } + }, + { + "from": [ + 0, + 0, + 0 + ], + "to": [ + 16, + 2, + 5 + ], + "faces": { + "north": { + "texture": "#casing", + "uv": [ + 0, + 14, + 16, + 16 + ] }, "south": { "texture": "#casing", "uv": [ 0, - 0, + 14, 16, 16 ] }, - "east": { + "west": { "texture": "#casing", "uv": [ 0, - 0, + 14, + 5, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 11, + 14, 16, 16 ] }, - "west": { + "up": { "texture": "#casing", "uv": [ 0, 0, 16, + 5 + ] + }, + "down": { + "texture": "#casing", + "uv": [ + 0, + 11, + 16, 16 ] } @@ -78,53 +146,257 @@ { "from": [ 0, - 6, - 0 + 0, + 11 ], "to": [ 16, - 16, + 2, 16 ], "faces": { + "north": { + "texture": "#casing", + "uv": [ + 0, + 14, + 16, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 0, + 14, + 16, + 16 + ] + }, + "west": { + "texture": "#casing", + "uv": [ + 11, + 14, + 16, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 0, + 14, + 5, + 16 + ] + }, + "up": { + "texture": "#casing", + "uv": [ + 0, + 11, + 16, + 16 + ] + }, "down": { - "texture": "#body", + "texture": "#casing", "uv": [ 0, 0, 16, + 5 + ] + } + } + }, + { + "from": [ + 0, + 0, + 5 + ], + "to": [ + 5, + 2, + 11 + ], + "faces": { + "north": { + "texture": "#casing", + "uv": [ + 11, + 14, + 16, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 0, + 14, + 5, + 16 + ] + }, + "west": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, 16 ] }, "up": { - "texture": "#top", + "texture": "#casing", "uv": [ 0, + 5, + 5, + 11 + ] + }, + "down": { + "texture": "#casing", + "uv": [ 0, + 5, + 5, + 11 + ] + } + } + }, + { + "from": [ + 11, + 0, + 5 + ], + "to": [ + 16, + 2, + 11 + ], + "faces": { + "north": { + "texture": "#casing", + "uv": [ + 0, + 14, + 5, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 11, + 14, 16, 16 ] }, + "west": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, + 16 + ] + }, + "up": { + "texture": "#casing", + "uv": [ + 11, + 5, + 16, + 11 + ] + }, + "down": { + "texture": "#casing", + "uv": [ + 11, + 5, + 16, + 11 + ] + } + } + }, + { + "from": [ + 0, + 12, + 0 + ], + "to": [ + 16, + 16, + 16 + ], + "faces": { "north": { - "texture": "#body", + "texture": "#lid", "uv": [ 0, 0, 16, - 16 + 4 ] }, "south": { - "texture": "#body", + "texture": "#lid", "uv": [ 0, 0, 16, - 16 + 4 + ] + }, + "west": { + "texture": "#lid", + "uv": [ + 0, + 0, + 16, + 4 ] }, "east": { - "texture": "#body", + "texture": "#lid", + "uv": [ + 0, + 0, + 16, + 4 + ] + }, + "up": { + "texture": "#top", "uv": [ 0, 0, @@ -132,8 +404,8 @@ 16 ] }, - "west": { - "texture": "#body", + "down": { + "texture": "#casing", "uv": [ 0, 0, diff --git a/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator_diagonal.json b/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator_diagonal.json index ae034f3..a3465b6 100644 --- a/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator_diagonal.json +++ b/src/main/resources/assets/streamcontrol/models/block/mechanical_current_generator_diagonal.json @@ -1,10 +1,10 @@ { "parent": "minecraft:block/block", "textures": { - "body": "streamcontrol:block/current_generator_side", + "lid": "streamcontrol:block/current_generator_side", "top": "streamcontrol:block/current_generator_top_diagonal", "casing": "create:block/andesite_casing", - "particle": "streamcontrol:block/current_generator_side" + "particle": "create:block/andesite_casing" }, "elements": [ { @@ -15,17 +15,44 @@ ], "to": [ 16, - 6, + 12, 16 ], "faces": { - "down": { + "north": { "texture": "#casing", "uv": [ 0, + 4, + 16, + 14 + ] + }, + "south": { + "texture": "#casing", + "uv": [ 0, + 4, 16, - 16 + 14 + ] + }, + "west": { + "texture": "#casing", + "uv": [ + 0, + 4, + 16, + 14 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 0, + 4, + 16, + 14 ] }, "up": { @@ -37,7 +64,7 @@ 16 ] }, - "north": { + "down": { "texture": "#casing", "uv": [ 0, @@ -45,31 +72,72 @@ 16, 16 ] + } + } + }, + { + "from": [ + 0, + 0, + 0 + ], + "to": [ + 16, + 2, + 5 + ], + "faces": { + "north": { + "texture": "#casing", + "uv": [ + 0, + 14, + 16, + 16 + ] }, "south": { "texture": "#casing", "uv": [ 0, - 0, + 14, 16, 16 ] }, - "east": { + "west": { "texture": "#casing", "uv": [ 0, - 0, + 14, + 5, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 11, + 14, 16, 16 ] }, - "west": { + "up": { "texture": "#casing", "uv": [ 0, 0, 16, + 5 + ] + }, + "down": { + "texture": "#casing", + "uv": [ + 0, + 11, + 16, 16 ] } @@ -78,53 +146,257 @@ { "from": [ 0, - 6, - 0 + 0, + 11 ], "to": [ 16, - 16, + 2, 16 ], "faces": { + "north": { + "texture": "#casing", + "uv": [ + 0, + 14, + 16, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 0, + 14, + 16, + 16 + ] + }, + "west": { + "texture": "#casing", + "uv": [ + 11, + 14, + 16, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 0, + 14, + 5, + 16 + ] + }, + "up": { + "texture": "#casing", + "uv": [ + 0, + 11, + 16, + 16 + ] + }, "down": { - "texture": "#body", + "texture": "#casing", "uv": [ 0, 0, 16, + 5 + ] + } + } + }, + { + "from": [ + 0, + 0, + 5 + ], + "to": [ + 5, + 2, + 11 + ], + "faces": { + "north": { + "texture": "#casing", + "uv": [ + 11, + 14, + 16, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 0, + 14, + 5, + 16 + ] + }, + "west": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, 16 ] }, "up": { - "texture": "#top", + "texture": "#casing", "uv": [ 0, + 5, + 5, + 11 + ] + }, + "down": { + "texture": "#casing", + "uv": [ 0, + 5, + 5, + 11 + ] + } + } + }, + { + "from": [ + 11, + 0, + 5 + ], + "to": [ + 16, + 2, + 11 + ], + "faces": { + "north": { + "texture": "#casing", + "uv": [ + 0, + 14, + 5, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 11, + 14, 16, 16 ] }, + "west": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, + 16 + ] + }, + "up": { + "texture": "#casing", + "uv": [ + 11, + 5, + 16, + 11 + ] + }, + "down": { + "texture": "#casing", + "uv": [ + 11, + 5, + 16, + 11 + ] + } + } + }, + { + "from": [ + 0, + 12, + 0 + ], + "to": [ + 16, + 16, + 16 + ], + "faces": { "north": { - "texture": "#body", + "texture": "#lid", "uv": [ 0, 0, 16, - 16 + 4 ] }, "south": { - "texture": "#body", + "texture": "#lid", "uv": [ 0, 0, 16, - 16 + 4 + ] + }, + "west": { + "texture": "#lid", + "uv": [ + 0, + 0, + 16, + 4 ] }, "east": { - "texture": "#body", + "texture": "#lid", + "uv": [ + 0, + 0, + 16, + 4 + ] + }, + "up": { + "texture": "#top", "uv": [ 0, 0, @@ -132,8 +404,8 @@ 16 ] }, - "west": { - "texture": "#body", + "down": { + "texture": "#casing", "uv": [ 0, 0, diff --git a/src/main/resources/assets/streamcontrol/models/block/mooring_post.json b/src/main/resources/assets/streamcontrol/models/block/mooring_post.json index 25c3e28..23b6848 100644 --- a/src/main/resources/assets/streamcontrol/models/block/mooring_post.json +++ b/src/main/resources/assets/streamcontrol/models/block/mooring_post.json @@ -1,215 +1,212 @@ { "parent": "minecraft:block/block", "textures": { - "down": "streamcontrol:block/mooring_post_bottom", - "up": "streamcontrol:block/mooring_post_top", - "north": "streamcontrol:block/mooring_post_side", - "south": "streamcontrol:block/mooring_post_side", - "east": "streamcontrol:block/mooring_post_side", - "west": "streamcontrol:block/mooring_post_side", - "particle": "streamcontrol:block/mooring_post_side" + "side": "minecraft:block/barrel_side", + "top": "minecraft:block/barrel_top", + "bottom": "minecraft:block/barrel_bottom", + "particle": "minecraft:block/barrel_side" }, "elements": [ { "from": [ - 1, + 2, 0, 1 ], "to": [ - 15, - 3, + 14, + 16, 15 ], "faces": { - "down": { - "texture": "#down", + "north": { + "texture": "#side", "uv": [ + 2, 0, - 0, - 16, + 14, 16 ] }, - "up": { - "texture": "#up", + "south": { + "texture": "#side", "uv": [ + 2, 0, - 0, - 16, + 14, 16 ] }, - "north": { - "texture": "#north", + "west": { + "texture": "#side", "uv": [ + 1, 0, - 0, - 16, + 15, 16 ] }, - "south": { - "texture": "#south", + "east": { + "texture": "#side", "uv": [ + 1, 0, - 0, - 16, + 15, 16 ] }, - "east": { - "texture": "#east", + "up": { + "texture": "#top", "uv": [ - 0, - 0, - 16, - 16 + 2, + 1, + 14, + 15 ] }, - "west": { - "texture": "#west", + "down": { + "texture": "#bottom", "uv": [ - 0, - 0, - 16, - 16 + 2, + 1, + 14, + 15 ] } } }, { "from": [ - 3, - 3, - 3 + 1, + 0, + 2 ], "to": [ - 13, - 13, - 13 + 2, + 16, + 14 ], "faces": { - "down": { - "texture": "#down", + "north": { + "texture": "#side", "uv": [ + 14, 0, - 0, - 16, + 15, 16 ] }, - "up": { - "texture": "#up", + "south": { + "texture": "#side", "uv": [ + 1, 0, - 0, - 16, + 2, 16 ] }, - "north": { - "texture": "#north", + "west": { + "texture": "#side", "uv": [ + 2, 0, - 0, - 16, + 14, 16 ] }, - "south": { - "texture": "#south", + "east": { + "texture": "#side", "uv": [ + 2, 0, - 0, - 16, + 14, 16 ] }, - "east": { - "texture": "#east", + "up": { + "texture": "#top", "uv": [ - 0, - 0, - 16, - 16 + 1, + 2, + 2, + 14 ] }, - "west": { - "texture": "#west", + "down": { + "texture": "#bottom", "uv": [ - 0, - 0, - 16, - 16 + 1, + 2, + 2, + 14 ] } } }, { "from": [ - 1, - 13, - 1 + 14, + 0, + 2 ], "to": [ 15, 16, - 15 + 14 ], "faces": { - "down": { - "texture": "#down", + "north": { + "texture": "#side", "uv": [ + 1, 0, - 0, - 16, + 2, 16 ] }, - "up": { - "texture": "#up", + "south": { + "texture": "#side", "uv": [ + 14, 0, - 0, - 16, + 15, 16 ] }, - "north": { - "texture": "#north", + "west": { + "texture": "#side", "uv": [ + 2, 0, - 0, - 16, + 14, 16 ] }, - "south": { - "texture": "#south", + "east": { + "texture": "#side", "uv": [ + 2, 0, - 0, - 16, + 14, 16 ] }, - "east": { - "texture": "#east", + "up": { + "texture": "#top", "uv": [ - 0, - 0, - 16, - 16 + 14, + 2, + 15, + 14 ] }, - "west": { - "texture": "#west", + "down": { + "texture": "#bottom", "uv": [ - 0, - 0, - 16, - 16 + 14, + 2, + 15, + 14 ] } } diff --git a/src/main/resources/assets/streamcontrol/models/item/mechanical_current_generator.json b/src/main/resources/assets/streamcontrol/models/item/mechanical_current_generator.json index 8526ea4..c8fa4da 100644 --- a/src/main/resources/assets/streamcontrol/models/item/mechanical_current_generator.json +++ b/src/main/resources/assets/streamcontrol/models/item/mechanical_current_generator.json @@ -1,63 +1,132 @@ { "parent": "minecraft:block/block", "textures": { - "body": "streamcontrol:block/current_generator_side", + "lid": "streamcontrol:block/current_generator_side", "top": "streamcontrol:block/current_generator_top", "casing": "create:block/andesite_casing", - "particle": "streamcontrol:block/current_generator_side", - "shaft": "create:block/axis" + "particle": "create:block/andesite_casing", + "shaft": "create:block/axis", + "shaft_end": "create:block/axis_top" }, "elements": [ { "from": [ - 5, + 6, 0, - 5 + 6 ], "to": [ - 11, + 10, 2, - 11 + 10 ], "faces": { - "down": { + "north": { "texture": "#shaft", "uv": [ - 0, - 0, - 16, + 6, + 14, + 10, 16 ] }, - "up": { + "south": { "texture": "#shaft", "uv": [ - 0, - 0, - 16, + 6, + 14, + 10, 16 ] }, - "north": { + "west": { "texture": "#shaft", + "uv": [ + 6, + 14, + 10, + 16 + ] + }, + "east": { + "texture": "#shaft", + "uv": [ + 6, + 14, + 10, + 16 + ] + }, + "up": { + "texture": "#shaft_end", + "uv": [ + 6, + 6, + 10, + 10 + ] + }, + "down": { + "texture": "#shaft_end", + "uv": [ + 6, + 6, + 10, + 10 + ] + } + } + }, + { + "from": [ + 0, + 2, + 0 + ], + "to": [ + 16, + 12, + 16 + ], + "faces": { + "north": { + "texture": "#casing", "uv": [ 0, - 0, + 4, 16, - 16 + 14 ] }, "south": { - "texture": "#shaft", + "texture": "#casing", "uv": [ 0, + 4, + 16, + 14 + ] + }, + "west": { + "texture": "#casing", + "uv": [ 0, + 4, 16, - 16 + 14 ] }, "east": { - "texture": "#shaft", + "texture": "#casing", + "uv": [ + 0, + 4, + 16, + 14 + ] + }, + "up": { + "texture": "#casing", "uv": [ 0, 0, @@ -65,8 +134,8 @@ 16 ] }, - "west": { - "texture": "#shaft", + "down": { + "texture": "#casing", "uv": [ 0, 0, @@ -79,20 +148,47 @@ { "from": [ 0, - 2, + 0, 0 ], "to": [ 16, - 6, - 16 + 2, + 5 ], "faces": { - "down": { + "north": { "texture": "#casing", "uv": [ 0, + 14, + 16, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 0, + 14, + 16, + 16 + ] + }, + "west": { + "texture": "#casing", + "uv": [ 0, + 14, + 5, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 11, + 14, 16, 16 ] @@ -103,14 +199,37 @@ 0, 0, 16, - 16 + 5 ] }, - "north": { + "down": { "texture": "#casing", "uv": [ 0, + 11, + 16, + 16 + ] + } + } + }, + { + "from": [ + 0, + 0, + 11 + ], + "to": [ + 16, + 2, + 16 + ], + "faces": { + "north": { + "texture": "#casing", + "uv": [ 0, + 14, 16, 16 ] @@ -119,7 +238,16 @@ "texture": "#casing", "uv": [ 0, - 0, + 14, + 16, + 16 + ] + }, + "west": { + "texture": "#casing", + "uv": [ + 11, + 14, 16, 16 ] @@ -128,26 +256,171 @@ "texture": "#casing", "uv": [ 0, + 14, + 5, + 16 + ] + }, + "up": { + "texture": "#casing", + "uv": [ + 0, + 11, + 16, + 16 + ] + }, + "down": { + "texture": "#casing", + "uv": [ 0, + 0, + 16, + 5 + ] + } + } + }, + { + "from": [ + 0, + 0, + 5 + ], + "to": [ + 5, + 2, + 11 + ], + "faces": { + "north": { + "texture": "#casing", + "uv": [ + 11, + 14, 16, 16 ] }, + "south": { + "texture": "#casing", + "uv": [ + 0, + 14, + 5, + 16 + ] + }, "west": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, + 16 + ] + }, + "up": { + "texture": "#casing", + "uv": [ + 0, + 5, + 5, + 11 + ] + }, + "down": { "texture": "#casing", "uv": [ 0, + 5, + 5, + 11 + ] + } + } + }, + { + "from": [ + 11, + 0, + 5 + ], + "to": [ + 16, + 2, + 11 + ], + "faces": { + "north": { + "texture": "#casing", + "uv": [ 0, + 14, + 5, + 16 + ] + }, + "south": { + "texture": "#casing", + "uv": [ + 11, + 14, 16, 16 ] + }, + "west": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, + 16 + ] + }, + "east": { + "texture": "#casing", + "uv": [ + 5, + 14, + 11, + 16 + ] + }, + "up": { + "texture": "#casing", + "uv": [ + 11, + 5, + 16, + 11 + ] + }, + "down": { + "texture": "#casing", + "uv": [ + 11, + 5, + 16, + 11 + ] } } }, { "from": [ 0, - 6, + 12, 0 ], "to": [ @@ -156,44 +429,44 @@ 16 ], "faces": { - "down": { - "texture": "#body", + "north": { + "texture": "#lid", "uv": [ 0, 0, 16, - 16 + 4 ] }, - "up": { - "texture": "#top", + "south": { + "texture": "#lid", "uv": [ 0, 0, 16, - 16 + 4 ] }, - "north": { - "texture": "#body", + "west": { + "texture": "#lid", "uv": [ 0, 0, 16, - 16 + 4 ] }, - "south": { - "texture": "#body", + "east": { + "texture": "#lid", "uv": [ 0, 0, 16, - 16 + 4 ] }, - "east": { - "texture": "#body", + "up": { + "texture": "#top", "uv": [ 0, 0, @@ -201,8 +474,8 @@ 16 ] }, - "west": { - "texture": "#body", + "down": { + "texture": "#casing", "uv": [ 0, 0, diff --git a/src/main/resources/assets/streamcontrol/textures/block/mooring_post_bottom.png b/src/main/resources/assets/streamcontrol/textures/block/mooring_post_bottom.png deleted file mode 100644 index a6ae5afbf62317fb4906e96272d62406f526486f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 658 zcmV;D0&V??P)08|hdbVYs zH}S)FUvU@R=#kn9@BZ82j0T{e0$X4TiB01GXb&U%-UDzLJpB{^sGT6)7zi=(>!0r_ ztsqL#9!9h(_;@=k-BQi~yngczBZ_C=d<;7dR{Z?p+Z5}Vo~Ry0;LAtpl1h*n4P zG?g{;m|78H;{F;gb{(}7YA38Khn#IH_Wi`*VN+XD&h%qoT{(&Zj8^!VFrom1(F&ys z?yoDhs}copwy6PFRhH5Sr|S|cY5@ZrIpn0atSifQRU*1TDl4oi%eE;|MS+!hg*%`R za~?yaafZ=HYB#SIVnzV2ZhAsWp8<2`$b2Nkj5V5lKePW~KX6i6HjP6r+m5-&z_xKq z$A0n*K2jP1GU?c0^pTurMXvWfa&Lku|(&?Fgx|o@sOz^C#ZgEeYbMCbsuQm&YSX*gw)CpOfuJHQf9%+^Xprqi@YLorn z0XOEVynMesYC*+mPABZs3Huy%LcSfG;2X`?gA?k$0iYZ9xwpK)ZmWxDG@A#<%vL?> zzCi$3)`0ED@fqzPVyD$%jDf)2R)_X!#BQsDmJ)z0FR<<}Un~9u5k)a3x_rI}%Np0F zTpRUl?GCc6T3cz-4kG3oUip}2IZ6sF ztf7gbtc@^N^O&i+j4S^^K|zvb{Y!w&rn-cNY?V5xjd z(tJ|E`o#ozFYJhI=?b0qh-h0r>L0O#xi3d;9}M9NhS;N3#L|0000D{lpIM-m60QX2Y_GhVVxSQu@|MZTUBOG4%2Q`=^iGuTUB(N z0bq)YhN-}a|=(HQG ze%)qyagM6;SYDhf!2V}qx>>Q^gM`2@0dTc5#g%gttUOy|d2xgVK^K zIclMfivtiI^!$~%38ehD8}1-s@V6UVA;(z(SR5(Ijp5a&pBQ6{hDF;Rs%5O+(*i*G zCCaX(>^kJeFxjY(W;sru!G4q?ORi*mBtY~vm}~@qpf!8~<+;?9M?LTXXblhHNXcZQ z!as!Z$xO8@myG!SJ`1}Je*1i|-e*xYk67I{( Ry5|4@002ovPDHLkV1oNoL#zM* From efb7fac299148aa6f01dc0ed5516cab1890e92ae Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 09:07:41 +0100 Subject: [PATCH 07/14] Publish verified 0.2.1 model update JAR and validation results [skip ci] --- docs/validation-0.2.1.json | 51 ++++++++++++++++++ downloads/SHA256SUMS-0.2.1.txt | 1 + .../flow-control-0.2.1-neoforge-1.21.1.jar | Bin 0 -> 223849 bytes 3 files changed, 52 insertions(+) create mode 100644 docs/validation-0.2.1.json create mode 100644 downloads/SHA256SUMS-0.2.1.txt create mode 100644 downloads/flow-control-0.2.1-neoforge-1.21.1.jar diff --git a/docs/validation-0.2.1.json b/docs/validation-0.2.1.json new file mode 100644 index 0000000..5676be2 --- /dev/null +++ b/docs/validation-0.2.1.json @@ -0,0 +1,51 @@ +{ + "source_commit": "d1aae5dd0d8596bff754d92b59faa03b8ff975e8", + "workflow_run": "https://github.com/Mikaaah/Flow-Control/actions/runs/41600440210", + "jar_sha256": "87191ee4b24f56f8e360553d415391345d9dd9b119223fd8272f96c7a4b0fdcc", + "checks": { + "standalone": { + "vanillaWaterAndVesselFlow": true, + "manualDirectionRetainsPriorityOverDownhillGuard": true, + "bakedWaterStillnessAndOverlap": true, + "mooredBoatTwentyTicks": true, + "savedDataRoundTrip": true, + "connectedWaterIsolationAndPersistence": true, + "networkCodecRoundTrip": true, + "dimensionIsolation": true, + "masterSwitch": true, + "controllerRedstoneAndRemoval": true, + "eightHeadingPhysicsPersistenceAndPackets": true, + "profileModesPersistenceAndMigration": true, + "controllerLinkPropagationCycleAndMissingSource": true, + "calibratorCopyPasteLinkAndLegacyCleanup": true, + "sensorVerticalHorizontalDirectionBoatAndComparator": true, + "mooringHoldBoardingRedstoneAndCooldown": true, + "engineeringPacketRoundTrips": true, + "standaloneWithoutCreate": true, + "passed": true + }, + "create_6_0_10": { + "vanillaWaterAndVesselFlow": true, + "manualDirectionRetainsPriorityOverDownhillGuard": true, + "bakedWaterStillnessAndOverlap": true, + "mooredBoatTwentyTicks": true, + "savedDataRoundTrip": true, + "connectedWaterIsolationAndPersistence": true, + "networkCodecRoundTrip": true, + "dimensionIsolation": true, + "masterSwitch": true, + "controllerRedstoneAndRemoval": true, + "eightHeadingPhysicsPersistenceAndPackets": true, + "profileModesPersistenceAndMigration": true, + "controllerLinkPropagationCycleAndMissingSource": true, + "calibratorCopyPasteLinkAndLegacyCleanup": true, + "sensorVerticalHorizontalDirectionBoatAndComparator": true, + "mooringHoldBoardingRedstoneAndCooldown": true, + "engineeringPacketRoundTrips": true, + "createRealNetworkRpmReverseStressAndStop": true, + "passed": true + } + }, + "model_capture_checked": true, + "full_modpack_playtest": false +} diff --git a/downloads/SHA256SUMS-0.2.1.txt b/downloads/SHA256SUMS-0.2.1.txt new file mode 100644 index 0000000..22db6de --- /dev/null +++ b/downloads/SHA256SUMS-0.2.1.txt @@ -0,0 +1 @@ +87191ee4b24f56f8e360553d415391345d9dd9b119223fd8272f96c7a4b0fdcc flow-control-0.2.1-neoforge-1.21.1.jar diff --git a/downloads/flow-control-0.2.1-neoforge-1.21.1.jar b/downloads/flow-control-0.2.1-neoforge-1.21.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..8252d150ca85299386e53eea7846dcff27208632 GIT binary patch literal 223849 zcmbrl1CTC3)TY_CZQHhO+qUh#ZR57>uWj45`?hV{efQ4J?9BfE#BS`&MpRZ+RGiEc zkr8$B&F7p{k_81r0|J7A0s;aO{?~wjK>p7=5D@ggr@XkDFuk;b1S2Sr(tj{)31k%C=bBWQmRa|X4~{|p(_sJl z|97vT|K1(!{wII`ca#6(@1KdAqo;$bv4fedwS%RZqrL0@Yaf#Thd!=uF6PGerj8D7 zE{^}RSD)*JRKICOxgIup~;1 z0QKe~kP9K%sfU4MmkzgQVgLE`+K(dJ^W-T=LcL+fd}$n;g7Is*6w#(SaAh4*&zhNytF8V6(&+E%HUcZ&<7qG78bJ-b0Mk6y@OH$E|NWKo^ zJiLDs`E;#wDBvZKVAQbHDkhDN0LNe~phu$9;a+N?^a8~_&9j&VpY|2JeN!*ETDp$} zF}Ifva>F;l*{L$+-=Ummi+SRzv!9kd3eBX|^+kYfMjnaUB!fWnfpoL$m)Kxq#Rgta z&Cq25-6oZBXo`O|O_aD^eEDkk-J&IOw5*D^|D&LUR@2RDd|e+yzN2re`FdTdHcvQz zFFc%y-L;2M0mLus3|=ScPF5eoegQsvwY|3Dzc*XHU2Ixs`MX@MbM-A?#7|E0LBm3Z znQ)ESjW+rIR#IjtG9L7;UTDZ}xJ!<+s?nuf%^t+r9hh*%8L8MzwQrI@*@~-#v}XEa ze5Vd8Eq;hKHpRru{SRv_vigtYiuwuIM<-N2xZ@88Sh(`9Vq?8A)IEAZFHdq3q}eP$ z&AQ8eIZe&+W3V&EG3jJXRdFnIkdH(Usb(vybUJ{#{u5!+)q^tEgn<=b*Xw?Il{q^gZI=J22BC6Xu;P%_E1Z2`LplTI`EhkFF?jaW&5yv)D79T-kUG}84hg*Q z29y__ptt1iu3E@%XBk2JT=FUmci5h(@V-VNyex{WyrC;c&R8an7CG?~Lylmc<~ z)Vg$TrqcA4{HDc}RuRywja2_P@Y|>LK$`*50|v^2);X3?Bh`pvBpI&Q2>+1$?OJ5? zAT6PXQ(a%8aw@>#q;kb+t*{XvP!s%WaiPa#2SdQIG>sKil-V#<`Mnft%ewByXKkq_ zd!H!>xNuge&C&E`)YcH*p4egzg|MaU5jc#cjcOhCLyg2V?9g(-+P&}vlPWmM5>Gc~ z=n_q@k;qhL?uO+a8?&5WVs&)FJ@G!bD{Aq<(D^uHaNSy3b;^{)*Q}dzTBOEY@{6F# zroSCs$1#s_mCuojC%335F+l#!JvOL=K*X*j*rLY`A+pCUAl?B}`=hQ&%#d6@kp7N; zm%)?w+RG2@2X1(bGq`s5T-kW*t#L;p^wqPJ{~R~^mDIPcB?M8T$lS<$&C{H+TuZV{ zm_shQR#;YBR4C|&kBlP!?H(7zIiFK`Enn)VIiDr>?n`?nRSKe)My86BZa$%Q2XmwN za#`i$!vj$Ki0icVBGO>IH0-w!y>(>5aTq3PX^>c_B0XKOWg8#u{h^S-l}Dde=8otG z4^`lZhE)wzf@t1YyJWy7);1i_A=T0!Z2ZC5Q5F7Mk6dfCq`jqfnPzCB56)`>-zW^> zvX~wvF7@uZD7ceZ_!v&J;0Dk8nH_h6+mN=QRb`h-f9kw#l~&{bt-^ub7`$EFz=5s2 z93f$P-KebmDPfA=_>B_|xFzQ!-89qH@EDK3va+;%F-Lb%Zk64oYNF$n;O%LNvz<1Y zmH;Q@E;jSfBwWRD=SR;#+e`X=ZG&B`11=e^iS3SlG-nhhnNn-i7@UwROv`Gdmf+we z`S)o;!@_Daj2f#DM!+}f_4e`3In4xVsU|5Ynq(8VPH_Vv(FD=2VjP@a#7i#7&>k8HI-wpz07&tMdH z5P>sT&w+I{#+-2+S6F%bF!v*;7VVB${u}G@?jX;-<}ly%PfYLJ!Y=jbf*3910WMb@ z#|BTF5GUN@GArWT&G5Zae8lHBf z?oPBjm}u^mrr0~|xiycnCz6nKTKEwpV32Q>m@#jVT+hNj4~bi^(1AaIL%&M>Jzw<) z^XLoJU6s!!IXpPr0DeZ~+iJdBP+wF`RJAPoV6H(GIhY>=y(t? zh(9QYF=^}LClQA)6Tcq36NE@fDY4iEO$AOuRya}xO(>drSYie50Dj?L;QuJZq^E9*mi|eU6LcUT z&i}6x<-dp>QAd0Gf9lEgziAXLXfJe4Z2t6av%x8#{Rsmr(XgacNHAebzb~|oAM~f|pLv5zM0P3CyO-R!5FAeYQg~bz5QXf~7I-X|ZAJZbOdSLUjj`&-zGi4VrIF zp$Ns5y~K?V;t`BNmEf38GAqxSOe(wKTv)&Nmxb=rL_K&`m2UWuJuKhU`J~*QjO9RM zlV7V?<7RiQNc@0ZLh1P$2*@#{gwmZVn8)w<5iODN?qE_S_aGovX}S>>`1Ff*ICYRX z%>7`Y4nBq%5h838+vlSf2Bf1uXDPnvmtJ%lP-MXl6N$CC{exmOrPd92noucOt!&+B zV3qF61sd4t0Z9AU6tzfN9v@Nz%%D^5i=TX%EpnuZg+tFgIQ3ceUJsqY$0PM}G#v7j zs#`oUNm?=PI5_UrV~1e189Kxf4&vFOLIyxn&^8Vrjvbsw1yXixD>F2590&I}c?G7Z zEFkXUVJmq_Vw z+}{N^7%1WR%mY^Vy-z;p={3D&n}g|2^h4Hz2=Kh_SA(eFIC#AH?PGZP9zN{}O%Ah) z2?tSbs!v)-6I&t0H)%gDIaYn8C6$4MSgp(g8d1e4QC}H_5kRPy3IS?q1dEp-jrcteEdoR z6ofK%KJ|j1!QVHH+osW5`jk;a?HXfCsUv1z>uGse9ByudB>;kT%#F<&q2E051uk|NpH3Q}5ik)q2rv(+)C<=!FT9Wqrm@Z*R0m~jG?o}w?i&ZrMQsj_c?_7j z77A^y)p-o!)}W@DA{|ZLU0om5TJN2lllNusdDI>1Fxz{5ve20LRg=>j4UW7|s$L(Ouy&@`4Jz=UV9T+rh z4olg(WsR;=LI`f^QRMlYz)qT(Dr&;?%AOF)WymR8+DnbwaPt5=hteKs7-2YN2)6~~ zi>ssM?WJqM7B(B;VDfc+SjIset-mj)acChD?$9s6SLK`{F$I-b*=L@9Z8iG%sEZJ@ z*bFtxHBelgdF8S!u~4tyWymQuov1IJV4&qfLzIi-<&)!wmHily5}xP{ZC|C7p1@9+ zojR+YtOVS#`^gxIF6Kn_fi`3=hBaItVs6uOVC*w2-{VL?W;O$YA-{1bvl5w zIf&p9C?{jhd5g+=tB6-TWKDhJ_MB;Nat^Mayhrjj3RHVkFPco#4`0`GkKNJqCKd`v zJyxUcteVuZJ6>7n&cX-;(EaF)VcrRG2Tbu+2RGBi2coi%EN0Re;2)(1lk_PbAifoc z3!cBR{*XAmJ2j^*UB2AGAX(%SVN1d#&k*|7M{kX{K}v|A!HQ=X$S2sJ*I7Al=ZOfg z{+MM*-3b{Q7;KG=A00KaANFxHv^bbrRzJM7k^RI6TD_I=ocxUR+HPHpf0ie2vO^8g zCkVjZKMaY>xFjWlJz0$HpPSM8!WNf_1AFcAB z#sv>b_LF_2exs}Dfjv+_u-M!F(#4QJ;Qy)`JA6Ix_nSRJe^aB|8vD`q-_+Seq-Vc` zJ1IGNoCCrD`ED;EoSHMXwlU{wk&$1y_y5Ha(f49HGho~VYbD{W7387^;~uqA5AG`2 z-hh5P2Kj5UWMeW##eq+ZbMoz~1Q&PK*j2E#c{z9BrH5Si;?wzAyBW$(hE5@8Bw*mi zCKab)gfC(!TLv@z<Dvtc%=p8cMUTS#bgc4#Np6p|x=?bkTB{XmL z1T`ZJP12W%^2rId$78w_>;dQHkRhjVmwE?u&g7Sl4l^R* zAyrU<>orPB&KOII&7bmpRGh5P(NA0(!qREVcYWZ1_=V)Q1G4G_)(kxsAWXHJe1har zZqhs1@K&^dqfxCPoLY_DNgL>adsWktXXHimH@q8oz%8!GUyF|vrN1*=p+C=-cR6YM zdgXG- zHAbB{ki@`!C#VvoTAU*(+a=DcE8t-d;Q8`y#l0_DlQU!!cHC&k9J!+wmvtfUUWnmj zB?^$Z8;Mj36Um_p#LJgQrI8jf3}oQTW|*%~nGvp}E+h#O2MB*fCx zCY+@q4}T=!)btkz@gC|GwSk@1DQHbLZ!| z+v;W!IZLLOc;~aRCp(`rp0`_>-tT?80mwoie=i0hn#JcCOi6jLipHM7`5i7a*z;)d zPt6kwP3w%YcLc&)2MW&>q|RasWFE{|| z-n59Mr*YK7YbS=US;NFw{L9DdX-%CO9h`kvJu16hdeIp-pF8bGD6eG-G;>amtCrF@ zYqH@57Q+ahB#=@UAj9^3bZ_Oz~ zf%&rSJiyDo37IS^$@?Pcui{65j*OMU3>H_Yny5WprXn5AZ+pPvv{dq_BYf%(*R^IX zLPyDP`21&LUf(+IbBhd|a}CzS0qIhaB6(n*0lUi?RlWij1DTC#l(ao_|D&aVYo2L3 z8fu21S-L%}(OAWk|EBz=Xg}3<$i^XvH(q(a_TsM7L94Qg@h-Yk>o84+SueLb*>|S}lDO_CanBm~^ z3@3NJb;6w%s!}SsId;=25wEN<3KaV{8E4&YL8!D$VoD#_N|m$wRx{=b^ER7I{LT7o zq|HO6fk0uJKj;OXpm413FxNdTv1De0lsXBM67t;+RWZ@tL*JOuky@!a-iv0+)Z9^HCMilhQ!JWoRbn}U^SFA~e&*5Ew_yLyFwcCc4z zO>lodllSlX(h893x;yC%c)c_DCDGz3!3UWloP0a;3bB+j!J_@ z%yt=DHCa6{1+n>K3U%HFY_|r}$c}oe?Bz$B&ayQ3n3JlHt7^gDXO*Zx8_Hq{4jAnQ zwa`GVvEIN!Sqjk6DA>>l>aPvqhw~CDBSA*$Jva*v7kR>5e7Y;@Qyv$c6&T-#gX&WQ zb`Qe3b)0%;%xc$I;&;eqyX4~n1Brc59Yx*MT`18l-SVTG;`ZBTYwFOqCBpzE&LAl- z%pnV8Ujuf#sTo&FYo!jS3ex3W`a=U@@wUKO0L5Yl9r%GjIDLuhAH~a3gPmnXC&8Ls z%EN%d5-5Nlg)^DD)p@`#W7_lhT*R5Du%|$&QBVc zo`gv+sWW%;#r2RBw)Lo#&;;anlb&X>P3z-7lxBP+Cokx#>n62KOFX0GIdE9eY6f99 zsw@PkS>Lp5xlJFoI^_bwkdz&{ z&GyLe7|V>4UMxne>9i$Hs8#g=)RAK4Pc-$0Y4@@7aW%{Kh2JoR0AB=3z@VT1md7Y= z>H6dXZ!q39mOqmfRE#W39_stD=D6Z)Ea9Y?MYL*|nup1S2K3ahjFkeG^R}D60i!Q| z@j_|gds^Y`xR)^21$V}5DO7@EnHC!EK^M#H0p78lbPlH*J+9so!QJD}CriLD!bSU# zhdhL;%T=>q%cEB?D_sVY%z5_9vRj#p-!ZXC4N-g6+stBucy_Ng;ZyajO{1Tr+!sz? zLNT_;`XyE~umkcT%DOfhS$m6OkOalIrA3nL{wn#1xw5`f7G3~z@^IWW_oAg*>J9j^ z=`r}g)G8x{m`1TrW_#@|Y*zQRV+XK6<8}-9S}3c_#*JJ(@2cofDv~$IA^A)GMd-ar z1`ibsy8^Q=Fi;Zoa(1E{#9q442Pdk8up|TEUN#YK!bx9I??5U-sAJJWKeCjBu!nmk z0qjXj5oy4m^nafiQW)PF@#Xk*&t4^$W0K9tIBm)XdWGZQ-x~gi{TSgI6d7`7{L0@m z57hid6NF85ypIF^*1feA3>#$EUaLeLFGem z6bzwNFfsCltK$vBpK3p$TQ-NwAHdBM3B0{1#O*r?vGeY52}?JAc(6_CyB~1;lV)42 z^xfLw-LzXV)v*U!FKF%Ken)! zz-c=v$F@O0F7$yyk~K&=qoA%DACqZOLXYz-NhjZ-8r$B}+=+!VrKLBh%YKZ%Y{1+o zs(N#iJik*msM#f{y0awNl|1_O71w3<{^uHb&QmiOieuS1!y`^-?Vp5!#;+D08}`}%p@ zU@_1eeAS_LjotAQUbrsO;A|D;bKo!*bO1{}NxU|0@zg%-GHNzhf3Zv=!{X zecSRB>-a=bV5p#EM*TA*!9*m5G|*xk6hSC(CYQ|XxuL|_x$d4ENH#6att~671TXyr z8uqff4d}GQLh3%&w%7iOfvkrXo=u^lhMyrWbEun-k-2f;dbtc&nyXoJHCd5-) z_=?u|XNky!u~|bEN|Q1d8&1Qqy3(u|HlDrs)-o!DY|~ycMha`8SS*g}N&@sAy7mzJ zUTV9j{n!~*1u7$aIn+$NxSo?JcNw4{=mX)kTbMNgDTO*&mvliFMys11tQbqA81HQy zPtx+IRa(EoK*YmSD3LC*kcDI_he*I<)N|r|f&d-8(&rP%{O3GnYXN6Twv{a9x{F3V zX_?Cq?m;cfCNN_>W`*#h^#qE_KC9X|9u@uGtkKaQ2=s$X#ptp11}EPPPX1sr2p zpy%!OHA;>=zaz1I8e2d>W@vQkVlKg zp*3LCPTG%bIM2Sg5UbF0>P+AnkhJ`LAk5DsruW4*7KcDDKUIBlEY@*zCV442>#G#x zVi3c9YREt<-DLz7PsBFC_vi0K6=OxJWX{($~%elx`c4w3R+c^C|5a?HG#zyJ=)j377z_F%5?CU$*TYWL?_3jS} zLr3)5q^30C!o?{iPqs@wd?K3B3KcRUz3nocY!xKnvYm>Xq}yxj)GIJXVj~XgO@Gj@ zKxp+ZQX^k0y})ZtT^rp^+sY>^h_&5$eqB0;1Z!6OiO__drWX^l3kOiLTjcb2<0%+> z=KDDe+oE?Xj9faSc8!{$3~p5be4hBzuG49cqBtwtvD=u44qjfijDT^aRlBuEYP@3L z+)rv$krmPN@x8L6+YUKkmWrNy&4CHo^@veFau?ffQLJbai@}H6gS4FtJ(j;|9L9XD zJ|i=+QjO91v}5R&HFwJnzS~23G>iE)Sd@oYVlBLqvy zC=dQL2+{(;9W~hZ%Ycvat-ca8#J&1pW^_rWS!k0DP}DvMxD(F;-|u5h$89fZFIPpz z?6ev+Jx<8!qXL4N>PRoIjGp?gLJPX zUbe2IeBR(qp11py>0ZNAx$B2GA?rG3thH*lB!`_GUumuM-EE7LEm&Ra6%SS#Nv<8c zr@SYpzPzo{=dpIx1#^jJt^72$qo%I&CJ&s7^SE#AwVc(=;ZwIsQ-<533|Hxl)<}>? z>wrFLH5$&$1}g206D1zyK62}LEI&T@?qK42JBz#n;*daN4nf)Y$dPv2YI@Yi zk~qsO5%WLnWm;-YWzkJXVaIjm4}a~qbg5o#)R}dssZnFdZZl~_DJ(z5d$fuo0hL^m zVBY>&RE-jT!+49L`mOL4F&ukay43jVFe51SqoT8y{Qa5(IEmWMV8))gt;epEO1`p7dN@~l|7T4^jp$xsa@ifsf` zCg3qU)a4WY!2zlLN!A@g$W`DN3i6XFE|Cqvt~rpuFwq|%1);ve6$!pD>>tvZeP=ca z`z-JEk)z+=c?Il)5@?N#50N8B50yOdgwKuNI_Nf;u4DBVU?8vN?Uy2)Z&fj)ca6?^`uc8YotT^19o%G`GtPRxSfZRC!$Ft?4g{i|?*f}yiknzy z0kegp=2WMBP1c7T2K}ur{@gV7&6p?)EX#+EZ@ddLBM@Jpe@jv$QT`700sB6~{fOer zaQX1d>Uw+i;?C`RPkIle?RgvgDBvi~6Xyx@N;?AJ@c_5PztwyWo!ykq`T672PN_1M zB=2Q{T6%4EmAfU31W%?`aKRJ`9PO23)NbTWy)Ius8Tl5}7Gw^)O?{U_9pXo-?C>>^ z-&x-D@u?=C%k`x3Lwk~Vyvm1U8x!ZkPr22QTZ3`)2TY)do$xEj?jF4r@^Vsv`QklK zyS}RF(&t=8Hh}5)whqNtT0|J-Y2t8*nzFLqVMp(F{504(sw5)liiL%|&Jm64{Peu9 z)R8p}is&(-X^lwp%|p{=n_FU2ir;=oX0aGf`{_>eWh;A2$Z^-2B}s=lmUiK%Rc(_g z;d(Ot`PxX0ZSs9=rypN5bnk%1DjGh%Cli(qdy&?fQGn}1!k~-tK9(xo$u71@ZF#e%Wi*YlY28T-c##5Iq75^{88diqY=o$pK%qN=9-|DcBHYAVDL$i?_Mf;sA z#PL<0$rTkHw)sR-aX{r3o!ddPY=CwfyJ*U9)ok)xlAw&OA5z=2M2Q^#ZPJJi;)_Y^Yv))k+kv&Nzd(PW{qBFKv=)O6Q$t z43{gPMpn5B1E!eH`dAmw@en_JNv8u#ywC}-;9zszg?GE}4#T{UyF%<7Aw@0JS6E^Vl49rK1NT+>e-UVN1C4`T4!%XSm)3Z4!3~yc!jph!4}K2}5aI;8^W= z#zb(djQWtH4ywM)A{w}m$fsL4v!c;NalpRjcIQO?u$8DFTadpr63~LKlsujP>)>pe z?%6$V;GCJ>tVK4?Iq8Z?ua$P2Qy}$g9Hj^A2Bro5{dMb)Jq-DQ*shZ#Cqalr%Ulfv z{5g%w#N8#c1fzCt$KM9$6Y7&Mo8@T!2DCGk{LkA}X?*bK3H$RfWs$wyuX%DM^r%i$ z@=1|#ry5Ndx2n|h$(WeJY_j0S9Nwc)WF7@2agv zpC$`ukljVWTf2VGw>*o|y3}Pa_zzMbtasSep?eM&w%J84$-^17-a9DFz{|m0w)Rur zR_fZcfc}JV1pLqCA;z;}LMB#$dq@GR!-sGT7<)OKeIH!TSf{2qZ&Esfa)&nM9WR`D zY*5xP*!Fnb3=S{}p7{tc3l$KZ4`>D!QCKv)I3%`I>n!$tJ>xIt2m7t-_=|PBV-+Pu z%Xo}%AuYtcGA&kXtq=&?1LkTDjr{cQ0n0lV>^RF&pit(@V&fBfFt*nvSm-|-w7gb} zd~!+RjU~5fl~L%5|EZLeP8~PwmTe{!Q z9qzQzNH5T@lzx_LF9Ze;Q$&LxV%~0t$#%2V#=kvFuj?UjipD>4SX+S!KXy{9Iv@V! zJb3hq@7a-UfLY_W&JJC7EC-vpO!OxysR@(JZyQ zg4tog=wzZx$8FBbS$wJrqrl>JLybBDy(|vhtNV7#Cd$X0hn+Xa2f6-gswWQ816P>Y zQGp!3kSo(W)|_ zP_M_d%}aY)+#Xy7Q(J*Gj3jEp>$>)o(`cJPkgF4z<_?#u8$UDOdd4#X-DBlLzRgs( z-a)OOLpm9uPrTi;m|e4?L=!EGg*>*$Gn6TI?bFi)Gm5pyNVs?NLnWb1IlKHx)7U`rS{ZsLHlnzMQ93!Sl?<7h`)?Qo}!D$0Vjpx zZb>dBtIF}q)RXsG^$KxBao0tkB-_+kg#Ge9W!c3K0kCmwbz^MbbMr6}R*%10%`{IJ zl<4qO^A3i$cob?5<0MrMK|e6J*`Qj`rKcC|fQ$=65bu$REQ3jtSqB;wX2IqXbD&Fm z!}ltsAj+UsnckvGaIIn~*9MaGZIzO8ZLQ=8;A;xGv0>|o(_*P@trS}&SLYj~Y3Sfz zq(n@?WRTEB?qLeO!j!s2s0@hF5TT+noeaTT2g8h2AgP1Zga(P26M>*y2--kTEYIaL zpuVH>1U=?EsjT18M1bi9K?sX8v;HW8{C$PQl6ioB$KW;gY3-*1mScS`&DT&Cg#FS< z{s7;CUS1-jC&86|;UCbQTNJ#SQp>>|u$%|%hiE}1vSro@`9CmH^<4`W3;ZgiZD@q0 z{}ZO5d6*#zd%$H8lN# zIb6f+>wIegP&EY^hy4*VDh~B^+E+%WKD7Pti1rePdc>{dNiX-|FK|Ztxz+VcAYAwn z{ErA%K<_z;6ATDQ4+aQ`|9@wBP;@eP_#dLuUR75dEr3HvWN?vWWwnxCtszv%SJ!$3 z#v}+0SFR8wI8LKyLVqwU+xKt=LdO4{HNf*CHhK0ec4_X1YRr{`Q!A(tp75)_i}Li! zd-ikt>-qII5F}$jk$QOkw@{fF<^hPm?n}JAcdKD*TC{Fu3HX6(?d^qiQ2f)l4#+kL zr~lmIK&@euzvbrhl!8))Hak8|mkNv@K13e-8Xsor4*cMCA)xX>RjQB@n0g^b6-3hy zP!oMwrDEl1HRZU|oTk1`Uf%OQuikrjJ#%BtuDgqLM&U(C_-1}M4pRIq-5nedgch@U z#dK;*I^A%m9<}DgfnpKjv!E)GVZMKfa(W*wga~UH(y!X;SOT8bOYRJe364UiPls{_ zc#``0)h8}5tWhbv?WuA7U9FI_q(XCHRKnGkO*-I35%o&PD~DhQ zHV(#3lQI<}>cH*PVF#Tn!9;jRKE4*}rNH)3GlA1A4=%iJcbDMEY#^)M=K*(2)b*Y! zalJN5klix6y1_@cX*2Vk_A@jAAw){f9$>tbXR&_xE*vH+)uGT`882zN&d5o7%UJNG zc_~gE2YR$5vsh0hyHA%dnVyl^8t4{cY#}SOJ*Io#A>cNX@zW%U00*|l+qnHD*Et_A z=^f>3S6o%9KWAnneIVe9vSOqeHfg-mI2=tq6s})nZM=GlVyks3MqLvn*@Eq590Ir# zD*DAJJ>zB1^XTyb#lNJ@h%E_&c<&CfE9D2PYjhyi#4mP@=BY;QR9>AOp~n-@y1tT( z#a^3EhL^a|{*b-8?NO6I&lL!3O%{>BG1{9_jUK`>)+}_IbARiW$H2HsD~?{fVFCB? z2t0#0Q#jQ}YEic1Rzd5KJKa@ynY?^14qP>3mZ*`MwHL~b+@3Q_=qFs>9ijC!zoqKK z>U6VNsIROOhIV;}+$mX5vrtmkZoa$voQU%Lh%CdXom}y^OtqAHYgtAKQPyVXcq8xq zwx$XXhUr)%~6GObwAkn424C94R`vym68q#{b# zDC7soEfc-WFk4L94d%owPvlER436R2d5AB9e#86`q;-FR`YjuoT6012H3&D5=-#L~ zh^%I5fd`eobdJC6?KNAG`Oa*2mD+7SAkWY;c4?Mlj>DNWTTXosSJV1|^s+CJz?P@j zv~T|!f}xJ}xAk5n@s2GrCvLlWWP;A{b(&RekRsf@b&QrBa(>HAHOJk^M_=Z-B;_^c z*?q5+;u4Tdir$M?{rObyn8FdWDzG`tDyL}XXS~v%S7#pXK{JadY!!IF=c9~eO49kn zDWO;aq_hy7PKU>2A;eU)s2!n>Y0}wz!5-31Gy#Koq>Az`JO;}YlNu(bMgjcQ?F#^fE zAe@kUt)epJ;t7=EL7X|gUr@xzs56b6{gc}_9bFN`ijM((yMKu*hRHNbn`s1z{t^e0 zr{=96199JrRa|7RXWr!fl=^mN2mW;ZaQ-@cqYiSnQbJN)hERpt2-s{0DTaeT-?^t4UML|dEW)N4A}&jW-kOSc;w`B>`hdG?R%#O#hviu0&dY3@GU298+f-|gIex=?1=(bQHDLx6 zp}sB@aSdf6SVa0N+1aTyXxp)2&ZJ8g^EdRWi?_`$id|Zk1T=K&k05N#C6bZiJAm^E zUZI^xuZ8~c7ZOkSWB&x&MU>#LG~&=ul(IFob?Du&S|yTfp_qw5j46v)@h7BbkcR-Q zSwgGz6pz3xnj`lhQ&o606YfkRn!N4mXl&YAe?TDoM%^1_yntBv0uhQ3-^`23pC=n1 zZ(2c4&djk`!0ity4ZMD@tpqDs{nT&4pLT=q;qqJ0%iojpW^(hC^rOMp*)IM2>^MT~kJbd!?N1>fKw`wdQYM2Im*IUAFuWtGtWsD6Lm0jc^riHOo@ytLO$=4df#VQ@g_N zvemD3V1BCZ#aZ)?=tVbV%rvb1(zQ<47>ek{HX}Vyu1RE2pIfTOD53ws5j4Nr16V)ln(>1gUvtX(7{1PLC=fu_ z1h^WUW;)Nj$H|s<9yGS%f zes8sA`DkJmpzEnbhJnENkL~E7%m@Cqf_^00mk?$r4{eypc@GtuP4pw${#>UmP(YGtBgFkBa!P1&WqvDkS4$`FJL4PNCHHePF5=6H+2ih$<2ii~Gg#wAWY?d#412-9stOq`BMZyK^MugsWmD~Q=$C> z03@N8w8-Pqoausf7=Zkt0`4V28}FLxFz#i3MK0}#5kM8BN(PCJJo_rwmqhv^UKYoGPY{t7x0?_xiw>7zx+ zI#VM!i~^)oC3<-als{1?8LKiDuqq1U3!+I-3y}sVR+#8u+Sbq+DP%m zbe>^%$eH}VYB-H@?5A4!pE2`#!xsdd&LBpqp#}d!&KjgbGEnR*_|TB7O;0p29GY{_ z9;)L&F5so6*SCiP$m!^ewV`8Vv{VLzQPPs@GeQAJ>=Ofb%;o?tgR$)P;I=!Coq;Yd z#M?tqzsP?j+hROX$YXrHr7osQ-k;&4&Y^+32fkmC^8dNq;z=T5Amtwg7XC+p1^;(e zMs+8%e}{1Yhg$!3MHR;i;IMZkvjd(0zq}Rv0jrP9Z;~<| z9;6z>T7*O8y+K{G?r1!(UiB0cWiC1OJFoH%N9NURatb!qXvIUnni@~tsb$PIn2*nq z3LCWN1gRJ-I8Hg}rCAO@x>2yd@~%bEHgjGCImH^oh0`oiQrJu{Lhjt0{C%%?T4?nF z=24ILA>vaL0stjX*DQA>yNSfc18cJs{RpLGE z=UG0!i7TB*{Zeg%6b78Qwb8k4DdkST;FR=cs!zS+(W4%p^?d-!E@gouus{#ux6yMM@`s^5#_ zZ;MQaP5+0dFX7>77r%I22{~RblJdpIQrdqoShjI@exxe9ZE8$>)&#hXp3a4?aM;Oq zyonj0{~$(sC-rCcw~JvQM>G7;0?xZ9SK2-MJuLR)EyAQATTidD23G0kk~KSgPX%;Y ziD~#klCoE&NOD!Khkod#Ll5~=6f}-Q)k%17fC7Z%im9Lpmd@_-Gl_jNPY7!PaY~D1 zwy~8V76YNc+P%KsG(LV2?Psr20_bfJZl`^rnAEev>%?`4MzMU~2`8Y6hdA?DHowHQ zc53Tyi{VMd-j&WgG_J||8m-^SinpdabTj|WxCCt^6gNi%Lvm&0@-~qQMu1T}2bG|H zD6L9#{jy83RN~0F7Si?>>=T4}yKLPO^U~szTIqOU-udq@)%sm3seJ|u9!5B+qPY=k=#qGi`+llI z(!5`erlA7A^fTV^39;@FIoQc=g!cNCMn0IOa){|y}x#@R_f}#>to7<6THAVe6hp<25XW~S$_CsAZdMv=| zGu3^~um*~;Sp?f@(>0V4RJkR3LFeS50cthkc7>+(2yTp~cInUdhQ7e}!`KFd9V0xQ`GrX?ko!?k#{TdPe_;vlgu-oE!>TaFJ^m?io%i!JY^ z-s}dhy0K>XDW?rzKE+xdJ9DTfc9M!11@qQy3c`7DJ=O4Ohwn3xXrH~i#3Yi9)KF7d|L+eCko{Eqgb4P{ea^4R zYWg)S3)WB3*1xi?%asLwFxqumBtr(rZAEAE;%+z!W&S(;@ZpRJIIc7}t~ZsAQ$9kN->00()nTHBH<#YwhPv*; z`{bdX6_LN|<0kr#0|1@Oy~OWc{^WsVHMMLVzOr@YNv!MOl_ART=M2c&9XIrkMmq+z zF6xEnJnEQN{pz>(W1)Jk6#}vNI+`||Z5?{3DJ;O`iATcaO4KxPOPT5Vb!#=FaDCm> z)q~@|o!x$Yu*k!7I@B-0eP>#jC+qwlti5GZol%&s83+!+H}3B49^BpC-92b<*tom9 zyGw$*yE|;$oxsqir)#QvKAkgD_5Ovm>Uy8&zOR+CvPr#9Iw?MU{D|95IgsHT+9B3k zK19#YUK%-ARJpg>$t#VSOjW>erzjtxi1Qq?J9jpefit>9x6qJVLd|b*`71aURzt==S6TRo#r9!wFplY9IXu>5&AJX?C zD7bqqKM+Q^*^33Mm?|fS^^+4Xoi$SodI=VGpmF{JLDrPl6FXqt;3}ZUoyS7DvkN9bM|HypH3$mF4RN5^J+vDZ1+UGMtW6|~n zl$>!ZqMvA!9+4j&sFX}%{&`Cq`E5+m*g{uH>atf!`gUHWY&Ofh#X8^yvptkQi-<^O zm_gqL)cY7wA3_v><{{}zw zQ{8odX@QYxJGlLf2)8BO+o=}TMZqRP!8pHnW6ALHvm5e=tY@|q_<|#*{!jjokUKMf zM$5-gu|?Z0dJrR1%QM1DDHY!=IKW)m+bQE+P{eZES}Rg>?#$PxwpO1+K8;GRz%)Yn z5IUO!A*+b;hSZj>|7S=-;L)!=8Pre-*reitJ1cyVdo<5*ivP;&aO{-|F7#r0JW zmij*eC|4_6E7xED?`^u;n*!QT^&RxR{aCoqCa^6jHHoA2F@$-KJBZ@eL5w>KRu`PhC zMwqpGE3|8Gq0+2vT<4?2*0#Xg9nlIcdA{xl;0P^pq(8Zc_>1v^FM)om&s+z7;?kLR z7ktmZEUji1I?g}69nqZ{b2h@F#hEQUdW<6K*!$b603Q>32r^ZD7KQJ4J#!9qk?IVe zkqbgc{}!L&*8W!y-HVS^Vt%yp;d~C2r7|rXz4aa{4>rOBO(OZ$znfiGe0z1&`n?(r z)ED;7xbVM!&D5R&p#jfh%v=3uMz?>g_i((Zu4*uun6lqOBQo0tk+<&fM=QI;_h`fB zmd7e+Df11zt$r$l8GI%p=5y{^P5@*ANB6Bj?8bcH! zl(RCr+a`okO}pslu#Sk_$LQONy;VWDO6^ln7=HO;DrBWg&72WM7obHqv8=N+Z^pDL zahQu;LywY<*5WCSWy{kJKQgl2M(5HWom)EX-(tLKurm)+L=qc4-An36A>=$#dU?ze zsjO2&kMO((nXnX=9VFNg!(^Lmy7!#N$N$v(c8-ugl|zgCFviWRp4aF+MGvN@ChsqW z`bnu6YKU0DAExq!_fL6<|_g%G28rcMBgdYax-k^m5v zSot-b+Msv}D=dJFMshn^KWsY0oApeh{{<`ct|;N#3jW4Kq~`N&HdKe^AI?gVf&m(HiGyDR^<&u?i%?&!p>R4|nwQB0BTmJikCu@1F4^>*TO z5)qBHCfQ$MU*xEHB@VIqwS{I7GD~Y2%Rrx|lV}C|+Y3{G2L6>IgM zsOH5q*6L1jjK#VwXY<3ACFy$sR%l_Ok zeg4cWA5&uKR4oS>A6Zl83Ga|7u6$4|N5jk)ZZU1=P808YXhpb!_7ns3a7rGqJDE}! zM;{fuvqNbG6&R>62cMxUf2hbYCb|%|e1H2*P8(upKcc!9ABc7NVbm=}CHr5z<{GJWWY} zQm$=`7p#EXeGU-|b2E2_e#eC<@u(ji9pbEHYzoxR2}Y+~oPqhg4k>hcUgi78k9_y8 zxCFh~=>4@8ZsM;HeQNqFQntQZ9PMg!%NC~z(+eCbc5_$%p66^5tcqFGM#mEg~vlTdo0L;B{-fB?(w_M?``kWkSc8`R@}EMDOjO8(R`>jG%Qwycngn~ zTjTh5CAjl4VWjMraKxu(mm`q7l8`nCty^qcs%|*=V%t&336>8PgbtK}VF)x2VCCYQ zS7wT!?fLbPtAb|&K`PIJJ&8C1ky_gpn-n%$zB>MIh3HC_JFMpfuDMqH0AAfYSWL+~ z77y_T;q!%x;UbW_I47uagW0x`Cd4<6NM#BC7%OVHR7P+CijB04K^vo$UsC?)zWGts z=ns=U%LZSf8(bNa9&dIM_yL+pAgV76f&o!f+B!(-4A}*j6$g4#K5|N#4T)IJrUH8M zL1RE_5X{5!gZ*Md1ls6Z_b7ke!3;drXgwxq^&z|zv@Uj#x60;Qi^d#p42AtSv%Mgl z(OZe%4nQpn<_O7^b8H z0fz4qMkR>R~uHO_;$;jM=(uw_c?LhXJ z$1m|IBWr)Yn|S=}x{L-g7U$O~8HHyJPPsGnjZ|}(*cXV#M1i}^^?zIH<_{evqYQ*z z`Adp!c@^3^)lW2xG~Z1>#|8U2tP~j0`#<}(;k|hiC|~e_`~@GP{~zwa|F&>dv-=P3 z@N4P9qYopZ0y_LAqOYYaC}<&36e4RbBO3Tm?&vGPW^Q%gCnzIYb| zx%yf9?{)~VyV`TS$N}`uZ!sgsUBZTtbI0z)XRs&UHOW;YY^l&We+1w4d1^?JmLqjV zk$-lA&5J@aFw4R*R0ooJF130Tk<)-J@#c8I+&B(;w2icfMTR9XrnqCRQOPhIMsyuD zmdtd>>WXs)cK|3pZ76CA zV{b9Ke+QgwaLR4;*@a#QTuJKhvSaA*#`kEe%W*qFt~(fi3sTkkTU=z1>i(I2PKw3C z9OaE(!g|(lY~r@Z_USSgK?F<-P(m}ovPiQro$8-&a&_iAJLC%T2wXjJQIEnMsfJHy zV}^{BbW|c%>Y|Dm;wp;`@j|Z7RZ$w##>Js4|DukflGSvQW7qPy-H(!Nr_s6W+lH1- zv;UwDoXo=-5gD@{;)MQrC+$&esI$Q8{4x^yxFMbaCRCY4doH$DG>WxUeV6vL!>yGb zy`6+N)n85Ww)jo-uUwp2U3F%or7gY{Xs%PR4g=fxcZ~hw*ZMBUB?E;)N0Vx zDQ59*-M@Ee@e6(sPkwJdg`E4#(*G|q!H~%Sw)bC=4K!G(Kr5k%7_V9qB0^yCe4&^@ z_5J;Cwn#FSlzP%S#-d;*ktcOKpU^N@PFh6I;9;`#HPeb-8Pgx}=dXzS{hruH9Xzo! zckNJ=HBMf%J!*KxlY0^Jg2h%;1FeaHIBf2y+Gnu_fjH{{JKUhUARY zmi>htyF1>JA-X?u``41|6A}2IpC?UiqTjSyB&`CjyGJU_>bS; zwl4+0QPg9L!Pvp|(X7q(&UBUwE;a-0lbg-#VLHE(4;=I==2&Zc5sP2F;c}vi0(csc zwF*mRzDB%F8oPA$cCw0?BgxD&H4)7@3;_LEY^1IL+T+r-h?TnRs%C{#B(hDPks&<8 zDI|a&WERe)D;-!6)SER}tj>uZfqGi?Y? z>_skGx5V`kxgjW3!^yCo#-OXwpZ)l?xw6Mn%Sj{5_@kE1nh!vFrmKE~xJ4daL?xN2 zYOEP^tljQJ6Yp(jKscXxp96ey3L&!tO^K@~arK*4CLHPQRMJ2>Mf;5S*PH=Ztn$TH zd|w#>obALa5fX4UtP@$0n*an>ONXVpooaA?(&zB}w{JfooS@X=h7?YF9+k+L3wF=| zg;*xxgsRI&F=gve9#p6QwB)fm*dQUTK0D|uBE6D%**A9*)v0U8e}wwHmodg(k~#k` z+<@WSwBVXz!ub!}Q0py4NLPR7;UgG?SlfVp_zGM(MdtH&vhgRHarp%CPvfAMh|i;Z z;YM4(W9=fBA&4%`OeWPWGpCpF_%3I@TFjSX@OoYAB2FN{F+Ei-VI{3u&OVtYx;*qi z<>5i~til(|z*D3|wn{nl9!*9erVQh3k)&1Q-Z;eF*q%yF-EG}5fJ^Oy0G>*lYUyu=}0V$tpqd~Qm-a>J0_qxFuA z(=q+T8D8>WGVSi8xAlk}-m$-`+bZ4F-WC%7<5bU8K4CB+a_LvUwn^S4kONQI4p) z4s%28-<-@LEj*V%Fa8?eYk?j;;n9O$%d0bZUBb4{Ix&VT`_SdjPV(7DGs#NufNS0wx!Ve)Ej>U$Fk)J)u3cKmFN^S&P5PNx1oQ7wCQZ&#{nN8g z$HdQ3&{rZM-#rbs-#~>ib}{n0Q8(X2q%QYR9kGs<1hB||pA>S~eqcRv_=al2tK^`iR_?}QTA6i^?~ z|NWn<8?T$03+>xCQ@;NVRqKCv(Ejhvz<*wNlRB_Is*8)Cxuax^>3ovmzoATHGk$~; zK@f+B(lNyeNecg_+8duB#b!tZ`4|ZL|Mh+9@t%JDbDZO{{d|x)Oz>UtLi-{B9vg0hh9zEX zFBBRKl$!&a27}x1U!rj8_C#?4kTHmowY!?&&2czcr*Vr%tOjMmz#m4;gs|;=o#Y z>qKWL&fMNb4qA*@TCH15xMOi103n=@M?bJg*F0S%>R1UDLzWi6kxL?6q*arE7I^b5 zpjkaHHt54XdjX>p(5e`CMmapB`CeZWo+?bWSTK2E2|2Im5^FI+zAAN63TjGh#@x3H z+K?>Vd1s{%033sQJ!&d4MvQEufa$qAs6hd?9iO;=TMv_CwJUgR@4$B`O9adzTtt1u zM(*KsN%yMa!>voCqF(xEG*H_SPm|3HH5fL#!|F##?uk%}kjwKL>J2t~o;(fPTp^n75kMu=?4s5NO_X9a)9} zGi0&^pWC%kRPZAcb~WbT%c2;GR7Z~mVKb;?)J1fl+ET+Y9XMVe{eumI#7EmI7}z9= zT*f9Ajo%xG<<489npX}&=0A?LX0M#aokMtSj$0wi6COq+NP^szZyaaQutV%XR&`7U z+6TjIH7zziK@z4%FY2_kvMnwyqNe=7tjw}pvxGP|qes~^P_-H0752)+07jM=VZo8m zxRcQIn%KH(QVtOsv1IaaN0ccWB976YyAcf3$$Z6eM>~~ii;R+AFVyBEj_b^ED_EC8$xLdjC`?Y*u?bEn@Mb&{r^vW62TX93V@8Azk)u(g@JCsPUfH3zTjY?iD^`=~T!Zhm+^i{Y$GG z((emx$IMl{mI6FQlTcKhn1SG+_&mS80eqwfOK;MfVrqLO3I^ipFe2QrOYGK^2>jJV z8paUk8>&!{ptaeR>cMjpwRi46 z2Ko{2ea3rbw{mvam+2{F$)*m}xbfuPrF$A2)VyNAE*wJ8a*{ zq}L8+c&qkcVw}@a=G|`yGFT6&6k7Z_2#hRi_n&+~FdKwwH&{Ir%#=7M^&|@2(3IBz zNCUN-FCSCf@*iI;5}bZ&RxF*`YKxM=2l5L7z5oZR=Mo_04SiqKe8VvnenjRJ1DULx zQg^e=$+KNbQG2-(*-H)ZDgtY@SF<}QwS&n=d+@8vOJHgpqgZaa2wzQj6F*yaVdWB| z#m(YZuvhAATIOupw8-B2YF&XFd^xT54*uuBH00#9uV3*Yx#@6EONzlidr9lu6tw8~ zhahrv>{#_(Ju3y@MHvZ6!|hLM_dTDH{>>UnYaBG?O+jF)YFCsX@)RM;S2=0IN{DEs zFw8_Z2$=y3Jh_a3bx#Q+;mqO9Dw~1%L*cnG@K4z@t-jICoMwN9Q(KEQe#8&bJ1a+X z*2X{kgm53_dj_7#idmP!N0vA(-U)Yb!&U@cq5W_l{ouuzaK${V&qY+jxO?fG#o&?w zODI0g>RE1a@#3Nkecazos|E}n)1*!E%%hdw!X!#0x26;q_)%vf{gqH?-$O};a0 z@jwvv(_9iG9nusze@LOt@u+3rRjIRbH*aUOgh(ibz*x!D@g?6{p$^m24`^r4NA_|# z_~ndCRBQ`-GGvP-0x}BbRCzM%GprLJcvWJpmzdezkjZmdr(EHzGKA;Vcr+T)0`pbK zf@Y1+9{5Wpvdib_q}Dc#2(D-FGAd{Il7S$;zBMC6g*TR|a!JyZr>+*X>dZEhxAtDp zfm)B_)dik~Yj?=m%opdomP_6u`u=86EKid@;9AFh9Di+^HtjV@r&5!*BuEut*X#Q8 zAhf;IwDrp}0Qm{kXP;y$fVSYG#R`Kckw#Tp6m#qZ*P?Y>pYIfxDuCF#iN<#Tv7Hq= ziH~!*--y<2s+e50d`3B$p}?#k)0-4_Xk8EKD(cM1w=p@nhE9IamS{jr*PjmuU?WZT zG9#2;sK{URT_a>dk?LM{4mj2-k#+u*1i_caqVvb*}VfCH;Cg+D^ z%vwXD)wCqkA9B~s%Rfw-YRZ{zR%lh9!M2ssnPhOLPnO;qgF*Sf!#L(KLRu;ohk- z7$|JQjx1!I*~P(V zs)1aiqn1(@#z2!rsQx#BF^B+$M$fmi!766wBkovm>x4a;tjA zTh)tkv-iaG6{sC8m(iP0E=J-k(`1ZyTVJqxFQ9b)FPQg}F*f_)3edj-C)SiOj@Kbm zj5I4ygUg*-egX{ZtdxrYk&5B#w})8maQ|8x62rWp6GHTrW&7aDccUvg`>f*3@)!J> zs|peTyZu*qQ!CPrIk>nFsEPIn^qJXP>kg1>64;v0m(URtmq#x)g=@B&&AZS3*}4ia zHKfO3-=>MNP&ziD&-W9>i+=yLoFJgm>N1+aDio^{bK{#us>_^FnXk0n*!<&PATOV< zycN&=Jzw%bST#=Ll`dxV$3DuH;OB2flL4x1_CD%CDa6_b4^C?ocr!SD7Lf6uR_*EJ zw2Qx~br(??UNe)CW+y0Q0mawN-iu$$M(CJy&8dZ00bv ze|N(C=}Eo5-;W(%DGHsVeWYd7zi`1Jk=ApP4HF~X3(28o(4@Q`ruYOiTz52wLudcT z)M1)Ol9&`+B?I}uP{vCvys6Ca2wMnZGWAdj@}7yp!*KCx19PKX{_q~U2_|X{p?8OO zXrSmMHZoC&eWdN?M`SYKjKgBUo0^hHl?&`=#M6Q{jt(iPs0L)gYtWCFM-^g;{b4ME}7!(8JCxPJS5rVfJU`fV*bQw z|F}Vud9!ofWIt)a{Vmy(N#zp{SK6l|NrxI~$`iy(fYcRV@`sTB!4~8kt@_E8tKgF~ ze+`R9`(8$E2S!_0aQi>(Urb%&pr!5~7!#`{YlxE$IJ4c(y}Wf#3xD6FEaES~J3V6n z>{#L+e9G)>>xB0C|76zdyPC9e{Om?&TG_R!7EqgFa27EUT`uwFjG5bs#_@kU4-QJm zZhGFB{)^G{o3LYl8C{PbuauLI2DSJrKpK41MKQ_Sg8^c-T5PIA@BNUO> zZ*Toel-Bg(u%FN`y<%@K+jKULB)-5;wF}sLt5<|p?t87*tj1@7Hu?e`Y4{`vXPhxa z;w$75JQ3o!zfqGLxgIdbg#D0nj41-2T8>fek39ySFqj1Wdp#csB5fe7l-0Yp!*tk? z&&`ofj(yuEmR@(dL5`{+ciSPglq?lHEzsRPQ7hbZju2A)Ikzi3z9X3*PGVf|h0a(^ zU_j#E;^^YoJYyS&R)K)#_l}1u+v8JUjc&G@VIBsRg?{XtlUXYbR>e_0MlyW>pW-|lpz|dHUyOO z-4FH^D=YT(lvH)it@u)rd&s4+AS&N@0`qMCTU-u_KNi1QG>uHkN&O1)t9GzFdPKPb z_dP_MuEKap1BS=pa!&C-rUc3!S^td7?Yx;mPUH2(zM;$RSeQYlS%#7~4I3l(+3p;^{bV>4-bIk2SXhT<}_7q;DMCWmrM%Y0xTM==Eo1aTNGPdxGAaF~v zvq*!xYCrGuaoVkgYP;qP?tk7yPF$b6GCz4ji1V}0{dL^%i?C7X&Wz{s+Dfd2-G<|i zdRsf=FFfo!bHE?7B=YO4tbWhUBWIdlZ|C@bjX0|F(J;bR?*XqBgS$5OZeji6M@05H z@e={&KNLPr!453$<8yz;&ZA+x7}Ge72#y}Gwr}cZ`Ec{jVGhYG z_mpUes&f64rijl)m<1<@@P=*1Hy<;igrA5GkdM z+fv6a@7a!nvzT<6Jjpicz&TzIL%l-zCISHOvVmuEbgGUCzO{U zx8t3Z=k~|@nnaUY3(0wvk47<@usYeJA@;OOqnd#vZ_JG|dTFElcQAwPt1iKh&UYz= zu67u&^x9+j-`WyL>q7Zl^C0}HgudzIyEs61%tUm)Y=@yV+0IXRm*vpky1YX6yP>JX zbI}pWYpMr6kfrRCAR#f=`HwD5^!s%L`whyk0PUuLh$)X+uk5*Hd-W%ZTRT`1Zg5LR zuV>DVYTYpraF^9-L!rmP%Qpu!6qJ|gR54vfToU%UJ0lTvQx5dK6p!2qjl0B@pD127 zEa|jR+3y(G`V%LfG)7y@SxgsFeO+;62$cJX-SE&bcT)$JzSy`Iw`2kObr5@j#N<;~ zc=82HWLbZ*f?XJ3@Uj$4N}PGFPKIBgy`1d(Q|fzk4ZWS)J7*>>KXwF?5Qjcoao?g8 ze|~Jf?HJJzVkqjs3pDUmGJO?PHp8exw1#i0;*wz{P6(F270EXnKT!-R<1!rCTA;OD zgS9Nq9XKOusL-i?L|6cf@&V$TS=fiOx!C1eS$YR^2G5dcINq;u9m8{aaUG3Fvj|i_eq2`db^;aexw9LFmx;bz1=cpp_igUX0d+_ zV?WEiXN(MiKD?&^g4hq{&&rB8m3mR(_VKUVq~mtS9L+i!vP{>lhb;-~k!?RZQ`#$5@|T@E17jn&Ya;bh9d(8-iZ>W`S~Au(==THIo7R`JALTlm z=Y8xo+O72-sNVlar>Si(i14;7Z2q5N9QyLFPyab-QhHLv zbW(Vz?--Jm{qU%UQ4lTiWSV46l`t{_5}l-0hVB-Pov7gh?Rd-F_`}@9_4ut;mM%@2 zT*4HX_L(Je^BnwhB~RHUa$egJXZPL?p^MU;b2aME8n}_^zwWj?wn=+##+qxtSr#8} zPzl$Arvg!vP<@p6Pa?6D_|cce6MGufHxS-reU&+VNlO4c`!@5aUKVUtWTk5ZtocoY z;W(qD!7(`gHT@AqDGR>0hM592ayUz(U8klSz>}Mze9DaOphGH=cJNl9nj)-sVF{yE zb~Htk<#QAYKDKSWf)#`HXcr8ZsT#D(iD{a#&Ky=O4qDa3Za zG{a3Af%I+3%}a}GTl3yY%_)?xn$j{oh@>@P5NI(+B^l%OKU%3*zNByNsP@@NET)4G z?IKlqTRne;IE^y>%YEsN<;s-n;X7f?VEMVr($RQ+PA^Z)QOTp63RcTm3#dfK)NhI! zYwO}NKbSkLId6|x4QIhtNjI+4e$*bEh6#neRr}0@4 z(c}zUTa{9zfUNW_431{+KN;ZWC3B0W$$)UHly63Kg?jguh;?@lfA~j(818mxx?Mgc zWD%CRj9AeI9|m)_|C$yrdFsR=YS$+#-H0sShBuuYhNoet(y*1OYIg^?jWm01FYWe&I@eeP=llh4E{JJ9je zW}^xEb_3rVD(w1@87SUa@hJF|UAEyS?6i8ar9>NNHk|-|S%xC8>pYqBU`7U8v!rq^ z_V>F*fqnom2-xV=Z&*_NduS-?f~if@Ic&{wTlTeedNC)X_O$j{$B>hFcZ)gBt z(VmfI7e6!u?$1Uot|gPP(4veqWB-cR4Q z>-{AODQ#~oR)=+B&PZyoxT<%e;LuQn`x`*S=-5#f>%tWCD4t;<$n*f_u7EGgl+69< z(8_Z-013xLX%cEgDb4T_FZ)kaA56mMu1t?BKmLgUEL6o|Mn;9ci3`-!`M9 z6=q-*fdTj|f@OOm&rJC&0|`>6kD2zHQLq9%nY^oJrEIM^4tw00>3~rqG=YjelQzR) ztx_+znj)`TbH-dzu{$R~?%#RaaZ>k)y*%0)6!}j&f$|-0lvBTiok>n6C%&~z1J&lK z28$6^+40irc{qXUJybvQQFn^7U&7quG$VFW;pGnKi_5or9hRj6qzMxiu=&Dc6=wTy z=mNES$Jcjs-V}P4e?&Oh5xtsa@>8`K@@xvmt{2;nY-MsN)i_Za8*LdEBZVx7BZWpY{4`Y#kkl%;yn6ur)8- z?C#Bvju$G~$uUv?vf}+2`=i^DGEG_Rn4u4YBD82VvdTm;}0SZR1w0w+=kH>B{^e1=Uv^Bg&{4 zli}X3ju7l%P*P%ts>A0i0Gb+f(8RQ_0OxX5;bLLEl<4Q4jqvZrm6GKlM06_USsNQC zRvWI4IN05zkP8J`cK~IzioC@Mn}P6QF|)*7k@Vm4Bh`?O+Tu3tjYV$3QyIIN%xtAP zmfga*s%uo{o!R5LN+rR}(5X7_mpww$Odg5VA7STC%%s95*uPf5`a?O)otCdk=v^y? zb=20xTTw2xPJEKo3_a|Edo!B+f;x4HyL=Wq2fnE@)&D^i=-+IC+9}7 zNZ-uFHIw;Z{v47>J|dmWIvBL-!x2ne;YGoo-Tz+jZ=Yk`A%x9E(ZuxqoUS8b-?(5w z^&1QLAWSu_I|3pZv5rEg^{o&XBqVl$_ zcYjt`iNA>TIHwQ;hv6e)L!AVSM=dg<(Y_C98gP>-IFk1JW`f1n58_u)$XgrXdtRd83vcD!?iCYZ>~)qfFjBk4VwJ)xLNvST$A1g~I+7Pi$qKA7Oc~us zf7D3F=f*}&w~)qK?-hn6$78s*9RK_6ty=iJ4I17orL4>MX6W3dNVa1oQ*@vDmBdDwqo9%!^_7~G+g^^$n+put?|LoHN}!R;+rrjo z?8LJpx`-8h%)@gaFr3?@KSTl}*A2z`jxv4!Ut7HH#9HI*6x(VW?5|iAtVpv4{-{7Y)&&I~%z@Y1a%HDq6NP}mULnJ-kS~~w=$|&Eh6)DdL3lKM5zY4)eZ^*! zWy$KgAw^18I~mGenYhPaQ^}kniBEr!zF*oCVokBc@|*&)`?9HD!SwB7&ZR4R$#*#Z;yLIOk>G3>rYKO6oA}d9aeiGwvr65@j69EI;V<)>I?nZglHAF%R=MI&$mo3Vn(|pncN5S9=l~(R!hlTb?*Wt z{w;g!h~OMWP~ir5?Ti?p4XnjtHyK^P89@C5p zJRTE{Z?9DntcN3CUB7$k;kS$3Aj+1`@ROM8^mN!Ue=XXdt?{QbA!Fn*2b|{<>Ndp* z4S&0TYKj*rj6&trzF+`WO%MFclHK&7CF~7`tI9|VC69e0hu8j|_Au;?m#zU%=+AEL zzAXgKc|W|?gxK7c^=C_@i;(AO#uJkEB}uu7+Q`RQzfdC3*%9a7CJ%*l`|n#THUr@k zw#%N0$U#)8@{Kw*@K&(u#(;US9t}m+*^-&;7`#hkP*~Y&fItlD5cGMKN>5ZvzVQ(! z*Mad-pa}VdnqxS#8nnfX)9DK&s71;Z_hOz}-(49V-+YunDxO6BQr>EppvR_|L*nsR z>v7LV;{qXu**eA0LAvXm>963^)Xs-h)Py0Q-i8ZfVfo=Wb@@8_R*JZh2C$F8x)jmx zszCnK8N@X*ZH&oEU;tz0jf1WM2aJqKSU`A~VTP7&HIcex+}lvZ*O`9_sdFzn+0G6; zEZILuz1nmQ%!l*7Di)9siM_K=|MJHYlxwsm!dkk zyGHG_xMrc!)-o@3>hav*6w&z&QmfU42aWc7*IwFmMV@f22f8N^Odx8Sht38;D6q^V zWO9deSxGP`5>t^m+5%{Ct&*y!uHyj^?3__|P(ZWhaZ)bhoUy-DG-T?~>H_6?$D{&! zI2eRlNB3{*+6DSQy>(fiHzM24h3)iwgEXI#^am$|!7IqXHaVKm!J=c-2RFM{s7Gyz zi1lexJo;U8lPpNz%5(W8Ha4d{iW3fu6#|&Lt#x0CQZRgyVwsiAczBZ1ZPkh_R7-!CQA?qE;`MC3?HdHnRWN zsXN%gK&W}x4S!oe)w*%~UCMp=*BC@6uymo{_{G=B6vLmTbVyoC?facS^xBRH(xYU~ z_X#Wh;XWr8%|*L&#z6007k}XK2m16s>YO(fzNbcK1sTvk*HGD%+?^(f!Q{c{u6NR| zbH^8KaiVXWi?AG@#!&t)DC?&NeNQVyXSMs@Vbc7?jnCc+)U1yRtj|d6M4U;wgP#*8 z)AGo2Ro%Xp10P9RUUeBZFI0s)t<+{v?2&jRxoClnDhv;+4WY*?+WwaRd_SiH9nJ}yA^=>Yg4Yk{0j8Q~bHL6;WfBM3k zXvh9|w}8*QwzoBQ@hmI?$=!$36M6;uZ^=3odyI4rgPgotU7iSf-s*xiWC`zF{qIDAzs3S$_O4$|r2k4K>Zq)Xqkk-6 z!Q(=r;mvU*AP);gOrdpW+Nejj#e@ppYRPlCV+=Y za;>K}J=bme?79-3HPwJ1tsZ6*$-`xJPR=E`kij3JvwbSQ3d^T`4b9mdCNSe}O~&2o zjr5m?ud`uAfk{BWG6YgPQ*5s>U8bzeG+Uvy4wa=PX@z!TXE-RVBRqztibKc#d5_?h zE3cOFRiD^(?NRq=;1Ir1gvFXKw-&-s=Cn0m$j>Y_rXrFc7X;Q)2_wmkdOVp8vuCS< znQTCNc+Rd@7jfg|>+GPqq5+5`iE+%x-dU#iSLo{0Ed0K?OYKMq5w>86Q5XH@4Pw6> z$pVV;sQc6Q-Hk^2k1;b(i8_GAZ_N;WG2km)2)t2njfSRB2G-qlxhvg;sN(n>~G)6x$Upwqo zP4g)c;A)Bb1l?6ss`Wu*2+m6|mu1iBsvFqYt9CNy9d7k~A@&Ja{rzRXE?A09EJK|X ziWz)z-x=u&h4mbSc|0NDX)x*s;z}5v+r)M5L?q~2&9yyr0d%aof_Ck!ws>a&p9@{# zep~F+&nMv2HA|J`mv*P*nI8xMU6IyS*Xe}2YYW|T?FA}xg+;19StCRCUy9B9LM#x1 zE?zVU|B4GK2X$rYA zR;~p4d~OfxaXO`H4S~q8t}N+9szjwYR@-O#qzhyeXRE!T3>r+`5hb2_C>)p$I-q0v zySu921fBqK2Ln?0wZDD%mwsjhdQrvVE{H(&UUTz{+-jDr>n99h^W{BZvazB_Ao((y z`$N8chwG=!O3(0%aD8M%5FG6p&|!4k<(3+_j@$Yk;EHN-g32kq4L-@hj$9Y0Mub&u zlzn{&LgA21%nzS*9JYELYu0>BrLZP>PK29T7_tr@g4uT}D-X%&Ufp&iuGsJwZRb>t z8MhHCdk>FFGBOdv2?oaVfjtp$ZBX~ zd}TF1dnTAu>~32i8Xlz+Q1+7~DO*0%wwviZMoY({Eo-&8!xXnCcRP9Jd#vn%hXyjZ zvVWEdcxm|=_t)dFze0CqucYa96lS@moK54%YpTvzH^xlga);5UsJW(@qc1fD_p9-V(96h3X%} zFgyhG(dG?qUUir4cFgwG{)H%&gMZn0s9ofEeU6_#SFl}t)zeFPs5dV>12WO3N!(ef{?@8ct(G#p$3e0froB5$0A z5<|NfhD;lNOA=BllHKkE=!|Of&w#d0TGw-_N{@^`jM)b9XcCv5V2H6Z$Ns5Bop@7Z z*;cq)J}BBV)%_>w?4W*kzAJOt6QbN8$;%ps7b+aRFG==&2nc$jOGFh4(}YFQ)RCGY zC<(zFjb(*4XdH+D)#`YN|M=&k90Q)R9zt$UZzECjr&oFt1 z`1Wm&<=Z!&|HD)GpNFscztX;(iCv=y=Hy`FWL46V;9#b5im+0@gUJm0NPZ4V9g$E%T>xjI}J>zwplRj!fv9B**4rU#>=_FSD! zPk3MTxJ>h(eP($R^1D60D10wtsd4Q8-5;z%{Np5eL#KelT`{;aDB#x8QiEyl$7{=5P@L^ z*S38P+*|$8ACw%;8WzXNHIY~)PkSzoJq9>365w4G94Yg3&t5sA2?;UAS}s{T`r)>y z_JgHO(+D=D;ZtX6d1(nbC0gn*L(xI!ue7Bev9<m4xKni>oGJ>7 zZ_t8veTJ-R;gD!`A59g-1g=dU>IB31nTc|rPs;=7sJ6aTb?np)?m=_h=RH29Ob~g- z*$IQaV03^dzOiW68T zrRc~?tf;G@!73iD!zhOyuwZMeWV!fz=IE#t7lObZFLD)ahe+C1rA-T*pMN6oLEN-V zE?;l>L!K7zq1F34izT(IB&aP|ua0$%Jc#{vU!zS7FLh7`g1ee-yTj116^lM^raF2_ zcU@6uQJL0+I3(v8>o_*bjI;_lU?E1bjB{fOg1os3q^Wbt7gHT`4=-!mwJljgiP8$mXRdlnS!?$pu(-L=Wz z<>=&#e}^*U5t;J@v!Ai5-Q5lMwCh)LGZbWXqIr?!m?QdQiM+rE@Utek(humV;uN&7uxf2Px!@b2%4eao9G{b5P1z=c5IvTBRktjCzZJZ55ap=4NXHxT3NP+T|--vpL@3HM~jcM{+ zcGBPvmngk>Ywl6M0N5dUyL4F9&`X_NY3FJw8GupJd61p3-1aU49jj0ee3hmCMbmj_ zQcD@`^ul4dDbjh1?{z2`}V2^i0-o`F!+L&bENCOAURpzK(uIg zqw8L7azqnkzJ&M7-!k_X!3@Tt=1T}m=!|zMc2&N^1pj#KXkcordax|^JT+g~dAc+) zJTQDm&YMYLUZFk&_kP@K2QUqF8$i?*oNL=zw&J~XEGSkXC1^j4a;ap^`JXW?F+n0+( z!>b(VuZPE1+(~pRyE4)H<0Yjn(k0O%0HS4;f`8H1EV(=Rs^#C$EJasln?u5`@l9QL-JKTAdZ&F_im^GRgz9mPgZw;u&f#r3ldvUnX=u zp^S^!lzU1peKzVU`eXXTkhxY#G>+Z5xi$s&(|*a>qS565xnQ9d;3v9LLZgiAebj*( zbi%N%)NJT%(1hr5j>j}m;GV}%b)!jYn04{?XUd!xXOmwlIa6PzB<3?V*FODb@?CWP z4IC?!S43J);T{mbU2BXUniXlQ?i`AHRMKKyy`j)07P3tV0Vj2JrQ)3GtGT4IRBP+< z7SZNvD|vja>P&EZwT*Ojwye7ZVDAdYXE~dSz%TF#%IafndvM3h*wQm-<;nPv{Qa?^$g83&>k$&J*sS_;3tK;ODk|2H!%2p|2Aw>!N$g7 zZM8P5v(e}|fX$xrlT$yp`T)-X4zJZ7@QG&P3gLXZDPeB9T@bqDr|B#$Eip&VJ|BK1 z@|B$u;t`|jO-@b`H8=3hjQ+LNQ15be(v`k!ewA)>Oww5t4R5QjD@34vgY;1W=#RQS zFGs#}jOkZG1Sez=C_gy7fxhS4JZo9CWO*&crpPudl@FDW++;4!objf3Fxg~&G)flK zNDDN|SKee5oSdbpAl7tI#mNxVf&9GtNh^cCUowhSIAzkyU!|TuQZ2oR5p9F1t{U9GSX9f zK=b;?hV@>bHkW|0qwpXrxZ4GJ?B3})+H^}4V_ujT}Fy+pq6^GWOPZ!bb7Rm-wbKXR+P7N zOhMb-oM(&r3YTr+tRBL>A93=XM!CL{6mk<1^s{%dWA1kK{NsHb+RC{D6McjGn`i{Lc79(n3LOCw+PISJ2)>AO zoZXSd2_??q4bF+ z{96M?nN(q|`N9QnE&WCo<~t;x`OVgHEm2c5`D|chrrGcQbjhiTc6lkeTW&+{9t4W ztBx?F@cD95o8V)!Q$_SZR7e098n+#LT)6r|Lx)lln%*Hi zkzTD1Sgfb=Qq^XAOsqQHC&1A8Ac!A0lyZ$xowH*K>0z8p8}8If#Lf=0 zYK+0?`65-bh?X*3#U7A-8nV*!ekxw*c7{_m>QEyoTWbBy0rxi^4&qx*fHSiJKL^!i z8BV?QTxn^nkbiKAY6Tu-UL&k>Kr(luIV-8&U2Ah@u+Bw4XpB2VzS}!!%=Xn1Dfgdv zh;Iw2ZEq&{>;%U3Z*hKG+2KJT+Y`YZpesO~&DxOPbNv>0Y6F~FkVRU+5T%r+E7T`r z4#rHlg6CS7#KJAlj_W8$P{=$c{(g^m#&K5f7oYnv?#S0L6TU~(H-2hQBj&c3aaw4} zy$krULCJ4>K&-4m$5;4Q<$|HF(t+j!#v3&~-EXHq)A~8#J|7<~MH2Uex`yo8KH?#3 zw-Knp^C)t0BrPxhVr#jG<&`BZn1&7Azk%S_unei!Mu)u*!BEG7zwr|n4Fc~j4;Z~! zctc1sFE?ZND8G66%P!p|VtFEe<)uaQ;7}_Bh$WFX9VaIu&WiY%1)?lWEok8cYSqkY zO}GWLZqnCp8kToRlL{xi;t!N+Tp4lH9Z~YFC}ezlaQpoZ+gm)I|ERfLU{8?WNyv-d z8^Y|SKzadol)m?)bYtwq9hmv~!jqRFr=0q>;h{Hr@v->IJ+QzU(33_$Sa5;A;KGpR z>}+8;-3|w%vUhXSS(%s<{Lb?$d2@*z+ZEstA8P(#uD3pBtw?D^V}7lLhQA#*73G58 zybOzmi@%yFw2<;e0s(xT8sToCgLP%vn$qUsGbS-7X(o`q2Z>F`T4_Gg6 zh#+!pLN5w>^=yslLWWo^c8E8%AM#7ScE6ai6Xn2hzT3?jPD}I=>rlMX7+gsh?qb{i zFkW{xz^cZC?{uL8ACeH|=5UF@wBQyG z^-CY~h)cs-(^W}0(a6!u%uM+px438Ju<-s^j8EL>4I4WV5+A1`pi@U&fR}tm?^g?c!sdKnpDwGLz@0n)h*8 zk9a=pbMcHSy2pv<41;IwyFPaCe39tX(60V^g>+Abhk)1~5p)U}7%+bGxa}Yec;L!j zy7l2Y>t4tjRBZ0Xp zH!GT1_d`!jZ%n#RML+v`_Su+o2kkaz zQfYvU@EJ^+)*Wn>N!}iZH6ZW8)wuHj2vwY<3U7UW6)p=wvsU9ZCW(hWmO4K8>;XEk z9?ltyVR{!Dur}uiA^9gqo_FP-@%iy zWCnOYbVF|Qu=$3AWn_E}0$r>Ja=O#_aDy9nY!V~YR{g5#sVDoeG{L%jAEqeEU`e9S zxklC=V;kIGd#}yTQ0}nJ{-|z2bRLNoGH_mUH~COwBwJqq6L0zewiwp_RYnU1#LU4i zV3NaMM|1p&EC>$8O|9%DYqu{*KvS|AA`Z`QBhI@*+4T~sx7!0BoJA4lFE5YPrxm-nSLT3<7|3pEhFuUjAkk`j$Hr&SD;IWz;xTu#~An0 z??Jbm=Hay4*OO(99I6A#BVC3~BrBW~WN`#fvM#Og9raKfpDPl1EKqC`Qm& zDn7SAz=MlSUhk;1;_%E0#p$J4!?x#l+9zm4W2;syMO-PyT@+59outeR6}OmpbCi4{ zr7kmN;&F9)ePMm}$f=h$6I0B*w3Fcj$ZX8s}bR0;Z-x-fq`L* z&LMX&JD16Rl9*s`-G~;8B#t5NKuLy6x*)SD79H4MV8FoPaJhw>+cyRwM&6y;RIZ0u zSRt8;X4NFhfn_L>xN;;5aem&No9?;;Md6vzsZlf`${0_WGdOFLoPkH)>!Svv&Ie@< zE!#7u`<05}s$z7gN7xO~JS7taZDQm;iP!ZO@p~+H(GH{ep=X88xr+Wgh5pqH(9yS} z>^v+>Y5FpU$HH-!zb3gzzWIOA8FzktIZ+0dYtQ+77|)x68=jRAJ=#KZs@2|-Gt+fI zTegPt25Np(pziRyfVX{g1oU|o$f}WIWN=-i(g%6n9U+x#~k#7m;kc1rgye;vvo4CHMaW6b&Tz7oamjL9Zd{ujO=Xx z!HwKcP_H8FAg`TKuM?UK$WHvez$toE&jBZ~S34lJ!ti}@~WsZBl4_A&leSbj>3 z228a&s}>-tjTSnE*t|CRZ!O!OCy;&@<^|}Sv+4Z*Xh?^4i`51CxMOb@Nc8#($K<{jz~WlduLJi^RN9l+G# zbeM0+tC@8y9%<}{Zf z=5Cke$Tz~Hr(G9`j2R8|e^%lpSkq0Wc*68Gvr~E;a%TgVX8m(dgNeTmF>S*OAI6$U z)neZ8TGk;4(TmLn&$!9AqakJKX)AYjq|Bw!RD$JLb%^62qTkq-R2-wz6C7Kg(;#dg zwz6c-bW`Uonjd!N*G*3&$^7@Pl*lmCW*FAGG-lBaRIZb{x5|J6_ejZR;6+(#cE4p`|3Uq0lY4bZ(zp*wr|VE1V>JO9p#Sa>bH&qa z(HdvaP>b$G5@k0uY}A!HD!@DiM^Bzl^54`$@l;ps|Fv2AZonyob2YL~h`*cvM?7B1 zSFGGYMXq{NnRO2JuLw`%<{W@S|7Fj8ixm##15L_XKInj~*b;7sugd-V5Od2K=f2bi z`h!K}kJsukf^cpGYozHA@FNu9IROuTV*d^ zMnQZxLr4$;{pPkWBEATsvoS#*&{vYaXT@BK(e$}R7)<8G8O8_X8sMJ&{u%cJ&h0n2 z7SCGF#Po2p%7JuB|7{L`Sf#}hqg_T=MM6{D$xF}=hBO}Q$)Uc(TgKx99~Tl+Rmv?V8&w2-ncsZwu(EeF zZPXXoe-D%ed*|LG2!Mc;e(=1U|J$J=Y;Iy?<@8?@rHUI$Uq`j+Kk?J`)I*bOqH}un zLNcih7ws%C)NGODddZYn0(lXn3DbQ7Y<9F}2DqXQ;--M8W&}D?QaiCo7U*AKXca_^ zZfZb41aTfQa0Kw(OxyKTLh%?V?PccsRmTs!YlidL`uT3u@9GsDXc6$PLnxrwR}zSa z3n_~63jfwgq*t`FvF;VWCr`{V4J#Hf)_{~$e@BPL5+vFt*c2XwBoAH~AL7n~?e+(n zZkPqez*lp@U1tfFAICs*P{MPdFKjRN{Vicz!fsys$7xwmE|Iseat(}!3KxOc*zDd& zkI7`Is{l&|NIGXAKqpiY6WTU*W=OaZ1%?QS{}N!yx*<<+7{GWECmC~RIov{ufY+LZ zY!136{H&y*w##rlw#@O2hqu*`sfaE%zumZ3pNo%LuwF_eG}s-BbLs(?c9LGJ?sEj~ z+JYoam6JoLJFCTBCd^{}+&`b(i9@<(NRY%%)JPNz%M&~Jqd$m|aA$dl zR<*E4N=YI(AAwEMSO%6z^S7>Z0t~J8cQ726O21f8M1Sk1Y_5e5R3vgxNWDW8X4LQx z9)`gps4M#6RO0Oeg8WFWo04TUh@o^E1Nv#$XUu%_@Mi{xWbLVDpFap zFM&2YvuCq5I^soga+Ek%BAsL?6hfTi3u?aQ!JDbR{g(w!i=+y(p<1?(kB^P0CQHva zPm#bVwBoK*V$w_Ms&AMI&5e{I6X4-RdCotJF59XP!BTItCYzzNyh@4Y3c+$V3rpKL z0;d;HcAvx=V>X0I(|E(iAs+0C$CcMWsBC!2ri?Acf1hW@gD?t-&$7QA=P(QD!F?!= z(xOSnoSwH1r8`^I-^TUO+a2)GDcr5eftbaOqlLY0#jU-8#3l_O5o@H!zGeqrOJTQt zfPj*om2kg^<|Dyp2Tl+i%x>v>1?co{uFWjWz~bjOS}Uy~pRmmgR!dsbwIY6Sf%;dj zclytrNCzj}ft(p7yvb$j&&YPM7SB$QSO8<6PYKRJzZ(by=fPwAn(L@$;LHG@)-oC? z;wG#xU@k4M^Cn0{TP6ZltoQs}R)LE*X5eJG3|esNiwo=YkdP$DAj#rENl){alMqk} zPJ)LpsMS~RoVbZsJ}U|wCEIZ~nWNH??7J`h2`$k?E|J1^qlH zdMSe@SlGjU;pnGYFtQ4JNEE`s&0K`T`~rcBu{NB9xAdv7HjS$M+Cj**Y+49SU+H%N z=+q3r*|!qfwoZd$n97s@7d9Pjmk*>z^rj82 zo%5X`6XQ9DQr_GrS{~-v)RLR+ZiNWIqX+= zX$83=)n+lbAFVYEz`?TmoqfaFDji&N5f>5O_)m+ViP%Xta+h|1o~@^5E*QL6=F zugK!kc^GO3&KK=UP(vFLNZa4;^hS1iXR&n-gB=-!CdSL972&EBlF44ev3a}hGI&Fp z{`GQt$Qq2MD~cQMxdWIg##4!9f0a zj7iui9HIzeI24?*KgbvZ!rHT8p&=5#cmofw4mtx)oZWv{=Q)^3TX}&nU(j=Xp#3K7 zsw=3-*Xr4kh$F7b))Cwofvqs5byp1S8IXn~lks(9;6#)q%Zx6fCp22&O}z6_XAwDM z6)l8Ns$*@82^93C?F|~*MZ^2*t6Tdg(@9*2^>qh$AN3<@{H`G(+wNs_mknLngHu{o zSj5;hIX1JBT}bc8V#trAeaz$nCjLAiY$mM9xR#59{~XqWe9>qbvgkuj1 z;{AXRo|uIv99)a~1X{2lng;fgf@GiFlH||vqyR>WQEsc&ofhW4>58*1)#r|MSq#ie(IQGQmX^2B5vkVUGXtI*H^t=_UC4m_Rj0A$? zJDW>&wRGh!zrSDi+%b(8=h>cMZ353j-`i@UUM+ z6c?? z!P-LFM|UQ2@UcE|UkbOeoL%+WAliLh4<^eL4N?lR{x&a57TH3P5p##JIH125yP3Fh zje0}#oS81*@Bqeytsvxt(0cMVdu7p-Hj$-1Mx8=cMQNFcN~tbz@H{r8YwuLFlDJ#N zkr4IYUh@1- zO@B)Y{NA_-13VJUY=yxr6u!o%bjV3qy2Q9V6DM@#&aN0gx{$?GI8r;JT=zF02Ynj40Stl zND2Kn-i>q5xKnB5nS|`QxqZ1AUvn{2^D;Bh?jtUSKrDj2iS(89N|d7|kLxqaEb#>L z1qqKof*_HTn>Mq;We?c3s%gp;pC!f&x2-KUk$W1CAPy%I&g0Fy@d9LW(aNPWCf(Am z;_}pb_69sC*rU*hF9Ni34|`j}Gya*;sFQ4b+uV^5N09MY{>)t@qN2RcBsL^h%>JaW z{?W|Mu)vi477NdA&wA0I9bHO6aqh;+c7Ej{2-~x%Mm2@{KbRLcY|ck-O(Re z^`jt0Z=YsqTX$n^);2XC+x4-o-&b{nd-bZqICxb^c{_H1%QqSZxH-%rZ2naH_M&rd z9?~r7GDitII{NYP@%<^9{jEdu&4yzCNYhNUD#Lh5@**DC9Zb;MOd3C7xqL4#)?Judz+YYeg-yVHA?rs7H_t=a4TgBKFME$zI$?|9nNdSrw1(2JJ?d6$p$$qcHz{4kvX zy|_eX$s5q9BG^nGAKdp>&-7xQm@(r8d@Lc07ip#rEJUlqv^@OrXoNQ=Ov-~HJ!Rl< zdBUvwo#hq^wbxt8A0XY%`3tukGTRjDuVQnM?jTJVi{#GJxF*Em_r@5%UjBK=r(+Z` z`w%v;E-af|%eH9jFG*ALy|ft>V`bbNl^|DbhQo^^%v;X&CTn}v59a;|aHUP_ARNeH zxHAhT|5Ec8b!_AC;M1gKV?u0%-$LyviCa6PSZqN?V?@)%Dj(dJu~Y$3fx`lELW)vO z-jd5xsV?5ZO(SAaoT=Pjf@p}f; z3-m#Bs0M`s%NUUVb_>*xJB_yvC1~oaKoIYc0t)VvWq8x?R7lfJCN+}Pf?WfovVvzZ zphA3z?6hllsB{cd0M5FT=uRczOy#@xilD_+4kzK`fhZyB9YKJIG~Ii0s_*|PV|;ezLP5QLV`NU+48LwV^sr#a2J?f##7n_@`xDT9oC!C&YbbW1 z^y274OB8Tfq~`}P1Ty8@sEtR`!b2UOTOcg*IuQ(M6T0M^V56c>L(VC3)+Q#Yzfu-C zgC>fn;cuVi8gbY`gym2ORD68@gWgS?HUx+ zm4Ed6?GnIhZVps^J4a(zUT#tObMypj(pA)s zGp4!^f!f#{8Skbci2xg0qtE)TVY=<+hY}NXXqi0itA&x|Pp6hnR#sj{6LPAJsLsdR zGNWgaW9TEz>a+vo8KNC@TpH5Wji(^itKH*Wy6vaOvlD$>%b2?&I&+}1o%8)kF3C^> zGuplSOKhwOD%UpF8rLVwVAkx{Zq{Be4Bu_>9iD5Wc3QlXAasi&L3ql-z?X3Hi)zx{k&cB?-!PX&MHDPG7x}Laj8jV|r|@tvrQADU zzp07}F(O+5$n6pli$T)A55$zwr8EhbnP>Cp;2A-G_uHkO?qA;7NT6H`a9Ht#f*0g7 zR#T(Pf)>{tw9<*$`WH$W>e|r@TI@4HLorj9u(D?471eojv)`A(h76!GC}{|!kSp)8 z(@uC%@nOpo#>YY9;A^qSCShHbHc|^niLL|HaNPcK2&St>y{1^QvbwZ2x64~}^7>-{ zuiojdtf*y!hPg4BLj>O-+IFH$I~^ zqbP@p`J|3ygn_NbidE2Kuf2ARm9Eq5CHq%0Tc2?%fRAr)7_|%O6QcfvfO}t%1Q`;} zhCm8?L)nMUp{i95ZRKJg+yT=-kzpM1(9cuZ$0y0_rX1OUwzos^iI9e93!i_oUu^pc z`&RO)Iag>^&9&bE40krkt$d$6=x;#9Gwrd^%A(1%hi)7q`^7#pE@wC)=RV248u?|z zKTkLIKw9e%I=~F`ip() z{U@ltJ*d5xLz4Z}ualyF%Pn1=1-$lFWmpu3{J7o=a&ETtA{x4wT8~dIlkIe;wzL_) zUP4`CG53U9{iq?Xf=ERNb^@%#kOb@``A!1MD)X!e)rx)0p;u<~qGYJ!L#ivJ9phh0 z+wGo0{k-WnKj+? zEXmnpc5PY3o|#S`m355R5N%3-$++It(WWtlVw-xLVU)H7l~a*M$y{_lg&_i$+o(Jq zM_HoIyweEIT^KRsyD#x0_gKauZ`>LFkzfoehu8-Sd}#&8Ad0lOoZilEVM!J+7r*5p zy+OSxiNdWL2qUou`uz(tEAMeAVz_%IYBxmTP9uNwiEr7?vWT7w`v!N5fO8p`SOw-p zuoKlTttwU|u$nNxvi;n4_v9Ac+d-lvZ3q+_+&mFV#}{@XT_?4fFg+P~f@ZKub8%(3$^e~|9LIS{ z$|^&_wQ+{Y61^A&5`FFa`qTRXY@#d4YvZ`xPefL}kT}pe)@~jcE33tY=^G*k+Dd!B zNw&`tN7jdEJ{3~w@ekc97E*8_=j)qMF|sLtPKK+`P6pIgBcxNmC-NECx-^P?*n9s3dVZ=Mcbc8T{&u?p=z1x zF-*s#G4VEIX3^gJkex$n;;V(H6X7hNOxz9>AkJF@1@XT9iAv2ePQie;^!q3}8;RS*|{GA&Tugme$IfJ(qBDmJ5mg!tvQDa(Dx< z3QO>dXhO`@an#iw2;g)!C2cp_g+}7*D0ERGBpD_?Egyjedi# zKswJEX$Sg=S;l)I-s?ecqm{ZyCv9@O8No6sJUrP*UMSYDa{szox5gZ=OHcHHC0cN=< zw3Y#;jwFd)skAw6m@zX%vAq0&G20>3BTX%q-{~P-muk8xv!DVyP>v&(4}fFc;xuhL zoZqYkMW4{*C9kX((FB<30yyv7M1-nRZH|B&sAY#c*@D0*$zO>N>As2>57!-xne{=es8?6fq8(wRymDAQ zffv@n3K1r`nFb_x{A*Tne`e@pUnp<8v}oOdY?0dASlI!Mylcl#^ZJa=TaO8lrQ(yLyfgK1@23I%K84F2 zhy4~b6(fV==bHQ3OXfz2elnvxIzRB)?w5^UyfuBAmW_J(&AT$wOzR;y(6$up%rzdQ zy|OSbq~{N%7n4OExP!l>LtQkK`7H<3CXRn|!ueG=;st8VfaBlZL4Gt?rg)`nnE1Z8 zc%lC(-s87rjoxRdWZjwDTRwdEzQ{gxe`2%RN6w-hOX04Na=ReoXptbhJYMcpqLDoC zwr#hu&=FETYb&=GjrU}x*-HrpM^nt2wh&Ei?YE}GW%U<^t0cXKe z3@UF##aRRkXn=K-09Tg-tRV9UL%U*DG%4|DOBzjqx?h@7&V=R)V>eRP9NcnhCIkA~ zqjFS`1=)qdNvEyNLRd6Jek*b!NOE}%dv8*im_l2_5{)znV>91aY$kqwC_Fhuj^#Du z1_ELXyk;m}Q+B(Nyf=Py>=~Ci*~9*q7w&V6WtUjP8rX@?d%KYEs#6X#_`}j$PV+DL z&sheYhN%3fIl5;#%n|CTyQ~TARF%Mi-a-M^wF1>M3_&iV247NBnx;<)f4N?yrKoRT}6iWUJiGZ-l(lS&f2@Sm(=aV zRh#R^CZ`ixFqQ*1^?o*qyE?XbyT`oOVbN9Fnx+jXlNk68OS-pR%ot9Dr9_IVDB4wl zL1*r3AVSeCQ6m2pu_+>cO~wgbJ-5UJel?)l9z$Mi{dsGMEm*Qamel4qwx5RTK3)DN zX$uM~euI-yPUh2M?CZO{$jb>};$D4(X)P0lnf|_E3ZPwUn8ilUT1| zp{Gh4Tqbeb$@}HBwu6yF^EYWziI6X|OSJ;~A$-nfY4wDzd#4Km^_2Y{;|ta` z_JHqlK$U%J37G52jKRb_(LZaSpmk=NEHn~B+occaXKzk#Dc|t@u@}}IT}$c6dE~mV zo@wdGp@X~>O$B;N>q&A7bFf$M-A)g3=M~jMFEFl4LH;#RT%2|ed}i-CYWyGm9jEk*oHINf0bJ9 z4^w70)wsiCdv1p|^`I$yYQ^xETbH?-!OQ?2p zDpqy}X6Mwfsr=NXJSG1nAdBA*DkQR|6E6jt6o9UjUT;#(j}v?3@b{ z(yG|wA{QB*1!e$WA2IVf zuPs!4Jy7aBCg@Cl@QOWj4dL56trw8WK)-%T4QLY$kfT*OL0|sL5t78Vxau1N5GC|<|62%_yBi3pSm3@9Qw6_-ZgXQP$ifw@Z69q#S+3ZPWh_4wYc$T{0 ztOqDOM-LRy$pWJ5FA<%4qH{oK+67DNY7^dmbyuAIqwu^7RgsSRfZ&QErt=m=sLoC( z(MruO@=DL%W!C&|aP4{>z142oKm6nD|@IE2M$*l;z@KzI`)xXr!5eh-~XQp z)Ttd8=1^|1^kxuowT8?q{o6{Reo#YlQPmA-1Mp07WjQULGTf|qe$9UbeL|B-6L9*xR2YTT~ z3$x-Lf#+3}?E0MJ^t9dK_V~=-^ZmoI*>NNC&kKr+Vryj9VSyX^(Ibkp!f3Z^0yIp- z9dxvnCp;#cZ6*|s;jHYc@2t()gw>~O@3dQF)ZL!3=*SXaN{#_0TZ?ziTF%M56Kv2C z`InX<#3g`?w2Doh`b?-okZk0BrglPRnMU|NL@JBwQw;}Ib)z&(p@@M}fVdiI5so4h zBUVjb=zF0kP)N*Q*brkB=)pxSs8Y;fdDpM_gJ4~X{nJDT>`z#mmn{`DQ4v!K>TwGjId_UxXhV(M*WwX|-TNrPegem88S`-WF9Sl2@^i>Gv z_)We87D`$XED32uQ3YCxtdU++O(pYd}k8ii0+ZYs28IW@A--D(9=n#p`jal8>&DXk-#+e|33m+kQF_bmCEA9yqO#kw*~(f}RCbd|B4P6tXJxk< zX3TJFwuOS_$J7J)>f6Sw)LVR8<{;du?Ba+7bH*-?ahC1W+h6FEcRVs!TgyBrG%KM1 zyS0pcd2>!0ZzH-fjbS_~s0@WgX>PXSLFb103W2prPsixO==%-mP#qIYF2QQMCh`OP zD`p9tB~Tk*qvdLosLp<;xA$u zI}Yt{9)_FFO#>QZEy(L~T%nH47fEp&^Fqb(vJEWgbLgjDj>%p*7KMubc001bXRjYk zknx&Uz!P^O<*_{1;OLGncU8eZtswQseW~Fdd@+L-pv^W|98l;b-D34zE`w9z&f)?! z;_!F&AKgFI3*#5`egNBtA?Yc2hANtkg#^o;pCpWMwxi%Cj6&Xe54(WHOT?KKy=Gvm z6Ri?d#{m{rA;cPI;2mdVV5D7jdZMrdW_7RcO{5;chdvNbHuGF#j*eRwtbTd~f#t6P z319RV@kZn-@s8_djGN275NO8$$yg zds?vicv`^f?1jJO(|>?jw>YYwp!P;IKy-zFa)IVe6%?dg;mw#!e|$g0!xutdcU?z= z1WkY=fixrzYgXlAr+|Tgpum8D zejvjCgSO>==B9*+f$>knH3V8Wvu7witjX4B()GTAos@E%(;0%WRB zrtn7!juB6_%v8dIhs8}dmb?3ti$!`KLsa?3hi(#%C>zg7GsN{&DmLG92i=QDA5-G7 zivIVqEmI8kAS(_npD<})K}bYJDTdQoaMNq& zqott)mF>B?azuN*p*zof7WMWEVa zoK$0fFNMa^U2NmK$CcqI>qsyy{#S9$j2Hg%LO(n(J}I{aq>(d#I)T;_8OWeYC=O|u zQSc>90s?Rb^WqNb`aydOw*II60^Wf&^D>Dvg3ihFiEZNn?OMa~p6&)?6!0 zsnD<8@8%wh5R{x&RItbhqN&BeP@Ew+W90c3ud`sjG(WU*PGB5nz*X-ZP^w@ZvVA5| zz@*5iB77#b`~mvk&xh+y@W(a`5Rf-E5D@eK_I&);=_uBOa#vYG`?|KaGj)$+AdLqV z0v3@8V2C3G2#$*B6T+APW0(D3*IoK#q#ZfvYh_avZSxYHmbRi*xlOj3#gL#-60~ze zm9CAARn?Zd)#cT^rSwl}(1ZzA5f*MI^Zv@`$1tAzxcz?n;zz&S%6a%&D9liT924{i#R*Q#1AFAxs;WvzRnps=?6-k8*1ak)rOJl76E?}&KEd^S+!R`$N(t?asvNKC-)&93}6LjADyTX8d8p|i0g(m3Q{@&e(7 zm=K5|U9IWCLh+rhD=|bD^1mzf*{eB+a;k=98G!w`lFfDy_NwI?7R~O;_?{O|{)Ybd#_o_y~Hs`MJ7Q6hmro`mZ`$});E1J!!2;;jFmvUFkr#XswED0exxAWJ5 z4y8`WYcehFyquA?|em24t{)o^M#Z7$|YrksXjhCrkYI{5FWP(M>v+MWBUD6yq>AZ@BrKtCcDPqNq1#llJp6-goi;R6gvLiA5@vMMYdK)b*S}`H10;@n)*EN>v?Jq z6>yN}KB+r2GnA#+7_G~czJPR#xe~9bX4DjVf3-V1$o5q3(YQvw#IN3*{F8AdkDdx# zukT$}^vtrl6ERTF;m=*2vAGfX1Z)Yk9M!K@o9@uxTcL07VkrDehZhv6j*qP%Jtzl2 z=p}o-Lto);qn7d|BpJ~1@q~S2q4UBCcd6Ejrv{ginE?ZZ4l?V-)l*lOlK?tgv32Y$ z^E%er<`SikK&999cKLuZ{!vJN%_RD!xi-$-ML7y})CBZ-g)AkoLrbK8C|LyLRj zHjJ&b{VaWya3Acec<-8agqa+;s4qkX3%fR|lqCq-)xKIaI$33upUo{E| zDs>u=vg%ktJFjdmg;q5pJ*KQtSzoYV1Vw$EAi2jYc}po$my&CW06N zCCo{lH|hYZ|4;|k;UKzY`UlJA*#sHWWo}NH-OUIsMcd8S(IOzg?(QVIL6FC-s~ajN z*r3wW>`@JDjD@zMB@6pjm7NQA8)mF9MdulX zlTxtbFV<4~D06~daS#6jMD9cHa{dIYl9clJwLzMZ-pIT?j@Wps>jYr##Ga=hCpG+( z;|_O_`FrCIq&n9r)LHaK+$GCrnBOlBJ9neHgte8>yZ$wgp5M0?)DWYqXZ5P*PUnm- z;`O?vzq}#r{|-a(rS z+!9ZN>(&t$;TQJTA-Xz%OC8#I-9PO(32idwuK>1nHU50d@^V`mwroD+`R5 zYp@AKqSR?k9-{kE=(O|uG)Z#9V#R4D?)nKD!Vv>L6M>^6=rr8>G!y9&DGG)RPQw9u z{fuWloPur0p`_sPQDqJX!=$4T>Uu+H$!d}rG5tW$bE`U0`Gr80M3BTkO z!1HtFK>`?f>x$wyfP9)ILR3o>P$J0`{E8J*D1$5BMM#BgfY31Gj(~AwW6Q%sb|(a4 zPcnA@_%h;4d0Z}>(a*7kZh`m4d<_Pt)A;>OlH*#EkgxSUxg)-4`=l>#3&7Uw$aQx` zv!Ux>kCNN4HOO;8V_%92xJ?-FmGEa$@u!U2H&SG*D8fya8>$Qz?6>Qa6Y)s6ff^c~ z(JK)ZU(HID6B&!%44@JkJEI)d*Ni}qe&sYymepHaHKw*jW33k>+-|U(ZCR1qitPiS zWouxp-?oX7V;7z#J=o&%=47|SWtu4(?vx-I%BBuS!b!}fx}&u`g7Mjdy+%?j_#oD%NCCgD+*dzj4rZr{!TtN^e4QM5SXo;QQD&L?6)as4GR!(l(T}! z!Rh;?usx?FAQhsaf@v_ltIhOu1rr5QUyse__k^||?`57apeO`NIC2?Bl%bIk5lsZ` zlkPfDa{PL6spc3h9?MGz(JY!5@{6LCqE=NM5)csKwm??HVLB2m>?ZsL?0v>@P(kX#`hIt5{tzp3=es%$u*L`}NCsMP54>d#PzFIliw2 zBYLNUX?@H={*uQX!ylJe_K)^kqP@bV*$Z0vt$+*$zqRQ(W$fbu-hxqZ+gE6SXi5foWl#J!s zz@mC9yFy2}T78$=318#Nnf@8gBYg9DXG314uEaV>z8q=(;*)YGgT4gs?eONAAVm_PWNeoZt%Q{}aloVt!Gc2&;h*Y>o$3Uc z{fB1WUaetD^qx$}Zx1vd-are&3IC?_ZL~E}r3<2&<%Al|r7+P6Wb}CD@HVDfaBGbF zLbHeAB{cVc|4okV?57_43i;y)Cd&WKaazXN$ll(}(C9xIqb!wI4^$www`j7OhBl#{ zEyn~h6u{8nTTN{h4j;u3`getAg|QE?Pd}$ht9{8;(ZuOa))l|yqJEN;Exq1I=1e1H zsxU{=clxC_xI62$`2D;~??fpG zJVm7$&91678>8z*pcEuXMZ4uP!V{F@poU1fT#z{^BP#1}aFpr?G|Px2HE8di6=z382qd46g)gElu{Y9I0e5;QUvvc zEXIYrt-k?b8Z#rGu)gxy8R)-@=}aULqG301wzuP{KR46@7EPIKGs0L^X=F9}GpG&8 zSlgMi)ys`d#ve&R&%xKm=5J~z*0L)q8~O%CEKy3QRya?O#L-PP2R$ioMuW|_qUj)- z(_2B;B`yf8b2kr36p{rKSm_{L6wTaA!a5R{spq2`Kd_eahJo4C<8?4VsMbZb@h=#z$OgHEU|*Rphcx6DHsbesaRunzq3NNid5|C$~$O) z4HNL>-dWdj9?r-u^tvm>UIM0D2p(FbIxHUU{ZYeuJbKtwne}ctT?eZEgzRg>@E;N6 zSObhoBy%7xvw}tIUTM$8AB_{tOarSw-O^7;hv5wYcp-GQqSz*2<#-HM;O$?HNkkM% z8vs32Tet(M)*G#6NX+)_CrOWe8DlOfYYtUV7rU<7$+VHkcf_ zv^zDw*`i<7_r@o~Q%T41_Wj2Io*;%&4gaL^d+=sWOkiH`=zht47;@UyD9xGVOTAxB z>I=1TwKL*dx7ey%vD2Wz{*0>qYAGVzWDRtsnv^4j;gL6uPo|e3oJ>JJ%runm^IL3| zQgfA|2TL1a=)3ye4MY>`rTV zP&Ct_ro{kdDS0QEhxEDnY@T`l zH+@9JsU&Xk&r%9U1O zkjo|+$P#qCuD0G}Iz7q0smWM&wla)MypR$?pBskmUu5G6>XYw_yZ7se{*A$tb}0Da zuyuK9R3qMtTQR?OQlh>3!2_QrC&dl)AJR&uoxv!eNo^djMp46PtEIEQ!=d|gtE1n3C z2kyuZ zdKa{8_XDYKvc5`xi+xd5CXur7xgiq<3bm*6B?+IVbrdey=sa29&&W3>7m-ZNDi_Z# ziFT}5{vn=ZP&(hA!@lGxbA}M^0@V-ky!|no#yB;1Y4c6~9MUST{xwQa?P$v8`Ui)I z>BJ{Zj*iEkd?p2Ss&YA%4j!rZo5ez^B?Pib@nkhA|07D>ypWQ0&NHV^ITwdv z_gJ_rgi?vwobHzo2CI|PeQGv8eu~Y}wOnbQmZif?e6;^lpThp!6H30&kHt~?RQ*OF@>rD098(4jrrNnseQ zv%9Q5?QCV2XVTMW^LXX_fzWgO3V@sZgQTHoP$3-jN?2L)WrAM3Js2VfTz!bX)z+r-2fz!&rvPV}6BebRgtpZd#8_3Y=Ae*HJO z-;-gJ8uT{^!SWk|{XfI+{;$%!ti6q~nWYgazk#EfjrD)pnu=O7sB%cWEt}5k?P9Nr z)Re^Luma%xgT&2C#6x$;80knk$#A-VL^Cuh0MqYp$*VF^Rl!NnQT%t8kt&0V z_P*B%{F0zFcAVueJ`C5aaNVwcac!Ccw((XIIf*~P!`O+uEhsxS2-$qIWAK%0er*lD zsklOeb3(=XyZb1aC0vW)0}WQM70MH2Y=b$vyhCmptCv%V9@kc47Hg9^>mr)0R>(t9 zI*lzz-=ESQ`d}=7hhU@Dd$_LKinLcDMgavZWm`f-D4H{6Y~%f~WFV5Lz;LL)98deq zTK&;gSet1Qq9S#7;xxq_5m>8lA5uRNB~hcpb(lXDy(qy~mFU=-5stA(U+qJZx{-zp zTccG1v80a~^=!I*@RYyS+(iBnR^~>NL9x9=Ve#j6T71%qci#c6&&LBGoA<5MH)~;PcBN9xsTKX0s3P zcK99rtkwIcK&QyBpEf%IU>Ah;GLq+5wS#GhYWQh*7&rTcy21GdnGngj6{HLEUWy-j z4I9TKgQ7!x*_3!U$1QEg@H8sZVNjSieSxAbf#t{SB9|mPY zOqtoNAVomp?pWk|(DaGJsfT$ZvLZ|ymNrjR^3P`8tLMjmt?gI&DJqac{rDk)`hQc~ z|IY&Z&&pCU)4*Lu_hwKR88INCX~vDTvkbu!N2&-+<@$>P>ZYQ`)EIwHnA zW*T^2EZN?=+Fs}({!HdHziHjOU_IaEmhFADeWF9jdpsouB^yThB&>3reaL&w>9U*i zukDk~m%kHL2$ToryDEPJ8%S?4uFg|}4SOrjYo(6;)5m9NWGx2Dm3TJo7l^4Ml42cV zd9NSfk#SNR?WV{9k}~%A(5W{< zFNYu>?PtW^*WFkbhfZVX3^CIDFpDr2lMmsDEiV7T4L-mXiRUdLp2V@>l%DsW-aG3P4w_ z<-$^ZyzZupy8Y${^lD69ZxTARwyW%rTCt{@BZuDVyJF^mAjmsaW?qREFSFi3b^H)* z%~RQlN%Kd#&@>)j{`UshEd)ZrfPW7A;L1bl7p6Elst4`Z#XnJf$KW_pML1>@BYO^3 z9uC&ZollUeU~AyLn#9oD(Pb;62{2^BvyT=#&CH4@6xkJoLk1flL97-l&lqfnf-d1a zR|_63B%jg6XQUCyf}I7u0}{uz&xGGg>Xl(nW&CHJI=eUWFUc#_b*y?d%EcLI;JOi! z7_PqZkbT9D2P<|jWErL4qVO)(botD03Zz1;m^5SQ<;XRDV@@c-9|%VLdluS5 zAVAp@!x0?y=!g_0J8a2BF_D~Q3C;|zbH5QwM;oJ414B1-2&ub481=TJJUJgVb;`;{ zPJ`T&g2b?Uy>0l+5ozPTT74_CY__@;%MEjqm+&W;?*~Enf@zo4dsF#F|H0UmYCMIm zKrT)Faup5T=xtj&UCX89+O2}|sKhzRT|2x|S*Bj*0_48?EWvym`|A&yKaB#85-SJV zG#p)ua62s^CRyk0HJ-fBNi_$2&oEc(_Lonb%a#efW;j_ado1l{4>KoLcl**vJwQUV z&Z@m{HnWmv0#AkE%4+9T{7HW9yiqlr)Q*S~e*JKLTOkmCNKT)s1an=!xJ{Az;gWVw zdf>DIoHq}1Ub$H}L%FG6R+Fec`9veSN`j_ToOmRj{xRRb2WCS>1p(%Z-qzDa zsXV7Z3bEMPT@utg@KsNw;df8v0R?aI0Yz8V_m%Q}MV>T3`)~g-{51OOIx6T}=uoGD zM7P|Thk7pi7Nd0^D8S;z(H{Lt10{^OTP?`Z8U3so(sJtAaE%XUy=PieqZZeI+9gqG zgkE9*RG!6-s3s<`c&f_hc3$ZT&sJ@y58uK?8w#kIxmIA><8#f^|MST$aQ!6RzZif7 zAyz&6{#jAT2on^yYw^V6P;|2T?ma*@J3rPjx8>W#JqZ=XwP zis}CaWrhr+6^nHPhI@}+Z&zddX&#>)OI_sK4gf&UwTw{rMj!?@J02o#qev{(-YSrms{TDPss&> z%B1#yILVgZ>1R+BoMSiy*HALHw45Cy$jiSMk-g)YwFbzjzG+jHyMp+;EF@|HQ+ogw zNW*cwBJ;-F3~!r!iMCP@v7PsqpLu43h_@t=NiUe6ej~}>s67KaDPscZYN8epC25%D zJVz$X-LQJceB#T}JiHw87+Gs>>*v+~dW{Ve7+Dv+elEXWSOrzo! zBlw&x+GD#m9aqH6+-(Z8KbigettkYvR<1#YnFr92-BR%O&BWsu117fy5}o`QAKOsY zNX!c^B>v}HNWL*&HnDcXM|Oq_m5>(D6)auVwiV_{jS|Z$$?j~nrOmAp>pIBu2&=j7 z%F2mnNmWE38p*C2_=VOU1D752t04>bb?ZXV&Fr;3<}@_c6?lazXY;HRIzPSTQeG`y z!YsCA);5CtRDo8WyFRPjSvaK^IX|lROPFjcK}fGaZf}cM;e)50NKT}xj5gGA>@c?~ zvDg(O_j{_xUueCRN$j7k4{UI92Bs~ro);iHawxaVHZ)`m3B9SByuqdCBrPb6Ix@+v zjwPJw4Uf5;=?#vlo$2>*>*GOM%DgXI!&+*?SvUH*yhHv3FkC>~twc}!W&ZN-*(Egn z`fqBRrDqWHQ1~A|Msa`q`1Wf24+n1KjZFUk-Ms4eJi)TlSB341b7*WR zr@1Aw`N#8a8=YtJ&Gp8|rGFdGENkS7SDx+H*&Ue<*RRvx%9{e4PNzo*-;Twv-_$$I zJM74RW%V4`P#KP-jbO_zc1*drc~Ws{24ROf6TS!GjUrw($-QmJUCzE`w^K&w{`jYs z?X4<#By)>dPT{w8j!W1hCBfmhewtfh*V6|OB8bN@VN+9vOsmVwUc^pJ=sA?d%(o!~ zXHw+tZ_!S|F~P_JMSisxc@lZjGGm4H1GgjyLvYkD#7q@9tPtja1-&4Fp*s4Y-oNB2 zPH4))`I`=!A#XAqphH4rN*ZSR=x0>A3!GKC?S>MwY$7Dqo1z`Z|Wo$DMz{(sP zbnWWyUZ|rrTOGJYnY`ckk9n1%t0irPyh{)9GcqCNY8`OVD=l4ICKS*<)H_zlEp>sh zDF}WHiYo2g8#l#EjzV0U4pL?_i_McbnVB5N4Y&}#{D=!E>o>)Ew{7wJBuDsFR{KUS zhD<=8I2KzPL(3}K$Pnpam*e*iaLl*x%Svbq`+~bPg*zA?R&bN|6Jx@@ge%Zc{!=R3 zAlvsFVYk-rI^GID4ZTS8dg@rAqz#m(zo8rb2m zs%M`gWkjASCm%MF9#CWdTiQTE5=@yu-P?U~K0op5OzKuC zp(>g{nfl{U1ajiHdGhQ&lNI4v$E3S>Zs9upunHyE+8Ge`@Q3AA^u?eZxyXW@nx<3X;Y9(}C-~1YyQ#UQCW45HiAf{# zH~B~A=p$+3^?X$@Arbv+X>fb@+RUn2);^-X;$if`CjBK@iX98EQR{{9&u}m2mVq9u z`p}vV*t6njkN%O7x##m8x_fBY#rv8cY`N8OBu12(4jbb%e^5;k9{K_fp1TGZQy*>o z4El__a=E(@7fOLqG5zP$?VB%pN@1N_bxD5RK{5Q6^$|dI8KUeGef(icos-i@|r(&&nGpCP+do>n(f8jlTUfb2qpleRW9e;;Uat!30{;GiA#h z-<=X0y}_0xNOM*T6J=;pcRcW^a*gMV7QK}7puPSv7TKm6?2C*px(mm3$?O|KoR4p) z)W{zbFqv%;lJ^O#LRYiLaRu?PM}7Tyyw#Xm?`(~!VN|S1zct?$4Qw2tD;d^uz!We~ z@E>@#?f3dezQJy#{{)|b<;lY6O3wJs1~_>()xY{oo3WW1yeMF*+aXF*y>UITnA11Y zH8WNlug@-uBI`#n2y3u3Ssj|2nv=s-?C3v3Xj+%OEM6-BtKtN^M_tu-pSbm$oe!<+ z@KF{I!aUCTbbKQt*p=TboFsjA#@$Us<2|sz96laqSd1hbLpJG8idd{P;y(_s7>>#C2XbAA9oPl zQ}QSsBGC$$WQ$F`%cR(ER2n!g3!RdOLN7?B8T`K=9PAP&rg{by51u5)KeFZSS+S+o zsJy^mD2yH7QyJy1Pa_I5!dEKSXJsv_K61>A)CU(O8G(+IV`Lb?j({`w#(0Zt$ zJ(c?&D|4$wG%G!gpV$I!1V+RB-AnmFjoRmVauW?3tD%~bW=5K8hP%VV#TAFNg@^hi zpDyfvhFJI6BDUw(s52J8I>Z* zsr8Za$Cx`T_3FGsn6`&6-v)VsJadrqyy)Ej_Aa;9%6dhAcz6SAz~)()KgS$&cLxPo zgo}QBfB>fgU^hdYy2{v$Ed7WpPuLBW9CNjV03|gN*dU_;Cs@+^DZ(H}p=^^fiyaxc zf|Gc0J5Kh_ZmME)=)JtpxFl207qaB`b+b_Ur&I#{>0`HRK^&nkYEfSUhsS5BZD9M` zsZoz?dBgrP58oH8%SCpUwV3npDpTMV#eVsqW&*KIf|JAhFY;LO5)YUK-4I(6N2=`C6j5*D?eeBP#`aZ0VpNh-GcR$nq&R=NPKZq zlB5=Miz(%b4sIMoFQjg|ULd+5C%Ac6IstG<(9;&tHqG5~}z9`MFr5>?b~XYZwfQkEDo#1cRG zN3~XjFJ2CX_gW@Uw|QiE3Tzko7K;pv@nEx2XDhT>T_wE|R-p6=dx9OhRBmRkQXd;L zBg{N$jk8<;Z+4rlznrs%OZ1n7?LYv$G-ERR_l)Ne`JKhxq)4U`9~5j+$NEc>`Ju(y z7{|n9i=^cSOO3ejCi+WG8o&fx#&ZjMOT$@Cw2Vh^Bp}yD@H^HCzNIKa%f8*kOgVe2 zx~n#F|NI%oq8Pxdy=bd})lPHp(?J*QXS8|7iVI)M5wr%X9(Azah}DpYq+R3}M*&HitY zz{EzxJS68knBkNl8+1&hs;G^J4vVqPt>^mJ5y6kuB`zytP?(lyQ z7~3UE_t8Oe?J_EQa|SUUkO1PI$HR=@kP;J7=2l^9NvXKj&3AbB>2t_A(;J>{Y7kf{h6pzWwWH=k#&x4Kl5vBreD(1YJdNzB^)V)33b0eKieaGB%guR9 zYiYolZh8R4sAaP|)9QV(!!UU*mlT$3;(dBDXX9dYGHYXEbTVV3a&$6nBXV>yWy5lG zGHF9f{8+pk-kzJLDWM9cNlsW%ah1B5t%A&mt@!<}p3lYHt0=M6s^pwTBK7TpKJ-pqq>iwQC+}M7fg?|0q^al}A1N;$l4W-l{zb-V z7-z1)nbuUc1!sh4^RXiTM_$4x)orED5e`;87D{C*$X$j;2V}!qi!b|#?ye}I+uV|1 zu(`kz&Z*66B`=WVXRl6(`Qw|ZMU{}JwONieo&jet8hpkn`P?ZbC~&V;pK7MK1LohO z(g(j`XgZqSd@94}NII=jUe-hjzt`-~w?R}n^N3YHx*$w$hxu%{p%N=}rsx8`xs6dU zJAN%r_bRWXV2(v}mB$__h6U3jMdLbnIr7=_Ddr$FVM}JSHY{J%sn=TZ7A&0Buahpp zdYMTS=MvuDRNO&+ToWPItj+e)pYj z9ut2$CC&ir)rS{CxXEe&y+fVH&|23$mF+KumvZ4L{TJW|rO27wF5}YVwz@#0Y<4r< zZiv~UXxzVVHJCU52Ugg0Be4m{==BiPb`%f_>Vr}^JBobeFFZa_7mtu5h_I-^-oGC! zTNbZ`L?|oO=U4CWEqPUiWi?XDW1Ajjld_*) z`GamVJ2TN379v8r<*f97xrX+Ef(`BYkz&-V^1y`&HwNc{HeTiIC!X<2&;NmlX-Gx2 z%SL>j5w{<`LE5Hr9+D*OXMFvo+$sP4)g!j{ro@I)BoF{sZxh_Raj2?ioxWS z^j?Xs!|Oo$HTaXk_ZJbuO6*RQZY})KFc>>hc9F^ZkhbqZmNzv|yE=tV;KjLcfqrkkf&ZlUx$;UtCy;+0wve1nVhk^_10nD-hv0b*TVz7vIYbN`Nt!dj!6)$;R*0xXP_I% z(*_CV0}`~ zReyON1h$HDQ9CI@4^)rT^0HWV$OQ=FV4SOhY=gVG^w+%3nmnS?OSrmt3_P-1Tbo*M z&W&1^M53~hc*U9aV2d@c1m+=e|8_X0y~bnuM6c58ScgK$cqE`jUGDL(_2fEdr8RLL z2K9TN^kzQmODbKoV^ywAsvOir$QmnGMm+2FtCs+p*Op*J)>yG${ABa{V;UH&s*-fB zp;4hOtYYEF5}I#Z9J;w#-&WC7mIn|-6@6ay#=dG&Gsw#uvE`UCdhnPD#elA83J@X<1qXNxveMzR>&1FZ)@euA6X8wfvAsG~h?{BN6Sv!)IU3UOt*WmP)c*~k*&*$XM( z(9>R3!qZr*SIoO9wCL^>@uPu{*b&yaV%m|bxl>9NF8HZ3l6$MlKocUnvW znJdj1Yl4GUhEvVW7L4J9BYYY)919)9+;Uvj7jo4Cv5;c%4-2QX7kEM70<_M;Em`Nt z4mPuM8oZycd`e%jnWPCLJPdR3vs0X|ZxnJE90H<}Ww?m5+K2k}#REFNjuJOGiHNQz z#chiLS9Cl6;1P?oR0cTS1H3Sa^Wb#$hE1T94(hU^UWdwx zWSLMp{Q8RF3uMuZ{p;%IP+^NyNpYEsOTcMep64Yie$76-v|#>YRWfhyYUgGnyfb1z zEm46>reMo)T|8+QyOXC@ytW?kX_K>KljW7Q>HQ9!r{KW%ZP;z{30@gm`|_Qc*65&% zdI4z|?dv`>PtgGvCr=r%iS)q=wSOX&bSPITjh|llKH-G5L+}1^Vu^ksjD8J{N)_kn zDO+Ec3KUyjy#a*#6gXc}z?^*sj?m#c6S$rG$`y4g`L;BLRn0|`{I8_wo?#g>pq)Np zO>ePmG{*vvIz2~R_`XFRQaUD3?AC?L+s{SS!|&F+sLOacolMq8i0ohPKH;qlZNzq? zf3(;n@m$Zz3;I`5gRP{fpg{(dB0HHM$`3yB*$(2_9#mzil;Gg)Or;XCVV)P(F9o2_ zZV$A(&6p>ddCbD%zl!}9`H3SoYs-_fg&QB#F*@LJFvQcKCp>&q6hUXmws_m)Pra>! zSSqZ00`HoAxMi@JN?RS-Aa`LS2L}h^A2QYoHF6j#CTT~cy1FTxx~~D9T7$I_KgVXN zQeIfn3^EuYlCQ?h3fJAM#hLNR*zHdHno<*lC}k+v-Jpi>+|9F$hS{E2!K1Js7p4{x zE8mzX{O!akwtpw(u+bPVA16pNvrx~J$x^5JH-xBtr8cE_bw<x zB+jm|mQ^)R#u7r4@{?qVMGzjg=D(~|8g4JHOFgLA88(~ zcQ1^Fw2GNx#r&eZCI@@>h-Gj%vRbWt30E4xV<<)Cv@!jKCyl$-gi=3(o!S3}(SWdO zw#*M_RjY8y7{r-WqP1TB=LDJzRMA4E0<4`|CSgK?RLNq^7`@-8GGY}8Le3+XRW4iq zTp5N-CN3~sRbUZ(p~k#CJQN{|4TbQ}F-df5zeb7TnKh2!y2wXMb4 ze`mgGC3Iw_OhrD!cnHUTiC*Cigez_CxLJQw+CO&78~F&|Os&7d96lWD8mfaRtN)w( zf~nG$yn%Ws?yrAwHhZ#<>FC!GwENx1x_JkT{>=EdA{th1y=0xxK0s}`AA~=Ur_H=( zRGMDVO1H=EzX`Dq(nG=JaPgBr=x|=#AJ0+nWA{)+DoY6=duu^*d=1w25iW=~uiO3& z(wL2if+8cO7AZygp{>zBGw2YG^SQIZxHj~w&)GnXO0D42WU<#kMZ&s=dM>!YGWhkF zyDrQ~Yic(wmhV+F#9S}6L`CN%PN?8L?ITF~*qjl&ZKBXMfvncavEFgl_DS@QpvY@eLazZ5sKX4<}fj4Or7dy@L@}WHP_*pz!Nd=%#j(9L7YP2lgEbA7xdhkPy zrwB&edVF%lRu-m9Tj|6c)F4H%F(L>da%6c+iqjZmfxI@6pUgDS9aJR9fkv?|u{Lmg zDDuLjw7acyXVSxM99FyUwLO73bz9Q{THS3vs#T~zJg+c7*peOmf+IHKMb)6;Hj0QZ z1yKm3j@X^?5`p$s5}+ibNAD$E`&q%oD>;om%h;bkv6Z2gD}dQ`k*9JJC}Ni-Jx2+= zdtp;{RWY1-XrihbCF9Q_3WC&N{*(Cj^r^Uo5`nk1Tqg)QsTzdphFzUG-8A!xZNe2W zm7GvhmCmtd2o{i)d}q-#Da9LFu!EN=~L*;YJ8f}HugI)ZYQgI zB#y-yFZZSrUoCPULucK@2FUK842KU&=;#|+Khmha=&$X?6w*!s=;>wXwFf4~RjC-B z2u3)g&p48^`;+W6S;Lb~7mSN!X#nyaq$Evhko7V9Yon!;Q({&>H`DoR!yT(M8Nbr0E5%_qG!LncxH#T#}V{GLSRh8!XA@c%IM->6o zKLXWjmWAoUG5ft>G!Z5Z^oEq1hTl;`4#cQEf+u(H(};aPR4iSXoTKSu)pk)XjGiEp z5ZUe*wCF~Ly=(C z$kHWVM}~$p63i!PKJWgC(T~gU7zXY!?^7g4(R0zb0y6YVM;m~1j>70fK9i(e9@B8Y zofcQ*QsM7*-qDjM(t>q-k)*5Yzf){a3Csfhx0q2^3e|!dQ?t|gx3hKv9MOA+54M_# zjCh2-xM4$1m2`|17478FD)TA~(zjkJ@^C5o*^;jAv3zN{4h-j-nWcLi-N}v%Yj{sh z3Q{jt0~yTWe>mZ+7(0$y>tPc8JwG(ZR&~?Xtl9)a_<{z^Tf#|sR7iK!)N_or>)o`d zyn^q=qvc8OKm0c4+7I1{`&4{Dtdr>|`w$7eK(fILUXbtOywL73@PInQx9lZ1`yAc` zRDBGPqPNe81S4`HUW}9ZDutBx*j~!M1|8s+{ru;Q@QH`fK)IVgwt7{P#G%j=?Lv@vp5CT6x2s zyQ%}UFMs&}Z}qga<@6?{^6xs$YsM?OL@I|l%xdKM^b*6B35RO5OX964${OjX&+9EV zwOf`SX|ckrK0>z&C+)Cd?Z>ak*nDP~b zFVSq@mP%c(vqFn+e&+G~EVIky^UZVgr}dY$0~+HoxNEsc*(s%Q@^Q9u^L-+-|7Ki+ zgOk%Dv{1#kgUk*_U*xKczTBfFf|y@lI^$r(ypx@I4JZ4LtKOlp`_9(zyc!IZ`)!D+ zY+ltcC}8O1H1fi}ab>@E<*-33MC6ET0`s|y+mX$Tm^I5Ril*dvUHXzP-D7^zcU)dZ zH^4s210{YxT(MJ|eH}>VV3lJkFApK& zu3PzjGUW3Psn#SN`~95*P9BL=P!=6>j&?hH9dO8zop<=Y6{4Wy#I87Hvh7p)=)^g? z?$wcIbD)4;an9O3UL)Q9#EFvr^~Xh@=u~fDaqKY^BgiGm(WgJ=3=S>}Xd^zO}J<*a9KE?t%9SBme^%&ERPPc08EJUh*r5k4!#6)x_OxK-HJ2*16oXb+Mc<4y2h)7 zhP9zrC~kejvaB4a!5uT|Z%%3U!UFSMAu0N?cu-aS+fOMan1G^){l{NisYx| zRz0hyZ*f8Rzv+3*7b>R%&A0r4KlsOOI^RiMNzFt_`q@@{>Y*vtL%6t_S=`9M=h@|x zb9#2~;p-CBYM0knjOUac7O#Mu?LwP*v&4UY{%ZvXueiJF;Cp`E^n1kie~y+>`S$$% zAC=G~MJops6*Olb(T)U<^Wy#lw~WoF&<1m4sj^8tR#AY^1?X`#+bnz z8kmffpyo~Bqj?n-$hGN=&@Xun)-z#bHx)s7fw7`7Eo4_2LG|h`HI}nQ0JOW#fSQyX z?Yt`8HVqDpwPg$)rQdz3GGmb*1YvAo^CcI#or%L?$c68r)zQUKMOBD#2I>UL|0a_6y-LWOYkbBWK;JIfX+~xM%x8oeO{Stpa za=CW}DSY+ELX_Z;m1DNB0L)g*WTsNFgVhndi{h@6qQt{vb`IaKg`r&2h}URJNp!ji z+L!LS<(iiC%7cI^nF&K`df9cOd~z?)r)Mh8ywQlMx7|FPzZZvHm(cEh3nZwVwfd2d z`I1#dcJ;ys2_I2+yDB>f|2$Vq9Mm%pL%2b z;I57fin=|=-MJK7zeb4xaDp_MMZ;S3iOw52f#j|R(h`rVAUp5cV~oXB0qRNI`-P`? zo%pPkyM+tuS~*sg6oGIBx^lsCPDW2iA@8q9cf6>kj0N({C)LMU}m_5@UG9K|M$O4jUqbQcA zcU|?opv4a<4Tc(4G;s?r>S&XH@+HDR24Jc9)1aiA!JCPjuXbNx7o1KXaWmC+(R-5Q z9-+4p{z-3A;X~AtVB6hjlQOe?V{H8w-&!!=LAa>hY@!6%3l+&nLD3%2kkZSt;(y@F zu&+qX*hc&-C0Lg$YF6W3nXTE@1XRYY=1eMOv_mcegj#^NSw9h%f2F%SvR< zbE4c(mbDXPELC_q)Gtf(O;4fc`3SV>QP7Gb2ut_Ei0$#=o0&z}t?iCDpO%~X+;=PH zjjTpSpa1(mpN&W{Nd_KFARzO9H!n>8>mMoq^KAUzh3}j$w3nXxzdF`}#gU~;U#eUF zQbJlbr&L}VHnp@>zGbm>%W9dN8i^t+!z_DBE;B0?LJ15V4GaxgN?mMe-6jpiSx&j> zK~q`Jc?5n8UUL_H4CMFD-;rX6ws5ij1K-y;iD$`~EKUyyK4d;xj6~Y|5RetG5 zD^Og8xo@h}sSp{?m1=2bbIo;*j!u@$@=Oj4a*V!|C2p(KvWd=ctDlNJJMA^|lmqKF zRy|8kFK95;O1>GsBDL)v@V&63^dRmHgY^xUk%z>LrlOvUDDezgp6EeL;dUWc(*2D^OR|8)K?tvsy7K=A{9-d(zo!~`szA$C|9eNQu@|3>9Fq1 z>=bf&43iYL1ws#T=4iaVq10D>LS^!vo~+wxoM@w72Lh+#MeVimK218w5rjZ z&Q#g9){(-zl&i}8Dxzq2R+u{N6d+FV0S z)Md1es?n~Tx6D=zrT(kg%CqV^2k%!;BQtSV5i$1eYwB|5J}ZUTS1{o{@`iwnW_Lp> zEfCG-r0lP``4IaerNL*2x5}t+h}V@<2z}y985_%Oukx@%4kw=rbM=^3GodDM{!a09{R>^XCak_Zeuo%HcpP!HX7MiX&990 zlUV}C(kZyN4^m{o+_b6S?yYj7`gAmnp03Z{&>e_x-~ydE8Jxnbi2b40yQr#WOYrwQ zDeZQYT{#8Lk`p-AzVLmU#kv%Sk`8%;m7;mkC6vYutlCzFOqav(M=W{;)5%nu`6Av6 zh0uM5OMExXl^C@sXHb!BeG4&67fDrdR+b5GYR+sR!}`)5-Q}Ltfv&;oSA;gNhSD#q zC~F9eWK|wtc|targ>0e`uQXaozmC$kMc<>h!8Ok6wjjB=KRLE6ocBsX&hqiZFPb9o0!X_2_7Q+|Z-SQiEwdKgP zrns}cw6wLkIS7BSax6x*Q8>b|H2SLSmvD3EvX|o&0SUs6*81E=j!u0}blMd!g_Mr! z{?oA1NNX%UFVLh-Fqelmn7dgJ32Fecbb(ro)2iC)I(5AOxpkOA2<=*xZ^@#TA&aIp z`d=O97i;N)rS&R1JF9(t!`pJx=giWDCF)X9TTfnY35JoS(CZysCdry>7GoYVfr(gKX}aTiv8Wb9Pg|(#~}B`zyQVN^)q~B zO?y#SRd;jvt(=aSE=D5WAeRyebO3d{q(4$g!;PO0vFT6-)Gy<0Mg42oADhd3Na-zUeMp)ge1-z z*QNWRONBtB0Ry2_H;Tfw$-k7+f#m~0{eeU_ZM#wp)SnM%s)PA@K0&|b5Z$K?pOC7* zRHv_v-Y-DiAO*sVEOQEX7-{jp^q1tHh<2-(j0+ft*`$@~HP^AwY?A+W3-^5{8%K78B zb9-D*ENc5JO$H$+%!GZA*cYEK8RJRIkjDULG0oZ&b)@d8Ua!^@N_hH86=h0r<0Zhn zS{bSu8WUoy^xOn2T6JX&hbF04WWqwOLj=NderWu4Z`hr88sf;HNt1ZlP-LfDvN9dg7MIkKdcC(Bh*cdv`zXl277q+lbGt0YsfvkF_$5W19SH>n_VS%x zh%0okHT)(Jhh6D?uhI^u98@aoPddreb8Vto*Dlh!?=WjVH<{H%f%!Y+hGpHjkx%fL zo>mP4QDUdI9U4fZ3OkOSu|4p2L*MfO>u@p!YhLmtM%t7zNZpz)L0?3W zXswF8Ms+#}(szlB9o6BDCsKYz^3rTXA4G`2++h>Hi(&f`}0E{E9Z$cKAchkpa)TW;377?v$4E0K;3aEdp))_)9Nzb zB`2KJOsD8JOLLqxc;2$#g^a*;pGN|i2Qa#yvxSCRE=dOzA0Fr{+I?q*%cFTT1HJlV zBIOa=Ma}Tr4w!xhX}AS2$35f&vG+|7dD(+O2azZxF7_i?ic$VVNUy$WXMpFz*DtTh z!;zGOxqE5W-ionywep)mv-0{RjCzZE6*pE@4m0ZL=QlVBnb*v`>lxSgfPjJ_M5zG5 zK%zO+6fm~W5YhJ<6)D2hZ{qNwjqVSsz|BL`6v1J_IjY~(pdI-JMM^wRO|DhQE2dPJ z=jv*?pWX7HlV@fxGgd#ELM?BpF2&eb!Uz`J-lgD1&O?BrQNa?&;#h&0s8WT$Z`RW- z-Y;4rmY>Q~$@irf@`gdRODT`9`;CpAn8I9*Y=8KzAZ#3ZviSyMi@r9aERyNh9W|0Hjk=W9d-_S zU7*wIxA&NnhNlfAA^jq!f@ySKP5Be%5!Yk2iS=*zse_Y>A-HiUxMeIdS{Cd4axOOk z33&&blY6O8tUygx{;|tsp0vyxxxm?EFu{=n&UeU^z)8XE2QG%Wrqx%a!3vgaWbDO1 zDk-Vf3G0;P5t}~gfhG@%y}}HhW*VBG<|R+|1Tj>@Q90+ zK0l3rtwe;1ckVGwLe>aPYeDG){I_H%Fy-6wcgAcdenM2GvO%4)AnU$V@0X9W`(Z%# zHX@`p(R@tF*>;%tGF6yb}9WGzqBCB#rh zUq^A759a4*H<}Yrlh5^6m}E>i2x`&;sI_#nZDP0v=?JSy6PhfWAyyO#L$I;6vn7D} zeA}7bqK@Z&8hvK0D}pM?Bs}|Wyp_@Y7fLSm^yNbjz{l2RJtbCjS~+k)uEAQD3sc?a z+K9@ULluIn0Bx&1Ouk;Yp$MDHb#66L?YKxTlc`Y}-mdEhUp?>moP0nBXKyhgWEhF< z(3CHBcG=xL5&H_h@mfr}T~e#W7f;&b@{IT+7oIg>4-9sroFt78MCIpuiT1~>dr$SO zM+}sSLxre|vo@DQP+VDkg31O=pU*m@d_nwK7KN4V{$)Qvw`vRYY71edUwU3vg&$(N zRn6G8Vog$U*7R}#sAzkh+5ks-C`HEp)s=b)c#9)j7a{!Oblorq5!&_ zDdp$)5e+Vg!_`8YaP(oe6=;Y`0sg#nIoGqWfuav19o{};Wpf*Tcd|&?r(U4==TY7_ zIWOFu%4^bM2miyQV_bit9B@oapM(E;8K-Kq2ThUSGgALk9h2QeWb7QF5 zpjjsio6zcEe8aZ2*u#4(Q;b*p-gNwR)N}dybxnk_jZW}mD_=(r7^%q*1?C(cgase+6&Y@nR#15%yqz)n_EZa!$ zp^&0|<$G*e_bF>$YgLdoGybNyPPmKPYT*ilacHaIB7LAg)DRzTQB#g`794LoWHf!j zLafh_tTWq2i*T9{i;T3EZi)Vk8%6n@H~P5V-?Nnk1`M>p3VZtcPMV4Tq zyZL8%E03a>TxvEypsGs9nkho&~x}juCS6;?gr9v z^AqTN)y2`n795HjAf3^T9P1s+jm7Y3w z+Y?hoM>`Q!5Jj5sXEqESPnZVyY12RCN*d6@@hhqB6cfJ z=K76(v^Z$W)YW$LhF}&P{k~0)^e*m1%qR}kDiKg2%NRvxp#tctdB2)M@v14 zi;xkkYssi%i7QRSI!b;q32EFh=or5OJR*qJ7mB$LToM~5zLA$psL;w7A>_rUY@zey zi0Delb%n9kH^uh!YdO2^hZc2V8fmIWIBO&ns)a*9yWlXD4xU3EQ#G>m{1*lU3r5E7DTYpKw)d?Ck2r8Y? zJa)c$R`ud(dNy; zo_J06lU6m$CDQ`)_c#AV`|}*?hxWRYlJ~xKB5H}&Hv+HcH-tjnPgq|Aq-qkx5ty zYF#2s{BrnDOXav3Q@tYQMg#ogZ7fcaD(Kz4sZL)>ufQx@w9S3{bPT649I5JEQ)Ig8 zZ_}tJJBT!xdcNAR*97z))~2CsWRA4$p;h2-@JCPgxRU97!&1HQKr5+ZLqQv5x_*L~ zPU>+-0Xf(tmUsGf0!RFCW;9hl-MIU~PhONAa=;A*8I%bAltdVPp^0C8(aYp7Z&etN zHU3NCG~S?0CPN`HS-Ru}36D7Lr8Z58VG&QSRE`(5{xE!N*4qlkT@lP(g}oo7`V*?! zm|=-cKsW<>S1bOb8m-3?!jghJ0BJ3@r&4&dQhDO9qm_WY=t&1$Nq$#PajGDdE>Hv~WMUMk58)_ZBl2ZBM*1KTO!id^TJ zMZMB|-jMb``Q?(0dqcy3Y#X@!(sYAzbO=vuKB@)s4j<|n8Err6E_Yq01{v)ash)3z z7iY(jY{~b&cVDNl#LBQSi{=({Upz$>1pz`ymM1QgZ|9R{yFM2H)!d_*E#>IigR;xn zUs5US5xkl61+F8FI&FfIuC*g)jt+}Nhv!YafMU-u!2`Zw#rTH};lH|wlzxu+42(Ti z9PFypZAy^0<-Ua#Dt*=BQ9D2bbhu_K`Z|9>v^t{vi_tl>Ln+H$!GsM7wOu z7QnC6>_UqotWYEeT9@qL-aU9 z^LUkkc$6OQlwTFP8vJ93reBOZ|A40_q`Ji5#5>0&?+T~$&hi2O%N}y0K214NC=!ZL zgv%s`=%C{%rN#VC^RO&rrj4{4g4+<1_8f)-eC8KTX2OU2%Na<3cZcmP#F^Fi&>nQr z(i^{Ye7%XK_lGfEXI`oFXTl@=mU4_cY`TWrndht)KUxD2<_bc zcR!((v<_kqgfUXv4mgDigUP4`1Xq7BB+0H$D4mI-WN*o4>2BV~LxTu~P&#*HR62K4 zfvE`}z;(zKomV+eB4@f%Zol2?zCwDLyl=f-nz0gFE)U}U-|PiY-C{kr$M47a-u=)0 z`+)!H3nx(PVhuqj(G-=65*%mIQzcLJ=dlgT)ja`Ub+~+puP+@o>phtid_1IiDw0Ds zgpG6s`$*j76vD_NJffKwSQ(3mzUcW&Yc}{V$Z$%j#V2Z0DF(+X@e1KO{M-S~#t5nB zwKXD|8Wc*}Y!@*W90viNIJ=G6Doy2xNQfZzTh3>bnU1`KgvpeZm}2RV^~&O^n3iI8 z1i@QmZ3o9!yi#{hNli&bSw~M~W0NYAqRnTLgIL?->a?TP5|(PTwRK<*M=5p$Mw6M% z>mh}gIh{r$m@N3$@WYmaa{Qdu&LY2VhCE{WP=yh=1F@QTD=|AN zXB{H3Dm(kI#hH6ueBz}9A0W}TL}yo!iYN;>^s}N#Yr&^BwMk~kh7CzWUp8ouuNoU6 zJn3bbdOa+q)q*EG0*A-(aQkf79EJlSD#%Ku5yBQ)JUiP$m7$<)zs*mki68(Q7tL<8 zTswQ#!j`xkdd#1`4EVCiyf5%9mRm77?RhiBCbbl@}8`ACP$>lraJ8RT0M)_D@-Fi$s!hVvAR$m z>^DRjR;Ng1TC!Mlh~efe$_}yp=I+kslC1R%+m%{WFc6_o=GXOs?6)<-GcvK7x@UbK)}+JYj9gFjgX-kqtwDWiuQUM|oD?V%9%jp{-; zst|75Hvuho3R1=?XmPVjeC;9gV2Zf^L5=7gqOCD|(Jwg@XYG&8Zm7U6ZHeI!5CU@h z+`A++2ljM03VHf!?Bx;71_Sybq#;bXgz87F(Fp~!h4}Xf zd$|G}1Y2s=*hwr3x;f{h9a9KOzjhJoVyqdW}cak7TbiS}i=%c(-_yaDRp|g&Y>oX#~w3?P||CH*kAzzuHm3K5_WfA-(uH*>y7Dfw% zzcDRx%W{U2c298g`zY$~sUen5+4N=Qyzay(70G?YYJ4?^+O1`JEd3^28oi;4_*TOKAiCotM6f8euOP zt2cLW?V%-fZieE!Ym@tskd50uRFiuV_BViHG{q4-xFaA%AK)>@+7zWK)xGbXm}CSZ zA%`B3Q#vvJ?(U~L?nw16|D8VB8gAq&rn7uG0ks`polU;)FlPp{;TiN1C3xGT^1A0p z`;PCIBQ)_5*t7Y;4?f^{n_C$XCWr+5AO0{t_b|_bkYK2w%EQDvs)xA_{+f%py31lK zOk=*ZgpWGzr7z4cTHv^pvwr-^q|L@LnwN;o1E!vq2%VByHO1F5b-ZDonZ~sLv?0wq z?KgYDX#3r30!O`Oo-zNC;)P^*g!N2#6RHM`nKp?|ru}EfJ1=%%!y)85Wd4oC%r3i? zM+H~CY>0l*etLa7!Y}}@ddq0e{9W?`wd^>U67FrY4>;1n27;=PbSB zmzIkB=x~U1{WB*g!CO4PPIeD2#+~7#Bg?P;(9S#b(K??K7dY0u$ckxP6ZNb|$e~)P~$s7tl1c!Td0o4fParR)!|b)p8LBqTWw_BaX9ktXWOT?EiAht5L5liDY3= zyPceu5-vbW}2+E!+72)*WNes`#R5GZGQftSfrm#yBA zo4$KsYB(Bq%VMI#f))l!%e?o<{?{a-(T_08z%62`S-o-@Y-w0y&wIa7yQIgxW+FfI! ztl*q()?uamjp*Agj`8K%-yH&v zxI+sybvTYSBgpR#L`5%;^H7PE`=5JEUSs!suN#OSHYS;b0M3oQ;=@+iqPa)z z$-nF~^XW=n4I*Eas!RbyCF3iudd5#vcYxt-x3#(0eTcxe`E2X)(~}a4%cP~4E}*D8QX%ZFA_c*jDrwiwT7X!Z$aEL!wN%)&2SnI)j1 zacoOSrYN<5Wo)l0*Grdo+*^-X88)q<&zTjQz1@&C;zOn{QqkF|kYjZ9d7GL2`VWj) zQLgg%uUCAp3{&{~z9g_!8^Ib;L@p2O6vYcW*Z6NMwEBw8ql(mY*K&_s%ec^DuQN=6 z2{MjMp9`K8RpyO`fXEt^NVDrUE?Q86Y4*vNnD{=qz4 zl@&e)+^W7i0+C>Q`Kh2!I92KrSL;grno!n?cNpoQ_k)LGZ^K6rqiv}KP4Opt2}5(m znx1}z+xbY}X!*!&hr@qCi%ca+&d_Ayw5&zW(0F1GD^)cZJ}&+ubcV(gMUi&QDOBp1 zQ*iVd1dTHf(mx)P0S92%(bg4I{9UsN#3skAOh4Aw9@?824PAU1t0>w9)fG7Bo!U=b zDaBfus;h>vo#d7(LB~8ztpHvAr&U}hNM)JY9M$7q7@Sn7+Y4DH5IsO8eB$GcZ<;q} zJ+6c%Ry?DTF81_}&f(Tp=a2X?*Sfj$&g$2?EYyu-_TX!Mn|5nl$-m`k#$wvoUIj5` zo@lb#9&d1HJ@oDyJzX_jQ$G3{^7SQ<6&z6@=u&_+UXxPb5*JF*FTlA}5xm;wX(#Fb9B*L(Ln^uz74#T`-7!q{WB` z@|~l#bPm9=tJ=&(%E3Gz{85M9Xm-IkaLOORpn6H~k8spp&AgvvYgY7o*N+9X5n3p{ zr0bL(WTRXoQaklH5>kSSdHNPjycH$}JGERek zyPahi83lU|fdz2bPhQo8IBsz%r)%XGfKT_GYSWk&RSoln>O5)??@!NjVX>>-7Oq-Y zHwjfeXmC-%sZkoxP&`s9J9sGhA;^?s&cy5BT5>!hFh$A1U}ahZ+FIe}(Luph7fk;YzK zq}g!BDKkC9xpG-@#yJ*yu0IO_wiFX6M} z7r7Vjy5=VFA#9-0TJE^`>8&=?R$MB125#Rr-;ni+dNWIAxeR?KPOp{m$r6xDbcWa` z<`<*9B+U)fEo1h{6`1zG)P93}&=($n6PFMgPsnTaqtqAvBS%R3$&F(s=DDms|0d3I zRZ$p3+gnNrHYtN0>G|Xu8pp~@O_bipG9Pn}VS5e3V-9AncV-B=D6;7__m{>%=tYhI z!~1uXEi?D!8mWn+F0d7aY=tu1?}<+Du!0KV>6}I5g}SDaU%mivZi2RC*){IB{pmmc z`4ji@h4&B4z|b_cuq^xVwCb7OKe>=`Ir9wDJMjPW);)|4Ega(m0f~tN0dfDY(z~>S z+rQv${6Ey_|8H(@_|HFe8~I zDAKaVBG!i`_3D1nx*{KFbO0+Q$AFILnTcudCdRdxNh%RxI3dnOSvT!(ba2B?cHmF) zdHRUoHz2*SU5tPEPB^T$uCcb-Gw3PATSmg^-bUDH(@LeoE?U8jZ1`kgY27xQ zBt=4P7%NDAs6IP$g#N@Pd?&HvaZwT_Qp8DivPNZa0_Y0i>QJ;6LAEb_!q;m#$HaM~ z{dU{^szK%sTJRM!P7yG+hjL-$)`vv7i@jy_7QV8o;=UuV)$zJG9FC6lmG$OzvNbDZ zIWNE|4>nx7;VM+3NztCaA&VNB9Kp}sHY*~|eR2`5NDA_h{pq*biJ4XeTCmq@RFN>v z|5Ykzl4wH2-!>E7iO(&=bU50^^z%$_48@8Kt|%NIcgkHRa?+gNO~8xA_zj;Fwvd6+zFF z>SD=q6idc?jVkuC?I^lO96Z}XdFvyWbOf8B-L8E5h;uELj`<*EQ#c#^>1^qC<0S#L z3f91GuUv$Ag|5|ICixr$=@B%KTyLw_*(7POdKUb*NHU!0rZft@5zLN7*nv$#!uzwe zf7FC$y09OauK6D6>%kz5{j$e##qk<=#kB>NL+v6ob}|z8dFdwA-U)`#p~)1v`q(ms zn71Z5NEH+Aei;ZL%I?|8X)RU_^9JEKu8&tw^m6PJo zwHDBG>c%@xyO&yvw7^O%57>dkoNQMjmum=K`4}CX?YY>1P<>RC}lJiOX{U+i(JROP7_u6byQhV0X(&%>=d4Y3{CL{KkaqQixOFG-g+ zAZPV7$at8+@+}jtd9;x#4gMT(@IE^;;aPxQ7J}A$78Y-lch%l+B;~kF+BamC znwp;Slj261PG6jY?Ij<6FnoQ|`_gy-m6Xl}TT>HDgZ|Dx_Q8?29G+x9x+*H1XnbQ* zD_H$N`OZ2FLQB4lRI0RNqc&>FFG1F+iO3cq3d(9;p%Xlyl4A8X6$0fs;WNvC?u9zE z(-0n7l(atIEx%O)J}GkK^5Mug6Udo2Y^A(I?t&e88Q6^aO&Io%v~hiDdEhV&44pvp zKsY_(+vcPPt4;~NQajOV#I=nEz5H$p8h;{GGqv%IG=K}xAsY<1$45_ac1SgzYqCz| zJ`5_E@>&%CB~TU*Mv)gy_4AsH1Jy-$TOQQu98y^LtTf~oQk7U6Q>Ch@EX;YzNuq8} zk0qfnXuHnUWcWQ*GzZ8qY?i>^3aDsZU=z}L?0$#t>8iOqkc4#R*YTOQbZmq=Q2NFp;* z^XJh%rvHb(R4|vHa1aDt@dSwRb{P^)FQm~*Y_PP14?OQP2)SI#IszYDk)pzSKECRS z+G^Q9-7xCU!cV8%moDm${yBucAfvDF0}Y6rb4Qo!+-^qM>_*^*U^w){avMUfR080q-taYJs zU4fkCxfgN5wa>Cq{}L29)fOos?!E3d8uRBA6)7somzT`0Z%)jum%s}F3mc5I?|+KE z1;)v)KpoYc@s#?~m(^}g zhR2F*d*ONrL05x#7`X{1%6B*8`B@;;ccW8t88YqGh%Ygs0_4SE<@buEHO*6u%n5GB z8sj2j{JoGF`O8Q%8ZVRNGKRX3&cOkPa4f&ivgOXZDH~hu)Y!A#`qu$zbPfoI4zC!g z2X#L|>a*+i7Q`)tZ_RD@tRuSg1BS(bvhVrv{UP|TtxlF+CDaC0^8J+9LzveniKNS7eMQ zfD-u(0)CuGaS!|cillBE#e(_r1YJ)9cG&O9=6J}?ru4J}P@yGE#Z^z6i$VwAptVYI zT!B0zhO5 z_z`dj`2caC{)qieuwjL%T#lD#0-V0P?P?a+E`yl~z(#-BoDL`i{Cx*$C{!Aj*3f2C z#bb@p2&cZe*bHUDGdg zTx_JRN^UV@s%gcb_RQyo9-Ux(fY>fi`h$Puh4~v&#KC=85(DhdkhpMlqpQk1E4th6 zyW@9aoMX*90)cFeLhJd43UT&uc0|l{ceahnh_mnVv1jvjd{Fr6a>ZB1HZ9OPLO$d_ z*^)VMFaAcj(>f%1DU>j}ci*@#DVlGIj-?bMlt*M2l~Nd}@Gbj5+YQ3_H-9Q7R0fS% zQ6@vl#-Upu*KKOtcNGbrS>0S*b-2nM+XUTc>#WWQuq@jYVv3s|DGm?HnhLjJW99xCBd(x~lwSW!;obo(Xq`+*y07 z4l zys+bY+pV-4s^U>Q;9+Z4<8_hes4)PUIvum^a@78qdn<_og>5a=mv3BDpQR;z*5AtX zs$wNH?bwx)x8wOQM@V+#z)||M81!l?4DwMORa0Mi)*M^&?66M~3Br5%CxLcz8+i@b z4}~MtifNNH8U@svioKA6Tvl7%$=2Otx&Xx?rI0-eiu5{pt>ZsZ(^xL%MKHgcB&;Rzo`d6RRHZX#n4LT7 zqH>Rw8l^(TRQywS9?h?v6fL{QfMcyZKiF!K5MNz9yMp_>=UHo&lx>L`Rf9Bng2`EJhXmWe9fm)EL|aS^8NIicheN~tCBm;4WZaki`uh4^3igrF zv9hwE>MRsT_BsJkae9sNlN;mi3?6PLC#(wT4kp5la3rbwFV7{`P+A-hyOu}`9^zOr zt*1o1Q^Y1EL;4tbb*Gx1#IFSjH>;bH&3Lrb(Q1#nsdf@LA%xM`Jx82_&24$VAMVBQ zc>)#qW7H4PlDJ-3OwAZORLj&ghj?eEqe)ga_?5}dXhos&_&cHUSQ~&RTVlp%Dy~9^ zxoIu#w_07r?Y7xE)9U;TtkOY2|xw3mu{CH zu0zhT+G6*R4rS)kwKLM?$|;nXiX~!L7gfj0m)hy>{qt*)-}8=JInEIX=vlk?^jx^d z_Ka4TId{<9Ar}zz^l%GtY{{lOJXi$wi)T}DYWvLLsHKB4a9tt4#Vkw#{#JJ?;>mfi zVd^;OmmJZ{^@@GNwtJrAyhF^F8^Gi8PS3o`^({MhI2$dX34h8Zxq+~s5KhjI-;vrmYu>ndb52>C9RP@ zy>`{L#le11D({iuPhD2+i3%qJ2s3M1t0+U$%GCMCa)wZ~7qK4RqqM0hOW?{xfUGy) zr^h;^x}QLoO+hU|Ae2XpX@^-Jv8}sA`v^^lr&=-d84!`J${^qPIhnQ-%q9=)wzTB?RZy{1rkr<$^go zY^ zJo7XqOfrQml8#$_ihL^dI$nww>yFdovY)4}gS9aEp_O5dkoEo0N#g#Z!%`Ab8h0w? zMFIu50KTK0my#R6hfY#64f$o|&du+zG}@r9L$xYmt$-apdYjCr5csU(#m%YwW71L5zgj`Lbo%Dh8MVZ> z12{wjMh9z4f#^iClyY2rf-m`!v63p2@*Gp-+)qrM_d(&INiSR{pm-n+K!44fepp1Z z6`g@+!NGgMcn}prz)g~LCf9Po2wtl>UUVFazrIhQsiX#}BMY&jFRY=tuAyqvn1Ig{ zlwLAx=}3HHC7JmR{lv*;8zzh@J>IJ+ThbIoAh}Roqt7Z@DOXe(Wb9x&(U=5LAYO3k(@p~JUqpOno;_Jk zS!1)_o*~otwML(brB=Eqf?K8B6Cr3LfF$YzxyMc}IX64zITB{&+9s%lZlEV9;8fkH z4Sjc76r_4Vxa0)lD0VbN(cV>NIA7VkNaH|B50BUUn;YWJ;#KtD_`ZbX5lIl_peKpxpw&(guKkZ9NK{7J>YVns?W zr<8yr`61!$*2H?}-@T{4#bm|m-K6_|+|(O?$e}EJ!{e!hx~a*9$^Lf(u98g@^L}4Q z_C~h9tWW%JAvV$XM4i%+7eiAny)^$9W9QhU39u#MnYL|C+qP}nc-yvZ+qS1|+t##g z+uV-0`(^jj{Rj*BTY+<+mOO%Bab25&2iiFY=UoNr4Tqujw8 zzL=a#OpJ6C1?+6t;~z66NQ-M2uA^(dC8h3JGnf<6b~_h!B&wUVwKB6bU02;6cxF8d zGVsiC&o2OB33ZE&&xr3(Ncd+oJg%wWwRbyVq`IOU6MSk(EE8}yEh=3+65Ba<7+DBz znGz&!&oIYt?Tsh`UC2s!|n za>v>Zv=%cDWHNXNUipD8(h~;9%#CM9qN_8$$VXIAd4>|tnMwUKsNo#G`v-D`Vf?YU zBc10<9X4Tw3Ck3wQ_mcgKd({33K;x5j^qvAAq~>YrW+d_=IVbG;+rCG>jz{EG^I1w1Dm zxj7=eJOVz@gnY@+bB(VWkYBtDz6`+cZxSYv2zNvBuOx=yBK zcIX^#Q(42+*5L(B%yS-3raTkWeQCztA_Tm6{C#P&FSD~7OW1m{u}-$D{J)qWdBVOE zUJ$owav*5p@*w*G0!ar@=E4k-W9Gy`j+Lh363VSrZ3UwYXl6lfU_!0+(9|-M6i-Jm z5gL&3p2CwdVeZWqhs1*)L>2xlvb|N|SpVi$%o3?t;q45i$?TsR%ML zN$|+l(w6F3ayJyvG_;s#TxA0IM7B~%6n*FoCeX(Mvy#Rk$yVwfa0%1lI;4a=K_x@F ziWz)UuC`x^f&JoPZq+M};uolP>KE4-NNU7`$&k0Z2|+Jq4?(Tw>KoFOr}{4T5M!nf(q z9wa3fXf1((4TPPs^DKVGNz7=14Ah~H`k=;&LyMX~pS4I=1t3r7c9h(5kXIdcSRMeD z9JtbbPIh2yeOTRJrh9no(6&YIxQj0ENqa)_Az}cUFSO}Cwq0#6_@!`Ed0JNfV6y;8 zL_bP<7Uf9KypZ~K*gcXmRNs&(Mbbry`#fDuNLWSC&GUSPwcj#|Y*}PFFjMouvxGdN z&je=4-N0H!YWY*~z?U&1v%BO0RWVF}OhY2=ofRl_PQe?3kzZD>8xUMLt^uOc^VjT9 z?fY!AhwP$bLTC@{YIC1XE2q?l&R0RT_ZIY7Eke2XHm#$t#$oKCf6hL@2D57T zH(tRWxVHT_X~8e-X@Y*MAznCFg?Lv_+0|J>YwykPC@!`{KAi~39vlO+~Ir$yp(x?@RIsMSEuUvVIQ*XfRRAkD4*?; zl7Qi>(FSKGXYQg+Yu-|;M{(^~-3Gm28O0sUAj-`rg8$tCvJcAHP$WnOp1DyoN1R$` zd;Qyp>~LdcQ+TUGoP(qny2?DxdJF3@o_|Y&x{b130K-N8999adfz3@<_!9F%OKuQ& z&xx{ll;Xlpi!>8aX4(zk7uXU{jGtS zXK`Y>cRUDPys2#P5pYg)2zD!VOEtd7Gv2hPQb71etWEnv^CQIJscoG17VGiIFIckY zrOGW^veuwj>m%mPE_{34ISBL{yaIxJVT1}W@O}d+Zv-(`D_w%=7Y6gmc##O`fdT(D zZg0-<59_ayTLq3Br5Ih$p@A-FH?-{F^O)UYc`YP3qClG7Q;*yS4!m+bzwz!nyxSI- zsXa$GaP-EZ3lQZ<+aY@?&T-~4kj-?d9$PnTB*cr3`k#FVk93{E+z;WNEb43X#2tK@ z4@0}|)i++R;BT@R3in+qS~hHJZJ%MS-^O#79AKpgsvJnJrkP%y&}wOZkrVbZ9JG`p zhZ`a+qlqp6q_!X*bZ}$)j>wWdIg{vD(_8fRT)2AS00duD+pwNhIbZZ|B84%sFJs+r zL)~qLn(K_^=P~j#yshu)P>lT3h&oL3-(s6&Y;7IPZA?XMoXnlv|ChS00jaP2 z?;kH&`T@xRs9=zp(MaAH41rYuDU^`_rt}Z|8N%Yw_=p6PDLtGCImN(|ZLp%s`m+k8 z#lrfsKt(>Js>w`CtIGPHrq+79laf|(W^<3_rR$Yvx-_Yfcr9V)`*hdyMuV4Wn=Rh^ zOdoi787CE2Zaw+>pVR`JapMYzP|CgdsogY8I495nTz_%bN#J-PuVw`& zJOl`pz%miF!VFsELkCrr9WTnZsw_Sg)nlW+X~aS4w+wxm{2U~6ym{YA8~tGpDh&9( zRC+aS6(27}#r)GNk-~&-11XYJF3vbJ8r%N#n+c|Ba?_C#Vz$|=L`1~t0pe>t0aCaD zX}R(u42Y+p^aZl65{e9}sC#Cm8TSdBkYHA|8Q7E&V`c3sT0M|@r@%=mIc5Ip&Kw%U zK5rbfqFt>^RZTTzu56)V;5dr=C>P-^PTcMs-i1EpMX09GBWNnK%JSR?4a3P20KE|b}5gI}<4$2Q(hr|`tf zqMx|6Ur<^EQ~fPS2>RmRS)R08Bh&-h;T$MJdEbTs(@Y_(wBgNK4`VEC02YeBM+P2lZXHgmqkT8}dVOA}LU1j0Rh#%TFW+VzTf)PJ- z!d#gUQ!Z^WZJ=O8J0#E)59{4Bp#?%hMkqwH$7Vzc>W%Ic1pIZlsK=nVYGr@j09Ix_ z>gaX;1WW{F1fn*hZR1+6Qf+wP#gU^#7hf41!k%(0=t*woC_oo zkp;kf5@`)iM9n;-2l*V771XJz!16>h$aQkVNCg~7pxlgf+{n8HPoJp*oG8QY0R{peojJB3Gp7uOcnvdGs`k)sP^=FVDy@Vu^V7BQrFWFe z5*~R_t#_5NlUvT)E8vKy2-i&pDqTx1^~SYQGd^5DRjfT}rqDj$t`BH-d;?DBn~F44 z5gF$cmUHwjb-1sX0&vj%*FN>cf4Hkgxt{8CLJ#zJ@w~rq16XsMv<93JZ8*iZ)gFL7 zKpxpmf`L6utmS?Yga@_o;3nZWf@6Nd8Tqn(hT*ZCFo^J#jHI8lSKEY~P=R6CMvvf66%A@&4F!Q2)V{+I|Kt<^0ul>daaO^=c z$cSMkmUTD5R{C(8iiJF10CJwKC&m*9SP*{_Mr&5 zqp<{!jtY#dROUSmvUIrf0HcT4{X`$v zU(Kiy#}a)^0d;5cc8Mg7pb_YtBDMcw=ozL@Bhc@WG%#%vA|{#1935s5vaqZoU!{kV zwS$G1+nUILOb?Tm{w4oAr1fmz1B!G@-#gT{-X0Cul%_c~#i{ZzrS%m{JcL-Ltlmd0 zo1BkR&u?AzJ6Nb%IGilhX7b={8K%^v`R=dq;!RbBjPjsa;4!_1BjT1T>C z-Ln6eIE$6MTi(QRO5I!dDn0VmUl7y<~U_do}i) z8ayUjUGrzk*@L@Uv@?f4)y)&8a(9{-XDAER@G9Sf15iHn9PZ4IMVCn)p!29Y~a6k5`<5-wDD%(fp zZ>#G({Wbiwz6Jdz^420`9r5q>XS+2CY$4wohqw+0_RNCT=SFf~16N9WhIVo}4O=ON zV(3LE)t$y?cqxpi*@=Z6|1f}b<3J1FQ_#+E_tf}H{}Qw(cUOAQA-mylK#iqr<_(8C zqBF(?(=B;hN)n0+r(>{fj#Witui+WJXL)E?Mg73>S)Mn&L-({j&~!sJrB2q)#kS4=59~P~6C+K_ zG+k%xHJj1*KCJtOW1FMm(?^OwcN^ydBJ*~OT)W%dF4JQvEYWVQxv_%TYD+zWPg>^t z+)_bX63FzwX3PI;~`p*S}?;;>fIyNextOT?$ z6*;_{`;1Huq{eu?t;E;&R8-rSOaNHN|i}L#D&b$1`Jl(Zl zoZd4HmS98752+5?T@ z%CLoeZeJ4W3gP!3*ftNsg!B52!+;dzaMuWVk-)x|rc!)ADL!=!hE0x*CN9H{hdw^u zsAi+^XN7}?HR`rK_B=jg5bM8RG9YBZC%Iun{bNh7KD2lu?o*qurA=s}1>9n&=^**Avs8^OANW-i34` zxUl+0c(mI5fyq}aEk<}ajtP7Rp9DuXF^@u@^Q=7Cnm{jJHFf}>4YNJ}z=e73UUocx zrQiMV@!h?mm!ABGluwCY?(f}a!I!{2JqUs5ncdW&oBF*{cM1QG@6t^3*?%at_@dMX1*qmCHA%ar^IyOmkIL!s^9Zd#cJ!1#B zLtQAca$k5O*MAUV=kq2j&j`biYNX})0wQW^xha>4@1dlR?eM@<#qjT034cR zow&oZHRXv@+@cg?a(2%@0b-54hb%y_m{RTp49%Kv7*PF-KYxns_Idnw-Wry4>5$)% zq@Nu>upUwouNJWS7gqZc;wdQ^sj53M0x!)HxH``Hz+51;Wu|jU%MBBwI)0jmKHpseFd z)|#_iR?t4hu}RjFZfoM2Go)K*5HQda<%h- zMPAnwV2w;5sw)>|LeFl%^O0a3aSQ)A6JR&awRnTJ*9GCa(q3wN!e2+kC!WA>?JNnM z%Ce3LqZvUM+avEyA&%BnO(Cm;hwNxAcLW?(e4q3@p~0P$%#_Dm}KgsklIThbG< z(~jek9d0)BS8Z!s4kyofpnGBxOWtY_o;I#%IgtpIPp|re5dza^+*wH|fy9;SI_-5E z8xE^w{m{Wmo`;95zz3=V;D>dqq~zlu+9z)Qo|zKorwX9hKbDNWWOe5hR{dS?;aukk+BHGpWWRJnL^e#cz82JzJqS z!S=A8K+W9XWL_TxqSR&yUgIvY{ELgj)`n3w3$jR~zC5rJwgJFapqmV5Wu2F7Km)v; z4ceA&jT34IUjE?_t=9a9PUEQ7h2+f&@7-Bn(D=sQMrc`CEGhaiUP-|?&Z=$}k$XJZ zqk`??O<&vk2?Kq_#Mu6uxK zk)e@B#G&I0I6dmAg74qN{YFkk4-iGdyF+x$OlLI4Y_nc1#k(ntY}=jFP0yDkkX)1H zJ>CpT&=UA65zXW)Axo1~hjO zG~_X2SdK^W^v-OD=CW`V z57S60x!+GWk&q;iO`(vuVMCok#7W4Dwd7YM}2M ztpzu(d!%gk3my&Ai$h?I_7kfys&e59H$%}1@e9-Gp~1$ifl?evs;ue#Py*`>_5G76 zcM)4pVkOw{s3)WB&GEGim%g(k52ci-4d%DD18R&1XSyDp)7ctIji`CNTA>qnMOGd& z5BAyywo1*m)IOUUE<%dk_Xa>)uY{O>M&R{M!2 zpP=_+_|4eknuOvL6dGE^S%R(b&yK6oQqc6Qegp1CFV%)mmha(d_7ApMpNW~<$mtW; z>66$GG9QuHugRJ_z1MAZK4=W8`H?~$J>Hbo z2X^r-WX)boiq-D|L0ZIkJ6x|eJdd}oJD9k>c6w63;PTLYWe7uB!%3mRkbue!9Yl|C zPGyf`qVSc1<$o?ohl`v1pPaFn3^TM91WXmd^)cLpzQs6dG63OL0Gc}Kl2$8Z6;S4x z>SxYAeadAU(3DG=7p6xyzZfZ(I@|d2!zRs&A1g98jg?>r|GFgdZ%0Y6fipJ@W0n#g zUc+6JBG8Nt@vc+NixACr87st&l)F!Z2MyltLcA%6iv+w_C&Rh!7P9DyiKn5P6hZl)BRFY+Q3a!NHRl6xiC^j_5g`3>Z2lbTGf=nc(u)xX9^i z!ok@De?=DeRopAwnEBLIFo$dP4y7u#Kg3Vohhwo0)D_??oNsw-Er~)E&l<`0 z^}hc5t?OtcBQ9OPdmYp6Tr~?N11BdaV3PpKxhjH536!F_m0twV2Gu_4`)=t0p%zOS zj;vo$X~_P-xR}|<3s$>AM`EiwLR+Zxyt9kt1(rf@Yw#)gC!+>Q*=m|dq&q}c_FHQq z$-=D6do8PicLrJ`hZ?@zZk!5?f_pBb_mp_1Sx@5y(kElyw+E5^CR{HNJ4+JgSqt~d z8Je$GilS3^D4lq#H*72fUWk=jj3t-Ny_s>D)du znPeSisYbGt6T*gzoG0N9dqhuKgKrX?Uud()$DH1$C7@meA!2f*gR6hPdChNL&sP6_ z|-PuH&s3(QS3kSO%sJ-|k@3WP4`8`6IJ0n2) zuyt_o37zsv15y(Fx#(l}(+pt<1z$7yiM^rakXfL8hnWT$Ly#9;gkR3uOwo_W7kR|2 z(Zc_(gpneP$uy?5ZXYCL;sZj%r}m&+A|_7W;G-s(Yv%8`g*yEby(|>reqwf|E?trF zG)Et*j@?l6KzOm{Ud-^{0R+?Gv_giDEdJHPoC^Dv>QXHIlZ|bMDOJa}j|;72)*r|n z3rFrzrLery`dZ#MoNJH#r~V$VEVDHe?4FO=jrKN(yVeS&jdyVIdpz#IHS5+Grs-ra zJ~`h!W=8OHCHOpu5o>RYgb}4LnE-#yH`ZcxV((DJEX2}V9k1APC&9h<2NuF8nl-g! z-GeMq7pf?#6`O)r3+HV6|P5yJ7li25oA zvz^cvg``4%d?x5VdTw}2z|(@LCvy*cXvcsKUO7pGk&5+A1Gyp&otSFP&T*59kK88R zjg(74icj?N4cCXiqr}^1eAhkPJU;OMegDe;X)bU7)Vo5k|Fv6f z>OU{wkS3%T_RzoYo~He#Lzx2dQph%3gAoErL2<#XiIimhIC!g(@&Ulo-I^+)Wpqr? zY+%wm@Az_Hvpji{B6$+~qCHODLtZ1rL*7FH4UhRLC`}jqjwe$`g0V&lHL}m(tNC$P zw(Inyr>)7;3$~EluQJ7HJAQ$j2rt+~d49XAx#!cXJiId(Hm3`Q4+X)#5`J=oO~Fwr zDqH6~1QALctcZL>NkP#?T*gUSrVVSS_70E0E6#=m^e}oI-Il(d`|)vaLzfEbK@_wd zcx;bFgvxBJl0Fe~7-6rHEpsO%la$vGXN#B+;QXucyG^*sUTM?@=1DXQwcvoOvNk@H zIiYONHnGxGYeYY~&Vf4kdRYFTtuF0Mh651m<|o!v<4Byu&$8)g1bGsJzQ zRGb|VxyuxG|JCAhK}?9&0O4I$^S7u^;H^?xbIh9Fn6Y_gYIey4IYIN$z|w_iW)<&Q z!SXIfTZXJUP8jrKv9WpZ1SyR;VAFl+GBHy(x6Rx%^kB`F?cu=6=;zMJVV4B`$xf9? zqbI@pv!|G;s5Y~L7PDE$Dp7c+iY|7Tjip%^iCg~uDT-e+4~ipX3=<^+Ea0j}eSnTA z_3{Vl{Lr6H6x-!5yV`&|dv1rR#(a=Lm(sAF&{|V1HIXaguQmI8C>sDr}G^Ol~vL$SnbRE(3r4QoCtQF5l?T>c+K# zy~g3B29Z=;0Mk;7Lr~687-5M)ZpdeAn$V5-6-=F9myItx85R67HPcVy8yf6+zPNns z8LohfwMu*C$wY4jEhz;uj{B2dfa_nk*pTNv?;w>ntT9AptS~4YmsDdUZfbj=7$ihPi!x zffC;SU7`$Ez1ft!1j8@1@e#x4{UPd&bi>fj8gKU46hqY&yyd%i8x#Hxp)FhM%Kzqj zH5{Gct`byW-_Ln>Yvk6~j`%5^UZO(4gWy0_9&?zmGeFK7u<#PfOl-Xyg5R=2#6Tpg zEX~X+sc?@C~cf3%3cpu8!m}!tm@Se&38Ymmx?d?g;xS-m>)1TfvYN1CQLoqRyDP zp=}derI(@I?o_Ag1o=xla+q39PmNDz%pki02qSPuT0~IZ;dVP2@s~-ibRA)g|E)ZJG*!m)>POPSg!JsN^eves8Rf;CXTTX5oGB19{%W@NqrbYw`ttW3H%DL<+?>M`lv#ahq2<5% zY6FKnFOo#RHrALcDX34Q1T)WuN>pwTR>Jqp~x%8R%5Z3ffm*OB~C}x%uGAwK< z*TM5GOBxyT-r!o#LyVbG%qUXu-#Iq3s<5v9yZ3SK92c+*T^>g74$=mkS*}hLP1@jg zUP;Aki#@!-DE+{1!X)!=RARx+h+4trRMWSBSYw1*ggM)!j9IBrgV|Gg@*#5EzHUgK-o<)E{_~nxuMeweQDV9hAtKEqo%QqjM@D8#Oh*mdKJp zCY^m`ey7^B*zB=>j%Cq#Nu%;FxY2L!3nMY8;Bxa;b9<=xP5^wPQGLKlQ}9Hb31oi- z`cTmYZC+88r2it|-Th+V(qnX+NO{h#Hg4Qa(aAo;EEXd_tXCFo1u7@GtAt|F{F;eK z0XeM%~WE3y)6uM+9TPG zLmK}`9u@8!TzKjt59iPBWBLty?0~QW8Qa8*>70tD(tf+EWG*Mw zLyUY0i*Z9YMWF-g{?9rPhF;veU5w}c?KIr^4HD+=SjI)F`Du+HvMY=>AJQF9=OCn# zcT{=oqYK6^+WF-2A=9TvtqMFih!xR&A&-9;H_P~?YRu!*IfCnNk*{6snBdh1WD0Ss z`?CjLt!}2WXBVfl;sQpv7b&$|UaTh8mH}x7^b6oAQJ%_YEF26X%;q{nT&y}O=r<5x zR)=*h)R|7{cRyR_>53?qG4nesPBq?iDQE^~pu1npDr;CED*hqVeJ-nfC9lh2u{KlRmJLZY(i6=i88X|)MNro8+5*Y@(G2KEI1jrlB8mQpO zvQC|SP!_(+V3Uu8WMjEC(`3N3#X?klfrnl;;w1wYk?foJxESseq__L|BG6k|;7`Gd z+9{j@V4I@4c-Ydl%lTAzB?l`6Ih@Rg&N$5OA_iS2`tA2E&qzA8zc+e(T}HC~e0Jr` zreLm|g%kYd1S{y&6~FjZ(MX)WeKUF>1cB(vCOLkBb@{)i^i63MY%DZqy2!Ui1m_;n z+K5|pg#lewPRl)<&>`Ml1AHU{{G}7e2MB?~D(l>CKH}#aTM4to zAv5(QBI@(nK)m9azs!F`pT%iM2=H>WHo{G}-l!v3NN7)KA^@;4?Dkw#_LF^{F(b?# zbX_wPUn3aLMZMk%g=InA)Oj^#PLN&e5_-7j0o)XKoTrvSR7$|@-05+ab#pjG{?Yc$ zi_{s&oGH~=n&Kn453nAh#ilIM1-2120uI$?NZYJg{FWS{UwR^$#u#RUwgA#o1p`u2M(_yKbkp`=u(uJ8n z{>J8Dm>$$%4RgDKARXih8`dWOGS{hx=!fhdpPD&mq_;x9ucEmor}RWx!@*q8JvuBM zqWm7H6I(1D8SreUIK*$1Fkf@0Hwb50c~;dKn);$r`$Mg(Bmy%<)T4!j7g9jF-QP z^WSmqehsoKEM*n6Fs=c}TOw(>33~>B?(muJ1}?D;g|aaP;8M7nQ`uO97EZ1s*&wuZ z=z^V+?4z6V5&h-8|GF8)HS4qoI1^L)0bIM#SNP2X)9q& z#Z8R4&rx-!OXakBv;+AsZSs7_Q*MOpnK;2gS>=OUe7mVTqCA1J>M`In4=yM$hAw=^H->NCGSooz z`Pll1-<2057Cu>9v9KR2i?LOEbp`nUKG_|AJ)#Pk{f^nwfqJv=L*PvOO@w(O3D$0{ zkH8bEp31#8(Q{6p?wd-8Us^joL62^%-dm^{et1&=6wMuTd@p|0CwUQyt)`D!J!}ER z_)l%HlxkR(6-5V;0z+SB0t)Y-Ol zR@(oqv~#4Y;SB8uv42bBWGBEIo%0x&Fo8=)AN!k++!$%~?-0Exa+29&8YZd$ z5{Rkr`_=p;V)sv*J6nBoY-}cCxsFed1iZ4rZmN`Bq|$Jg#aTO4SUWgIZnU)mo-lH3 zxdN{7``{JJ(U~3(4HdStqdgFn9A8b8)NZ0szf153psiUIzJB>QfbhwYXpaV|k$Bm) z)3|IQ_<$a)^SZG&Y~H62{X13v@JJg9OxKt+L|cwB{uo$|;!7{D!Hsn5*rJ+q(^RQ$zHkM|mqD?Ijf87A(Upgm53^&Lo=^QXfRo){HMA z0i~qq6Ogc|JkBBQ?&vYzX_Q__VOkhxgJ_NE8o0zsaO^~hLp%aV8XHa;P~ViJUCnXC zzFjFKdr0RKhUU1MEf{FkB9sh0LBY1~5vIm2aKOIJ6Q;)h0dwyGVz%o?%7N3cktG&g#R&Am~#oP!|%rtZ!rirp)uGbL#WG`$N|(CA&e?>oIFs)-HS8oXv_mlcsdhbf{Lq-ztsKO8VTaC% zO+?tMw4;zc^5cPbb&U0yMu@e4@I{NfAw=6(p$06c66V?@BVGbKVe>_51dPVvN6904 zhauJgV)k|#?*Z-EynvRg0=d4J|iSQ--6V#4Ji-Je2&rO?8qPaJ=&l#I8 zyzA0GbK{ZEN>E9J##rm#kR^8+>y=?Mt4p^^?CXV-@+Q_)yRHJptPx2ZAKc}65Uw|l zHUjYu^^AHNqc`?G(?l}Yog*rr+WkGVPqoSt z1-AU%|LcV$PQvd#{BcU8fB(0Nk&2VK)z3z@+I-MscC&a#Rb5=po!8)@y}&Z$P0>s>SBaEbDc_^#LA=Zwyy47`admI6D)H+>gZ z>U8B+O=|oVD3+M2a1SCUh&i=`%Po&Hg?b(-Ha^#7sC^?5ho~a@_xnJp{Po$+kd(h< zI;LI;Og7q^qJQc2J_70VP)g2cMGddBXVB4mCTY3K;{*B;bYL4!7(`EkprhV7`j~C& zt*?NyeEy%(W+e8{5&DPYjmh}y7xRDRH2v?n30m12TK?zQrZgedwN{7!xOgMl;9o0u@Vi_Zu?CFT(F>=IlyYGjbgq*7bYuUV&5|qq-}=(TBfG<4cXTEF^K6aM)u(8eO|RTk1T(XP%Z%^+iil{5)J$#fd;_RZerXNV8N5GR1|~i*}Yt>Zs7^4`C}kq3cYqnFU&Tz8n$CDjoVx()T#{yu86HT zXk;#ZgrLPzR}zyiWW+Cp(ji)$lVO3WRqA7{+wl(xa0{1-pDv}T%gsVN|D|@r)YhoS#ZYBy1uvCl{R!Ye+BC;?a zNT5UoqaHp!Bpn(1q=egt5P*Gx0}U0+xx%|Ty(GQBhe>Dfo$REpEq*XkW-72<3YvMD zu?)9isthGwDx_Q+e2P8}4HbI}onCuK#UaWf*U-_$8G!`7qy#$olSMt&0`F8@*e??t z8#)kVdY-Eu`a6;npGp8E2v)A#4JG>`8L;jW+5D#w)eESB`a}d>eVK>S!#-p-Ba(k{ z-p~iJ@WGVY^BPnL`gHRN#?wu>1q>9q`85OMfN-o{PJ|C^<*2i1JuIa9WEa{bqSkci zD=yvX*FDe{SJ*vNh%(GR5Z%ncgo)j-xY$5ULP(0|tKyqwek{Z9-N7#rkBc562uci< zTZ~}{uGFjMM)7f7o^hf8v0=*om_D3yw=oW#pxhCAg}$H&vK!+3Vsh@Fdh+|#F6~h( zFj!>4a9jCX=B?2f=HlXz2Qwp!d1iKO3UQ+7jN z*9EpJm4GZOl`tPvD+#MS@}gdkxHfditr;f_Osmilj)UI_fNoRmojfCAK}CDuT*RQD z)ldEPay!5qcEH{K0ZuD>LE!5)$c?t;%8#`}IdtJ0JX93`QPY}-@g5cu2J(nOBr7_j zPF-{Qh!2h23{-lC&~_Gzu`yS#VJ{odDV>B>hwl~U`vTkSh@pIxMc@y_BA?w|aN$Co zQml5DmCq*O$ztEZAWbLZ1gDOpo!DX^XM8~ZED@8nA&QgrclJ&*9#9F?wAnohC$>ig zkQ9Y_Rp`ho$PWLdD7x`5{ug13Kv$MF6zO8S=afkW_vw*n*rQ|SB{_s+WB(D(UU>nL zoC=@-(EVXNpP;5%n$PSbqhoirs$Q?FC`ACXzM+`V~M0AB9eK9(b_y&FLQh~Q=CG$;my`I2u9l^LHCuvNQnj1sRZBqiG88b5aQxK&WI^YH*;BBi zrt*R1qtp1}-oo`b5ohxgh#iH^lHY@q=~tRi>7>+Nva^>5?&so-+*ZETda*{VZiRpb zU%1N-i~BqHoUDo3baY+u!t=qKzagy^-bj*Nqj#{%r+h2+V#qbaDOR2Dhb2av{0!+! z$r->mfn49fwt9R`r|bpkJI3RWiE8|HOZFDrL-w#Fw-IXDYq2!)m+}kod$22ZIQb!J^XQ1Y zafTgOqxUN^!gr|WmP1^`5K<`hnIx$Cjpc`GZ+EN+i>_NW=xfjsP*a;Uw4G+m+)Q4U zr&hDm1AX#4KrzQYeiD`mX>MTJzAP!ntT^$4CiXD3u<&QP={PF?H6l@$EYC9f5;9*W z!NWm0u4ID@HWgvOTB*MExb~SGHNP+-6QuysUSv z^=(P+pQ_eK-Ow?AZqw3opBZxF*lSE7JSl1Qah3@FjCuFjR*{sUrOjIk$e-O(xyoK9 zwQAXYk^$d!bjMzOU+=AQUu}q?!fxhUHh@1u4OzZr;MAoQ>>opFafyn#n^P_GZ%d^l zQ7|4c^Q4$|I%6?1(Lyd>U)!1qfpK*1e%b^^2P$D9`QW}@rb?FrCH)|+cG{ah^m#@x zb;;J)^tnXc<4~GZ#6l)aCuexa($RfGbv>RwBS!`myMl8k!MNIKwTfPQX z-Huid3pzDR>$1G8X$^9$7)Wp`DTQ-tvj$UR4LbEf=LKY8KPo9w_w0Mq5bJGqm+VK@ zNBK!Shv8lv(=P0|?Z!;dx&MWsVZ~g6gUFhj^(PvFO77sI?QYNv*{9DhATna_S-)Lt zxic*&u-Q)Nx{o`_fXw`P+YR0{_d2J^IJ4HIiGr|2Op_l~6^jqLL+UCVupS8oW6RyJ zqrJWD(66Oo4KpS9drpD{kb&NigJQeT^6929fS!>vPho>X&(wUj)Ay<5Q*NVmmE%h0 z|75RAAG;A!lR71X9ViV-DWRyG)Jv)fXSdkKi!$?C>&|@!&UdVGG)duvOdUkET2A}C z8L*<6CSFc>Q>W#Z!og%5B|8zmKMM*-{lF)!3qL`PDd?IZhI!hYo$R5*wtAL!`3F z+^X`;by5U1G`!`~-bB_8Wqe~mk=9KzIdc2Ek+f)3ZgW$2AjdbOFVGX}7YWoBm$;Z8 zP0Avf8s=Jz7emsI0sW`HeOi(&aGHkIs|>!whdHv0Tx1;Cr@l>(f0iU`atGX+Rnhf$ zlheD?6{=w^T+zyqG3Ck1Qkri)*}7u9;Li6ys8#E{)*L83>&sf1ls6i)T_AvGW!Dbn zfAVk!sn&579bwv52I%2iejex{I3uaprnV`EuEwL+2AcfK zhGm(ZDpqG^9*{>YZYL#EKAscQ33U6I{oLKBa9cnd!z~-VtT{f*dk-xWrEpW>~bB|dBRJ;4R}+Z}N*6F3@-xwY}ku*H3T3w0AW-qa`(W ziS_MIULn5}4P0^LsJ=A(4{L7~R7n)1>q6u1&c@x{-QA&acXw&5ad&rjcXw~x-QC$Z zG!2(Ib8f_$c{_J*MOD32L`A)=51C>}l>0Qg3uz*ZkVj7Rib4 zaogR8GsqLFP@X(JSpKpT60>!oIZR!Ow&x7FnXUucmj)F- z>9bo7Ka=@zcWisJfw)3AJC!*U%v&PDZnUKt2}Gd+5H~4dD3(A(Q*gjIG*3K=>u-ex zYU(o(ewiE}DhNL$-Q`*e%xg9`?!p|$A90e|>!)erxh7h@*AtG}B+0@!Bs3-=)EILT(tl=?a%;ys*U^`d zDzD!tgp%}zx#mx?p2L1#*`n%x86x^S1LQgAM#`k1s_&@>K_`8$vfFZwmbbo%3bWTq z8iySrecCrklxwmZ+++~gH`08Osu?bAaq7;gzA9AttYAG!@AzjqINv9jn~Gqc+hoF> z;HFTv|Haa@zOn?*LNhQM+w->Yps)&v+1t&>zhp}Ovuw^Swd!UbZXhrK|Eb4Chpif^cM+w*L?MZ`y$XYX?rTP!?gnK%J zkc3O;uuEMTQ4DX<*ts*z1(=sk{s)^G(u1e||KoPO>MqgqD>v_To_&cmvP19KaDGlCbm{)_O6UzApg}5 zLuQEwKMoE8QUD7A!uNmkBGLc#K6OV^BUiKk7qz9Kqlzz%{)vnEjR+#wO^)Y{m~hU? z{~?_!Hbilj2th)Yo<9mO$Hh+1(K0s|?jHH8xBIjl#;0mllZ+%Flkzpj*}}KoRPkFW zU|K`oV>ZL(YlgeW|MTzWElBNt7#EFF1@WkIh;`^FxykYzU`TI{@-#IVheZu(vlgIl zRxal{GwcM-j(dRLvIj3(TNJjFiHBX=V%r6mng;hs^ca%B%Fp@8FR3X0HyC=A&;RWz zr`s$zu=(A1;8{0xF=8f~R)pW8Yw$7VP08a_B=OI2PoT{<2WFzvQjxGI>6j54^W&9+ z%Mx&s0Bg-woF(tFY4M$NcGs#q(o z8K)nVIFCVE8M+v~4mu=;=4Ks@ zDHW6--(N|8kednzTX8}otdbG(xG&Fskted7?m@(2F$)QE8>@4{`+CD2!zx&w0!;K? zf5{}UB<9_-1V`aAOz`QavTKGi4ZZ0Js95&|eoyw#qsf8RYh;P0#jSPj4o<_F!50eM zk3Yy}15 ziOh*l*&>w-LmP|JUAxaP#y`aZe`7F3zKyas?^)zoMYoBh-j}+H)Cjl$QjF=eE1t7T zmp$Gc-O#-F6vQDvPquXnO^?%s1#ol6!cQ`QS2``;2aOOPg^9AMiEOfEb79t(51eQw zJ{Bp?$$=$rT-PQ$aycjJq25RbjwSeurKfb;{O zeeUj7;Oe6H%bMN#B3Tt4Tx$obs+DrSdOQQZ>^aMANpi8kh#?N|O$8Ds0^n~9L`F)% zmR%I}id3v}Cv3r>;B8!|)JYF0)BE{KJqG;)#qu?FU!;S&z(;~-UJ>CZ=vx(dlD~*0 z{als;Z&6R><IUOdI{P%>^sC2tGaXo6 zK1r?5T}s1s@c6UZ7v*O|BSm>OggGl*D{-7U6>ONLZuBJpF)6?33Ilk`lp((9RFN-0 z(Cg`T#co0s>{CZHq%$>P7138{!lWI=@FIZrb$RG}pR%kC%`+0D<*H@;N)kD)b_x22 z+;hpvd~MD6HYZDSH(*k~U^?2YP9^?`uf*^(UHtOisiX6P&!4V}N=tkKv*DhrmZGHP zyLlm+qj~OlzLP#y`Iw)`p-~Zt^X7~V_KI(ygl~5?l;#?FK-63n{+c54Y~xcDT)qdS z?;T6{`fmzZov1{)i|}2?Bmw~u`oB`h|5RREGiN1dGj}U9kN>P`wrIh4qMv&C30jqC z(Su=5n!SO*|8Q;m4YCPs92_5Ak64I7g4zJI^dLjX%+b1?3UorGjLivZmR>B5DX_~P zmHvjRAdq1EJRChwYL;K*aQj>Ak+mb8MR2~ohT!{^vFuB9NXaL{`t{}i^5uK`^{=ST z?`uOAB=abU8NEPLR7?^^2I819Mpa^vBfCIswO^X`7*6IzJNCFwT1i)Z8&6!Ve)Pem zG(ox}HqYg{#_LjQhR-ac%p}|>0#a{Gg$|7_FWIf%&2G^Vyn%Qz54*b3I*&~HoqH0; zy80%r0DqEw*sZ!>W^0aBM!c0f*MW;#wZ5RT)7L0= zl%;wU7oqL4ydMzAADeTxy%=l3b&ir5@6M`koEdgVk~vghcLIwDC(}3-D%rB2A<=ZZ z;KaGYVyaJLk@@IIpc8tpK|%&Zo!DD1H|oj1DP7`Eb;u%)id=*Q;3?yTwp=D>G{vwc zvlu{^!qO;lj$%ho^R$*v$F*xMD$iG}C>M#S9_Un{C{8b(myc=8xN^8PlR?nN&hB(_ zv07)vUat+HPhgW$9Hy{*n4}6$akdEeQm*l>md@s?$aq|=g=_~}{uzIN%g!**{;QsS zyXYkN44sOIgY%G|Vv^g*{i~NQ*`y;vW0C_;J^1-z4T|CxR-$~UKHGj#I;(?#bj%66 zGC51ybSp{b<+mN55l1na7Ol-jw7xM7`#-d+)%jqsEhEwtmZs$T+Db#8owloC!yW0j z)XQ=;;5`njBpza+xM)=@lvDVTi@jWX!A`wwKte$_GZB{-`*zwoigx!t9Iobe)qcHD zUM0PP(i)~H9uGR5D=f#(Qs#xexWCv~*8KFHW^N%I6Didh0YEYc{lSM5Z-ki!zkYj3 z%6C*gs})O>@SPoh6{x|-hY%tHOtutA<+OExv<$`;pPO?OnQK3jxlz)F6X(;HkIUE8 z;>jn4FxSqoc%Kl#SyiX+jKvT`L`{aYdvWaj0o;!Kh1OMLbt0H5sWhl~2f04~^S5~UPIzD^>(&Ldl2`t#ISa3X z@6T4-2dkb|%e)0}h^9ucc;VggZ(tX4@l)I$DXyQI(UBxX7gml5M9v}i(lGunFmouK zClfw3{+abMgx#s-hhaR8^E;=}RB2|!ZU9!L(J^0t3yB~fU zL$l|vUOw*gDu@|Vv?(hMGqpFlqLkX1iTr`XBqTf`Sr&hyUd0je7M)Ov0(0sngZ`9) zaB0O&%U=WJg2id_W(d~qya0X0@N=1Q?jCKf&%<|o3{}b9B=uDr8;HFMeeVv_=qa1C zhncaLuVx`rqtrj1`I|DsGRO;9PRRj%fs8CU>D+-}E=JR~#KQd3tb`+J6lhmM=U}_p zQ>k@luk0x_4W_Hg_Wv4EP2*q>9L`>?k%wwYpO36utsT9NIEY zDh|_OAB$e~WLWNdvzXP8**Ll=$c+lyDu4_?)EPK@364jop4zg8ke4l2NJHXz$aTkO}sSEEIa zBnQ2r2C5^@Yh?&IgQ)>{-GwK@*BHgdxcN2f!*gs+NLqg{9#59O(YtAM^QpRQnBE)ZAP9+L7m}-2LoH zOk*?kr>kDMq>{i)uSK#F=dJy5S^V+8bh+tg&RGn{m8wg+VNOroT$9ILPRR%AEuAW9 z>Ww_zcdm}h*d*ra)1%c)PH23Pa3#e{Y!b)r1n;G+Vj`*oODpG`>$cyc?I2Uf0nTL< z9_P+&cLF~|oI=TAhlMLMhuOKjY zVA9I&xl^+Z1WkF&XZ8@JbM%IV0@ZoV+)h}*E+UcFa2-6>=^t^qWnp3U&~rZ9Wc&mM>+9k%<`11=hQht>kR z)0i4HNHPeCB(%ZI4FMsr1y0-Yv7iTYLP`{Td?$TzQ#3U9Rw2XY=t0lQsz2XKS`%=j z@KP=o3_4Vq8vDsDBIk&D^$!NRG1h8{w2xP-r+Oo#2V>S=LeXdL@&nQyIM0Lyr*YGX z-N&MV&l3%QF8|mCUSwFG3KOP`Xq)3Vb1=q6gq`YlqWA?wk#GAjn1%klTyBcAtNNqy zyu_Ml&tyXT!pcYeBMj-NC*niZh;ARC>qaG8mcn+bh~u6c$uSdOhRQXaZx+23o*|3h z9JoMZXYXLbI629C>mneIvyQk(=)S10#)XH(FbuK&)X07bpCWt9xB9lTDRWHET%9VQ zr(N8ltNm>eH`^QbKxG_IJuphlQ8JCYa8}Cvv#e-6idE{A&{Q^VOLHQumuY6uadjA6 zLZNWcXpqU(xJ*?vxnnpTBdtNONLFUjRo_ZWNv=IZ?J-OzB=)*owM^xc^vk`H9b%A) zDGa)-^<2HR>qbg|cNHtw3)_3f^zzA{W^< zU3{CMm}eO`=n#>9LJr`24RyP7fF+s&_rQRTO0aK-SdhQY!8iNJ<`rhRd3l|RQ$YRV zjyXC!q8!8S6=}CsLtvE2M{n5bBBUU+r;pnI^H6I+fzo{jgw6dOcZqSfe0$CL~CrX=KSa{ymB4xpZHvDK@6Za*b$oz$@AI+YqoQw z9V7Kk1D;_=N3}R5C7l+mj)ny;AFdiXITaT%*oQ@(BFFGzDWT5B692>!EQ#3%cD`;7 zjqy%S2Ay`n&X$pwcy=;;e%@1stva>VRo}4qoxuvo$rBdU`$7P7o*+`+U*lFs^NwNP zE)Gu*1-V1>D&xK$-S~FPtZ0E5%DPm&m-v4qfN)q!Jdv_#%p9RrCa;4H@2``Q)!ogm z1eeFSs=PSiSgYh(QR@5B}vh*a>?pJfcR@(s!T`ntPcYd2mwrG)KFUWeW% zUl(a#qnt_$aLxCyKTl{rg&h&TV0B0Q(Sg_A7uSEq+iAoDnW_I3o_UjCBrt1n#E7QG zxk&jS#wJFhI?GWk8eJh( z7ww!U!nsN=Ymm(yvd0bCshC(@sxlhXAk~O+;m_i7K;01Pyy8sskbYA#3yVdpx$@^dz5E zLnjza0|%w6K zR~J@gRm&gB7>nZ+_yf)7ft2?&0@?(s{G)VIM*{x#kYqQxkP!~3B4`=wwdm=pY|8tN zX48{}c|+RdMLq6v8rAXaKZ_44t7(6r@f4!IH=#|S{n^17*Wjvcy5;Vd*Jw&9NCnZ6 zQEE2oQ!;uusNUu-Yk|Ttxqk28KzPvEtoO887r{hdx$h(SPKm3tj4Q^2oTYqMO#-6x zRIlYUpByZ_9^uX|Y4wTml6(_h#}a+XfevJUWeyD#pRJr&*Rf)d$YB_O`kyNYvlNU4 z&&EV9DyuZ9Gy6hcqM!_Q2iCljfLvFZRi|)j$)o9NIYU7BGVq_cNwzIELO zGld6V{|#oJmfR-Z_Fbqe`EI!u{{NOds+u^Pnc0&u|8GZ(nxZ0_F#4B#*L7>XRE-*a zU?FC)xR&sTXr%->awa-i#lBEC{ANI{t;OY4^2M~n{zR32ce;=q-z#Wz-o&fB4%*;= zP*3|r*2~HC-xu$u2fvT^XF$IyT`7v_R+v;$eO zj4k*4n?POSmY${UUn0x+78GU!4sB#fm(+2R-$j% zcdBqj-dbk40}QU$6@tPLr&AdxT70G|u^ij3H)aU4`fo6QdNOb(LkHe#II+gi&17IV z#KUEEta(%fdxr5I4crC$MH7QMMEl+o8M@NwZoG-rDb48fQB!`) zf+}Y#PJ8iT7(9j~>co^T3FZ_i|pY*Dn8vr_~8^b+RJiAl-Cy%xSbP zN#0ae$I?%Dzlbe{g-r0GmJq%g#)%Ys=15r~GV))ihuEZ%;tOVlo@9E&EF@MWjR+-G z?U)$sv6oc+(Z$ko#36WOiYkE~I3G`>x{#&H#lyt8uq6nx*wldEfIT|q2U591wCGoh zg|WDPPryKZ=QBSxc_Fy*I;HD;dW7TdF#Q3fe6iM)cqZLRM4U>!W*uyltA}OVZ*R|d zxi857T6BKRe0jhi7oGoStAgb}S4D~Xw9BR#`j_32W@C|xk+qD>59;(4LZuL7 z*a5qI1ZitW0V$aUAEBD@$QrR!mc)gAc=+SP@eop|8Gw0v^7mk9c=!&Mp%DMyXq2_t z%nqvx##_=b6?~Vz@8>;jeJ?w`+XkPX`;;JQ^%O-xM&oXebDPd!L-ci<_9a)#Klq`2 zC(ASbV+cS|R;*n|fxv>N8=e2kBmHCyai9W@G6oBJ=tlye1QNT@XcQ0UFRohh-UlaDFbGylh zRktQ<$DobS(?qLY`Kt5!Mytz{T7`Vh@siRlt6kW@4`Xu%NJ#mSAt|QeaD??Rjf?>L z(ep_d3~9bU$eeOX@GAfQC0`vw!BDv{%`z`c(|ShlzY-)|#x@vpvnZfUvLA*P@P_Kl zmuak=(NeAz6=EqexdsaiiFLNuvEscC)Agy@a(0Ccg2KcsDqO2N;VLqV(P((a2+LT& z;ww~mnq%pQAJQ$bu+TJ)GZ!O9JNPVqW7T6S?I4rq8y#%fxmeH_zY{6%mvb}AWRy~A$1Vl{`ht){d+nkaqG1=F4juEz>IE^(r@sOqM~X^gCzf$Y*&b z{K~oQGY&F-t~c9*F;DR};StJ9H2f7Snd4>4!8Y{-V4otM%~XXJ4;Mz znqj|wb)*U(PZR9K$}BdE5w;j--zb+_eSDHi7Ye^1@;GJ`Ga?reIKXxMzL03&@QEV2I~(0}>Zx5YF-H3~xPv??cc*e-&pOA}89bB>TmBJwM# zSb-RWSy-ThErPo7bb$@^=#)ND5p6LG_vS^6DM(8@S&~_Z)j)q@C%_eItk0_GUqOBi zhihgtX?tWF-t(0QNx#+gQF~CACz+GVJIb~P(9<1H(YgUuUeU(6LULm?!>cyQruLCM zdAO-xxu-+r1}~h5lHio8;D-|(%!6}lqym=Ipjmd|!C^Go zK5jAEqO)g-M)4s=yEAagL%$IyZEUY@sspq(pa`T$V2=br`ANA2)=YYmCT*W z|FuWClo6ArzNo?fztxk?qws`9!9YOHzC!}J|4~SwVq|LN=AvqAWoqX9zjaVe?>}^q zpHqWoOnGrQUZl_J5OX4c#wS@t7uHH3JTfP_{SYS8{`xWPP-xYP!%s=&>Pc8T2L1vs+^wOTl1| z)ODyd=L2hw%)A|?Oqujm+o2TAbsao`Ne0JeMRH{${a|?>`yo{_^?ve=n3h?DQdJy+ zR+b2gDu)bW=|1vJbj+~NLN-Cbk074IJ$Q4N5xEHc6=}BpXFO!UfxS#mUa@yd4M7rJ zL9~Z$_oX3$1x(wh2(g^o2;-(`EW|3Dj3?o#ZMKIaC>9K>;;`!en8@`zLIJPt&{ME9 zC$!wPnQj9xAgHQcLKAOy*qpAJ@A=NYn8Y{Ean~0PEr>|-Nt=Af0t0H*Daf&N7p_BI z)I4J?rDID2Ws!q#@G4@aCWo@IMpkoJl0(4V5lz78=IBevs>8-}Ls5JyO(zb7 zqK(8RJ(R&7M?tc*FWr>OE_}aD26Ok}9_`ZFqAub$-@XZ|*WD3m*O5d1orX;Frt;-? z{YPr5Cw-{4w8)K1>C6Ym-)%sK04guD#h<5Q`h!#{(g!{{ZSz7Hyu%mY<8Z@*VZ8KQ zV9RVTXYmc$zGy;Z?Gnqe0{Q&q$gFlyoU%2=zh?SXQc<%{x1+34p4=1pjPn?>Lo4?m zC8nLIQFKYs$I-2=Kro~8uNi9pfPrF#ICz-Uwf0G$rw4R^d)ihBaPll9myxD-~P7?u4c zmzw)N%SZc07&bx#HADLza*qJX5WbDQaglx?ej01ne4ZI3N;0di$;$9$i1nN3C1blF zX63A~91wc>1SJ&__y$wfoos)^mpx!3N`Og#FWMR!j}c@Fyq*L-61pDPLAm*Set=u6 zyU1alni#>juNPWQAV@Ka`_VgFb!mBIgOb&qd)gh*_8OG}MBd~YOGTe=rqKWKUn3R% zU#oOh5FjA5@E{3u>R|uB_klEKUC`XnzkIUf-IMHz5hUnaKjuUh z!C^=w@}ZL#3^H5SQh#8SY)+?{o||*t*i#YkdEF0t(y`8P>HnIGidB=e==OZr^WXQp ztHhdA+T9F}6wg)~oAP<^-F?}9**X2U^$+;jwhM+WrYD}&4>L9cb<=o=r(iYV{D-{l z;`CpClEkuWPQS}_x0TKU%)Mw#5q%HNV$wo{sIZ#2To|mpq334gFAH1J_|psFJ)R#8 z`NnTOlHib$n=4%XYp6UM1#qspgakO2fGvJ#gC z$DR$AoUpwDl8@s$IMwqO z>Qo%L@j`E#kSJZVhlR%BCbjl#s~EPJ>~Xy|9sj&#^cQIuwIlS`?KelV^2~grfGUq; zalbLQYK;ss5Fs0s7MNM$KJDU~^2iA>yMF(;10Jw7mv-e>sYUH0-mNVXOersy#m}d4 zqd1&Y#8=s_xQCivw@hjH*dQd@ZWo6{)2)@Z3fUE+HvKX*#EGmq4}9v`SF@I9AzW;E zjgX}j#`6zS8L)GeQ@!aCe4 z1}RGjqdNr7=f?n&zeG9YA*2b~1e38b*aMO_^RCnsb+~B8hvzA05#=i=LVTBEdC#H> z5vcu)KqkoiQII7ImLsG)Gf1pMJe@YY8#}tfO}o4oWOz0(E>-%(K5Se~7dP~--bvJ4 z13py?UVX(H29nUXMfT(mGdsK|>M&@d1xXwxO>igyOp z1IN+9R_-|F|F$5%_5DN7-D4|X&k}8hgT#CDL357gE~F2x;Iz+T!pPN-myVKS9q+yR z8Gh7g;~Bc*()=uO4Y841=0;SJa<e;|K{T0um5!Hrq_`5GrzZ)EM3pkB5yy}&NIS}(1ok52f5FL8owl~s&}4{;4O zT!o7bwsk!!oJ_?8<$D2~`ubqxL()d7MH9DsLL`HmJ;wafE3W>jlEk1ALCJ^E+*s9| zqwcViI@w-?I~^RLO&m%9gZD0HEh0}0wJ#j~6S-?Jew8Zt_E198nMOc}nvNTRQ01)S z=%8I5VvIa(PsyRw+?SR8k}2!BQ(+;-SubqZtug`IPcj3RCGzkU6r(dnxdmj%vM)?w zzCgUW>3{$+{E;UR!By!!znqIv43Aw>=dfPb{Btyp4axLELQ__@en>B0=CAz$tr+jH zQ$@mV%*Z!QVEDlQzbQJXVEeZEckW3F{r`)i|DVxUj@q^=o;v#1cDyO)#E;Fh4Mt1l z1_~uDL2d8~O#xgf2yMLJRE@0Z6A=xLuBjV@J%fCt_aoK6g-9&XaWh=wuX|lHuLp#t zd>&|UC5S`ytS>hmr#lb8zd0_qd0!vTyuV@8(1)=l_*c?o24z!1uufOC(Tna^m z=yZ~G%l-sSgd+Ej#dq&}#$sDw|G_xtWrzy8TYM{FbIn$cU%o@tH*a^dK6sa{CHJJI z4t>SNdcomwek+W=iwtdA=us1lk9@#okP4BBG%KUArul`vfV%d6NPk~&fGS$rf_RyF zSvoLRwy)kjnh)Jej|*ynJv;4dWT#zf<7Hzm4W4|zHjfI<_lOrTE&8CZllfpL%hfCS z@p6a&@sq7PVhe6rVE9XJC6r4CVEKU+^9^09vcXa95@0c zCi*=BKq*6+zD4^lk>_#~GJ)1n$754W_=fk^Y^t=WPz>lXXDonsPBuC=k8I%0LU#*_ za={)7xp%XWE10bEE++m&suTK0JX^ki&R#+Klc-1$27ersYAr@+cD*@b1KMp7rmUzR zGj2|L!55u0M)_m=k9Q%(I+WEXU)OBekI1Fj`3aI~=?mWargr&zcCsTapXiS9v{)}X zF#@+O;tJBln?&?DvQAA?Aj||L&IM1bAN-3_VTOv4zfvIe!ZrL=fj5_M6LWU)+g3e` zC6z_`JJ{0Ih#pyE&);@ivgl%!8B=)ipT}!Mml7me1g{WY+Sbc;D=)y6)ng+!rOKG% z+GGUv1d+;YUk9XB$R^TIYqCQ#{t}ObbtuIGs;;xr@I%FXG7l8RD--8>vy#LXni|$) z+kk3vK>&(i8kzqUU*pvei8XP$dV=akeV<8&eMxujgKK5DHP#*X`fx?^Ix_keoUH-p ztO3B*7??3r#4V{G+T0!40cQkVZ`7;0C7nsKIR>ri0|Ki2qp*5D?U@DLD0T~Oggop+ zH-|)FV3<6g*u@!4Y4+3;{~yku$27)tg`vo?Pl*2- zj|TLtWHKJr3P;yGl-y+FZWVG%8L*$iP*^N?5M~v z!B{e3TyCD2XX!e-aJt+=nvOF1JzKzzlMOo|{3_4O6M4WZ*&_58_>^^EwLMUeW(xLAHjL;HD0F+{uR6GjQR(MaUp zxi7#-wxY{f={@w^6j~Yv-{IEL0@My0X*q1x*4(hrjm#*m%26c6Vv#O+F{3$=VMAud zu-GM`_0G~3rr0w_`+=##i%NRcrnQEYh`{Ms@@K}|Q0xr3$!sRcr@`V!mmJy*Jvz+{ zBW#&+8Jw~UBh%FqtX0Y+*0oppgwC&N^Le9ZkC(EQ`xtGp06|sY`6HcYMq+vSr+T4j zFlIYN$S+%I>EZ-cq}%kSi`9=a1AmEjib=>=_>K+hO|gpk6dSw+qbUZIfEQrujALMu^)j<90V=#wd=nPng&n#1VyYB9n%B&Fdu!dsM#1wJ zu-l1#Jr~6O3yD;!p=@rl6vaeZ*NpWw{tCu!483u@1#tuYUbBo{dxMC2 zE>VDlIy_EVK=Pa6_7~=&3b8tbB~Bpmx23Ts%PVcIJp`&^zcy2u4OF@pB+pz3Sa)CC zrsST;FNCg@AEvFV9v~3PT+#pNne+ST&*PIVd7UY3R4{W{)vQ;bQ=f8o7wM23<2=1! z552TU*~+eXYU{P87JR~{jS{xcL>gVgO`BRS(9m^Uu#qeglV&a01V&biW0KN72P1Bn zla)#ZkGalC)`BF3|8DV4Cm9GxoHhuE;Qu5E{?EjBnh(YkZ+V{8f&5xq zpSKY|WUZki6MPJ@!6k8+?5Gh9iWjEUg$vYnJ<$$D3pFttj4BzEDtKYRIm}sA1-1k^ z{Ez~lpK1=1s)Vx{or)9vkGgjLYo1q^cAXjbxb$CNf9vaBlbvp_hm+~2)X#$^U!))X z#wDCk;8ZkRu8x6lM*3vB8PWDJWFHCrCrZV%$k)CvM7Ke3Kf*wPvd z?3Me5-4&z+@Dj-QIZMHgV!mYQ)mJd$fdD6e3l@moWxUF2^5517Y{A{cTs>k@I$^qV zD2SIp2Sn8S@74rgs&)Aiu?0eD3S^43<-C*KgF5)Xq`R z{ZUFB$(f!^DAzF_;Akl^<`n`msv(8VzZ-IZma{beicBaE9^hD#KWsiG?1R~HPNv1A zThUNLOa{sZxd4bkKD5WLXV4`0dZ_~H@6ee-LJf#$`QQU?K2)eO z3}Wd98eeZ&Ha8cQhR!x@y+r3N$P#qHqtrDARXWi3)9H>Ojbu8b%_uU!qt&%y5L@cA+qe$m$UBRglMfM9uC$CV zTs2`R6X#xD+t}a13U-3gyLoPG=8Q02Iu06#5N!6yFmT;01I>d!g#Fm1=nLmyrG8Cb zTzJ0XYL*TCf>eWMSKS#r;~+82xeVT{+xO@7N>z2U4B=P+1(%3MlISFBY^0uSZ_^7y zyjeyy$1*`=fyv=pZ8U>#h3xdIRmeSN18|6@D=O1r!_V2G%8P|jU0y2_ry9k zrYrt+3H=t`*h#Hrn{MaGzUalF>Vhb8Ts~$WorUDp70%QM?ikLQV z99pP|Aeo*qT_Bq^hwyVyokq82h`pZm(vAtH7$UUDFY~R~$b!KxGiLoJAwr9w)Zx+* zARFCEj;+|JKN*0xCxKzVuy5WDVYE`Nq@cTHq-i&{F!F=|?IIzWz}=l`^%{%V#teF~ z&=M2FUX_^hpD?G z0Ju+LaI7q?(%Dz;xBhiqGij}#aJQ|t}qkMQNWI$eyHeSnaw)+f3gEj<=) zr9~oUvp`;vZ!KNEE=zdFE}6euxUw(3q~!TXPBF1(LYB!SyJKL#JKTf^Qo*fC)V4kx zV)1;S5|oX&m9b4dHqKvQjH2z2)wz1Y`pL`uafsa7s&+z1;sEV4vTb8B@&ATBWic!vvkeg7i4;JvG7vWyis_9`i>)KxfbIe%>e@4m|HDape!fLDM$6 zAJ~xSHDd_x(7XIfS|IP4Fl8G&`jih#OMi-WtY@7-s5`r(;iQ_doI;o#y7W=m5#q{I zkkQj~AN^(8)<6o8RL*9Z-pT@1^?);Ky@^gJ1FF{Qsb4Fd&flh+zU||ydE)~%~ ztPKVBUx1Ja6DpBp`0yW1qCqVvM{T<%sJ8Ld`yC~Ovig6s&0huo#~qd(wjPxIS_#o(+(B3$g^uv#!|r zEICO7G2)i5jM?&k3)Ga(%JYMU8LVv)2hZ2VutpIL{AVToCuVfDIqt8wrkA2&$r??wKBY*bqLfJK8jXB2vi1Sk5IJrb}lO z-U(0Ki^Y~J2o<;YPcTsxOzS!`R5Iz?vE8cChqV<=fu)D5(CRk#?s_wR80%cv#)*n3 z&f!g*r!%&Pf~z7|zN)IjG)HFg7vGbh$~Ak&C*Ir`uI3doyW)_}-D}A*TP{-Y3Ia*t zP6YH2cz{APBdX~~rL!!h3&Rm2T71Y>T^h8zx7#}7TF2Ht0~gY+G=}DwKvqSHO7-ccbiDZXvfs#KHBh_WqJRCJ^&$iMg z7F`cA;I9ekW*gKf*^jtFnUL1*3fjlE35EpxYTOhO@x%lpJ=0%MNSU|gD;7U2$++JSU@dF#JG2i?Bn*8li)#`FE4B{sDbEX+-J z0Tx&VF;VlI2p}*Pke*X^^=!k1F?+c0z2W*LxsjF)OeDsZX|$sBjuAC3Iht9YeREM?_cBX z?vIJIE2b~&!0?&DRjf5Yi8(k z!=l$mcOz!yB4pxOfk1lUN`0=x`9HZ7u!@K{A<+;(D4rd9up>)TE3Qmv8qQeyjFVAs zpa90p*;<%)*zvI4>FnL;_-ix$xxN5S-jyO<8acz%d@(a6#d6e7^`Fw^a&>k7gO#Gpn|@`K*`S zFyU@5kGU>!{2zaGLRH`?&*u++?x_s!J=5XLngUY~RcBtto8rdVJX=>AWk>n98jt(vaL6Sd>bz+B(sUw&s*(g7ed__!o#I4u;Yt zhLFlf$ZA`XY@0*B$Tnu6M~lp#4B!o4cTVEttoY4q8J8caxzFx1hb+ejW*vnv^5M`) zQsff?$FZ7N{%*JbVt>2Xd4H_6mgg$>Rxw;4TP?(l|JtgTuU zVYpXIP?SS43DpH(meitwoz&QP>yKHsS0?JNq*@x$+{a5im;Ua4Z)O@AFpk$nU zoMEDp$CpSNfzPm%w`--Kl9*L&!Q~a@kdvDehv}NNrt3^WN~b`iEDbY5-?G+qO8SQ( zd2v7`?9?g)TG?9Tu4_$8-1 z>OQUZ^QSD2q|)O}lbIn8-B<)-hh||^i7^h47iTM#%md8G2op;Z>Xk2`IrX%WW- zlOj3bc7^hsjQy3@wwtIp;b3|LcdU0Q`!EcS;HxpHY>-o2^dkvq*(J2R- zcU9REHQ2Ncg9fBIy#q0lg6+b{gwJgJ;s8rKdouKWrsA?VZ5?-6f%)>r%Eoe4=Jp`t zhWdO#)bD%%&pilQW~quvlNEBiHM$&k{!?-}w+A)VMGyFlM^rqQJVurq%8BgT{na5T zsneVgNVi(?i(YIswfP@%HM$uK)F*s;EH|=bB1hXOKwz_K_ z8cE+MwZVp>HHuZui2}_Hb1<+v#{*Gfs{8M-+IwP9cr~UQ2)?tM#pMCMa6?`c30lS% zewvZnl_@kVd`|@6@0#SCfent)w{hw|Fl8H@xK)z4KreRb7cnZ&%b_g~fkJR=B@ zxVFxpN-2!e$(`!i|132(bw$HAJDMBJoxlnzwOYGF^(TL>GO9xQxpH^)O|wT`zIC$W z5~W60P;zT6Z!QuoWdzLV3pT>o?+jH=cn5xnxSsPG3i62Ap*QUE}R^(nG&hxF4 zF-t`HT207Hi>&U&l|bK(z47J^!b75fn%tY@J6;Th+C6S62%^$nQJ72h1?(^%#+s}Q zfKMG6TO?&lXuj=Et|#?et&PTAUsYy6xep9HxE;8fYxFyJMn?k%BSnR*W@nubv}Igf znyaEbu9Ylvlxrd{)f>V@*5^wRqz#_HE(rAj;HD3Q8Cp{z*L9S-~y zlk4rIFtjZTm<1t_J{?`kO<0MmQlNf!LN`s`5uJr+4lBFn*+H}F#$lH#Q*f9utgjPn z4KCPd#kt+XmBo|I4KP3&6@p|R`k@#S!(|JHQ6+~v-%}7-?HUIgkW6e#CkmGY ztriX!xz>wC>zMdVy&lGhl}G6h&c^szyV{Z;r~@S{?JG$?!~XGKgMNvb;87^#g(-Op zx!9$*(^co2MmIN0T7YFcpbm0=lbL4unef7_f~?I+TayksGlkEa2-0?#D0_@J1}oN& z5U)i9H_YI3oHTw7O+AL7INQ?=0;6)%*HH|k}cTljIXpJ zEG;Zmg6AK2HWK0aEy>3@T2X$qMUAfMPn7%6Z)!b$45^28JE<+OI(l}%52M@9UdON# zGLgxW>WR+zuSTPI$7#zuonePqGfic<#aOSK9+>P{qlV?5<{7((3sLJZ(OcB<458Oe z{g=Wirf`YV)BtC-^z6VbqAAcu)eVR{D;U!{`HC(yqd(${uG33HY~gH|%Ag-GLC}!W z8Fv`k(dnsWyNnKtvkWd-<$MI(Y7xTnM`KjJ2Ct=G7>P>6{hSij`u1m-)`Z%iSN#h~ zFR7OLD<&Yi<-mc$PwRCQ(fOL>IZB#4pR8VtL`xILk6Pgnqr)w2rItbga85CIHiSe8 zCebO(3M!3Z?p>%WVV68C?yUQNNIR$C%%XV92OZnC)v?vFZQHi3j&0kvZQJ<1bl9<- z>6tqZbMHLenW|mq>^je<{HS3XRo}fCH~miwgXE>b@NkGjYN*q z??E81xwXzp?^vHmD=>P z5F&C?Pxle*&+>Aar_|qc*h7J68d24!xnyr+19q^TB$(7gm`u`kG;NbQU80+yKW)MLQMStA89^uMcvnyyMJV z^Y1XmlHEqqXj8n0wC+sXBN>zJ&uGlb*>(K<>3A8g^E_0?f5Q*Ht;b>O5sSFJi@M#5 zs$<|q^pW6ICz;0xio{Pxf>d>Y?M);jVFdYE4{4sHITP%jfxzGLX))yFh%pn^%Y>vK z{(2f}odYv|=+yA*YL&}Ga75mT!Q!=Yq&pnAt?C7Oho}2j5Bwu6UM8&gl?E2F048)Q zKmz<5i`Y2u5A~{HPxY4By=b*oaXX~X8IqEc5gy_~OXXb7gFJ?P!!zDB9V<|j>N7TU zc`p-(>f!(?LzY`G=>05LhU&;a>BQfY__Kl@_Yck=AkJNdqLeOGUHKQ|{dfgs6VKN* zd}qBe(Fe4lHKeHwMH3l9!wO`E<)ZL3+hxSPTniQon?hgApFiWgQf1d6*Oy?a`hJh} z8%Xz!1<&(O17simGkhq5oDknI_ojTEPOAkIHKmR?lMmqM0dD9ix7He<29TMVvC!;Y&l6g=8sT|to z*)8}m0{?DV&dL>~M!29)>oM6`K`FppPA5Ln{;5~0*n6t271g*%El2NFQAHc+;B-hq z6#*lpj|?QD&#$Do%02Po^(~S5jzl}~vp>2kayjW}>FnML^!rHjtnvCe3*z(XGF#Gq zaikWB)snk#|Nf0^!Qhi+3bWLl(nV~CSr(-oatpxHtSV}gD_knNR#&PtqShOtzz=z? zF1ZBh#8SLb4=YB34?wR_VYDmhBJ>n^P5U0rz#;hD4WVbE%{9ircGHt{=lCHFLm)xk zhx2tr9MnNE=IDmX?7M^dW^yN9sU-=_;>?i00?Kmnb*|jk2_OREZ+L)ZWlp12WbolMT=Nk}+W=Lyl z=s;l95=2H!pV&zoC&K66)uU-rreb%krW z6>ov#;&nG`wkxOO+F_wfl4m#R9iyrF`vkci?p7C1V5_8lVZ`UQ#~Zk-aoN-TTkR^F z9+Y?KMsQ6X#KUV06S%Gnw-I3g<#;jb08gLq$(Sc?ROiw^|5K`_@`1}sHoBFX)M;{KCBK}g< z1o~68ZCGpy;$aVzH--1WxHNz7d3e19I_MI_PhZY>mAB*t0hyi|p&4rBZ*5OUYF2b%{cJ7P}L@_e! zXQOXW_C!fzm$I-&-2K8n8xCI(sm=BSErb-yIUohAo%pS1jgCHrL2NZT3R?}t?a z@2aa_sIx^Dl4F=%NrU(m2Hb3-+=B^T{J#phRp$fx;$>$-#fNC3DSz~L*%Q!F|7EXV zPW_&N!vbG%!x;l!NPn8Zi+nW;8*qIic7ug`%8@*h-G}{~_MX3y142!2{HGwV6JO`< zqDadNyX(@sri;~PnHTu*mUvDFCS9|CyK0=UBOI*@6d9O1FQ zRAF1zbSXmolVH}ZFza?-@`VdEPlZjwTwMAU-^J`z`foJhImhkrMCr$3J4R`4z&flG z%$fIs1IWp0MnTeKm3$Fm2p+6GvaZ(f*9&yK5X7LvidKebvqw=rfpC7tu)OQt1>#i< zWGX`gDs}_L+W8gdSj`!jFnoI_#t~xp<3O_GOxx`GC4g!K?4pYuYRkdZbV&(Lx4N=- zhDm(|p)1{7IN7NeLxPEv)4UrKL|p`hBe<9?r*O>5rJ5t$;|^^5pvM8y!w0lGfc)j> z+R!C-@HL>-5$X&3Y9wGlZwOovxfx*Jhgj-rBn+k-+NsPZ zYF8CQmH%VD{3C#hDIgF`F1H^ZF)eX?fhMq9~FU+HSz2s)suJ!LxCo}E$tiE zCfpc~u>V6sC$czp3m??p?MKXTc>UzCd(sc5wp6Z&kl)GVl84C10L*M>zM*S`iO2_bt`JTAxsP3LRP ziWj2D93}jOxsufjX$&Yyf*7zI(L0Tol+JYvl*Gzk?_!a_2J8a<5~JbC#7JW1Rnb6KI&BPh=aP`6c(1Ng^>8SLP~e>`WE$7Y+@!O8HA264wJ`}0g@z3ArQ zFO^Q=ua-NXVdhss9$N}v@w@nDDg1ppdU5XB<}-1CSpUhDU9gf(Jb&W6m((O_Pqwt` zYdm#W-JXW7o&`b|k&HM=aJIW}4wmuySa7e@5G@NBKj5 zj)Vhw#ETYUk1GG9$fCEkfsR&MH%K`ilUiw8S`XC9)hLy+ z$z)`-a`76Cjdqv<#Zy&_{;XA8s*DdkyCfO4hBdr~sum{Ri4ClsT-;wwu4S+OZZVW< z9sIb}`(3dssFOdmBTl>NKCCV1oqlgE+$}0Jq|RO7Vp&QzM<{*1`B_C17w58Wv6VMR z?_)1_kzLG~ZahjJ+g{uce1f}U-!QZQoT%*lu+uH_<%4v>Wy9ked5t~ z(jNIwq9GaduHN9V8(Ko}dH|m%0p0ewmM8^t9{>%i|Gn zoESXAQqLT3w<7CA&tPe<5^Rr1DsI1DP_Fea7<6tu1aYVePIyYn)c&&>x3CqM3NDOF z%yLi1Xbj@l*hO{nAK|wEL4YkxdPqP}^@sySAE#l&OYX??zZjE0(n*5>skcg1pmaDb zHluuECA`p{c&)4%HIoi~lJua^{d~IgAWbqxs^Sh`hMFOr)gK7i^q?V;O&hhaL`sHq75MC<7LXHBo}ZUvTn-2jBZ+LeL=b+5Klsk1z1|T`F|@4Dx4ac4v_fe{F?Y zDDyA^%5H=EDVfLTP5NAj`PuR~Aq{NrU2@X8JfixePC#L1;W8I~&$+T;`5|UuF|Y|j zWugap<$%VNKHL!gRx?eGzd+kPY+|#2Ta(P`&h+5A++NOOEpMVV??!dfZ|Sno{BDY^L=U|+ z``c&U=VfpR?9P%{Vs6`3w;85ZU`=}IF*Y-ZqVT1C59Yx4&$?E#F}VVX7*RK{&#WOO zQ|4AHCiYB}_A6P6KGrtHbr(@B>Fx{wDcYfSD5WU&1sBizbE-}2;vwz>R zJNMs3T%^NtE`S+K8wXJ>gBi4AcC475V$*@dnst5hY>IDVN4GJjQTH3k^{nt^y!vYW z=~zTR;;m)Jd*RrOv*-&_s7uHp_d_A`T`qEToF?!i&6M9LLuum^+t9%@l9>tB$#aTM z&8&;%=(-DEN~Jq{^MUM2fp@jzBi6J3QonZbs0usw8P9TnizJPfSv6E2TwG&pT{-*8xvbwcBC(m~SS_yyTN>i$th4_gfn3v=vvi^O3nI^2y}n@Wk4i?3C7 z!jNs(!@5d<;6JZDAe?M;$Mh-80Xeu4cKR7M`W)3Ie2bw~aa$Dz{P3UX z*2r;=r=S_ji=*Vfi2`(773EllqegBt&iw}jt;;(-}KB0dpX377KElSMZ!ph#v%=sUvQ{;b9 zG|83Cj7%NeT>rx#Rja~_xa>>;S82&O>0pfnT{$a> zPHQhXxTbU|O4guAVJX_YEN{+n5$aUL%~>6_-<@B6YSen3F#kTcpWothz8@+8`~`Ae zoGDOD*Kk|=qz*b8UIb46U{Wl6aBAn6=?;61+4ukqKD>0Gy~Gno zRDNOSG5E5~QcRs(ZIn|M3BA*b-D8ImS3_O}WNsNJ@0x{&|tJ&ba!FWXLJc zbfJ5g1W~w0@-|KHKDB4kOb~gzj^EGF4J5#VN|5%blnfm3bf++o(v5^Ei*Sq7w{N7i zylNsUF0r=M-e&~eVYjCCLs4F}#Xs=zbL0AQgZoU5Xhe!BAL$#nG*kI=5FeuS3b>3N zGRJM$;ha5}1Bp(OLOcA)_hGCUWy>-sSK3!`WVKb6myv<+8_^uYxzh97iq*LcCu=*D zB0uH!G;>$f57k2=6mr8Aa*XvBdN*8!6>?e4<*z(bVvp`6Aw^zWA`PAqXVD2=I?1wZ z!7f5@>_~^r7w% zsub#yWXSMH5%s=z(nUyb(3*>OPvlv~thQ=_TwuoEBF4Hb%;o=Q>kX0Nu#;JiTG>A*_%e!JjE!o`C z12Xx~i^mG#;OphrX5gMif3_dKtva~5$>h`K5Hwdzq+ z0XKHPx27Q1T5Myo5*!!-Q-a&?y++NG$Fg%uhfCm^&iIU3npHaVk}>uQg20O)_Q-{z zrW!BSq+rU+4{cb1%pb_jvwT72ogt4a3vZk!-@j<}`>Fca!0^}?ugj}4R>`F-*2#ru zU3@ZUWh=v5j3wkHp-&_fX6Wm8Uv%Y9`#~^N>DM7tX)o3U#i{(kP-ViSe;9E=#Vp&nMWm#>w_9nPcX(Dn;b>fO&xyHq~B6V<*NOBJapF{_8IAh?v931`SdJM0;aBLxPGtr=YMU{ zSTg(#Z9!W4$+Zh^1x3F|i}I{PYfY%eHz2|{1Z({waFz`U+#BbSayWqc_|X5JLN-Z3n~LQ@LIWC!eE#`7gW9@J|0%)<|la+yQv z$&f1$$AIP=F{H8#xG3)zkeq*n^AHco{|tNnaG?D8(pmh@h zm761CkL{SOP)KA#kr#7>Fj++*GlWFGvr9rRJ_jxuc9gn49qSSo$Yy}4xMffp@#KUv zvAX4$PM*ZKv@g?J&q`7RkeSxmYwGFrmwtTkgj%gq87f)*WXPt&V#}a0!bB&LwdCBA z1xD`wc7Pw#$>en+!>2Nz!;e}URMS#~cX7?2Ga{Ukpf-iw3NczHV$aGqV|FQyF}9*m|vA!$}4Q2G^sD@?Q@ z^U$A_zAwduKwtJrSnaO3gvHTdR!3~S73(K8i4SqhUfN}3nFCpZxugbkY2>oX^NV_ROsd zlgzqG8TN=1=b9;al`do?WY#eV5li|7TQ^kE+4y*yT0KGsI&w0qS$cJWXN0T=KNZ}9 z)pCJt)ELw@)$kXZl;gyXIqLbVh>86*{Afs2K9>iTsn8Aqa)v!u=m)tq=P(D%HbA+mycJrM2S!NjagtFT00{>d`4wp_0AUR&{#^WC}7^xYaJKg5RqOn=v`E`B6<2KJ75I3qD`tuCW}@PSd8GOvLK{kB~#?9hBgG0qEob{)5W2!V4*j%SA+AmcdAbiU1tA88VEk+)PI zg_i72c9GTq)hA1))DYOYqt7 zj)|&PKI~|QI;q9&WL-mJwN5;PlU!`rm7KdDuCH=fA7($;p`72+tb$c?XK~6JZ<$EZ zjg)X7(!)jbMK4rBeq=Yx3FYXrB+nF3H_Y7;9xgvg=ZTy)UQI%qNJ3T@MWeMGe-N$%sB8)Rv)G2L`D@^b zDO?rCiqWC@U=+@7T0$)jHid3C8*JpyWy2f$szc1VEXYH)wu=*jq%!j(^3QI9L$LrS zWC-b7@wTR3k6mguP`s;vh$R3P^byf+dE?@DYN)}m1M(Pk@&1WS8GPJtQl(`ehEU?e zzgnSoQ-JX#O&V8(T_!8$SXR0_@d9?X*oc=m!%m*hj6C!NN)wA6U2UW%pA ztU6?gv^aDQy%4w{*M`i@i7~8MtDw+PSLOC;hNH=ygBK0io?!?biaqL(9*2#rZe*cg zsA2}zu5jX>sgl4y);b?@YnC2%qOKdW3(FHRonSNcP!u_^3g;g4ObLu*sXfM1*+P@H zq)~7)v{n>=`7nQ?6tO|1zRo{#!=j+nj7Quy6sRp@#^zf!jagw zjL@HYhs3&%jWxZkk`tm;M+A}~-?_B}^4=Ws_zMqt_r%COSe^=H@HzT_I;k{BZwOM{ zE_-&G{r0>?nMq{99nEI{<0;86AMD|msY|)@TSKx3RZ!+CIwK52w^;?aT4f%AS3hXu z_R%x)_vWo7cbOaAM42wQn;X}vJcwEd$W>NEsz=epoDg_P>ecAs(l){)n?&9u$SK)_ z;!redb9w%|q1Si?V=gszEe$?oXX?p{GrJIWkLPTNu^FK&R+%SGNBP;=GGlv^iy{K% zM{(KKha*74izs9yx92bWjpWbK9#*{oEk~DVH9R zfJoK}$~_wo2{4RGWF$US=6{nSduS9H4@9D2`TZEKTfHooppt8rd`UK`l!&`@r&4z= z5J7tFTvt@_04-2=s6hUeq7X$HyOHhfTw=UyI~;)D%R_Zg*(6}O3-dpD*(`306JpNE$h%yf_y zK;1`q`}_j6XG$eX?wJ?lWrvAB$VvV`JHsTRdjhIr_FmA-wanJj%>mgjX>krRA8^s$ zSBA)YI~>NX$E8l;eiFcL-wz;kHNrH+i$~=5K!CECOQ;r`*^89AxN64Rzue=v3F>z& z5q#1q=mOjH^+{MLQ4#Q!|AK?&n3*u|ea0dlp<~~#R_;Fvm-kRs|ePKnoMmI`h zOqv-E5}99G0=+tn5BK=f)Z0iwSl{e4CdEFfGgnL^?8>}-+ zSs#iz0*@ULM47M}{VaNUq_Eyhf^k_!SObs@SnSwblT_5f@VTS2DM5uA7qzL3e$R~# zF*wDHEO8>utT59)r${}*a(REKB?8B4adKSRr$3-9-uNpj4CpF@qn^kgk1Jx|r4_0T zvf|LlC4wbW!j-Jx2zjOU7}4s!n)L2v->8~$TBI6fX1gpe6C$a79XF>*7ofsLohH*L z92TM%Q!N|i+!*y+VGo1&iI?W9%5b~$S4~=xa*a|VTytAbb7v;~t72rUTr-4)_+@JY z?}BgjNN1NOomguHj_WTLV*^A2)k=A8FabH9#SL~}c#XY!6{Bw?QuAER`sn)!nBNE? zzE2Ayn!G(O%Qsl7R*Bi*O*F!bjLEs}73=q=d1^?r zX>2jD5)^QlQJm^LDZF&ORc#Y1B5TPN)jn3qnGI~+>Sl7>d-{y^gItcL_Net+q*2gQ zLaqHh39?HzN+C+&wgz6{JR>_V zjOGt&e7dN;_e2x1&o~VNx~hEdt;Qm!XF|%WXyqMZ z`xfU=wM67`CAcVBiHPjm9s1Gq5e88XK;;qFI4sZd@%O2?Db60lDB&Q~L2WMR-W|RG z@+sCo5A9-9t#Y@>=IRgK?ae*WB=g<?v$&8%f zvLduS2NT*>%04(Q@!N{A(^Cp3#WG=XTqXIdyYP)?QRGYi&`PQi)C~-GIO>Q zbm;Q(&BAN+f|T}v)i{D7VDbh{$yZmeS$G2z!Vel=kC|rkRy#H(6zmSbu$7pz#~A0- zEOska(Ga+V?yeJHp4woT&1+c024PHsZwlXWK%SpxqbizG<<|D$#DkXKPO0`ZK7TE^{mI0ddH&Gp=vF}CXJFY*~3WYm`>s!l0}C9N8t7kP?!DJL0j z^tDtg{1sD-RiT&t$*`oh>dqWD2_wwVo$CposHvS?XXIK=vxw2f!Rm=JTB@`ln0_dZ zRj2QsUbBg5FAWaE&u_~?qiY=eYdG|BhlfZsQ+l@2wzxGzI0)3Nu4c-tF3qtSN4S#% z(wXba%!2k|&_{%Yh>vUXAxZZbcHLurZxsZ$e=xI`?DL+lS@!rLn*EMDBE zT;TNu{Wr;I{HO`xEw)t^C5CpgN5E&WY0*Zk6o2GsB2Nn|qYG&;82&ItFY&&mYkjWasdK zj^7{p+NhN_7R0iII4Qny5b$tDtk6>f5FM`q>?c6q{>(kCz>jpXKp@B49jE~u*aWoz zh$oQ;vO!_FirR7X_8AQWh*QK1E!8*B1}NX{lCj{DUH^i73IatU^NaJ(A9=|@56+m< zEh+a)fec@0*h?frah2ge!6A9&$Z}{#xH+)*M#}vpe!#zuxJnNQ;ZQk{>o*i|J{K5l z912X);+ddK<#^`%yn!E+u*HHV11=k_0 zS4YNR($7L#U~Bl{=Ra1i$`)(1yWNHpYVod)zIv1KWk$edDNxG>Z8P>9f^A0IN7^r8 z%mdTdtx!8&H-?I&8N+2K$ml&>hhJ@?y9*n$ZXCG5&`!t)`k}@aHKq@l!u9RmNrd6Y z-wR#veLws=E(F452ae2Co(Ii1FG0usR4Ug<9V{Y;|29OeYuEopa})uyXP7+DM;fw= z)sNsbA=>Ff>Kg=sI^czQ(T}_r>Zrd3*)b^cdEEJoix6V79(fW4BRmf$T3ZCe4;}wu z`@n;CGa}%5^^@yJh-=Fd;Z{cO{(KAcg(1JSA4AzXAVbUI3PU7ld4n{@ps0^mid?qJ6CjiFU<4ri%dc3BQKk(|d+tGlO!`6tG ze$_aj@eow~)?}}{4AqBKPkh&C&WSB5u$E%#(~Q;;S5dO=O-YS3-^{EirzdS;Z+mL9 zlQIB@2vA3bsUj`-DwYK*eRLP5NZh7-_T>G@V*4j?S6eE7EhS|}*!c`*MqF|rb_@2H z)XdCrM(T6w3ZT3B-c+VyB$8;RF zSBD3a!@Rb*Pr>8a*#q?iL%g6V^pB6XaY~{AevC2qaZ(3*-LHRjtYP=1GJ`#4P^b-& z(*l{-jFROj!*JzyjOxj6M?6#93>fjH3`DpO zcX02%gz$YRfe~$kcbPD9B>`o({wikm#acfG`Q;5kFT_jYLbrppeoHYoWj?0|2E+7-U^ zbzt!UwKo{A(B6q78ulozu--S3Z4BCKP)w~2P?3JYXjLdP5TpKK`;k+=8U?;G3@T(7 zd0M6nd9eaJBINXYX7%6cX}tO*)Q9kgC?EAt5Ud_bLQJH{h)AsZXptTbS;%JvAjmaZ zGKH_s&b-bXF%3bN2%j)pJc?k$Wzi5NV#u6(;)~*q0riqm5TeY^H)wn@R2{_boBOF_ z@tdD=1Q`f_1B!FFhdtaCKPmgdrD%9q`V}rw}{A>%YQRRj>q$3@%6rW6RoEOWP5Pf@rO6ffE0M zGQW@}pEB6GW-o#u&Omtdv{^rwu(avJT)odKdndA8Sgd^RS>iBHb2V}z6#f8Ic3);l zd{HKnzMB|_oT?iNg2@Bi1mkn4;(m{JrgAznxW2GB1s36Xw&NM>LFL9LvrT!?Q{{KI?|&I&aA?g2 zAb3s`r3zu#2D<eK!| z$X%4tFB{kMiH}znhSQOwtxqUNv|LUS!FL24`nj?RJy)MXHMyxsXi>VpW+3i z`69VJw#TBGn_9{DMQHm7-oxfVaPJnC4(uKqWEmU)<2fFggS79G81$_tW!hwO{?1ZQ zFeX5t!S+1lY%mO|&uXf%s;@3A)Wz{9>_b&=RUSzr!6;Yrzfv<>>EtUiMA&-Qk%iY& zf%3+)BqER_x-Cc+Ib!4}AT|dX2gTly+6rT_0d+TGQWpYO9ZBqi<7o}2O6sfI{y}Q(1y$$oZOGNc>&+}Zo@*1H6WQ5e$0pFz;r^5 z%HcFHZ&nYqRuA-6|0>(8o&Sh~a%a$)$h0k0<2*oH`0*TKPKj}>#cO_PpQkOZ?>15*rnV<>91g;532`6Qk^1! z9Rj-19(nKd9Gbr;ma>&8b~?3pxEb2(E;4q`G%(<&f02L9e4mASHgk^V6&X&%Z&l)8 zG!hko!4mE(PwZm`02Gs~eOt#D4YF|DR~feyfY_cQ)mqV5L+gcjXj2&*b8^YHe| zuCrp_u+YP!OptLy=Cd-~PXvzH?o-l?J7U+75B}JQmgP(DUUo?wW~Eq+Be-8<_I6bq zxxoX=EjU~BR0j8%B^XLu2KBRR#|!VyjjGvj`gVE8%b2J;XIsX0FrME?|M|v}INo)D z@E@T{4+aE8{{PVxpgHS!BgRB|Be6>iZ)ws- zX&sa<2rUU$3|hkc7bA1YuCaB`+{G&(tB(s1$vtB|ERG{ug);DU`VjQJTa}RD^MHv9 zCJ<4}X!g0fzIg5Ece$F4@ArEr2*jtww}aQ(Z#Hc>lV~&0a{08TsF3()eK1nsKOW*Qa!fwNkjT!gvwaTZi>1!&7F8X);>L07Ftcwiftl_=#0*~7l4m* z$)e?YMv*LgQ$v~zJ?eRd0gSpN1E8h~R?U&?wB%>g)*kvio~TFX-q%G?#3b&xI|dWY zR%7ka_$8Ui$pA1CQLw{`XW%}=ZMaL1H9iP}Wt&;BUT&|+o+Gf?tm%1Wqbi5RH|T4H-`oTtQvCB` za+(x^CP4Z*W=qo!jB+~K7caEo_ZvHi61f;^VkwZ=xEh+9;K*oLTdD@)9cwxFK%kFZV#g<1p$f$HzdI@B;m&hu(g z-6jowVdc_+#$GdC*VQf<>!xFI_;u;;Rfwe0&K**kq#deF@=E5@yk1(qaKIY0wR|UT zZX*>*^cWwyzgVab1&gk&7s!2-s5-yyxd|Wk*168PlR@JdkIkRlauZcJ>RLjnE?R6J ztkTPx+0DPqm-s2h6{)BA?TCJ_&nb&STJX4qWOsGvHv0gM*ecMXLmkXS`X4A>8Djfb zfEEjh!~zng?;VLaUikF<5A_llzCgzs7F`~1Rvb^2Vd7mlf(JP1;hLX1OIwmWi4>;6 zE%AvZ0R@aMz(1AxwFcLm0un%*7K^vn^wT$bch8VKNN$jFr?5OYpP!y+$-iojm@u~A zndG!}YV;@=P;6LBtQynC=^r%d3M83R%cg*T{16;2F-FHGh9=u`UttyE|7J2SJi~D9 z4>DEi?H~LY26ufvM;eGFcsS)fjltSNY#Hfr3fh5`3YVNqHua8`@DwU!WM?>WySBd% zk@aXQQcpPqO{&yzFDM@)0;sj#i}u{B>b?_?IYCl%y$FtUW`qst#|AVs$gTa`+NEUE z+nV%E4sp~S+C`ZfhP>brV~$0}iZ$VClD?C_)SnuSqfJV+$@n@W#vVeN*u{+Ej?0N- zK50bvITYT9Y&*59-^hQMd#3M!huW0%OYr;Tiv#Kw5wrK=7QcA^^CWU8th{ym2U$=5 z$8MJU|C~h1M)nqF|0gZ4R>Q^xe-wkiw_Zysq?cX`XA@h5Y3^!j5gQD4lIMp`Ta6oe zwq{%m0u1hDTg%~Y?&i#cq`Lke2*^9(9x!sE%A$%Xtg3_}MGSuswbvn}A@1GoG*c-q zd5Ws6t8Neb{l4d&<#vgDzuU=j5cz|8OjIz8{-X-R$#~uVy@!u5?}fM=$*?86bufc4 zq3Oz2zB9U$mi~iR<#4vHKdV?JQIHA3Tf$@EVKoCr2DIgJ+1jUbbP@e&!3}3C|B8Ia zg59ZZ&culswh3D4571?j+qIZ6=sfBuI5E}V7UMzT+G4vKBn;=(JQm%w>-rC5JF7?% zY`fP_do^p*sy-(G_HbT!&j)m13Oij2jD=wvF4mm85_6HNeJ2XLlw zK7HkR=-7pa){pKe4&mNaY|9Zs7tN0Ku_PB*T=#+lzAs?ODZ34>S%kx=YQ2MgxY3{5 zUHfAsd;^YTl_?xPhD!%%boECw07pEbi`fe{k~Mf9?`B;LK|#$sw)&L?Z52c;`7LcO?q>9ICpvyU%tVEbl;HUZH(e<53P z&n@8Od+A-j_1`7--f=HxdCeIPe~&L7C=Z{xJ{t=Cl;YZa#Gw#Foarvptu!X?2_$bQ zrF?03TNhgNw`-FOE4(3n#q#8y6s7Y|`}xTmH>?d0n5&HN2F^uyD94tAnvHraP~bN-@x!@~JVNx2^=BD1;h zV5JU8b1AB^1%zg|5<%e3E@u-AzvF)Q;`FS=WAxYq5OyK<$*nj6w;!VgG(OaBc!ylP zcE~IT9&LFkc}5=VFvCTsH>SvJhw?|$k}WQP(WAJXQQ!5n*5T2NZEHCnX;iiD^LG|} zn@%NisoEfhi-w!Hfng8yj<9F@r!q$Nqs%khLu>`DI1edUFTcOaQ-9wVXL<-`XWrvn zvgY}JZ}_7VCt?30Vz-!vy5h~4t|il&Kv#bJTPd8i%=1Am2i{Q1W+#MC5wRY|-?|Avwfvh<|7zhF=f7eZ(J1?4nCY{3F0P97?P)$Y z7hE(iHwkE$r$h3Y#7n*+9rWZ;d!~5$czffP|3#}?W-o6r+aox3`WgUFT(ytge7%G# zbzec1KU{^{e0aJ>Rr*e(4$@!L;=#}s45$WRu@vIVxaVTbx%3HJ!|&&74<+aw$Fc~p zsWm%m{MVQ?BrVL@xjwA+f0(oJ)~trf&Sf!}GB7;M9^={ESZaAAr9FaXwuC=*H?WY) zc(*ukeVbeg>P(cFL&5rW^2eq-U{#jqK@th&&+?O*9 z(V}}{_cuY+A9V1U(H@NEH?KXQ(51@2`Iuv3l5^B&gP(DXz=8*7_)5QFd)`nm52GKL zPI-eL4^QX`>MBeM%R+{cqe}Xu;ZW)^ZU{(?GdjQbnbVpJ0Nz9On9(L2C}DWwJp<=G zu>uAc`u_`-agC_tx%Xc;!9Lu7vqkCu@CN>GrTrh~z*2P`S$s9@FGQbAv&`OK-KE>r z>e@ltZTeBL4AL|UwQ#BhirS3utl+$6?&i6f40gWEjaI+rf!s#w^QEb9b4uG*np_-uv9|kM{e|Z*B|!m*=r|kT)liILJ`)P%}|v z49R?zIXZ5YMoecDmlM}jwBLjr^uvGApj$m;N0HGaJMxO@C|29}#yNCOsecy3H2t!X z(prJCl~L=l8m2?-%ro|?8|Zr)B3MVuGtq?WC3ubkN|I8LFcjl3fL*3t9Z83mR>!ei zAK~w|(#2JEci!UCZor#uqzxQ4rBw>aQ1 z$T&qIj$7cmDfq|_jV@3&I_uhgnNBYF+9S5CzaCjmx?{RnE8SN7O+lYuZk75BUf)iP zFGld8xJbUG-h$Y=!ZYnKhUb;;w5+J{(RE2FrJV)~dkcJo(_+jA?N)7LsCquWe`O_j z#pdZmFV*E>9J|FvlsrvJ92N@FpPuo0N;;xVYnvFz(sOq4c)YkA2w4LQIrDd44j+?d zHkmy1rbCQgZ8x9)ikG(v8gbkoJzjl||9IXm@Oz9ou%tw%xI@W2a*$9oycq zopiEe+qP|VUd}!DR=soHuY2CAwbsv3wN}-fW6Uu=xNkv^en9RLe-Y-E@s<*3nGY?C z*-QBnN3*1*qlibcR0u%COTk7pmVbiCLZI_%Q|;;P#f16=-d{+DYyLj-cGUudI5)rS zH3Q|F9ZdYL)H~yBa(>fpwTnJsOE+3)HpdbkrsD!AY7ykicjGMs0qo8I7ZgC{@~KGC^8uy>e65<`@a!? zt%tA2*1Q~=+TYP`((o4a9mJmAK*@Qq2tq%h8)F)FUxTeI+sOjN2>nqkK7c*Mv5RF2 z#7%Z_B{H63Pm#@sgTHF$tTPu8sj>CVY)CK%j0q@Z(C9zC>OIXjtRz9a4os&_)s>rC zqLHU7NZLLQ58X918bO2>|4J^KF>Sr;R1Ee=+j4jI2kN^+Uspsve7%>7wVYY<(hh@n zPHe?_9JJfne$iG}IOlR!k!B=Tq$m89Z*~_w`{S5{z48jQeFU;1-PYP|XA}2n5QuPj z00HyAEx7&M7FxshHr4k)Fn1F*2r{uK2hUjDMR&5{6#+8DxidePgO8q*D&RbFzVLA4 zLK`-N8}pAx`&i|7P!a1f`}Vslr9Rdj(LBUsqB8f=MI!&K(gPG+x`aw{p+QO7cjH|wM8D9lr4QOmH_hW&%kE4!j zZSkS$y@A#YBD(dwFmCHb?iRJ|&0G#1dk6Ev$L)+`Xq6uHBmD=d{VwrB{LXy)(jzjs zNwH_L&mn%H$}OGLuRDEBs@!+vT+BO$gUmZ4NoBpDJt$ViJC=q3+$&TSLp{7^D`B3% zBkt4WmM3Rf3`--4+(FpfamcW<*g?#qh-AAG?-ZNwKacWAH!$rKiGxP%9w(=t4aqo8BYDIVFCD@ zr(TgV`}3zwli;e()}p5G+N<@2;fG+)ln~xj_C_ah31;_s7SB_b_tZ!B7SGe<9+QC| z%unzfCSg?2sQCr~(4HM}i1pz#W}(A{jYnz2x+K^>H6O zNbJOJxDl#gr14Y?e?o4NJ$Q$iy8RGFb^#Z!k3n)?m;+cL;m^LKl`%sc)i};3Ycr|r z?aCskJ&r6iis2Y5PHoX@4|Gsj8m3;&ohxvgMeD0Agnb&>UaQ8-g&nIb_3!91LO@DH@<9O$BpvRed`vdjlB)6vYRsHs zpK>C2u~rNR+@h1(9&PCHXDsDTH>S#@QhRB6Re3{xMOUIx6nqNFxZvC=b~%8?I>HZb zbT*i9gW)yUEFx(PV|02!t7aQ7)&`KR_pkT`z2GBIs)3v!y+8SJlZ=#xBz*jP03%e$ zrSWtDB8(7Fi4MInfSOfctAR(Ud8`&z88VZnc^ebqKy{|Hc3v%#1S1DmeLpYw-76NK ze6u^Wd9dpuTjfC}RV!R!N0~?}t4vU^(dpwhK$uA#!h!K*#jE`F)v2GP8x+SSre!=s<7KQlppdS!zT3SA?!4_EL->xz z#cC#rGl~G1mE=bo8e@{G3hv#q#0Ch_4=}G(3R^Y{iio*v$npWX_M3tI=B<7JjzD9& z!D%=Gmz>2R|K*K`v$Nk(&di2@DB3!?BpgQC(hNa%&Jtr~ji-d6$0Kfpa)u}fHB!Pp zKHu4ky`hw}xmF!cx*(~_UW%7Ty~dunI$C40G3{_geYhT8v6s1R)kCV;TYHG$sRh1v-)mmoGAk_mh z$=isAGBMZ3Z?IMdYYcuP&oE^+%-!mH^(61vdGIyK4yhpOY7**fVB6c<$GTu&t;0%X zq7z&taT@TIpNfROF~+*@2_XFA|5pEf!ijQXamfTth3CYM;3}DgPMeJ`DBhGC1mN4G zI_po8yj*Q_Ua@T-vcwep3xF0J{u^=PEx&4;nUT*B47$r1PW(do?UBI=j^41WOMB+H zi^B>pntjB2PHmab6$HA80i&dFqa;g+0~64RkDeheOKe-0;D#D;QbMV82jRWy|6vGL zZPO1~Tx*AJ%b|;~RIS?CL!ulZ$;3@LXC+E%)(KlfKA};nlDS#n#5J;1>A(V16>y|U zSY8TjLkx|VxqS`;Q^a-GUO@mPIDf z`2`_zYfk9~My?}tBxb6dl3lt@>@NmNSbSD7tB#KsRK%efAxDwZ4Pp|-vK8b3OwwmkQeAG{=v9U=J_zEm2qI)8 z&T9V%5@D>I0*&?Wr6>8!Q;gzmwt(jF)K2;n_a$n)nPH0#IcHGJDHiSDr(H7EhBc;a zq{bCmhjbb!HMKd>U*%`Bx3|nPkj!K!n&GJIO3uIe@eOTMbo51Sy_JLi3)nmIVEs)+ z=kwe^?B6>Fm$UOs_fJA|5LRdchaFn1abV-eMD=62^eH%moVNMx8hRo&9rr=difqzs zNLTj&JG9fv^0;oVUabC5{q6zcVQSVE7prrl^1=fIMd2+uzIz*7V|xECj-(> zvDX>F=8%iR>oBG+{dT+5h7Pmz9i!lg!i%mC#+OUPk176;RXT2lukgr@L)Z;ACyKhN zEie)sTlwWj%Dmp+1iCU_N1}?*x=W*ArUG*a{HR)gW7D%NGFRu=b#A+T{^ljU!3yCS z4y+wNu4%e^T}a}OltK&w*<)D;Ca_lAWNz`ySG<^OpW|mD=I)bNHXr!6VNsd5Kl^}Uhdn+<1>|UkZRHJf08*97aAoABHn!^GUFZDTqPSmzf~MBoTRqMB7224?OHm~CNAf3ejm6D+>$&Vg z^7Lrr75ymq0|~`+;w4X5@xDTPlFyfXQYl#GTzO9W?4KzPdf53~@Bx6gVz!|IhKj^5 zOjHH+wNdM^c>F<@7no$Ilv0JzcdD^aK$IGUL-J?XP3$VB8POE8!eNYJ$a_GQfNNF> zZ&#r07BM$_G;+)~W2jw}20dOc6|TNPv&@MzEB=!$U5%^Vm}v3K5p(zUf+`8od7<{z znt$NiRE(gTh|!URr~CzQVJwnq*Du{JF7v`p3||S6en^Gg7FKB#^e*u4JxghG#kcEY6xnD+ZuSXEb+dE=a;diCh2)AGk-*-$Q{gP z6n$r(qT!FdDvUO_9zrkL>j4qpxDQ7OfP}8;|AkmUF&Q?G~kFz9wL2XoNGtRwX!=vh1@)t0&(&sTa2A@_QB2vY0QFvW)s@3O6PhY$oMV zMm?2HNbT?=YNgW**cz;kF(2^2f+0bN*YtdNQL6$BJ4sfQVAMg?d(_dS&nXh<%5Q3Y zw;3fM6Wx>brF6HJ-***FkaFD+J%JxPQ40s33K6V7giwR&T|K+e>bDQdRa*lBMV)jp)5IC&tD!oG zE8H0|^4}wA1xCPFt2Bi)_I+NgEW{P#C@K{5dG-rtH@y6`_+uEJ#0NHL1xTfsJ&y5d z0GKrl=D@c~5bHnl!ltp@WWio?z zV5@kaR0$sg*1fkwETU1~pA6^}wnR#ifJ%#zWZHrlfPXHBJ%GZU$~U88)8sL&h;AbP8pWAR;}L&b4xQxw#m4AH!?k zXR)%5rYJ9wiAy$*KyMIq#3LlAST?Tyoy{qP0HQ_ zy)!=~`^P(I&2>FsBLNN_U&TBFU1b->2f&Txf}!2DnLi|#w5veqzC)+ithF^Z_tMB# zXs&eSw$);qAWiv$$WNe~mdNkx-yH0K&_6dE`3U@qlJw&QcrR7cXMUAsm!#c(C-fcw zjAomb>rufF+ao)Pwi~)k%Pv1|mIN9fzH|SbfP&}gARb(S>bZjLV;WD|Q4k^`ArL^J zr|)8BBSdL+3V4GW+hgahLPHil_7L&PaFAKCBq(aQ-P7&tPlB6YHOF;ZjVt9zBgfF8 zV0`yT>DrKazTu}*tmqOLF3DzSI_co;4#Ujxjp7fFeJ6jk94qkkY`Vngu)%9SMYHl@RE}tB3RYDfHQlt;% zq1N;vdM~~0q6|xA8^m%`R%t~+mFGvz)A(&kx9!m!~?syLGGxx z>{n|19Ih2#=am(i#&$*&HqTGd=h9gJoh`X7PWKgC&r6lC86#(~I@a>qbR;{M+>FXv z5kn@uPsyRRXQsQ^K?8B_Hmw~|dIwuu%VCy(NIPYI_G5hdCm-Wtls~_uTZSuCXHzl=P^57;+Vp+qP()~bKq>ZgEl)0_nx)NYn3pop)MC!; z85MK1ZW^Pgn3vPII(QV!OaH>5rCnAnI)P;$zIzQo8m{jW{lpp;St4JlZ z$MHwjHRfhCQ3`K@gXdMU72<=SV-nH4u~YxS@$ZzHWuZG^$)@Y+&zaj;up7Nuh3pd# z{nZ#eJUuI&)22DwID(RB>OJLDHSbqkCyKe`Ljh2E+Eg{A?L_0TWBx31PCSF7?1(AL zB917uoj#FUrS|pQLfxDP5w0Zn%4WLoMsYSonsjz-vod>Mi{HqN$5NU|#HGVksj13? zP38M?W*5$AWKR}9p;BToG^?0fhP3uWS;6vSWqMmrtbXruBEczKm#D(CTN=sZ?5m8w z1~n&jb>!(JZ!7KUEwcW#cvYr53?Zbzf~7GFPGSp_3!zr~-Dpq3a#es4+Y|9ddIyO zT(i#fM|8i%PEromF`_%Lsb*%O59eKDuh|wAu)0zCN-wNQ_nt&M+0uKp@DVHUFmUc! zb0#pJCNMTgmLXY6q@~3t>>aWMooBuj6LeNIT;eFAEF$F=gR;JO7kVHci8=gexz%yP zxcWVZ1E+)MGdQe#G78=A_A9(lZh~Qs22h&=LMf?fCL^^uoEp9FMzsb6Sp@+&R~oR+ zVRh|>Pi}%8V7eA`4MbgHc6vguM~qS1wxL6W%22%fgTQ3T^@mZbroSUc~nj zBM0vy2c1`D*V|x9BMLNaOMgbyi;JpJ{PsiT(-nz}8RK)#^c|Jr%ycWolzuxg+H^0^ zP<6Tf>G#UJq|v}M9QmD=ny)>nn`GnyknOc_oXP5?QtF#jmDl09YnARHQQGC=4yn(z zDmgXQ-{R`^TeA3GAJ(2+ZKOp)DP zu=yb((KCO-*gmP)b9olF?^Bcv`NCk48z4zX|Mx0VQ1Kw{4oZ$CSqLUs=(I7jTTi$X z*B+;y2yt!Y;~x7m_*8^S!A!yM%EX|(L&Lb;AAWl41TkiF9<{*#8ml9&&C860F=ULmC2$*~xY5%3#QC&&vB~6i1%MRF zA$tkJ8PL5(zOiKK{LvkEDLx`f%~$FsG}?gUn@gWJ_HwFP6LfFXeTwuoIA+<6{}kHJ z%V(iJU~zP{bClD^+6zQ)NJ|<3aP<*qwc!`{wu5t{9uH)FXesHoAU`yLr3_fT)dnuj zUk*gBXZTu{sqYQaPcDZ&Oy-FrPC7wZ+-=_`%o^Bkgk4xi`Xh?a)Ax_l^FHRw22(4G zL|Z)meFYA3vtLukz_!9k(&Z2GMbBa0EB_RT@DS6yy;JdMc}A+AC(5P#?NcQfPIzre zt%`mss4d*8N->E6zRUWOwtLzZU!HW`m4zAq&HSNnRkdi3c3@Hsntn=w$2YoK&DmY9`wRXt*9{7%yEQ=Ke3$KoNtS~j{mMV@`crp()GNt`}^HTn|Xahjmq)OvF15!w|9VZbf7t` zPTt&Bdwq)T>ATMaus8@L)YOIcq!x`RINUvyhYVX@gBV=XkNyIQnT_yS3;yXE;Lnb{ zb)>?^O&$=zo$}fI3$41}ls|^X165TT#I6&5G9R$_su%r~7b~AT$Z!vM4L&ob>T^c% z{%bS3eYYp`PxAff2l7JJB3CJZ^LqH`Z>Qo*vWZ+dqTr#KS&k~H+m_$AIJU%CCmw5i zhR24}K&_nJ+x_@BamLjR#`UaKJtYAe;fEwyW2Sb~OWbtt%WvIP1-z1_MZYI+AYBf* zU6T4McI?bY$SsqC74{wV)Oq(*EGlQHUWgBReLhMky7}uXT++KU$@F0CoLR$Kow2q6 ztYO?%_KwY#!-V%!xTIQGTmCRik)rb!H|PN?aj9C#J?8^8D|`Q@E&eIf$|?S3o!{mk zr$=$s4JfmHw&xPs7gJ9UI97GZ9($qpq@kp4>ljvQg47bI&JP!qmv%RU|0J(b1~gZz z!XNQ5-K7T~d%Z?`DY}5CLd1Es$LGq-&&l6w(?B@^cTlbwfBydLb5_lcd`&V<-p*}! zmes$GF?bibh z4TrZq6?m#=NQW<)xcoUdouubR9h@^dJ%@2`kYT_VYL4;kAYtCPS1X}7gQ3Y4ftBv6 z>CD^8O%{nveoENF$`5IyKzJHA8hAPo7X{FTYbd@qZ@UuVw9-(8qJ>=U;Q6_IwLfXZMLWF z8d3~{7g-8y^D$b__OXtNhOYWz?h`C4Kx*;~*!U0Vm9CD7uD(FXXBFr!H1G!IL^xPx zs}rySbF(F$1|Ecd*pxP;zDwR2{jxtWq80=Bg%CA0Mh!bQ_QH`pMx6H^t($KkDD`Lu zWQ4tFpeF5Syg{|V<`zzYuCzhAe=^%1XiZun`Q7154P#^Ud~Oo)4c}cV&<)@3A*s5b zPoikMu{=F;IA(a;W5BLikeOyK-iykMZm1;)O=lIly<>(8<0V;#Y-p{#A`Ozb znYb%DV=R`OBA%HP_H5v%>|C%dL*Ug=0a)zR#}7UN!>8~V!XrYFPJJrnHbGHm(@Ko9 zEn0L$FOl1n<=pJaVU$4XOb%)N1{XimtW>*l(h6>01|}&(^t%%qV?kf}B0eo`q6e3t z%x+4c*kKjSFxCP^SFjPpsHSFSarS_jqk{0$kt$_?S9{PU1WQiGE$%B0WbW9s+HVuD z5Xt797lRCp=2^XRYI3fw-+ERCWh$?<8->Fge1Ec9($?82TP&EJT$EYbtV9#;hFOB5 zDEAk0RcL+>P*_?E!#d4e@4nsfpF67SQFxZ0QCe!?wMs~00_em`&&!&HF2JpMIcxg+0 zp-S>AuI^E8sF}VxQM7)yaP^J(H?``@Y(1-@yLk^>xvFJ@&RtE)MSY&PMj8Hea%QrVe(_OwKM&W=3`< z4)!ii4z^4t4t9=4E==Ix{_CLiKLY%pK+OL)flR)FyO{ld;+ZHvvaoysR_F1*eG~Z~ z#1s8rVMQ&?Ol+M0b8_3H1?xkgj{Dg&VQ%5hW*5t8)pC@QQZJoouj@r=C*3YBV;P$v zuZlO%x{^&kH$GX()*v0Esjh?}#{Wk}x$Z|<-fW~5wNSp$zEUT$5-L+CCQ~O0{DZfH zyEBJ;!*wEYw(s3x$EN#x&(%Rhs-hrFUaZ{>D1;x@9{1&%8G}#>Dyg;_r)#JA65M*+ z=-PGxVPa+S4>s*p(zaQekc67W8t}lfWagK4$w3%|P^#KrB|PgK`id_!m$8;*nF4n{ zuJyQzSC->=CtHKgw*90@)?55Jv%=}7iPjOXYRko2U z+mR!|LVeO^ZSkXZvk9Oisqn;T!Lc&Gu^y_s^2P)eOIC~2geDLnxs90(;}NLPwOUx@ zLUoEl2zqUZ<+9ZA;;*a#2NGQ#b{b_SmK?w^^4>veF&c$L!`CI`8<~S8q@?eYs9gZ+ z-Qw(3F!0Vu<*WE`Pc1BGxg#Dj!~v!E!!QJ-WTMomN+c$jw76LEsQt>6P)j)*2(l%S z_tdB_ejI&hi^Ez`t_U_x5BNb#8rcfsiZd#R2Y$md4KcFM;ptMeDYI1-90wLl0mNr@ z!hI6BnYHOg2V%);%HY7{8C*=J37>3EHJnM5Y}@1h_bCDIFIAmZ?FClr+GN@SuEIzs zHRsUDitG0mAe`_HK*WX|rBbW}IFV+>-H&of6%dQn0D_%ksd5bVUx1p&`p2n|K)j|z zR~RdrmJ3QQIbKx0hJWhK~j zaQb*|(f_GP;T(pRNKwPuA;h#1)riMD(1c>C-b+Q^|BPEkq|5eb2uU}0-?dE* zAvto2PT^2U?>-mQVvM7m#Nd`yFBr&DJe&+F=lP`R^@IeLZy8{R6iI#@#&|3PD-}Gx zjiiZ)LpkL1Af6Crq0p~hBG;$~`sR4;L-KdAB1KG9F~4XgoKX>dRm-b;RH-iYL6T1S zzZLnn=|70%f!0|@4tHwI%O)k!tv_>Iq-M>~FE!qhzE8+$8}Ug6a z@HsXG+jzM9P=Rtjqp%{~q!6sv9IK+;oiTD!WfG)ZEgsV@O32t9GtNx)rmWV3&p$e$ zs`uiaMp{v?N+~5n{s7?Qvts;wP>2&86Qhy$%$?TLOms0y<1CZxGtV689b6=-xmwG} zSOo)h%Q2M>8i7b=ZapZA>R_R9H~TN##7g+3&#?r-4oJ~>{VB+!P>F!mAxgf%A)>NsX3c|J z&%t0WTth`CtVu*F*5p2{V9oiv6fVt$DYMW#BAhdxSa{X-3Iv>T|u9zkZmU8P$q&lb$>Pd%vjUL zdOBX0q!1!wmbdDr&suI{y&iV8Ck?AO^8DRzSTZHu+(Ilk5$LL^Y9lJCYUYU@)7_2@|J0I0M=KtYKmP$qh+=>#QH%-jl4zY~XmEkVdO;;be2H}RyQ z$j9X~F~)CBkyB;zSZ`%t*fGQEUJekc(&{JA(ViLw>RrdjzX%O0uI1FlGuMp zi2OaV<=%fLedxUn#O|ujBKCxTiMI=m8-OnJC@RKyX;KuC^ zL-p^yv#@y-EsODBxet8iNm*67Sc|pmH9U@}bc6KEM!6QA|CDWewqOk2&?9crL7TUr zmD$F9P1HE?IsPti@|4;|B_qf9!(}-7l%G!A0GI>NwanS3$so5hjfvAwNSFA`fH{7+ zX8;U3iH9{=*bDFpOiu1! zaG({!_s-tw5e);&7Hz0wTU+#A;2Nw#v2L>NB(3J7%46_^v~HeRwI+CAbjxQ6|CLso zMxEZL1J=eEjbScX=7S&x*dd_UdXIiu7sV+Pni^;*m)SYbIYF_Bldn1j))*?p!V0PGxxLC+&S zhp3JR-r|_16gE6I0!t>f2H}noZ7^igz!BmW{Lf<*@Aoayq2L4-nud_1dUguuI)0-; z+e7mg^4UaAD=Z&5V*^ss-pjQJbxK_Yfp4CMEFE>nKLiwhxyc?dN9xi6V+&ny;NwhI z0DA1vKvk^^+`$2FI$&ts0Y) zb+WbpUq#bExAE{AXSnJv%Pep>8F+j^Cq*O3)~dK zUMW|M-@lM&J*8V&(w7C({5Xqpzf=weCigLkFK|Mznp#5e5%o*|6fmKuUGn<<dS-}`~!d`OQVFFUN9I|sy%_1DJ@7OWB#J}oBXoEoc6vNla1 zj-nb;>vT0R&qgSvt$GNuny+^K0YxKxmN!~NFGzkoOy>ETT>7>FtR3xYqSEKQd>r^U zdA!=gl_mWY$(SP(Q>6~8?b1xVG7VTe@5)7&uTI3-QEleDtj8;vS`n69&l(t*d=8U2 zbeI?`;f4uc3;Ac6L}LtVHYaWabXYImc-t_b{fvT_VmkVvOwSV}{7hb%dL0O%{oW%l zqGl}1Gn_?&{W5iqW0G+sTNxqtIVvlPNT0*=MfF-;HGM> z4DG5Eb^JZ$<|4Vt7Qmp}yCwVLt<7LE)_SxIIczdEU=7)!l$RZ){wIWPfUSRV+5nd4 z-l{o8Uv5%+inD$K=Ka6%dB1n%+D&|^oKJtT43z%o2a^BPIajqbGIvoivo|$!GIRRh z#}f^CXMAxK-@@TlDQ$GR?H`%fsJp*SskB9&qoaFM&c!13Tj^ymhGwkkqjI!Z1Ir@5 z=}!Xyi4%12{hb+2L0zIxofY9Qg?KD2z<0vY?9Z?=$O(yQr!#~G-&5~bE4D{095Eyd zGB1XA3;JsvIvv`;Qi52%B=tWeO~qhfTE4MJmd)ev1e-La@yF!#0;+f{i3(n=Cx(Q< z&`p2!HQGRUsGB8*%_$AQA94L~#@&aap{@yffM+Y!{ap#^qWrS6u z-DbEmM8p(kwQQ@D?v?(4e26fEl{@sXjt7RNT&}EaWpB#AwyqgWAG7 zSsh-+o0WoFrncM7M4C9+Vyic}hR^`JXf9=}OpA=o1Tq|Wl|Jp}_i7G>s6!nLj9$Mm zk^qlilwp8(MsSy?S`Kyml8R@1qWuUbSCJOeX>+&jj3O0fRIVOrp|%lHDH+@==zKKB z`*Hv~z_aT8QyolL;N7jjxAf+h85!0hpwp&=93dSgsnSDCU!tzq67f1*C-C_<6_=jt zL>mEla2*0y#jZdfUzaib94RhopNM0O1I;uH?XTlQh>BR|8YMXS&P4p3_{UJ<22pvx zbub26=g8K3+@g^V^^-|5NWex zSU$_5s#URC7GB1@cktCnp_ce)&FM$TQuMQIi8JJJ-qE>J z3R}qHZKglJbU@AZ1|xClw2A>K_gZ8Rm%@etSB1(GDzS80L+3sJwKvig+(1q9wRPOV z{Qv4@{I9L!KR1gi4P9q+E{uOkYiJg8!9S@3D2sc46Ec#9K&{G)qAy{9D47A2Z2Y4( z1KRZ|{5m`&H6M`gm>!m;{4THSCl1Ek9h_|^60NbMhDBSV1p zAwZ3VhqR$ZDP`owdI?GX>4(r-{vX-NoqrT4%*-ZW@U6w42a=m+S7k$`h4jC;O5qOd z>VMKa+g2>a^4T|0y8FU|l(8*X1|44@3}u=qY3}aYI{jUQa)Ryi-0m@ z^68@CCi5i>t3QZIcf$~;LUp%9RFV$kSjE)t_aNg~~*i1*;t-xNm<z=g;xnUk<8w>@ncwtU(p* z?F`VSfS5yJy`dPlYqI;2=9_eP$A5jyAR+E2qP@SwY20v}F5hekc=oL>L2{?A=q)M{ zGt&EZH9TNFQCBCQY*r;BUa;`bA!x1g-rD3=usyphBR%=S7HQ8g|8*fIZ(Lmb`C`Ju zV1D~1`9IF#()KQ97EVV0A<6N7I*TWo=$aUx0?h&33@o(Ci&a=0%ZsQjz+OmFOLj00 zjHuPwk$nmTIrG^Oh+;PfyQ+<+#Y?v>OkJhQ=3MVru7~?>X|c$FpJGTBo9kRxmt!4V z{-1nakU!D?-RD6Rqm7y-6$bXMl_Hfz=4Zeb3#<-tgyk0~bGcgZiI(?tSHLBgC2YsD zK(huJ<3*Yfa?Am7&z2^{#$`&98%>-!%C$>ObVJbq`M^oMj-&o+(1p0_Z>mb0^Y{ ziEBWU6~Wm_Iuk}8a`(VQJlT&2Bh9wxLVOv16YE&}bQ$tQ8C>2LaH8=cFjx*&dyq&d zgShOFlGTwLPQkxxj;I8hVTk~mfwJ5HZ9TsL+VxmIa{7ci99f(UxDK&~1eyh9_EqOr zG?&yrC)W_^vB5^v?%Dm*O2N#@T9kVV^i;I@lPMqjCshL;y!+RtyxZU*MbLD$Dt%uL zT0)>h<8qcVt~va`u(Rj|*2_Tw1Tzu;&?dH0

    T|jLKpqYpXK^*HE3|X#7ZKGTd4* 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 CEk^kO literal 0 HcmV?d00001 From 93ef0d1dd7776b7131796532dcf88c28fcd5fe53 Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 09:41:03 +0100 Subject: [PATCH 08/14] Verify live client engineering interactions and dispatch Calibrator item actions --- .github/workflows/neoforge-1.21.1.yml | 35 ++++- build.gradle | 9 +- .../streamcontrol/ClientTestWorld.java | 68 ++++++++ .../streamcontrol/ControllerBlock.java | 4 + .../streamcontrol/StreamControl.java | 1 + .../streamcontrol/UtilityBlock.java | 4 + .../client/ClientGameplayChecks.java | 147 ++++++++++++++++++ .../compat/create/CreateClientFixture.java | 22 +++ .../compat/create/MechanicalCurrentBlock.java | 4 + 9 files changed, 288 insertions(+), 6 deletions(-) create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java create mode 100644 src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateClientFixture.java diff --git a/.github/workflows/neoforge-1.21.1.yml b/.github/workflows/neoforge-1.21.1.yml index 83118a2..466e79c 100644 --- a/.github/workflows/neoforge-1.21.1.yml +++ b/.github/workflows/neoforge-1.21.1.yml @@ -52,7 +52,7 @@ jobs: - name: Upload test JAR uses: actions/upload-artifact@v4 with: - name: flow-control-0.2.1-neoforge-1.21.1-${{ matrix.flavor }} + name: flow-control-0.2.2-neoforge-1.21.1-${{ matrix.flavor }} path: build/libs/flow-control-*.jar if-no-files-found: error @@ -73,7 +73,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: flow-control-0.2.1-neoforge-1.21.1-${{ matrix.flavor }}-checks + name: flow-control-0.2.2-neoforge-1.21.1-${{ matrix.flavor }}-checks path: | run/streamcontrol-integration-results.json run/logs/latest.log @@ -95,7 +95,36 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: flow-control-0.2.1-${{ matrix.flavor }}-client-preview + name: flow-control-0.2.2-${{ matrix.flavor }}-client-preview path: | run-client/screenshots/*.png run-client/logs/latest.log + + - name: Exercise real client gameplay against a dedicated server + run: | + rm -f run/client-test-ready + ./gradlew --no-daemon -Dstreamcontrol.clientTestServer=true $CREATE_ARGS runServer > client-test-server.log 2>&1 & + SERVER_PID=$! + trap 'kill "$SERVER_PID" $(jobs -pr) 2>/dev/null || true' EXIT + for attempt in $(seq 1 120); do + if test -s run/client-test-ready; then break; fi + if ! kill -0 "$SERVER_PID" 2>/dev/null; then tail -n 50 client-test-server.log; exit 1; fi + sleep 1 + done + test -s run/client-test-ready + timeout 600 xvfb-run -a ./gradlew --no-daemon -Dstreamcontrol.clientIntegrationTest=true $CREATE_ARGS runClient + python3 - <<'CHECK' + import json + data=json.load(open('run-client/streamcontrol-client-results.json')) + assert data.get('passed') is True, data + CHECK + - name: Upload live client results and screenshots + if: always() + uses: actions/upload-artifact@v4 + with: + name: flow-control-0.2.2-${{ matrix.flavor }}-client-gameplay + path: | + run-client/streamcontrol-client-results.json + run-client/screenshots/gameplay-*.png + run-client/logs/latest.log + client-test-server.log diff --git a/build.gradle b/build.gradle index c962d22..64839aa 100644 --- a/build.gradle +++ b/build.gradle @@ -2,7 +2,7 @@ plugins { id 'java-library' id 'net.neoforged.moddev' version '2.0.148' } -version = '0.2.1' +version = '0.2.2' group = 'nl.townsandkingdoms.streamcontrol' base.archivesName = 'flow-control' java.toolchain.languageVersion = JavaLanguageVersion.of(21) @@ -18,13 +18,16 @@ neoForge { programArgument '--height' programArgument '720' systemProperty 'streamcontrol.uiPreview', System.getProperty('streamcontrol.uiPreview', 'false') + systemProperty 'streamcontrol.clientIntegrationTest', System.getProperty('streamcontrol.clientIntegrationTest', 'false') + jvmArgument '-Xmx2G' } server { server() programArgument '--nogui' - jvmArgument '-Xmx3G' + jvmArgument '-Xmx2G' gameDirectory = file('run') systemProperty 'streamcontrol.integrationTest', System.getProperty('streamcontrol.integrationTest', 'false') + systemProperty 'streamcontrol.clientTestServer', System.getProperty('streamcontrol.clientTestServer', 'false') } } mods { streamcontrol { sourceSet sourceSets.main } } @@ -45,4 +48,4 @@ dependencies { tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8'; options.release = 21 } tasks.named('jar') { from('LICENSE') } -tasks.named("jar") { archiveFileName = "flow-control-0.2.1-neoforge-1.21.1.jar" } +tasks.named("jar") { archiveFileName = "flow-control-0.2.2-neoforge-1.21.1.jar" } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java new file mode 100644 index 0000000..49b0875 --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java @@ -0,0 +1,68 @@ +package nl.townsandkingdoms.streamcontrol; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.GameType; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.server.ServerStartedEvent; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; +import net.neoforged.neoforge.event.RegisterCommandsEvent; +import static net.minecraft.commands.Commands.literal; + +/** Test fixture only; disabled unless explicitly requested by the CI launcher. */ +public final class ClientTestWorld { + public static final BlockPos GENERATOR=new BlockPos(0,100,0), TARGET=new BlockPos(4,100,0), + SENSOR=new BlockPos(-4,100,0), MOORING=new BlockPos(0,100,3), ANCHOR=new BlockPos(0,100,6), + MECHANICAL=new BlockPos(4,100,3); + public static void register() { + if(!Boolean.getBoolean("streamcontrol.clientTestServer")) return; + NeoForge.EVENT_BUS.addListener(ClientTestWorld::prepare); + NeoForge.EVENT_BUS.addListener(ClientTestWorld::login); + NeoForge.EVENT_BUS.addListener(ClientTestWorld::commands); + } + private static void prepare(ServerStartedEvent e) { + var l=e.getServer().overworld();l.setDayTime(6000);l.setWeatherParameters(100000,0,false,false); + for(int x=-8;x<=8;x++) for(int z=-4;z<=9;z++) { + l.setBlock(new BlockPos(x,99,z),Blocks.STONE.defaultBlockState(),3); + l.setBlock(new BlockPos(x,100,z),(z<-1 || Math.abs(x)==8 || z==9?Blocks.STONE:Blocks.WATER).defaultBlockState(),3); + } + l.setBlock(GENERATOR,StreamControl.GENERATOR.get().defaultBlockState(),3); + l.setBlock(TARGET,StreamControl.GENERATOR.get().defaultBlockState(),3); + l.setBlock(SENSOR,StreamControl.SENSOR.get().defaultBlockState(),3); + l.setBlock(MOORING,StreamControl.MOORING.get().defaultBlockState(),3); + l.setBlock(ANCHOR,StreamControl.ANCHOR.get().defaultBlockState(),3); + ((ControllerEntity)l.getBlockEntity(ANCHOR)).configure(FlowHeading.NORTH,3,1,false); + // A separate high pool makes the sensor's independent vertical range observable. + l.setBlock(SENSOR.above(3),Blocks.WATER.defaultBlockState(),3); + for(var d:net.minecraft.core.Direction.Plane.HORIZONTAL) l.setBlock(SENSOR.above(3).relative(d),Blocks.GLASS.defaultBlockState(),3); + l.setBlock(SENSOR.above(2),Blocks.GLASS.defaultBlockState(),3); + ControlData.get(l).put(l,new FlowRegion(9001,SENSOR.above(3),1,0,1,0,2,false,false,new java.util.UUID(0,0),ControlData.get(l).next())); + var boat=new Boat(l,.5,100.1,4.5);l.addFreshEntity(boat); + if(net.neoforged.fml.ModList.get().isLoaded("create")) nl.townsandkingdoms.streamcontrol.compat.create.CreateClientFixture.prepare(l); + try { java.nio.file.Files.writeString(net.neoforged.fml.loading.FMLPaths.GAMEDIR.get().resolve("client-test-ready"),"ready"); } + catch(java.io.IOException ex) { throw new RuntimeException(ex); } + } + private static void login(PlayerEvent.PlayerLoggedInEvent e) { + if(!(e.getEntity() instanceof net.minecraft.server.level.ServerPlayer p)) return; + p.setGameMode(GameType.CREATIVE);p.teleportTo(.5,101,-2.5);p.setYRot(0);p.setXRot(20); + p.getAttribute(Attributes.BLOCK_INTERACTION_RANGE).setBaseValue(8); + p.getAttribute(Attributes.ENTITY_INTERACTION_RANGE).setBaseValue(8); + p.getInventory().setItem(0,new ItemStack(StreamControl.WAND.get())); + p.getInventory().selected=0;p.inventoryMenu.broadcastChanges(); + } + private static void commands(RegisterCommandsEvent e) { + e.getDispatcher().register(literal("flowclient").then(literal("power").executes(c->{ + var l=c.getSource().getLevel();l.setBlock(GENERATOR.below(),Blocks.REDSTONE_BLOCK.defaultBlockState(),3);return 1; + })).then(literal("unpower").executes(c->{ + var l=c.getSource().getLevel();l.setBlock(GENERATOR.below(),Blocks.STONE.defaultBlockState(),3);return 1; + })).then(literal("dock").executes(c->{c.getSource().getPlayerOrException().teleportTo(.5,101,1.5);return 1; + })).then(literal("reverse").executes(c->{ + if(net.neoforged.fml.ModList.get().isLoaded("create")) nl.townsandkingdoms.streamcontrol.compat.create.CreateClientFixture.speed(c.getSource().getLevel(),-128);return 1; + })).then(literal("stop").executes(c->{ + if(net.neoforged.fml.ModList.get().isLoaded("create")) nl.townsandkingdoms.streamcontrol.compat.create.CreateClientFixture.speed(c.getSource().getLevel(),0);return 1; + }))); + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerBlock.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerBlock.java index 6da958a..495bd67 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerBlock.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ControllerBlock.java @@ -41,6 +41,10 @@ public ControllerBlock(boolean still, Properties p) { if (level.getBlockEntity(pos) instanceof ControllerEntity be) be.waterChanged(); } } + @Override protected ItemInteractionResult useItemOn(net.minecraft.world.item.ItemStack stack,BlockState state,Level level,BlockPos pos,Player player,InteractionHand hand,BlockHitResult hit) { + // Let the Calibrator's item handler run before the ordinary configure interaction. + return stack.is(StreamControl.WAND.get()) ? ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION : super.useItemOn(stack,state,level,pos,player,hand,hit); + } @Override protected InteractionResult useWithoutItem(BlockState s, Level level, BlockPos pos, Player p, BlockHitResult hit) { if (!p.mayBuild() || !level.mayInteract(p,pos)) return InteractionResult.FAIL; if (!level.isClientSide && p instanceof ServerPlayer player && level.getBlockEntity(pos) instanceof ControllerEntity be) diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/StreamControl.java b/src/main/java/nl/townsandkingdoms/streamcontrol/StreamControl.java index 9305e47..f7d93f7 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/StreamControl.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/StreamControl.java @@ -46,5 +46,6 @@ public StreamControl(IEventBus bus, ModContainer container) { NeoForge.EVENT_BUS.addListener(ControlNetwork::respawn); NeoForge.EVENT_BUS.addListener(ControlCommands::register); IntegrationChecks.register(); + ClientTestWorld.register(); } } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/UtilityBlock.java b/src/main/java/nl/townsandkingdoms/streamcontrol/UtilityBlock.java index 975155d..0e3fb54 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/UtilityBlock.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/UtilityBlock.java @@ -46,6 +46,10 @@ public UtilityBlock(boolean sensor,Properties p) { if(l.getBlockEntity(p) instanceof MooringEntity mooring && on) mooring.release(); } } + @Override protected ItemInteractionResult useItemOn(net.minecraft.world.item.ItemStack stack,BlockState state,Level level,BlockPos pos,Player player,InteractionHand hand,BlockHitResult hit) { + // Let the Calibrator's item handler run before the ordinary configure interaction. + return stack.is(StreamControl.WAND.get()) ? ItemInteractionResult.SKIP_DEFAULT_BLOCK_INTERACTION : super.useItemOn(stack,state,level,pos,player,hand,hit); + } @Override protected InteractionResult useWithoutItem(BlockState s,Level l,BlockPos p,Player player,BlockHitResult hit) { if(!player.mayBuild() || !l.mayInteract(player,p)) return InteractionResult.FAIL; if(player instanceof ServerPlayer server && l.getBlockEntity(p) instanceof UtilityAccess utility) ControlNetwork.openUtility(server,utility); diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java new file mode 100644 index 0000000..d3a6d67 --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java @@ -0,0 +1,147 @@ +package nl.townsandkingdoms.streamcontrol.client; + +import java.nio.file.Files; +import java.util.*; +import java.util.function.BooleanSupplier; +import com.google.gson.GsonBuilder; +import net.minecraft.client.Minecraft; +import net.minecraft.client.Screenshot; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.AbstractSliderButton; +import net.minecraft.client.gui.screens.TitleScreen; +import net.minecraft.client.gui.screens.ConnectScreen; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.client.multiplayer.resolver.ServerAddress; +import net.minecraft.core.*; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.phys.*; +import net.minecraft.world.entity.vehicle.Boat; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.ClientTickEvent; +import nl.townsandkingdoms.streamcontrol.*; +import static nl.townsandkingdoms.streamcontrol.ClientTestWorld.*; + +/** Real client, dedicated server, real input handlers and packets. Explicit CI opt-in only. */ +@EventBusSubscriber(modid="streamcontrol",value=Dist.CLIENT) +public final class ClientGameplayChecks { + private record Step(String name,Runnable action,BooleanSupplier ready) {} + private static final List steps=new ArrayList<>(); + private static final Map results=new LinkedHashMap<>(); + private static int step=-1,ticks,total;private static boolean connecting,done; + private static Minecraft mc() { return Minecraft.getInstance(); } + private static FlowRegion region(BlockPos p) { return FlowOverrides.clientByKey(p.asLong()); } + private static FlowController controller(BlockPos p) { return (FlowController)mc().level.getBlockEntity(p); } + private static UtilityAccess utility(BlockPos p) { return (UtilityAccess)mc().level.getBlockEntity(p); } + private static void add(String n,Runnable a,BooleanSupplier r) { steps.add(new Step(n,a,r)); } + private static void use(BlockPos p) { + mc().gameMode.useItemOn(mc().player,InteractionHand.MAIN_HAND,new BlockHitResult(Vec3.atCenterOf(p).add(0,.5,0),Direction.UP,p,false)); + } + private static void click(String key) { + var label=Component.translatable(key).getString(); + var b=mc().screen.children().stream().filter(c->c instanceof Button button && button.getMessage().getString().equals(label)).map(c->(Button)c).findFirst().orElseThrow(()->new AssertionError("Missing button "+key)); + mc().screen.mouseClicked(b.getX()+b.getWidth()/2.0,b.getY()+b.getHeight()/2.0,0); + } + private static void at(int x,int y) { mc().screen.mouseClicked((mc().screen.width-316)/2.0+x,(mc().screen.height-238)/2.0+y,0); } + private static void slider(int index,double fraction) { + var sliders=mc().screen.children().stream().filter(c->c instanceof AbstractSliderButton).map(c->(AbstractSliderButton)c).toList(); + var s=sliders.get(index);double x=s.getX()+4+fraction*(s.getWidth()-8),y=s.getY()+8; + mc().screen.mouseClicked(x,y,0);mc().screen.mouseReleased(x,y,0); + } + private static void screenshot(String name) { Screenshot.grab(mc().gameDirectory,"gameplay-"+name+".png",mc().getMainRenderTarget(),m->{}); } + private static void command(String name) { mc().player.connection.sendCommand("flowclient "+name); } + private static void cycle(FlowWand.Mode mode) { + add("calibrator "+mode,()->{mc().player.setXRot(-90);mc().options.keyShift.setDown(true);},()->{ + if(ticks==4) mc().gameMode.useItem(mc().player,InteractionHand.MAIN_HAND); + if(ticks==7) mc().options.keyShift.setDown(false); + return ticks>8 && FlowWand.mode(mc().player.getMainHandItem())==mode; + }); + } + private static void setup() { + add("client world and region login sync",()->{},()->mc().level.getBlockEntity(GENERATOR)!=null && region(GENERATOR)!=null && mc().player.getMainHandItem().is(StreamControl.WAND.get())); + add("open controller through block interaction",()->use(GENERATOR),()->mc().screen instanceof ControllerScreen); + add("GUI direction and radius apply round trip",()->{ + screenshot("controller");click("gui.streamcontrol.short_e");slider(0,4.0/15);click("gui.streamcontrol.apply"); + },()->region(GENERATOR)!=null && region(GENERATOR).dx()==1 && region(GENERATOR).radius()==5); + cycle(FlowWand.Mode.COPY); + add("copy settings with real Calibrator item use",()->use(GENERATOR),()->FlowWand.settings(mc().player.getMainHandItem()).contains("Calibration")); + cycle(FlowWand.Mode.PASTE); + add("paste settings through server and sync",()->use(TARGET),()->region(TARGET)!=null && region(TARGET).radius()==5 && region(TARGET).dx()==1); + cycle(FlowWand.Mode.LINK); + add("select linked source",()->use(GENERATOR),()->FlowWand.settings(mc().player.getMainHandItem()).contains("LinkPos")); + add("link target through server and block entity sync",()->use(TARGET),()->GENERATOR.equals(controller(TARGET).controls().source())); + cycle(FlowWand.Mode.RESTORE);cycle(FlowWand.Mode.INSPECT); + add("open linked target",()->use(TARGET),()->mc().screen instanceof ControllerScreen); + add("unlink using GUI",()->{click("engineering.streamcontrol.automation_tab");click("engineering.streamcontrol.unlink");click("gui.streamcontrol.apply");},()->controller(TARGET).controls().source()==null); + add("open automation",()->use(GENERATOR),()->mc().screen instanceof ControllerScreen); + add("edit redstone and Profile B through GUI",()->{ + click("engineering.streamcontrol.automation_tab");for(int i=0;i<4;i++) at(150,66); + click("engineering.streamcontrol.profile_b");slider(0,3.0/16);screenshot("automation");click("gui.streamcontrol.apply"); + },()->controller(GENERATOR).controls().redstone()==ControllerSettings.Redstone.SWITCH && controller(GENERATOR).controls().b().vertical()==3); + add("redstone switches to reversed Profile B",()->command("power"),()->region(GENERATOR)!=null && region(GENERATOR).dx()==-1 && region(GENERATOR).vertical()==3); + add("unpowered restores Profile A",()->command("unpower"),()->region(GENERATOR)!=null && region(GENERATOR).dx()==1 && region(GENERATOR).vertical()!=3); + add("open sensor through block interaction",()->use(SENSOR),()->mc().screen instanceof UtilityScreen); + add("sensor GUI independent vertical range and live speed output",()->{ + slider(0,0);slider(1,3.0/16);screenshot("sensor");click("gui.streamcontrol.apply"); + },()->((FlowSensorEntity)utility(SENSOR)).radius()==1 && ((FlowSensorEntity)utility(SENSOR)).vertical()==3 && ((FlowSensorEntity)utility(SENSOR)).output()==15); + add("reopen sensor",()->use(SENSOR),()->mc().screen instanceof UtilityScreen); + add("sensor direction comparator and settings sync",()->{at(150,149);click("gui.streamcontrol.apply");},()->((FlowSensorEntity)utility(SENSOR)).mode()==FlowSensorEntity.Mode.DIRECTION && ((FlowSensorEntity)utility(SENSOR)).output()==3); + add("reopen sensor boat mode",()->use(SENSOR),()->mc().screen instanceof UtilityScreen); + add("sensor boat mode and zero vertical range",()->{at(150,149);slider(0,7.0/15);slider(1,0);click("gui.streamcontrol.apply");},()->((FlowSensorEntity)utility(SENSOR)).mode()==FlowSensorEntity.Mode.BOATS && ((FlowSensorEntity)utility(SENSOR)).output()==1); + add("mooring live boat capture sync",()->command("dock"),()->utility(MOORING).settings().getBoolean("Secured")); + add("open mooring",()->use(MOORING),()->mc().screen instanceof UtilityScreen); + add("disable mooring from GUI releases boat",()->{screenshot("mooring");at(150,186);click("gui.streamcontrol.apply");},()->!utility(MOORING).settings().getBoolean("Enabled") && !utility(MOORING).settings().getBoolean("Secured")); + add("reopen mooring",()->use(MOORING),()->mc().screen instanceof UtilityScreen); + add("enable mooring recaptures after cooldown",()->{at(150,186);click("gui.streamcontrol.apply");},()->utility(MOORING).settings().getBoolean("Secured")); + add("real player boarding releases mooring",()->{ + mc().player.getInventory().selected=1; + var boat=mc().level.getEntitiesOfClass(Boat.class,new AABB(MOORING).inflate(5)).getFirst(); + mc().gameMode.interact(mc().player,boat,InteractionHand.MAIN_HAND); + },()->mc().player.isPassenger() && !utility(MOORING).settings().getBoolean("Secured")); + add("dismount",()->mc().options.keyShift.setDown(true),()->{if(ticks>10)mc().options.keyShift.setDown(false);return ticks>12 && !mc().player.isPassenger();}); + add("stillwater anchor live GUI",()->{mc().player.getInventory().selected=0;use(ANCHOR);},()->mc().screen instanceof ControllerScreen); + add("stillwater GUI release action removes client override",()->{ + screenshot("stillwater");click("engineering.streamcontrol.automation_tab");at(150,122);click("gui.streamcontrol.apply"); + },()->region(ANCHOR)==null); + if(net.neoforged.fml.ModList.get().isLoaded("create")) { + add("Create live kinetic region",()->use(MECHANICAL),()->mc().screen instanceof ControllerScreen && region(MECHANICAL)!=null); + add("Create GUI direction apply",()->{screenshot("mechanical");click("gui.streamcontrol.short_e");click("gui.streamcontrol.apply");},()->region(MECHANICAL)!=null && region(MECHANICAL).dx()==1); + add("Create actual motor reversal reaches client",()->command("reverse"),()->region(MECHANICAL)!=null && region(MECHANICAL).dx()==-1); + add("Create stopped motor clears client override",()->command("stop"),()->region(MECHANICAL)==null); + } + add("render Calibrator HUD and world bounds",()->{ + mc().setScreen(null);mc().player.setXRot(35);mc().player.setYRot(160); + },()->{if(ticks==30)screenshot("world");return ticks>40;}); + } + @SubscribeEvent public static void tick(ClientTickEvent.Post event) { + if(!Boolean.getBoolean("streamcontrol.clientIntegrationTest") || done) return; + try { + if(++total>12000) throw new AssertionError("Client overall timeout; screen="+mc().screen); + if(!connecting) { + if(!(mc().screen instanceof TitleScreen) || mc().getOverlay()!=null) return; + connecting=true; + ConnectScreen.startConnecting(mc().screen,mc(),ServerAddress.parseString("127.0.0.1:25565"),new ServerData("Flow test","127.0.0.1:25565",ServerData.Type.OTHER),false,Optional.empty()); + return; + } + if(mc().level==null || mc().player==null) return; + if(steps.isEmpty()) setup(); + if(step<0) {step=0;ticks=0;} + var s=steps.get(step); + if(ticks==0) {System.out.println("FLOW_CLIENT_BEGIN "+s.name);s.action.run();} + ticks++; + if(ticks>1 && s.ready.getAsBoolean()) { + results.put(s.name,true);System.out.println("FLOW_CLIENT_PASS "+s.name);step++;ticks=0; + if(step==steps.size()) finish(null); + } else if(ticks>240) throw new AssertionError("Timeout: "+s.name+"; screen="+mc().screen); + } catch(Throwable t) {t.printStackTrace();finish(t);} + } + private static void finish(Throwable error) { + done=true;mc().options.keyShift.setDown(false);results.put("passed",error==null); + if(error!=null) {results.put("error",error.toString());screenshot("failure");} + try {Files.writeString(mc().gameDirectory.toPath().resolve("streamcontrol-client-results.json"),new GsonBuilder().setPrettyPrinting().create().toJson(results));} + catch(Exception e) {e.printStackTrace();} + System.out.println("STREAMCONTROL_CLIENT_TEST "+results);mc().stop(); + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateClientFixture.java b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateClientFixture.java new file mode 100644 index 0000000..71ab424 --- /dev/null +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/CreateClientFixture.java @@ -0,0 +1,22 @@ +package nl.townsandkingdoms.streamcontrol.compat.create; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.kinetics.motor.CreativeMotorBlockEntity; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import nl.townsandkingdoms.streamcontrol.ClientTestWorld; + +/** Loaded only by the opt-in test fixture with Create present. */ +public final class CreateClientFixture { + public static void prepare(ServerLevel level) { + var p=ClientTestWorld.MECHANICAL; + level.setBlock(p.below(),AllBlocks.CREATIVE_MOTOR.getDefaultState().setValue(BlockStateProperties.FACING,Direction.UP),3); + level.setBlock(p,CreateIntegration.BLOCK.get().defaultBlockState(),3); + speed(level,128); + } + public static void speed(ServerLevel level,int rpm) { + var motor=(CreativeMotorBlockEntity)level.getBlockEntity(ClientTestWorld.MECHANICAL.below()); + motor.generatedSpeed.setValue(rpm);motor.updateGeneratedRotation(); + } +} diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentBlock.java b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentBlock.java index 019b082..2ce8fe6 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentBlock.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/compat/create/MechanicalCurrentBlock.java @@ -38,6 +38,10 @@ public final class MechanicalCurrentBlock extends KineticBlock implements IBE Date: Tue, 3 Nov 2026 09:42:09 +0100 Subject: [PATCH 09/14] Match the Minecraft 1.21.1 connection transfer-state API --- .../streamcontrol/client/ClientGameplayChecks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java index d3a6d67..a1edba1 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java @@ -122,7 +122,7 @@ private static void setup() { if(!connecting) { if(!(mc().screen instanceof TitleScreen) || mc().getOverlay()!=null) return; connecting=true; - ConnectScreen.startConnecting(mc().screen,mc(),ServerAddress.parseString("127.0.0.1:25565"),new ServerData("Flow test","127.0.0.1:25565",ServerData.Type.OTHER),false,Optional.empty()); + ConnectScreen.startConnecting(mc().screen,mc(),ServerAddress.parseString("127.0.0.1:25565"),new ServerData("Flow test","127.0.0.1:25565",ServerData.Type.OTHER),false,null); return; } if(mc().level==null || mc().player==null) return; From a6cdbf4d75d54d6816981c19464b90c8d15a3906 Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 09:46:29 +0100 Subject: [PATCH 10/14] Isolate sensor elevation fixture and verify Profile B's saved heading --- .../townsandkingdoms/streamcontrol/ClientTestWorld.java | 8 ++++---- .../streamcontrol/client/ClientGameplayChecks.java | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java index 49b0875..04f23fa 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java @@ -36,10 +36,10 @@ private static void prepare(ServerStartedEvent e) { l.setBlock(ANCHOR,StreamControl.ANCHOR.get().defaultBlockState(),3); ((ControllerEntity)l.getBlockEntity(ANCHOR)).configure(FlowHeading.NORTH,3,1,false); // A separate high pool makes the sensor's independent vertical range observable. - l.setBlock(SENSOR.above(3),Blocks.WATER.defaultBlockState(),3); - for(var d:net.minecraft.core.Direction.Plane.HORIZONTAL) l.setBlock(SENSOR.above(3).relative(d),Blocks.GLASS.defaultBlockState(),3); - l.setBlock(SENSOR.above(2),Blocks.GLASS.defaultBlockState(),3); - ControlData.get(l).put(l,new FlowRegion(9001,SENSOR.above(3),1,0,1,0,2,false,false,new java.util.UUID(0,0),ControlData.get(l).next())); + l.setBlock(SENSOR.above(6),Blocks.WATER.defaultBlockState(),3); + for(var d:net.minecraft.core.Direction.Plane.HORIZONTAL) l.setBlock(SENSOR.above(6).relative(d),Blocks.GLASS.defaultBlockState(),3); + l.setBlock(SENSOR.above(5),Blocks.GLASS.defaultBlockState(),3); + ControlData.get(l).put(l,new FlowRegion(9001,SENSOR.above(6),1,0,1,0,2,false,false,new java.util.UUID(0,0),ControlData.get(l).next())); var boat=new Boat(l,.5,100.1,4.5);l.addFreshEntity(boat); if(net.neoforged.fml.ModList.get().isLoaded("create")) nl.townsandkingdoms.streamcontrol.compat.create.CreateClientFixture.prepare(l); try { java.nio.file.Files.writeString(net.neoforged.fml.loading.FMLPaths.GAMEDIR.get().resolve("client-test-ready"),"ready"); } diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java index a1edba1..2a93b55 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java @@ -80,12 +80,12 @@ private static void setup() { click("engineering.streamcontrol.automation_tab");for(int i=0;i<4;i++) at(150,66); click("engineering.streamcontrol.profile_b");slider(0,3.0/16);screenshot("automation");click("gui.streamcontrol.apply"); },()->controller(GENERATOR).controls().redstone()==ControllerSettings.Redstone.SWITCH && controller(GENERATOR).controls().b().vertical()==3); - add("redstone switches to reversed Profile B",()->command("power"),()->region(GENERATOR)!=null && region(GENERATOR).dx()==-1 && region(GENERATOR).vertical()==3); + add("redstone switches to reversed Profile B",()->command("power"),()->region(GENERATOR)!=null && region(GENERATOR).dz()==1 && region(GENERATOR).vertical()==3); add("unpowered restores Profile A",()->command("unpower"),()->region(GENERATOR)!=null && region(GENERATOR).dx()==1 && region(GENERATOR).vertical()!=3); add("open sensor through block interaction",()->use(SENSOR),()->mc().screen instanceof UtilityScreen); add("sensor GUI independent vertical range and live speed output",()->{ - slider(0,0);slider(1,3.0/16);screenshot("sensor");click("gui.streamcontrol.apply"); - },()->((FlowSensorEntity)utility(SENSOR)).radius()==1 && ((FlowSensorEntity)utility(SENSOR)).vertical()==3 && ((FlowSensorEntity)utility(SENSOR)).output()==15); + slider(0,0);slider(1,6.0/16);screenshot("sensor");click("gui.streamcontrol.apply"); + },()->((FlowSensorEntity)utility(SENSOR)).radius()==1 && ((FlowSensorEntity)utility(SENSOR)).vertical()==6 && ((FlowSensorEntity)utility(SENSOR)).output()==15); add("reopen sensor",()->use(SENSOR),()->mc().screen instanceof UtilityScreen); add("sensor direction comparator and settings sync",()->{at(150,149);click("gui.streamcontrol.apply");},()->((FlowSensorEntity)utility(SENSOR)).mode()==FlowSensorEntity.Mode.DIRECTION && ((FlowSensorEntity)utility(SENSOR)).output()==3); add("reopen sensor boat mode",()->use(SENSOR),()->mc().screen instanceof UtilityScreen); From de3c64c667c6fc16c09cbc9b1c6f988045519589 Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 09:53:00 +0100 Subject: [PATCH 11/14] Keep live client boarding fixture on the dock platform --- .../nl/townsandkingdoms/streamcontrol/ClientTestWorld.java | 2 +- .../streamcontrol/client/ClientGameplayChecks.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java index 04f23fa..51355a4 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java @@ -58,7 +58,7 @@ private static void commands(RegisterCommandsEvent e) { var l=c.getSource().getLevel();l.setBlock(GENERATOR.below(),Blocks.REDSTONE_BLOCK.defaultBlockState(),3);return 1; })).then(literal("unpower").executes(c->{ var l=c.getSource().getLevel();l.setBlock(GENERATOR.below(),Blocks.STONE.defaultBlockState(),3);return 1; - })).then(literal("dock").executes(c->{c.getSource().getPlayerOrException().teleportTo(.5,101,1.5);return 1; + })).then(literal("dock").executes(c->{var p=c.getSource().getPlayerOrException();p.teleportTo(.5,101,3.5);p.setDeltaMovement(net.minecraft.world.phys.Vec3.ZERO);return 1; })).then(literal("reverse").executes(c->{ if(net.neoforged.fml.ModList.get().isLoaded("create")) nl.townsandkingdoms.streamcontrol.compat.create.CreateClientFixture.speed(c.getSource().getLevel(),-128);return 1; })).then(literal("stop").executes(c->{ diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java index 2a93b55..2b893eb 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java @@ -90,7 +90,7 @@ private static void setup() { add("sensor direction comparator and settings sync",()->{at(150,149);click("gui.streamcontrol.apply");},()->((FlowSensorEntity)utility(SENSOR)).mode()==FlowSensorEntity.Mode.DIRECTION && ((FlowSensorEntity)utility(SENSOR)).output()==3); add("reopen sensor boat mode",()->use(SENSOR),()->mc().screen instanceof UtilityScreen); add("sensor boat mode and zero vertical range",()->{at(150,149);slider(0,7.0/15);slider(1,0);click("gui.streamcontrol.apply");},()->((FlowSensorEntity)utility(SENSOR)).mode()==FlowSensorEntity.Mode.BOATS && ((FlowSensorEntity)utility(SENSOR)).output()==1); - add("mooring live boat capture sync",()->command("dock"),()->utility(MOORING).settings().getBoolean("Secured")); + add("mooring live boat capture sync",()->command("dock"),()->utility(MOORING).settings().getBoolean("Secured") && mc().player.blockPosition().distSqr(MOORING)<=2); add("open mooring",()->use(MOORING),()->mc().screen instanceof UtilityScreen); add("disable mooring from GUI releases boat",()->{screenshot("mooring");at(150,186);click("gui.streamcontrol.apply");},()->!utility(MOORING).settings().getBoolean("Enabled") && !utility(MOORING).settings().getBoolean("Secured")); add("reopen mooring",()->use(MOORING),()->mc().screen instanceof UtilityScreen); @@ -134,7 +134,7 @@ private static void setup() { if(ticks>1 && s.ready.getAsBoolean()) { results.put(s.name,true);System.out.println("FLOW_CLIENT_PASS "+s.name);step++;ticks=0; if(step==steps.size()) finish(null); - } else if(ticks>240) throw new AssertionError("Timeout: "+s.name+"; screen="+mc().screen); + } else if(ticks>240) throw new AssertionError("Timeout: "+s.name+"; screen="+mc().screen+"; player="+mc().player.position()+"; passenger="+mc().player.isPassenger()+"; crouching="+mc().player.isShiftKeyDown()); } catch(Throwable t) {t.printStackTrace();finish(t);} } private static void finish(Throwable error) { From f7003633a3edd2e1d4df7d3ed2686a7506ab3d5b Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 09:57:44 +0100 Subject: [PATCH 12/14] Diagnose live boat boarding and start fixture at water surface --- .../nl/townsandkingdoms/streamcontrol/ClientTestWorld.java | 6 +++++- .../streamcontrol/client/ClientGameplayChecks.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java index 51355a4..1a16c3c 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java @@ -22,6 +22,7 @@ public static void register() { NeoForge.EVENT_BUS.addListener(ClientTestWorld::prepare); NeoForge.EVENT_BUS.addListener(ClientTestWorld::login); NeoForge.EVENT_BUS.addListener(ClientTestWorld::commands); + NeoForge.EVENT_BUS.addListener(ClientTestWorld::interaction); } private static void prepare(ServerStartedEvent e) { var l=e.getServer().overworld();l.setDayTime(6000);l.setWeatherParameters(100000,0,false,false); @@ -40,7 +41,7 @@ private static void prepare(ServerStartedEvent e) { for(var d:net.minecraft.core.Direction.Plane.HORIZONTAL) l.setBlock(SENSOR.above(6).relative(d),Blocks.GLASS.defaultBlockState(),3); l.setBlock(SENSOR.above(5),Blocks.GLASS.defaultBlockState(),3); ControlData.get(l).put(l,new FlowRegion(9001,SENSOR.above(6),1,0,1,0,2,false,false,new java.util.UUID(0,0),ControlData.get(l).next())); - var boat=new Boat(l,.5,100.1,4.5);l.addFreshEntity(boat); + var boat=new Boat(l,.5,100.8,4.5);l.addFreshEntity(boat); if(net.neoforged.fml.ModList.get().isLoaded("create")) nl.townsandkingdoms.streamcontrol.compat.create.CreateClientFixture.prepare(l); try { java.nio.file.Files.writeString(net.neoforged.fml.loading.FMLPaths.GAMEDIR.get().resolve("client-test-ready"),"ready"); } catch(java.io.IOException ex) { throw new RuntimeException(ex); } @@ -53,6 +54,9 @@ private static void login(PlayerEvent.PlayerLoggedInEvent e) { p.getInventory().setItem(0,new ItemStack(StreamControl.WAND.get())); p.getInventory().selected=0;p.inventoryMenu.broadcastChanges(); } + private static void interaction(net.neoforged.neoforge.event.entity.player.PlayerInteractEvent.EntityInteract e) { + if(e.getTarget() instanceof Boat b) System.out.println("FLOW_BOARD_INPUT boat="+b.position()+" underwater="+b.isUnderWater()+" eyeFluid="+b.getEyeInFluidType()+" passengers="+b.getPassengers().size()+" hand="+e.getItemStack()+" crouch="+e.getEntity().isShiftKeyDown()+" player="+e.getEntity().position()); + } private static void commands(RegisterCommandsEvent e) { e.getDispatcher().register(literal("flowclient").then(literal("power").executes(c->{ var l=c.getSource().getLevel();l.setBlock(GENERATOR.below(),Blocks.REDSTONE_BLOCK.defaultBlockState(),3);return 1; diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java index 2b893eb..a6d0128 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java @@ -98,7 +98,7 @@ private static void setup() { add("real player boarding releases mooring",()->{ mc().player.getInventory().selected=1; var boat=mc().level.getEntitiesOfClass(Boat.class,new AABB(MOORING).inflate(5)).getFirst(); - mc().gameMode.interact(mc().player,boat,InteractionHand.MAIN_HAND); + System.out.println("FLOW_BOARD_CLIENT boat="+boat.position()+" underwater="+boat.isUnderWater()+" result="+mc().gameMode.interact(mc().player,boat,InteractionHand.MAIN_HAND)); },()->mc().player.isPassenger() && !utility(MOORING).settings().getBoolean("Secured")); add("dismount",()->mc().options.keyShift.setDown(true),()->{if(ticks>10)mc().options.keyShift.setDown(false);return ticks>12 && !mc().player.isPassenger();}); add("stillwater anchor live GUI",()->{mc().player.getInventory().selected=0;use(ANCHOR);},()->mc().screen instanceof ControllerScreen); From 7e983f9d1954b173549249d22ec8eea3531ac2e8 Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 10:24:06 +0100 Subject: [PATCH 13/14] Document verified engineering release and capture an unobstructed client world --- .github/workflows/neoforge-1.21.1.yml | 3 +-- CHANGELOG.md | 12 ++++++++++++ .../streamcontrol/ClientTestWorld.java | 3 +++ .../streamcontrol/client/ClientGameplayChecks.java | 4 ++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/neoforge-1.21.1.yml b/.github/workflows/neoforge-1.21.1.yml index 466e79c..1fe0949 100644 --- a/.github/workflows/neoforge-1.21.1.yml +++ b/.github/workflows/neoforge-1.21.1.yml @@ -4,7 +4,6 @@ on: push: branches: - "gui/**" - - "feature/**" - main - fix/neoforge-1.21.1-stillwater-render pull_request: @@ -81,7 +80,7 @@ jobs: - name: Capture the actual controller GUIs run: | mkdir -p run-client - printf 'onboardAccessibility:false\nguiScale:3\nfullscreen:false\n' > run-client/options.txt + printf 'onboardAccessibility:false\nguiScale:3\ntutorialStep:none\nfullscreen:false\n' > run-client/options.txt timeout 360 xvfb-run -a ./gradlew --no-daemon -Dstreamcontrol.uiPreview=true $CREATE_ARGS runClient test -s run-client/screenshots/flow-control-current-generator.png test -s run-client/screenshots/flow-control-stillwater-anchor.png diff --git a/CHANGELOG.md b/CHANGELOG.md index ad73976..a34460e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ ![Flow Control](https://i.imgur.com/JGT2lvz.png) +## 0.2.2 — Verified Water Engineering and Version Ports + +- Fixed controller and utility block interactions so Copy, Paste and Link reach the Calibrator instead of opening the normal configuration screen. +- Carried the redesigned, centered interfaces and water-engineering functions to the existing Minecraft/loader ports. +- Updated every port to the exact Streams Reflowing 2.16.2 dependency and checked its current-grid and surface-particle APIs against the matching JAR. +- Preserved old wand items, legacy edits and controller settings; clients and servers must use matching 0.2.2 builds. +- Added real client/server checks for GUI Apply and synchronization, all Calibrator modes, links and unlinking, profiles, redstone switching, vertical sensors and comparator output, mooring release/recapture and real-player boarding. +- Verified the optional mechanical controller through actual Create motor input, reversal and stopping. Create's normal water-wheel RPM behavior is unchanged. +- Adapted modern ports to their own persistence, comparator and rendering APIs, including world-bound item components and 26.3 geometry submission. + +The complete feature changelog and exact supported dependency matrix are supplied with the verified release bundle. + ## 0.2.1 — Barrel and Create Model Refinement - Kept the original control lid on the Mechanical Current Generator and replaced its entire body with native Create Andesite Casing textures. diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java b/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java index 1a16c3c..c8c8277 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/ClientTestWorld.java @@ -63,6 +63,9 @@ private static void commands(RegisterCommandsEvent e) { })).then(literal("unpower").executes(c->{ var l=c.getSource().getLevel();l.setBlock(GENERATOR.below(),Blocks.STONE.defaultBlockState(),3);return 1; })).then(literal("dock").executes(c->{var p=c.getSource().getPlayerOrException();p.teleportTo(.5,101,3.5);p.setDeltaMovement(net.minecraft.world.phys.Vec3.ZERO);return 1; + })).then(literal("view").executes(c->{ + var l=c.getSource().getLevel();l.setBlock(new BlockPos(4,102,-4),Blocks.STONE.defaultBlockState(),3); + var p=c.getSource().getPlayerOrException();p.teleportTo(4.5,103,-3.5);p.setDeltaMovement(net.minecraft.world.phys.Vec3.ZERO);return 1; })).then(literal("reverse").executes(c->{ if(net.neoforged.fml.ModList.get().isLoaded("create")) nl.townsandkingdoms.streamcontrol.compat.create.CreateClientFixture.speed(c.getSource().getLevel(),-128);return 1; })).then(literal("stop").executes(c->{ diff --git a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java index a6d0128..70259e4 100644 --- a/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java +++ b/src/main/java/nl/townsandkingdoms/streamcontrol/client/ClientGameplayChecks.java @@ -112,8 +112,8 @@ private static void setup() { add("Create stopped motor clears client override",()->command("stop"),()->region(MECHANICAL)==null); } add("render Calibrator HUD and world bounds",()->{ - mc().setScreen(null);mc().player.setXRot(35);mc().player.setYRot(160); - },()->{if(ticks==30)screenshot("world");return ticks>40;}); + mc().setScreen(null);command("view");mc().player.setXRot(36);mc().player.setYRot(45); + },()->{if(ticks==200)screenshot("world");return ticks>210;}); } @SubscribeEvent public static void tick(ClientTickEvent.Post event) { if(!Boolean.getBoolean("streamcontrol.clientIntegrationTest") || done) return; From da3055527c1e3da70a8b4c721dde4a24b6b550ee Mon Sep 17 00:00:00 2001 From: Mikaaah <59295501+Mikaaah@users.noreply.github.com> Date: Tue, 3 Nov 2026 10:53:06 +0100 Subject: [PATCH 14/14] Synchronize embedded mod metadata with the 0.2.2 release version --- src/main/resources/META-INF/neoforge.mods.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml index 279b31d..41c596b 100644 --- a/src/main/resources/META-INF/neoforge.mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -4,7 +4,7 @@ license="GPL-3.0-only" issueTrackerURL="https://github.com/Mikaaah/Streams-Flow-Control/issues" [[mods]] modId="streamcontrol" -version="0.2.1" +version="0.2.2" displayName="Streams Flow Control" authors="Mikaaah / Towns & Kingdoms" displayURL="https://github.com/Mikaaah/Streams-Flow-Control"