From a78a627346558336e90fb96eb765858a9d30e80c Mon Sep 17 00:00:00 2001 From: <> Date: Sun, 5 May 2024 10:13:06 +0000 Subject: [PATCH] Deployed 448007c with MkDocs version: 1.6.0 --- .nojekyll | 0 404.html | 2160 ++++++ Development/External-Resources/index.html | 2401 ++++++ Development/FAQ/index.html | 2281 ++++++ .../General-Topics/Capabilities/index.html | 2228 ++++++ .../Energy-Fluid-Item-Storage/index.html | 2497 ++++++ .../General-Topics/Global-Data/index.html | 2301 ++++++ .../Handling-Fluid-Bucket-Size/index.html | 2222 ++++++ .../General-Topics/Optimization/index.html | 2220 ++++++ .../General-Topics/Ore-Generation/index.html | 2464 ++++++ .../index.html | 2351 ++++++ .../General-Topics/Tick-Updates/index.html | 2442 ++++++ Development/Glossary/index.html | 2366 ++++++ .../Annotations/DescSynced/index.html | 2219 ++++++ .../SyncData/Annotations/Persisted/index.html | 2219 ++++++ .../Annotations/RequireRerender/index.html | 2219 ++++++ .../Annotations/UpdateListener/index.html | 2217 ++++++ .../SyncData/Using-SyncData/index.html | 2316 ++++++ Development/SyncData/index.html | 2211 ++++++ Development/index.html | 2219 ++++++ Gameplay/Ore-Generation/index.html | 3331 ++++++++ Gameplay/Steam/Bronze/index.html | 2218 ++++++ Gameplay/Steam/Steam-Generation/index.html | 2504 ++++++ Gameplay/Steam/assets/bronze_recipe.png | Bin 0 -> 1571 bytes Gameplay/Steam/assets/ingot_crushed.png | Bin 0 -> 3426 bytes Gameplay/Steam/assets/p_water_pump.png | Bin 0 -> 49042 bytes Gameplay/Steam/index.html | 2227 ++++++ Gameplay/index.html | 2202 ++++++ Modpacks/Beyond-The-Docs/index.html | 2342 ++++++ Modpacks/Changes/v1.1.0/index.html | 2329 ++++++ Modpacks/Changes/v1.2.1/index.html | 2351 ++++++ Modpacks/Examples/Alternator/index.html | 2388 ++++++ Modpacks/Examples/Greenhouse/index.html | 2532 +++++++ .../Examples/Ore-Processing-Plant/index.html | 2361 ++++++ Modpacks/Examples/index.html | 2217 ++++++ .../01-Material-Creation/index.html | 2454 ++++++ .../02-Element-Creation/index.html | 2299 ++++++ .../Material-Flags/index.html | 2358 ++++++ .../Material-Icon-Sets/index.html | 2333 ++++++ .../Material-Properties/index.html | 2270 ++++++ .../Modifying-Existing-Materials/index.html | 2270 ++++++ Modpacks/Materials-and-Elements/index.html | 2219 ++++++ .../01-Customizing-Veins/index.html | 2432 ++++++ .../Ore-Generation/02-Generators/index.html | 2536 +++++++ .../03-Adding-Stone-Types/index.html | 2368 ++++++ .../04-Layers-and-Dimensions/index.html | 2303 ++++++ .../Bedrock-Fluid-Veins/index.html | 2298 ++++++ Modpacks/Ore-Generation/index.html | 2243 ++++++ .../Adding-and-Removing-Recipes/index.html | 2469 ++++++ Modpacks/Other-Topics/Custom-Coils/index.html | 2294 ++++++ .../Other-Topics/Custom-Machines/index.html | 2483 ++++++ .../Custom-Recipe-Types/index.html | 2308 ++++++ .../Other-Topics/LDLib-UI-Editor/index.html | 2229 ++++++ Modpacks/Other-Topics/index.html | 2217 ++++++ Modpacks/index.html | 2262 ++++++ assets/favicon.png | Bin 0 -> 839 bytes assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.a7c05c9e.min.js | 29 + assets/javascripts/bundle.a7c05c9e.min.js.map | 7 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.el.min.js | 1 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.he.min.js | 1 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.b8dbb3d2.min.js | 42 + .../workers/search.b8dbb3d2.min.js.map | 7 + assets/logo.png | Bin 0 -> 700 bytes assets/stylesheets/main.66ac8b77.min.css | 1 + assets/stylesheets/main.66ac8b77.min.css.map | 1 + assets/stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + index.html | 2295 ++++++ search/search_index.json | 1 + sitemap.xml | 3 + sitemap.xml.gz | Bin 0 -> 127 bytes stylesheets/extra.css | 48 + 105 files changed, 128837 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 Development/External-Resources/index.html create mode 100644 Development/FAQ/index.html create mode 100644 Development/General-Topics/Capabilities/index.html create mode 100644 Development/General-Topics/Energy-Fluid-Item-Storage/index.html create mode 100644 Development/General-Topics/Global-Data/index.html create mode 100644 Development/General-Topics/Handling-Fluid-Bucket-Size/index.html create mode 100644 Development/General-Topics/Optimization/index.html create mode 100644 Development/General-Topics/Ore-Generation/index.html create mode 100644 Development/General-Topics/Overclocking-And-Parallel-Logic/index.html create mode 100644 Development/General-Topics/Tick-Updates/index.html create mode 100644 Development/Glossary/index.html create mode 100644 Development/SyncData/Annotations/DescSynced/index.html create mode 100644 Development/SyncData/Annotations/Persisted/index.html create mode 100644 Development/SyncData/Annotations/RequireRerender/index.html create mode 100644 Development/SyncData/Annotations/UpdateListener/index.html create mode 100644 Development/SyncData/Using-SyncData/index.html create mode 100644 Development/SyncData/index.html create mode 100644 Development/index.html create mode 100644 Gameplay/Ore-Generation/index.html create mode 100644 Gameplay/Steam/Bronze/index.html create mode 100644 Gameplay/Steam/Steam-Generation/index.html create mode 100644 Gameplay/Steam/assets/bronze_recipe.png create mode 100644 Gameplay/Steam/assets/ingot_crushed.png create mode 100644 Gameplay/Steam/assets/p_water_pump.png create mode 100644 Gameplay/Steam/index.html create mode 100644 Gameplay/index.html create mode 100644 Modpacks/Beyond-The-Docs/index.html create mode 100644 Modpacks/Changes/v1.1.0/index.html create mode 100644 Modpacks/Changes/v1.2.1/index.html create mode 100644 Modpacks/Examples/Alternator/index.html create mode 100644 Modpacks/Examples/Greenhouse/index.html create mode 100644 Modpacks/Examples/Ore-Processing-Plant/index.html create mode 100644 Modpacks/Examples/index.html create mode 100644 Modpacks/Materials-and-Elements/01-Material-Creation/index.html create mode 100644 Modpacks/Materials-and-Elements/02-Element-Creation/index.html create mode 100644 Modpacks/Materials-and-Elements/Material-Flags/index.html create mode 100644 Modpacks/Materials-and-Elements/Material-Icon-Sets/index.html create mode 100644 Modpacks/Materials-and-Elements/Material-Properties/index.html create mode 100644 Modpacks/Materials-and-Elements/Modifying-Existing-Materials/index.html create mode 100644 Modpacks/Materials-and-Elements/index.html create mode 100644 Modpacks/Ore-Generation/01-Customizing-Veins/index.html create mode 100644 Modpacks/Ore-Generation/02-Generators/index.html create mode 100644 Modpacks/Ore-Generation/03-Adding-Stone-Types/index.html create mode 100644 Modpacks/Ore-Generation/04-Layers-and-Dimensions/index.html create mode 100644 Modpacks/Ore-Generation/Bedrock-Fluid-Veins/index.html create mode 100644 Modpacks/Ore-Generation/index.html create mode 100644 Modpacks/Other-Topics/Adding-and-Removing-Recipes/index.html create mode 100644 Modpacks/Other-Topics/Custom-Coils/index.html create mode 100644 Modpacks/Other-Topics/Custom-Machines/index.html create mode 100644 Modpacks/Other-Topics/Custom-Recipe-Types/index.html create mode 100644 Modpacks/Other-Topics/LDLib-UI-Editor/index.html create mode 100644 Modpacks/Other-Topics/index.html create mode 100644 Modpacks/index.html create mode 100644 assets/favicon.png create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.a7c05c9e.min.js create mode 100644 assets/javascripts/bundle.a7c05c9e.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js.map create mode 100644 assets/logo.png create mode 100644 assets/stylesheets/main.66ac8b77.min.css create mode 100644 assets/stylesheets/main.66ac8b77.min.css.map create mode 100644 assets/stylesheets/palette.06af60db.min.css create mode 100644 assets/stylesheets/palette.06af60db.min.css.map create mode 100644 index.html create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz create mode 100644 stylesheets/extra.css diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..cdac32c --- /dev/null +++ b/404.html @@ -0,0 +1,2160 @@ + + + +
+ + + + + + + + + + + + + + +This page contains links to external documentation that may be useful for several topics regarding development, as well +as other resources you might find helpful.
+Official Forge / NeoForge Docs
+ +Official Fabric Docs
+ +Other Modding Docs
+ +LDLib is the main library we're using for GTCEu-Modern.
+LDLib Docs
+ +Overview on using Mixins
+ +This is a great resource for getting started on how to use mixins, as well as a good quick reference if you're +looking for how to do something specific.
+Note that this is not exclusive to Fabric, but applies for all platforms instead.
+Unofficial Documentation
+ +Unofficial documentation for Mojang's DataFixerUpper library.
+Using Registrate
+ +Architectury Gradle Plugin
+Architectury-Wiki Gradle Plugin
+Note that we're only using Architectury's build system, not the library itself.
+Shimmer (one of our soft-dependencies) displays information about colored lights in development environments by default.
+You can turn it off using the command /shimmer coloredLightMonitor
ingame.
Alternatively, if you want to disable it by default, put this in your KubeJS client scripts:
+// Disable Shimmer's colored light monitor:
+let LightCounterRender = Java.loadClass("com.lowdragmc.shimmer.client.light.LightCounter$Render")
+LightCounterRender.enable = false
+
Fabric doesn't have a capability system like Forge does, but you can use several utility methods instead:
+FluidTransferHelper.getFluidTransfer(...);
+ItemTransferHelper.getItemTransfer(...);
+GTCapabilityHelper.getRecipeLogic(...)
+GTCapabilityHelper.getControllable(...)
+GTCapabilityHelper.getCoverable(...)
+GTCapabilityHelper.getToolable(...)
+GTCapabilityHelper.getWorkable(...)
+GTCapabilityHelper.getElectricItem(...)
+GTCapabilityHelper.getEnergyContainer(...)
+
Note
+In general, these containers should be created as final
fields (that's what we need for the
+SyncData system).
+Set their base arguments in the constructor (you can pass args for subclasses to modify).
You can create these containers via one of the following classes:
+NotifiableItemStackHandler
NotifiableFluidTank
NotifiableEnergyContainer
In general, you should prefer these classes over other implementations if possible, as they notify all listeners +of internal changes to improve performance.
+IO constructor parameters:
+handlerIO
: Whether the container is regarded as input or output during recipe processingcapabilityIO
: Whether the player can use hoppers, pipes, cables, etc. to interact with the storageIf you don't need to use the storage for recipe processing and/or providing capabilities, you can just use one of the +following classes, as they are more lightweight:
+ItemStackTransfer
FluidStorage
In some cases, you might need to create a custom implementation for either of these containers.
+To do so, use either of the following interfaces:
IItemTransfer
IFluidTransfer
IEnergyContainer
In case you have special requirements to your containers, you may be able to use one of these implementations in
+conjunction with one or more regular containers.
+They generally act as a proxy to the underlying container(s), while also handling these requirements.
ItemTransferList
FluidTransferList
EnergyContainerList
For proxying multiple containers, limited to a specific IO direction.
+IOItemTransferList
IOFluidTransferList
Not merged yet
Branch: mi-ender-link
If you need to proxy any item or fluid container that needs to be rate limited for insertion and extraction, you can +use either of the following classes:
+LimitingItemTransferProxy
LimitingFluidTransferProxy
The transfer limit passed as a constructor parameter will not renew automatically. Your container will therefore stop +transferring anything once this limit is reached.
+If you want to make this a rate limit instead, you will have to schedule a task that regularly resets the transfer +limit to the maximum value for your task's interval:
+public class MyCover extends CoverBehavior {
+ private LimitingFluidTransferProxy transferProxy;
+ private ConditionalSubscriptionHandler rateLimitSubscription;
+
+ public MyCover(IFluidTransfer myFluidTransfer) {
+ super(/* ... */);
+
+ transferProxy = new LimitingFluidTransferProxy(
+ myFluidTransfer,
+ 0L // Initial limit of 0, will be updated regularly in isRateLimitRefreshActive()
+ );
+ rateLimitSubscription = new ConditionalSubscriptionHandler(
+ this,
+ this::resetTransferRateLimit,
+ this::isRateLimitRefreshActive
+ );
+ }
+
+ @Override
+ public void onLoad() {
+ super.onLoad();
+ rateLimitSubscription.initialize(coverHolder.getLevel());
+ }
+
+ private void resetTransferRateLimit() {
+ if (transferProxy == null)
+ return;
+
+ transferProxy.setRemainingTransfer(transferRate.getMilliBuckets() * 20);
+ }
+
+ private boolean isRateLimitRefreshActive() {
+ // ...
+ }
+}
+
In certain cases (e.g. in a cache that holds all currently loaded instances of a machine), you might need to store data +in a global (static and mutable) variable.
+When doing so, you need to ensure that remote and serverside instances don't get mixed up.
+SideLocal<T>
Not yet merged
Branch: mi-ender-link
To make working with this requirement easier, You can use SideLocal<T>
to store your global data.
+It is similar to Java's ThreadLocal
, but operates on the game's sides instead.
If you are currently on the remote side (LDLib.isRemote()
/ on the client's main
thread), it will return the
+remote side's instance of your data. Otherwise, you will get the server side's instance.
public class MyCache {
+ private static SideLocal<Map<UUID, MyData>> cache = new SideLocal<>(HashMap::new);
+
+ public static void cacheData(UUID id, MyData data) {
+ cache.get().put(id, data);
+ }
+
+ public static MyData getData(UUID id) {
+ return cache.get().get(id);
+ }
+}
+
Alternatively to passing an initializer for both instances to SideLocal
's constructor, you can also supply
+separate instances for the remote and server side.
The fluid systems of Forge and Fabric use different units. +Make sure you use the correct units whenever you're handling fluid amounts.
+To get the size of one bucket, use the following method:
+FluidHelper.getBucket(); // returns 1000 on Forge and 81000 on Fabric.
+
Not yet documented
+Due to Minecraft's worldgen limitations (1), GTCEu's ore vein generation does not use the native worldgen feature system.
+Instead, we have our own system of generating ore veins separately from the actual ore placement,
+so that ores are only ever placed for the currently generating chunk.
+This page roughly describes the process of generating, caching and placing ores.
The generation can be (roughly) split up into three steps:
+This document will cover these steps from the bottom up, starting at the chunk generation mixin (ChunkGeneratorMixin.gtceu$applyBiomeDecoration()
).
The ChunkGeneratorMixin
holds a reference to the OrePlacer
(not to be confused with OreBlockPlacer
) - which is used to place the
+generated veins' blocks into the world, limited to the currently generating chunk.
When trying to generate a chunk, the OrePlacer
will query the OreGenCache
for a list of veins surrounding the current chunk.
The radius for querying the surrounding area is determined by the oreVeinRandomOffset
config option, as well as the largest registered vein size.
+It is therefore automatically compatible with any additional (or changed default) veins registered through either KubeJS, or by an addon.
Of course, the ore gen cache can only hold a limited amount of generated veins at once (see the oreGenerationChunkCacheSize
config option).
Because veins may be removed from the cache before all of their chunks are generated, it is extremely important that the ore generation is fully deterministic!
+This ensures that we do not generate ore veins that are either cut off, or have a mismatch in shape or type across chunk borders.
+It also automatically applies across game restarts, keeping continuity even then.
The only situation where ore veins will differ across chunk borders (other than certain internal changes to the generation, of course), is after +the relevant config options have been changed.
+In our case, that means that the RandomSource
s used for world generation must be completely new for generating each vein, so that its type, shape, offset,
+contents, etc. are not influenced by previous queries to the random generator.
+It is completely and exclusively seeded from the world's seed, as well as the chunk position.
For the random ore vein offset, we also include the vein's world generation layer in the random seed.
+This may need to include an additional component in the future, in case we add support for multiple veins per chunk and worldgen-layer.
Whenever the OreGenCache
cannot find a vein for a specific chunk, it will request a list of that chunk's GeneratedVein
s from the OreGenerator
.
The OreGenerator
is responsible for determining a vein's type, its origin (influenced by the oreVeinRandomOffset
config option), as well as providing the appropriate
+randomness source to the used implementation of VeinGenerator
.
Vein Origin vs Center
+A vein's origin is always the chunk it originates in, regardless of the random offset.
+The actual center of a vein is influenced by the random offset and might not be located at the chunk center - or in the same chunk at all.
Once the relevant VeinGenerator
implementation has finished generating the vein's shape, it will be cached per chunk, inside a GeneratedVein
.
VeinGenerator
and OreBlockPlacer
A vein generator is what will generate the actual shape of the vein.
+It should, however, never try to place any blocks directly. Instead, its generate()
method will only return a map of OreBlockPlacer
s by block position, which
+are responsible for actually placing the blocks in the world, as soon as a chunk generates.
+Each OreBlockPlacer
should only place either a single block, or no block.
OreBlockPlacer
sIn certain situations, the process of actually placing the block requires a randomness source (e.g. to determine the chance of its block being placed).
+To keep the ore generation fully deterministic in this case as well, it is recommended to generate a new seed using the supplied RandomSource
at the time of
+vein shape generation. This seed should be passed into the OreBlockPlacer
returned for the each block position.
Inside the OreBlockPlacer
, you can then simply create a new RandomSource
using the precomputed seed.
public class MyVeinGenerator {
+ public Map<BlockPos, OreBlockPlacer> generate(WorldGenLevel level, RandomSource random, GTOreDefinition entry, BlockPos origin) {
+ Map<BlockPos, OreBlockPlacer> generatedBlocks = new Object2ObjectOpenHashMap<>();
+
+ for (BlockPos pos : determineShapePositions()) {
+ final var randomSeed = random.nextLong(); // Fully deterministic regardless of chunk generation order
+ generatedBlocks.put(pos, (access, section) -> placeBlock(access, section, randomSeed, pos, entry));
+ }
+
+ return generatedBlocks;
+ }
+
+ private void placeBlock(BulkSectionAccess level, LevelChunkSection section, long randomSeed, BlockPos pos, GTOreDefinition entry) {
+ RandomSource rand = new XoroshiroRandomSource(randomSeed);
+
+ // ...
+ }
+}
+
To improve its generality, RecipeLogic has been rewritten in GTCEu Modern to support inputs and outputs other than +EU, items and fluids.
+The new RecipeLogic
no longer handles overclocked and parallel logic, but instead delegates it to the
+machine via IRecipeLogicMachine
:
/**
+ * Override it to modify recipe on the fly e.g. applying overclock,
+ * change chance, etc
+ *
+ * @param recipe recipe from detected from GTRecipeType
+ * @return modified recipe.
+ * null -- this recipe is unavailable
+ */
+@Nullable
+GTRecipe modifyRecipe(GTRecipe recipe);
+
In general, a simple electric overclocking can be done this way. For details, see OverclockingLogic
and RecipeHelper
public @Nullable GTRecipe modifyRecipe(GTRecipe recipe) {
+ if (RecipeHelper.getRecipeEUtTier(recipe) > getTier()) {
+ return null;
+ }
+
+ return RecipeHelper.applyOverclock(
+ getDefinition().getOverclockingLogic(),
+ recipe,
+ getMaxVoltage()
+ );
+}
+
Parallel is also not complicated to implement. Let's take the generator
as an example
public @Nullable GTRecipe modifyRecipe(GTRecipe recipe) {
+ var EUt = RecipeHelper.getOutputEUt(recipe); // get the recipe's EU/t
+
+ if (EUt > 0) {
+ // calculate the max parallel limitation.
+ var maxParallel = (int) (Math.min(
+ energyContainer.getOutputVoltage(),
+ GTValues.V[overclockTier]
+ ) / EUt);
+
+ while (maxParallel > 0) {
+ // copy and apply parallel, it will affect all recipes' contents
+ // and the recipe duration.
+ var copied = recipe.copy(ContentModifier.multiplier(maxParallel));
+
+ // If the machine has enough ingredients, return copied recipe.
+ if (copied.matchRecipe(this)) {
+ copied.duration = copied.duration / maxParallel;
+
+ return copied;
+ }
+
+ // Trying to halve the number of parallelism
+ maxParallel /= 2;
+ }
+ }
+ return null;
+}
+
ITickable
/ update()
The client update is always present and you can override the clientTick()
method, which works just as well as in 1.12.
But for the sake of performance, our machines are no longer always in a tickable state.
+We introduced ITickSubscription
for managed tick logic.
+Understand the basic concept of subscribing to periodic updates when they are needed, and unsubscribe them when
+they are not.
Automatic output of our machine requires periodic output of internal items to an adjacent inventory. +But most of the time this logic doesn't need to be executed if any of the following conditions apply:
+Lets look at how we implement it in QuantumChest
.
QuantumChest
@Getter @Persisted @DescSynced
+protected boolean autoOutputItems;
+@Persisted @DropSaved
+protected final NotifiableItemStackHandler cache; // inner inventory
+protected TickableSubscription autoOutputSubs;
+protected ISubscription exportItemSubs;
+
+// update subscription, subscribe if tick logic subscription is required, unsubscribe otherwise.
+protected void updateAutoOutputSubscription() {
+ var outputFacing = getOutputFacingItems(); // get output facing
+ if ((isAutoOutputItems() && !cache.isEmpty()) // inner item non empty
+ && outputFacing != null // has output facing
+ && ItemTransferHelper.getItemTransfer(getLevel(), getPos().relative(outputFacing), outputFacing.getOpposite()) != null) { // adjacent block has inventory.
+ autoOutputSubs = subscribeServerTick(autoOutputSubs, this::checkAutoOutput); // subscribe tick logic
+ } else if (autoOutputSubs != null) { // unsubscribe tick logic
+ autoOutputSubs.unsubscribe();
+ autoOutputSubs = null;
+ }
+}
+
+// output to nearby block.
+protected void checkAutoOutput() {
+ if (getOffsetTimer() % 5 == 0) {
+ if (isAutoOutputItems() && getOutputFacingItems() != null) {
+ cache.exportToNearby(getOutputFacingItems());
+ }
+ updateAutoOutputSubscription(); // dont foget to check if it's still available
+ }
+}
+
+@Override
+public void onLoad() {
+ super.onLoad();
+ if (getLevel() instanceof ServerLevel serverLevel) {
+ // you cant call ItemTransferHelper.getItemTransfer while chunk is loading, so lets defer it next tick.
+ serverLevel.getServer().tell(new TickTask(0, this::updateAutoOutputSubscription));
+ }
+ // add a listener to listen the changes of inner inventory. (for ex, if inventory not empty anymore, we may need to unpdate logic)
+ exportItemSubs = cache.addChangedListener(this::updateAutoOutputSubscription);
+}
+
+@Override
+public void onUnload() {
+ super.onUnload(); //autoOutputSubs will be released automatically when machine unload
+ if (exportItemSubs != null) { //we should mannually release it.
+ exportItemSubs.unsubscribe();
+ exportItemSubs = null;
+ }
+}
+
+// For any change may affect the logic to invoke updateAutoOutputSubscription at a time
+@Override
+public void setAutoOutputItems(boolean allow) {
+ this.autoOutputItems = allow;
+ updateAutoOutputSubscription();
+}
+
+@Override
+public void setOutputFacingItems(Direction outputFacing) {
+ this.outputFacingItems = outputFacing;
+ updateAutoOutputSubscription();
+}
+
+@Override
+public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) {
+ super.onNeighborChanged(block, fromPos, isMoving);
+ updateAutoOutputSubscription();
+}
+
I know the code is a kinda long, but it's for performance, and thanks to the SyncData system, we've eliminated a lot of +synchronization code, so please sacrifice a little for better performance.
+ConditionalSubscriptionHandler
For ease of use in some situations, it is possible to eliminate some of the boilerplate code and delegate management of
+your subscription to a ConditionalSubscriptionHandler
instead.
Using that class, it is possible to simply provide an update method to run every tick while the subscription is active,
+as well as a Supplier<Boolean>
that determines whether it is active.
Whenever the input of its condition changes, you need to call updateSubscription()
on the handler, so that it can
+re-evaluate it and take the necessary steps if it has changed.
+You should also to call this method after executing your tick logic in most cases, to ensure the subscription doesn't
+stay active any longer than it needs to.
ConditionalSubscriptionHandler
class MyMachine extends MetaMachine implements IControllable {
+ @Persisted @Getter
+ private boolean workingEnabled = true;
+
+ private final ConditionalSubscriptionHandler subscriptionHandler;
+
+ public MyMachine() {
+ super(/* ... */);
+
+ this.subscriptionHandler = new ConditionalSubscriptionHandler(
+ this, this::update, this::isSubscriptionActive
+ );
+ }
+
+ private void update() {
+ // Only run once every second
+ if (getOffsetTimer() % 20 != 0)
+ return;
+
+ // ...
+
+ // Now that the update logic has been executed, update the subscription.
+ // This will internally check if the subscription is still active and
+ // unsubscribe otherwise.
+ subscriptionHandler.updateSubscription();
+ }
+
+ private boolean isSubscriptionActive() {
+ return isWorkingEnabled();
+ }
+
+ @Override
+ public void setWorkingEnabled(boolean workingEnabled) {
+ this.workingEnabled = workingEnabled;
+
+ // Whether the subscription is currently active depends on whether working
+ // is enabled for this machine. As soon as any of the condition inputs changes,
+ // you need to update the subscription.
+ subscriptionHandler.updateSubscription();
+ }
+
+ @Override
+ public void onLoad() {
+ super.onLoad();
+
+ // As soon as you can get a reference to the dimension/level you're in,
+ // you need to initialize your subscription handler.
+ subscriptionHandler.initialize(getLevel());
+ }
+}
+
Info
+This is an overview of technical terms that are commonly used in this documentation.
+If you're not sure what something means (or how it applies to the current context), please refer to this page.
The part of the game running on a player's computer.
+It always hosts the Remote Side.
+In singleplayer mode, the Server Side is hosted on the client as well. In multiplayer mode, the client
+connects to a dedicated server instead.
See also: Server Side
+The remote side is the part of the game that is connected to the game's server side.
+It always runs on the client.
This side may not have the same amount of data available to it as the server does (see SyncData if you
+need to automatically synchronize certain data to the remote side).
+It also does not perform any tick update logic.
See also: Remote Side
+The server side is what one or more players connect to.
+In singleplayer mode, it runs on the client. In multiplayer mode, it runs on a dedicated server.
This side usually has all of the world's data available to it and runs tick update logic.
+This is therefore, where TPS impact becomes relevant. In general, use
Short for "ticks per second". Should stay at exactly 20.
+See Tick Updates and Optimization for techniques +on how to reduce performance impact.
+ + + + + + + + + + + + + + + + +@DescSynced
@Persisted
@RequireRerender
@UpdateListener
For serializing and synchronizing fields, LDLib's annotation-based SyncData system is used.
+Please also refer to the LDLib Wiki.
+Here is an overview of the most important annotations:
+public class MyMachine {
+ @Persisted // (1)
+ private String myPersistedField;
+
+ @DescSynced // (2)
+ private String myClientsideRelevantField;
+
+ @DescSynced @RequireRerender // (3)
+ private IO io;
+
+ @DescSynced @UpdateListener(methodName = "runAdditionalUpdate") // (4)
+ private int fieldWithAdditionalClientUpdateLogic;
+
+
+ private void runAdditionalUpdate(int newValue, int oldValue) {
+ // Run additional clientside update code here
+ }
+}
+
This field is automatically serialized to and deserialized from NBT data, that will be stored with its container.
+ By default, @Persisted
only applies on the server side.
For fields that need to be available on the client (or more specifically, remote) side, you can annotate them with
+ @DescSynced
to make them available there as well.
+ Any changes made to the field on the server side will automatically be synchronized to the client side.
If a change of a synced field's value requires rerendering the containing block (e.g. for different overlays based
+ on a cover's IO direction), simply add the @RequireRerender
annotation to it.
+ Its renderer's code will then be called again every time the field changes.
In some cases, a field may require some additional code to run on the client/remote side when it has been synced.
+ The @UpdateListener
annotation allows you to define a method to be called in that case.
For serializing and synchronizing fields, LDLib's annotation-based SyncData system is used.
+Using this system, almost all boilerplate code regarding these topics can be omitted.
For more info on the SyncData annotations, please refer to the following chapters, as well as to the +LDLib Wiki.
+ + + + + + + + + + + + + + + + +If you want to contribute to the development of GTCEu Modern, please feel free to submit a +pull request with your changes.
+The following pages describe a few important concepts that you will likely run into when working with our codebase.
+LDLib Docs
+ +This mod is based on the LDLib library for a lot of comminly used functionalities.
+Please refer to its documentation as well.
Architectury Gradle Plugin
+Architectury-Wiki Gradle Plugin
+This mod is using Architectury's build system, for compatibiliy across multiple moding platforms.
+This is an overview of GTCEu's ore veins and the ore types they contain.
+Please note that these are the default settings and may be different in certain modpacks.
Height range: 10 to 80
+Height range: 10 to 80
+Height range: 10 to 140
+Height range: -10 to 160
+Height range: -15 to 45
+Height range: 30 to 60
+Height range: -10 to 60
+Height range: 0 to 50
+Height range: 10 to 60
+Height range: 15 to 60
+Height range: -10 to 60
+Height range: 30 to 70
+Height range: 30 to 80
+ +Height range: -40 to 10
+Height range: -65 to -30
+Height range: -60 to 10
+Height range: -30 to 0
+Height range: -40 to -10
+Height range: -20 to 10
+Height range: -65 to -10
+Height range: -40 to 0
+Height range: 20 to 40
+Height range: 5 to 30
+Height range: 80 to 120
+Height range: 20 to 30
+Height range: 20 to 50
+Height range: 20 to 40
+Height range: 40 to 80
+Height range: 5 to 40
+Height range: 5 to 45
+Height range: 10 to 30
+Height range: 80 to 120
+Height range: 80 to 120
+Height range: 10 to 80
+Height range: 20 to 80
+Height range: 10 to 90
+Height range: 30 to 60
+Height range: 20 to 60
+Height range: 5 to 50
+ + + + + + + + + + + + + + + + +Bronze is the most important material in the Steam Age.
+To prepare the first batch of it you will need Tin and Copper just crush the ingots with a GT mortar. And then mix them in a crafting table in 3 to 1 proportion. Then smelting to receive the ingot.
++
+ + + + + + + + + + + + + + + + +For early game steam generation you have two options:
+For water you can use a primitive pump +
+or use a water connection from any other mod.
+After unlocking steel (using a primitive blast furnace) you will get access to the high pressure versions of the boilers and allow you to produce more steam.
+Large boilers allow you to create massive amount of steam in the blink of an eye. A boiler can be constructed of many different GT materials, that will allow for different steam generation rates (consult the table below).
+Boiler type | +Low pressure | +High pressure | +
---|---|---|
Solar | +6 L/T | +18 L/T | +
Liquid | +12 L/T | +30 L/T | +
Solid | +6 L/T | +15 L/T | +
Boiler | +Generation | +Boil up | +Max temp | +
---|---|---|---|
Bronze | +800 L/T | +40s | +1074K | +
Steel | +1800 L/T | +90s | +2074K | +
Titanium | +3200 L/T | +160s | +3474K | +
Tungstensteel | +6400 L/T | +160s | +6674K | +
*L/T -> Liters per tick (1L = 1mB)
+ + + + + + + + + + + + + + + + +IM=l-E?8{LI+{h}6-&qOplDc<`Jg9Q1N%lOg<6y^i;{qynuOR5P?L$CVX<%&7{-xR-!H;Y EBo$3!RzuiNLz?E?mxM zB6}s !;Gip3CH6s&bItbH1ADmsD@vY-N8n=Mh{7Zw`(L#(i8*c90Z)PpiGlSK*(lyZS%j?K|wo^@=o z@UN|Z5IPr$2BY?zv^qy%UAGb1n68i$^ZX=D;UX!EaS1FY=JC->Cy}?P0X#}r0QDN! znS6MB*UrGFQ|}z!XovOsd6rfZ^)sv!xUzeqrkb`PevV$38`5p&v{2+je3&pMK$6#$ z%vac+Y|J 1*Jgn&Wri&wTm!XYlI4-}0k`LnO5adrAzL3jBe6Q$ z#VmgvpVW8JTk{4bxWq#@BeKU-R7NT^iFBl>u#ZqnJokw{zq_-1Ib*Uvd9DL{-Q^U1 z%R#t=R}tPy*V|5=jnjNU!7T)|mPjM|%*7WvZ*!hT*rXr;e !sl0Q?#d#Cjc-r zP1T{Ff$OEG_8*N0fED#~!=MpYasu28jXLr}!r|DcQ$7(1p(jEULcu)%NVN*bMxFW| z7ZsZjZ{>nWwMw#bvD<2u49;h_zFRr$boj4pduRI(67S{b*2uGdHZxNIu e@ 9vU2p;1*GyBcsCM23!qGrJTGvLpNtsb8MhLNWQblb$oj|&IK!V8*FBf-bi z)B%oa9dP`94JTfb6^>vN+_h(p-pz)0X{NeS-DV^Ru X~=ZU9eV&BB(4?#b~kck ze-E;*F*v>w??SRfgm31dtDqV<4lw`zN_8S!Bu%J&(R2M1m2Kj-?H=W7$UFD`-%K4b zSR%1@l`HU77=b|88fYdogBqOsx+6j2Zf}3cWrNcoZ~-e#+1RbDlsEGVoPe*tsxkP2 zT+33<%p_rp^Ia3^8CRoz0E~{FE$~34(P1qMLV+ C&OODXq`0uzWHPxka7zL!Id%-Z!J= $ z{;-iRzFj|W|2yqV=Fk3-x{IUkX$UX|{{G>87JX+e?ggfk;)tVk4z(ErR~~f$GQOF! z>HR6({q`;6e!j>Hx(=MKxvU%`xk_zD!&NrCl2(I#S>s0MPQ2G82xXb5v&u!@1kMmC zC~bvZ-l97;;x}oF)1lFkESDNrJdI<)##OV)2wY_)xy6S-w^-xy@YE_1@Jq%!ebX-M zRdoG1GXe-cF_o+RsH#KojpN#xqhqLX4cSI3D2%su|F1g?Gl?ojQnVOr}jL+XUz zL_E>QiX2K&w|~We$;qPvC&Pz>D;G2y4F=s3fJUnM(!{*d_7(?jY&V_<*tski%UOYL z$&a~HL{!WKZ+RPx%oH3ZLA3)=9kE^6qe+ArJ{*64>)g|)lSg#zNS;~%A+;VvqEH#L zo;C{5p^0d1JI?X2pkD#ly`0xgW-66R-;oFc!Hw IW@>86%!wOpz18XMeCpLM zth0}=@8iHG5hpd=W?=C7ZD!66N5?e?)i6Zcg=!28h8!%lQOwGFW>o}OnU>BiQcaCw zh#~1x303R3^fp$HFYlvOVq4O&DpBS(+h5-_&wEPfHc90T3j#s4$&txH+R`o^4|5n1VCREK%%N{-2gN>FSdj0WXL7cEgtG;=NlGR{`^n)R|C|$Jt zd7oZr+#@q~lZY}_Iw6`=xdB+%Je0)$^rb+Z h(p<)M(MCv>_r5{(Xjid!8Lq`{&m{6QJv`o#G#x^=tp9glD;KIN4Vk&1F21nN qnO& zLx{?O$eYkLvuR2SSCt-MZ1m#-%2(~g4;^txe0kc-Aqa^NaJavA%cNhBpdUpTuZt|4 zX@Y(mKO;rw{rGh6T&~U`^lk3VPzRCOWbyTo%d~78M$HbkzsJn03!TETs$qI(u9h18 zw22fn+Es4N_75SvZRqsw;*v;MP4aiGee6Su=`U&u1_!DN`PP3z)oKZd3kXSf9Qz$t zR#w3$yruMJ(6VLFR0p=dcJS5p@NR<0Y_;A~d~sh`w7jyivQv0QCfa~dHOhaojJ*ij zL4RPy_8+U3)q=<)szHKtQ;n1}S=<7Zj0 wq0J=PR^0`+yXdJ|;1*S{T6e4OPu*LSG)0&?
T(qtPkvM%P)w{+C-BK8H2cc1j!Fb1t#S~nunB5(V5l?mFaCfwMmbe-w zdAgUxC67hPMGsT()Cp0>`5>((C$cIa88 _XQm8O$F!}wAl6^cR_^vz{LIm24 $=vIW)xL&xih<2DSUiI(5?$^`k7&p(14W%QP#{jj6nYG&icD>Nic0EsJwiu~ac z^{w=cU@EQ)N&1pK)$*OjQB%T8?+%WZZ@v4(c0lnfy%nR7HO6$)uh3{7o+0px8n#71 zvd>2tYh}O~s346aKF!0)X&pjEgR4q0<74%KDMNW@Z-e>}T%lY4g&?E8lsJ$O!VnZ5 zy-{`Oqx1l&SkI=AiYi!(He({Rst^lX%v&<~VBl-e?OS9%+?M)cKCLO$Fk{8M!{ 2+8nt}u)V$4zsOL?ay`gTB%F0fX&iR+@|$3PDEsGkj4O5sJxpD(U7 zCA|1UlzQD=7<9uT8vfA5EYxm&1M#61T4+}0i`D}B{%=K|b*j|_>!}?c9vcyx3w-6$ z+_bbb5WsP7_G60=f`vJ^cMez~K}HJ30rQBqwl*e<_w3oDz@`_DBxU~#1reM4 !CsMSGYQs5CNtAAmv!V@VA%?ma$N7@JGht-%8eT*eT(4Z z4-KC}4a|>G0|p#F>K033jP|>&2IdF<<4-lr_zU js zcJ|( &gM6zY=!BJ3L3UP{{u4i3HN?+3o$uE-d6)4)Pa z%URXd!d~9Q*}&Mq*#LGA4$kv~k+p@rlAVREv(pEDUC$40ANbjrKe)qwdNcoX1q5>a zx7R=*`@gmLSNp%$dftM~jIa@Ov`CAIs=4VOKfm>}(bT(%I^FlSJ>5q`%GUnqUm5)x zDeFoB6z2E-JsG_CuUFYb`E9sBq}Q+g=|fd;l>T7%W_G;7eviCG%hTAn-~KdLJNs~Q zxpH{qy%Xnsla}l*d@Ec#cd~tye4VD=QEIbbKg`l7#&lj4EX2%_`oIT5qJ%_y-Hm&isj7wj zuP#u6Y2*I3hTtmn%$(1>Zu$FIq`{4r!-~sdYMxa$D%!G0aA6hozqLY_r~f-LB!;vW zIr@^{;{S97nMRQXA^$Vt_5T=gHZsjWe+>MD^S^iX9}gi-QTpEpeLyUbA$lNPdj9*Z z$b4bRX6xE>g(C2+x6mlBCa{0pDz#p!v>gKyJ!F4$7lHg=yESkT)F#+Fm>ULkE*I7` z-|wV)m)xsY+j&f-dNGEs-j98iu(7$HW!~Qedmh&d$3M$mai^4RmWk`!d%uUo^&I@q zPvx2 Xaq87`#qv+T7V z>SpSl2iqQxI;9S^Cygm)G4=AZ?j*&Lm3ZE1Iss2+dWyACxs7&PP9uxLR?P*oU;Uyr z{ASKca1#D~xBjndFNK%&fTx}mU&3CxK#O|y8NdG3gNG6#^JG?uW?tj?tC_BPb1J1# zr(uvUt4_TSD+IGf=f7^Ep4D?>J--r3QO)gH9bkq_TAPQu=2WTPRQTpz$%0O%?yQ5e z-<9P}d5}a&bnQv$?6|V(;kD+JKu3!HjmKlzrrM|SPE-gkvgiN20J$k8>z2@di#%eU zL*9CQGtS7|#_>bmnXKFLAXC9V5>NyjwNJB76+0eRH`+7j^}@a&9kl;(L6Iqq(I%yw zkpAa3e~(g`s1hRJ10=d0>E935e{&}OW3m40y!_uCuK)i*|B7}0rvUW-&(Z&fbF`R% z*0}5#mKl*F3uvD%%o!-VD5m!Cgn@!FmD7?< x=;LLd<*r!?1#OZRB=TXf?efQzc 83Q(&;R<}{+YgLAbQE1c#%Irc8MOf`Z=Ty z z2Aey~nim+3GsF=HJ^z^K-f-laUs_L$8}L{IEiT3aIVqm5=Db5OL7{Y|{Q9c$*I$8Z zPNePf_%ojoV8gD3p- Xm?$>dJr;R$S%a9p?C*%;)}56APT z4|ke`?>xxP4(~Sd*2Euwq)^n1P^TJzMDO$iPnkM#>uG0_pnoC2f}1Ow`m6PR;eG74 z5#T6 RP`(kbCFq*7H zxol!f`AkUh^sdzMawDZsX!6CThi=|<_3f>61po)-s(Nx&o_OXd3)zM=1sZ`28zo^~ zvQ_^Y(mm(;#V!Q-c+Z~6j3D92)I9~tJb5G5At*q>yUA}}fJ~PBxoRKL>2xW$#aid* zjzwppYY6yheY^%Id Y1% z>%eI3=B&L<1rE-2ZO^4ot1J(n;^c~S$uk7fFe-s*!3;Bbg0F%_Dulh5Qf5mtw}L)R z(}Z59KoyL5x83`e9>lO{xt2Methc<=Q*`U5WS|iIxBuC-{Fgc^_D?3X)6l6ITTUnD z{=)#4Yb$D6XH{@B^6}|0JxRA!d5Th1oWt>3#qr)C2AkLt`J&{4BYoHMbuV$8Pz1wO z3M~ro %N1os zk=cel+S_Q3x}M9{a(JkwKo9 !BrB3Kv2XrdzcSQ4NT|_U$oazg)Gj)h&YYU!BHs0KVaR4zxd1j# zK<<4EQm-MTD3vcYar`_Yt0RoFpdpn6z3U$W7i^Jf1P|pozX|TFCw%S*I<;uB*;u(y zr98fsNlFHkqei)}&~;j7vPl1Dlu^N1gvf+o>}&zV%t3!n!M;6+f4J*nkjsPD+|M^R z(u9sR5yEaLGOH~Jb7Ye1%RpCfgo+VKN(SShwA14>bjTYfv{)61rE%L$t}CK_tQcQI zyUfzt#<_674Zi@<+ZT-zYn}zjK-43mXNz9Qjq^RCX&~XGn=S(DaKQ`*AL|YcOD0Rg zg6HMZVG&BwSCJB)Y|!0HL3^v+i_0wygIisxCCK6 >RhM1m@^n* <44-am((2 0D$?VFXCI>bf z3M@5B4Y!xGDZK*kElj6b=k>~6lMoxoa bLu#^3}wbZ`*4gyXn67@mg$)AKX_zz_NRk1V~H@ zk}Rk;+-#t9SH?3mfH)YRO*zv^nROU3*7dN_)o-&1iR1ia@)%#3pLB z=g6!$Bt&tc^ol$VZXsc;#9u_eu6`Gif@T9}&Rcn0mWr8=Pg&Lbjn=9jNFMuTA)sL$&%3rZd=FRqD$#H*m4eee z@j%g(>iw7W)dftjY#N-6a;Ce)lyE{p9Z|ge^l^cTyfh4FUQcR3M&)C}E0v?^~Y3l$c(E&1dpLFU9v11v=?VzN$ zzwX+WR-b+*hH+W4XMgPMT=x_Z)=TL>%W!mW@vE86Xfm# {%u$;l{Y+PEV~VUNq9IKu%UBH%$cx&Q#@#?g73oSUJc8 z=S;~;dDhaFZRQI}&^`&im`F|k&xy+ftgSJ8L~NPfiJgsG@j29LV5=C|c`$$VzQe56 zns+;WB92JYS1xOGWiO72Z{~Dcha osjNu}53&K HrzSEnBT>5E zGX5b6KsPrZW;iy04`+vruMksR_7D@-cM8Yl9TOPbc8 #q{KCy?`_`pfJ0UxNxTFg>_} z)lcER?TM>Oq&^6gDS@;)Tw->G?k}{)1D|-0>ixdl)8i3P_R*I#PznV3cwr4T |nA22@lm{5Q=0qR3ojKH^?QEwi>HsZuz88qRT>4%VV{_ZLy_$KZ zJf{~86}i*8uRd5Wp=)8ZRO`=8A?svhGg=CgxvjIQYCAp RpFaT!t@QsKWTePd1S=zEXV*LJye(jhrPTJt=w{Rr z3ImV^w7b#TuCeOn+u&0gCn_>7r z3JT-zPH;z$BkW+^{^fiz1JVidAlQhvx#>z+l(W#1hTki< ~I2f%eKZG`ft8yx6id0YM!3i!9Dj@Z#s)bbV z_nI#w2`x+nh?JUn3GJzP{qmaujVRN_87KNy>mZ9Ee#HEf!Aj>PeSp5`g$ pu=0%%O#ys0>)%^o|zqOevBD{yw4TfYRJh`vNrt9+OIxm#>?=; z+VuHxlX-H=AR34$`zkzd(?9t`Zif9ULg^sUrZCCKa^nH8Y`g?nFu)a}m-g6JkGgS^ zb}q*LssE54fHk9|rNyX9Y);3hBVSkeQGM_BB%`h*n6vRl%*=)<(7t50@(XUUgGdVQ zVpmRjejMT07+@*-qd;(LI=73Yz=+qSM4y9Zy8AJnUCE+=LZMDiDEH`I7e+Z! zu&tl>r6xu7RRq|P)5W(+4+cAhEp1^sDe zZP}P}(DGwpo+&(4iL9$w!|0bR9=*$Xj+v#+x$6iA__@ujL!kW(4xsV)h1M*w3}Sju z{#EXFs$u4O2CChpGJU~RyuVnoI-gcvfRH#Z_}jxBBP-p!@;)u%Y+- A76OaRbv;7K#I#sL?HiG2-v&`AHEXm++kiAK}BNiU2Hq15!=lJw77MACNTw z5@@D66|XOY6~-6GKki^ ?SDcB&Elx*}JYf?M z9R6drKXzPw?5p9jkW-mH8(8P+7Qc?NUiZNp=&;M $Bv+haS(IdhqXj52&y93s5 zWa;~8)%}&*3tZX$!X&ItbiabrJ@)Nkg;~$$qUGC5{m;j7zw3QAE$_{$uTOoyb{QdC z!*+s)%EI*yP~n4tJ+G@5k`Da>l{b;)> AWmA<}8qY1jCPr z(m9QMV{fnX36%s9mh tyvh>2K3Hzu=K{69cpj#ZV%){!lzG^H`^T zobY@(DCO3AE=JZI3g+UE4^fJbVEn!QqEJdUsk^+4@Gi%T6^OT}KCclq&G~~P$xmr` z|Fzn&5nQ17 kjv5}?a!S$Ad?d@^*x*4YMJk?3lnQ#Q?cWh7!nmm0m zks5>M0>$8mW6{(IZZP!6L^FpC(H{L2iT>IA-u1X|xO#nFJid0VYGCzGb6IRVPU}`J zjGMY0$?_n*5$!h3cw3vS#uYS{eOX)s`rd($9=KVH6$8o^6lDR{Up$NqvC!atz-P$} z_(Z%1XT29>l#*-Fs0ZiN%+=9a9eW^CmSey~1LD0eRO!~UC~P^E?yK=8ATx?3)FoLt zBid_hM4s`H5a1S8-2hC{tiT48j4y3Ab zp|$5qeR!7tw);HG^xJm~UNC3ZIwe>6$2?>tgZjx1-av2?8%V7joCK?Usl(!F^Tmdl z;N(pP#hFk7&j d{M;&R^gK1G7;o={r8IciI`tc0@BQHLr )ktM*KS!e3gi>)hVQ~04HX^ z`e)nZvcxfIxHqm v@>?2jjMWG3iQ^(d~J43Z);KG&1X`O-Td#t|Alw zza9=d6ZQ8@jcz+Vs;cP`>QH;lpmq=?DeeUGKy>N#Y$!TcR6~|_VzRo If$8Brc9wZ2igvulHP*R&Lz1IzyV+?mkt>{irP5`7eX zA!((X%|pN8XZ%*7{rx-T3gM~66ZT-U %^d~aw(>F(f~^6>oI&_84*NC?W@J5z-F3p7bL0kyzc(r4PN>3F^?#=fOX |YB@emoTmEvNOTK-h`%0-H zntUQCvt>IKsqQU*Fo7;d2i~xOa1TK6oP*hwq!};5Fe>qsvQ#1+@HENAQD3)_NTW=n z|M=8Df9sD4(m_s9iXlOY-Q<@r*3{#6dUroVxvwRBnQy0U@~wP@{G?FL!3tT$UxU%a zsy1fwW3jNLt{M_;h4K~FWE4KLdacEhQ8LoN<)D{@#an4gL0jPa?k?KPHtU)8dw(|m zdh?~}0-?q_O8(2A8G}#I?aun;Pc&Bqux*U%x*7vukR0Xim)OnCm7sVUnajoSSqy;* zt`OR|t#0u0oqVRwqnd7cSm;iCiv8@=y_lR?EheYHj;z&$G}1o1(GZ)sz|2)CdP0h} zcFtUuQ$o?w@^|wQFX`q3=|tUfv4?vm1S(;xcQpRLhwlye%PlZoRijRxsPk_~xd<#K zW~3xF9*bpDQC<2(Eq1kQN#_J2cVgD3-inEpY#x+W>MLuj)yf06TuA>dz8OmmBpv4W zqzXDaBLS_#KNijQ@`e)2_vW!1M%NjY{gTNrq0#k22S)D%DwbD3F!D{ !rfs-K E+?j2nf>er_3XQDdx-HJz4B9l@4a6)OD}z@c*6=L|mDC|B5)wV{$VBOS_7*r^3$$ zsmfWKL+rVV&&TrW;sE+bsnWaf{L8pErYaD7b*1tn(vyZEF+JUG&T@O4-IJq;v4siU z(B{w?37^T&PwqPK&*UKNh@UUEI3TI9BoR)?w1SZ6%pA$Z>x@5fN0Hp(A~epJ0nkfb z{+TQ?`gi8|Y*t8N#)U8b$G@J=YS}F=d7f6}g>82Yxy-}q;*edDFk&S7xani%6NYJ% zd3fMD %J-hYg!tEPpOYEk}N{7A8=J5qe* zw1iHgZq8za8r)v;mW1Hz+Kf-eP3W}AwnN}-wEIFg*!M7L-kpjBx>8zvcge5L-J0@w zb%GQ )`eQs(#F~=H*nvRmMt3@|Q}el_2*|$-!a* z6Hd%Jef^0rpJo9 iIo5LEG(8Dr 3nM zgSSt$AV)+Sw5TW+Et><~HLAL-JO#Ny*^K)lyrt3nay-?1n)x`sw=#L3`{Ndqle9S` zmRveSN90~xNER|AfmTlH@DEyJhUSe@C{E_DGvUt_H9>tHl2w1GsGKw?oBSv1r+tMi zs3UjG7}F^ahgI?cGB8dn`8J~aE3BsTPuN2Rcsx+q5aytXler7@>4K5n-q2rt|K1 hny{K_ov`Q0aB=M1Fi-w8xYATr?l8oqV;9tC|qv`^F&_K^bj+bkkd7 zzPbAxd^XLL(_uR^R?{j}5h@(A4^d@gN_P#s*8WX}J6ONzRL}9}3#RhMBBO+|91}I! zhFBi|q(@Ki2M8|=$49dguuRQ!Rl{rulO21+K;PZ(xB7*bOR%e}brG$R*Nbq1T <@8%*cR!O~e!>6<#Ez zNXPiGn+A^TJT|rZr&U? xf zp0r|`TM2A?BY#I8{6$ll7!Q5LQOyG#=KjHeL6yaqcc<;TExA@18Y@aa+!3f+teOO} ztBV6Uyw9e EQ=}z0kiQkFKP-(Ji zMk$)k*=yEKnFmkEoLb!}Si0IBTrf<^e0CZI7XNELS*?kV!V7j1aumJJ3$#d5pboF4 zkag|MJd^pu7rwoAZurJlMw5V%(@r(L^y-{u`(@f27O!OcHV4sOUuSZGgWiXGyv{B! zn;9{z^K@#A_wMMR<{Y kBFK 1%3G%CAp()j9}}`|&|(xUB5QhjDldi-0^I`(T$0&v1^w&yiJ9(EGrzx9>=N#Y zX<;0ti6IS=z<{5LK7WDUI5{MC^K!zET?{j5{wdY>!45Ks9Rw&`7Lf3W6t3)vu$8 zz;?okQP45G5qqUVp9JyXUrKLblVdEXe_p7ei84?4QUH|+SJVW@kf?C$;EvG^CErEM z^K!!sU-0tu4B-S14cUYhY)or$D$M0vK94E=3CNT=AZZLcdOLdxHieZTLG^(4uTKLW zNb$4kgFvL@z)7jgccJe)K5t)Gwj;KC15K-SQYIN^DL4c#WKPTThlcrp?5C?I<>iKTwA5&*TFX2TFC=m&C=C#C?9>pKa -*h3F9yG#~XJ%ycQ_V`wgHEc}!Zjg9gcfYNh>3uOB@QT-P0)jYTnp0+c7QBa z^Z9Ce3B1Jg$tEJJu+jU)`euQ}=0Ry+1OKZ;T6YnfsqcaLdo$zh9E+AdiO_JPRIC(` z)YSL0m0yoZJagVPEo*onq+ HlC4pydbHqd7CKOxEUWm5KM zWkw?-00ARIIrIX`O3#=0S-EUZ6dB9MRsrjfBD4)#;nK~Wu&(oJ_eVtd{afFM!-= atC3Fha`;C7)v@bLuO= zFTXmEhWySIWBR6l2t{o5c#heqZp0K!{KAb#sEkBqJ4ir{bo$MU0p-V6%$gr~aZ=TL z)jQX2SK31#DmO7F-;HDvgDl_LkbOEhK2xHubl2Zr?Q-`gUl33Q?RvpzO+&sWrbo*z zvc$)sFy^QR^LNNH&ByjR5^S~RZ>=P0IlvMyX UlWr`v?qq~SbuaMoQAh4d5dMIw(6 zXUhvJk9PSlu=hDFQ`}V}in|~MEVn}Z-)tiz6s_TmgzZ8LZdoYg>d6!@hj#N^eWZzU z4* P75ez+}}yg zTUz=tE*a&XJP{_~*j&Sb@GV}BRKd0RzKWh{sH>5dmTc^`xaqs4UZ?!)i WD_j8`?SnyDyTbFL#>9{C+V?X=^7IzG4#vKDTAYnMRvC{LlPyXM8B*o)_D$L^8ba zB^xZJv) 3fdBS6% zmLeU=2$3oGN#zw0r{0E>X+-TyN%)QTj3Z3SyJfgcTwV583kzNo-Hk||qUlsO;JJ34 zeu{=WOsUCL=WVlE(iv@q1binw%UO-m$#C25$yL70H@9>h^!diiy~DM&R0Yx`x eJ8{T5q`tam$DsZCkr^U8??k6f0>jY9ludRo{`DuDaLv+#!AG|Y+j;cw}fiimH~ zFNYeH=uW0DZ&BH~douBQ=w_XjDI{@WX$F7A)ormv|BKjh)sMbBZAy*eWO9BXGl8Nn zC<_V#Q( WFe=^}{xV&&{jm z7bejo>&$4{%L(%;xv%2)F^YK#lSb0U`+{Yd8l5zlN%AsAG$!-K+Ubs008NGt{vAb0 zjRB)_C~7%j#~^9Wq|Lrdd_yUL=Svz!+6_$!7BuLAm@3I>n&S&f?)Swva#-=djg;cw zZ~?T4Wsodj(qW##qzny^O$d5-ltVU)8T1B`5tBc?j9O?pSE|INUMUo}WPz(^9v5CX zDi$YfA|wQnr0^;^s&k}7S%V`-dtP!c(}+B3irBnz(hNc|Jb_c;<#u%^`6ra6H)v=P z%$P?6zxA$}-FSy>rlXUoy^-6sgd&xKvi)jQ)}m1s2Q=^yKpQt5I0(*VHR6qS0BNhA zyZeoJm7h<*$`zKzj_i~x46pfpH8bN;KXzJ2geK9k^J6oUtLI=#we^e`@ny(2E=cxi zN_xCwmueprWmft8R%WbB7;KHKGc#@80L_DI@1O93|AF|v)hXrGMz8R<5Hv@TW=!uL z*)@*S%Nl`-l1N+p3&cJ}X6|wVt^pWAUf+4YTN^y{o<9D#{Tu+3+x}*QDH9oN= =s51+Ec{uGfL8Dq6+!zie&%w5l$#-Vw zUN!xrwG)i553E~>b8SL*m$5pRrU^OyNv(2fdc5|55<(5jbb$erxK-bt&DeiBe?K?x zu6;RLTO;*8q3FPqCyxDo6Rf1oP!>-jp$2ik>P|d3+P~j6_ZY*Vv2@-{>?B*ci&D@w z7s;QB@Z0>(Wg<^2M|=x38{xQ8Tzi_+5)U|Ji<(j}s47?L`63)EtxJ4pN%THMyM_2S ztPDVH2g?Waq{eMx03?USecm@h`OTJ@2p+j%P=wEUVQL0hbs;hOFXbQIGS9v0G5lca z5!<^7u>)9r%Po(kx|+spCzu>Yn>^uVMm|d`4#G 14+@?yrzJomVS_1%Px_tG|Na zyYH7L&AT#|^VzE( Cc;>;pC()?;R7XtqLQhbs9EKe2O=MV<|ga4%z>@)g7#(X%pZ1tss_u{YX4 z0~umWD&pqyfyKVBMqMvnPLNjD&Q|pH+sm)Uf=X3b0TL&lprgjr3{+O_2M0{YxKi^B z1`6KIVrC4Zk9J?a7cdj%6gv>+Sp2PCA8hpYLAv9lOquOMeawDAUJbU*#v=D3@x&|~ zHpQLyuoW4 gDXph%P`Dx7re9Qv(t7h)hp!}3PUFn*&@5XaBmQ}M;? zC##cmn2w1Vn;lxAZj75q&-kl7Gkl{4-7s3Nh%$iqd!pKS+B)oivyCu}A0tzm(4XS? z;SI*u{9=)>pxU1=+@eq~6{)^w?7%GNQ5ofh6#`&pK5aZ}i`5`eM|-*C)WQu4)J$|r zh&3t9A!z|A@y=f?>b`MoDnXZq`5ns){_d(Q4_jNGLAgX5Pbp`VZ&jZmH<{d~d1!%~ z5<#N6{8%6VBr0(_$(n?2N;78Tgw1}a$VXw> wPHzqHdZS+uz&d=)AF46jso5EL&>Lm&^uJj?wGUm#M+u>&5hMrd?6BM Ro#1QF^khe^WNKOYt@+6 zuRl6`>W-&D(Z0$}3NVWJw@5*WXe0>Y)*^yw07%-wFsHi;m({8kJ~Sh7r O}>9w*o&ha&<%_v3TP+usSum>B*1<%ra%%|O-0k> z+C xI0ST zZr5}K<8xVZli6kiA d&jm6wA02P>*Ckd(7|Hj?$PesGlWdjst0DmvJMBr zGM|5rjiFw$lE_S+o@i4#dAx)c8V;lGrsdY^7AMvfRqt+)SupvmzkIP#eGM|ANzjyB z>@Zx0fBLVYyroqD5}2=DPjIu5A!2b_0!Kzl;jdAY_>NOj>gD}XsfJ0ObzDtRc%6ww znRA+l=uReP0)xpn1D3as{5jvqjUdxOi*kELO?5i^4B(m@=&g2;j`ndoZ9}PRq02i8 z_ &L8`% rWdn z*^u>25w#eVFeH0b!A@qe9KNQYhcJU& 8Zkf{i~d8$Gh*p zjz0aZs@8t^wLUl5Z(hz5fLSxkTW7asN4nU0>zftedGpi)mcx+=&Bh5DF*c13M+)G! zV|z_sei&p>Rgf(N%dE8v);k=#UR!lx2BUB~(vMV8+Sq2bh}xE`W4Ms@*qHlPR7I8H z8^zBrkNi4(uERr?H|VwM6$&IVK8~(l_TphXEsJFV-oyZOa>@hrkZlf5<;
zj{T4+^N`R_mTpZs@1>?^Z{Ui`+n)j9MBZex)kfIGVSlaKvu)WA8Xr-%T?f*tm*tq} zUmso_Lb6G#J!08oDe2EuQgxjB3v{HID6d!4u_5UnRmKU95^fH$UdHllaQw4*fa^2u zf2Q`yVk_Ji@fvX7jT0A&n&ljJ+Q;f@Bft`wi-9{|)S&)f)%Ivf8@0|1n*8tB2z*Zl zrNcYyq #hK!RrUMv7XXxNXdT6@v3Cy|-FSEQwK5UmGuB}l(54^9dlfYnLd_?dP zo%|gZRge&Axt_58Ov6ut*gvxrbefh?ZVWQpsf`L5e;gO?jg-!FuQHl^*oJm^|1qHz z+1)X;UGO~nosWilkExQ(###2}D5fEmxl(-}Rg>1G5szR#5P7npNS*0NFuQ$Ux!SP~ zf2HhT{X8Eq067KoC$1=4cjm)VYA#9mI&PQOtmQ|b_NnsCqq@$I`CsG4Cp*%5os$ZO z=@CAEAkh!n`mCil+WPtpFR?Jzhj>A45mGE0LQHv0e dZ+6@!hz{ANfw&R4~tD)(WY9X%)YIr$td@<6U6V z^kTv>Ou8viENAU>xz6<-!qQ|ZT}sX gWg|2FuLq`rRnRW zIzyAEDYWnCDYWOuVJ4hNSSy#p@Y^w;pPW;LEGo0bk}&KKj0 5^wS;HjQX>ueUkU zUC>Dzf^!%G(pLJoUH;&VJbHq5N!}lB*Zesr`LltYK_Gnm<2(fV4S7Uby}lE(nY=hM z@$dj+(LLzYhS2kJ`j^+|;|L=uVzL11$)}%Y$pnAP&cfRtV~GtcxxFxC=R%j<{-FJR z`66KE{4f=EzS_E m0_? XD>4y1DB# gms6I|jvPpSw5UKRwHqX5+c=lg-u z>&2Jr!fh=XRm%R}5*Zzg-wT!|$~v1KdE+dslBtgZxhxU@@7dg^mII50-Ce+l!UzVT zavWyP0fkLy`G}BJUazDMZ-wteU#A%Oey3A|;zm}8@HyPMMR_t({bgeAYoDgjt;`ZP zQTJoE3rsxJKpLZkrRb&~ab!@|1N-vOZ|Wprvb;w9`{b;#cN0Dis$j`veTSJ`9LAJ2 zubW(Klu8UTWf09$&uqeWp-rSX6B(j<8&U%LCAUEaO~&rp(^TV%&(7P$ *$ETLH>g&;0ZF5;&0p2GP zOx^}bY>$>UC#OhT2n(`rg?zu)P{mWUD0Po#VuCLG{;FRC_R1?LI7TM#;PV{ZPiuhE zd+_M{=v?gcZ1SaYmw>|RT+ 9%a1+`1DcbCJJ8u*cq00JmhKn&5nG$ zFpYP-vTWnxXednij)QXY+uoAA&R=#5JF*u11N6!=f#~FfCi|S=7QP?r7BUMK97fM) zU|*_YSY5bR?aBeqCcGDxsTQ*1>U2JL_s1~+^kEU!C_a=Qp-QS0rDO$>%)og0hIx{e zp|4C nD_* zsU}@aen@nUX?{0df}+c(vHTvq<(xm&qSlotibUD`H|cwoFFHwCpv=LkQk!E)n_7(> zCO#^bNhb`hdY@E}qHW s8?zHLQbkp+WG4cAx+BcB+|)C* zHPM((IX3WY#BjY~By4`8td~T#eWBTgXuTQh{=or|e}p*)kJFT*#{ZZHW2hBEeLrnU zj!JU9&G H~QRP|Vf zFEEm|@V8vzf0Kp%z131~N8jp2f3c&Ela}5ahm)>^K }gq1huL!VE#mQ}b+)Mjd- zOL^9({8)TWYYVHUG =e=fsq1?(MQCh+L zGAac1=zwJL4> W*81AAn-LeS zZ-~^x$XA^f31!7NlDK0^wq)kb%zdQHi!4(Re(9Fg6_+V4pc|cq!3t|-Tufkbr|4`& zhZm1Zc*?p1_|D9KvrpO9DL?J)cI>OV#QZ4T`LWJ3>}F}iRPy#nLt6VMffV#cZkkc| zV)vyIx%*JA^+fS`Wptu2yxL!BDD3y6xxayIyJ`vpoOfE?Bveotu@d>fUDG~_8~>0% zk9ig*+OAtQ&F-)Q;Wja{SH3dErQv{P31CJ>p4CeSO|nRCSAhFYZq8o@?j!HLWr(4I z?k}EQlAYmQ($&k$BF*8W+@4jZ;{nvP@fZoJvB |kcS1xQ~3LC&G@{mh=C z$ThIl8=pQOANX*B1(E{(-Mbv~Q&?o=$zc_@Hlm-bcQNAUq&X6g#!0CKBh!PaE{VB= zh&+1LH6;MPW4T7{M+;GmQ_<|KHA2q6r>&DU4j|K{-K}yta~i8P%|-nuJ1f*A)`zh( zsw-VRGc95>4Ug}*e?l{yLbx;P!P)~86MR;F* 6dQ*Jr2ZnpYozfzKdji2uucBMPhuYR$e2y71H-}F 23uTWnJpNp@(D6%$$h9#)*FW_#wsF<3GpgMKj`^yY`_M9FF(g*2I z$0JoT9y4y5%q)Y3xY=?H^YjQyRWRJ7QY6)EX_a*{>JeeW&+C6Ap4=fBGT9PQv)?h* z!Eu1%2z%e^bYgb=5Af2;wa{HDRUyICK}|Ig&?GV3xB(4SXrv;thKHYv@Uo8U6fOBc zD;`A;bJ4aeJ`4uw{yy;Oez!9@g~+Jv(1W2dsNUpG9g7_El7UWIw@khSh-1MRgR&c| zzL%H#Nkh8ws!;d@YlnOiL+Q%K+`8}s70DVN>RIj(YBvFq^Q>rLdNCheoGTR 8_unc0EguytjEOEs^N0G)5T3)%XjK0V)rv{t1S!oukvte$6|h;6+<;{X z@Vz;8mwCIbHT9~F=$j35W os2O>SNXZu-3GA6r;}zM@zI~QyBN?Hkqh> z!c2FSQmC9@n2TLeC?seb3h1$7)ccBmF7)_1oPLbcbai6f_g;5mH_O-lQ{u}(?n{(< z@O|mLh49<9wVY^=3L5GTZjtg|k?R!@SHwvKYN`HG?M?gGW35Akei%dgOBYkd(0n!d zxDAxwT=ir=2gN64Dkot9h<21wsi5Z4Avr~br7RD>2<$@Dosmf5looDcL_^4Ou(`1N zfvZ!bv%q+^%;+Dok1mK`C<>Q#B6j6lpCwqy3e?m_3#|pvi2|FfpmtsiF0hyN5}^Bo zy;}83mXDtq;X59rHN{|=&&5NEIoHK+7_)i>gBjasBD1d@MRJAg3fX3dY^d* {=+#y(S_W*;t1$TFMcMlTWof+Jn;12KPob!D3 z{iCLenmuc;-K%%^eP8|8N9fAgN-(JHO7#T43`x}kS@V-ETsYjeUzvHr*0TPE-mCgG z)WxICRT2j8X (tz3PX&>EB#%u#qgZ|St0(_eK1fK}AS6KzA021F38HUy zT|uK`TRzOmncW3%il>7r-7oS2RUkCYf2w@tP3kZ0=d$46b-=hQwcg<^N)r;A=ieOB ztBt#jQBxW08)>UDHBeC7f6z}LqEmvJ4icd?`&J|NDy>VVMw=FGEX~goSlN=M#$S2X z-%q{HjXZOSggRE){|IdRLLbRhPk)jm#naW+4p`* zM)^4DAGJVK&P)u$z=T{tkhsDxhYp`OwFi?HZSRQzHs+_hu<@W% k_HW?0&o|YyC#{KWNa|f1bQ<_qE Ew zu3LuYONgnfvx3~s#?H2i6NK`!_72}NSCX`-dpXSm(3W!r%vd`14I5l!G#bogno~iN zi~Ofy2aDO>LCbNNBI=)@XA-xYI(=|R*uEowNDjLT{mL&P41i{F;3vdH6rL#c$RXzz zDU oVN_-Ioskcy zj zs`sf<_m&F%Y%sQno?&J%O2v8-zV}CDQDXAYB$^ZoY}j65PD)(WZ_ic1D$t6mI5b*_ z&hd3M*usSwm+;2>X)~sbbx4sLo+Or!Dy)QN_lV6gT=QD;P8uemG= Sb|B^DI7{1HR<&G`*6Q z#CY^157_T|ZT3DTD~IHJR*_{|%uAYICI<=MDOOJ(hAO8}@+Wr;xqGV_fRbJ`?p+<> zL>II0^?u1mO%84jDl(pz?dg7Fey}FjE<2gGuSbNkkDxDXI}^eRl1^jr6IJZ9cWzk| zk3X(D=)Jy>ec3H%@n!7+rOc1O9U@YO`4Lp84ki7BdF)cW`GE%d 6;WB9TeJu;7A1%BbJA0#)H!mzcc-V_XpD-)e|5If#U#Aj z)588GGc_X2$yq_rk4lm%f@E+R?w?WBYk?vvy;ZPE6*!?zdn&$9UxMnqnSWuf`|)g` zTAJu19Zt6b=OiMT(!yXMwxs7_Ox*6G;M+(b)G9a7_OzoT!l`m$Sl$YSM-4+O?aJJU z6Omsgbyyz^)-<<9vtAAk3MbuF8IXLVZ)5WQDf #w8!ImVfd!V@?_>nuygoaVN zNbC8J)y*o64m{a^guJixD)l`@@y3lBdpE?rIRW^44RJFix9({{8NjS6d&U+!s3PQ_ zt%LiAo7w} jb}ug=-OUv)*%@n$Y{UHI~{_)1NxgjDv+$5o|XX1ZYd`Xn#jP3R(O!M{Bi zAW#4xxqZ&;oG#DuFcHCX7EHgsV#(&nfhrU>^@wLU1TX%iTj!kc57B2Yq*i@~XSgBm zX>%o_nnU;CcF~rKHd5mJ?HcAw4CE0f_#Of)O(#|L5jFjxS?|HjYDAhkI7*$Zkd`$W z6i X*Q))Mm|4Kh%%1X- z1tNV-X|Cmrv =7k69uV7v!_5vfG3qf-~z`rX6gQ )1}mX zOlLkSP{WR*n5XS_c78~fxS}UU$xJYOxcT3kkx5OVZ uE;+?Q{2rA@K`}68wJ}@{( zJWI6dflkH&G V z0lj6Dt=rzbMI_;U8sj`LM;283 FV^g%7Pj;f+Az( z>9z6^lY9o>#q!5rGLbr=DFsyn@$EM$xO8(9B?A)KT&D3}I9UOm5!MrmZk_Xh?eFy# zXJ19Eds@_;6?iwiGG6i%QB}KpAIe)gHrLRF@ckZE;4^;T*> iD7z0kFri|WV52mg(?lE?!tkrDvZzMsYwU(2xmbCl7WD~zf0S~;7| zhauLjFsGS@=u-sFx(Qp|L(pzXaXbCd`H!ag3l_8gSlpX*0l{+5_n&O*`jE9$j8J8L z6x`rT%GY-}JzYMgI`DMR+=@4L`HE(;6 XMpl}-5D1lUoUQS$O>pM)qi zfnoclUk6JT-v;Jw2dd*3(a8kN%~+Txhvim8x=T>`v_2ANg5Sa8=o^j~N*N)l!;F)k z;_Zd>yEdj2q}4wiyXi+K)$!{DkHYc >CckQG`y;CC=2Ylf>gTVWZt=E z^&}h%cC7DowS8|bU469>E9@Bx)PlOb`;)(h<{*LV*S72Hc9cW*&&k_YGqguu1aC49 zmh9fmSYD4dlnKE>MwaJI1i>>EbVx?8b>QhqvapXA1YTxvwVuw+D`cJ*Q)d1&-4jnZ zq+0|s-Q7Qx9mo;;|I@bJH>X!{J2}9TJI~J6;*t<$Dsbjls1nwxY 4nArK z0Fy{Ch}lfvcXq}K^0Jblz&BWwSOp!%`H)w8ZmLO4hW^+LVytkuLUucqscM>EnbOyD z5&4wmXzS!R9kic;qw8clTvL$2Rf`ymZYteNHr$r5`m=8>UBj~*6xmnBCS;%O?gl*6 zmi>@hWNEk?uT_&u+aIO1JC6u8rP4f|N7zET*OBFDK0`K9;Z 5MiglL1f0>$O)+0U{akRfv!%86@>KWs>Y4J8#;4R;+tnL7)M*t6`gZ1|pyz^no zb+zF~n1%?&3Zt4p<)Hk~!w=Wl+7 zz@k^Tozj=GmC-{@ZEvHv>hPKUSgx+Rid%%vMcI3wuqLSSV^{f{<5<}c(3Wz4bW>{= zvys^HEp$1MWvp}v^qvF5wU9ZGR|iNQSkMdg(Q`Aq4N%%Bn5dHF3#<-@2Gy0Bl2=6e z9M+TCtTSJqEvR+9vm;^q7UF|2zB6fi-zGz^h;6y9(!Ff&Bbmzk6{!Rmu{-8fH8(Z! z6f}bZ{tn>#Bi4ivzNf{Fc74xVKT+|#Nz(j>$iRP$q}0ghEThnbdWt|Ipv*+hyk%10 zn4eetFW;ejPV$gSy0#*9mu0{U0>;wu!qX7z?v%UkAy`^Mxf+2b2R-?lPTnAs@~8?| z?Wp}rojkB7e->AL$e|Yhl%S_S!cE<~y{Cr}1YX^(Uba35#ZnT=UT)MHc^3tC1e82B zhp-DdIX_2j+VaZf(TU(ws^6`=y{^U!nq l`%!%rO2A$vv@h;_T*94f4{dtK_4Q%u1yTZQE 1_e(rIf4=G!`+f-Ie;dG{smfOi=OYZ55{d3 Ged=rgY+>gW6A z)u+*0W_lzv;Fp^Z)IAn*7!yLrI#%~M2wVrtsSi62wLgdPHI~gu$#7Y4I cOD^xEoT-*=p)vxmde##m`{qn=oMM1rg7sTV7s r=9@}&pX&Iw%#ZJ*P%PX`Sq;^H=p#qaOvK~1 zB#QNSx8O|r{e;I^13-0)t#{*_v*(r^J3Gk`&Wng9jcDKiB(1;b)p#$|Uh2YK-}LrG za8w?m+WIDJ7Y$*mWi4}Cl^AxWR)M>6IJp*UN$+FeciQo#GU^W;saA1w_N)_uJ=GTl zor8~6(DC~)Vyls( ze?ID0-+S|tZ{Ie0n3;-^O31oN##l3zQ=`UdTdE(Y=8q<1P;-OG&0V~k5jtWy|D_#D zmXs(*n^jnj>oPfB%g2%nbW$A$I2kj=&Pyv3$!Hz`3X9;p9p<4Q{ba@RqagOyST{;$ zeZ1fuV`W`6?usyYZ1=hR^j-Q}-+v)&p}VKm-mwZnEwaR!h9YOYu4cV~KRh=(UkEqW zNjM+gyzlebaKe;@jDx-FT|F$WJ~4BD&PQ#Y1>ja6BQ?C?K6CA7dilxF#%NAXB!V|! z+TA>1jVSQOoXgx`!WA3KBXg{q-p*c3+J6Tg=~1)h8e&dieG5Pr5oTU(oK0jxzssj; zB0lGie@{dT)I=sofIp-2Yco$l_njm-c>0R1j;o^j31VU?08~Kw&M(xgUyPw=f5)7@ z#1syMb(%pG`ReEMpS4p^TftG5LD%(qmE<*HU!X|}>!`=yO^+Ju za@Owb_9scuTCgRXemn;bvi{T#q8w{(3oU!1W67xV=$7+qv0k*4*(4x)W>l`XnA;^0 zT&iv*LU|SOa(0^o(HGub0{BrC(F_*7Ts9qekv-vJ2dbjU9SlItr(%;H1M&Ie03%+P zJN51Yu|qU_y8URK$ENHxQWru$-sMI}V&KFCHM_><#wJ`Tph3YT_@_w9)J!Xh1Cl|9 zA#ao&ZMCJf$oxb)S7O X8;tld!@5a#o8q)S#-h?>82Cj5{Nso!it-jk)r-7bbPdVoogq;?3eAt zM%6sYH}vA@x%pIv-6oRuIasQ}qOl9vtud7 H?ee5z7tP zmeJ%z=EQRcFjIE{vP^&`CqFQHI+yZY_HAz?n$@i9b3<{8;?#l|4)9ozTc^2O>G|Z8 zePD)aC*x9cS#F$e#r1Xobp#%sHS0Tvc^2;ic_)i=ZxzCP+SDKPXI=AfaHNn+(yZ)i zzbDrjeoCVp?ut))k8t!u#XNtJ-AjCQT7j;}H`xCI{%W5WI442##kcGjWrG61D`CE2 zO3AZ204}-5Z!hLAiGf*!%-m8-K0Ez>);MMIX$#B4X;ZF5$-YSQ)uo)dmZTXz3vSbM z6@0}K`$1O&vLjyRJ1)ZDcYv~Ew4c9TTW}qC(^909YDjrOQ}QO+?y?6_HXbTIWc!hB z;I7v7$wH_*4|I^9f$uz^aK=1fSCAZ1SlN>CniYps-#N1#&>p9hLL~*K;YDT#O}$u6 zrzVn;wpccXYV$#5a^}{SY`@!RPFknN@&As!>ZPZcI->hv%NCjL8>%qxXQlD%svJ48 zAutMfn2G3?fpE$qPhVA*nv6*=p2)k6RtGxT3$)MUCWdkw2r~CiIy8M{93d@etLo_O zE6*`DNgcHaYROO%T|=wWoZqXh$JmVKO05YI@$h(?o9EtzJ9}nER&D0M35BfOmM+IS!Ds9Y3?aT=ffK*N4j=E1-QFB%Ci0n`J}Pcm>MphWig8k>sM74@mI@ zG_oZp8&aIPS9P)JTQtF%b2)OfOAUV#y@RV+P~}`!j)$@A46*wHswxkxS&rlhb@zB4 z|FR(D;|$9y*z9@ID73^WF5~SLHDsTaY$M9i@tjxWbXE@7t=VR2n)}|U^qZpiEx&st zK+7{y{9vrTD<_j;5 jwo`W6-YGS=pWq>4{64~tc>^Vcm`D!hJ!F7@e(XI!RhDfEz+r8QH4)8( znmRe!$;{%+a?zsFYAfsTur!(`7!NZ0X_0;j*=)@s%pM?Y$0~9sVp-8F3qyc{*3O6* zg*paF7H63ZD*PQ8# ~m_x>}kg z9R7KtcSw5jrP1&HkK-i&sC-}C6x YPz%CI4yGZ90o5QVL#HivCj!O+jvg|i9yY>*Z3qTLSf zetvrBUUsW8)@J=BwwujjIjq9@|879rCp{B36k|l_7I*)<^WACScC)0LIdz#rgU9Kf ziT$e?*4^FLwWPnD%dJ EY=2i=vvo!C+KTiy1IR!kSl z`QfMN2(Senn_z2 e@*uc<8K=N>5@$_`554 zZl?Zv+b(!wHl*eMUjQ6~p-6iKYf2V9cka-Qhew+XxyM*LEAZzW11DeV+mZ%b_utO1 zrv7THaD4g07uGnIcbDy9NY3?VW|~D7c*mB?W6V&&mE(*wqBCE!fHuMj2SX~K;1Qck zX6*4y$Mo!QnX^uzpg(;otITun&NRucDUdg0W-~^YFP=P2IGWX}?UAT|el;uibz?NZ zK;Aj;=CHrq1ngVPXlKI)P(+lL6TDgGHkT(qXz>{d+%tJk}z><85txCcpV zCHfdtd7IksXJoJJ!iHKgK&2_8Z6~`ztse)wTk6zs;W+3^p_^`a;cdxg`B~F9n&*>C zuH4lCrWBuQ&ag{<>ls6uy^tl@gdr$5;?fZm)QYZY#bV((ZEx|kzO8)UY7_s^8}gns zbq$_|v-=9PM&`KS(jRZbBF>I~$Z-!je@)4ZTL}K&YJvlMzvnE{v!UCFU}R_1sIBy^ zEfEWOPyJ^# mZcAKxpF}mjYO!S>5PoB#%bOT)*|C#O)H@-IsSUtLn-s? z^)Co#s%C%RqZq5BV^wn@`N*(>*6c8e0f5wp zCMUYz!HUS}WN8u=O#%xa4RHLtAx?dh{S6N@qV-+Xb4?u2>=dUq&U4HrN`|&Chna#w za8%9qGW>!{-tX(j7#c=*S5=7q99x46PZYXYI&3vRr7QMzRnn(VE!T7gNlHh~B5FLy zNJIDJ5F`+E-F^V)DiOZ6w5-tga)-sf;yxALR0*)zf1X?5Xqn$58E7|1dUD&CsiK;f ze*rQyX9uK?5c!%2bzHT`1$09G-q8)`Aa^O?v~lJ92c3v5lZNzX&}Zk`)mmg43b!&Y zVPWiCJ)J&O8IDtooX{7+L8i*0Le+3TcV$pPk!72BdcnnERdXPm{p{#06F=0h+r;!e z$IJoaqC?@}={;zz0tFo>U>1;_m|iRN@{>Ql9}vubmt}!|W`=9%gbfMdBiieoPCx}t z& OqKZzi4Jh|O zFwWMf=t9x^GgT% wxtDJI!l#D+I3byob=8Pq}4p+87gnFx@3#@UmZYXLi zO^-HlW8Jx7t^>NsyoCRYr%lr6`m4!hbbfvo5fv>bnU3IY18}yqW&<}H4W&&^1+F bgm&3V z#b)E! >#1@=U z91C>UU;B0k*gRRxfi?KSFf7&=wcorxl$!{r>gJZC=!M0Zy{##DYk@~;M$Q+Q<8Qp- zaXNIH*rRpNxLNMyl;sE)miM=~7Xhk7ii%JsiU)PKhW{G#Gl^V#H^*a$%kut$f%gV4 zIc;Yjft3C0TIGeaeyUg5y ?u8_FZ00s9IZm;sLgXeBlJ|as zG4PndlsxHpvB{IKS&1T^d7aiKcJy1o$D^c^FRZq#rg$>ai?|6t%ToI EK-B}e0ty!H#PT+{#UFyvGF|n%i-bD9Bzndg z=L_{h_tlzEv&szk-y5a>N;YQhvkR%s=737?jc+F3o!FI4RkIyoBCxqY$>Mm<+0>w= z nq|eob$#chG$Uh%IL|82t&$b zlZlhzVHoGqKF8cTiPf=vH>+>vbmxS? 1b|P1f__WE|r; _Ga?$YfUG|##VNu@sPW`vQ(u|=90P>Ii= zk8RZXrc1^!28JIc$A`g^F8rJzNx~~&;B06OwzM^vw!rew)e0LZ-me7Nku> c;BAQU1!nD-!DzPd@J(%apE)b2@OlpqkxUQ*%$(_3L5lVw*Js$&Bvb0 zKFLFqOSY 24q_Acd2S!wdd7H)__lvaLe4?*vJnn%Q;yoa4F#K-K=4cym4WBa!E;O0U3 zO0hag^}R{kMK*5R&3}1}*|}5|%+Zn}J%0glNdRLXf3c2Hk3@6wkp3IMC$l}izR$pY ziF D684h)aP(08LVVk)cOJZJ>_E*+_>RMgG*-?@Tk1?9^jPP_&+fvk?1C2a_g5oV9a z5eh~TQOAt7Nl^30!Ds?kh|7v|a%aW89cff_gMi$!hJT7cxv@yIEg$7$Ew@J-8g)q# z2{n{^jt0RwhuC)YyYJY+K`GyPbVEc{FC}vE|6i&Fg~kUW@^cD8X{ZuV*r$2C^Fbhc z?!AZK>7T$K#!X)puPG%l5>S2J8+EMz%)l1R{OE+*(g-{{s7~>{%NARWM+QjS2deQD zjLq7)(j(@KJ?VT%BVR7)QY6e&O;v-xw4Xrsz|#P5O=_Y5$!^c>MMSN9Hj|R@!Q!g3 zQ%6Mt=F%pnz>7dtK>V3f^&Jn_mW-gyFhx}*BbZl5&=B_ T9(#>~eeaP$S{kudRaYCX=dO=-_68Y`6%&th S1Lw^U#i}P{aEu#~aAWKNbmlBvk)6}$xCXBn(yP}oA z-UcQHCJ9Q)!IK9k^wn9l$0v&L*?-GsFhDw4czRxpC$tSH GoTLql{3kSo=CJK_%bzIuYohb)Z+8LsMZ!eho`ZP8L>5?DWHP?lzCl}n3* zOj%rB=ZB8^Ci5wKQ{_+kRO|8#j)47Gr%RhCuG|6m|I&7rT&O;KdF-`+DT2hNxICX7 z2xK#rk-!RrwhOgqOp_=b7Xi2@OLKNIgEO+Uy_ddOLvns8iZ4xto$eN+%Fx!1u7>)g z?wiZF!o-Ro@pyr%4;)=7@sW#>TEO4CzK<#70L%1K)m*6t3nwBi^ioUl6MCy_FSI*e zqr*;1SmKeWO`ECBsNe`Uv{>Q2+1yZiUHLI@BV>QfqTAM{W@@>K4<4Boi<`~wK=XZ> z6Jw#945`kMl^~3X5X}zm&3*5CrRIK_{8`NZCvcCBu zzsX*&tit@~d$Xrg)%1Uf!!2D%RTcbZdmAA@)#V`8(mG~73!7s$a3r|_Zct`&>vg}) z-dJCrS1oPo=6?m$?+r-e7^d%m(8ahQ3W*> N zyf5HJ^h-@JqX!u1NvKuA_f=+PWiUUT7_a!Ci7*zbfS;y@9kQi;Y|XQgLFbA^1J-R7 zsNNmLta}IJWTbS{5(@y`gGx+>Y3e+~>v9`rq%f{rmXWp{OykD<_u?sv*P;+soyU&r z+I_Y70Mk@OCoRt_52%Y4stW$kl!&CMz+NYi3qX#xcPm0+T&%qrol2G#IQRP?N0p8v zS5hHb^3xf_P$qRo)*R|v aA2@^J%4V8x>IyJvQkx)aD6f$tBM!E}&b zhR?dTgsXTn?T>-1$#n_{V6&nrf<{Tv0K_fy=LJ)LP=uhxArfks_NKH*Cbf$;(-`wZ z;U1|<*;HW&&^;Vw$z3AR*J5HNRr$lQN5ye|zCS K0@iGIB0AiTEBnJ`lg4;l_1Qpa zq`Im$c+L66oKygAZcCusO}nFEgX(B58m)OSQexA@J>>IPIr9&WTq`Kg{okyYTK?nV zXztVv0EApj);xOpzTb(1lRNuAk6T+eB1^7h1k&m$bj4itcM_m;Hmqc^pa42q+WS;i z*gFA)3*ynYg`Cw=7H+dBYc3=-&6ZEHbw3u4Ba7gB?#_8qIADd#l4Kyw%Nr*)7baBE z1>=7@&e7IlEgQx-A9P1yV@8oN_ND-L6O=Tou;M%mKw%5VWFPrqN&>hF)ZnK~TlQcH zHVYS$pPWB6O{kM!Nlo}zpaX&;WfOrPhTCfBV0lJUMt9ihNG!x6;xwsF4P~ru2*%Bt zHo(!rCi^m9b!aO7@cDv@2z3R}%1$dNIYtAsTIug$@jSyu!atgd6pB6hcppI=h`cv@ zl~MHt!0POB2Y&fg#*NjGd17KR#>9pnp7MvOvw>AM|LR^qjn70G)1k{t&>N_s1{H@( zdT16Q*LX;fXH*i#PXR4tWhV*ZYxG~iId-kd%cS#pS6BG^5M!}U8-Sx-_+z9S3Cq!; zb-jp%W(8A&Rc4dXMmXmFrSCMx9oZca>*fBpRK1O)(<=ca?`m>|RCmK F<^DsSS$`SK?duhoR5}hU JRxbtn40lnvmE{X2mBVQ#K8mdH} zI^4j99SGdG?7ikV@NGPmSx_EDy>stD6zT?_&Qa>d8jC%665=!HrV3RITc7@68>|sf z8~TCXttk(5r5UCUM^K1-#2u{p{wj5$AWw7SiK;6n>~%kivbNtBTV#O-ItvUhArSrc zMgqcpBQYphoPQP-)k5Vo*#tvGITzKjEh7@^kk A5@b`U)uk$#`zl#7r-ZPhg#9IR!by#D$_C(P%Z=m&ky>>_*ipky zQx9TPoh?P+(86wO`R?xX c8b+!bZ`Qp6Hm4#3LLzWgcnheNEnpy9`V<4i`20z }GchqNyT)4p zoc0&KT4Cx$Ocfw~U~#=8PXFa@Q?&c~dIF9kEyiAA9E;xF1$khwdW*X~Nf=p1XGMWW zKS7#m{rMbmU)~oM5fqBHZN0@^LC2)ndK+5)sH8LSSR#@p4 Wry@6c2q`jFU2wPQlbp}=KiAgeK0-v1 zH`OYGk>>YMRUtpHaZN<(!HWKQvL#WMIg%UTxnkJ@wwxS1oG Af( zEHtC={a+!FCHEIvn_CSZSMEWg02|N*wO1dS#9ko+7XqP&CsS;)4Kj2D>eaLq?RcPc zv~!9d^w9LGx8e(P7-&YPmXWk+S9mI>d$>cIpNm&P+4^840teIOv(I`Z;~POlwC%OX zmpB97pfWN@svxZsDNul?#7YESwUmxIr<-vI UcU?~fDKe;4=~&(*Y9*R zfK=Wx==Az0E_`aI?`q|w4XOp+d><+hRN*md4yRSB1WK6rg5D4zBK|dp66GmVqJweN zqivZ~Q w{HvfNfrW(}#vP6ReDdGvwj%7G=%@=v2eQ)RhPH(ZX2N|pB z>~gegVnodBPD#P96PMFLXFTpAn)y3|ZAX|ZR_k1RBqx7ByMxK32bA%Spd&5^$j!qs z+Fe@GkL_DCB$81a{TBs{>@XQ-&hN$Lv&{UnYLVKWL!ZN?Zy)#24EXvAf6Ho)dB?Le zmHB-RnUUx GG!`J1kX=8(^(iAq%%j}X&n8A3uDPW?dnTEo4bN@ z_W8_=Q-((Ci$rqba7<=zaOgeoe7=(KSSNwgCirjk8`awkmZ7ke7%|?Ug8mnk3%86P z?Zy!*3wjY8_0-pQPGEB3`joWv$Rbm-yZ{>Lf4vMz73U8c ripub`IPJfvXkF&qGpB&;{7N%u$ 8lD3! zqN9w{cI{JTUe6~y~FYP#7D)y$ZP{_jz#=zG5W4B9t-(CH8%nP8^}0k?w6*Mfhx> zm zR{RY#nLv@k0I7zK;KYpKKq3|7B#R|zD&<9u;+y&~p+kk(@X$S9yT;WKa|3f;scqQ7 zq`E)P&>>N{gSuSZQRY({#u0vxAz5n+o`g8jPyT~PYy+mYYbzn2q >Wz?I zx*^fvvg^1wQJp4OT2G16bi6HN%Sx`2rUj8J+{(PzwH+-Zm8;sYjpx;L>kf@rlHNu7 zaM7|r^<@7ASbufdNrnLti;7>EGi^}!S_;Q(>w(8B;2Tm}RPEfI4RmNDp=$TKH_LLY z$bp Y^jMnma|K *wgfecaA^4X z=r=dck}tJwdFaq_x~$7}?8z|~?62Pa6_ok{f(TcNV`lHIB5u=7tsss+0zW@*t2j#3 z%g4)C{t5(ynUHobSjOYEA;$d`7Y}B^{%iFqn0 $-1}cH1mKAVbo!Dsc_Z@tt1(ux0zu=#nXp9E;i093kN*AIj6CH0xO3=m zmQC$X2Z!IG0xNEyli}E50Zy-iGdXVTa&CJ*{gEv<+iW5Am23nPxSe{TGs1pF{D~Nt zzxfJNo(of4?_$T9dZiATz+>|sumqVhrKP4uKSscuYY-kC{|a``wAaBO)3y~bzabL> zT95IAXVW}zQa!|mD%8cc3@w9L*)-CB7`>9~geIj-&ckj-e7-}c-F+T%GSA2KB={JF zfw))SnjjzCG(rL0!GYbY{S*R*CR8K|L%b`v4s5ZU=2NLXCiqe#$vj1-pDJcb63#VL zfLuUUf>qGQcc=c8kv?gJsLUo mQE=_idw@ _NQ_Tku9TdrV;kgEG?=mtX(D8FCElSSuw;wXK z&ubS~!ag$ O;!`A(fF~jPd@R*s>=ZaW7uwQr>Om-yB*55Ehaw4cW z6FWdz5ly B#IwW zOUOQ+RfgmT4APv?%0aPQT{N8lwg^{xUuHat_YD}-e#;u^)Q*hghWxY8OMSj0ku-cc z89EHq=MUeBIPKd*Q8Z(Klunc{U*Cc>bJ6NcQkS|p?;W?PDSf{N#w<`D0*8W&PlCQZ z5Rs OABP5^SF*6ZweXpm=WfpWukmFV$5f)L{Tpu*sq-0 z{Dbacu?zgI;}m?{8bvQ?cWz&y5 jdLPn8oHu@?OV;-~I8wz~v+oNT?9A^3@kiN20L)^|zV!^c)L1 zp$Tdd96>aao){Y9r}uSD)BU>PWPh=Icsi*Ql5mY`>~1@ak0BH<5 ;%)96;V2 zo2PY=UiumAxHb9R)06#K8vzEWvWP`0<%#Bv_^E^>O|*<4)9Jw6h>EexytQwhNVLEX zEW@L4OhLJSh2dqMf5C9aK7khNi;uvJ2-k3l -rX8tMaWP|UYOXg!N6~8tA3DgH_5Fu$N;BnWR_p(S(gcfSzTI5FNSn^sW6KPgx z0msi7L{dZ3FkU5i8dHg&+`vjSADK{CwJE_v3-;IjgHq#=u!dv+anf|GEvi}M^vISX zOGF-kF{;$GvG3RzCLUEv!JLsbs}eq x)1szHUda4X&BZc8oqgLq-C%t-+Ij8VFMQFCgx~NV_2}_do)yGN^rrr)Rfq^+o zsbLrP-!YkvdrK54lWGwa;)oX5jA`O=d52`uNlWI{2yni#i)kujuHfqkn)3HlHZ2M< zCSsBR(+EEqJp}b5ax}^`Nk82}-(yTvGkS^(mRZ<34ey_Sa%BRk y30g)HJOuB(ih}4 U%ORD(b z#N0R9{Jd=oSQ0R;?GL}`d?_-dEeuh7Ik~wAJCQcgd0~Z+kK_f7&;oZ-^z-hZZeBh& zxT$oq5bf6_KD5y#SgFcEU*)Fm%p2S+%dR04Zi{;F-a~$aD5Pceq4W_K`e;gkzaf|} zeg$iUS3tk9e`1bm%Uooy^Al%!!;}QJcD?2`D3w`Q;%ZvC!v0-^C+6S^-uO5(ltNG; z0QJQYkgRqpDfn0v6qsDu< 06VNeSf_@fB=SML3NYD`pasu}TkA+jEjszM1L`o#xLC8v8YAA3Ca zBE#p86U-@UU^~k(O~Wyj$)L8IqRwVj gCn?yzNg}G1fn>5_3xZy$62aO zsf)~xy1RJ#W8;qBCoQ3X4d2q@lZt5$ayWQ0GR}|WlUxf-WGqg3 z48*1>1>Z|>l-o@{>ohG_7>hYPCddq-kvItq6<2B@_5aB@JfV-rpPU!lGA{aH#hlh~ zpNbh#JT)Dgjr6p l7|*Wx$+3BZpW zaGifhm=Mx*kn~^!C-z*LCVnO16R=495K&SIR6F?5V-P}CGB5o3_M9Xu%-hvdFc+c# z+-@yP!2r;I^QiR$e{j>z2t!{%@8wAo@6-? BqRs{#%O8;yX%Ln5`*+dtil< zD&2|~$psBikLDz4Or=KlG7T$y_~qqcQ<~#c?81BvUp6{f2jrdO98N!mx95nV$}zKM z%l*kvADp)aS<9^&ROMF+sAuJD=RfzwiU-ErVE8Ob`FpJ2c?<6H9Oub+j!e%do^)m{ zys{T=dvc^IzgWuUDp*lf=@TZ(?g;DIHN+@wCCpEk(qj6)6w{cEzMploAFyi(3-nvg zU2?60b$f4}T{@MJPk7QEyf|K-L<)|ixZoh)9+yUL*~uUgoX2nLOYC176PPGsJ2@Q~ z3cJ*=X{G`5LtD1SGe4jQJ9Okpf xmYN=)Dc@8UGsaSdy-*5F>6DznxH0fDMw)}lOn LO5|Vm(qHmONxl%(s_P+z2W<`)6)kbI}2>g&B hR`uqP5uv5 z{|yRbQ#Hpi?;juIB^ LO@c?oUny)zBy6 z_hZr!ySm=ybW#C$?G=X^wpNj{e{Uh@zs{ViJ(8s&%%=-JScX9J94dNmQ}%#n6kt*j z`oS8*jG b!coo$|LLD&>GDBtCso?g<=WDpoF0r495!>=^Q12{k=uh&fBq#1 zXimN$TCOZk{wMyauMp>rTT^(u#XuX?Kb~CSELDK_SIelF6ISLq?CLr*sW>xTYIhqU z|CZt(qIPVvFC_or!5HK2Hpj!p!>4Z1Q_{>WRDEfkcKnw=17+LyZTmEqyrGzSOcmc} z-UR4I?VsCGP3?EBf}i=JD1jhdqCex`RE^srz)bba1Aj=MoJt6Ts;KB2Y&&-V%Y^CL zg>m~h-}_+)@{~#bmUYT(gT~Vz7~#-^&nE3IIlh9|m?OKil#cJCsi_&xN4EeErWzH^ zg;+d<0WzyaE{)3db%=$m-c70;h%VeAihzUO$QJ&k(@TAIZ<aA;E%kiV`j{5?z(W z0tWKO6AxyM>W*u3Ei( H%>4b{n04(XDq`_0WS- {xQNkM*l =uL6`w4t{;7#6jO3C0D^PCZ_DKJ(dC}c^DG;dmF82NR3dn }tmezrAjrQXL! zr2PN2_f}z1eewG!iYOr6jff+q(#?Q0(v6^WH%d1uT>^rXLl52EA)z!w=OEG`j4%TO z3~@GopXdDkzl(Eso^y4$;bCUjv)9^dy`Nm~i+8tSANJ9zFDEbIGzLI%JJ8p!^cZCE zrxszZoVF0Iup#XBZ2}^D06@FseBX@@n=q*nf1`c4^@XIi6R^_O4B~#%MR|7b`9$ep z-Db50mq6YJDY $vh@Y0$&W4Dj1$J)sbYA4;)5+DkqW<^UgSS-FfhsT8V7YT z7++6Q4*&rt-R7!mOMf&;trq~JuiAzGXdZCMvPKhu&E{Sh1g_TDH$m`?CCjxV9I(HB z4Yp3no2Kh-C1s@}66G+0u&_ RL6Qzjh!T(Vdkwz`-M&8B6+=g#T%nb z5vQSgmb^X>TbJCVnfDFX5N*{K!}Bcavl_wAorcs(71yi>kXf5qG~kMR|4~wkWz!WI zz`Wdi_cR9k&JwRtf<9?>D$#EfxgX`t_4*GyU1hoi`sP$09%oUzXO6{tUS9>j&}TxS zPvk#+`lOHUIO`1JV6g%NaR!;HI!Fa9i2am&V%ZDBs8!_fwrL`jL52s6^cp6DJWF59 zIy{{wgQ~J}%GYpscsCw$by#8=b$dLh;+SaJnOJa{)sUC^v}ODj3Hes#n}wPFNS+My zmuMS7N;|I*bfqymx-rZ9)iav$cAvkWm>C{!kpor~5Dk7s`;b#^LTg3~&*MR_b+}~= zLTu?IFZIz%aZ)yMG`GLslz&(OEi5edcU81>%T=*@S&!89x|9)k!9F%7K>`>`X9c zAtO%~Pc{9A^pk*(MtwB<3?X)_@UT-Jp3Hok6aov;b+J)&n`bySv#@wP3u9HZ6#O2~ zC|(iIEJYPVa@)a_l-AUFQjyq)|1CYeMrVQ^g_88;G<05tk){o;fhDyb|H-+_+L~;^ zGqvbu)3E Xrh8z< 2RIbp7{F M z_v~$#7i{`$H_Tm75SWxWFzMN5 Z4fxk1uobJmEMy2yEou(1qBhC8cT4iS@D#uW=^>6eY1Q?GDQ0U5=_ z90IN6dihZ{241DImgK`a!+cykvEnu+J$6@*5N|E;qh+ng`YH+?T)kdpXpV)@=2={Z z8V4w4??yt|9FJubx(o2PE^ZvS2Dd@Hpajp|Ve)+1NtRwO3 SEbTM?Yr`9j=)^3BG}Hg9_qoVICeHPr|HS^rm3>I8kO2nQ=_uVu6pEyNu#u zSxEoK5$K`lPfNIB&23EP#fAb71cK(a1qv@q_7`j+j4^ts(DGa9=%=oJ$jm^_Xaxnu zfT0?HZ@!mT>deh1xN*CxuD+hfW~RO~-oeV_=clKQz_ICNKD9Bch^!ix2z-mFzi#P3 zu=@#CbJYAG0M@Z)U6A9}JY+*2&-BEB%03@&fi#ShXW7(WukD`qT>iru6{7$(#vSlD zEZhM&cz@rxHr=2>ilso%E{I5aRsi9%Egs0pNw0F<7ey|)IRW15fd^s$U$4QpN+X5l z4;M4Ungt{qL3*H0oBlw-L$ViZ!&=t*Y!KN*rRUYm*L3|0qt62|l7GaC6O|#V3RU>b za8GnUJ=i`!K`2SHG9S;^Nz+@fHX-&!GBxfoQ<6Slwap`;&ya>???%d^v;Nzkl;^!t zm$KQ>dCxPyfFqqXeENSX)%JOa*`?0#)~^&P6P%_t{TRj _-;)_>UHPfoUuM=33$3MJ56@X+ig%+*QI|AMPXI^-|FqE@FsN#-%`L2J#sjvi zv1zLQi35&KNE^3F5GvKoVtsfgSwi{5BWq^5l|tJfOnAt<3u9b%bJauqdtKN>-Q~WQUd9&8PWGx-%9(%q8?Ak>JL??jLInxPY(H?DYGzW6~nZ`WGtUT z;~$q?jA481z(9#S;l8;lPs}ChrIkgY9>U{fCNe+wqyg4Mo25pp-OWMrL9A1Ay?}Yg z>)#P3yE-X`V>4W~1=R3rXcUc IQp zxCAf0X~Ja<9IT$ORJ6lDVHVBDccB> !AF+-Jxq40^a9c}E^P<3f$V#AeYa zg1rGkA89Ojm*dh7BP2FhV3Y=LN&opur+|mzd6Y-p@w14*GT%}XCn=mImN!GePOivi znO)2tFpm9DP?^9Y*FDFicjK}ZRNgC|sg(bUE4{kW8G@3nAsX@&^yA+mDyItwEz^Z9 z?y}I%@@bd}cM z#bd2O^|Ya8jmJ+ArLK3N8I!OFL;0m9v1LI_C&z`t9UK74tun+wzX8sGJ~#E#{g1cS z{j}tL(B(QaCfO2MI4Y_4d-jd%35Vj3*<%*mwpQ_Snc6tj6RK@n#i7x6CLUg1UrTn5 z)<_$$0F`jnV*513svj!Uf-#T7tAV2|xeg@A^amD1o(+BtR?ZLkpMi?B{T6X2!*x{I zl-KZB=z&K($%D|%=N!f9^^CvgEYo|MV^44Z9_PFVvSTq^(BqHO_}Sh4GTlrhW@BQl zw+0AED1^#L$$IsE%aRC2xt%HF4)D8Lv8#Z;S!XFl6;_sxmEF@zm63_dkbP7G&XrKM zY*+}L{}7oF2Z#y`hRt=Yok&v3TUzEzZsMxEEaS~H>kLlSNZC=M6|EC@&dmk?csI;@ z{{l!pgvw-S${#00ND8p pJmSkHYQj_@-j*jM`v!I_D%`ktN`@sW>|g@3xeXqw$75U}@BiTV3ZD zX{44cgsvA9#ihXKbc~}s1%Fnj >E z1(hP60M6KB8b bic2dcHS-8`E|ddqo6Vk^2ay8f~N7)dwSv}9;&@(yT!U$EmS zN>erNP{(EQ1svk{+n+x&A#;xackqZq(MT{LgLK8~@Cw-N8KgKWoMu6ZfR%q8wM#+S zZ^?vt?I_leArH4KG`Ksn)EWm$7H<6^oNUk_OoE-+lsGe&X;4zGTNDF?!U;A2Zf1O^ z55~j+PrnR~aL>k^C36v~@#p!`uSs_uzs~05&E(bh;g2h3YSaNde2P^J;-(gez8&t{ zuS2)NHm#2o@EsH|%6Fjgi`~+`EKdznC%5ioy@K25E6|hGJZEDmPy!r?sk3$O_TC}} zbG)5H<2Ha4z4C!Qcy}sx=WRHt^9D}#o41@guwJjRk+FWjGz!MJwR_Nv+py?OBmlo2 z&Fo$T_~tI D#9)i_daSQ7V?dtAt+TX)5KE?%r{~_ AnVPjuYuchBGHT)xM@}^{cm qFB7eJ^*lCD>gvW(KqqCKuZMzBu-E?~zR_B*x4BkpPnN z`@nc*d{!~=ZJqeeoL1h70wjuqnp>yop&EaYapv&ou9;~nATf4WS;^PqM%8nJ8NYd^ z!#`MuaseH?SmM>wQXtc*7oV_p+L}O%T0OonMgaMkTV7b2T+)?V&ln9+K-9CSpVXL; zHM(Xe*X`$6-fwqi@gNDYpx;*M86RTPv(U}EEThlBl=b#w`4rkOGe>RirKB?L83B*O z1c;-<$mn3z4w9p0g|u26pcxMWXLJeKr$A2var;}L(5sgfB29{pB*{ l=fLZF!L_zkJKmhl_4N6*BY*Fyyj<7!%av?Dv;Dic-fMii_;Z z_FDqabFTV{J0^>wH^2L@4DWS+z^*w8%^2((QI!F}4Qoro`_Euq95kn_9qHtV=P~&7 z-a23x_@K&=nLQvNW4ygpyt1t+RU1LTZ=nRXMCN&a7*IAsDj2*I&PVaaNh}$C hlrt~M0FSUN!as$8_MI6Pc%G%^c={QS4%V%`r9!lT5aBe3i7*oy0`2|adsQv$PT zqz$L~F^x{5ZuQU^VFM^Y1Aw_MQx}BhTJV6%b&T`^snFL@MU1YHaob^vW@4fH)RvmH zgH6m#40q=|r$${Np8t1Q-^ZX#-%KM~4dXrsPk >Ay*tpgGh7Y{7uLn1fz5XQ!vm_1Y2Fw?tqNH|)j z;+@Jv`GU`3>$?2kHH`*sebmewq-KkrPlcjM8(AtmvYpyqDLJ~Yc+Q>cCegdLlYY7T zX*=;&1Mm5R*y1!z-QE}&aNzOfYy_`jf27b |26K8X-fuD@#FGkocbnjTWg3EG++b8LY %>?3e+#d!4@nTqCvZ*C$n<{rr}zGkMbO zq4|pe;mDT+Twe{|kVR{^l;`X-pLIU~Y(;RepIxqzicCX~D!;uwG|XO?Q#v_mq<(V9 zVZ>GtlsnURN}$49_8bp7_{1vkdlJyyq#`qz!9vhOL8qQDn+xRc#duyC$^RX(mE_W| zQx<_vlMZMl3-f%N#5PH$*8X0iB8CT$uQ3C7Kl~poD;M 0- 8~G&Qo-ylEPxbxfA7Hz;!}Rt>1+st?)U1cY<|{jqrN#Lo zK$c8N6xf2JBwr)9oPk1;$rHd>?0BV&R%%D=P7jeMzpn)>TWEqGux}ir9m3J=fLp$< z1Cr_Ggm^y!yd#;WGAD%yCh5Z>TD`ryDnRHEx`6`-5xBP_0ue~ShVR;nyeAX!y7Y0H z&H&0Fqj%qdH-j?XX|T@_h?9^45>38 kInfj^!%~ls>Hvc>eZXKjkf) zk!S;q>{eNvp(tNEm`&Wh z0%^~VN^Mt#h6`Dy;{?9j? Y~Mzj0~lA6I}uQ%&}Cw5;^cb;&xwEEV1RCg|2?3J*kQ2MmSs@VJ=X zt<|3R0j|6_%d&@N+v}}2^dVK3q$*JSqdA4n52gU63`fZSK^VqE@Ix#Nlxt;7a+=0X zw-TfSq=*EPZXcXs8DRH3WkpISzgD~n;57BXs1?(O^Ap7N{Z+cXDSBWYj7jNW3cUhh z=82P~eaH~dH{cB+I^c~JoeEMy|K4rJ7#&;{5&PQ(>Lh0;GuXObT2^^nLe|mIA*m-5 zK0z_HK=3_l@88VIFx+18_+ONx+#MNx i0Py0n z%=Cx=--OKa?qZ{(Wvtol>5&$n`4%|4Aekc9gcmrK3D>2f0K_hoBze>Uo)%z~E99qX zRrhtFDzDh&u$6(!Zah?DUm!92cK$5u>YFW_81b#^1kmmWyk-Q*GeZ;f!e)->$-e?E zPq%-42Np9hLR^+GfKn28fkXx$a4~LQ2&Dk@E^c4I )_LX9 zex#tf_=mvIyZXuh^HZg7RNHCjy3t3vi~9ZTI9)g&&c5OkH{O4X!E`wm?H_cy_^g%z z9n&j 3ABwlb?H4|uY*JQl9T 9-Bv$y(V>;#Gel