From 48addb7661dae24828f071f81d2d49ceae1a3292 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 15 Dec 2022 14:14:14 +0700 Subject: [PATCH 01/47] If you obfuscate all of your code in an included util, your code will look a lot cleaner. --- .github/workflows/publish.yml | 41 ++++ build.gradle | 9 +- gradle.properties | 9 +- .../recipebookispain/RecipeBookIsPain.java | 9 - .../{client => }/RecipeBookIsPainClient.java | 2 +- .../access/RecipeBookWidgetAccess.java | 7 - .../access/RecipeGroupButtonAccess.java | 7 - .../mixin/ClientRecipeBookMixin.java | 44 ++++- .../mixin/MouseWheelieCompatMixin.java | 11 +- .../mixin/RecipeBookGroupMixin.java | 83 -------- .../mixin/RecipeBookWidgetMixin.java | 177 +----------------- .../mixin/RecipeGroupButtonMixin.java | 22 --- src/main/resources/fabric.mod.json | 5 +- .../resources/recipe-book-is-pain.mixins.json | 4 +- 14 files changed, 102 insertions(+), 328 deletions(-) create mode 100644 .github/workflows/publish.yml delete mode 100644 src/main/java/me/melontini/recipebookispain/RecipeBookIsPain.java rename src/main/java/me/melontini/recipebookispain/{client => }/RecipeBookIsPainClient.java (94%) delete mode 100644 src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java delete mode 100644 src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java delete mode 100644 src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java delete mode 100644 src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..c6f6927 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,41 @@ +on: + push: + tags: + - 'v*' + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: checkout repository + uses: actions/checkout@v2 + - name: validate gradle wrapper + uses: gradle/wrapper-validation-action@v1 + - name: setup jdk 17 + uses: actions/setup-java@v2 + with: + distribution: adopt + java-version: 17 + - name: make gradle wrapper executable + run: chmod +x ./gradlew + - name: build + run: ./gradlew build + - name: Publish Minecraft Mods + uses: Kir-Antipov/mc-publish@v3.2 + with: + version-type: alpha + modrinth-id: etNS9OnA + modrinth-token: ${{ secrets.MODRINTH_TOKEN }} + modrinth-featured: true + modrinth-unfeature-mode: subset + + curseforge-id: 643246 + curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} + + game-versions: | + 1.19.2 + + loaders: | + fabric + + changelog-file: CHANGELOG.md \ No newline at end of file diff --git a/build.gradle b/build.gradle index 0973d98..4df6bf1 100644 --- a/build.gradle +++ b/build.gradle @@ -8,11 +8,6 @@ version = project.mod_version group = project.maven_group repositories { - // Add repositories to retrieve artifacts from in here. - // You should only use this when depending on other mods because - // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. - // See https://docs.gradle.org/current/userguide/declaring_repositories.html - // for more information about repositories. maven { name = "Modrinth" url = "https://api.modrinth.com/maven" @@ -20,6 +15,9 @@ repositories { includeGroup "maven.modrinth" } } + maven { + url 'https://jitpack.io' + } } dependencies { @@ -29,6 +27,7 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modCompileOnly("maven.modrinth:mouse-wheelie:1.8.8+mc1.18-pre5") + modImplementation include("com.github.melontini:cracker-util:${project.cracker_util}") } processResources { diff --git a/gradle.properties b/gradle.properties index 208d63a..cfec85f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,10 +2,11 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://modmuss50.me/fabric.html -minecraft_version=1.18 -yarn_mappings=1.18+build.1 -loader_version=0.14.8 +minecraft_version=1.19.2 +yarn_mappings=1.19.2+build.28 +loader_version=0.14.11 # Mod Properties -mod_version=0.7.1-1.18 +mod_version=0.8.0-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain +cracker_util=v0.1.2-1.19.2 diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPain.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPain.java deleted file mode 100644 index e95991f..0000000 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPain.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.melontini.recipebookispain; - -import net.fabricmc.api.ModInitializer; - -public class RecipeBookIsPain implements ModInitializer { - @Override - public void onInitialize() { - } -} diff --git a/src/main/java/me/melontini/recipebookispain/client/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java similarity index 94% rename from src/main/java/me/melontini/recipebookispain/client/RecipeBookIsPainClient.java rename to src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index 6ea3030..12c61c6 100644 --- a/src/main/java/me/melontini/recipebookispain/client/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -1,4 +1,4 @@ -package me.melontini.recipebookispain.client; +package me.melontini.recipebookispain; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; diff --git a/src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java b/src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java deleted file mode 100644 index e2cbb25..0000000 --- a/src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.melontini.recipebookispain.access; - -public interface RecipeBookWidgetAccess { - int getBookPage(); - - void setBookPage(int page); -} diff --git a/src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java b/src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java deleted file mode 100644 index 7e6c2a4..0000000 --- a/src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.melontini.recipebookispain.access; - -public interface RecipeGroupButtonAccess { - int getPage(); - - void setPage(int page); -} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index 591fa42..a31a845 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -1,6 +1,7 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.recipebookispain.client.RecipeBookIsPainClient; +import me.melontini.crackerutil.CrackerLog; +import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.recipebook.ClientRecipeBook; import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.item.ItemGroup; @@ -10,13 +11,38 @@ import net.minecraft.recipe.RecipeType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + @Mixin(value = ClientRecipeBook.class, priority = 999) public class ClientRecipeBookMixin { - static { - //noinspection ResultOfMethodCallIgnored - RecipeBookGroup.values(); + + @Inject(at = @At("HEAD"), method = "") + private static void recipe_book_is_pain$clinit(CallbackInfo ci) { + List CRAFTING_LIST = new ArrayList<>(); + List CRAFTING_SEARCH_LIST = new ArrayList<>(); + + Arrays.stream(ItemGroup.GROUPS).filter(itemGroup -> itemGroup != ItemGroup.HOTBAR && itemGroup != ItemGroup.INVENTORY && itemGroup != ItemGroup.SEARCH) + .forEach(itemGroup -> { + String name = "P_CRAFTING_" + itemGroup.getIndex(); + RecipeBookGroup recipeBookGroup = (RecipeBookGroup) RecipeBookGroup.CRAFTING_SEARCH.extend(name, (Object[]) new ItemStack[]{itemGroup.getIcon()}); + RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.put(recipeBookGroup, itemGroup); + RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.put(itemGroup, recipeBookGroup); + + CRAFTING_LIST.add(recipeBookGroup); + CRAFTING_SEARCH_LIST.add(recipeBookGroup); + }); + CRAFTING_LIST.add(0, RecipeBookGroup.CRAFTING_SEARCH); + + RecipeBookGroup.SEARCH_MAP.get(RecipeBookGroup.CRAFTING_SEARCH).clear(); + RecipeBookGroup.SEARCH_MAP.get(RecipeBookGroup.CRAFTING_SEARCH).addAll(CRAFTING_SEARCH_LIST); + RecipeBookGroup.CRAFTING.clear(); + RecipeBookGroup.CRAFTING.addAll(CRAFTING_LIST); + CrackerLog.info("Finished setting up recipe book groups!"); } @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) @@ -26,12 +52,14 @@ public class ClientRecipeBookMixin { ItemStack itemStack = recipe.getOutput(); ItemGroup group = itemStack.getItem().getGroup(); if (group != null) { - if (group != ItemGroup.HOTBAR && group != ItemGroup.INVENTORY && group != ItemGroup.SEARCH) - if (RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(group) != null) + if (group != ItemGroup.HOTBAR && group != ItemGroup.INVENTORY && group != ItemGroup.SEARCH) { + if (RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.containsKey(group)) { cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(group)); - else - cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(ItemGroup.MISC)); + return; + } + } } + cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(ItemGroup.MISC)); } } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index d07d9a6..790a0f2 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -2,8 +2,6 @@ package me.melontini.recipebookispain.mixin; import de.siphalor.mousewheelie.client.mixin.gui.other.MixinRecipeBookWidget; import de.siphalor.mousewheelie.client.util.ScrollAction; -import me.melontini.recipebookispain.access.RecipeBookWidgetAccess; -import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; import org.jetbrains.annotations.Nullable; @@ -27,12 +25,11 @@ public abstract class MouseWheelieCompatMixin { @Dynamic(mixin = MixinRecipeBookWidget.class) @Inject(at = @At(value = "INVOKE", target = "net/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget.setToggled (Z)V", ordinal = 1, shift = At.Shift.AFTER), method = "mouseWheelie_scrollRecipeBook") private void inject(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { + if (currentTab == null) return;//how tho? + RecipeBookWidget bookWidget = (RecipeBookWidget) (Object) this; - RecipeBookWidgetAccess access = ((RecipeBookWidgetAccess) bookWidget); - RecipeGroupButtonAccess accessCT = ((RecipeGroupButtonAccess) this.currentTab); - assert accessCT != null; - if (access.getBookPage() != accessCT.getPage()) { - access.setBookPage(accessCT.getPage()); + if (bookWidget.getPage() != currentTab.getPage()) { + bookWidget.setPage(currentTab.getPage()); } } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java deleted file mode 100644 index 54b5554..0000000 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java +++ /dev/null @@ -1,83 +0,0 @@ -package me.melontini.recipebookispain.mixin; - -import com.google.common.collect.ImmutableList; -import me.melontini.recipebookispain.client.RecipeBookIsPainClient; -import net.minecraft.client.recipebook.RecipeBookGroup; -import net.minecraft.item.ItemGroup; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.book.RecipeBookCategory; -import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.*; -import org.spongepowered.asm.mixin.gen.Invoker; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@Mixin(RecipeBookGroup.class) -@Unique -public class RecipeBookGroupMixin { - //me when I can't use Fabric ASM - - @Invoker("") - static RecipeBookGroup newGroup(String internalName, int internalId, ItemStack... stacks) { - throw new AssertionError(); - } - - @Shadow - @Final - @Mutable - private static RecipeBookGroup[] field_1805; - - @Unique - private static List CRAFTING_SEARCH_LIST; - @Unique - private static List CRAFTING_LIST; - - // pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work - @SuppressWarnings("unchecked") - @Redirect(at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableList;of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lcom/google/common/collect/ImmutableList;"), remap = false, method = "") - private static ImmutableList listOf(E e1, E e2, E e3, E e4) { - if (e1 == RecipeBookGroup.CRAFTING_EQUIPMENT) { - return (ImmutableList) ImmutableList.copyOf(CRAFTING_SEARCH_LIST); - } - return ImmutableList.of(e1, e2, e3, e4); - } - - @Inject(at = @At(value = "FIELD", opcode = Opcodes.PUTSTATIC, target = "Lnet/minecraft/client/recipebook/RecipeBookGroup;field_1805:[Lnet/minecraft/client/recipebook/RecipeBookGroup;", shift = At.Shift.AFTER), method = "") - private static void recipe_book_is_pain$addCustomGroups(CallbackInfo ci) { - var groups = new ArrayList<>(Arrays.asList(field_1805)); - var last = groups.get(groups.size() - 1); - - CRAFTING_SEARCH_LIST = new ArrayList<>(); - CRAFTING_LIST = new ArrayList<>(); - - for (ItemGroup itemGroup : ItemGroup.GROUPS) { - if (itemGroup != ItemGroup.HOTBAR && itemGroup != ItemGroup.INVENTORY && itemGroup != ItemGroup.SEARCH) { - String name = "P_CRAFTING_" + itemGroup.getIndex(); - var recipeBookGroup = newGroup(name, last.ordinal() + 1, itemGroup.getIcon()); - RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.put(recipeBookGroup, itemGroup); - RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.put(itemGroup, recipeBookGroup); - - CRAFTING_LIST.add(recipeBookGroup); - CRAFTING_SEARCH_LIST.add(recipeBookGroup); - - groups.add(recipeBookGroup); - } - } - CRAFTING_LIST.add(0, RecipeBookGroup.CRAFTING_SEARCH); - - field_1805 = groups.toArray(RecipeBookGroup[]::new); - RecipeBookIsPainClient.LOGGER.info("[RBIP] recipe book init complete"); - } - - @Inject(at = @At("HEAD"), method = "getGroups", cancellable = true) - private static void recipe_book_is_pain$getGroups(RecipeBookCategory category, CallbackInfoReturnable> cir) { - if (category == RecipeBookCategory.CRAFTING) cir.setReturnValue(CRAFTING_LIST); - } -} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java index 9355844..be98a43 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java @@ -1,203 +1,44 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.recipebookispain.access.RecipeBookWidgetAccess; -import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; -import me.melontini.recipebookispain.client.RecipeBookIsPainClient; +import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; -import net.minecraft.client.gui.widget.ToggleButtonWidget; -import net.minecraft.client.recipebook.ClientRecipeBook; -import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemGroup; -import net.minecraft.screen.AbstractRecipeScreenHandler; import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.List; @Mixin(RecipeBookWidget.class) -public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { - @Shadow - @Final - protected static Identifier TEXTURE; +public abstract class RecipeBookWidgetMixin { @Shadow protected MinecraftClient client; @Shadow - protected AbstractRecipeScreenHandler craftingScreenHandler; - @Unique - private int page = 0; - @Shadow - private int parentHeight; - @Shadow - private int leftOffset; - @Shadow - private ClientRecipeBook recipeBook; - @Shadow @Final private List tabButtons; - @Shadow - private int parentWidth; - @Unique - private int pages; - @Unique - private ToggleButtonWidget nextPageButton; - @Unique - private ToggleButtonWidget prevPageButton; - @Shadow - @Nullable - private RecipeGroupButtonWidget currentTab; - - @Shadow - public abstract boolean isOpen(); - - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget;setToggled(Z)V", shift = At.Shift.BEFORE), method = "reset") - private void recipe_book_is_pain$init(CallbackInfo ci) { - int a = (this.parentWidth - 147) / 2 - this.leftOffset; - int s = (this.parentHeight + 166) / 2; - this.nextPageButton = new ToggleButtonWidget(a + 14, s, 12, 17, false); - this.nextPageButton.setTextureUV(1, 208, 13, 18, TEXTURE); - this.prevPageButton = new ToggleButtonWidget(a - 35, s, 12, 17, true); - this.prevPageButton.setTextureUV(1, 208, 13, 18, TEXTURE); - page = 0; - } @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V", shift = At.Shift.BEFORE), method = "render") private void recipe_book_is_pain$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { - renderPageText(matrices); - for (RecipeGroupButtonWidget widget : tabButtons) { - if (widget.visible) { + if (client.currentScreen != null) { + this.tabButtons.stream().filter(widget -> widget.visible && widget.isHovered()).forEach(widget -> { if (widget.getCategory().name().contains("_SEARCH")) { - if (widget.isHovered()) - client.currentScreen.renderTooltip(matrices, ItemGroup.SEARCH.getDisplayName(), mouseX, mouseY); + client.currentScreen.renderTooltip(matrices, ItemGroup.SEARCH.getDisplayName(), mouseX, mouseY); } else { if (RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.get(widget.getCategory()) != null) { Text text = RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.get(widget.getCategory()).getDisplayName(); - if (text != null) - if (widget.isHovered()) client.currentScreen.renderTooltip(matrices, text, mouseX, mouseY); + if (text != null) { + client.currentScreen.renderTooltip(matrices, text, mouseX, mouseY); + } } } - } - } - this.prevPageButton.render(matrices, mouseX, mouseY, delta); - this.nextPageButton.render(matrices, mouseX, mouseY, delta); - } - - @Unique - private void renderPageText(MatrixStack matrices) { - int x = (this.parentWidth - 135) / 2 - this.leftOffset - 30; - int y = (this.parentHeight + 169) / 2 + 3; - int displayPage = page + 1; - int displayPages = pages + 1; - if (this.pages > 0) { - String string = "" + displayPage + "/" + displayPages; - int textLength = this.client.textRenderer.getWidth(string); - this.client.textRenderer.draw(matrices, string, (x - textLength / 2F + 20F), y, -1); - } - } - - @Unique //mmm spaghettio - private void updatePages() { - for (RecipeGroupButtonWidget widget : tabButtons) { - if (((RecipeGroupButtonAccess) widget).getPage() == page) { - RecipeBookGroup recipeBookGroup = widget.getCategory(); - if (client.currentScreen != null) if (recipeBookGroup.name().contains("_SEARCH")) { - widget.visible = true; - } else if (widget.hasKnownRecipes(recipeBook)) { - widget.visible = true; - widget.checkForNewRecipes(this.client); - } - } else { - widget.visible = false; - } - } - } - - @Inject(at = @At("HEAD"), method = "mouseClicked", cancellable = true) - private void recipe_book_is_pain$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { - if (this.client.player != null) if (this.isOpen() && !this.client.player.isSpectator()) { - if (nextPageButton.mouseClicked(mouseX, mouseY, button)) { - if (this.page <= this.pages) ++this.page; - updatePages(); - updatePageSwitchButtons(); - cir.setReturnValue(true); - } else if (prevPageButton.mouseClicked(mouseX, mouseY, button)) { - if (this.page > 0) --this.page; - updatePages(); - updatePageSwitchButtons(); - cir.setReturnValue(true); - } - } - } - - @Unique - private void updatePageSwitchButtons() { - this.nextPageButton.visible = this.pages > 0 && this.page < this.pages; - this.prevPageButton.visible = this.pages > 0 && this.page != 0; - } - - - @SuppressWarnings("IntegerDivisionInFloatingPointContext") - @Inject(at = @At("HEAD"), method = "refreshTabButtons", cancellable = true) - private void recipe_book_is_pain$refresh(CallbackInfo ci) { - this.pages = 0; - int p = 0; - int c = (this.parentWidth - 147) / 2 - this.leftOffset - 30; - int b = (this.parentHeight - 166) / 2 + 3; - int l = 0; - - this.tabButtons.clear(); - for (RecipeBookGroup group : RecipeBookGroup.getGroups(this.craftingScreenHandler.getCategory())) { - var widget = new RecipeGroupButtonWidget(group); - if (group.name().contains("_SEARCH") || widget.hasKnownRecipes(recipeBook)) this.tabButtons.add(widget); - } - - if (this.currentTab != null) { - this.currentTab = this.tabButtons.stream().filter((button) -> - button.getCategory().equals(this.currentTab.getCategory())).findFirst().orElse(null); - } - if (this.currentTab == null) { - this.currentTab = this.tabButtons.get(0); - } - this.currentTab.setToggled(true); - - for (RecipeGroupButtonWidget widget : this.tabButtons) { - RecipeBookGroup recipeBookGroup = widget.getCategory(); - if (recipeBookGroup.name().contains("_SEARCH") || widget.hasKnownRecipes(recipeBook)) { - ((RecipeGroupButtonAccess) widget).setPage((int) Math.ceil(p / 6)); - widget.setPos(c, b + 27 * l++); - widget.visible = ((RecipeGroupButtonAccess) widget).getPage() == page; - if (l == 6) { - l = 0; - } - p++; - } + }); } - - --p; - this.pages = (int) Math.ceil(p / 6); - updatePages(); - updatePageSwitchButtons(); - ci.cancel(); - } - - @Override - public int getBookPage() { - return page; - } - - @Override - public void setBookPage(int page) { - this.page = page; } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java deleted file mode 100644 index e852265..0000000 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.melontini.recipebookispain.mixin; - -import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; -import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -@Mixin(RecipeGroupButtonWidget.class) -public class RecipeGroupButtonMixin implements RecipeGroupButtonAccess { - @Unique - private int page = -1; - - @Override - public int getPage() { - return page; - } - - @Override - public void setPage(int page) { - this.page = page; - } -} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index f51a77f..c156a15 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -13,10 +13,7 @@ "environment": "client", "entrypoints": { "client": [ - "me.melontini.recipebookispain.client.RecipeBookIsPainClient" - ], - "main": [ - "me.melontini.recipebookispain.RecipeBookIsPain" + "me.melontini.recipebookispain.RecipeBookIsPainClient" ] }, "mixins": [ diff --git a/src/main/resources/recipe-book-is-pain.mixins.json b/src/main/resources/recipe-book-is-pain.mixins.json index 41c12ea..b1e549c 100644 --- a/src/main/resources/recipe-book-is-pain.mixins.json +++ b/src/main/resources/recipe-book-is-pain.mixins.json @@ -9,9 +9,7 @@ "client": [ "ClientRecipeBookMixin", "MouseWheelieCompatMixin", - "RecipeBookGroupMixin", - "RecipeBookWidgetMixin", - "RecipeGroupButtonMixin" + "RecipeBookWidgetMixin" ], "injectors": { "defaultRequire": 1 -- 2.51.2 From 26fd81523d6c9eef53c24df6ba2478e2db5cc91e Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Fri, 16 Dec 2022 22:26:28 +0700 Subject: [PATCH 02/47] . --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..db3a118 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +## 0.8.0-1.19.2 + +### What's new: + +* Experimental 1.19.2-only release. +* This release moves most of the code to a separate util mod. +* Compatible with m-tweaks 0.4.5-1.19.2. \ No newline at end of file -- 2.51.2 From 3202c8193d5acc37a921e1e07bd7cba312da8c60 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Wed, 8 Feb 2023 18:24:35 +0700 Subject: [PATCH 03/47] fixed pages not changing when scrolling with MW --- gradle.properties | 2 +- .../recipebookispain/mixin/MouseWheelieCompatMixin.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index cfec85f..c701970 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ minecraft_version=1.19.2 yarn_mappings=1.19.2+build.28 loader_version=0.14.11 # Mod Properties -mod_version=0.8.0-1.19.2 +mod_version=0.8.1-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain cracker_util=v0.1.2-1.19.2 diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index 790a0f2..8fb2ca1 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -30,6 +30,8 @@ public abstract class MouseWheelieCompatMixin { RecipeBookWidget bookWidget = (RecipeBookWidget) (Object) this; if (bookWidget.getPage() != currentTab.getPage()) { bookWidget.setPage(currentTab.getPage()); + bookWidget.updatePages(); + bookWidget.updatePageSwitchButtons(); } } } -- 2.51.2 From b77a9a8fd1469a1dc0656d7d241ad6ed1fcb7322 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:20:21 +0700 Subject: [PATCH 04/47] changed log --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db3a118..2b5f5fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ -## 0.8.0-1.19.2 +## 0.8.1-1.19.2 ### What's new: -* Experimental 1.19.2-only release. -* This release moves most of the code to a separate util mod. -* Compatible with m-tweaks 0.4.5-1.19.2. \ No newline at end of file +* Fixed pages not changing when scrolling with Mouse Wheelie + +> Compatible with m-tweaks =>0.4.5-1.19.2. \ No newline at end of file -- 2.51.2 From 8c782a94b67d99d097cc5ac675518640a545a98f Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Sun, 12 Feb 2023 15:36:45 +0700 Subject: [PATCH 05/47] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 34 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 +++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..1497bb9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,34 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[Bug] " +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Logs** +If available, attach your game log. + +**Environment:** + - Minecraft Version [1.18.2, 1.19.2 etc...] + - Mod Version [e.g., 0.8.1-1.19.2, 0.7.1-1.18-forge] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..6bc8057 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[Suggestion]" +labels: enhancement +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. -- 2.51.2 From 148e52b6fee7295c37199c900c0b9aff5b4ee231 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 16 Mar 2023 15:42:26 +0700 Subject: [PATCH 06/47] yo --- .github/workflows/publish.yml | 44 +++++ CHANGELOG.md | 7 + .../recipebookispain/RecipeBookIsPain.java | 9 -- .../{client => }/RecipeBookIsPainClient.java | 3 +- .../access/RecipeBookWidgetAccess.java | 20 ++- .../access/RecipeGroupButtonAccess.java | 8 +- .../mixin/ClientRecipeBookMixin.java | 12 +- .../mixin/MouseWheelieCompatMixin.java | 11 +- .../mixin/RecipeBookGroupMixin.java | 25 ++- .../mixin/RecipeBookWidgetMixin.java | 152 +++++++++--------- src/main/resources/fabric.mod.json | 5 +- 11 files changed, 177 insertions(+), 119 deletions(-) create mode 100644 .github/workflows/publish.yml create mode 100644 CHANGELOG.md delete mode 100644 src/main/java/me/melontini/recipebookispain/RecipeBookIsPain.java rename src/main/java/me/melontini/recipebookispain/{client => }/RecipeBookIsPainClient.java (90%) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..bd0d2c4 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,44 @@ +on: + push: + tags: + - 'v*' + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: checkout repository + uses: actions/checkout@v2 + - name: validate gradle wrapper + uses: gradle/wrapper-validation-action@v1 + - name: setup jdk 17 + uses: actions/setup-java@v2 + with: + distribution: adopt + java-version: 17 + - name: make gradle wrapper executable + run: chmod +x ./gradlew + - name: build + run: ./gradlew build + - name: Publish Minecraft Mods + uses: Kir-Antipov/mc-publish@v3.2 + with: + version-type: release + modrinth-id: etNS9OnA + modrinth-token: ${{ secrets.MODRINTH_TOKEN }} + modrinth-featured: true + modrinth-unfeature-mode: subset + + curseforge-id: 643246 + curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} + + game-versions: | + 1.18 + 1.18.1 + 1.18.2 + 1.19 + 1.19.1 + 1.19.2 + loaders: | + fabric + changelog-file: CHANGELOG.md \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..86677b7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7 @@ +## 0.7.2-1.18 + +### What's new: + +* mostly internal changes. + +Supports: Minecraft 1.18, 1.18.1, 1.18.2, 1.19, 1.19.1, 1.19.2 \ No newline at end of file diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPain.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPain.java deleted file mode 100644 index e95991f..0000000 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPain.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.melontini.recipebookispain; - -import net.fabricmc.api.ModInitializer; - -public class RecipeBookIsPain implements ModInitializer { - @Override - public void onInitialize() { - } -} diff --git a/src/main/java/me/melontini/recipebookispain/client/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java similarity index 90% rename from src/main/java/me/melontini/recipebookispain/client/RecipeBookIsPainClient.java rename to src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index 6ea3030..05b47b0 100644 --- a/src/main/java/me/melontini/recipebookispain/client/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -1,4 +1,4 @@ -package me.melontini.recipebookispain.client; +package me.melontini.recipebookispain; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; @@ -20,6 +20,5 @@ public class RecipeBookIsPainClient implements ClientModInitializer { @Override public void onInitializeClient() { - //null pointers are epic } } diff --git a/src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java b/src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java index e2cbb25..9f143fe 100644 --- a/src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java +++ b/src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java @@ -1,7 +1,23 @@ package me.melontini.recipebookispain.access; public interface RecipeBookWidgetAccess { - int getBookPage(); + default void updatePages() { + throw new IllegalStateException("Interface not implemented"); + } - void setBookPage(int page); + default void updatePageSwitchButtons() { + throw new IllegalStateException("Interface not implemented"); + } + + default int getPage() { + throw new IllegalStateException("Interface not implemented"); + } + + default void setPage(int page) { + throw new IllegalStateException("Interface not implemented"); + } + + default int getPageCount() { + throw new IllegalStateException("Interface not implemented"); + } } diff --git a/src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java b/src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java index 7e6c2a4..1ed4489 100644 --- a/src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java +++ b/src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java @@ -1,7 +1,11 @@ package me.melontini.recipebookispain.access; public interface RecipeGroupButtonAccess { - int getPage(); + default int getPage() { + throw new IllegalStateException("Interface not implemented"); + } - void setPage(int page); + default void setPage(int page) { + throw new IllegalStateException("Interface not implemented"); + } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index 591fa42..aa3c99d 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -1,6 +1,6 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.recipebookispain.client.RecipeBookIsPainClient; +import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.recipebook.ClientRecipeBook; import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.item.ItemGroup; @@ -26,12 +26,14 @@ public class ClientRecipeBookMixin { ItemStack itemStack = recipe.getOutput(); ItemGroup group = itemStack.getItem().getGroup(); if (group != null) { - if (group != ItemGroup.HOTBAR && group != ItemGroup.INVENTORY && group != ItemGroup.SEARCH) - if (RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(group) != null) + if (group != ItemGroup.HOTBAR && group != ItemGroup.INVENTORY && group != ItemGroup.SEARCH) { + if (RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.containsKey(group)) { cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(group)); - else - cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(ItemGroup.MISC)); + return; + } + } } + cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(ItemGroup.MISC)); } } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index d07d9a6..c8cd6dc 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -28,11 +28,12 @@ public abstract class MouseWheelieCompatMixin { @Inject(at = @At(value = "INVOKE", target = "net/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget.setToggled (Z)V", ordinal = 1, shift = At.Shift.AFTER), method = "mouseWheelie_scrollRecipeBook") private void inject(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { RecipeBookWidget bookWidget = (RecipeBookWidget) (Object) this; - RecipeBookWidgetAccess access = ((RecipeBookWidgetAccess) bookWidget); - RecipeGroupButtonAccess accessCT = ((RecipeGroupButtonAccess) this.currentTab); - assert accessCT != null; - if (access.getBookPage() != accessCT.getPage()) { - access.setBookPage(accessCT.getPage()); + RecipeBookWidgetAccess widgetAccess = ((RecipeBookWidgetAccess) bookWidget); + RecipeGroupButtonAccess buttonAccess = ((RecipeGroupButtonAccess) this.currentTab); + + assert buttonAccess != null; + if (widgetAccess.getPage() != buttonAccess.getPage()) { + widgetAccess.setPage(buttonAccess.getPage()); } } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java index 54b5554..b6ba11b 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java @@ -1,7 +1,7 @@ package me.melontini.recipebookispain.mixin; import com.google.common.collect.ImmutableList; -import me.melontini.recipebookispain.client.RecipeBookIsPainClient; +import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; @@ -26,7 +26,7 @@ public class RecipeBookGroupMixin { @Invoker("") static RecipeBookGroup newGroup(String internalName, int internalId, ItemStack... stacks) { - throw new AssertionError(); + throw new IllegalStateException(); } @Shadow @@ -57,19 +57,18 @@ public class RecipeBookGroupMixin { CRAFTING_SEARCH_LIST = new ArrayList<>(); CRAFTING_LIST = new ArrayList<>(); - for (ItemGroup itemGroup : ItemGroup.GROUPS) { - if (itemGroup != ItemGroup.HOTBAR && itemGroup != ItemGroup.INVENTORY && itemGroup != ItemGroup.SEARCH) { - String name = "P_CRAFTING_" + itemGroup.getIndex(); - var recipeBookGroup = newGroup(name, last.ordinal() + 1, itemGroup.getIcon()); - RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.put(recipeBookGroup, itemGroup); - RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.put(itemGroup, recipeBookGroup); + Arrays.stream(ItemGroup.GROUPS).filter(itemGroup -> itemGroup != ItemGroup.HOTBAR && itemGroup != ItemGroup.INVENTORY && itemGroup != ItemGroup.SEARCH) + .forEach(itemGroup -> { + String name = "P_CRAFTING_" + itemGroup.getIndex(); + var recipeBookGroup = newGroup(name, last.ordinal() + 1, itemGroup.getIcon()); + RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.put(recipeBookGroup, itemGroup); + RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.put(itemGroup, recipeBookGroup); - CRAFTING_LIST.add(recipeBookGroup); - CRAFTING_SEARCH_LIST.add(recipeBookGroup); + CRAFTING_LIST.add(recipeBookGroup); + CRAFTING_SEARCH_LIST.add(recipeBookGroup); - groups.add(recipeBookGroup); - } - } + groups.add(recipeBookGroup); + }); CRAFTING_LIST.add(0, RecipeBookGroup.CRAFTING_SEARCH); field_1805 = groups.toArray(RecipeBookGroup[]::new); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java index 9355844..73a0f5b 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java @@ -2,7 +2,7 @@ package me.melontini.recipebookispain.mixin; import me.melontini.recipebookispain.access.RecipeBookWidgetAccess; import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; -import me.melontini.recipebookispain.client.RecipeBookIsPainClient; +import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; @@ -14,6 +14,7 @@ import net.minecraft.item.ItemGroup; import net.minecraft.screen.AbstractRecipeScreenHandler; import net.minecraft.text.Text; import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -35,19 +36,19 @@ public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { protected MinecraftClient client; @Shadow protected AbstractRecipeScreenHandler craftingScreenHandler; - @Unique - private int page = 0; + @Shadow + private int parentWidth; @Shadow private int parentHeight; @Shadow private int leftOffset; @Shadow - private ClientRecipeBook recipeBook; - @Shadow @Final private List tabButtons; @Shadow - private int parentWidth; + private ClientRecipeBook recipeBook; + @Unique + private int page = 0; @Unique private int pages; @Unique @@ -55,63 +56,64 @@ public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { @Unique private ToggleButtonWidget prevPageButton; @Shadow - @Nullable - private RecipeGroupButtonWidget currentTab; + private @Nullable RecipeGroupButtonWidget currentTab; @Shadow public abstract boolean isOpen(); @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget;setToggled(Z)V", shift = At.Shift.BEFORE), method = "reset") - private void recipe_book_is_pain$init(CallbackInfo ci) { + private void cracker_util$reset(CallbackInfo ci) { int a = (this.parentWidth - 147) / 2 - this.leftOffset; int s = (this.parentHeight + 166) / 2; this.nextPageButton = new ToggleButtonWidget(a + 14, s, 12, 17, false); this.nextPageButton.setTextureUV(1, 208, 13, 18, TEXTURE); this.prevPageButton = new ToggleButtonWidget(a - 35, s, 12, 17, true); this.prevPageButton.setTextureUV(1, 208, 13, 18, TEXTURE); - page = 0; + this.page = 0; } @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V", shift = At.Shift.BEFORE), method = "render") - private void recipe_book_is_pain$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { - renderPageText(matrices); - for (RecipeGroupButtonWidget widget : tabButtons) { - if (widget.visible) { + private void cracker_util$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { + cracker_util$renderPageText(matrices); + this.prevPageButton.render(matrices, mouseX, mouseY, delta); + this.nextPageButton.render(matrices, mouseX, mouseY, delta); + + if (client.currentScreen != null) { + this.tabButtons.stream().filter(widget -> widget.visible && widget.isHovered()).forEach(widget -> { if (widget.getCategory().name().contains("_SEARCH")) { - if (widget.isHovered()) - client.currentScreen.renderTooltip(matrices, ItemGroup.SEARCH.getDisplayName(), mouseX, mouseY); + client.currentScreen.renderTooltip(matrices, ItemGroup.SEARCH.getDisplayName(), mouseX, mouseY); } else { - if (RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.get(widget.getCategory()) != null) { + if (RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.containsKey(widget.getCategory())) { Text text = RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.get(widget.getCategory()).getDisplayName(); - if (text != null) - if (widget.isHovered()) client.currentScreen.renderTooltip(matrices, text, mouseX, mouseY); + if (text != null) { + client.currentScreen.renderTooltip(matrices, text, mouseX, mouseY); + } } } - } + }); } - this.prevPageButton.render(matrices, mouseX, mouseY, delta); - this.nextPageButton.render(matrices, mouseX, mouseY, delta); } @Unique - private void renderPageText(MatrixStack matrices) { + private void cracker_util$renderPageText(MatrixStack matrices) { int x = (this.parentWidth - 135) / 2 - this.leftOffset - 30; int y = (this.parentHeight + 169) / 2 + 3; - int displayPage = page + 1; - int displayPages = pages + 1; - if (this.pages > 0) { + int displayPage = this.page + 1; + int displayPages = this.pages; + if (this.pages > 1) { String string = "" + displayPage + "/" + displayPages; int textLength = this.client.textRenderer.getWidth(string); this.client.textRenderer.draw(matrices, string, (x - textLength / 2F + 20F), y, -1); } } - @Unique //mmm spaghettio - private void updatePages() { - for (RecipeGroupButtonWidget widget : tabButtons) { - if (((RecipeGroupButtonAccess) widget).getPage() == page) { + @Unique + @Override + public void updatePages() { + for (RecipeGroupButtonWidget widget : this.tabButtons) { + if (((RecipeGroupButtonAccess)widget).getPage() == this.page) { RecipeBookGroup recipeBookGroup = widget.getCategory(); - if (client.currentScreen != null) if (recipeBookGroup.name().contains("_SEARCH")) { + if (recipeBookGroup.name().contains("_SEARCH")) { widget.visible = true; } else if (widget.hasKnownRecipes(recipeBook)) { widget.visible = true; @@ -124,80 +126,76 @@ public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { } @Inject(at = @At("HEAD"), method = "mouseClicked", cancellable = true) - private void recipe_book_is_pain$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { + private void cracker_util$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { if (this.client.player != null) if (this.isOpen() && !this.client.player.isSpectator()) { - if (nextPageButton.mouseClicked(mouseX, mouseY, button)) { - if (this.page <= this.pages) ++this.page; - updatePages(); - updatePageSwitchButtons(); + if (this.nextPageButton.mouseClicked(mouseX, mouseY, button)) { + if (this.page < (this.pages - 1)) setPage(++this.page); cir.setReturnValue(true); - } else if (prevPageButton.mouseClicked(mouseX, mouseY, button)) { - if (this.page > 0) --this.page; - updatePages(); - updatePageSwitchButtons(); + } else if (this.prevPageButton.mouseClicked(mouseX, mouseY, button)) { + if (this.page > 0) setPage(--this.page); cir.setReturnValue(true); } } } @Unique - private void updatePageSwitchButtons() { - this.nextPageButton.visible = this.pages > 0 && this.page < this.pages; - this.prevPageButton.visible = this.pages > 0 && this.page != 0; + @Override + public void updatePageSwitchButtons() { + if (this.nextPageButton != null) this.nextPageButton.visible = this.pages > 1 && this.page < (this.pages - 1); + if (this.prevPageButton != null) this.prevPageButton.visible = this.pages > 1 && this.page != 0; } - - @SuppressWarnings("IntegerDivisionInFloatingPointContext") @Inject(at = @At("HEAD"), method = "refreshTabButtons", cancellable = true) - private void recipe_book_is_pain$refresh(CallbackInfo ci) { + private void cracker_util$refresh(CallbackInfo ci) { this.pages = 0; - int p = 0; - int c = (this.parentWidth - 147) / 2 - this.leftOffset - 30; - int b = (this.parentHeight - 166) / 2 + 3; - int l = 0; + int wc = 0; + int x = (this.parentWidth - 147) / 2 - this.leftOffset - 30; + int y = (this.parentHeight - 166) / 2 + 3; + int index = 0; this.tabButtons.clear(); - for (RecipeBookGroup group : RecipeBookGroup.getGroups(this.craftingScreenHandler.getCategory())) { - var widget = new RecipeGroupButtonWidget(group); - if (group.name().contains("_SEARCH") || widget.hasKnownRecipes(recipeBook)) this.tabButtons.add(widget); - } - - if (this.currentTab != null) { - this.currentTab = this.tabButtons.stream().filter((button) -> - button.getCategory().equals(this.currentTab.getCategory())).findFirst().orElse(null); - } - if (this.currentTab == null) { - this.currentTab = this.tabButtons.get(0); - } + this.tabButtons.addAll(RecipeBookGroup.getGroups(this.craftingScreenHandler.getCategory()) + .stream().map(RecipeGroupButtonWidget::new) + .filter(widget -> widget.getCategory().name().contains("_SEARCH") || widget.hasKnownRecipes(this.recipeBook)) + .toList()); + this.currentTab = this.currentTab == null ? this.tabButtons.get(0) : this.tabButtons.stream() + .filter(button -> button.getCategory().equals(this.currentTab.getCategory())) + .findFirst().orElse(null); this.currentTab.setToggled(true); for (RecipeGroupButtonWidget widget : this.tabButtons) { - RecipeBookGroup recipeBookGroup = widget.getCategory(); - if (recipeBookGroup.name().contains("_SEARCH") || widget.hasKnownRecipes(recipeBook)) { - ((RecipeGroupButtonAccess) widget).setPage((int) Math.ceil(p / 6)); - widget.setPos(c, b + 27 * l++); - widget.visible = ((RecipeGroupButtonAccess) widget).getPage() == page; - if (l == 6) { - l = 0; - } - p++; - } + ((RecipeGroupButtonAccess)widget).setPage(MathHelper.fastFloor(wc / 6f)); + widget.setPos(x, y + 27 * index++); + if (index == 6) index = 0; + wc++; } - --p; - this.pages = (int) Math.ceil(p / 6); + this.pages = MathHelper.ceil(wc / 6f); updatePages(); updatePageSwitchButtons(); ci.cancel(); } + @Unique @Override - public int getBookPage() { - return page; + public int getPage() { + return this.page; } + @Unique @Override - public void setBookPage(int page) { + public void setPage(int page) { + if (page < 0) page = 0; + if (page > pages - 1) page = pages - 1; + this.page = page; + updatePages(); + updatePageSwitchButtons(); + } + + @Unique + @Override + public int getPageCount() { + return this.pages; } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index f51a77f..c156a15 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -13,10 +13,7 @@ "environment": "client", "entrypoints": { "client": [ - "me.melontini.recipebookispain.client.RecipeBookIsPainClient" - ], - "main": [ - "me.melontini.recipebookispain.RecipeBookIsPain" + "me.melontini.recipebookispain.RecipeBookIsPainClient" ] }, "mixins": [ -- 2.51.2 From f11d11122b26c4193fb1c3ba3d147cf0f7845485 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 16 Mar 2023 15:45:34 +0700 Subject: [PATCH 07/47] bit better --- .../mixin/ClientRecipeBookMixin.java | 2 +- .../mixin/MouseWheelieCompatMixin.java | 2 +- .../recipebookispain/mixin/RecipeBookGroupMixin.java | 6 +++--- .../mixin/RecipeBookWidgetMixin.java | 12 ++++++------ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index aa3c99d..8318b24 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -20,7 +20,7 @@ public class ClientRecipeBookMixin { } @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) - private static void recipe_book_is_pain$getGroupForRecipe(Recipe recipe, CallbackInfoReturnable cir) { + private static void rbip$getGroupForRecipe(Recipe recipe, CallbackInfoReturnable cir) { RecipeType recipeType = recipe.getType(); if (recipeType == RecipeType.CRAFTING) { ItemStack itemStack = recipe.getOutput(); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index c8cd6dc..18d07c1 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -26,7 +26,7 @@ public abstract class MouseWheelieCompatMixin { @SuppressWarnings("ReferenceToMixin") @Dynamic(mixin = MixinRecipeBookWidget.class) @Inject(at = @At(value = "INVOKE", target = "net/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget.setToggled (Z)V", ordinal = 1, shift = At.Shift.AFTER), method = "mouseWheelie_scrollRecipeBook") - private void inject(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { + private void rbip$scrollPages(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { RecipeBookWidget bookWidget = (RecipeBookWidget) (Object) this; RecipeBookWidgetAccess widgetAccess = ((RecipeBookWidgetAccess) bookWidget); RecipeGroupButtonAccess buttonAccess = ((RecipeGroupButtonAccess) this.currentTab); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java index b6ba11b..855cd22 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java @@ -42,7 +42,7 @@ public class RecipeBookGroupMixin { // pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work @SuppressWarnings("unchecked") @Redirect(at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableList;of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lcom/google/common/collect/ImmutableList;"), remap = false, method = "") - private static ImmutableList listOf(E e1, E e2, E e3, E e4) { + private static ImmutableList rbip$listOf(E e1, E e2, E e3, E e4) { if (e1 == RecipeBookGroup.CRAFTING_EQUIPMENT) { return (ImmutableList) ImmutableList.copyOf(CRAFTING_SEARCH_LIST); } @@ -50,7 +50,7 @@ public class RecipeBookGroupMixin { } @Inject(at = @At(value = "FIELD", opcode = Opcodes.PUTSTATIC, target = "Lnet/minecraft/client/recipebook/RecipeBookGroup;field_1805:[Lnet/minecraft/client/recipebook/RecipeBookGroup;", shift = At.Shift.AFTER), method = "") - private static void recipe_book_is_pain$addCustomGroups(CallbackInfo ci) { + private static void rbip$addCustomGroups(CallbackInfo ci) { var groups = new ArrayList<>(Arrays.asList(field_1805)); var last = groups.get(groups.size() - 1); @@ -76,7 +76,7 @@ public class RecipeBookGroupMixin { } @Inject(at = @At("HEAD"), method = "getGroups", cancellable = true) - private static void recipe_book_is_pain$getGroups(RecipeBookCategory category, CallbackInfoReturnable> cir) { + private static void rbip$getGroups(RecipeBookCategory category, CallbackInfoReturnable> cir) { if (category == RecipeBookCategory.CRAFTING) cir.setReturnValue(CRAFTING_LIST); } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java index 73a0f5b..a1f8e79 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java @@ -62,7 +62,7 @@ public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { public abstract boolean isOpen(); @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget;setToggled(Z)V", shift = At.Shift.BEFORE), method = "reset") - private void cracker_util$reset(CallbackInfo ci) { + private void rbip$reset(CallbackInfo ci) { int a = (this.parentWidth - 147) / 2 - this.leftOffset; int s = (this.parentHeight + 166) / 2; this.nextPageButton = new ToggleButtonWidget(a + 14, s, 12, 17, false); @@ -73,8 +73,8 @@ public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { } @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V", shift = At.Shift.BEFORE), method = "render") - private void cracker_util$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { - cracker_util$renderPageText(matrices); + private void rbip$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { + rbip$renderPageText(matrices); this.prevPageButton.render(matrices, mouseX, mouseY, delta); this.nextPageButton.render(matrices, mouseX, mouseY, delta); @@ -95,7 +95,7 @@ public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { } @Unique - private void cracker_util$renderPageText(MatrixStack matrices) { + private void rbip$renderPageText(MatrixStack matrices) { int x = (this.parentWidth - 135) / 2 - this.leftOffset - 30; int y = (this.parentHeight + 169) / 2 + 3; int displayPage = this.page + 1; @@ -126,7 +126,7 @@ public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { } @Inject(at = @At("HEAD"), method = "mouseClicked", cancellable = true) - private void cracker_util$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { + private void rbip$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { if (this.client.player != null) if (this.isOpen() && !this.client.player.isSpectator()) { if (this.nextPageButton.mouseClicked(mouseX, mouseY, button)) { if (this.page < (this.pages - 1)) setPage(++this.page); @@ -146,7 +146,7 @@ public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { } @Inject(at = @At("HEAD"), method = "refreshTabButtons", cancellable = true) - private void cracker_util$refresh(CallbackInfo ci) { + private void rbip$refresh(CallbackInfo ci) { this.pages = 0; int wc = 0; int x = (this.parentWidth - 147) / 2 - this.leftOffset - 30; -- 2.51.2 From 7f01fc1ad944ae6f86af8a2241cf5fe6d72af966 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Sun, 19 Mar 2023 15:17:35 +0700 Subject: [PATCH 08/47] 1.19.2 --- CHANGELOG.md | 5 +- gradle.properties | 2 +- .../mixin/ClientRecipeBookMixin.java | 7 +-- .../mixin/MixinConfigPlugin.java | 47 +------------------ .../mixin/MouseWheelieCompatMixin.java | 5 +- .../mixin/RecipeBookWidgetMixin.java | 2 +- 6 files changed, 14 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b5f5fd..2387444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,5 @@ ### What's new: -* Fixed pages not changing when scrolling with Mouse Wheelie - -> Compatible with m-tweaks =>0.4.5-1.19.2. \ No newline at end of file +* Fixed crash with Tom's Simple Storage +* Updated CrackerUtil \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index c701970..894cbde 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,4 +9,4 @@ loader_version=0.14.11 mod_version=0.8.1-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.1.2-1.19.2 +cracker_util=v0.2.1-1.19.2 diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index a31a845..b74cc32 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -1,6 +1,7 @@ package me.melontini.recipebookispain.mixin; import me.melontini.crackerutil.CrackerLog; +import me.melontini.crackerutil.util.EnumWrapper; import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.recipebook.ClientRecipeBook; import net.minecraft.client.recipebook.RecipeBookGroup; @@ -22,14 +23,14 @@ import java.util.List; public class ClientRecipeBookMixin { @Inject(at = @At("HEAD"), method = "") - private static void recipe_book_is_pain$clinit(CallbackInfo ci) { + private static void rbip$clinit(CallbackInfo ci) { List CRAFTING_LIST = new ArrayList<>(); List CRAFTING_SEARCH_LIST = new ArrayList<>(); Arrays.stream(ItemGroup.GROUPS).filter(itemGroup -> itemGroup != ItemGroup.HOTBAR && itemGroup != ItemGroup.INVENTORY && itemGroup != ItemGroup.SEARCH) .forEach(itemGroup -> { String name = "P_CRAFTING_" + itemGroup.getIndex(); - RecipeBookGroup recipeBookGroup = (RecipeBookGroup) RecipeBookGroup.CRAFTING_SEARCH.extend(name, (Object[]) new ItemStack[]{itemGroup.getIcon()}); + RecipeBookGroup recipeBookGroup = EnumWrapper.RecipeBookGroup.extend(name, itemGroup.getIcon()); RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.put(recipeBookGroup, itemGroup); RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.put(itemGroup, recipeBookGroup); @@ -46,7 +47,7 @@ public class ClientRecipeBookMixin { } @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) - private static void recipe_book_is_pain$getGroupForRecipe(Recipe recipe, CallbackInfoReturnable cir) { + private static void rbip$getGroupForRecipe(Recipe recipe, CallbackInfoReturnable cir) { RecipeType recipeType = recipe.getType(); if (recipeType == RecipeType.CRAFTING) { ItemStack itemStack = recipe.getOutput(); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java index 7e2a6cf..77b4246 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java @@ -1,49 +1,6 @@ package me.melontini.recipebookispain.mixin; -import net.fabricmc.loader.api.FabricLoader; -import org.objectweb.asm.tree.ClassNode; -import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; +import me.melontini.crackerutil.util.mixin.ExtendedPlugin; -import java.util.List; -import java.util.Objects; -import java.util.Set; - -public class MixinConfigPlugin implements IMixinConfigPlugin { - @Override - public void onLoad(String mixinPackage) { - - } - - @Override - public String getRefMapperConfig() { - return null; - } - - @Override - public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - if (Objects.equals(mixinClassName, "me.melontini.recipebookispain.mixin.MouseWheelieCompatMixin") && !FabricLoader.getInstance().isModLoaded("mousewheelie")) - return false; - return true; - } - - @Override - public void acceptTargets(Set myTargets, Set otherTargets) { - - } - - @Override - public List getMixins() { - return null; - } - - @Override - public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - - } - - @Override - public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - - } +public class MixinConfigPlugin extends ExtendedPlugin { } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index 8fb2ca1..1f11dd7 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -2,6 +2,8 @@ package me.melontini.recipebookispain.mixin; import de.siphalor.mousewheelie.client.mixin.gui.other.MixinRecipeBookWidget; import de.siphalor.mousewheelie.client.util.ScrollAction; +import me.melontini.crackerutil.util.mixin.MixinShouldApply; +import me.melontini.crackerutil.util.mixin.Mod; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; import org.jetbrains.annotations.Nullable; @@ -15,6 +17,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Pseudo @Mixin(value = RecipeBookWidget.class, priority = 1001) +@MixinShouldApply(mods = @Mod("mousewheelie")) public abstract class MouseWheelieCompatMixin { @Shadow @@ -24,7 +27,7 @@ public abstract class MouseWheelieCompatMixin { @SuppressWarnings("ReferenceToMixin") @Dynamic(mixin = MixinRecipeBookWidget.class) @Inject(at = @At(value = "INVOKE", target = "net/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget.setToggled (Z)V", ordinal = 1, shift = At.Shift.AFTER), method = "mouseWheelie_scrollRecipeBook") - private void inject(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { + private void rbip$scrollPages(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { if (currentTab == null) return;//how tho? RecipeBookWidget bookWidget = (RecipeBookWidget) (Object) this; diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java index be98a43..410222b 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java @@ -25,7 +25,7 @@ public abstract class RecipeBookWidgetMixin { private List tabButtons; @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V", shift = At.Shift.BEFORE), method = "render") - private void recipe_book_is_pain$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { + private void rbip$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { if (client.currentScreen != null) { this.tabButtons.stream().filter(widget -> widget.visible && widget.isHovered()).forEach(widget -> { if (widget.getCategory().name().contains("_SEARCH")) { -- 2.51.2 From b9c6809f7384115d72b683bbc5579438e3020d80 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Sun, 19 Mar 2023 17:59:44 +0700 Subject: [PATCH 09/47] bump --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 894cbde..e470b45 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ minecraft_version=1.19.2 yarn_mappings=1.19.2+build.28 loader_version=0.14.11 # Mod Properties -mod_version=0.8.1-1.19.2 +mod_version=0.9.0-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain cracker_util=v0.2.1-1.19.2 -- 2.51.2 From 2042c451f301f6e5334b2ee0d7e6bacebd64f108 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Sun, 19 Mar 2023 18:00:02 +0700 Subject: [PATCH 10/47] sad --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2387444..be2e381 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.8.1-1.19.2 +## 0.9.0-1.19.2 ### What's new: -- 2.51.2 From b4e4cc07290de527438361cea28a2f7230969dde Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Sun, 19 Mar 2023 18:01:42 +0700 Subject: [PATCH 11/47] sad --- CHANGELOG.md | 2 +- gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86677b7..0293a9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.7.2-1.18 +## 0.8.0-1.18 ### What's new: diff --git a/gradle.properties b/gradle.properties index 208d63a..f260257 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ minecraft_version=1.18 yarn_mappings=1.18+build.1 loader_version=0.14.8 # Mod Properties -mod_version=0.7.1-1.18 +mod_version=0.8.0-1.18 maven_group=me.melontini archives_base_name=recipe-book-is-pain -- 2.51.2 From 7cdcce7fbcc9d62b006bee7e21b1cfb67cfd4e4e Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Sun, 19 Mar 2023 18:34:10 +0700 Subject: [PATCH 12/47] redundant --- .../recipebookispain/mixin/MouseWheelieCompatMixin.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index 1f11dd7..69a829e 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -33,8 +33,6 @@ public abstract class MouseWheelieCompatMixin { RecipeBookWidget bookWidget = (RecipeBookWidget) (Object) this; if (bookWidget.getPage() != currentTab.getPage()) { bookWidget.setPage(currentTab.getPage()); - bookWidget.updatePages(); - bookWidget.updatePageSwitchButtons(); } } } -- 2.51.2 From 777a5d2adbc0c9bf03fd07b1fe896c4c4a7d470d Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Mon, 3 Apr 2023 17:02:17 +0700 Subject: [PATCH 13/47] > life --- .github/workflows/build.yml | 25 +++++++------- .github/workflows/publish.yml | 32 ++++++++++++------ CHANGELOG.md | 7 ++-- build.gradle | 12 +++++++ gradle.properties | 2 +- .../mixin/ClientRecipeBookMixin.java | 6 ++-- .../mixin/RecipeBookGroupMixin.java | 17 +++++----- .../mixin/RecipeBookWidgetMixin.java | 2 +- .../assets/recipe-book-is-pain/icon.png | Bin 26163 -> 22631 bytes 9 files changed, 65 insertions(+), 38 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 23627fd..a1050dc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,37 +4,38 @@ # against bad commits. name: build -on: [pull_request, push] +on: [ pull_request, push ] jobs: build: strategy: matrix: # Use these Java versions - java: [ - 17 - ] + java: [ 17 ] # and run on both Linux and Windows - os: [ubuntu-20.04, windows-latest] + os: [ ubuntu-20.04 ] runs-on: ${{ matrix.os }} steps: - name: checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3.4.0 - name: validate gradle wrapper uses: gradle/wrapper-validation-action@v1 - name: setup jdk ${{ matrix.java }} - uses: actions/setup-java@v2 + uses: actions/setup-java@v3.10.0 with: - distribution: adopt + distribution: 'temurin' java-version: ${{ matrix.java }} - name: make gradle wrapper executable if: ${{ runner.os != 'Windows' }} run: chmod +x ./gradlew + - name: Retrieve Version #https://stackoverflow.com/questions/71089787/how-to-get-version-name-from-android-gradle-file-in-github-actions + run: | + echo "VERSION_INFORMATION=$(${{github.workspace}}/gradlew -q printVersionName)" >> $GITHUB_ENV + echo "GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV - name: build run: ./gradlew build - name: capture build artifacts - if: ${{ runner.os == 'Linux' && matrix.java == '17' }} # Only upload artifacts built from LTS java on one OS - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3.1.2 with: - name: Artifacts - path: build/libs/ + name: ${{ env.VERSION_INFORMATION }} [${{ env.GIT_HASH }}] #https://stackoverflow.com/questions/58886293/getting-current-branch-and-commit-hash-in-github-action + path: build/libs/ \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index bd0d2c4..45ee75c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,3 +1,4 @@ +name: publish on: push: tags: @@ -8,29 +9,29 @@ jobs: runs-on: ubuntu-latest steps: - name: checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3.4.0 - name: validate gradle wrapper uses: gradle/wrapper-validation-action@v1 - name: setup jdk 17 - uses: actions/setup-java@v2 + uses: actions/setup-java@v3.10.0 with: - distribution: adopt + distribution: 'temurin' java-version: 17 - name: make gradle wrapper executable run: chmod +x ./gradlew + - name: Retrieve Version #https://stackoverflow.com/questions/71089787/how-to-get-version-name-from-android-gradle-file-in-github-actions + run: | + echo "VERSION_INFORMATION=$(${{github.workspace}}/gradlew -q printVersionName)" >> $GITHUB_ENV + echo "VERSION_PLAIN=$(${{github.workspace}}/gradlew -q printVersion)" >> $GITHUB_ENV - name: build run: ./gradlew build - name: Publish Minecraft Mods uses: Kir-Antipov/mc-publish@v3.2 with: version-type: release - modrinth-id: etNS9OnA - modrinth-token: ${{ secrets.MODRINTH_TOKEN }} - modrinth-featured: true - modrinth-unfeature-mode: subset - - curseforge-id: 643246 - curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} + changelog-file: CHANGELOG.md + name: ${{ env.VERSION_INFORMATION }} + version: ${{ env.VERSION_PLAIN }} game-versions: | 1.18 @@ -39,6 +40,15 @@ jobs: 1.19 1.19.1 1.19.2 + loaders: | fabric - changelog-file: CHANGELOG.md \ No newline at end of file + + modrinth-id: etNS9OnA + modrinth-token: ${{ secrets.MODRINTH_TOKEN }} + modrinth-featured: true + modrinth-unfeature-mode: subset + + + curseforge-id: 643246 + curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0293a9d..6e4c1c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,10 @@ -## 0.8.0-1.18 +## 0.8.1-1.18 ### What's new: -* mostly internal changes. +* Fixed RBIP's enum values having identical indexes. pretty epic. +* New icon. +* Updated GitHub CI. +* Removed `static` from ClientRecipeBookMixin. Supports: Minecraft 1.18, 1.18.1, 1.18.2, 1.19, 1.19.1, 1.19.2 \ No newline at end of file diff --git a/build.gradle b/build.gradle index 0973d98..6dded89 100644 --- a/build.gradle +++ b/build.gradle @@ -70,6 +70,18 @@ jar { } } +tasks.register('printVersionName') { + doLast { + println version.split("-")[0] + " (1.18 - 1.19.2)" + } +} + +tasks.register('printVersion') { + doLast { + println version + } +} + // configure the maven publication publishing { publications { diff --git a/gradle.properties b/gradle.properties index f260257..cb71d37 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ minecraft_version=1.18 yarn_mappings=1.18+build.1 loader_version=0.14.8 # Mod Properties -mod_version=0.8.0-1.18 +mod_version=0.8.1-1.18 maven_group=me.melontini archives_base_name=recipe-book-is-pain diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index 8318b24..1309f91 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -10,15 +10,15 @@ import net.minecraft.recipe.RecipeType; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(value = ClientRecipeBook.class, priority = 999) public class ClientRecipeBookMixin { - static { - //noinspection ResultOfMethodCallIgnored + @Inject(at = @At("HEAD"), method = "") + private static void rbip$clinit(CallbackInfo ci) { RecipeBookGroup.values(); } - @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) private static void rbip$getGroupForRecipe(Recipe recipe, CallbackInfoReturnable cir) { RecipeType recipeType = recipe.getType(); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java index 855cd22..8c2c5bd 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java @@ -6,6 +6,7 @@ import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.recipe.book.RecipeBookCategory; +import org.apache.commons.lang3.ArrayUtils; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.gen.Invoker; @@ -51,30 +52,30 @@ public class RecipeBookGroupMixin { @Inject(at = @At(value = "FIELD", opcode = Opcodes.PUTSTATIC, target = "Lnet/minecraft/client/recipebook/RecipeBookGroup;field_1805:[Lnet/minecraft/client/recipebook/RecipeBookGroup;", shift = At.Shift.AFTER), method = "") private static void rbip$addCustomGroups(CallbackInfo ci) { - var groups = new ArrayList<>(Arrays.asList(field_1805)); - var last = groups.get(groups.size() - 1); - CRAFTING_SEARCH_LIST = new ArrayList<>(); CRAFTING_LIST = new ArrayList<>(); Arrays.stream(ItemGroup.GROUPS).filter(itemGroup -> itemGroup != ItemGroup.HOTBAR && itemGroup != ItemGroup.INVENTORY && itemGroup != ItemGroup.SEARCH) .forEach(itemGroup -> { String name = "P_CRAFTING_" + itemGroup.getIndex(); - var recipeBookGroup = newGroup(name, last.ordinal() + 1, itemGroup.getIcon()); + var recipeBookGroup = rbip$extend(name, itemGroup.getIcon()); RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.put(recipeBookGroup, itemGroup); RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.put(itemGroup, recipeBookGroup); CRAFTING_LIST.add(recipeBookGroup); CRAFTING_SEARCH_LIST.add(recipeBookGroup); - - groups.add(recipeBookGroup); }); CRAFTING_LIST.add(0, RecipeBookGroup.CRAFTING_SEARCH); - - field_1805 = groups.toArray(RecipeBookGroup[]::new); RecipeBookIsPainClient.LOGGER.info("[RBIP] recipe book init complete"); } + private static RecipeBookGroup rbip$extend(String internalName, ItemStack... stacks) { + RecipeBookGroup last = field_1805[field_1805.length - 1]; + RecipeBookGroup enumConst = newGroup(internalName, last.ordinal() + 1, stacks); + field_1805 = ArrayUtils.add(field_1805, enumConst); + return enumConst; + } + @Inject(at = @At("HEAD"), method = "getGroups", cancellable = true) private static void rbip$getGroups(RecipeBookCategory category, CallbackInfoReturnable> cir) { if (category == RecipeBookCategory.CRAFTING) cir.setReturnValue(CRAFTING_LIST); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java index a1f8e79..82e74c0 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java @@ -170,7 +170,7 @@ public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { wc++; } - this.pages = MathHelper.ceil(wc / 6f); + this.pages = (int) Math.ceil(wc / 6f); updatePages(); updatePageSwitchButtons(); ci.cancel(); diff --git a/src/main/resources/assets/recipe-book-is-pain/icon.png b/src/main/resources/assets/recipe-book-is-pain/icon.png index 269967ec5bb35f69b46e5beaa6e1239ec64ea1a1..81b39384076a68e02a67055c10b46b51107fcb82 100644 GIT binary patch literal 22631 zcmeAS@N?(olHy`uVBq!ia0y~yV7Ly#9Bd2>44t({wlXj9gP2NHH)dFnGE+hE&XX6I)&* za`oH)doyp|{nFAhfk{PWVV3~UUhzt%MIx0-t~u|2GV$lwi)gzFNGq9Dyx1(>)up6# zp3PApaLM;LW*3FM>E+M={hP6=JT2Y(RM7L&={IItm%lrg^RE2d&gXNg^%xxz54Ch! zv6rvRKhV;-T2yVP&kPO$pQ4!tf(kR97$qt>7@SN!2ymc!$FnloWhJvo_fM+ zOe~XQ)O=Vt2Dt`~>A%=~V&*Ems%K=nS`#x(VaJ~L=Z~Z^`KJ_WE5)6=DtO0A=WFf1 zppv4=F=`<%I9*Dt=bdo+lMtBO`OIH^DcjT)xBJ$uWe_^Aa@~~UQKLf@lZ2=CqlX9d zKmC|c(aNJID~{>oV;bx zFDp}p*`DjPMUFIhykhs(`fGW&vR3x4Uh!J%$Uj>-u1!fZl}-1&zN=ef{iRh>Eyc>S z*-bC0To+~Xe>GdWvcyHnCHk40*G~t3Ic4Qm^{MNZJ=X32u-N@t-Wu25*VW3C-|d;0 za(TY-Nl^uXJ_RMsMc>}8_-}Z87cAfcs*pQmR>v?`&o~U$o0;*}Ub+neo3EHBwJ;vR>S}JjR{VVZ}Dxzso(> zt!4>&e#uj<^7!N}O+{3sKE^&t~Ig(7VNG zg4wTZTThjjHi@TJJe<*`YkabFYr_tYC5BNIinC^Kd1NA=ms|Zai=X}9{oT?w5kJ4& zU)odnMN7U!C2{>#FXi(s%5kUn2%in%W@g#e9KYp#%kB~;MvG^57HuJGT9m3j8Ms`n zZ+|FWZ5{6%uq~F^yUjjXS9zw>7{EeOSJgA^TF5qpRct&6{6(RD1EUc=-7%r`;?@mvlp6t{(M;_ z+;m~!@)=IsiepNW4#r+(E?%?KzwM8ls?2S@;03ih%`&g1+@tBk^hYW(Qzj_nvBvH5W$;EAXDY_v}bN6^@ z|J~QOpeymPcxTU&S%RF5lVkEaG9{aTt$lrcm+T=y7t_8^ft(zjoF8w7MI=d7beAtG zYGKw1TVHyl$>>Hgm&udK>!#+rtBI=Lm;U_l*7G~3zkZmW!&b(1_O$oPCnuv`7)1#9 zR!7YjGgT8_rMPoOw(0jbVGDH4PL}#M8f3|_GCnSOc4z6PxLu8!$#z+V=JytQaeZyj zOn>icUdI$6Y;738yfWN~@m1w>STzzi()C;a=TE;uJ9bsA*SoHG#uB>(=DVCVtgm{fL zRWBa8CZ_~m+3p^*+iv0inO}vxRz7i4csk`>eyYherC-GtgwE}rqIAaepRn(LiR(N& zdzMToTJYW_+;qnC;85jds|EiqlQ1X=IwO5>RUvoVhw?S9D|IqcHg$wV&kxPD_0p5Q zdFQpHd%T3;>si6vca_v{Y&VE*XKGFfdUkS!ypIIr1REbbNQlr8>sZv$ z)y4JX`SZtLUgkV`GRHO2Q}Ev@%jV7Leg`x4+s`^B2r|t3?9U}Bcy`A*(* z*3X)owWn--!HP>>&N{igo`Ee3XRVN*Y3SZ1er;D@-OUe=Es$yd@S$K!-d(A+(c6!$ z2wbetrPL>H-}m(N^yHi3-31l@&05$z_u0>XtP^?rqPOw?6P2wE3>j8SBst#CR@#@< za)sa3V@vsQz5J(%+?y-^%gs|*wDEoBzkhogz0Xf~D(Q%O9pSt-tEEkS&i!J(<8?N# zzA0yPJS{lz={oDo02Y~vR#JgiTz@i|pG;L*YvW-sk;!$bh~P#|38NYjx4u2hYooR{ zDa70=-+TGxk^KFC+rpopJ9w=0zw->=ko*2Vjgq)$GG-_C4TSN85EeVy!^NX9){lC1p$SiG^b0FB?rfczU zbHy8Oca{ihPrY-RgJZ8#xMkv1k-m(pcEVem)xYvGXe^xM@AdPq<=guW$=|2??z7w9 zqOj35zUJ3csWrd;rSnJ{J=vrr#_hyW_2ot5{OfBDGxyu|PxA7#4V~9}*W&K-Wp9M+ z-M1!qXibhO<#U$Q+&``JV5IA;m;cRL7*wB%T&udC{O`B+hqvYS3*7tV9_-Lwd^>V& zn9aWWIkn=9 zBJVg2d$l%dEn1`|v|vMz(#A^rKNGe}{x`4ul)Cy~D7)`$v!h*8?GH&!5juR5ij)kbR`-h01$(*~hFqxS1obEY;6yop^j z<@vPa^Xb;S@ewUIJI`42%Za$A9{6yP|52-W{Ho6#U8g0VpP%nOoo}t6Pf_gS;JL*= zC!NSMO*!UNV`cZ3RlUH@Q;~&p1IzWZ-+wYa)qL~x+pf%>X8+@68VXi>-3vMPFhuVt zf84bB5+}!=htlEkVF9NUKQB!G_~WsEjM+2?FHJ3N?ZRJQGG#1_SnB_N71xW|(J*O} zP)KO#!K94}Mn*!Oo}MpmY*dyq%ZXTQarDNG2%AqgOwP>xt8ggCZS!1xqn#n#@@GC? zn%Z|LsHwC6%%Lfo{nu9%UlWz#V+R!uz0&4M|Ns5nQSgvy(c;B|($d{-y;2KHUtjC! z?sm?|(9jX%ep6=M)!n_Z{C!-_my7N@zTc~!IAcb{;`jfq@Bi1zfB!eX*5~iLS2nVU zPmGzx;GfhtbzMrx)R4q0Z)Z+#iCCneq^{0x|NoD1+53CFmo5dF#`<}El>f;k*idF~+^f$1UI(=Inm?(Y4c%u}njE+9bN z_4AEq6_w|-#d{;lcFS6qy*c1-|F`9EJHN87F0XC%wWQ;w zU6=dKHK_WMp`xySopa?}KlL|d)^q&SW%$@vty-nfrKGV`fQ2z^wW!(bv&)(1Jht$u zOw#&S`(D7MmGRAqE$2=??F>0p;r%Ot+c!qDV2X9Y^^V;W=FO9v@lBR5=l(v~`1-%5 zTwGiimU@fZe7WG<(cQf|%(`s1tfi%;Mac_+Z}0AQ&zU1*A;V`O!zbVr5E#hlrD@UE zd^D-?Y+CcxtX2h%1yc?^ELgB;5mS>w!nZd!?e^zCIMC>kcTLVUefx>I^RE4!;r-QK z@a;zLEWx!bt555j3l@AxwOM9kw$$(Tk|~dFY)t;~=kxi(Pft9zWMAhKR`*-8ZQ{Z` zdt^Y7v}x0(2L%=a;^OVnc{>?{0I<=Y4d8r@ckq*w)e8j1$sv5C1OZ3{B$mW(7mL5rCwzIQLSC?5& zojUc$kH`HRD?g|4$k|A2PCM(Ak+I@>_PM#%?YXzNJ$!OuHtQ)3Rez$cs>vM5Ad`n-%&$VljvFp9p7Mh#>pZRt(EMm_4l52v!N;T&e zh{-N`a{N=+am_`GHXK@OQ(bEob|$(}OgHMso_PNSQ!&+K>q{-T+dsIxJ>3)3wMf6~!~UcHS5GutxMhpT>FN5%Z*9%KxT`d~ zN7hC?pHeXo+-U5RwSM$&_xo>>l0hLME!X4gW%=5f z`R)H~2!HhE)>iJ%&(9y9>~GikxGc#>ujgY(RI8Y z7Q5Pa&EwE_3SK6h%|htJ$)< z@AieR4tsbzf4}STK3T)+Z#gb58OPW0wKM{0?1u+`u5{``8q-lFV{L{d@`sPsxnON;x$F-g(6?ZM8K{0dDWRqEo_qAt!l zlVh)oooaaTBI9syXlN+Nr4y%4ZDnL;OL%ywRjPFDs#RX4Y|o!QU6^}&+m6S5))QvU zdbRm+_act=!;PCZ8G%AtU7h`Szx?ru%I*OnAuU~9TvMh_T^P5wD&z7p-Zoz8wzRXe zVlOE?`t|j-^4e53uX8yjYSS0)KQ$%dy3V0BiER_P)cxihSQEL~Am@g`p13f3KUeXfkzGJuKL3W@QjwiIciz~VEpC>7uV-`m`KHGfS7%BK z2{rxrQDKsGg@comGvn44&7h#5J1UQ#Hr=abfAG4W=fqLJZ%kh%zERt|&ef$=YPYwP zdET0dAzh4*udEC{apJ^*!~FI=Y`k}#zYg@8ICpMu>Fa9``|bZR94{1LVXXc2<=}?I z!xJV=Dsnxa^6uVVYr8m)*e93Hvz5sw3kFxkF6I#GdCXzicX>sEb@{s^FD@?TJ)W+r zs(NEXB6HZ1qup9F-29~EEA4+s%(dc3FlGN*e$WXQ|UjX4j^=AY@$5NTYX@t$${l%N=kii6p* z*(Ds&8K&Nbbqd9@!S2~YMKIfj^Mt(lYiZ}?)V|T#5(1K zKQ)g|yqBQyJk^z(9WZf<5@ z?l(8+F(+fDPef>F>ysxbTQV=RNlHp)+}TmMcFUF%Cp=utJ=zYu+_Y?!mV)}q##4`) z8Lq5+8_F755K@sIUJdh0i3&c}B@SQ)Z+yyxhB5%Sp4vU~rx zKdp1-TE@L@QE#~}x%1I&seb2(DNm;SPzg^gQ{>vrz4zM6>r3R6ChsZFxv013htI~< z4NMRByyuVi*E{8*aai*jr^<_vfR#g$$ob-W`d# z*5z*Z_tgqYO1@lHWF^A~Dl&e5d;8gmx?gO+dg*k zee~%S*WcgYkDoQaAM?8G(xpoV#m{^KqBj5W<&`!oS=s7!%ZN|!t3ZhM&UHVww)tG) z2%j`{$2#MHt6y#g2L~$_v;;EFd}_nFz*GL%hqEFv*CkeD>$Ek{LU#Y{Z z+Nx$8*|p7qqtW@xJpPL<)=5c8OAN(dUpJb3Vn%|aMbjy*`|AXRqgdG4y_5Ay*RWQY zrp!2X(3FEI$h9D&&zGDLB!`vae3~co>Q-v zt?;N__m$h@@`YMnJ4#THYloMe}F8G57NJF8uK!@yYY&&LXY?P69$gO~-nrmF?{85*)Wh zMn;}EdGg?ki;I~r?bByrWo3T;GHnU$`;K=Oa?yjt-$ET>MxMIzkBR@Ys2NnNK zO-xUoKUX$16nuMoyZidMy*6(5!`b6&KC*(EU(4s${hD-4gX>hcvt)i|+`m)NadFRk zf|{+=)>Vm!h%Z>PhDTBHo@$k+CudyMOVy4=9o6smif3kK+HK`bz4WAwSNg-P?DdI9 zIs~_R-QAXSlnc~$zr4)1`1iX_n~Y>^t3=fO<~X>zvPzldbo9wuv*}d1T=3Bk)NQ>r zdy$*gqRwnKzI%;(_Smd{VpaM|WSQ^mHh1}2k+sp=zwOR-;!sjnF8qAf{Q9k*yNjRu zfohD3k4MEFIT)9Q%>DK0@AvzM^R_4d`SH=i!^5GVzyQ?jHqE~FVCC|8tFC^pYFe@Av!3A0Hi!*p$M#YL!aqOo67myUSNU^jV~lbZW}3vxiSKJ+{#Fn6B({Z$VxQ zvxT4a@zWuk>unvtNI`_4s&y z_OTnF;LqFtw@gG#Ea}n`PmAhrI&FNitAxCFUN65_$==Q{&!)iogRSVAk-A{#4naY= zlP9bBPM9{Wt(99`$=qE0@v+|3*Y<|9Gwq(SUH$mRB+Vr*zrGmyUpf-Xc1ZAz?H=(d zm!w!X&9keOnqU9Va$C;LrZsDHL_|a!1XxPm-;>pi+Tw73Uv1%KU-QIAM>;`;>ZTOV zYwKdWA3aKPag|&yapAsuRFu@MZMoeiC#x^czP`@G+uOOK!eU<4E6p>rOua+-FJHQ3 zkbBGIPSxwRjOY1OGt@kdEY~s4HEh1Sa`A7)PxkSpe{$YD>I#~)Oz$0nI^7vSfg6S=y-T|6lni{xqLpTq2E6@mVfu%zB6ZhY<@gw&bYo# z_E^7s|MvTJx7Wt44qLmS`g>l0*T;{?!c?@mYE-(L%3cb6@g z0;>4U)@;weZ#T!Pl*{J)<9pTbSru8TzrS<6yv(=o*OreK{0xT<9}bMHtUPX0#MRl+ zcyjKE;=NOf8H68XKbqwf6f`O8&^Pv8Dbqt6laF6{yuskHf%&}WSKs(A(s=aZ;^K@; zOE_O$U!R}xHdsJfx_gn*`_(66vI^E5x#Xq2$V;2A=ltm{N8=}NxS3;7_^9Rn<$J-w z!3PUv_Wk>nE#PF3bw%TF6*C);Lr#v4OW+ah^?RBWo!b;lOhjzXKmPOcv)q1tOUp>- zd#45G%+}}bF`k)x#l>K|6$K%B)!q?R-=$ z`f5X)IoHcQ8eS~MXFpumn`M&Obau9R@_`1%x~tDE_-4+WsiC8D;Z1Lpz^Y|(6yZidS{fe#q z{q5-Y`}OsK@0RYeD0wlVY}S6G-!pp8JYWd$vzl-$mZfiVYeCTaw8IOI7__KY`OlS^ zEbzE6Qj#?=G;oLep5xCC>)7tOl0I$Gh8BbQJ0HD$S~lfLh5vlrTdpBffBE?bOnH1e zBuD@2J_aj>J6GPQx!l;Z{CrPD^lMtNuS5)SrA(QI_NG?*4dsd>yC} zzGqvo_=@=bcHiFIeEhLyd*0m*6(5s&q|M)L3g+dPw_Bq+eNtR6lh#QM6=gPdh871F z2W{B}i@vu%YaC=cYQyn zwcI}_VB#X1^S>Y6`=_L)!e+S8Fz&U>_3m#kyjStPDchYkt4%I5GxNva@Avh&b~-sb zn>ucyx)-I5*qsMUjs1bmyJ#oVa~s8aa4*kIu8L zR_JQnp7YV>{pad;yWiXG`TcIU_|v*o&3|{BZ=S4bn|mbJCT-K}TdayKO$r%I1;#g<5GB!^H}GZoo234FHcWB>+-c|YgL=rnCLT%c3ZHW_NAAJ>nGUeE0KD@U_V{IeoU>AtO=jl- z^Z1(P{OPsbuEpYtuiMvjr~UiJZZ?~D_V-*qjhEAPBAXr_ZvVYEt5bnvhFz_d-LDtQ zQ>Ofg(=nWIV_T}SQd4Kng$ELuM?JI-NeaI;+FTV^x?)qv!|CyLj0|61US{_e(>-`? zZS=W_{YHTc8Hl>+9>+m#s4GKH9V~`S_#T`TKcK)c#~{ zKipVr{h#5uqv28En^*X*r+A*2tkP-XJTvI!~DYc_xt_*-|yGUPYJq_V^$#3zSzBgQRL<{P?IS!QSs8{%NO@ne{V=LWop>) z!(dJ9?rmY5HnxdZSA|L#Cb{&^TbO*jZ-!y=F;(y6+CM)EJ4By5IK;dz&RjB4=9SCJ z?i8J!NlFaMC-0hD{x=Cte5{yk5u&)rTC-t&9sp`64Q6Ym^;?tFJfk@B2H<^QkD zdt|Gj^I>0JL8YUm7S|qicX8K?%k_O8uzbn8bvs*DU_soJk5h`%tJRm;*^3@#=RJO; z-oNE&l4Dw$+Pj_4<<`XP6uMvgUAB!+wkvFH)WggE_O7X^s%d9uwc7vxBb>kYt5_Sq z{JUr0PidYy*jRi_^U{rUZC%~3b@v&x&Wk*%zhB?pE?0FT{qC!z$H#grzTHgEF3HWv z(0EgJzwf6*;@w@P9lcY6g1J}CQuo%dJ*m+#=be|DL_<{~gDB&~ppGl1f9IbHlu=?W zD&`6(yHo9M_e3C2=5?)EW>Sb!Uf$zq+l=`)?k&$M$+)gKMXchzMe5H~4gD2+KbxNr zYAJhrt8%R~hvVa8y|(k-7uU-F`T2algmszDysB54OO`J`oVFR%j+QXXk(j0v*>pXw znin)?SXpWL?99w&zqwWq*KWUesF~jm)Q-+t_D24^W#3o!S7`_0%ar)7{c;@x0|k|o zviAS5>h9{|ntzaW9;n56-ReYX=c!X(U+b=?t#ynMQ9s*iGDqj6gyoWrVvOfK=QFu0 zd|=RLVA6lfJty1d*yl@WQKGNeWUb4N$d=z}+*$nm(L{H-!1Vi{Z2Cc|@ud3vBa8d( zxEuvQ?S4lQSDnaBEc5GrY4*w4N?ow@PgQOG@wngq)tr~jh0O1k z1k2u^Sia}OA#Ttpn3k5-hP=1^8=_*~>6jN=>rZZ(+_^}=`=*VAFYK3gcy2@34uX6dZ#@jmzllT1jbUI>Zkt&Cxgn6C}sJ?siCTGw0d(|FZUWYzC zJ$=<>Mk(j&1FT23U)h}QzrJn@x42%y^>wip_5b!r%?u0-Y@Dhco^-rV_QloJ;dAd# zHosGTzjlUkI^VOiv)Q{%S^O%GEYP!fCw4%)xxwQnm*UE{30EEX^h75py95ckW}cg_ zG3(hc2L(+{&c*KiZfR+1c0Zp8m(B~$$1x(dP|M?JxA^0m?s<-<-Q-TN zKAo|UV`^@P601dOjq4MCu8t`VDxW0Il$f#ee0_EG@P~(o4NG5z?D_d@c3te{Et$c4 ze!W^P;3^0j+gj+{{^9rg{f`e!WWG_KV}I_+{6+!A15$~tx`)^f{r-R4x+FpV+xz?d zVQXLI=^Aw(Z8|PrFT-#1f#K5S%Yt%pef$6Y;%?`cKjzGDDg%9+6f|_B7rQIr z&ySB4&*zq3SQ)IYvh9cTn^yaslbW(P-E3BrvdApWy0RzfjKU%pi-`gqO0APCcHMJ{ z1+@iMhpj!-$}J8Wve>`=u?3%|rlyCd=fxiHqT=Gh2L~8)Zf)V*{r%msgOk|{UmQ^^ zcqpTjD8_P?n<@V(?^VHhizBw>NY1N#Hgi{niRjtc=Ev**|BeUsMxQ=?x*~kNoRn!+ z$;G9U%t5^$nd1w+r|W@I?S<9h`k)f#^1NEX@BeJMnbr$CGqqIPL z+xz=`Qa*|;Tm=@I7F-stO;=ZkKfdTLzxFfB+$Mzum7kxL-b%|Y`1hys&!5ldC2Xs< z%YyUo-*8lNl^ZA13bITv~S-(5*AaL?h7SmTu6$*LD`n(69tPGgq#loE2 zCce_dtXL@XO{&+r1CRdv{Css%)K%Aj0D)QN`F+pM&R)%TbJZ%Xl=O7)NO0XBi>~hO zi)$i{U0huge|~x@VVWfZ>N`)FGNn6@Z@)yv@3-3pWo3Ier=MT6X_JueY%^9x7WY0G zM<*wyLx&GvT;$5V=i@QyibtKxXRw%7eHDmmGR&U9T<~*$g;&Ve0K+^B%dU=u9e71;;)Wxf9WK0aQ^ZCUw%F~x$xwJ8kJC=UO(54qsK2TcH;C}d#^Up=KSw3 zha)OipHKDURMgP^{4RsN;qlJnflo_(6Lhq7ozLx@V(tva zYc-!44G#~uKfW3sfAml*_v=5qW%)8oPqXn#U8%hN@4=Usmq8PLt5&TNkdo@sjo!Av zxt)(eW%0yKPcG(ezuOkL*lnTze7kiVyi)^wTJ~g1hD-9iRB7^Hl}Wwo)UcSPH%UWi z(NZIIR+r^Y4qVGMJa_GBa+>q=;_r|jcV1ks*#2*~o&3Mv!2BOQ-(Ea^)7-`N{-Stm zYipeGUMA3xL{f6Ce$zYdDM53rN>8QleOj;Qp11Og&?=oZE){haVLGveH+^!qN9cI? z`ybzsc=*GU$^M73wl)QEwI5!n_dHm3%Cu=o7ZU*so{w&SJ|369rK!H>;u6nmmS-Ga`%LQ>m7nf9!OZbnedLs)Z!+#G_h;0s z<$S+j%AvrQ4kvF4iM-c5_Tk#$iCeW!XQv!LdhA%QbYNIm8ym0Gg5=|U3`-8y`PL?s z?T($SzHiMMp8bD5akKHsbj-CbKlHLhNkfC<^|j39dpj1b@Z9OEd9>gDU&P|-fPxnn z6nmshxj=oY%1XGrQq!)L zEo;6g6|jEG5^DF_R>5`ChJX5(MKTIqEHdi72j{p<3Tp`{@O$~g$mmZ@8ECE%l)PWO z$SCP}+3;WbQ~i#Q$E5Xd&N_VW!q)8YlDD@+XPf7TIj`TeX;ao3IXSBmkE=WyOJ~?t zn;97!fBbqqURgtfL%#lx;kMk{ZPVlHB8z2@7fNONaU9%~diuh0fBF5(*KGjRO55`8 zcDc({vdlKiJ=Df44H}lwiQgyl^yyO$e*WW^mU@HcNo@Z8c)V)=`pnDAZtN;uZSw5W z6Sb5c38~LE(w6HPFIvrryf3c4vSZO?uVlkiA2*E-4cFEg1@2{KW*mwU`)VqCli%pE zT9v$LNIgC6;ob84ph?`UHQVaG-!1>~-2Q*(-{0Sp4>qxO^z|JBP0t-{W`F$a^?J}i z$iJ`a>m|3zOG&LN%=-TFGJ9lXWX9E1qIEx?il6nG6um9S@%6Q}wo#V(JD-Z(DLSod zQT|S5Ud1EMJGI~Mu2{9oDKAfNSJ_*x?xRfeo(l>JHvafg@#N`KMKv|hfcuU8_4`ks zf7+SQb+B2se&dtHpXMdmE|KD1^eBeSBJkE67f(fpgR|clxl~qKvN#@?U;nSOqk|*B zD=;dm>(8H>IhMt2ph+6guw`5v-|Vw(U%r%pR(4#EEsyOzW>MO?e14r&?XNE%cP`r~ zryaJ&AuCI3(c;CRF;2H$sfVZa_aC|JZ{PdrQxT}34_hs&8@;V$^Q0iJz{tqX1q&2D z*z|AOWOOykGUtYY&paDR(1^DF{y$9)gRse|IeIZLGW_Fi2Zf8pt&QrUMWRw?e0P)X#t*qH1*v|&qH6j z#;#g2FF|Q)h?}ZSmyoAz2Qf|AG}>rz{I{W!sXg39UJTakr8jhN-}OU&b2OaTOYUg!oJ$-`C_McxkW@sfSQao zf4^S8%C+F{yWQ_W-S|fb+2xP)NE$ORD7*C>kj~%Jn0a~GO2*So3JDJmG=fTaEp6?M zMNhrf#O@YjWo6y*ZrAICtx<-VmsF<496Wf?!`u7ty4c+YWp5&CemrbHapnw*!rGaC zPO8tZP?@gLHN(1GZ;qe(rAwC{6j*Gi{au!lmZoHDD_i{ROyJcoe6m&v|Ni_0wOyT@ zoC2bvxa<~d+8@@CihK3P#o0{tsg!?=@uZt)0=qotKjsPZOg#JdQ&^Qc_x4K5T9pKZudn&}bo$2|$^DuC zdT_A$$E(%rHzXb9dUJn&{8onf_Vsd>mXJZ`!!TWRrO%r z_SJzu0s{jrs=jC#85vEOKE1t}o&VI6q$Sggp3XOD2|gC*#&X#&)G)5jBlb3T(C)6R z$QZskpYy)%OFMZq>G{mL8r!SqCqL6DULkB@+1RXlgh|oIAq);|55jL$3+&eYUY37ZN7h6hhh zP6kb+?oreD+LC;{@8R|M`q0n=6DA03$-d6lA^>WSbBpO5=rzB`;ly!mZFGB24^Jth z9V=fuGiVjX?QOXeXV2~i)j-T_JO^~Q-(hm%Q1hG90U9T*{{9Zs*ks;|GcYK0nm>J@iZ5f*`!uXM_Su6t?D(dgZ7A-Ey3Awl}en|%$Z zZ|ZDij_Ba1-uV8hSl+Wdsl1mi>(t>tDJWn{$PbThUssW7KPq-J zY?vPEsPlc|!|j(Cv&`qoo@M0V+TQe7yYSV6`9I$8^R4)NHL{~4t3f({mt^@JMQhty zo9+8MIyw&cn%`}y`}^zRzu)iO9UU3l_~rY8m;3GXJij^p{GqI^i|YRVk}%1b5Vf!7 zXVLyNm+C{udZi81&PeD)Z}Umk^zrpQ`s3r{tB>pc{z^PM%k;5$y#s7 zy=`Waae-mu#*Go1(|AFx7SL*r$?E=~A`vuz7`)t1QB%`1QaExs+a@iA&F|l(s6D7y z3fc z%JF5svvxnl^cYS%e z&ay4S#r#`Rn%?d-Rbf-F!>&e)gw7svR+|=*_B3*m=R_H`S8O)yH&TLb>NrgJVQ*VFWveAwEo~y@;rBctiCSMZh3HET^lJC#>Ds7_b%&D9+S1nF#;Pj}M zUd_6J^V0HAwW(*hSRz$7u|_w(o@DXG|8~3j@$bhDwfuI zGd{g=Hr;eCm29;H!O|^!sBaOudWWyp7ioZ(VJh~^PXSanCyOb z#%T_AKAC{Wrs3=3di!Lp7dbYwy}GoaA>~O&XXnAy>-Tk4et!1zPoCf6Uy>^t^_nCj zgl_WeoztBob6lur#q7E_M_0A1VwrqAS!}29jI6}FjuT_T8Z$gp1$`$a92E1I(S<>+9?No~`bcwHBLeUH&bqJ*W#b_X@J~#^;_vnO7XnO?`DMx%QdWyveH4iasiPuN_$Ea(=gmn&7FV zz$-3H+WrZGKFw~ijn6r9m;#SSnMImzIoUF)Z))+TgPsaI6sI}|*R*!dEWhs26zFAG z_XoU0X6MeGKR_!k%kNKJCb;*{r_&M^1q%PZ@BhDYp-Y2`>N201L93td{d~^);!Oiq)JT4eEt zNEN0iR`Hu__L%T_Ki+rnvcFx_Tf>Nq42@e`GMSw^r24ibALj#2+kssE?RNgfz18J8 zH#fP4N-{pUSN(qNMI8pG4zCAmqqi^eooyEPIz1(2MUb|Ig~a9M{^94Zt`6t_|MPtP zgb5QGB#qNn1V=SBH`hwV?qPYiYjxw1wS1fTRVOvCxE#U}^UqM@)!Zj6li4;-n0sc< zl!McSQ=PhlX8ZLW&J#o!VpFp)DgSQ2S%q3XYQ-pEHLwHW{3LvgzQ1Uk3`l1z0XWqr|_}Gw9SJm6E4R z{IB&cn%{Kfm&NU+1wSf(TmN`6`5P#o)!y4Kn78|_8K@a5VUi&rSM$M9MOF1-ulcsmFs>Rh*FJS)!hVC6r!hwVv`;F*Ll;~9JoG4fM( zaV$&edt`aD@y!yUoh}MylM+hgxt0qTSS;Q5qTtl=MIp~b8cn;mAAY%b{=RwU;)=a{ z^mn}Vx5{>($-FeZ)`j1~^+tcphq&YZU-I1p^m(jAqXQ3iW-ro~?o<0O%W{nWrIDJZ zoy*Zx-d7Bb9zF@tY}w`hkU?U`!N>dMZMx3Q-MzrITkLAxv~zQub}F%F@N7rHv2yxn7_Tb*$f&mYi(^^FhxmEk1zMu zmV>(6?=%T2yRBHsU}L$WR#97RrJXZ-xa{G;OK|C*?WUldvt6crgktH^F_Ox{@bHmc;s1xC;SOZZI+gotn_WOf*)$bZLx(Y00Ui~R^*Ge>9K zEPZV7ci%3*=~8P}mpZI|RRZe8RFVGG+giU7r6|31~Y`I2$T=W)A*^eJTKB$xf z^@$%H?FN;qQ>IMWA!*>`>}*)`qrm3(o6UB*Q@!*Kt_)uO=%{$SOGU+w`0rO1I5MZC zq&zq-Uw>p*>FWve=JnmU5g}t$!twLx&yKDxr@%nLdo`cWX8GO}tXbJ~?A5|Nrlstn zlMa}c6-!!{+^i5~W{=6d;llUeDnnf5wM|CX3WO{~gseF_CTFqT4Od>%^rSe*BSEm^ zn56!OJmF`l%gQHe2!~7!b-MX++Z3IS9h+)3t=A+5{F|t`^g+dgYi9L{2mhFVymC4C zZ=Klevu$>@zg8UIUH+bpLB_5|V&TGtZO7Ufnb{OHG&uO}{}?=a{P^P9Xmb@cH6 zA(`U~7c5|qHp@9MO*b0U+1~T@TJ%-FeuKO_7CrLza$?=A#m~=yrkm!~|Et{d?N&CZ zBLiMMXCuR;omw;5Yg*BTY1PUzob+6$Y)UrMol$x~;rV?5(Mf`(e~uP2s7u>$1X^9W zy7$gf*Mi8OI&)6DE?i@DSjuwB{$8WHp#N!IR~n~&;~Sg~b;+!UUm3C|ijFUc6RYgw*5=C!i+Xk2W-u{mOHsbWuN zGTR8ZJu~vEm@!>_{~HD2vtPeYn#3RYXj81fPxa7itP`{xrlw61_`uMXCi2*x``)21 zlE&FzavnZ>_~O=9?VzBb4fX%)On3T(g^B(8_ICBk)n^uF-PvK7xA*HcsoMGKZ|?3E z@0Bt=)F*3gQ2HtaG;Us4RsvJ8xSc+VTJYM-4vGb2PKF3@>~-$A}< ztbGQB9YG7$Cq3A(iMd*JlY^Xl%-H~537;K76Rz6siselXnzO&@wB;Is;KDoFc6vv7 z)=SNuvR{72bhYKRhMVgDUty7}uCHaUtgPHxbqqA>WL^F)q96zh{5#$;`|IjU4pJ*>?Hc|228A)9%L1C;59mvVpqRw$c*$ziBD1r+3cISLzW1*%4?}DUEue=RLAD1 z?%b5_**P8p71LY7k9)KfJ`kF_IHGUS3UNJ8JDcIY~^R+Wqe}4yBn*dsOGCO~tq;dMWBiGhOU)>{N%J_e~bc^J% zpwkILOW8#)q&BH5w5*tPaI&LU+!l_s5s{{3%}9y=MKJ z8-syq%zm><~lK;k6J)5(d8tisaHS!;6_E?d=l-oh>)G+z7YXtyC~j_&`z z-#2!b>+dRk&9?e#7icY=tX0X1z-KYaDypi9|Ni{^@pAe6gsoAD8zT%-Pl<$tge)k1 zeeK1ywbDw;%Gpz=Of6Pt{J4s%DvUq2PTKiC~TIM3pqp9aq z4L)}9rUnR0uU_J01cijQYaQOZuEG_Ew6U5aKeEsm(=hczY4e!?-WZ|UcQ zMH6xb9y4r<+@iIhZW`nH!UvUnHvS=+FTM6Is5Ug3)$FA4Ek8A7jgi*tI@x~F`Pb`` zQn%;boiKTFbK2QiiFbAsf|kN;L`L7u0=oCB0FBa;oZcfXx1b! z`who5PqCchi2=7#np^(}1s+@Uio2cp#tg?kWho`ki=t7*w#(Hg9m{!dx2~x@xlC%( z0p^cS{Bv$Uvz|G@{7&ih*jG}Ab)&W%`1AAg#^mFCrs=Jl4*Ym^bv5tjnwT90;KtFu z+TR-z4l*$usD8h<-M0GMic&5vE`#cCIXQQB2*&O%bG^MS_itR`GOGvdDIQr1cdvS? zzq045d%qk1xw#WgML7R$K3QM0U1jN!&~^dWsVs{>36$PZTxr%)xm!raM)#@L9tnYp zCOzFHJA-GP5IVN%c$EFroxzh%&NUEdOpN{@NDT!Ca>wbc%BGc6{mG!IL?(&HJV&#hra4>Qyyv53Mwa%mQ zMM0Bs_B18?|39PFADc95Ru^b~T}_Rx!9=e5QK$Nci|+CZv#+oF@nUg5Xl39+=k`UJ zmzQ~XdO8LL2}zk`G|ZVJ^X1)L>GX4R4&K{aeN{9WGy_oi`59>WX~n}<@q+(2Xa_BMD zrX`bh9@CuERk87S%&!MG6;{hUR`1{4q?1FEZRPOSXpS(Jh8^-=KWjKk}obgpY`|l(j`kkdyQsoQuCel;LgtCjJvx`t;*hX zfVKv4a&qo?xokFQ#!bKpG&i*+|Gpe(Jq>6O7c|*h{QMkf0hM9F1BWNio;3+Hsn4re z*@ucuOc_HJz1Yo46xv*ELZ ztK-?pJHoib8Xp`hTW7e?cVmJPo0x89hqm>!S+^&iTyWH)vNBGo?SO~j)1wPl9PQec z;3Bkk*7G1y-mCTwrezstzPo(ad~e?IWW$f&!aH)W{M~9a_xSPSi(R|L@~$0x^CpLd zmG$ADpPw`C>@eiw=H6KIvj{X0={-&7;O6so-Ga()3AeZ9g4SlO+yAc$G<+!5&3bot z`Ehpn8V0YGiR+H+YJ1S>b1ZA&My(ftwo}$$oW8m~=b7)ReU4Y{wU)d#t@jA5O75Q0 zq(15C?URgif?uYv?D0qy^;R@#ox6KSmZE}Ws0m-}ycKMcX6rlDI>e3%9r`+Z7t{Qy z#jAdM{`{L_+TXlJN+`Bq#<}>XS-#nU!5pqLe|2Sf_S{-M~;B{$nKGml1@%e4@#^+!(d-s6F1)s2nbkkQtr%W8_+tZmzS3x zeprxkDV?3^$y!dwD-#lAY=n-euUs%$rK;$q74LFuwO7(tU5%dduQ;~rWPOR(%52*- zE$jZd4bCZP`qm9v6CYj3>^c-wnW;R{>tnalW(BLu>zoQw?=0%meK1MrSNdboqT)#* zr!u^@ynJl(d1*{qQRv)eKQDom!o@NdJ@~%GE%;-0#noh*@~_r=yr*Xvif~+&k=7N- zujtd%*IOP@lAv*~a(~+Ay?+`v1swYF@^aw*y4p2yd!_pA|Lv&ycUphHOHPhX)%SOA z%hoy_`TcG;|H+dl8F#xo`m5z%Iu*b2sb|tlUfG1ctu4y8_}Fw0Mg(Yi8U{{FdNsp$ zO4x=FE4}wBJM=nNykvBlxT1Uh=DE%CbWyV1 zG_AV4y5QTJ$oZ0!vbsP^@j?BBY5MVftlVM`R@U!F|!FlgmCWyk8GI&0o5@sb9ugL6Vo?RT77 zbV{JRax-&4b?>w9>I~}NEm~vNO!c4W;?-9j#=3<SOV)ZJaSFP48w*{qshmYifd*ki<3pqf$yHVb(vnc`BZ& znKHC#6wEbN61sZztBX}V=dy`k*q$!p*t5fkuY2F^@N`A*a4DNJ&p+863wmAjF6Byz zh5wQymFcV4jPlc*KUFG7q}o{qdQ~W&aw#mBpdKUCVH0{hB}{AmRh=wr$t$(1CQfR& zCb4M6+EaT!t`SL=-8JWQ%DR@4m$G|Ly?48r-m0_J#Co08tK#65vR@@Rq65EAUv}xf zx3PQo4!f^*+ADp8=C7+xtSdOQB{jg0JSUhd zyK2uSOOHSq7KZ0Rf|~3cU8kHn_b6DYgih)V39y>JitEr<*?>OIi_>1ti$58>(8FYE z&MXcdwf)M5Kjan#e?Rao{*Z^3;TFtj*H28 zY|K5jtMoO`+OlwKmZ>Up@|~_8d%jfe@YS6*p6b0-Ed0+oLb_)q9a|<6G>L;jiNnJ3 z<%+B?30Lf|&v5+imTI-T#KR<2rZ^~2^y~Mu7aZXym;AkZV>+j|z;ct@|oq7u_>`S<(E-rkb5 ze-g^|>Ez;ra%)=W*=?QpB94U0@&#IK`=h^!uzO}nL?e%NJ5ASg+ven_-@ADf58TWzcyORm>gn|TL5^a+AC-3U z_`LnMVuIeurNvyQ=bk;Q!ykYAR@oH3PbvR8sdFns)#pq@{$*R!UY!$u7NObK zr=VfIO~k$5&owJ+)xqAl+Jg8$=lGKfclEyb78$&Go6Nh;AdUmaOod{lukLn>K0ft% zOjW?qnXBg%KXpqF>d)MC(<%1y%*P6Ar)lP&I;9}9@X|3)X~j#&3a{iYbSQ1x62pFq zt!%PmjP!4zi#@4{AEXVQ$6Oc6mE?J~Szq$(ZTIc^;YHbpSJ-X&ZoG;8;OozEt9fi2u{y4T_$5e6g`Rm%Helx+3bQ z+P6jWDO=)VgNT(!PfB0R_p)W;eYoZ6y0Sfjr{bG3Z#BJ(dU5O8+~#$>Pj9U4TNl^t z(ZpSC?^;$?X1eReRBpdO=B+J-=NXp%4Cz=gS?&!_s(vY1zBqHNupw+!=Id%D5uQ`M z9LKJOOPky>w+Or4w7S;z&aLT%?)(qFUXLrZFBEMuR-48y8gPB*mbvpKgbv9sdZ{X> z-Fju0oQDgCa%M==YY#nl_YXe5r7kh<>U$S-ljr^oyN-n~_w1@_OE`JLQ03y5hm9%! z@8A8o=SCn);hw58-Z&OcwFML8IbJzB2{bpke|&PV`~UQW2@{+TtgzI0BE&Jn!=%yS zh{7Yqj05s6olXgX5h=|R4dlL+mjC?`R(ihr=9}v13pd}*TlH>U<=>gB-p$<8uAs&v zQF!1-;S~1N3cZ;4`TPO(W%Y~f_t|@Ye|I-KX3ACZudyG?)=qhUPU=w2#o`|~m_@&N zFtjmv&G>YqO=W+Rb=^(jB{)L+pgYmJmtdyErrJRqnDy1ch|jd-5a~(-YL(D zOmb$7P%EHM3Q>&)xnIaL+_a z;4I&h3jtS}y{8|a`1C?!W8JS`XAarl+wjKd47b>yt}T2kECiTVD7^W+ciP=Q8fFSD zt_$Pmc}QrmFJrTqH)VFyy{iI34#zf28L+G6u1?IUS}&Fn^4s~V&Ee2{mWA{E=G&$A zew)Bk+&DF9!w>eJz5dni6W8yy$#1op8MpqUZh?~0-f3Npr%JUxW<76HIOm!F?}a~O z6PvROv|bz5`fNYERNSae&ap!) zkKxFv7gi15TIHmcG5hN|JV^U=?R5R+oyGH6q*m)bQ!LVt$nDSxxhJ(+ou}pADQ}lI z!E-CM7Cm~nMcnvd=)9Okv0EG+^NbeG&xp?3=zKvTGS^ee1!|l0GMMd81wAmmt!Dr@%+$T$;?w$U4HgoB;*NYh$o;CzNlv}Oda(-7s#RAO}3&gc6*$rZk zD|}Qix~uN4+PLf7CUyTc!nQjrd-Lw^yPLVuD#-RaL&L((giHf9C)K^-kN-LuI z@4b>QZ_Z3nKCtM+1ldamGA=Z{cK-FwHepeZR`G|IF8k}gOWxi8e@30nTf@#jsh*2w zEmKxb^AOS36h8FLOP3Xu;NUk)L;C zDpvow&dJ!iT*=5vbj7aJ_f0Jh*{a9yIUOt6;>*VKQf0w9?kt@}?;T7od}g>ZW#Wsi z;@4js`q^K$=xglcgKc$l&reF5yjXmVqeI91c-QEURy=pkUEgKEBJ%Cjx#|sPPOp6B z#@~Bar198laDH9lcIM_W8 zUA*%}q2^4r=&5&XY>5h2i{2gIbMt}YQgyrblguezN{8O2%$z#AVWSNne`9ZxUx{qP zWU1q}FK_zDH~*2=|LZQUA2;XT$4RFSs9S!LU=ms-KjE8|Vnp7}dQq>c<$VSdj5M@Z zavWV_^cy_8xq}wCr`%4js%>bz>$d6ZN!~u^u$=kDvFeh)z`jQ5zMXpKzBU?)H}!lE{Z!b& zv3Gjlt2MLT*-y4SKftkXtLdWs?`m9U&z@b(m#{O%AYS+Eq&Vf1HS7@~>T|{G#PW~+ zdK8ebAS^SLJ0_ur~&Llst8>E^dOpUg>q%M-x) zVrxtP)ZERx=dJmo`r5ZV@c+XbY6~w;$vCU>sVaVX;`H1;S;-f-u4?zEZP=~zLvfSW z-P@mCc>A9>xH3jO%@<%xlV$5;n7nyM-@P4k@BR;2WNjaJU--RL)7pwRfide{a~3N%@c%6r=AOpX+);8uy>zqR z)uZ=Lwbh%(Fgt8*=sdDnyI}Rlmo}@5cc;~qEzzU>>RSzep9e?EulZc!`>Av%?}qqQgO48$Hs;;?qbBoS z>qNsI(JJTKuJ&SQ4>Lt^HtpAv(aTQn6}_xqCFQo&Oe;=LvvyMMiPGqI@@sCp-23d- z_x)Dt!|Y{(4(3;bC2gN+^2YlrH_7MVFq1)%O zemkZ1GI_~YnTMOzuBsisl)uWV(`R1zNvHW|5{10<1ytYX23eFYUVQxa-R*u~p69QY d7yHNm?D6cM`cE{f7#J8BJYD@<);T3K0RU-XMDYLs literal 26163 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 -- 2.51.2 From d7f5d6648fb1cc23092de61f734db331c45bb3ed Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Wed, 12 Apr 2023 01:59:16 +0700 Subject: [PATCH 14/47] my life --- build.gradle | 5 ++++- gradle.properties | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 4df6bf1..fd42e48 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,10 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modCompileOnly("maven.modrinth:mouse-wheelie:1.8.8+mc1.18-pre5") - modImplementation include("com.github.melontini:cracker-util:${project.cracker_util}") + + modImplementation include("me.melontini.cracker-util:cracker-util-base:${project.cracker_util}") + modImplementation include("me.melontini.cracker-util:cracker-util-recipe-book:${project.cracker_util}") + modImplementation include("me.melontini.cracker-util:cracker-util-enums:${project.cracker_util}") } processResources { diff --git a/gradle.properties b/gradle.properties index e470b45..9091ac9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,5 @@ +systemProp.org.gradle.internal.http.connectionTimeout=180000 +systemProp.org.gradle.internal.http.socketTimeout=180000 # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx1G # Fabric Properties @@ -9,4 +11,4 @@ loader_version=0.14.11 mod_version=0.9.0-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.2.1-1.19.2 +cracker_util=v0.3.1-1.19.2 -- 2.51.2 From 73a7972e1ed11bbef853e4ff7433dc182f3dd188 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Wed, 12 Apr 2023 01:59:16 +0700 Subject: [PATCH 15/47] my life --- build.gradle | 6 ++++-- gradle.properties | 10 ++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 7944c9b..388ea03 100644 --- a/build.gradle +++ b/build.gradle @@ -29,12 +29,14 @@ dependencies { mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - modImplementation include("com.github.melontini:cracker-util:${project.cracker_util}") + modCompileOnly("maven.modrinth:mouse-wheelie:1.8.8+mc1.18-pre5") modCompileOnly ("io.wispforest:owo-lib:${project.owo_version}") { exclude (group: "net.fabricmc.fabric-api") } - modCompileOnly("maven.modrinth:mouse-wheelie:1.8.8+mc1.18-pre5") + modImplementation include("me.melontini.cracker-util:cracker-util-base:${project.cracker_util}") + modImplementation include("me.melontini.cracker-util:cracker-util-recipe-book:${project.cracker_util}") + modImplementation include("me.melontini.cracker-util:cracker-util-enums:${project.cracker_util}") } loom { diff --git a/gradle.properties b/gradle.properties index 6d2118a..ba72a42 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,14 +1,16 @@ +systemProp.org.gradle.internal.http.connectionTimeout=180000 +systemProp.org.gradle.internal.http.socketTimeout=180000 # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://modmuss50.me/fabric.html -minecraft_version=1.19.3-pre2 -yarn_mappings=1.19.3-pre2+build.11 -loader_version=0.14.10 +minecraft_version=1.19.3 +yarn_mappings=1.19.3+build.5 +loader_version=0.14.19 # Mod Properties mod_version=0.9.0-1.19.3 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.2.1-1.19.3 +cracker_util=v0.3.1-1.19.3 owo_version=0.9.3+1.19.3 -- 2.51.2 From 679b250aec792d920653753d82cdc937d2fceb61 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Wed, 12 Apr 2023 02:33:54 +0700 Subject: [PATCH 16/47] improvements --- build.gradle | 5 +---- .../recipebookispain/RecipeBookIsPainClient.java | 14 +++++++++++--- .../mixin/ClientRecipeBookMixin.java | 3 +-- .../mixin/RecipeBookWidgetMixin.java | 2 +- .../mixin/RecipeGroupButtonMixin.java | 12 ++++++------ src/main/resources/fabric.mod.json | 1 - src/main/resources/rbip.accesswidener | 3 --- 7 files changed, 20 insertions(+), 20 deletions(-) delete mode 100644 src/main/resources/rbip.accesswidener diff --git a/build.gradle b/build.gradle index 388ea03..b1f4180 100644 --- a/build.gradle +++ b/build.gradle @@ -37,10 +37,7 @@ dependencies { modImplementation include("me.melontini.cracker-util:cracker-util-base:${project.cracker_util}") modImplementation include("me.melontini.cracker-util:cracker-util-recipe-book:${project.cracker_util}") modImplementation include("me.melontini.cracker-util:cracker-util-enums:${project.cracker_util}") -} - -loom { - accessWidenerPath = file("src/main/resources/rbip.accesswidener") + modImplementation ("me.melontini.cracker-util:cracker-util-content:${project.cracker_util}") //only for icon group compat } processResources { diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index 6b89f30..b22739d 100644 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -5,6 +5,7 @@ import io.wispforest.owo.itemgroup.OwoItemGroup; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; import net.minecraft.client.recipebook.RecipeBookGroup; @@ -13,14 +14,13 @@ import net.minecraft.item.ItemGroup; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; @Environment(EnvType.CLIENT) public class RecipeBookIsPainClient implements ClientModInitializer { - + public static final boolean isOwOLoaded = FabricLoader.getInstance().isModLoaded("owo"); + public static final boolean isCrackerContentLoaded = FabricLoader.getInstance().isModLoaded("cracker-util-content"); public static final Logger LOGGER = LogManager.getLogger("RBIP"); public static Map RECIPE_BOOK_GROUP_TO_ITEM_GROUP = new HashMap<>(); public static Map ITEM_GROUP_TO_RECIPE_BOOK_GROUP = new HashMap<>(); @@ -36,6 +36,14 @@ public class RecipeBookIsPainClient implements ClientModInitializer { return false; } + public static boolean renderCracker(MatrixStack matrices, int i, RecipeGroupButtonWidget widget, ItemGroup group) { + if (group.shouldAnimateIcon()) { + group.getIconAnimation().animateIcon(matrices, widget.getX() + 9 + i, widget.getY() + 5, widget.isToggled(), false); + return true; + } + return false; + } + @Override public void onInitializeClient() { } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index ef66fc3..b41dd5b 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -26,7 +26,6 @@ import java.util.List; public class ClientRecipeBookMixin { @Inject(at = @At("TAIL"), method = "") private static void rbip$setupGroups(CallbackInfo ci) { - long i = System.currentTimeMillis(); ItemGroups.updateDisplayParameters(FeatureSet.of(FeatureFlags.BUNDLE, FeatureFlags.UPDATE_1_20, FeatureFlags.VANILLA), true); ItemGroups.getGroups().stream().filter(group -> group.getType() != ItemGroup.Type.INVENTORY && group.getType() != ItemGroup.Type.HOTBAR && group.getType() != ItemGroup.Type.SEARCH) @@ -58,7 +57,7 @@ public class ClientRecipeBookMixin { RecipeBookGroup.SEARCH_MAP.get(RecipeBookGroup.CRAFTING_SEARCH).addAll(CRAFTING_SEARCH_LIST); RecipeBookGroup.CRAFTING.clear(); RecipeBookGroup.CRAFTING.addAll(CRAFTING_LIST); - CrackerLog.info("done preparing recipe book groups in {} ms", System.currentTimeMillis() - i); + CrackerLog.info("done preparing recipe book groups"); } @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java index 191cb69..09f50be 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java @@ -29,7 +29,7 @@ public abstract class RecipeBookWidgetMixin { if (client.currentScreen != null) { this.tabButtons.stream().filter(widget -> widget.visible && widget.isHovered()).forEach(widget -> { if (widget.getCategory().name().contains("_SEARCH")) { - client.currentScreen.renderTooltip(matrices, ItemGroups.SEARCH.getDisplayName(), mouseX, mouseY); + client.currentScreen.renderTooltip(matrices, ItemGroups.getSearchGroup().getDisplayName(), mouseX, mouseY); } else { if (RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.get(widget.getCategory()) != null) { Text text = RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.get(widget.getCategory()).getDisplayName(); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java index 6a75668..87fffa2 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java @@ -1,7 +1,6 @@ package me.melontini.recipebookispain.mixin; import me.melontini.recipebookispain.RecipeBookIsPainClient; -import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; import net.minecraft.client.gui.widget.ToggleButtonWidget; import net.minecraft.client.recipebook.RecipeBookGroup; @@ -16,10 +15,10 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import static me.melontini.recipebookispain.RecipeBookIsPainClient.rbip$renderOwo; +import static me.melontini.recipebookispain.RecipeBookIsPainClient.renderCracker; @Mixin(RecipeGroupButtonWidget.class) public abstract class RecipeGroupButtonMixin extends ToggleButtonWidget { - private static final boolean isOwOLoaded = FabricLoader.getInstance().isModLoaded("owo"); @Shadow @Final private RecipeBookGroup category; @@ -45,15 +44,16 @@ public abstract class RecipeGroupButtonMixin extends ToggleButtonWidget { matrices.scale(1.0F, f, 1.0F); matrices.translate((float) (-(this.getX() + 8)), (float) (-(this.getY() + 12)), 0.0F); } - if (isOwOLoaded) { + if (RecipeBookIsPainClient.isOwOLoaded) { if (rbip$renderOwo(matrices, i, (RecipeGroupButtonWidget) (Object) this, group)) { ci.cancel(); return; } } - if (group.shouldAnimateIcon()) { - group.getIconAnimation().animateIcon(matrices, this.getX() + 9 + i, this.getY() + 5, this.toggled, false); - ci.cancel(); + if (RecipeBookIsPainClient.isCrackerContentLoaded) { + if (renderCracker(matrices, i, (RecipeGroupButtonWidget) (Object) this, group)) { + ci.cancel(); + } } } } \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index a1642f0..c156a15 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -16,7 +16,6 @@ "me.melontini.recipebookispain.RecipeBookIsPainClient" ] }, - "accessWidener": "rbip.accesswidener", "mixins": [ "recipe-book-is-pain.mixins.json" ], diff --git a/src/main/resources/rbip.accesswidener b/src/main/resources/rbip.accesswidener deleted file mode 100644 index b3cb6fd..0000000 --- a/src/main/resources/rbip.accesswidener +++ /dev/null @@ -1,3 +0,0 @@ -accessWidener v2 named - -accessible field net/minecraft/item/ItemGroups SEARCH Lnet/minecraft/item/ItemGroup; \ No newline at end of file -- 2.51.2 From 62dabf9a11cd9f822df02dc23b9c266848f28bb8 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Wed, 12 Apr 2023 14:39:26 +0700 Subject: [PATCH 17/47] improvements 2. --- CHANGELOG.md | 7 +- gradle.properties | 2 +- .../RecipeBookIsPainClient.java | 6 ++ .../mixin/ClientRecipeBookMixin.java | 39 --------- .../mixin/MixinConfigPlugin.java | 25 +++++- .../mixin/RecipeBookGroupMixin.java | 83 ------------------- .../cracker_compat/RecipeBookWidgetMixin.java | 9 ++ .../RecipeGroupButtonMixin.java | 9 ++ .../mixin/groups/ClientRecipeBookMixin.java | 82 ++++++++++++++++++ .../mixin/groups/RecipeBookGroupMixin.java | 63 ++++++++++++++ .../mixin/widget/RecipeBookTooltipMixin.java | 42 ++++++++++ .../{ => widget}/RecipeBookWidgetMixin.java | 20 +---- .../{ => widget}/RecipeGroupButtonMixin.java | 2 +- .../recipebookispain/util/EnumUtils.java | 62 ++++++++++++++ .../resources/recipe-book-is-pain.mixins.json | 11 ++- 15 files changed, 309 insertions(+), 153 deletions(-) delete mode 100644 src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java delete mode 100644 src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java create mode 100644 src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeBookWidgetMixin.java create mode 100644 src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeGroupButtonMixin.java create mode 100644 src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java create mode 100644 src/main/java/me/melontini/recipebookispain/mixin/groups/RecipeBookGroupMixin.java create mode 100644 src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java rename src/main/java/me/melontini/recipebookispain/mixin/{ => widget}/RecipeBookWidgetMixin.java (87%) rename src/main/java/me/melontini/recipebookispain/mixin/{ => widget}/RecipeGroupButtonMixin.java (91%) create mode 100644 src/main/java/me/melontini/recipebookispain/util/EnumUtils.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e4c1c4..84214a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,8 @@ ### What's new: -* Fixed RBIP's enum values having identical indexes. pretty epic. -* New icon. -* Updated GitHub CI. -* Removed `static` from ClientRecipeBookMixin. +* Added compat with `cracker-util-recipe-book` +* Changed the way RecipeBookGroup is extended. Now it resembles `cracker-util` versions. +* Added a little exception handling. Supports: Minecraft 1.18, 1.18.1, 1.18.2, 1.19, 1.19.1, 1.19.2 \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index cb71d37..475a913 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ minecraft_version=1.18 yarn_mappings=1.18+build.1 loader_version=0.14.8 # Mod Properties -mod_version=0.8.1-1.18 +mod_version=0.9.0-1.18 maven_group=me.melontini archives_base_name=recipe-book-is-pain diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index 05b47b0..44800a2 100644 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -7,12 +7,18 @@ import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.item.ItemGroup; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.spongepowered.asm.mixin.Unique; import java.util.HashMap; +import java.util.List; import java.util.Map; @Environment(EnvType.CLIENT) public class RecipeBookIsPainClient implements ClientModInitializer { + @Unique + public static List CRAFTING_SEARCH_LIST; + @Unique + public static List CRAFTING_LIST; public static final Logger LOGGER = LogManager.getLogger("RBIP"); public static Map RECIPE_BOOK_GROUP_TO_ITEM_GROUP = new HashMap<>(); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java deleted file mode 100644 index 1309f91..0000000 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -package me.melontini.recipebookispain.mixin; - -import me.melontini.recipebookispain.RecipeBookIsPainClient; -import net.minecraft.client.recipebook.ClientRecipeBook; -import net.minecraft.client.recipebook.RecipeBookGroup; -import net.minecraft.item.ItemGroup; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.Recipe; -import net.minecraft.recipe.RecipeType; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(value = ClientRecipeBook.class, priority = 999) -public class ClientRecipeBookMixin { - @Inject(at = @At("HEAD"), method = "") - private static void rbip$clinit(CallbackInfo ci) { - RecipeBookGroup.values(); - } - @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) - private static void rbip$getGroupForRecipe(Recipe recipe, CallbackInfoReturnable cir) { - RecipeType recipeType = recipe.getType(); - if (recipeType == RecipeType.CRAFTING) { - ItemStack itemStack = recipe.getOutput(); - ItemGroup group = itemStack.getItem().getGroup(); - if (group != null) { - if (group != ItemGroup.HOTBAR && group != ItemGroup.INVENTORY && group != ItemGroup.SEARCH) { - if (RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.containsKey(group)) { - cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(group)); - return; - } - } - } - cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(ItemGroup.MISC)); - } - } -} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java index 7e2a6cf..c2cccf7 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java @@ -1,7 +1,11 @@ package me.melontini.recipebookispain.mixin; import net.fabricmc.loader.api.FabricLoader; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.MethodNode; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; @@ -10,6 +14,7 @@ import java.util.Objects; import java.util.Set; public class MixinConfigPlugin implements IMixinConfigPlugin { + public static final Logger LOGGER = LogManager.getLogger("RBIP-Mixin-Plugin"); @Override public void onLoad(String mixinPackage) { @@ -22,8 +27,17 @@ public class MixinConfigPlugin implements IMixinConfigPlugin { @Override public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - if (Objects.equals(mixinClassName, "me.melontini.recipebookispain.mixin.MouseWheelieCompatMixin") && !FabricLoader.getInstance().isModLoaded("mousewheelie")) + String[] strings = mixinClassName.split("\\."); + if (mixinClassName.contains("MouseWheelieCompatMixin") && !FabricLoader.getInstance().isModLoaded("mousewheelie")) { return false; + } + if ((mixinClassName.contains("widget.RecipeGroupButtonMixin") || mixinClassName.contains("widget.RecipeBookWidgetMixin")) && FabricLoader.getInstance().isModLoaded("cracker-util-recipe-book")) { + LOGGER.warn("[RBIP] CrackerUtil Recipe Book is loaded, skipping {} application", strings[strings.length - 1]); + return false; + } + if (mixinClassName.contains("MouseWheelieCompatMixin")) { + LOGGER.warn("[RBIP] MouseWheelie is loaded, applying {}", strings[strings.length - 1]); + } return true; } @@ -44,6 +58,13 @@ public class MixinConfigPlugin implements IMixinConfigPlugin { @Override public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - + if (mixinClassName.contains("groups.RecipeBookGroupMixin")) { + for (MethodNode method : targetClass.methods) { + if (Objects.equals(method.name, "rbip$extend")) { + method.access = (method.access & ~Opcodes.ACC_PRIVATE) | Opcodes.ACC_PUBLIC; + //bitwise the private away. + } + } + } } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java deleted file mode 100644 index 8c2c5bd..0000000 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookGroupMixin.java +++ /dev/null @@ -1,83 +0,0 @@ -package me.melontini.recipebookispain.mixin; - -import com.google.common.collect.ImmutableList; -import me.melontini.recipebookispain.RecipeBookIsPainClient; -import net.minecraft.client.recipebook.RecipeBookGroup; -import net.minecraft.item.ItemGroup; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.book.RecipeBookCategory; -import org.apache.commons.lang3.ArrayUtils; -import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.*; -import org.spongepowered.asm.mixin.gen.Invoker; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -@Mixin(RecipeBookGroup.class) -@Unique -public class RecipeBookGroupMixin { - //me when I can't use Fabric ASM - - @Invoker("") - static RecipeBookGroup newGroup(String internalName, int internalId, ItemStack... stacks) { - throw new IllegalStateException(); - } - - @Shadow - @Final - @Mutable - private static RecipeBookGroup[] field_1805; - - @Unique - private static List CRAFTING_SEARCH_LIST; - @Unique - private static List CRAFTING_LIST; - - // pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work pls work - @SuppressWarnings("unchecked") - @Redirect(at = @At(value = "INVOKE", target = "Lcom/google/common/collect/ImmutableList;of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lcom/google/common/collect/ImmutableList;"), remap = false, method = "") - private static ImmutableList rbip$listOf(E e1, E e2, E e3, E e4) { - if (e1 == RecipeBookGroup.CRAFTING_EQUIPMENT) { - return (ImmutableList) ImmutableList.copyOf(CRAFTING_SEARCH_LIST); - } - return ImmutableList.of(e1, e2, e3, e4); - } - - @Inject(at = @At(value = "FIELD", opcode = Opcodes.PUTSTATIC, target = "Lnet/minecraft/client/recipebook/RecipeBookGroup;field_1805:[Lnet/minecraft/client/recipebook/RecipeBookGroup;", shift = At.Shift.AFTER), method = "") - private static void rbip$addCustomGroups(CallbackInfo ci) { - CRAFTING_SEARCH_LIST = new ArrayList<>(); - CRAFTING_LIST = new ArrayList<>(); - - Arrays.stream(ItemGroup.GROUPS).filter(itemGroup -> itemGroup != ItemGroup.HOTBAR && itemGroup != ItemGroup.INVENTORY && itemGroup != ItemGroup.SEARCH) - .forEach(itemGroup -> { - String name = "P_CRAFTING_" + itemGroup.getIndex(); - var recipeBookGroup = rbip$extend(name, itemGroup.getIcon()); - RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.put(recipeBookGroup, itemGroup); - RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.put(itemGroup, recipeBookGroup); - - CRAFTING_LIST.add(recipeBookGroup); - CRAFTING_SEARCH_LIST.add(recipeBookGroup); - }); - CRAFTING_LIST.add(0, RecipeBookGroup.CRAFTING_SEARCH); - RecipeBookIsPainClient.LOGGER.info("[RBIP] recipe book init complete"); - } - - private static RecipeBookGroup rbip$extend(String internalName, ItemStack... stacks) { - RecipeBookGroup last = field_1805[field_1805.length - 1]; - RecipeBookGroup enumConst = newGroup(internalName, last.ordinal() + 1, stacks); - field_1805 = ArrayUtils.add(field_1805, enumConst); - return enumConst; - } - - @Inject(at = @At("HEAD"), method = "getGroups", cancellable = true) - private static void rbip$getGroups(RecipeBookCategory category, CallbackInfoReturnable> cir) { - if (category == RecipeBookCategory.CRAFTING) cir.setReturnValue(CRAFTING_LIST); - } -} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeBookWidgetMixin.java new file mode 100644 index 0000000..634bcf3 --- /dev/null +++ b/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeBookWidgetMixin.java @@ -0,0 +1,9 @@ +package me.melontini.recipebookispain.mixin.cracker_compat; + +import me.melontini.recipebookispain.access.RecipeBookWidgetAccess; +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(RecipeBookWidget.class) //What's this? an empty mixin to ensure that RecipeBookWidgetAccess is always implemented +public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { +} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeGroupButtonMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeGroupButtonMixin.java new file mode 100644 index 0000000..3e6f57c --- /dev/null +++ b/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeGroupButtonMixin.java @@ -0,0 +1,9 @@ +package me.melontini.recipebookispain.mixin.cracker_compat; + +import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; +import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(RecipeGroupButtonWidget.class) //What's this? an empty mixin to ensure that RecipeGroupButtonAccess is always implemented +public class RecipeGroupButtonMixin implements RecipeGroupButtonAccess { +} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java new file mode 100644 index 0000000..507383a --- /dev/null +++ b/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java @@ -0,0 +1,82 @@ +package me.melontini.recipebookispain.mixin.groups; + +import me.melontini.recipebookispain.RecipeBookIsPainClient; +import me.melontini.recipebookispain.util.EnumUtils; +import net.minecraft.client.recipebook.ClientRecipeBook; +import net.minecraft.client.recipebook.RecipeBookGroup; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.Recipe; +import net.minecraft.recipe.RecipeType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.ArrayList; +import java.util.Arrays; + +import static me.melontini.recipebookispain.RecipeBookIsPainClient.CRAFTING_LIST; +import static me.melontini.recipebookispain.RecipeBookIsPainClient.CRAFTING_SEARCH_LIST; + +@Mixin(value = ClientRecipeBook.class, priority = 999) +public class ClientRecipeBookMixin { + @Inject(at = @At("HEAD"), method = "") + private static void rbip$clinit(CallbackInfo ci) { + CRAFTING_SEARCH_LIST = new ArrayList<>(); + CRAFTING_LIST = new ArrayList<>(); + + Arrays.stream(ItemGroup.GROUPS).filter(itemGroup -> itemGroup != ItemGroup.HOTBAR && itemGroup != ItemGroup.INVENTORY && itemGroup != ItemGroup.SEARCH) + .forEach(itemGroup -> { + try { + String name = "P_CRAFTING_" + itemGroup.getIndex(); + RecipeBookGroup recipeBookGroup = EnumUtils.callRecipeBookEnumInvoker(name, itemGroup.getIcon()); + RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.put(recipeBookGroup, itemGroup); + RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.put(itemGroup, recipeBookGroup); + + CRAFTING_LIST.add(recipeBookGroup); + CRAFTING_SEARCH_LIST.add(recipeBookGroup); + } catch (Exception e) { + String info; + try { + info = String.format("%s item group", itemGroup.getName()); + } catch (Throwable t) { + try { + info = String.format("%s item group", itemGroup.getDisplayName().asString()); + } catch (Throwable t1) { + try { + info = String.format("item group with %s icon", itemGroup.getIcon().toString()); + } catch (Throwable t2) { + info = "item group"; + } + } + } + RecipeBookIsPainClient.LOGGER.error(String.format("Error while processing %s", info), e); + } + }); + CRAFTING_LIST.add(0, RecipeBookGroup.CRAFTING_SEARCH); + + RecipeBookGroup.SEARCH_MAP.get(RecipeBookGroup.CRAFTING_SEARCH).clear(); + RecipeBookGroup.SEARCH_MAP.get(RecipeBookGroup.CRAFTING_SEARCH).addAll(CRAFTING_SEARCH_LIST); + RecipeBookIsPainClient.LOGGER.info("[RBIP] recipe book init complete"); + } + + @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) + private static void rbip$getGroupForRecipe(Recipe recipe, CallbackInfoReturnable cir) { + RecipeType recipeType = recipe.getType(); + if (recipeType == RecipeType.CRAFTING) { + ItemStack itemStack = recipe.getOutput(); + ItemGroup group = itemStack.getItem().getGroup(); + if (group != null) { + if (group != ItemGroup.HOTBAR && group != ItemGroup.INVENTORY && group != ItemGroup.SEARCH) { + if (RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.containsKey(group)) { + cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(group)); + return; + } + } + } + cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(ItemGroup.MISC)); + } + } +} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/groups/RecipeBookGroupMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/groups/RecipeBookGroupMixin.java new file mode 100644 index 0000000..560ee29 --- /dev/null +++ b/src/main/java/me/melontini/recipebookispain/mixin/groups/RecipeBookGroupMixin.java @@ -0,0 +1,63 @@ +package me.melontini.recipebookispain.mixin.groups; + +import me.melontini.recipebookispain.util.EnumUtils; +import net.minecraft.client.recipebook.RecipeBookGroup; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.book.RecipeBookCategory; +import org.apache.commons.lang3.ArrayUtils; +import org.spongepowered.asm.mixin.*; +import org.spongepowered.asm.mixin.gen.Invoker; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static me.melontini.recipebookispain.RecipeBookIsPainClient.CRAFTING_LIST; + +@Mixin(RecipeBookGroup.class) +@Unique +public class RecipeBookGroupMixin { + //me when I can't use Fabric ASM + + @Invoker("") + static RecipeBookGroup newGroup(String internalName, int internalId, ItemStack... stacks) { + throw new IllegalStateException(); + } + + @Shadow + @Final + @Mutable + private static RecipeBookGroup[] field_1805; + + + @Shadow + @Final + @Mutable + public static Map> SEARCH_MAP; + + @Unique + private static RecipeBookGroup rbip$extend(String internalName, ItemStack... stacks) { + RecipeBookGroup last = field_1805[field_1805.length - 1]; + RecipeBookGroup enumConst = newGroup(internalName, last.ordinal() + 1, stacks); + field_1805 = ArrayUtils.add(field_1805, enumConst); + EnumUtils.clearEnumCache(RecipeBookGroup.class); + return enumConst; + } + + @Inject(at = @At("HEAD"), method = "getGroups", cancellable = true) + private static void rbip$getGroups(RecipeBookCategory category, CallbackInfoReturnable> cir) { + if (category == RecipeBookCategory.CRAFTING) cir.setReturnValue(CRAFTING_LIST); + } + + @Inject(at = @At("TAIL"), method = "") + private static void rbip$makeMutable(CallbackInfo ci) { + Map> groupListMap = new HashMap<>(); + SEARCH_MAP.forEach((group, groups) -> groupListMap.put(group, new ArrayList<>(groups))); + SEARCH_MAP = groupListMap; + } +} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java new file mode 100644 index 0000000..0dcd9c5 --- /dev/null +++ b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java @@ -0,0 +1,42 @@ +package me.melontini.recipebookispain.mixin.widget; + +import me.melontini.recipebookispain.RecipeBookIsPainClient; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.ItemGroup; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.List; + +@Mixin(value = RecipeBookWidget.class, priority = 1001) +public class RecipeBookTooltipMixin { + @Shadow protected MinecraftClient client; + + @Shadow @Final private List tabButtons; + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V", shift = At.Shift.BEFORE), method = "render") + private void rbip$renderTooltip(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { + if (client.currentScreen != null) { + this.tabButtons.stream().filter(widget -> widget.visible && widget.isHovered()).forEach(widget -> { + if (widget.getCategory().name().contains("_SEARCH")) { + client.currentScreen.renderTooltip(matrices, ItemGroup.SEARCH.getDisplayName(), mouseX, mouseY); + } else { + if (RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.containsKey(widget.getCategory())) { + Text text = RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.get(widget.getCategory()).getDisplayName(); + if (text != null) { + client.currentScreen.renderTooltip(matrices, text, mouseX, mouseY); + } + } + } + }); + } + } +} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookWidgetMixin.java similarity index 87% rename from src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java rename to src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookWidgetMixin.java index 82e74c0..97ca44c 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeBookWidgetMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookWidgetMixin.java @@ -1,8 +1,7 @@ -package me.melontini.recipebookispain.mixin; +package me.melontini.recipebookispain.mixin.widget; import me.melontini.recipebookispain.access.RecipeBookWidgetAccess; import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; -import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; @@ -10,9 +9,7 @@ import net.minecraft.client.gui.widget.ToggleButtonWidget; import net.minecraft.client.recipebook.ClientRecipeBook; import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.ItemGroup; import net.minecraft.screen.AbstractRecipeScreenHandler; -import net.minecraft.text.Text; import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; import org.jetbrains.annotations.Nullable; @@ -77,21 +74,6 @@ public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { rbip$renderPageText(matrices); this.prevPageButton.render(matrices, mouseX, mouseY, delta); this.nextPageButton.render(matrices, mouseX, mouseY, delta); - - if (client.currentScreen != null) { - this.tabButtons.stream().filter(widget -> widget.visible && widget.isHovered()).forEach(widget -> { - if (widget.getCategory().name().contains("_SEARCH")) { - client.currentScreen.renderTooltip(matrices, ItemGroup.SEARCH.getDisplayName(), mouseX, mouseY); - } else { - if (RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.containsKey(widget.getCategory())) { - Text text = RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.get(widget.getCategory()).getDisplayName(); - if (text != null) { - client.currentScreen.renderTooltip(matrices, text, mouseX, mouseY); - } - } - } - }); - } } @Unique diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java similarity index 91% rename from src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java rename to src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java index e852265..aca87e3 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java @@ -1,4 +1,4 @@ -package me.melontini.recipebookispain.mixin; +package me.melontini.recipebookispain.mixin.widget; import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; diff --git a/src/main/java/me/melontini/recipebookispain/util/EnumUtils.java b/src/main/java/me/melontini/recipebookispain/util/EnumUtils.java new file mode 100644 index 0000000..a552b6f --- /dev/null +++ b/src/main/java/me/melontini/recipebookispain/util/EnumUtils.java @@ -0,0 +1,62 @@ +package me.melontini.recipebookispain.util; + +import me.melontini.recipebookispain.RecipeBookIsPainClient; +import net.minecraft.client.recipebook.RecipeBookGroup; +import net.minecraft.item.ItemStack; +import sun.misc.Unsafe; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; + +public class EnumUtils { + private static final Unsafe UNSAFE; + + static { + Unsafe unsafe; + try { + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + unsafe = (Unsafe) unsafeField.get(null); + } catch (NoSuchFieldException | IllegalAccessException e) { + try { + Constructor constructor = Unsafe.class.getDeclaredConstructor(); + constructor.setAccessible(true); + unsafe = constructor.newInstance(); + } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | + IllegalAccessException ex) { + throw new RuntimeException("Couldn't access Unsafe", ex); + } + } + UNSAFE = unsafe; + } + + public static synchronized void clearEnumCache(Class> cls) { + try { + writeField(Class.class.getDeclaredField("enumConstants"), cls, null); + } catch (Exception e) { + RecipeBookIsPainClient.LOGGER.error("Couldn't clear enumConstants. This shouldn't really happen", e); + } + + try { + writeField(Class.class.getDeclaredField("enumConstantDirectory"), cls, null); + } catch (Exception e) { + RecipeBookIsPainClient.LOGGER.error("Couldn't clear enumConstantDirectory. This shouldn't really happen", e); + } + } + + @SuppressWarnings("unchecked") + public static > T callRecipeBookEnumInvoker(String internalName, ItemStack... params) { + try { + return (T) RecipeBookGroup.class.getMethod("rbip$extend", String.class, ItemStack[].class).invoke(RecipeBookGroup.class, internalName, params); + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + public static void writeField(Field field, Object o, Object value) { + long l = Modifier.isStatic(field.getModifiers()) ? UNSAFE.staticFieldOffset(field) : UNSAFE.objectFieldOffset(field); + UNSAFE.putObject(o, l, value); + } +} diff --git a/src/main/resources/recipe-book-is-pain.mixins.json b/src/main/resources/recipe-book-is-pain.mixins.json index 41c12ea..f722f49 100644 --- a/src/main/resources/recipe-book-is-pain.mixins.json +++ b/src/main/resources/recipe-book-is-pain.mixins.json @@ -7,11 +7,14 @@ "mixins": [ ], "client": [ - "ClientRecipeBookMixin", "MouseWheelieCompatMixin", - "RecipeBookGroupMixin", - "RecipeBookWidgetMixin", - "RecipeGroupButtonMixin" + "cracker_compat.RecipeBookWidgetMixin", + "cracker_compat.RecipeGroupButtonMixin", + "groups.ClientRecipeBookMixin", + "groups.RecipeBookGroupMixin", + "widget.RecipeBookTooltipMixin", + "widget.RecipeBookWidgetMixin", + "widget.RecipeGroupButtonMixin" ], "injectors": { "defaultRequire": 1 -- 2.51.2 From 5763a3d66bcdb2aba475225e6dc71d37d1251477 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Wed, 12 Apr 2023 16:12:37 +0700 Subject: [PATCH 18/47] Update CHANGELOG.md --- CHANGELOG.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84214a2..60b2bcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,7 @@ -## 0.8.1-1.18 - ### What's new: * Added compat with `cracker-util-recipe-book` * Changed the way RecipeBookGroup is extended. Now it resembles `cracker-util` versions. * Added a little exception handling. -Supports: Minecraft 1.18, 1.18.1, 1.18.2, 1.19, 1.19.1, 1.19.2 \ No newline at end of file +Supports: Minecraft 1.18, 1.18.1, 1.18.2, 1.19, 1.19.1, 1.19.2 -- 2.51.2 From 10e3df6e1adcdbfeab41727de85588609058360f Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Fri, 14 Apr 2023 20:43:19 +0700 Subject: [PATCH 19/47] improvements 2. --- CHANGELOG.md | 5 +---- gradle.properties | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be2e381..a56b7b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,3 @@ -## 0.9.0-1.19.2 - ### What's new: -* Fixed crash with Tom's Simple Storage -* Updated CrackerUtil \ No newline at end of file +* Updated CrackerUtil & Fabric Loader \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 9091ac9..f02cfb3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,9 +6,9 @@ org.gradle.jvmargs=-Xmx1G # check these on https://modmuss50.me/fabric.html minecraft_version=1.19.2 yarn_mappings=1.19.2+build.28 -loader_version=0.14.11 +loader_version=0.14.19 # Mod Properties -mod_version=0.9.0-1.19.2 +mod_version=0.9.1-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.3.1-1.19.2 +cracker_util=v0.3.2-1.19.2 -- 2.51.2 From 75a57d773b6ebe68194e52e5800fa16fc180605a Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Fri, 14 Apr 2023 20:43:19 +0700 Subject: [PATCH 20/47] improvements 2. --- CHANGELOG.md | 5 +---- gradle.properties | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0687620..a56b7b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,3 @@ -## 0.9.0-1.19.3 - ### What's new: -* Fixed crash with Tom's Simple Storage -* Updated CrackerUtil \ No newline at end of file +* Updated CrackerUtil & Fabric Loader \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index ba72a42..f2dcc78 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,9 +8,9 @@ minecraft_version=1.19.3 yarn_mappings=1.19.3+build.5 loader_version=0.14.19 # Mod Properties -mod_version=0.9.0-1.19.3 +mod_version=0.9.1-1.19.3 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.3.1-1.19.3 +cracker_util=v0.3.2-1.19.3 owo_version=0.9.3+1.19.3 -- 2.51.2 From dc32b90d1c9b6078970a866067846d674821846c Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Fri, 14 Apr 2023 20:50:37 +0700 Subject: [PATCH 21/47] oh. --- .../recipebookispain/mixin/RecipeGroupButtonMixin.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java index 87fffa2..620fc13 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/RecipeGroupButtonMixin.java @@ -55,5 +55,9 @@ public abstract class RecipeGroupButtonMixin extends ToggleButtonWidget { ci.cancel(); } } + + if (this.bounce > 0.0F) { + matrices.pop(); + } } } \ No newline at end of file -- 2.51.2 From 6775758a629d18f32a7dbfd9e57c580ccec40846 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Sun, 16 Apr 2023 17:58:17 +0700 Subject: [PATCH 22/47] update build and publish --- .github/workflows/build.yml | 25 ++++++++++++------------ .github/workflows/publish.yml | 36 +++++++++++++++++++++-------------- build.gradle | 12 ++++++++++++ 3 files changed, 47 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 23627fd..68f3ae5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,37 +4,38 @@ # against bad commits. name: build -on: [pull_request, push] +on: [ pull_request, push ] jobs: build: strategy: matrix: # Use these Java versions - java: [ - 17 - ] + java: [ 17 ] # and run on both Linux and Windows - os: [ubuntu-20.04, windows-latest] + os: [ ubuntu-20.04 ] runs-on: ${{ matrix.os }} steps: - name: checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3.4.0 - name: validate gradle wrapper uses: gradle/wrapper-validation-action@v1 - name: setup jdk ${{ matrix.java }} - uses: actions/setup-java@v2 + uses: actions/setup-java@v3.10.0 with: - distribution: adopt + distribution: 'temurin' java-version: ${{ matrix.java }} - name: make gradle wrapper executable if: ${{ runner.os != 'Windows' }} run: chmod +x ./gradlew - name: build run: ./gradlew build + - name: Retrieve Version #https://stackoverflow.com/questions/71089787/how-to-get-version-name-from-android-gradle-file-in-github-actions + run: | + echo "VERSION_INFORMATION=$(${{github.workspace}}/gradlew -q printVersionName)" >> $GITHUB_ENV + echo "GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV - name: capture build artifacts - if: ${{ runner.os == 'Linux' && matrix.java == '17' }} # Only upload artifacts built from LTS java on one OS - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3.1.2 with: - name: Artifacts - path: build/libs/ + name: ${{ env.VERSION_INFORMATION }} [${{ env.GIT_HASH }}] #https://stackoverflow.com/questions/58886293/getting-current-branch-and-commit-hash-in-github-action + path: build/libs/ \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0bcf1ae..9b44503 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,41 +1,49 @@ +name: publish on: push: tags: - 'v*' - + jobs: publish: runs-on: ubuntu-latest steps: - name: checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3.4.0 - name: validate gradle wrapper uses: gradle/wrapper-validation-action@v1 - name: setup jdk 17 - uses: actions/setup-java@v2 + uses: actions/setup-java@v3.10.0 with: - distribution: adopt + distribution: 'temurin' java-version: 17 - name: make gradle wrapper executable run: chmod +x ./gradlew - name: build run: ./gradlew build + - name: Retrieve Version #https://stackoverflow.com/questions/71089787/how-to-get-version-name-from-android-gradle-file-in-github-actions + run: | + echo "VERSION_INFORMATION=$(${{github.workspace}}/gradlew -q printVersionName)" >> $GITHUB_ENV + echo "VERSION_PLAIN=$(${{github.workspace}}/gradlew -q printVersion)" >> $GITHUB_ENV - name: Publish Minecraft Mods uses: Kir-Antipov/mc-publish@v3.2 with: version-type: beta + changelog-file: CHANGELOG.md + name: ${{ env.VERSION_INFORMATION }} + version: ${{ env.VERSION_PLAIN }} + + game-versions: | + 1.19.4 + + loaders: | + fabric + modrinth-id: etNS9OnA modrinth-token: ${{ secrets.MODRINTH_TOKEN }} modrinth-featured: true modrinth-unfeature-mode: subset - + + curseforge-id: 643246 - curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} - - game-versions: | - 1.19.3 - - loaders: | - fabric - - changelog-file: CHANGELOG.md + curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} \ No newline at end of file diff --git a/build.gradle b/build.gradle index b1f4180..082e5d9 100644 --- a/build.gradle +++ b/build.gradle @@ -73,6 +73,18 @@ java { withSourcesJar() } +tasks.register('printVersionName') { + doLast { + println "${version.split("-")[0]} (${version.split("-")[1]})" + } +} + +tasks.register('printVersion') { + doLast { + println version + } +} + jar { from("LICENSE") { rename { "${it}_${project.archivesBaseName}" } -- 2.51.2 From a43bbabfd8ed6c37d8ca5bce2b494c79fd4b95e2 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Sun, 16 Apr 2023 17:58:17 +0700 Subject: [PATCH 23/47] update build and publish --- .github/workflows/build.yml | 25 +++++++------- .github/workflows/publish.yml | 34 ++++++++++++------- build.gradle | 12 +++++++ gradle.properties | 2 +- .../mixin/ClientRecipeBookMixin.java | 3 +- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 23627fd..68f3ae5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,37 +4,38 @@ # against bad commits. name: build -on: [pull_request, push] +on: [ pull_request, push ] jobs: build: strategy: matrix: # Use these Java versions - java: [ - 17 - ] + java: [ 17 ] # and run on both Linux and Windows - os: [ubuntu-20.04, windows-latest] + os: [ ubuntu-20.04 ] runs-on: ${{ matrix.os }} steps: - name: checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3.4.0 - name: validate gradle wrapper uses: gradle/wrapper-validation-action@v1 - name: setup jdk ${{ matrix.java }} - uses: actions/setup-java@v2 + uses: actions/setup-java@v3.10.0 with: - distribution: adopt + distribution: 'temurin' java-version: ${{ matrix.java }} - name: make gradle wrapper executable if: ${{ runner.os != 'Windows' }} run: chmod +x ./gradlew - name: build run: ./gradlew build + - name: Retrieve Version #https://stackoverflow.com/questions/71089787/how-to-get-version-name-from-android-gradle-file-in-github-actions + run: | + echo "VERSION_INFORMATION=$(${{github.workspace}}/gradlew -q printVersionName)" >> $GITHUB_ENV + echo "GIT_HASH=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_ENV - name: capture build artifacts - if: ${{ runner.os == 'Linux' && matrix.java == '17' }} # Only upload artifacts built from LTS java on one OS - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3.1.2 with: - name: Artifacts - path: build/libs/ + name: ${{ env.VERSION_INFORMATION }} [${{ env.GIT_HASH }}] #https://stackoverflow.com/questions/58886293/getting-current-branch-and-commit-hash-in-github-action + path: build/libs/ \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c6f6927..9b44503 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,3 +1,4 @@ +name: publish on: push: tags: @@ -8,34 +9,41 @@ jobs: runs-on: ubuntu-latest steps: - name: checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3.4.0 - name: validate gradle wrapper uses: gradle/wrapper-validation-action@v1 - name: setup jdk 17 - uses: actions/setup-java@v2 + uses: actions/setup-java@v3.10.0 with: - distribution: adopt + distribution: 'temurin' java-version: 17 - name: make gradle wrapper executable run: chmod +x ./gradlew - name: build run: ./gradlew build + - name: Retrieve Version #https://stackoverflow.com/questions/71089787/how-to-get-version-name-from-android-gradle-file-in-github-actions + run: | + echo "VERSION_INFORMATION=$(${{github.workspace}}/gradlew -q printVersionName)" >> $GITHUB_ENV + echo "VERSION_PLAIN=$(${{github.workspace}}/gradlew -q printVersion)" >> $GITHUB_ENV - name: Publish Minecraft Mods uses: Kir-Antipov/mc-publish@v3.2 with: - version-type: alpha - modrinth-id: etNS9OnA - modrinth-token: ${{ secrets.MODRINTH_TOKEN }} - modrinth-featured: true - modrinth-unfeature-mode: subset - - curseforge-id: 643246 - curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} + version-type: beta + changelog-file: CHANGELOG.md + name: ${{ env.VERSION_INFORMATION }} + version: ${{ env.VERSION_PLAIN }} game-versions: | - 1.19.2 + 1.19.4 loaders: | fabric - changelog-file: CHANGELOG.md \ No newline at end of file + modrinth-id: etNS9OnA + modrinth-token: ${{ secrets.MODRINTH_TOKEN }} + modrinth-featured: true + modrinth-unfeature-mode: subset + + + curseforge-id: 643246 + curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} \ No newline at end of file diff --git a/build.gradle b/build.gradle index fd42e48..ee3dfb1 100644 --- a/build.gradle +++ b/build.gradle @@ -66,6 +66,18 @@ java { withSourcesJar() } +tasks.register('printVersionName') { + doLast { + println "${version.split("-")[0]} (${version.split("-")[1]})" + } +} + +tasks.register('printVersion') { + doLast { + println version + } +} + jar { from("LICENSE") { rename { "${it}_${project.archivesBaseName}" } diff --git a/gradle.properties b/gradle.properties index f02cfb3..e6d4ee4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,4 +11,4 @@ loader_version=0.14.19 mod_version=0.9.1-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.3.2-1.19.2 +cracker_util=v0.3.3-1.19.2 diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index b74cc32..8867c5d 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -1,6 +1,5 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.crackerutil.CrackerLog; import me.melontini.crackerutil.util.EnumWrapper; import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.recipebook.ClientRecipeBook; @@ -43,7 +42,7 @@ public class ClientRecipeBookMixin { RecipeBookGroup.SEARCH_MAP.get(RecipeBookGroup.CRAFTING_SEARCH).addAll(CRAFTING_SEARCH_LIST); RecipeBookGroup.CRAFTING.clear(); RecipeBookGroup.CRAFTING.addAll(CRAFTING_LIST); - CrackerLog.info("Finished setting up recipe book groups!"); + RecipeBookIsPainClient.LOGGER.info("[RBIP] Finished setting up recipe book groups!"); } @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) -- 2.51.2 From 5758baff760759187cc554e06199e79b944e0e21 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Sun, 16 Apr 2023 18:00:53 +0700 Subject: [PATCH 24/47] it merged my commits... --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9b44503..475c82d 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: version: ${{ env.VERSION_PLAIN }} game-versions: | - 1.19.4 + 1.19.2 loaders: | fabric -- 2.51.2 From c68cee2707eca85daa1dab23d71f2a2a6a3ea0f9 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Sun, 16 Apr 2023 18:09:31 +0700 Subject: [PATCH 25/47] pls --- .github/workflows/publish.yml | 2 +- gradle.properties | 2 +- .../assets/recipe-book-is-pain/icon.png | Bin 26163 -> 22631 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9b44503..6e8dbcf 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: version: ${{ env.VERSION_PLAIN }} game-versions: | - 1.19.4 + 1.19.3 loaders: | fabric diff --git a/gradle.properties b/gradle.properties index f2dcc78..79a98a5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,5 +12,5 @@ mod_version=0.9.1-1.19.3 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.3.2-1.19.3 +cracker_util=v0.3.3-1.19.3 owo_version=0.9.3+1.19.3 diff --git a/src/main/resources/assets/recipe-book-is-pain/icon.png b/src/main/resources/assets/recipe-book-is-pain/icon.png index 269967ec5bb35f69b46e5beaa6e1239ec64ea1a1..81b39384076a68e02a67055c10b46b51107fcb82 100644 GIT binary patch literal 22631 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 literal 26163 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 -- 2.51.2 From 8aef1f4fb0d4fcdb3afc144e1ecbcec306354423 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Tue, 25 Apr 2023 22:58:56 +0700 Subject: [PATCH 26/47] ... --- CHANGELOG.md | 2 +- gradle.properties | 4 ++-- .../recipebookispain/RecipeBookIsPainClient.java | 4 ++-- .../mixin/ClientRecipeBookMixin.java | 3 +-- .../mixin/MouseWheelieCompatMixin.java | 16 ++++++++++++---- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a56b7b8..d51f57d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ ### What's new: -* Updated CrackerUtil & Fabric Loader \ No newline at end of file +* Updated CrackerUtil \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 79a98a5..0336d3a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,9 +8,9 @@ minecraft_version=1.19.3 yarn_mappings=1.19.3+build.5 loader_version=0.14.19 # Mod Properties -mod_version=0.9.1-1.19.3 +mod_version=0.9.2-1.19.3 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.3.3-1.19.3 +cracker_util=9145906051 owo_version=0.9.3+1.19.3 diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index b22739d..71c8739 100644 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -2,6 +2,7 @@ package me.melontini.recipebookispain; import io.wispforest.owo.itemgroup.OwoItemGroup; +import me.melontini.crackerutil.util.PrependingLogger; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -12,7 +13,6 @@ import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemGroup; import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import java.util.HashMap; import java.util.Map; @@ -21,7 +21,7 @@ import java.util.Map; public class RecipeBookIsPainClient implements ClientModInitializer { public static final boolean isOwOLoaded = FabricLoader.getInstance().isModLoaded("owo"); public static final boolean isCrackerContentLoaded = FabricLoader.getInstance().isModLoaded("cracker-util-content"); - public static final Logger LOGGER = LogManager.getLogger("RBIP"); + public static final PrependingLogger LOGGER = new PrependingLogger(LogManager.getLogger("RBIP"), PrependingLogger.LOGGER_NAME); public static Map RECIPE_BOOK_GROUP_TO_ITEM_GROUP = new HashMap<>(); public static Map ITEM_GROUP_TO_RECIPE_BOOK_GROUP = new HashMap<>(); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index b41dd5b..3c5de58 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -1,6 +1,5 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.crackerutil.CrackerLog; import me.melontini.crackerutil.util.EnumWrapper; import me.melontini.recipebookispain.RecipeBookIsPainClient; import me.melontini.recipebookispain.access.ItemAccess; @@ -57,7 +56,7 @@ public class ClientRecipeBookMixin { RecipeBookGroup.SEARCH_MAP.get(RecipeBookGroup.CRAFTING_SEARCH).addAll(CRAFTING_SEARCH_LIST); RecipeBookGroup.CRAFTING.clear(); RecipeBookGroup.CRAFTING.addAll(CRAFTING_LIST); - CrackerLog.info("done preparing recipe book groups"); + RecipeBookIsPainClient.LOGGER.info("done preparing recipe book groups"); } @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index 69a829e..d868d3c 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -4,13 +4,11 @@ import de.siphalor.mousewheelie.client.mixin.gui.other.MixinRecipeBookWidget; import de.siphalor.mousewheelie.client.util.ScrollAction; import me.melontini.crackerutil.util.mixin.MixinShouldApply; import me.melontini.crackerutil.util.mixin.Mod; +import net.minecraft.client.gui.screen.recipebook.RecipeBookResults; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Dynamic; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -24,15 +22,25 @@ public abstract class MouseWheelieCompatMixin { @Nullable private RecipeGroupButtonWidget currentTab; + @Shadow @Final private RecipeBookResults recipesArea; + @SuppressWarnings("ReferenceToMixin") @Dynamic(mixin = MixinRecipeBookWidget.class) @Inject(at = @At(value = "INVOKE", target = "net/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget.setToggled (Z)V", ordinal = 1, shift = At.Shift.AFTER), method = "mouseWheelie_scrollRecipeBook") private void rbip$scrollPages(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { if (currentTab == null) return;//how tho? + this.recipesArea.hideAlternates(); RecipeBookWidget bookWidget = (RecipeBookWidget) (Object) this; if (bookWidget.getPage() != currentTab.getPage()) { bookWidget.setPage(currentTab.getPage()); } } + + @SuppressWarnings("ReferenceToMixin") + @Dynamic(mixin = MixinRecipeBookWidget.class) + @Inject(at = @At(value = "INVOKE", target = "de/siphalor/mousewheelie/client/util/accessors/IRecipeBookResults.mouseWheelie_refreshResultButtons ()V", shift = At.Shift.BEFORE), method = "mouseWheelie_scrollRecipeBook") + private void rbip$hideAlternatives(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { + this.recipesArea.hideAlternates(); + } } -- 2.51.2 From 0f705911379cfa3e7e1aa6b58af962fe5f7a4193 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Tue, 25 Apr 2023 22:58:56 +0700 Subject: [PATCH 27/47] ... --- CHANGELOG.md | 2 +- gradle.properties | 4 ++-- .../recipebookispain/RecipeBookIsPainClient.java | 5 ++--- .../mixin/ClientRecipeBookMixin.java | 2 +- .../mixin/MouseWheelieCompatMixin.java | 16 ++++++++++++---- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a56b7b8..d51f57d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ ### What's new: -* Updated CrackerUtil & Fabric Loader \ No newline at end of file +* Updated CrackerUtil \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index e6d4ee4..da6e32e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ minecraft_version=1.19.2 yarn_mappings=1.19.2+build.28 loader_version=0.14.19 # Mod Properties -mod_version=0.9.1-1.19.2 +mod_version=0.9.2-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.3.3-1.19.2 +cracker_util=e72786125a diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index 12c61c6..a37ab24 100644 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -1,12 +1,12 @@ package me.melontini.recipebookispain; +import me.melontini.crackerutil.util.PrependingLogger; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.item.ItemGroup; import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import java.util.HashMap; import java.util.Map; @@ -14,12 +14,11 @@ import java.util.Map; @Environment(EnvType.CLIENT) public class RecipeBookIsPainClient implements ClientModInitializer { - public static final Logger LOGGER = LogManager.getLogger("RBIP"); + public static final PrependingLogger LOGGER = new PrependingLogger(LogManager.getLogger("RBIP"), PrependingLogger.LOGGER_NAME); public static Map RECIPE_BOOK_GROUP_TO_ITEM_GROUP = new HashMap<>(); public static Map ITEM_GROUP_TO_RECIPE_BOOK_GROUP = new HashMap<>(); @Override public void onInitializeClient() { - //null pointers are epic } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index 8867c5d..138cd1b 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -42,7 +42,7 @@ public class ClientRecipeBookMixin { RecipeBookGroup.SEARCH_MAP.get(RecipeBookGroup.CRAFTING_SEARCH).addAll(CRAFTING_SEARCH_LIST); RecipeBookGroup.CRAFTING.clear(); RecipeBookGroup.CRAFTING.addAll(CRAFTING_LIST); - RecipeBookIsPainClient.LOGGER.info("[RBIP] Finished setting up recipe book groups!"); + RecipeBookIsPainClient.LOGGER.info("done preparing recipe book groups"); } @Inject(at = @At("HEAD"), method = "getGroupForRecipe", cancellable = true) diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index 69a829e..d868d3c 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -4,13 +4,11 @@ import de.siphalor.mousewheelie.client.mixin.gui.other.MixinRecipeBookWidget; import de.siphalor.mousewheelie.client.util.ScrollAction; import me.melontini.crackerutil.util.mixin.MixinShouldApply; import me.melontini.crackerutil.util.mixin.Mod; +import net.minecraft.client.gui.screen.recipebook.RecipeBookResults; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Dynamic; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -24,15 +22,25 @@ public abstract class MouseWheelieCompatMixin { @Nullable private RecipeGroupButtonWidget currentTab; + @Shadow @Final private RecipeBookResults recipesArea; + @SuppressWarnings("ReferenceToMixin") @Dynamic(mixin = MixinRecipeBookWidget.class) @Inject(at = @At(value = "INVOKE", target = "net/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget.setToggled (Z)V", ordinal = 1, shift = At.Shift.AFTER), method = "mouseWheelie_scrollRecipeBook") private void rbip$scrollPages(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { if (currentTab == null) return;//how tho? + this.recipesArea.hideAlternates(); RecipeBookWidget bookWidget = (RecipeBookWidget) (Object) this; if (bookWidget.getPage() != currentTab.getPage()) { bookWidget.setPage(currentTab.getPage()); } } + + @SuppressWarnings("ReferenceToMixin") + @Dynamic(mixin = MixinRecipeBookWidget.class) + @Inject(at = @At(value = "INVOKE", target = "de/siphalor/mousewheelie/client/util/accessors/IRecipeBookResults.mouseWheelie_refreshResultButtons ()V", shift = At.Shift.BEFORE), method = "mouseWheelie_scrollRecipeBook") + private void rbip$hideAlternatives(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { + this.recipesArea.hideAlternates(); + } } -- 2.51.2 From f9f6ff7215ba87ff879e92cef1ed19ccc84f8cb7 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Tue, 25 Apr 2023 23:12:56 +0700 Subject: [PATCH 28/47] forgor about the icon --- .../assets/recipe-book-is-pain/icon.png | Bin 26163 -> 22631 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/main/resources/assets/recipe-book-is-pain/icon.png b/src/main/resources/assets/recipe-book-is-pain/icon.png index 269967ec5bb35f69b46e5beaa6e1239ec64ea1a1..81b39384076a68e02a67055c10b46b51107fcb82 100644 GIT binary patch literal 22631 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 literal 26163 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 -- 2.51.2 From da9d16d5e8b9ac88aa8907122aacabcd5f76dd43 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 27 Apr 2023 19:59:09 +0700 Subject: [PATCH 29/47] cracker --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index da6e32e..1d51388 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,4 +11,4 @@ loader_version=0.14.19 mod_version=0.9.2-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=e72786125a +cracker_util=4fabc33fab -- 2.51.2 From 9d010348c2dddee61db7d43fecd81a1e91d6c754 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 27 Apr 2023 19:59:16 +0700 Subject: [PATCH 30/47] notice --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 4ce5717..5073f53 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2022 melontini +Copyright (c) 2023 melontini Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal -- 2.51.2 From fd7860cb95c25d8d5860c156296ac60d3fb57b23 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 27 Apr 2023 19:59:09 +0700 Subject: [PATCH 31/47] cracker --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 0336d3a..5db6280 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,5 +12,5 @@ mod_version=0.9.2-1.19.3 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=9145906051 +cracker_util=6b45321632 owo_version=0.9.3+1.19.3 -- 2.51.2 From 1f1a43b41bc2f95a7490c711cb8045f30a1a5b26 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 27 Apr 2023 19:59:16 +0700 Subject: [PATCH 32/47] notice --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 4ce5717..5073f53 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2022 melontini +Copyright (c) 2023 melontini Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal -- 2.51.2 From bf1ca7fdcafa53369d6e0e1fa587b67026664033 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Fri, 28 Apr 2023 22:13:29 +0700 Subject: [PATCH 33/47] speedrun --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 1d51388..ed59e15 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,4 +11,4 @@ loader_version=0.14.19 mod_version=0.9.2-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=4fabc33fab +cracker_util=v0.4.0-1.19.2 -- 2.51.2 From d31ba3d417bf7c6fb56a7524ceb2bdaf89d07562 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Fri, 28 Apr 2023 22:14:18 +0700 Subject: [PATCH 34/47] =?UTF-8?q?cracker=20update=20=F0=9F=92=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 5db6280..1e5c098 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,5 +12,5 @@ mod_version=0.9.2-1.19.3 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=6b45321632 +cracker_util=v0.4.0-1.19.3 owo_version=0.9.3+1.19.3 -- 2.51.2 From 0f89709baa58681d9dce009e4851f1177b3e3fb8 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Mon, 8 May 2023 22:07:56 +0700 Subject: [PATCH 35/47] annoying --- CHANGELOG.md | 2 +- gradle.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d51f57d..082f517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ ### What's new: -* Updated CrackerUtil \ No newline at end of file +* Fixed smoker crash. \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 1e5c098..199fdcb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,9 +8,9 @@ minecraft_version=1.19.3 yarn_mappings=1.19.3+build.5 loader_version=0.14.19 # Mod Properties -mod_version=0.9.2-1.19.3 +mod_version=0.9.3-1.19.3 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.4.0-1.19.3 +cracker_util=v0.4.2-1.19.3 owo_version=0.9.3+1.19.3 -- 2.51.2 From d2eed2faa193ddc385d271e438a62cc93990164b Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Mon, 8 May 2023 22:07:56 +0700 Subject: [PATCH 36/47] annoying --- CHANGELOG.md | 2 +- gradle.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d51f57d..082f517 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ ### What's new: -* Updated CrackerUtil \ No newline at end of file +* Fixed smoker crash. \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index ed59e15..e9c3f08 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ minecraft_version=1.19.2 yarn_mappings=1.19.2+build.28 loader_version=0.14.19 # Mod Properties -mod_version=0.9.2-1.19.2 +mod_version=0.9.3-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.4.0-1.19.2 +cracker_util=v0.4.2-1.19.2 -- 2.51.2 From 8a294d6e3627da2bd8286825540a0904fb24cd4b Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 29 Jun 2023 16:58:52 +0700 Subject: [PATCH 37/47] dark-matter --- CHANGELOG.md | 2 +- build.gradle | 7 ++++--- gradle.properties | 4 ++-- .../melontini/recipebookispain/RecipeBookIsPainClient.java | 2 +- .../recipebookispain/mixin/ClientRecipeBookMixin.java | 2 +- .../recipebookispain/mixin/MixinConfigPlugin.java | 2 +- .../recipebookispain/mixin/MouseWheelieCompatMixin.java | 4 ++-- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 082f517..b790d83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ ### What's new: -* Fixed smoker crash. \ No newline at end of file +* CrackerUtil -> Dark Matter \ No newline at end of file diff --git a/build.gradle b/build.gradle index ee3dfb1..2db31f9 100644 --- a/build.gradle +++ b/build.gradle @@ -28,9 +28,10 @@ dependencies { modCompileOnly("maven.modrinth:mouse-wheelie:1.8.8+mc1.18-pre5") - modImplementation include("me.melontini.cracker-util:cracker-util-base:${project.cracker_util}") - modImplementation include("me.melontini.cracker-util:cracker-util-recipe-book:${project.cracker_util}") - modImplementation include("me.melontini.cracker-util:cracker-util-enums:${project.cracker_util}") + modImplementation include("me.melontini.dark-matter:dark-matter-base:${project.dark_matter}") + modImplementation include("me.melontini.dark-matter:dark-matter-minecraft:${project.dark_matter}") + modImplementation include("me.melontini.dark-matter:dark-matter-enums:${project.dark_matter}") + modImplementation include("me.melontini.dark-matter:dark-matter-recipe-book:${project.dark_matter}") } processResources { diff --git a/gradle.properties b/gradle.properties index e9c3f08..92aef9f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ minecraft_version=1.19.2 yarn_mappings=1.19.2+build.28 loader_version=0.14.19 # Mod Properties -mod_version=0.9.3-1.19.2 +mod_version=0.9.4-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.4.2-1.19.2 +dark_matter=0707465f9b diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index a37ab24..9b6c9a1 100644 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -1,6 +1,6 @@ package me.melontini.recipebookispain; -import me.melontini.crackerutil.util.PrependingLogger; +import me.melontini.dark_matter.util.PrependingLogger; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index 138cd1b..a78f057 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -1,6 +1,6 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.crackerutil.util.EnumWrapper; +import me.melontini.dark_matter.enums.util.EnumWrapper; import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.recipebook.ClientRecipeBook; import net.minecraft.client.recipebook.RecipeBookGroup; diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java index 77b4246..57a86c2 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java @@ -1,6 +1,6 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.crackerutil.util.mixin.ExtendedPlugin; +import me.melontini.dark_matter.util.mixin.ExtendedPlugin; public class MixinConfigPlugin extends ExtendedPlugin { } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index d868d3c..a23dfcc 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -2,8 +2,8 @@ package me.melontini.recipebookispain.mixin; import de.siphalor.mousewheelie.client.mixin.gui.other.MixinRecipeBookWidget; import de.siphalor.mousewheelie.client.util.ScrollAction; -import me.melontini.crackerutil.util.mixin.MixinShouldApply; -import me.melontini.crackerutil.util.mixin.Mod; +import me.melontini.dark_matter.util.mixin.MixinShouldApply; +import me.melontini.dark_matter.util.mixin.Mod; import net.minecraft.client.gui.screen.recipebook.RecipeBookResults; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; -- 2.51.2 From f4d0c130836d0c1a15c91184c120d480a469ffa0 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 29 Jun 2023 17:39:21 +0700 Subject: [PATCH 38/47] dark-matter thing --- CHANGELOG.md | 6 +----- gradle.properties | 2 +- .../melontini/recipebookispain/mixin/MixinConfigPlugin.java | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60b2bcc..874d5b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,3 @@ ### What's new: -* Added compat with `cracker-util-recipe-book` -* Changed the way RecipeBookGroup is extended. Now it resembles `cracker-util` versions. -* Added a little exception handling. - -Supports: Minecraft 1.18, 1.18.1, 1.18.2, 1.19, 1.19.1, 1.19.2 +* Added compat with `dark-matter-recipe-book` diff --git a/gradle.properties b/gradle.properties index 475a913..cf6e3c0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,6 +6,6 @@ minecraft_version=1.18 yarn_mappings=1.18+build.1 loader_version=0.14.8 # Mod Properties -mod_version=0.9.0-1.18 +mod_version=0.9.1-1.18 maven_group=me.melontini archives_base_name=recipe-book-is-pain diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java index c2cccf7..304f99c 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java @@ -31,7 +31,7 @@ public class MixinConfigPlugin implements IMixinConfigPlugin { if (mixinClassName.contains("MouseWheelieCompatMixin") && !FabricLoader.getInstance().isModLoaded("mousewheelie")) { return false; } - if ((mixinClassName.contains("widget.RecipeGroupButtonMixin") || mixinClassName.contains("widget.RecipeBookWidgetMixin")) && FabricLoader.getInstance().isModLoaded("cracker-util-recipe-book")) { + if ((mixinClassName.contains("widget.RecipeGroupButtonMixin") || mixinClassName.contains("widget.RecipeBookWidgetMixin")) && (FabricLoader.getInstance().isModLoaded("cracker-util-recipe-book") || FabricLoader.getInstance().isModLoaded("dark-matter-recipe-book"))) { LOGGER.warn("[RBIP] CrackerUtil Recipe Book is loaded, skipping {} application", strings[strings.length - 1]); return false; } -- 2.51.2 From d0bfe1ec2faaa6d2c2d24df6165d2cb8cfaa0735 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 29 Jun 2023 16:58:52 +0700 Subject: [PATCH 39/47] dark-matter --- CHANGELOG.md | 2 +- build.gradle | 9 +++++---- gradle.properties | 4 ++-- .../recipebookispain/RecipeBookIsPainClient.java | 2 +- .../recipebookispain/mixin/ClientRecipeBookMixin.java | 2 +- .../recipebookispain/mixin/MixinConfigPlugin.java | 2 +- .../recipebookispain/mixin/MouseWheelieCompatMixin.java | 4 ++-- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 082f517..b790d83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ ### What's new: -* Fixed smoker crash. \ No newline at end of file +* CrackerUtil -> Dark Matter \ No newline at end of file diff --git a/build.gradle b/build.gradle index 082e5d9..565af40 100644 --- a/build.gradle +++ b/build.gradle @@ -34,10 +34,11 @@ dependencies { exclude (group: "net.fabricmc.fabric-api") } - modImplementation include("me.melontini.cracker-util:cracker-util-base:${project.cracker_util}") - modImplementation include("me.melontini.cracker-util:cracker-util-recipe-book:${project.cracker_util}") - modImplementation include("me.melontini.cracker-util:cracker-util-enums:${project.cracker_util}") - modImplementation ("me.melontini.cracker-util:cracker-util-content:${project.cracker_util}") //only for icon group compat + modImplementation include("me.melontini.dark-matter:dark-matter-base:${project.dark_matter}") + modImplementation include("me.melontini.dark-matter:dark-matter-minecraft:${project.dark_matter}") + modImplementation include("me.melontini.dark-matter:dark-matter-enums:${project.dark_matter}") + modImplementation include("me.melontini.dark-matter:dark-matter-recipe-book:${project.dark_matter}") + modImplementation ("me.melontini.dark-matter:dark-matter-content:${project.dark_matter}") //only for icon group compat } processResources { diff --git a/gradle.properties b/gradle.properties index 199fdcb..82c641f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,9 +8,9 @@ minecraft_version=1.19.3 yarn_mappings=1.19.3+build.5 loader_version=0.14.19 # Mod Properties -mod_version=0.9.3-1.19.3 +mod_version=0.9.4-1.19.3 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.4.2-1.19.3 +dark_matter=d0f89482f2 owo_version=0.9.3+1.19.3 diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index 71c8739..8309959 100644 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -2,7 +2,7 @@ package me.melontini.recipebookispain; import io.wispforest.owo.itemgroup.OwoItemGroup; -import me.melontini.crackerutil.util.PrependingLogger; +import me.melontini.dark_matter.util.PrependingLogger; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index 3c5de58..36b08cf 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -1,6 +1,6 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.crackerutil.util.EnumWrapper; +import me.melontini.dark_matter.enums.util.EnumWrapper; import me.melontini.recipebookispain.RecipeBookIsPainClient; import me.melontini.recipebookispain.access.ItemAccess; import net.minecraft.client.recipebook.ClientRecipeBook; diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java index 77b4246..57a86c2 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java @@ -1,6 +1,6 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.crackerutil.util.mixin.ExtendedPlugin; +import me.melontini.dark_matter.util.mixin.ExtendedPlugin; public class MixinConfigPlugin extends ExtendedPlugin { } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index d868d3c..a23dfcc 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -2,8 +2,8 @@ package me.melontini.recipebookispain.mixin; import de.siphalor.mousewheelie.client.mixin.gui.other.MixinRecipeBookWidget; import de.siphalor.mousewheelie.client.util.ScrollAction; -import me.melontini.crackerutil.util.mixin.MixinShouldApply; -import me.melontini.crackerutil.util.mixin.Mod; +import me.melontini.dark_matter.util.mixin.MixinShouldApply; +import me.melontini.dark_matter.util.mixin.Mod; import net.minecraft.client.gui.screen.recipebook.RecipeBookResults; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; -- 2.51.2 From 072eb89da294c954cf46ae67d6b5bfd381fe9b71 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Thu, 29 Jun 2023 16:58:52 +0700 Subject: [PATCH 40/47] dark-matter --- CHANGELOG.md | 2 +- build.gradle | 9 +++++---- gradle.properties | 4 ++-- .../recipebookispain/RecipeBookIsPainClient.java | 2 +- .../recipebookispain/mixin/ClientRecipeBookMixin.java | 2 +- .../recipebookispain/mixin/MixinConfigPlugin.java | 2 +- .../recipebookispain/mixin/MouseWheelieCompatMixin.java | 4 ++-- 7 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 082f517..b790d83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ ### What's new: -* Fixed smoker crash. \ No newline at end of file +* CrackerUtil -> Dark Matter \ No newline at end of file diff --git a/build.gradle b/build.gradle index dcc7a63..25a0998 100644 --- a/build.gradle +++ b/build.gradle @@ -34,10 +34,11 @@ dependencies { exclude (group: "net.fabricmc.fabric-api") } - modImplementation include("me.melontini.cracker-util:cracker-util-base:${project.cracker_util}") - modImplementation include("me.melontini.cracker-util:cracker-util-recipe-book:${project.cracker_util}") - modImplementation include("me.melontini.cracker-util:cracker-util-enums:${project.cracker_util}") - modImplementation ("me.melontini.cracker-util:cracker-util-content:${project.cracker_util}") //only for icon group compat + modImplementation include("me.melontini.dark-matter:dark-matter-base:${project.dark_matter}") + modImplementation include("me.melontini.dark-matter:dark-matter-minecraft:${project.dark_matter}") + modImplementation include("me.melontini.dark-matter:dark-matter-enums:${project.dark_matter}") + modImplementation include("me.melontini.dark-matter:dark-matter-recipe-book:${project.dark_matter}") + modImplementation ("me.melontini.dark-matter:dark-matter-content:${project.dark_matter}") //only for icon group compat } processResources { diff --git a/gradle.properties b/gradle.properties index d08d5eb..72814b2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,9 +8,9 @@ minecraft_version=1.19.4 yarn_mappings=1.19.4+build.1 loader_version=0.14.19 # Mod Properties -mod_version=0.9.3-1.19.4 +mod_version=0.9.4-1.19.4 maven_group=me.melontini archives_base_name=recipe-book-is-pain -cracker_util=v0.4.2-1.19.4 +dark_matter=f48acba6aa owo_version=0.10.3+1.19.4 diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index 71c8739..8309959 100644 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -2,7 +2,7 @@ package me.melontini.recipebookispain; import io.wispforest.owo.itemgroup.OwoItemGroup; -import me.melontini.crackerutil.util.PrependingLogger; +import me.melontini.dark_matter.util.PrependingLogger; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; diff --git a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java index 255b0b7..90e0b39 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/ClientRecipeBookMixin.java @@ -1,6 +1,6 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.crackerutil.util.EnumWrapper; +import me.melontini.dark_matter.enums.util.EnumWrapper; import me.melontini.recipebookispain.RecipeBookIsPainClient; import me.melontini.recipebookispain.access.ItemAccess; import net.minecraft.client.network.ClientDynamicRegistryType; diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java index 77b4246..57a86c2 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java @@ -1,6 +1,6 @@ package me.melontini.recipebookispain.mixin; -import me.melontini.crackerutil.util.mixin.ExtendedPlugin; +import me.melontini.dark_matter.util.mixin.ExtendedPlugin; public class MixinConfigPlugin extends ExtendedPlugin { } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index d868d3c..a23dfcc 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -2,8 +2,8 @@ package me.melontini.recipebookispain.mixin; import de.siphalor.mousewheelie.client.mixin.gui.other.MixinRecipeBookWidget; import de.siphalor.mousewheelie.client.util.ScrollAction; -import me.melontini.crackerutil.util.mixin.MixinShouldApply; -import me.melontini.crackerutil.util.mixin.Mod; +import me.melontini.dark_matter.util.mixin.MixinShouldApply; +import me.melontini.dark_matter.util.mixin.Mod; import net.minecraft.client.gui.screen.recipebook.RecipeBookResults; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; -- 2.51.2 From 38676d15fb73136a7975a158c3ed981a4b331f20 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Fri, 30 Jun 2023 00:06:19 +0700 Subject: [PATCH 41/47] Dark Matter version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 82c641f..5e5c95c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,5 +12,5 @@ mod_version=0.9.4-1.19.3 maven_group=me.melontini archives_base_name=recipe-book-is-pain -dark_matter=d0f89482f2 +dark_matter=v0.6.0-1.19.3 owo_version=0.9.3+1.19.3 -- 2.51.2 From bc7940573be87ef456c163013fb5dc0dfdeab1a4 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Fri, 30 Jun 2023 00:07:48 +0700 Subject: [PATCH 42/47] Dark Matter version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 92aef9f..28f62ea 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,4 +11,4 @@ loader_version=0.14.19 mod_version=0.9.4-1.19.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain -dark_matter=0707465f9b +dark_matter=v0.6.0-1.19.2 -- 2.51.2 From ddb7fdf1d9e644bf938c7b74f341d64ea99aa80b Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Fri, 30 Jun 2023 00:11:47 +0700 Subject: [PATCH 43/47] Dark Matter version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 72814b2..87064dc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,5 +12,5 @@ mod_version=0.9.4-1.19.4 maven_group=me.melontini archives_base_name=recipe-book-is-pain -dark_matter=f48acba6aa +dark_matter=v0.6.0-1.19.4 owo_version=0.10.3+1.19.4 -- 2.51.2 From f4e9e6384ae64278a3b9474198ec037841367441 Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:02:17 +0700 Subject: [PATCH 44/47] This is too big to explain, so I'm not going to. --- .github/workflows/publish.yml | 22 +-- CHANGELOG.md | 4 +- build.gradle | 22 ++- gradle.properties | 11 +- gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 63375 bytes gradle/wrapper/gradle-wrapper.properties | 6 +- .../RecipeBookIsPainClient.java | 21 +- .../access/RecipeBookWidgetAccess.java | 23 --- .../access/RecipeGroupButtonAccess.java | 11 -- .../mixin/MixinConfigPlugin.java | 70 ------- .../mixin/MouseWheelieCompatMixin.java | 31 +-- .../cracker_compat/RecipeBookWidgetMixin.java | 9 - .../RecipeGroupButtonMixin.java | 9 - .../mixin/groups/ClientRecipeBookMixin.java | 21 +- .../mixin/groups/RecipeBookGroupMixin.java | 43 +--- .../mixin/widget/RecipeBookTooltipMixin.java | 3 +- .../mixin/widget/RecipeBookWidgetMixin.java | 183 ------------------ .../mixin/widget/RecipeGroupButtonMixin.java | 62 ++++-- .../recipebookispain/util/EnumUtils.java | 62 ------ .../resources/recipe-book-is-pain.mixins.json | 4 - 20 files changed, 133 insertions(+), 484 deletions(-) delete mode 100644 src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java delete mode 100644 src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java delete mode 100644 src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java delete mode 100644 src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeBookWidgetMixin.java delete mode 100644 src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeGroupButtonMixin.java delete mode 100644 src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookWidgetMixin.java delete mode 100644 src/main/java/me/melontini/recipebookispain/util/EnumUtils.java diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 45ee75c..02e4045 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,8 +1,5 @@ name: publish -on: - push: - tags: - - 'v*' +on: [workflow_dispatch] jobs: publish: @@ -26,7 +23,7 @@ jobs: - name: build run: ./gradlew build - name: Publish Minecraft Mods - uses: Kir-Antipov/mc-publish@v3.2 + uses: Kir-Antipov/mc-publish@v3.3 with: version-type: release changelog-file: CHANGELOG.md @@ -34,21 +31,24 @@ jobs: version: ${{ env.VERSION_PLAIN }} game-versions: | - 1.18 - 1.18.1 1.18.2 - 1.19 - 1.19.1 - 1.19.2 loaders: | fabric + github-tag: v${{ env.VERSION_PLAIN }} + github-token: ${{ secrets.GITHUB_TOKEN }} + github-prerelease: false + modrinth-id: etNS9OnA modrinth-token: ${{ secrets.MODRINTH_TOKEN }} modrinth-featured: true modrinth-unfeature-mode: subset + modrinth-dependencies: | + dark-matter(embedded) curseforge-id: 643246 - curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} \ No newline at end of file + curseforge-token: ${{ secrets.CURSEFORGE_TOKEN }} + curseforge-dependencies: | + dark-matter(embedded) \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 874d5b6..74b9bdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ ### What's new: -* Added compat with `dark-matter-recipe-book` +* 1.18.2 version now uses Dark Matter +* Updated Dark Matter. +* Other changes, but I forgor 💀 diff --git a/build.gradle b/build.gradle index 6dded89..ae3cc33 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { - id 'fabric-loom' version '0.12-SNAPSHOT' + id 'fabric-loom' version '1.3-SNAPSHOT' id 'maven-publish' - id 'io.github.juuxel.loom-quiltflower' version '1.7.+' + id 'io.github.juuxel.loom-vineflower' version '1.11.+' } version = project.mod_version @@ -16,10 +16,10 @@ repositories { maven { name = "Modrinth" url = "https://api.modrinth.com/maven" - content { - includeGroup "maven.modrinth" - } + content { includeGroup "maven.modrinth" } } + maven { url 'https://jitpack.io' } + maven { url 'https://maven.wispforest.io' } } dependencies { @@ -28,7 +28,15 @@ dependencies { mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - modCompileOnly("maven.modrinth:mouse-wheelie:1.8.8+mc1.18-pre5") + modCompileOnly("maven.modrinth:mouse-wheelie:1.12.2+mc1.18.2") + + def dmModules = ["base", "minecraft", "enums", "recipe-book"] + for (final def module in dmModules) { + modApi include("me.melontini.dark-matter:dark-matter-${module}:${project.dark_matter}") + } + modApi("me.melontini.dark-matter:dark-matter-content:${project.dark_matter}") + + modImplementation "io.wispforest:owo-lib:${project.owo_version}" } processResources { @@ -72,7 +80,7 @@ jar { tasks.register('printVersionName') { doLast { - println version.split("-")[0] + " (1.18 - 1.19.2)" + println version.split("-")[0] + " (${version.split("-")[1]})" } } diff --git a/gradle.properties b/gradle.properties index cf6e3c0..b83b949 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,10 +2,13 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://modmuss50.me/fabric.html -minecraft_version=1.18 -yarn_mappings=1.18+build.1 -loader_version=0.14.8 +minecraft_version=1.18.2 +yarn_mappings=1.18.2+build.4 +loader_version=0.14.22 # Mod Properties -mod_version=0.9.1-1.18 +mod_version=0.10.0-1.18.2 maven_group=me.melontini archives_base_name=recipe-book-is-pain + +dark_matter=177e7f2915 +owo_version=0.7.2+1.18 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927a4d4fb3f96a785543079b8df6723c946b..033e24c4cdf41af1ab109bc7f253b2b887023340 100644 GIT binary patch delta 41502 zcmZ2`nYsTxGi!i1GmFT?1)>wBgc(I9>J>7IOkAK0B19+N6a~|hSr}zSL>L%2I2afh z92wePTrXGWVql09pKPdaTwf!7RrX(;&hICmk2;?V67!mKWRo!uXX6o0&c3%d*i`wZ zO}^4HDdtVLuF}gnmo@z|GQGv;mRw{kx#VcR(AjJU#E_+c(Pb$fe#{{0Ic3D#`nia)fNOK$Rv_-Q(v|G4&P zO<%wAhtIM6km+yB_D4JUr zmEZaL6BIZ%YbZSekY>3)5=WSy7cK?3W%qjKy2jd%EA1W_Zv%XZC zJ>$$}FZ1!Q# zUt3D_Z{0Gxvt^#lq+@ag1t(S%UGSNwrtG<4>kNe|vsCF$X3M}zo?FXLoNzXDe=G6$ zx#FdX##7wgzuXEDjNWx(YrTH%@khFs3o@6VeyuR|t(owa%}RNE{NAb4D_s>I$xK?O z#{JSJnP*w<Gty|xy{-d=iKI?~Q-C3Pke&_ORO%Ew#{ot)z z{h(Z`uHQbxqVsu{MXw=mp^g7RdDB0f_18X#|Ct(lI5eSWRqTof`BMM->OI*11t+Ww z|9GPQr$E2>uHsi88uI$LEDdsN(oFGG`#DSk=k(ID>ooLcKU zRh2Y0td8|p^R+ffxp0Ezv82=#R|~KDR=*ix8m}h{EcbcQlB(v^EYorP>lDGPnAur( zLMBYvdwjhyTduE;=;xmBmW$v<*oP@1vy(=9zV*E4?hO}=X)XMUVd&0j5Y=HB4TnZ7$R^^`Xr zI%Bl=N^!yY1B=YBe@{D{*wyo5rCGMcT!Ts9a#lV45$5NsuJ-)aq_*&^o;j>f&($WZ zyH>&X#>QxQ@P=%D>9T)sB8*I}z1(+9+MCGnW~OuZxyOgfHZ5M6pq|7__(kRedf2;UC^=s|_r%Shn|Ni7Ob?vDQ z-=)9J$ejBoJ=x&$w<dx?9@QXH+ef4CHz_QErcd&F#65Z%IBqQz84wN;l(WAH&fC zo6`j{AH7oj1>arxVDnjuxo-}ee|>Pb{`<3XI^EAR%r{%<>979UZ#bK)g!)5`(N z|Lq>sjm6m~IC;r9aqKUGcwzy*K=cSk(nD-#ePKQl6bW-4vV? zvNY#LL0aHK&tS1<%9BeMhzc_;hJY0dkq+!Fr%tyV?9o6qNzswv^?K3w%}-@x@r-=l%w@r}Da3txdbf9Rd~ zsoSsbcz^o#^#b{`x33>MpKqtSLr!T)>;9(wPtQJ{QNF#oXhwD`Gta}!7*laZ<{h*4 zPqk>u?r=@|$S}2jmj8`pVU6xJ^BeNzr+@l8d4+^T`=wXhzl=V}^Zhz?esR$Pod8kU z53E}<*ghMtn8$YAqhKwI{5%&~P3E;v4;Fbw%YQLV->_h75)*gy)CEo%M^(fGQw!O= zjX2mUH*L9kUikkpPMyiOpRS!Mt+ruNDDNuCH92c%wMcM;vFUNNG}VVnu8}(aDol5U zng6232Mf$PO_^2Xj^8R=GuuVEvfVgi);AYZ?Fw@c#Z^pD#c z^Rnb_2t?TP{VGwGeaCR^IpZ?f(6>vvNDN{&C;LRWEJyzk`S@^u=@)t`+vo%$$o;!#eYYqVJY#w(L^qJI28bilRotYnVl@uNrI zEUJ7X_WZ`j-npsYE#_MF@BhoFcKI5Q-pL1-c(%n>sy}mAyJ+QL|7OR0r7||X(+Sse zBa|8&@9z7&qh`SxORL6hg>QE5uVi}reS!0X7?t|f*X|XT%q_OKuF&vyM~~;lR=+Cm zSKIm$nNP26YZXhlcy;rWX~uzve5RhBArt#0(p=c-)x9$xu1(`USFQ@TX;oCLGlXsg#n> zFHb(;TKSD--4y>kozvXEIF26MFr{YM-JO?C`h{mm9trAtXl<*V79HmERYmDZoO9sg z8{smt#{IFS)8-~T^jIVQM;zSlgf}X0AJZ$;XJBA3p1h>OR`E)s(dlj>Zmyv2l5S(6 z?x5fuU0$EPjEaMEcQSzWOeMv=*i4<$G6 zZ>V8p6q(%cP;zr?&Jpr{e&t5XzOAa+GncH=?A|mnyoV*Sf5ogUyObHPip>7s zJ|vXh^+xFKYMyzVwu=o+I1e5=cWqbFniH=rC$UVbimE@i_EekJH`ayj7gBdve7h9V z<9YSO?92ob8XkEbG_x-!bcxhlEr~?#(H@##?h& z?K)<7@Iub|-0&qPoUdKOi=69pj~8v4)~h?aZB?r9(@A;h&r)w3IjAcgSy-4_@#SgB z>3JTat<$tl`2GI2t-hCI!k#7O&!6VL4lb}sykRq4r=ZU?FSYBn?|O+xNiUK)!ixJG zqpp?rY%yBd^(9kx^Gm_@{C6_z9q74=6UNEe%RoR$CI7gR=(VQ zi}UA&FwdulLt})GJky*gD|;riA%E?XjD(Ee{5Cf$!`|h zw57c=eWr@krt3?cs(r3wWy+bOe9G8zZrG=v4+8X4GwVfLFXm2v*|+jpQb_2cLtZQ) z=OT}$ywG_kvGOagYOdToU9m!)p!-^!Z{K?EeI|2iKe6ocmh#JQxLfTHiE_DrdsydR zEgqGTBVuLNEoH{8@4aYh%GxE$)iH-e4@3ptSCl+l`YCPkzQy7#?awY=VBcYPQ21w$ zl=!}dWs1LK8<{_BHOPGBlq3JOntj4Gz6Y_~?isJU<+P-}>1=9pb7{&kwL_?o`KZmyKzC88F0y5`Bc z$7?UR;WJUY?n&3;*#~BB<%;~+9XjJq=kMMq3ELe$pDlLgE=doQ_RPCbb6NS}x`q$e zFLqk6Dc%b&R8f$NE?lG+msZ$Q9W!IG<;#ix7y<-A{YZFz-cgz`e{x-)Z~e9v3U=Wv zjoJkbT}sDXJ}9b)`d)AgjMsS^=)bNyty-gwWq-H6N}#97N9G?3dp2L+JZH<312fci z8*kpcf9B1(xBvb5`j)*x@{YlRw==!+li=v8J z&Kg8~N;$jAGp;mu^&_im%6igerG?k))8{FcUKZ@D?@p{RxmUa9%!HUPt60u!9{!Y8 zdv;p?&spBn7OSp5bk}Hl-zDedOZ87pBsOioUK?#!^VoV`z^h3D+hR&87bi~6dfO}0 zDXF5^zUa5+>zcXy<2Q%b=>1(babfxyYHeUT%o%m1EU#I$!zv;~VMiDPUqHFeKsK`#2 zoW@sh{Ns(63;4IJ)ie#b&MTY3-MsNp?y0WY^MSP&?>{qMsdYxFd5zS%l#9I1$3xq8 zM*I@qsJN$m(c!DSZ?-QW=$|J1}KZ{5D{ zUhgzV{&2fr?>~7dwOj4~XXQo5{Hm$kT2+2}`kpg)eXHk-FX&;iot|0c{8BK$)-_1n zygI{|O`k~6WZ7KYtmyL6^^N!FGVZjOb?S?1s0tl6Ji*GqMVUBzXFKJ;e=0QcPst>~S$?ol)X%WzxI%N$I3#!Jc2= zr$3T8%gTCU`Ahx_M=W~ogX?EVT zf3laqzu=y^yjq3*%?*XiCw>0UIX%yI_x-wCn{V0w|M^m!p}0cjvCgIC84*(qTTI-; z+FDd4C1ZG#B(Gbn>pshMd{w}1Md$isR>#jW&@YO5y;UyPuoHY?;cwYM#H} zuDjV<9X6P@I`V1A&7g9vDzDWNE4M~%T{X+v^6-`SE5l;9Z(6c9Wk%cHGX>d~qW_li zy6?HXX!_h+NfWMRSz8^JRJ@TB;=QXhUN_W3=-gG4t(%rcwcRjpoz!sJV9P4|Rgu4Z z57)1{-Rib7bF$;kdW4*@}JXxIxyizt#aj4*+Xk4 zSMN(VPMRTlSjKtF^lF}>h1WKioRXY4;jpaL<)&)Z=Z1?CB%WKmGgk3GvU0~Chl65v z4}XL>3f|@s)VCA0Ig-xPJ#U`ejNNH(SKd@LJ}+OolC;Op@T`E9&$XJD8`s^GiPsDW6p}M-V?95?tdApO z$M41s-ba)E?H6s2W7w$|K5x~udwefeH1C|ezpN_d-pi_-M?1WDq-{f&#K})xlQk=D zz58Y3FFW+UewepBCZ6~9iX|%~Iu2b>Td*qZT5enST7$bjm8IK5OFHTk0u?0QvmP{K z|0tQ0{QY*`nmvt|E=O&seroc?N=WPZlv$xuGa}zKeSY}SM|R4)g?i!tHgxn^TU692#VnePu< zo6HkS&ylOmVRW2!Y`2Q^GUH3fHR^A+ZC(`RWz@!Burc$ie!-WEYu-6)9TU#subsV7 z{y}x)za!oS@^#J%%Do=@ldp-+|Hb#P_QX+(+-Ac|;q%@nFOaa){o7;gTEFQ7(?VOG zf4lk%3@w%RUaES%Q+PtdFS(s8(MmJI4NpxoJho2p;5y~gVJmfG$`{0!Im$YO8#a2@ zH|c~0Z~3I?VZTyBD5Y4$e8LeE)1{i~9{2B`DDseL+^i_jxcO|r=Ox+~&&a;Jp;-R+ zkiqUp7JWOl*!wKE9(XQuTxPn=w*`--`lvc;d^GBYs0>TwnLv4y*}?y`Spb7 z(G|Y)9Kj12T;}g#yU3beAiik+xd+N8+s|kIbDAXkA2K=$FC{+Yeh~6zVqkdB!oc7L zE+zgxR;^ze9P2OaC}O+$Z^Vk|m8`24aVUB1Pg$scY)j@9H8tN??m>rsZ;^fVVAJh0 zd7bq~|6dS~H~4t)$D4em7jy6W@`|nPpni!Zjj27oN?n^f}_5s z&6U&2!q!%?CV^&whJmRb=1a7j)tnbaSfzMu+tZj3@ya8-evjPzFD+INY}<`~_FaE| zPBA=a{^Jy*3iaByUa{}4x4*W&KJ75CD{sLP>zqn;<#iPgG}%_a-Q~1Z=H2fmuDB8# z(=F{?{4$B(Wiy4pwd`iT`&Bo5U%>5Rjn_PB_BIzKtdE{Ew12wo@ZE*7imx}%44R#_ zCs4t*JpT1eMxXWBOLFQJ`uij#uBPl}e80c`sQbnj-gobP>2tMTaX!r}SGeE#L(IzG zrEm9qOzcnm9e;tRJJzzK(%{-7>H1k|G9JhOJ&i~XE10~(C^mo1uSZL-T;ei*TUI); zm1kY#jn>>melzEH|4pb`r6cjFmMc&6=etP}efLi`)?b&~HBV@l z{oz-l`EL6s9MznaSS)9|Gx3tRTj-aws)-r%U!+_-x$K0-vQzUDYZmo3>a5M2oAP{z zU$r(<0%v8HPqc)%wv)Q%GwrL!Dzje8PmG%XqPEECrpt*b*Ez}>O@24_IOenoZko3E z)Qr&gVSyahPYWlPv7JqLD3&LDKFTERqNUEXYQMklkNll~A+{-LTg=b4kg0X)9{&H7 zl%%(wZj_1W_na4GlEi-FDxZkbfs$(??-HBe3E$xP_sT=kh1qReiOoZMW3C z=pUS@6_d?!Zf`Dj28N2swKF{GMMA~??_F~F>PiuTrWBQ)04>FZnCG0E$aEFmtg1qTJMurRwnoD+CF(zfoS{Rf%HWL+-rxKE?)AU#{ONYA7upIXPjB#b6WKp)L#&(TmZC*(9w^qI zb8cdv+dlVq)V508^8j%Bb^&)5;} zrYtw*qx7F?+w0XI>;0K$F4y&d-{)p{W1P*I!^%Q(Pv0J|`2CT~rm}H*S)4{bq+7+Z77#rn=NhK3dn2-pT4>Bit$DD5O~&bM~sLjqjy> z+`t_qWV#2k$c)KH-yM3H_>eS<19_{ih4@!FL)DEozyQGgJ1PLzahmY-9B6<%f3X zEL+%{Az2$5e3kQz(y<@!@^URK?&kEhrtP-mQNRs9p;h?E0XndW@fyXz4XnFy4eRC*Ume1`OM1&3A%L$4}WI*yy@!Q z#M`&x^a}4)IUekdSiFEym#co-;?RYs>sy8mR(ORZOB?p(F{?X}ReA(v0y_6ZL*t2BRqW9jjeoA*D;e{-*nRsT`L zfm?jRSKHg}?v*qw4Jp2ocw5R)sLJVX=FO}>Ld#~W%7hef=xe?>=Ekb8yzGJKk$M#w zv4~iaw|R#PHKzZmS*Xk&e(+CI$+w@OjS>B&tbMB%w^^@HD^bsrmiwyKzvcl)T<{00 zdlL#m4$ih%_P~Nqqk=nMyQ01M%DuT>yV$12A6vD!@6|Rt-v*IA-NIb=k`w;*egDk# zD11`WWSQ>Z9}b7wnX)$S3i=>;j3sZ!q1Qq63vy?*&Qmwp&agJq&AiRwvCpa4gqL6P z40kQu%zESLt8LGs%=WT&UEk$!*CfyOf6&6+GmaS?t@2pBy3)5%ZL_J_&TA{)i@cEi z%x$U>Ht)(=#_|iBue!cf__NGa3lt!N{xK^AQZ?^VN zF;~vqGVb~vlcHztzP&5wFK0|>yue&8UAgPB>7K7oJuT@iKet6!^or%r55Y#A_p({? ztmbbM8MHCU{<+{mGI4QoEzS%BJ^xt!M7#MX!9Q%eMUSoqC(Md#$+7oKl|9v6eql zd1lv|y)ic~ReW_^8m|}lD=?%@>)oU+s~)+%JbOiZ@620E&4aaD5BP4;J9w7kvWM&p zjkhk9)9PHNUfg4%<+oU+N^I%h<$_Yqky{dZ9%ek2SdwvBLg^x_i;n%%mp@c{yA>E8 ziB9R99-zsWystvk^bvb!&-osbIbg#=+^j=r3?#Hkw0c3H+&v**h1^_?c(Kmmv^m6 zWC~Ti;nekPu1fFHdzx7sydB9Cjud|SldB{8enIRUhv^mPtsS@K+ZH#;-D#`8eR4bR z7QTfkAC;oY6O$jjEjwSmVA>nc$2(prh;4Yv$;8fX_*!SxZ^@_g=bkA~GLw(5X~_Dh z7-INLGOWh6@gc9=`hZT4_45xzNuNC4gtJ_*}Sn@vcQ<_RYqhTXy(8uvzy$Gehe5q{rg>KVQA#7tph*CVctNS5-F@lh)eT zeT<;4-?X4W^cQyD5z1!7L#JTtW;%7`E z`Gvl!E1uMevgE02F5S{BlbewfC1Ax{m=*NmTQ%R7-!U_vOui^SrN2kl@#l#h>KgKr zf8&0BcomnUDy_QX{N-xw2l!KM{G*>Ws5Ym1mY=&^T=#tI z+xh$V*D=pHIH^yB%j%NGvPdn>(ja#>^Q$+fOgiQ1qi*PYVUF(oq7F~43mqXKoZ)6|ZIz>)a?N7Pba_cXL zKG}F*bAH0ST`qL%1>5evc`;tw6t|iCT#K>ab3E|V)$jF>nl)}aT|2#c-|0N>)>5aK z9i>z6Pn_LS=Pu{4rre>V;oG&pJ<8!SJLR>C6ZY|2KfPyr<{(3)`?i@j(@fXd#z%N3 zP5ZEId1v|enS9%nzHMBjce&-`;~fHDLYKeHo8_;wRrRoY&ax0=9v+3&dfRzlSfnQK zDYHG>nD9VJPjW}|#d;Mn&f>kgf{CA0{;Hmtv!}6Tv2YUR&9GFfD?ZvBD15|2ExFHD@c+pt&ev6Py@%7YGJN2jof8fz6v zCCvy83@Dtd7*{&WH}87av|OVeG1-c`D=<-jw z7kn|l7fg7OdV1R)YaV{}riTYVO-^M?y}B}R6X(kt8K&CHDvoLMe&P|CtCc@x=Y}P3 z>#ap+>N&qUxh>uD+bKTreNiVL%N_k%dfV)1R`c$4o;z9(=v>}A^F{1r-+$YZCaLbJ z&2@65oNWRpDdkcbno)nq3xkt_=fkmokEAa=eIijT@QNtm)-QA z{pwoszPI5X+LpS3rq^{cm+bO8@8K%TsZu)U*qpxlx;d8$g%4{zE4_25smoQ?J0fic z_nDNZt?6B+-aFz}hJHNE)4cai&|9;^Up`uVf9=Y9#oG6z<7V^vL-UM${(9$z-bt0< zpZEDoPIcenY1J2=PF!$s`MQr$Zx2fQe=y45a%R6z*v{Fjyyr@tTOE42^m1|KuA?)P z?|55ojQ;=hpWOC(v)8d%>d&Qkk7+7@*?Hxqv(%vlbMh5tP7(H>XCNZAh|yq<;%bi$ zgSDQ@ySdXgtmlvn-px_}>3q|;rt$t zZ7!}oZ^Sj^`F<*iu%9mb;KEm_w4=jYBz;GZ;QVy<+T4(XKY9!Tzt&$owNLRA-%8sR zvoB2&JZ1AsuG992S#9v|8+FkuS9-EdbDwgy?1dO#Dfhm2p|@6Zq{^)f*(2a~+cW;K zWfZTMvfug5UL8qn>oh+7PfnO6U>NmTrD$<%_ltbg)XB4Ha@=kv28LB^3=HNB3=H{2 z>H6tKi77dgduK>YKEH@<@~x%rtox6znBTKmZCNvuIAXSCrq2Gy%NZFM7Be$2Sb)3H zAmuX81SkJqVZba4(^ua#(6IeEsliB5qtma3$c+-X>v7}nmlNFY`5*`yuXNzYC1 zT>sFZc&ypVxvX+_{j+JO_wL#%R?pfO9-rXxG`?)>%c?0TK_#WgcU7wH_4aeil0$@6zl)YiiW z;q&G%{o?hn>GF$PJN7+$&l383sq!>~JBiPUrA#5{P?cAU0l7B(>$ZX zdS;y4@rAcZPAgJ6<>(8a+3g)OFaHiW`^fIbJRjLfnOX-zR_OHEO>^kVlu-L$q0Otj zgUiErN@9?3t4RH&OzF2q3%4}7erCUt^M|1`U*b1w?qdPZ#BUSlUo2$!Ywgyr_sc)_ zO;DXrkr#)~GH*FI?(JtETh*FsOnz_rD>>;=>=w?5lCA?gDjAZ$@7OIC^ou2EPwN!H zx%acw*9XOhD$Kro)LElC{gUG4vtcJbI+*xuVPEucn@q=rq8Tna=97=e`ji?h_B(HM zSTjvnD9SPJ6qDQ2I+3WawlR%<)(idBe)6N{o0k89g;OVQTpL`!^t70kQ|Okah=of} z1UYbMDo#*S^IbLL%7hoW8nZX;cr)p)?#KAX$>#cdD;iyd7l;2>ORm`*9jFuac;V-| zGv@DW-@iUn_w(C7s~cg^|#!Cqu-P|1>RKGd02e=t3B&3N_S|AK0v&UVpv?&sU` zZl&xuj#yB>yg6|~+)6IJ)}k_BvO#W2D zU*G0bnXtNq&9#=eEa~vAL;!3O*K*!)WgB6WV6BHYC_JA9uX7btAr7 zN8EV*b>Bp+5H`}ced)TMV`bIjmV~mVh29Zwt1j8@k@z0_)$vR1x%w%)4m$i$cdE3S zr*ihi8E(#<$qSvrzbXk98vT#+3NNh@Y}4DHQ_5^w!`IR}N$ z*2)*=O8&U?ebJIdi~A>vdmM_|Tdilud0f2c$rq)kCj)mEdY!0xsH&oR#bfoHgMwj9 zmPgYTI%=r>GrhaKc-EQB-4%1{CG)OL;C_;*pnr7VO!M=Xs=1zsJXtFfbwl;d74gqD z`L7q7+1V>!`N!_Nq55E})Q|3-i_gR~70b4fs--u2# zlY4u=tnb(JcM3`}I{V9-NxxTdo_>mU7e--4*#iYPE%eM z>94@)`(|n(`;nIH9n!-0534=r{J#E*>EjviXP?@(Y)YV0aF@Wq$Y1n>pC4= zbt$~+Qbo(!9czRh%Re@|?Yrd1S+g*o+1lGS9#s0)*e1TIo)I;9+@AWs@h%esLpD1D zgFUzkSJ)iRxmG%!+dS{i3-Qejo98njtr=eQYu~$gAqIw*nv>TzD@^KUtJh1;Nh~g& z8(EnUa&_nb+LLGQoIK0wq;Npv^a-V#%^HG-q{K|Un50+^EBQ^DopQoJI8Dvz&Wfhe zl}E3wZ7S7VyKGw)t7${vtL)c7*{iqNt=$(EfBSolclg>|(a2xc-_QA^P3rFaoBYo5 z`<(YR&!g*~TbIY#{ri&0VElBY%$CRX{;xi!fBn(jS5>p%p|fmW&4S14e|S9qaNp!l z>|y(&k7{<;7Csi1wX|6DFj)3*p^5nM0vqw)1x@^oYKxNFQz})Xk82cWKDuTYW)pYu z%IWzp1yYOYpdm$-t~ERH%G;?=3P)M}bmTmDIv^;0ft1+7cd+GFJWwx}&UZPhoQ z*mIL2SB0-Ud2?rk=H|Ud?vu5y&RtzL_xaSHUSC+_>LXX&6VD7v&-xrp1o~Y}BXwtNQ4uiCK4fSt z!+orI`s}}*ES2@&UVSOeW_hf~x4m6C`tY|WryNYu++II!+_Cbc>Ya~Glh2rPxLNV6 z7Ztg}mTZ`pdp^uPdadTGpu0lmi@#;~OfGG@c?a`!_vynz0``o3i0XPN&P+ zy2rED_)9LR%2voqd$Zed!fe9=O>>{^(-N+9OUFW(3hPt9t_nS^w@UcO zw0y1@xfL&Z*qucKH($LIw$VsndC0?^O@e~aH;%@7$|+x3k>Th34(77OCl<9JQPlAO+yut}RourZ-(_Cixs@j*Y zdVS|khFiF%ljFZn9>EG*tOR&heLu25`<|G}^ON%x*X8DLy?z&9d+=uKYqnR>SLQcw zU1QnHZ~4UR>)s$)b~C2ho7>ckC9R}cH*;TJk@Z4f^~Z&6#yX9{(?sW(u9y_ee#EkV zXT_NU2Dwn2FIMBl&0KkGMNR-gEG<%$IdelkZKF=AYPuc!Fn z%$drc+n6+^-d$8#pwujNRKJfk>ZO1DF85W|RuUJ=gaq|^JlIP5`dnt8%`i%T6Q~;F zekEsP%mkT}-okm62FsqD%`@NKAvB%cY3`jXxowXFzwSGe$8DroyvlSwWS=$bOhnGBHIl|Gm$}&88AjtiBy~w? zE!(?ewM_pLHdr^XUp_X$jI+Lo{pJ$6w@s%U`=yV+@>|Q7x#{MF4K6${C+N1hxGH+p zKbI7m?kBZt&6x?OQ&%s@xgdL)+kdOz=6G%G=<=6;cvag8a}q;-7)EE{mo4o zCPJo9s#L$+Xv`GkFdlw~NAtiQ!M_FsjNU`lX3Xp3%Q%=gf+*5$OHBo$Yb%zn7_(PxIbskghkayfWeVlj>PE>xA;V z6YdIF-fGM5YI)39r7Q3%gS%y=pUI6U`B{tGXX&tCRK0UL%gj&z|CuWr4*N{5ZF>{m z)T1A>|HG=Uvf*LvC%(TbT^V=t81GTnHXB9%ODme)bi04MHVg4q1HOzPCR37CKYw;QdGe)fkp6yt zi8ZGuJpG<1DXMuoZ}}_p<}*x}AI?spnx?th z$3?~Fu6gu%?vi^U<{cZ)iI<$)!oN^K>JOL2kFDQ$vbX)f>Zi~wrF_CK)Vy6#>SS(+;;hJM>{nMs5KUh;Ml8jSR zUVESFQM_~GckP-BO%KzGXYbmzdqq%hQF`y@`m9~7c41OnV%9sKeSSB0wncA}_zLcI z>ItbDg@-48_dI30>EkiwmDyzr7r!_hebz#Ix!uRo-LJT2axJ$}G`=I1zxmJL*-K?yyv0SzL`7(0-KF<{vv+XK^ z)Ri{LXQ=qs+h(6Te0G)d!t)Md%i8@|gUWwRlzf?8uNe3(D(l#+MF*dxZ{z!Fn7FO^ zl(R|G^1E*~2~<|xPsw$VJiPW%Z`${$`=&Zl`rG4k>)(FZknP_7ckiP2UGv^ObY!sn zJNsD0@*{7%Rm;6s7+;%aWARI}U;TlAvvHy0{Led6&h|vQe^^}KUb=u|@CJ{E3(O>SZ37Y*{SVAiaFWs_A=mN~PN$c!&KL`&VJO{nz$YX8Ch= zIe)5^$gGHd{<&_1mK#+8za2HVBrgwof=N-BN%0 zxmC-=rn{fIUOnZWcX)+X`ONcon=kHu8aUs2{{r^pGUfH+$S|wMaGh zQ(Su9_fc@Q!M;Ypa^_hY6iulY`#&th%A|8~m8u%+bzi$GN{T)e|GvOQaQc@8AzL4>-eZ@~f2vIR z{&U||-hl<1rS#Sphd&c}qA@x2&C#5!qvlJe@Ao>NvQj}<{X&3L*##3Zw2r4hv7?V_PtC>?jHT{CB{sXQ`(d#GP zZ;Z7&!1t5m`sw969Qz(GTcfjVS=V28gGoh|1@>|eKKuC`GT$(LFT3F(smmHO6VC^U z&GvhoH~FJ)4fn1i8zyY2p6I+%YHg(c_p_c~x;_ZWDb010e6uw!>zm>(%V&;TZF=)J zKM%V(<&538Zx0gF?pXX}-q&3J-pG9UiF}Rci_h#oKIvs%U~Rwc)5gjZ)_p>}mQrOI zH_AmeoAi8|Z(92%P-Ig%k7-TT3oEbAzJ!BoiA@)y&y~r)shxxwFinCj=b~mz@sReR=L@&J67&KR=@Ep zS3X}tTCQj8&4*s$WlMJ-h<$MDbckNT`8A)Ws1<)Yqa$-DGBRTG<+D5Lw|@~x<9u~0 zN8r$nO)PAoS}9s@58k}1eoy~h_tTSKgfhhSbB!kMFmKLPtu0qfPUfxMJ8fV1r+Ka? z)s^fYp5^{&-O&8R(K0w<*SsbTov%j1^W607P5pjdkgIG{&U&s{FgHP?%4AD+McCm) zyVhqvB!c@_U95FCnAg3}f2Ho^6#MgUISzj+(@!&>B6C3IQJ(0>iah3r#rGJ`tk?Et z{H&<6K(}h+gl*9wPqj9m33UD7E%8M3s&~YZOS0vMy}tQuS2xKA9q^=(u_3 zlOIJwG4)}qh_@yp(CVvqk%vU4|?3cO^Xd(%D{f?@uxRBb#?lf>|QB z#V2HcyvMBjzlLu|jiudR0lgDpUyN(k{b~C1^qcl#=ecHEz3Nq0y1TZizI3_j?XgO9 zhvv(pD7uU+74o16U{({E!YKzlU zzX=+CS3Xm7_f*O5ZpmW%;%5enKgb@twq7#!{o}|#6P4X1td4(VzWCAk(W}po4tE>L z>7P{k6EW>^YGmVlfzxsI6J>v_ywe>1v~-VN{)6YAy#E~P`Wh?Y_s_fYs*CNrUj}st zGOq1-|MrJs-I0ts`QVQ>>BT$lv+PN@xOR!i-6_Wo*Ya>1n!YR2j62dFYIpkfNt?v? zsef7)&Q)IjQ1s7~$cK}ke=vSGv3KUB-tf-rdR~8YK33>|ez(!(-_1#T=1qE1|NMwW zb$filnP(q;x{gb4S#fHcwBa9?RYEtvy_ZUh=KQX9ndiv!)C=r>87sE@%8zt$H=IAC zieQl7E&LU_3Rdf}(H+;ePm&c8nz z)pmAQ)b*xG;tx;S*H?a2T;sofv4L)&d+5%3^*4@wn$B5=X9bm-#jmQm$-T>e&ryk6 zH`+6wa_MOFisu)e->&(>x@C6!=PPy7e|(es_|`n4<$jW3o%`Sa+O7FZ*YMpxSii!! z>-o?1JD9@W$NmaRypgo-ufKP{>yr)Ie|t8)s6QR%X~?%OSz=}4TA9`~$ws%;|67V~ zEI;?Y<9q$xJJ*l>R;XRBQ@CTvwl5!=-gt#KW*>^n(bX+DyQU~w;l1CK;C*p1*Cxn& zESbOipMn(sf=<_2O|zdp*>khL&OU0&)~M9D_;F%FuOV} z%3wy_6dxUL#?I4|PKVAqvgrGoR~olB)v0#ZJn)z3wf|i5le?b#JAdZR{hQQ&Nk@Gs zk2$*Y^#{(k%}G%r5aSo|&G6!+qbX>*P8&hc&j?Z?53>?&D4^HWSXxGN1Jxg*@@TWaL@|Ufv4GP~7+83;Lu5QWw*u=0~l5daw zUom&*kNS`GeBGOW#hc6#|6jlV@j0WGxssLp{bOf}MH)Bg@88R=D95udZ^x$j2d4Zv z%Pv^Qq|5x?ud?LiW3k;j$rB4c@Qa<4zj*K)*R?vqqZ5?EHW%GJq#ZjYx94rlw!&?5 zbM)1Bug%%M@oiFdtM~D#IqM(&j@TByd2id>vLd;2-?($ur&iC^=C;1^PUY{{9RB?o zice=(oSgjGA3U%%S@DJBho!Eu?FF;ulo<)1pVMIT^U-{T`UBJLR`6?jPyh9t8d^9pc@4 zK04w;nYpgctKYh{J986H9yMPQYNk$~Uu>Cwpzmhzx>DCLW&7vLxzFF=`^+pB zR{v+xB&9WHp8wNTI$*G|yy|6}ch}VU_tU@f?MzmRyic5E&!HyO$jmDhE2iz& z{#-SCv3aT9yi;8k-VBk`t|q3>)CoVzcYe~+JEz@@qSY5g&UNhH^!e87=C$b}TRPdz z!alUN)nzPh>1N}(e{9vWgq&LilMnMsXGd%=bbS5W=F^m0Uu>lNx0pSxoW12&=Z()b z%xNOkQWuX*H>)=*xOOC2+TY>bzC+iS+^d~>!~6g0)_V``>#1!0blKzD3?qZF&T0kiCwbkbqR+a5P6FyVtW4^SF&gUgZb>#BO z@0A4K?-pGzDY2?xtI}et=~4@GC!{FOw94AFZ|kMR+vS=aA0~8hU98ueUMW`Y8?@cG z-{K=&+V^?waYHea-IG@oDQ?0t8-LESQE`FqPt6$JZ~y;t8gQxKoLh5r%HxiY!@ z13o3f?-+l5D|}_X#B5He1Jt|Y~sTn(ZGOP=pQ!H_a$?uWc#0Zrc(e*AF z5A8W-dhpN9G+tEs#^98o@?YzBd#W2I?|%@&z4)BO!Yq@;tLIc2?U^#=#^PPuml_{H zTm9iCF>SRi69WS~3j>24zA_=aD6ya*wa6v2xTGjEsk9_BKQFYXKF2vfuPn8w1Xe!G z4UPsaQvbJ1eA>0AN&%vRnyg!NPblq^$oApLatd0NxwP&0OQUHAQ_GC!3VjKG$gMKz zN7kc!qhrR=EsIoC@-{s`v$OWOQF`5a>4~?Bdk!oQ1b89jscx*P=F^%lTGI zbd=E=k=50I8mf)H#GQ5ssR}v}dOJH{O;)&!a-)u7W zxwiY%iQ0=(WIY#Td$qP5pTHCR*Z9fAFIfv$l{P2nP7)P2e_*uZuWHoYN!{)d|B@}T z@3pq4X2%wOlvvH<|NncDgqyxw{kLUX)oW&b38@$C^*{CD@aK~TPrAZmq}PTn)Ac!g zU-Y-hn$Dz`t5%)T zOZFxI5qbI6XfC_o1DWIx8818bOfvi=ag@QhWwQDa%SGIU(`xuRg-;w!6)WK0u35}B zd53d7Q@N)#$2Z~1_9dE=f>QRoKYzL7-S3uLt8MuIuz{;dc#XAx!=;tGCL1t%)H_6< zTHLbjg35%b4ZKN?p(+!&yBFvQ%7LVg-}^(KcQWogWN#T!n93n4H98&)hja zr?~Xp-p`+}f0t*Nmt=pyC~xhfvIgrNuaj>dx0Uy8oSJ?s<9p14YgzL-D%vYov8+3G zYlZpcj}AA>izXOe?)dDIrhe&_(L8lq^GmJu4nIywr1Bd_igZ0(Y_a`tMn>wal`kew zo!q(UVz*6sYjT0k)|b|qb2nA{SBWT0cJZBaAWz$FvV7{2&o7pq3&|Hty~MM4-{xC9 z)o;H~nVF@%;hX*xuO69jt^dlLEPrdVghQ2Bx1AF%3fOex>qO5@dlX(r>`IGK0*WFJQ^-Ful2mapU@ILIz zGajSm)9;y@tSXnkUbt9mW1OM+2G7?I)wUJ1#yLz0FZ>{l8jYul)N46e85nrDCi~|| zP8PT+Ro@#H9WER$@{iARh5=8U5|?9R!~zuokBhg$7KHR_Tv#wo!|c*6zLSbQercCx zaysRI%hNw!`(ds9!F?=IVQ-^%ht&s%hku{xslxe@DSPhBo7MC8?*IFC^Y@eX|Ns7z zIH37QMY&-~&*U8%iDn(%LVBlX9NxntFQ&3bS5Z~D$5paEyddH#bc(bK51Po{UfAy%YJ90L%ks{wB#s-8rY0Kf znzUTetl8;-7|(? zu1G}G_&$$RfB5pmrwH4^=%ZSdb9?iayQiJl*SzD@z1Wa$QRB)o*W3NHGi0Ny*g1Vy zlf_!+GDU);bvgMbK2)r(nDg*L+=SJu%Q@Dv_#TwKBkEDowr=^A$wF(cYG@pokf5dU zNSSjQlXPFxqzJYRiVx>C`Q~W;keDy9yJXw(y^Braj#|BI6lu};Au|7>rRej<6}cKK zo9fRO#vc;r+IJ*eXkXX|UbfW*T7QCH3;tF5vYl(+VP@9*j~Pv`a(}z>pruLvgYw}I z+<6P~ZaGH=FLmyfbvvARb_Fb*>{{35>>$zU$>g4eIOWkL`5nU@=a7NnuvxvFW z>f9qgSNZJ2hnRop!U+lct!~0n;-@P@7ZoPwJpg3f8~ak1BD%gEq6qi@gn zq3gGwZBqXop{^~}91I$rWn6M_kWf* z5}AzKSfAhh6|Zp0Valbq4=*+Uhb(=VYjtT`Y(6OdDWbaevHeLjdp&2Hm~~J_uA)k_Wu4g|NcLQ4|e;mPCRg2 z_r-xN5@|;!T+Q4ecC1v^{DY_Vq#c@Nc`tYL#%QM*E>~Rtus&E;utsdxPPU&H0}t$x zc$X1zp&FJGsqjPe1JbT7S0mo$l<{W^a#l=iS^A?sHz~zw~U!`opUXdCq)lPrLig zzxzyrh|H|wZIP=Bi+0qBt$+Bx!)>K!nAEmO`M+t2nK{(I){ zQm3-IxQt6@yj)olI`(CzbxetEZ~Eo>F61xosW&#wbrLZyJpxWYKQ`^W8ZbwsK4$LW zpc$cYMW59;LxR~O=04r^eB#r$vpAnKSDZd8BKCaVl%Lb`ck*p~vFOaS*JhwWjnX{_yJKLfz_P6 z^Q9x4P9EUUll*e0WC!z`wS6 za&LIvIWGNpv)CoWSb+a8S8nKx|4u$W$tg9h1sqLNl_I}7D~AcXM2K)+>yr~Z&f%Rj zr!;9+sb^W{CGQO1GUFXRQ&P;E12?ff$?};ey?iT|s^IGdxmEk5ro@|TJWsBwO32{X zHN1OoM$qI}#W6~02kV#oQvSvAe912Uxf#dZ;ue}VTrCM&s+g^Y=lE_!>ub=H4%m#7#7^YQ66x z+dzpYvp;ve&F0GrjUB*vvSOo{J32;0V=J(_M^7N#QH*;<}ouc)Uh)# zn1D+Y8$Rj!-}%Ds0{_0{6n#te?UD8fmh$N4-ZuFL-%@^|xPzKgu2oJ5_Y~Hc{rQw- z)!yRs&)fbu|D753V2kUjADv!*!?hHDIjjxgEdBP#Wt*_2Nl{sP+5VYxf2Nhazdqgm zFV6!VFSfo!6R*RO%(WHaE1xf_;D4|El9^fl(Vj-bp4U4P6zW$o1jh6{m^4ej{4tkW zNlfnofrCr>`gy)QnAOO#PCH-z^^S#)h1>M%@2*n&%){(@UHkc|c^Ws3wmuk1VVMaX%_gJ~+x{uhg$l)PPS`ck*Ubat4K>vfTDlRoGy zH5WUq#d2%**E_#w3!B!*)?4jM<+}e>;s@{XiE#(TuC7w?*?0Nk$-R6U@BVH2l76!0 z@K-P2>S?bH=6Egb{(i(<>A8pfcKZ&SBU-24pWEi8v|(dw@VT?U=RKXmDWW*x{j7Co z1$aMnhkAZI{;W2!&Qev&ah;W2>W(`z_xDNmv3<$<{y9q`)uNJN*1;L&+4D5l*GG1} zym2lpEcL)gw!Y#$eRZm$mdgwlCr^8<_RQkh#s$d}lR4+V+;Mbc&w0sTw~Y5kZGJQ9 zi$&N5ulCgP;O9Hm^1LsoY23~8vCO&c@J+Kg$Dc9*ynKzOqH9kUa(TAB`Tv@|EqS;4 zmRz2alu3$Hg0382Is4g@>!y*ai(AijDQ)$w_ct{UJ*{|BOhr`vrR=EZYZj zZ*0ji6R+G`{N3$xhHdHhn)2l3iwi z#AO$AQrhGkPvMM@=e&_p# zlvb|h+dHF@<1M?3obs+ctjR0--mxrS*mtAfV$DO&s%35Slj?KiBld`z*?!{QCFH(L zUU{R9P0;b|=ohsP2jyx7RF*W^`o@bqkZk=i$4+7YW%C#ObB@oCSjzDJ5v$LiUao(< zlTHR4SpDLtb&9Cc7uh+AofFSm1gU5`W%Y(!{!-6!%X@}Z)wcTo4aXg2_)H~cs5DP_ zq;0%~b(?*C^X-ndU{zl0VABYNUIpn8Me&GdAH}A87YNPkd1Jyg{of-&uJ!zv!+-r} zM$N{Tm=!Ksi7+sj=uGAlQm;Q7#aR<_^{T!4%rn(9_vA3Uura!`@lu<9X);hwRfw} zez*U=_vR$SOYeWz?XPoqcjxJy>TUlmpWoy3|MU7_duN8^|GhJ`c3wH08uQL^eZA8x zugpDC=RZxDonHOIabEDD(3&Vt+2=bi{Vjib4^WZkq_@6vS_cU*Jk-g)lu*EhpXJ+FG9T{G|4 z>5{ss?P4E)ZYpX#clv2@>zOrE(x#gDUNXtvQy=x1+xE(d&82x0&v!40T>LreXU^4~ zzIM;6S2SMFytD3e)m;5)f$i<{p7~{(op>p2`tH(>+s@fLk2_~qOm3eins=USdwS(& zlj$CpUoU)a@!+A|yXk4&=b~-5bX^yn_-Cbp*2D164ej$D=33={|FE=X=9?WcX?oWy z+Rv@Ocyo%bY`xTbk+tkgB_|!5lol~dFw<=*XI4$?x!o?uCY(!_yLCKquCi7C>pxL5 zd%M_^vsR@kFRq3y4GL&DP{SXS1Nw>N9oeK z$>*-W+!O!&b?H9GoUdsQe~Hb#zv}btlDggJ%wPTCo11^>XG6}O$oj|SSvA~~FG})7 zU)(l9vOCgnnenyA!)Zz)@!~gy`CQK|JbUqk$Ca+5yP7ucV0BW{U-s=?^z4rQsD~8= z7kbv2gwj??%wJYfyRSIzoS((c zdZlgre+}0(7|4mdo_5>K^GNf;V|m3gE=L<5c--hwUnKCL>CV-wmvt>_m$9Z#XKrOf^k?#ZiljZ!+_9Nchqvc&C7*WYL6DtgDr zNSZiDpUDU~c5aEbom9&*?ldE@l)T^fy{>64nrl`s!TG+ekomGstzYRhLu2l<-peZ& za2WKxJDk4zuci9*q=~cG=BC@c{;}%M^21*k7!SE?6!mP*w@F>_tmb+8@2bn^wAUQ0 z`20okV`-*B9^bn|cBQk9y}$J1uGIeamA|iu*rf)<+AePXH`l{Lv@dv%(!ReB>H`{r zw@m7&JX?RsPph8e-QWND8miB0SY8(tu&m6>Vhxnsz9FjPRB~9wio-_jRco)St&w0_ zd5O_%QcQAv{_?q#3PiS@Ilrdl$m7R<_r|W!Pi*1hV`;hRBi2LweJ_0zFQ-z zw#YH%+?~aNyh+bCT$ShbjeK=z5@T@h;+n`we5Q5!MozyRQdnwF)NjJVJX2%cJt~xm^r6ewmof1usE*y@XVrP+p}tBAKRY&$FBFihc$Cu zl!YjB@ZW6;=}H^)Wz4^)d55w#Z=bdC!Gn-1x@TXnetD|RyZ+W|*AM7Nu}?q2&NgT-$4bXW1MZO#v_Wvu69(siA)sQ&7k zM3e99o?hX4;POoGhDfgY;)M$W&YoO!YFn>T%tY50VFr%Rx2%zU)pld4*n^eUg3~qf zn>!~+ZvS<8nuYfM`9)X5rg5*gd!oP21;vN8U)s6{<|L-DzfJp>=)VLB|L6^%pCj&pUl(g8B4i?{zQd^RrfOJT2Uz zvZ#655go0Pu3e59yt`(Z=HR; z!()D_8vXhc51jubHrpSPPn|XO`KyEv$A2tlyMH|AL*mQYIrfd-?|HH$N~G`RUHJW? z!Lj@TV~l5gnnK(cE`BDCGwwXQCciU!(Ohz2f%}WVge;MtI}&3)?b&hp!SA1wJ@w@>>R=2LNGycJH_}l(v z|C=tmG*z*hFz*z&_S?ih=Ywb6kq7Qa+2=nzzwBJdhu5x6F8k`e+xZ?PYneq0ADqxN zhwI_9{#&MJH67`#+2EC)dSYj+fk>S8GMG{cnqR&`7E05^O5*I%oc4`=3S4)86duzGQvsjnftJ zjm-xhPLAy}`8W6A{^#}w>i*WgejP6L$NgV0Uu@RvH8!SQC-pa1OMmNYl`3O9?9BW6 z%nr%plUJRs``0Nj^|6IQUiY;w?x{9U^-i+|$n8G%r@HCmMae&6JwFdm++jaWLcYJ@ z>;(DZ-xKOz|CQcWa`;`Gb+M_%%+r3Ep*ttfp39}a@o#$b|3h!4tZBRJ$7nofV(^Sp zZy!daxpg0rdQifjYFPjEQN-q7+f7zye~AB?e}c7ADEIlUFH=ho z`c(d~S)vlM^U|D0%x{e!`|UXJPbs5ppL<4LOWD#kzgM2Qvx@2?TU0;aKf392l0~-- zw^i-piznoM@3d8aFRCV9{pvQeMu))(v8ue%vc2akpS^zN-Q2MBp8Cy@8CmBHr!KnK zoXH&ebi#5Tb^rcA<7>%pdsk1tU?#F=gVd9_#!K6+%~S4XFg~ubku9@&HpkrY;f_0p z!o&RUTh*$)|0(_dyxi2H;(9$9L2aFr%6@Ur#Lw1n&(18oSlN}xW)-||#g`*%b`&pm zyps|eUi{*Ur0d5Hrfk>JbH&d0no=8_ETkuXUUuP$&1|g$mn+XLd-tyR(_X;?muD-M ze%Pk}Irf@%eQ0>+TfWy{rZ=w3`ugkIoJq|r#!5Cu`H`$U{2aV=B-;wUF8|U{U--`I zZ19WEKT5U!)_9m4E;@VW)w1O1%r!~ZdJYwrX?a>}e{L)5e=Ei1mOL|GXjA;7eP?3M zd52y*HO2VM!Y!Jo59p{roipvI?r+WP{cj&|wm8^)y;J6Tb@QGTRn@C!>{fDD-5S!h zyK%)NsprS`*=pZZm3V#T&gL0e|9cBqz65Qr?`6o!P`YN;wfX6k$l!Z<(q=0ZZV0=+ zW2#XoUCuP=ed=eX29YiWeo@{wCBw?RgKUil1HHATx7E43>^nd4URp@-^7O7umEzb* z8?YYIYO`}^ zJh>uuzog#ixhk)6r}mu3V*8yQES2a;44#?dJJ0s^^0z1LQg40dDvri?p}7V ze)T7b? zTcQ>k)HLIsm)xg|z9kHQXLqh>xYzknx5U7d$RAUlJL*42-PSEK&cpv*1+XFN3Qb>@DC#Z~yX7Gs$iFu5)9-_|hPn&=FZ}g7boPs9{Vx%_(pL-E zr{wpo66TUwrLyA9R{n%srtI7&Rh@gJWG}z?p`xog-Hrd2axafoz}?!(H>T_k$k2aq z|Ne$F<_9gGjyZ2jd=XV~ICuBnb@!fs5)GXf{P4#jgVW-#AABoY>fP--@A})O?M)^O zT$dR(G%9K61kIA-`+N7o`V)e$FMF-2ZYf?q`!{e_?BinD zrIx1q7A-zvs=gv?!M406KWnez>}NarC-EQoY&1!KVbT`y=4$q;xfc?c&$h)s3lyL0 zd^d#u{~Y((Q^I7;wr>eLeJM)UJA13n+N+zkgq@aIyF`6Oar(>cI_~=?|EO${D{VS( zC~skXWYlMdjo-gKHrdahu{vZiYt|Qusq+`KGMm~srpqYTyR9`+b<#h(+-}t}U9Xzi z4};wQaI&6i`l&kOFHh|?&c@RQ>P>R%Y~9k;Uaoo9G;Np4+`k;USw%l%?j7}v3JQMh ztT3-R(9~zAiRT7$mrtsk+@7l@FWZ;us9O6_Z%Q+%(LJ2F{?okv zb4@C-4`TcLCWZN2I5oLFqjYk1+AFn^95?Zb*>C46oqRRb@ua+hY8NS5k+7g?{N85j6U`_oI$S27WCF$LnWWj$sp znUB|oR5gY1R_s<=@jE5-suOm@16>4jcfnJciLV-@qd%I?6vd!+rDDG zr*NBQK`v{J%i-|K__^#Mw^(@Ry*FOB)#U)c!!dQlg~G7jelT#bvf^$ z+Y@3s7Hz1OF`UY9RW6DnUuW5M=9X~9FYA}3?PAOP%4&Zc|ZOFSO^GCOzqfTiR8h3}b?16fXeFDNrq z;e7n1nPIEz?icJ|oV6N57JpIx;gd#*OvjD+LdJoU+6{ZnBd~6`#_@&4Q5! zbiWAy(iC-KEBhu^X#BUQj*ollM}JW(tEppz;QQ?o)=UNq~SckP8_@4TxoEL$dP zg%>7?A1V}DXdo=Ay=wDnHN`#Crt@u|@A+cJW{-11*;`l{|NK!|<>YF|^qk-0f{)Y5 z>5nIh_V4-=Re!+qQ~1GiK^Cw4FKlCsvDjuj%ll)oWS!pe^L&5yq&1yUj-4d8w|VQN zPaz9_Pds1tOyy61;xjudZh@a2#o-p*QTA^8gT8##ioUt>zHd&}jaY^KnFXINBw9Fr ziuUHM;Q4w*`S#uSTeB2{C$;4(JF_0)U|Mv}dREtx1xNhz({4{)5>P(3T*ospf60f-Ci9kD|8}Kvu~FYn138T^$Czj2 z6kRpGChU3ZZitGwjE))`SN7ie>PcI~S$4}Wtaab;xpdR#uRE=4_0GBHh8w>RE$eLR zu*xf$e&FX`j^EiIGHH|7 z2I3<77vF!}!e%x5U&B0ZTkD_AgSG*lC#iTDpE} z?9!^Y%lBWruedm3$22argZlywN-%!m?`+goZ{#7R(Kh;Wf8sEOc z`ZTN5u~Bu`)ep0-Y*_xz(2BY8O9{KCfLMuBv0O z`75CL)!pG(aO90l@7I@~g*-0W!}@P&-XHFXOX}4w-#8fhTs3Rs`duenkGx4(c4?=_ zy+tmy$zE6VOlyMIDP3PG8hH5c%EZauz3ct^yRZCc`*P!LZE@?mhNjk=jf@ND3rjHE zVPejU4@_|Qypx%^DmP)lq1bk})%-Gxx663OGrh_9Wx1tV>Tmjk{&Ydt^9xIC`lCg?ESF2oS6q(F;TXJ)b>RUEOkKyY-H_sc{EYM z;|Rl|(~7fZoH=JVePUvov9b278Nc_vU$W*&@xCYBmJur=rq+B6{{S%Vy4$K z)N`xq_P^vZ(Mw!6^VH8}$^E;pZJMC__sEZ*jzYJN)aSG%#~T`3hNs&#Zc{vdR>f%D zylp8-=dNy!e5s~(c9ZQmsZbH zDfzBdx4k5|Bk)qai{`rit!vlxq_ySLUcR(o(yhjKN>A-1<1fXY@;Y@T^6uP;c{f;I zPu`bzhUfLorq{1lzHU2HbY~uud&1{Q#?$iBh0=q=mp+`_w`zG$SwuI&NsoUniP*%TjYU8I5ejEHf)t^fleaY0^=9jj3$^1>cr$74CTN~^A%~W5j zu==6v4yjug7d{lUS+#JgBTuf>qZ{iN3eWi$q%Borqqkx0i>ygfx6jQvGczn|(mI)S znKKTTHhL^KUi^^l@!Sf}!>4zwd??Dc-sr9Ao^=m-_pE%VyJzhKS>E@LYjW`0PHgF7&hBgsf$X`rl4CFrMEL1`)=$#{@qJN%fD&sKH*6$-;Qea_87T7 zxn*^^ezBmZWceNG#@*s4cfD+_%Tuwh4xX3%w8nDP@5@sp?iws{cV5?hEGF&jHgdBG0}w&uz>bbzKGs}N0 zv5S86)p1)*&Dm+EqZe&#;(fJ5Ct2+4=V@MZomkg-dVBw>-}K_F;)^;uo|xot9YqhddP(Js1U`m(fh>g=58p8?rRD-1UsmWezrrNsR%t>UWt6Pd{u zeB`BnD_m%L^{Yzm1jE|3ty7N`ZMc-e7dGqGm$xDdJ+6CQ}v8FPF_FHcZV>>29{*VX@w(_+tJu zjkyz93ni~Mp50x(z~^YabEw?b@&NO#45mk}JzZ$JMt#EZHrA?_ol++k{}bzbb3Xa9 zZi%p?fuT)Cgv;ZC-%4ipopg1h^Zqxj-I90uvErlrSvm#b7xkkitcpAGO{iY=qU)Oz z$?1Xq#`2rixxP`7-L39?e3lyX-|`LVUA#IAex6sTpVKOQ!=s>~=#NRQ!n|VwY!i=2 z#vCvRl5k{u{^F|FrQ61B?+yFp4IAehbjEik3r=r(b5u}ur>sTOVn@06VxJ@q^IN!? zim2QTwXpU3a<=17H#e6Et8IPqVS9=2rM#6)my|!G)as}HU1{*zv3955)sHrE`(ig% zM4bpQ*tMoDA^$+VQ0>86{lN!sGPG88l<~UU?*6d8eTBcnUwPCLd1K1*%T-Ja4B~9y zHFodsNYziBa@YTIfW)!+n@hE|Wgq-Grawh9SwU7lsUxXJ#clFJabxcf@7Bn;E!?vC z?Uny0r1eZDW|(}u#Qk66akU?}bTZqt)c2P8)${KE-ebG`@8|Ew^%=M$%qF--w#}4j zjg)+My2Q`jweK@qQN)FfClXAU_r2^A|2Ho|V&%IJ-|rOF)W6>OxXZmHvD-S&THv)3 zPvzt=kw>C>-)DvCa>=asT>T|QwE5>HZsm8ovTq-{7rIit$#i=ALJr9=Z}qE}L+vx7 zHgdjpJ`k-d7{R&phVNplTeJ3iy1K3IQ;*yFT}r9qu=Kj3r?>B{{d{0zWl`XLYm>F@ zxwn_KBrYx4bJ%fJy1aG$JYn0!8E+cDWUlf{Tb$dj#TRt2;Lt9PIlAsSMoYXe=SzOt z+HrgL>pfFVQVXtn7VZm5oS{2cQZI64|5UyNN2V|~hA(ox&KDN3tmWges%zp)JUvyf zn?E$@^X*36l#Ay+&YH|2JiXxN5sq^+4JMi=CfqnudgsE%BL<~z_G;@Mtg7eXmpEp1 zF3!BHMb@zAzx?8DEBZLA<`;drwKQM?Uq;x3vWzolX%rycu!q2=?nU~@Y5N_EuY>n zUW)HCVAW!L=9p|(w5CNtS@j3AznoVv{WGPP_n}y5Z)Mn_(-YpFsq;VItLMkIUA6s4xk06q zPg<3HM17%P`R|U)>B9G|Z+-0hVI8!*^Rt&t>6V*!lgegU+#{`fZhv{5rVDO= znFFLyuIhMUpu~Awl7ZoiDFcJTWI-!g=-Di5p);4y&wf&y%$}lnU<03rN=mA`kc+dB z$_y5t2%d=4NqbZlPo7zr#&l$B>B>bJYp+FZDShpTBDw*4}-SmHoZ; zXVliLegAj9KkLTU^6ypuo$vQz&)J^-uk*d{{Qlod)jKjKZoBBMx+iKDTc%X~-YX}4 zt=1O`?Ekc6dQ452+^*|hmvzosWuE(XiTlo@r(t=YFFoE9H;dP5{^O-gdDC5Gt@5W> z&Mvw4W@*wrr7h>DF1zggxnlL6+{w>u=H6F7|G9LZ!}GUsvyS@8@txT0Ju8p@`w3y~ zv`s6E*SG&}Y0?b&y_D0dc;PwmmolG%O!+J7S9Tq~piOSCT?G`r}oC_?VobvxIVkPthk-p z-(U5EZ?1j4+T7~BUkdjHTfP7E;rP>^ocj0Aey{iuC%MyKVn@7M-KE3xKYd#M(|FTI zySetSm)hk`>Ss^6`aI=Pvs|6W^Y+rZBZvE|D)#rteYnI>A2&=umDLVu`fe(c+`tFz6_*5}vnPH_HvY^#r}t~gs6OO{h(LA?>cki7z5i;n~ConGKv+%rsVIwJo5$rp*5F_-{mke z-l^W5oTiXy#`c(VnW&}ejU?N|xAzk6C+JM5=Wshz`dQb7McH(bu%T=DGmFcAgwg|PhY(2<9#o9cJc8whxm3G zT$JcpYUY1BZN=H`Y>Pkf&Sm6J3z_D)zjbfgqTTkho6n}+6xq~jnf0c{l#iu{dv==t z9>b>!dqnH&mq|okJo0VfEbpd^QX6JH68tkg<<<7Z_6+=QC1e;%s+kiQOTNtLEbL@@ zY$eqAt~-i3uvKYpeCz(6i3ZI_ZmRRm%-Q+;IhW?WBMv4@)66H_RJOBJ-CFcDA%DH3 zarLdM9UjvhRfCfjt8;7GGrc@$V6vF!yovVm#-KI1eu8e{^`C$F9GYBxX2MJZ(Yd`7 zGrD&kW|@%0)Us(~h>UHMy7ENRjS7b&bQ6R_)KjfL1em-$@^A68b!YA+ht54`f9G;`gu#zFi;td3 zb#D{iv3ttK8C!B!FYK(VFBbpR+~K{qYlj)bowFOnj-P#ZFv7qv-A7=S{GezMLeBPKd`@^K#d-?^N%(9t=injYt>Zy&>_iyZ4>vs=4%omho3)ATa+nYFj2t$ zM#3?+rjI*B3r!EUSkHUW$)gtZAYjY2dY2^TMi(bnwsek2p~;J5I}#*s-4y8d_~+-u zG^58zw0~~E^dh^fw`JIF-bfJnb()9$vCd~x7dAGgM21@jmUx_L+j!2tU9Rb)?m>er zDTB8fv-=y~_8qy+l=RLjF^8>|7PHdRXm24&3VBU1qXbV7PjBI zuX$wSgGnhe^KGUHTCdkT<(rjybYsNyitn?|?PqwlOZno$o`M4*vD1uwo``wOaprcK z%g3tZ?h*2uSEKZN?1lu!;P`V#rs>T2H{HlA5?lK1vM(@yv22!G($4cw^ncXz`zJncXZzn*pZ`Jr$9IiMeaVwro!<4c{qOwG z6KCvd_(T6sc*}(PWPP(A`EQJ0OlK*JYmNC+{%^J8`%5bv@2ksnEtA`AX8gjnO4HK$ z;qqF8IUIa5R!SDkPfjsTIiIq~p!(0u%47P4H}gN(|CoR2kNllm@;$!~3;yqO(75rK zT|CQcE63mUOZJ!*JlJ`)aOykWf7@TY>VoX;OXXj30q@ryu-p zVA`*%rgtuItzx3N3!Ag;1O12LOPB4p7kK}D@q&-9|MVSv|4Cy}$<}of7jFFU`k>fH zj~&9twKPB>6437i?^s^TxGxNuRDaXN`*&LZ$V+|F_u-D@&0TtS^S;+k z^(E4`cygC5JbP)u_M5jtmVK9<%vt^3Vq3=#_J7uVJh^>kUF*)8ZV7rDvaIyI?na9w z1vQu8O}~rRFg>k|n(4TI;eDxFHEZYWtlvB(>R_Je*FO{Q#jO5w?PEq+<_?oPoe|TD z&p9M;RNPJcwcE$|jXw+9qDPYd<{osZFU^c#y?&#i-u|Mz#{$E@pNr&rXXH0qf=IOtC5h)C-JddzF zPGVWDvqtRTpP8x~#ulnmzM2XxOUQs@OgYLD{>nDrDVSDUzQ!+S-G{&rO#uJReg_8;PrC`Ta33> z#YX35@J20OXquUAu;;Rt2Jc&)+_ei$vtI|WJzuktXWsI;xf!~P?uBvYO)e4-+jT81 zp)smu!IV?+` zEtw?s^rE}l(yOu@OyTAK*GktPOS+ML`PR&5&qV~!;&Dm*2r`7~;A6KwE zohK=3aQR3~>S`;;1)GYdnwqZ;w()y^^N{$Iv-ZE9o%tW$9P5-=hZx3a#x+pP33Uh<>jof`BEKfZBJH3r6zurJ}R;4wjay0 z(wC3l7+Id1H!nC?y)LKxSo3rTPreoPJv%fnKlgH5tvr#%$w}c>SJhVKM&Z^K`As25 zbsG;FaILtp%Rz_t)8f3dMomj~&lL%#ADwYiU9ao*9*L#Vf9h8-Ot|vo+8Uj!0-UWE za$}D^otY$S?K|!14y7}bxsRG&Gfh<7P`riX=fR5PO@G?;m~9UvGMd~H;BY^*;+*p| zb3d)qg|C+yCB}SF?@3=}U)#F;Jr9d;_L1)6+U6%cmQFU_mB!IPY>NNTIk* zq|YnJ;N-H$rw@gHJNuZ$<xScjZ&B*$*8&rs_%8CtK`4 z`iSwg{1HjslO{$fsg~alxL(WMtKZvWc)infCfCVbTW!S7#aIjW`OflHz2fO&_49?? zuIV%09iHy?{qgU~lJ`@8{1d6Q`ubN=Ytn4}J>n;yPOq}_;9vRt@E4AGM`!%jc~SaN5PXZ(`m9am<5IP%JO$E7Q?KRk7KZ_vBIeZ_tE z%C1kBx)P0|PVe{lSs{5n%+%*`_S_8hE4wbd{J4`Z*fD+Q`KQHUVLbs44Mc4{kNysR zFpDvYtJRlig;b5Q@nfn%Y?d1ai6B_ z_&({~9e2OuM*f}Y`XNz)mQIsTuXfAu+NopEb~5~7aqopIpX#|v{0_gWy%O@lE2a=C^*Dv%04zYRN7P z?w_*bz0BTE3>C8O*)MZu@pZabzn##n!H`ipar!R9Ti$iA76-jr&b5o9N@9VrhLf+z z(OupfJ|$%>m6+>YxJGJ;T>Y)ao7S2xyEFJ>z2ujjo|0DWc$VM6&iVW#cI|Tup1*iq z(Hs_ZYhP&Q#H+KH=2i;JT3?xc;}GY$yd}>Wi^MhJ{O>c^n(x>%Z6D`?*I#tc#5m3? z&z$3z_^jsm%s*z5HeQ=gEDrAUJ8E?{_$_x9(?-9`_op?!%x9cAldWcA+@?Pb_5BIP zh7W|B_G~+BqQ5e7!8!J+VpCPWTJ679Iit&3yM5)Ic}>^5)@V*`SlJ-#X6F;SAmpy* zwY8E9S-0lRubv@x?bWA{f} z)GJ?mbF51`@tJKzsjyFt@m*i}rsO+|dhYTaKDYGjsSdw2aX$CM-U&MBRLtDR+#Jic zyt*$gaN>hb5r%mi?)u(i;gY&0v*>+Om$PJ@7$Th zm!ipa^Xuvp+9!%T`fRfew~TsgXSG~6xKLX+-ZD048<+3WzjZmL%q;0k*jD$+1TgJ5 z=rMQgxtRx4FS=hW7q5EHkZ0evVaIf{i*vWM+RfwYiu-Z2_=|Jvx8h(gOY^6q&$Z$& zOwsz}k$r9DJNt-9M{;D_;+D$a-1vL8f^uVCtfkZ8nQN!E*RPnja_uXDg%bC@Pk*>{ zU_tmC-ZgI0X3Li^6|4W&dq+E4SzZsehdH7wD>1k)f;mDeD23%lfU)t_>gV&_mQsZP5qapw;R^qh+OGy zvsUSCrs%fiYdtGxJ!#v#tv=<{_As3+OTSYy?s;h}zNy%KT~Q(Y#4N2X>G>1y>Ik0; zT$m+4Z$9fXJN7vF7Izz#9($kL6AYP8%zSz0+SEzgyX#V=*PrIgES^wSx7KOaiI<8k z%X1sD+@5?qv2^oXt9N0H{V$d+n$~>fR?&=GRuj9gZ?_5)6}vFqcI!FGTeeSD*NaTf zjWB)u?qYq&k2!skhfB`wyLg{z=iA>WR+OIXK3~eBRJ!G6*9zBNg;RH|nzv(q7FXt$ zRY$h|=xW|_k;`HBobN&V&PQ%Ym|>Rx(Q;|_xoO!kd-A`i-ds^)KVvq7TXyJ*h?VoE z%`#hTpr~<(m(|DNm7dF|c}&aaF`CcgW}V{5THigC7MYiana&+_RI{ zaHFici}47reJ}hzzNgGl=K-`j@Zp9^!u0Kg|Q%{Wd3T+UX&euk<$MS-1I1-P_;Y4mKHFTwUWoC$HP$ z?vX{sbNhqSmoMJ*SRvQe&|b2s^@ii#x1 z8~>kAS893hWm&kNw=mxAP%Uf6AH6@%**gx|vn0hYefz;H@VQWZ_hFHs>fG~Fw*PmS zE43nL`Syp4`PR&JeXkMkSG~ID?;W>~EJb^K>ndJ{ES;I8Qz!1V;m+689F>QQ7QTus zl56-}x-d#uru6;P{Eyof$;F-wy?F8El#1IIU#@!fqU84+rS!GlUXq>@m&am+ujYs%M|3D$)&Rru7i8az9A!23fC8M@hr^dQ}dC1C(4OtK3 zE}UO}IpXka;njQJ1T1ZnEsD**%o1UD`OT;91#j2PSa8T?x634JPkWDNb$h;T3$x3v zm04zI5nms@bjFv?)F6&&JG^7QU(T7o`N&?5%6R!@58{kg)%;T26|h+M`i_UC_G|0C zX77-CBN(ufIq#=I2;&(8!DBO-BL4^^utuzBzx?{czQ((n!Rs5|ceuaMvQ@u&Ay0ZQ zL*zl;E!hocly1N9434(-44ytoTb_05xp{#yQYE{WB=xsseM<fj(T5m1uDtKUl2A2Q>w|IF^fX@|EpN~<~ z&zt&m?%i@sYYv1nlWluyHqyMMf_vRu1U2ey1!pm&2uyV zP_m2l{q~PMyXK}}inZx}_xR?Q%z4i74|krL78p^>9lCkpsTFTSPCeex+^1pDtj@4X zE@9JL?hUhr1;6F!9jepY#aO&_Q^BRT8(tRQh`)5@vZjp9+B>uBAMX6U(`BbKr!5oT z`>kv5xyaq9_TJTUZ2ty7W-EWUr%M-KV|PhgtU7zp>ow1&YTEF#*36t#H)-pUXSW-sE!Q%? z_T+lm><^PCggQmXwtiabS`kx!Kk6sX+442B0y}HWcgH+jS9DB?fq&^)qx8tcAJsZCKK)m}Vfa+D^qk_Y;u-a2 zfD43q@ZMx&U#eGtjX1=+nX8C3puQ|3yH0??zpoBPn_u0MC%>@&+N-CbMlbp1+d0V#-@mcD|JcI^iuo25Z>0A!Ti?@cb(y#4$ESdY zR*j$I4E6pkdNs3s^S#iDIM?edmK)d3dU9E_zyACJ&KQ5YINl>>j|?ukq<@ggdbBx1 zcm3kEcbxX#Ve60RcaD_ieYCUN{KC>ZeEcsLtp2b^?!0tm@~ehGFIk&*|His$%8$;r z8r^-6r8fQ3$`9?FB9AH^dLPvId%di#*f;mdw}PFAD&=C&iW(GH-HX&-{btsJd0)y^ zp1r@e^Ovkuz3=kbjjsc9=Dp-H%IJM@pm~n-y#;%=djzLCr`781FT9ocQTT=MjA>$4 zfhV?xI&7D=nr``i(Z{KweL^h@cYo{s$C;4h{@~_pJ(tjzXQNM?jb1rn`^6GF`NIE9 zvrgYOzEqXz^(d&}%X_a!L2*21J)-6>)lz5gdUJ9Qi@;VDQ;+KU*>_eH6i7WYxy&jT zcj|P`{j5V;mUCacdh^61e$|evVpqFZ_nWp(zpeA4X4cvg*?CQ;m{hWNp1XFqvTW@W z){|P6*%|CbL0efqFI!O+9I|&oR;*Y><72dpoiY*LuIV&ikIh6_TAul3pHtvqk> zy)JA;;qq_Aw|{5WEIXC^)#9U6m!*uwfvE>(#i<0o-hX_j==1A){g zJ&B1?WK-N@M$kHvdy<>~#_O>&ifq0#+K1Ijq6nN0$tY5MGu%cn4T^SI+fTA2A>0NJdX^t567^?xh|A_mKxDO&!^RH%ANBn z>}=`*E}mWXS)q&9?5x_i@Iqhg(HC;f(LDVc6ZPInDE$eNWmN$*?KAo?f>?G+H~n^y{5#=gyTx*S`Mkdiqa7NY*yD z*pIxowRg?lUlj524M%;G7%_0+q-nGq*f-E9B0$+399s?yg;%Nm8V^L_8)ceV%VFUa7Bt>e<1KbuSJn{9}CdgTK>3IP^%U@ZP59 zlNE27LZ{G29{SUhorjI&l=7D8-Tlm&a_b|*a=P*4S*E(gsXvhN5xw59` zl&+Ktbh4l1a4a&=VwzYnA@E91Yr};PD?ZK;aCzn!qIiPYu;Wa#joaDD0uxdgjPzJC zA3M(Dattx_kmfh)oi$TnLI}gB`T!20hmOx$6#9=S2+E}hn*J1+@QxwHi9_hAV_1tq z|51fNxfEX0qXH937(TJ6u_~C`7c0zmnxH8o$$zOk-k3kg>1-JX$6v=4AB`*Y7y>IM zY4@VA4~dw{=^T?sSFGp91IK$jtuLkOmln5$-u@?A;!R< zFuqH~mQ1SDTxmUa2J*ZUj4_q|v4{Zwmw z*l2f8+rJ-%?`x0$u0LLV|NA|=Ur(C(88gJXT=sY!naj8*%84;f`O#LPKlK)Bjt64T zRLycNdBaN9&_)AhGeCCN{NbnqLZK9{Zpx3-}m`Yb;ZNm6=myNwm+6# z^Zgvdy`ztJ&#aX{e^2;8b!Clw{XO{uoO1RD9`S#AZdoqBxyhq2%R zPdWQ@yXHT*$;>$CQQ;)ZU>j@QN0S+C>QB7$WB;Jp_mYQO{?U0!!F1J}L(6CW-Ov(P z({{Zk?2z)0IW5H&=QqYp_)uwcYO}t_52bw~2d1-zyzOvFww?HP??#XC=MMS)za7f` z!^@-n*Z4bZsNG)_km;pya^kWTnHeW1>N0sneNDL)GU=I|>cl|Skmn3J`JLN#3KX^8 z)!kShtM_n{Okzp+X@}3dzA|6D$Hy4{#eEn1qK)h3ZL4vat|Gr~v+lO-tJA+b=v=yZ z?W%Nf=c;d8wz!vVIdY5b(_&GDr98GvrIsyQ#u{=41sO}U7+f@ zLMu7a{lsezqp60u-^2vt1wV$K^18NtOUL>^BlnQYo0jvY&CpJ`*mH78mf6>DE+_6N z1)aJX$@q2a|MP|dq1rB9m-pSOEoT1Y)Kws;CNyu;+g*8+PJ69#ez-%l{%{CywsK9E zq0>!`?;9NbGR&4V%sMT(WC?%OgZM{xs&_eMZo69cGFjv^lh^#sktILEubnGBS3Eg& zxe9-|R?nu3$#-ieK6DPS|efeLub2%hl^-8{C zEM)xG{HCL0{pC#4D^v1j$VOTDW^JyIoV2Lwm_*Q9q1ZX$8ofOF2{(e*WW+Wn^y+`gThVQZ%Zcp8!_4s(lX^WoODSukdKFcW4ezu}# z{-$H+BO)G(xw(t(da`Jyp``tG!@Q{x1+keO^-_v>g{ReaG)RLYpJCattt7mh|4L&CSQ9}Ek(qsQ0#$TEH zulfAGv?^VwQ2YBGKj+7Cw^LpuUo$f;`uE@ItsE{d&mD1KlJBK_-JpV`ABo-D<1_X4S`mt$Pb)#jJk8HPH4@z zup_Onjc-N!+sTvb{Z=~P+OX`HbJV5FKW7?WvzXj?$68Tce`BDt{C52Vk$3gNw~0NS zzNKNct^SEQc`mj)H%!~_dhMfMw2J8@rCt5UMK14NykqzFSf+cqYY(lSJZY`ayX{>I z)qHn9+iZU8O>)}e)qQIoU7K`e$7HXhWwSo@iHKfzytt$;H+3qr! zTYq!f)n~6Z{C-*)Zgicy@bbJnHnDmOckVJP_neovEyQ!mz9k-uLjOjcGE-lAw?%j3 zLD^2T-}n`fc+W4^7`cXOsFJucF9* z!c*e;@33h|Zk?yEaqR=YY6;)oUzgsq*LximczHW7>Us6P^Ght-udKdVz1RH2dXw`n zroQ~SYnJeejIEQ`CF(8gNY9*l_LEYGq;ihRgrFW1Q?t)PQ^gbaeZTv@X)%M)s!30t z^Bzw1^gmG-#PUFd3;(k#Z%%L2ca1zr&6 z6Z1Q0&Rc(9q-&XiUqr$AA=tif$Q$H^e3p6lt?Cua+7V(u46bsy$m(DQ;TXq`>3w%W!P%ZCY~ z{F7JAJG5CXF!}SeTYI#1?`_VFJMk>mwKK}Bb9L^sqS-qS1;u234!gN0syjUW^C7eK zbzHoYBXU1W<;GnWslVp)$WlGvZf5FRDeLU7bGBX$j;Q{o(kgvO*`hy9J>LAnHm2(V zAG9|LWN*A-mGRm$TRAL2*et7B`^c})6Am3L4ZgAAx|G?o_y6^7edaiI^7GBV>&t8kzwMV1+AqjC%lD42 z&b|LjFW#q&1pZvD4?Uc;4>kF&I^kESeC%6{u*Wws!rOLJS0R=&JWF)79j&4yqfTyamRP=3XlHGQ(6iHO z^$TV``SPWN>4w)HCT+&AP5rAh?Aw^99rcP<&o*qB9wFN|F|TMsnNZNe-YXAUm+Uqx z)Dt=%=e3!M`*Rw5v3cg^I?o;Zo|&v${>rv@+V9T|m-QY@(kbv1+tJbx|BT`OBhEc{ znexuE%gty1a9Z|3wCsc59gprlR1;ZpZCl;u^{2|~`CLQyb+#3MF!#~1?R#YKbq=ra zp`4Ani(feI5K1jpT*!9vp;u8E=fi6c%qGc~zWwuQjsEG)`*g}T9p8NWg!a9kS$huM z64m48Z1q>rc(h{wj4gTR-_@Io%B^3u@z))`{gC>%a(-*0|_U?V$ z-4Gu2tK5b+z?+eUNrYKs;sVjhnb#E=MJDP=PF`|dgHdGS0?EnGu1kOzqLW2#C_@;& zH?)yXK5Kh%y{|%MNUi#vb`R=f(iNG74w~y%+>N7wNv{q(7fF+GR z+>>YC*M^vT>pmaTAMVMo?i)h*0hKH~5VZmfZyjBECObY5XB3$n`9PVeglBSNrSaqo z57`(+ChvHl%=Djca$}|Bo80hFnaNEQ zES%rO57j)US#t7+hg?j{#K02gn|a{swI3-ny^)!GajLSkp&s~-I;cr-f4%sTxqous zBQd7yvLI!XPd-vW^7W3=g!zk@7#P&pAwGxrg@Iv7W3?h!`RYC)9dskvwfC$1WoBR~ zv~7s^a#>65>_aAFjhTz^$^a==S2Ca%oMF)wXd!I@~{0#Qu?xP72} zc{dB`!sk?d@ZtB+L_KkVXg%ogdx(0FV%}^_#hI|9@S(ckxl11HD13-9pse7A*OaN8toM zl5+Bdo1#pbRWQYqS8}R}qK5+bw7JRuZ;CQ)t%EDH;giHjbeEW6=UFi@D5AJ;X%k$d zz7X5wxI3UUw&<2JliYNugdDtBWxTD-#5V&hT(7DC7f!mZ%p^L0a-ohsTu9JTaM=|~HDzNhT zci7SLSlnG@Cb6Sn$%bfnmYNhN39ZCH3HQ)(u)IJ5?_|q334}-QDKjlQ36&C_9Cr^C zd^+iplk4trF}=G0mY9D}87ZkCMpV(g^Y1EH`QLlU-hqz%Fn|YsP`tD5CR90S97sTf Ul?^0o!C=8KN0@=(?qd)S02vWB1poj5 delta 37918 zcmeBw&%E|BGi!i1GYi*bMjp|LQo@W}6ZHxi!90Ez1_p-wqI7*`284>6q7cc+ER3@J zTnr2x91IK$jto;(FE86U`Cp+&{TJ8DDGu?Tnb`-;I#@#|I_T*Hl{Vh+d80Vz= zW5OynFLUwT;>M`ewR#U^pRW|!A(_4SUQfGi>iHD?P|cVqpB zsfMTI(l=>{96nx{_dD?ZDU;xf>e}wgsf)!c-*Fv(5R!Gd^paKT_W30m4r-lJmW^w} zY835Hc|5=9J$L0fl~YSzy2qw(eOZ3%y@v7Cu!NWK8dD`K*M$6Y7vk9U^M=|g7p|Nb zwI?f5Hog{~oKop{ZDmoj&DW0xN0f6~KWx<4P;Zy{(qMA(WS%LuHn-~imwnwRo5a4G z>8-Z8UcmpwUvl3&sm?iY>%Q+)-it!I8_JLF%6ZsqmT4pUBg$yArSY|IZ(h9GtStPY z{nAE;@}0MKsIyw0m4QKpYjVH}$;mQBBK3O7If=!^y1*!PtT-12hQBweE;kBSo8mOfBzabEdJr?#vp7IcbJt^+hM#EAZ(hdLFA|RA^h&lFF8P%4FwU!!1QKr%N_1F9|O9GyWlTQk&;r zPv`@l+o5-#Y@T{aY5Vi7uFV>WS5IXh6FqzFXm#(4@@b`;Cf0}O?w+A{E9&5bm%F!Z z+jQvd7t7N{r}*}s$=Efs)a3TVZx+rAbk^}OcfNk5`?hbInaSoE=d8Bni5<7?%3G@c zf=#~sV@BCTn>RViXB4XS)Yl3nzRU|td+}k%Pc5F8|<7M zHzQa&!fB_=iddn;eQfvjJnMIe{gHg96V2Kd(cEx$I?ufFOLF}x<>u;nxl8Bm@mPH` z`0#SieceS<_uDRByCX@cq{wXJtmoQ&c{5Wvx394B-W3_JwQFYlvu)Dx^@~(X*PaaM z(Jkc4{QWhZ^~=%EyL>O`R`IxO-J(>yr^Q~%*yOJ^Z|>D&AHTi|%fI-n^WIgr@HLGM$+~BJC*F72RG6{+*zDI< zp_4=APpl7V{W$H^6>H_7Cw^sX-+T!AT;-t>tzMFCJKRDC?Z zXUUX#exF=l>#vwyzUKCxrMg+RA0};EF>%F;N<)1f_ULOdztieDKZV|sN&P;#tao9s zzPZjezUB(2$eQi5&d!YT)Uo+E*K6AwcbNtJ6%3Egv#U*$o4fvU^sIS3^BN!WZis)m ziPyP=EjCGn(@NBz!IS6mNTCq!C(@yP*2ae~#OW|7le%`uCwv>rirIhQgl7OO!3+ zE5f&R-Az82F`-h-{YCBht1JHNe_7|;_p9D{ietmK-3x+WEGgD^yxY$AW#Rlfiyq}Z z9@q6jf6NO7RJ-;%UA(W%D|ly#xPz`mp|wldjB4-42CPyCwE8Zbb>DXGBLAZLN?^4_xfE??fR zy!t48(a#r^HNqS36jZ!t`?gX!^vl}h2D!hlUr66P^6w7YqfnU{l7FRR7x(|&?;!P6 zw)TYFuBD=x9fA@87IQ;ZYFy2l;IN$Yn<0~lmQ&y4I|{oB+0r#_ik`D^O_E>6z%MMp zXv6Z2M+E4M@+Fqv#q6<*((DjejYArj?q zTZ&0FRGTX^J6b_X%1c$mW%W7LoxHd8cJH|9@W0LO$Cc^(UQE6$9&e@WRJyG8^2~qA z|EexZ&b?UZX8T>Ju7t}%cJj%c=HKrW?|Z-d`J21y_4R)_4ru>4;lh+}vPkssr5=yT zrYGm*9(hh}iy;(b2>MyGGB;Ij2cOY7AQH6C;qTH)wrGCy#J?R-H1xF8v zI3M|_CHl~~M9gOYq?JGRyy-Zz>iqQSt@AZC(x)w4s3Q~jura}6>-A%X`BzJA;`Y6& z7L5;C&AMBPBfM2E?%UC>w^vu)u5O7J$~$o2Q%n7|vbPUx4nMuZ$TE+6Q~oqXn^#lo zJF|-qmK~jX>r&H)^dC*m+PbXkkIapHcl%R)t)Yz0twKSY78VYgeDHMY z%m&48TV^XpeTwmt5^0I%6nmMXE^%h<6QkrQ0$%mo)qWPm76uiSZudHKK*3*vHa;riV~{zHfAiJtb0}F)ui-8A#qye!4FvP+*~Ai zf8ma;DPnu2jy}mbX|!ubCDMZG7iA`(Z~^>5CV}mrcz#Oh2+MSm~T}#rZ?OcjP@}jxqnB z==`ldWUkBm2fn&@L{zQj{(GL0&!(%YeP!eO%TD}P(@G`%u1k9^46Od?`mxY=hw8+) zx1a7EaUEd z+gHg1MdchfJeeAt;r(aZn}s!T-zIEJ3BGB?Z(;o9LhcNPkF9NDHw{bvZauMVp`ps} zwqpiAcNa`~WB6;k!)vMD&M#IGyXtutemNkuWy`j<56q%heYf#i-F&b4josvt`;iaA zihq477R>K**Y8{X+H7IL%vqjK1nSSOG=E(&U)d=>Vaf83@0MFk`6qO%+~Bfp?!(d- zDevz&PZ4w0owz>XjOX|59j6!0pTmDqpfP2sX4vtB34dGle#djZHV^u4t@yW*@lR*s zpQSgJb{a3t-7J03+e5QV`Gs=6$Jt+3_c6|TeL?7BSk$uTtNng@&Mnf*TeiFU`b7!z zx%EdCZCBnu?3pCy_iFyb6;I||F;5VB`=hfxgDX*Q?vyeBrXkXU*4pFZVrGy-@RdGOx@nhtuM> zm-e5?Idf*POAQHaj>h%|F^y`eDlmrj(Dw%SSe)ad0WNx&jQy4OBN*jO5DF-3)Ah{bH6N7k`^`-*Wf& zi=XG$u@y+EGP@f}Eq%D9(QeP`E5?C)+P_cz(%8sfcFvLBjs#7thzl`h~N!MO&^q_+GxMknMcu&_p%`-1%JpI8_Eb}?y!p0LDTV7k`73e%xbB?cmHa%-v z>?FD4TwyOayvchdGhh2~w9NLxcEx*nCkiZXAJf*D&%ElO;)Z35OfCJCPEPn+|Mx&a z$@i9Ry^Vc7MlC^Izbr~G&-t@TZFS0)4UvKMOSZjS`D|I1rOM5wC683%*^U=vl;u4; zW^{Pv^sl!?R0H=~gfCh8Y(++Ez@EtT7h&S5+dHevKdjBI+r#V~QlB_$Qv6Yf2{j`1U-xwygcj)CGlvuUc`e5b?A2 zkoz)urHwW=LC3YDU+ncixUb6I!-KWDYoEq}_acvke>K=F&A(tg=cs(d(fK=?_a{8c z5BcCf!KaNW&Q<@O+G>G?`443$N!;vFcAccOM!s=qbbC|utJT2L2+_orQGCuO>Ff?BRMOguTHf)9(8Z?7n$2$k6b)C zm^N9&d2(>xNa&Dd*Zw#uqO3{Ssbb^2T-8k~OP1?QQJu1^I)ZD9&eD>FElV$45VAbz zut1ly`ejbZx0hSyY8s!}SC;Ym-}im$k(*jQpU-|jyXIr<_j%Rtc0Ql?d4BP`t?~cQ z7V8UL)cO~wdA0sxeZ>p=m-}sA{N0{WxAMaOiW9E#6)y^ZO`TrnyZ_^*WRu1=&%|$& zrhD6@Y;gWEC(i1W9?whW6G_`ML@uu2nqHN`SAFCF_rWzQW7Kw}uZ&q&(Aq9mw6wj} z=C&_$ik7iRCdbNK2WClgby>#Jg(FT5J_Ug_idrUmuP=2b6B_XRwiDi?QD zywi0xYwFfR;@W$TIfq|j*IIvcy1wAqrCR2l>zzHa!hRSneED=yrr=r8MLUB`Ub|e@ znq}5{UHi_uPi*|T57QR@4%I5JsMk2;IMsaB9?z$Kj&Ft1-hR7KdS~&cH2%L+wy(Ie zy1-+?uaI})m8+f9MejX(xVqBe>075`e68yPE0&+SzG{#6)7K%_LhtF8$cXH24>b#s z3#yEGDmYbH>wRG5`Ur{8ijapAlf`Gk8^k1r~;-D4?P zFYhO{G9+CkRVpFnQ)9`42fMadCLK9*VnN<9N1gZY?_IgOd2RLeYv1k#Y*;RxGq?In zZB=qeKd*V)nG_YXJ7+?!iS;k_u}#anx;QgKEdA5AZ}~Sa+}o`!a_8Q;BaZBWriN#4 z-ML*HnqRH4W%XL-O|plQFRWX;eE06XYx%9;yy7ma-}?Q__qVUO%F5WB-_D4XKlJFS zsL#K9-%4M18yW0e{PAI8VPEUqk53977X^{kTCfr1wbAyDu;Dly5G7 z-zRnG;zvi@U7`MNM{cNDot?4TVvN}w#OT5H#lX?@|+g_d~Q|IqROKt!8;ia zKXI(Nz4rYbr#{t5Ja+y{{xzY6FAb#ju>RogYf6^&N$I~9<5RaUxT?PFy&>D#XD>w_ zPT4eJCI7plR+_#KTMk{<=8-6!d$;lYt>5P7UwpaGx+#70W0Cb72W&q5UvVHZ%5%j| z4gr}i9_35Ro|#I1=*v2|q%HUEgr*$(qdc28?l;dk-FrmZ++|VQloc-?Znz-txn_ds zNxhsUXFSeKvt3=Ft8l9>;etnpr%wI46YnH@X1W62@Pd zS*@10&d{n@AL{SQwp=OEHSoB<`J{%1bOUp?ik9n58x=*YbGOeky0#{-pZ8SCt~I+n z*6D_sYq#-Uj+*ku=*&cmm^}*p`k6eg8>1JSve(t0op2^H?x>U+_v%e^rzWI1?%tt( zbDjEP!Gose{o41PCKcw&EskEqHMg=-`$_DgV7~*YCr(WDSknA*MV{1OOYb@HccNR5 zPn*_#QfrNxLP@<%=j9(z}?O={zY9ZM?KHpZUPR$pFZQf`wf`u9?W z*8ClMmKI8RO!dvp9Me^`_4iCzxiF*Z^wn)IOIJN%2&;7ZSW$N{-p7kZQ%42c$OV8*)@1XX1QjI2tAGaJc|9F<`{-TeH`$8Z0f6kSvZ{jyT zs~0ri<{g_aw)gypbkkolwQ-A;OFS0eekq`Jn};A%zb8Ds_i+`}& zbRWC>avs^sFWSHK9sB-CeB!muJC}y0c_`1B-#FpXC*%BoQzraZy?AH&$G?9X-1hs| zFSw}x!uE%sMvVT)WgnaWq{b+w*I$Tz-2Ovb%3f#I`cKzQ{#n&KKX(5yo6COH$G|$D z$H#weTeICo=*`Jisk{x5hK+x#v;+iSTF&&F;kLu^#kZD2{#k!?>%1N>|9RV|VwUXX zACh%WkKc3Lp8s2rQ|hCYX;{?di7R@ZoO*Lkfvs)Q$BPZe?mta;EtcujFj#Up>EW`5 z`plCeuTmxyd}@w-Y}mM2c#);1-`_bedb^)hnnZkL$}x8~ax0sCWxe=O&g!SW=k6(# za?JSX;N-uor{TurIyd{{ssWF@AB+DKx%@Eqb=B_XyWyk*4EBuHrmS0Ra~vm zXPx2DfAE}UvVeKxfs|ijvr|r|GjubBdzP~wI#6G0w8>hxLW*hjVm6`O5!1R3bTyXb z9S&fA6q6(F@0PbgyYqIC)8g`%$EEfk(a-*4`_HaNoA0gy)Aog-*EoCY53FaXn0!-S z&_wlOR?V#QHyX~x?^fBKG;QkN-;bs(e_Q)0yW!CKtUprw`F?->p1Wed%VYB&XPNfB zxpdQ&i#gaKpq}4EMxxj3P2Z72yst}x%?p$BHs^g83ghH3(7hT}$Sh?3b?(mq?WF4= z3H3*0W**F+7@{C%&b+cjN$|MYLxv3Yi3!Zo+sh8Vv(q+_esf{VC*M%T!p*T^Ec@Rlh)>mA(qYU#?fpY^VB z;g97%S$l-L8hIAfzPnU;&d0MzbzQ24ZYpc0{POuS><^h<&$U~ALt0sSUzydJBHx|c z4wf9vxA|$QGwt}i`NCG*3oe^a>UqCCF1Wb+o;24+b@_G+g+mJQFMnSB>ALNK=<-wM zi6;&mU9hQvd&x7VU{5*I`bowCp^Vkn3Lb@7En2>-mw8!@P|opKOEvb^?|pZsp5l!) zmprf|>)9bc*0cMzTMIp^s`32#W$9&2*Qfcv?5krsU$07zh)9eSEbYpxJ9;L3{!F#$ zYo@Roe3j@f&xlNjeuQGB>S-EoUU^u(`6o>ZT*-DNK0$)r`UXRK#9 z!ISr9cE6_U zO^wJqy*b;WAzXG!mB+~{3-|e~)gnjk@3CnX*|*_HF;fyFgYj<#mKDtt=1w{99{#m2 z%y5kcN2FzF+b@lrd9vb$s-fTOymFU$9Q-IdX?Q`n=e*)*{nI5!n5f0`B$B3_vg)8 z{z05`(aJxj#>tA)HJ5Jndbs_4-ljTto7AYiXIIph`HR03*_q~jOCa=G_q(peR+AG%lK^`U;dPsUree_u1QxHvX#yP2n{J$e6!lzkgjHr{M1b1ePfpT1ds zj=>~`4&A($?iKpG8x3;4ZLCS1XllJ|?aApzZ-3hUKm07A$0H}cM*mNFreN}$8IsmJ zS#)@=Rb7~}|AbDN)5p^bT(9ODKlEFW^vU#{T$j3gX>nJ5m@D7^g&ldzKCkHGN!rzD z^JIDS3xQwTg#tNi=ZIa%{nB~ohrzM=XQb=79{WGv5f8i-AVuDE?w9^eP72n?*(rZ%q>6au3!0d*Dv9aq9&Q-CpB(H_uH>E>tA#= z=?=U6_r=wSH(wZRHU8H}h3IWhzbVW$<;1*zgN<7&RyH^F-e}wyv9oec40H06cWX{g zD4G89oU&*YBANL$wX+O_s+eYwH1R$;kQf3$Mzo)D$o6FGIX<`hH-|M>5H zCep6Lsp^5}X#>uPK{~Z^TJuNkIQA%*GVq7WZqhuZ1UYA zv@v&HLBF%yuNn{4tVYgt3xakDrz%znYiZk6i4;JE79#W(+yAJowMt#kj-`QR^GdexY-S_2Hg%evK5 z7PA(W%sO>E^PvOpyo23-7c3{U&r~&kx4?DF#8oSUwQ_TJ918mt`10i>*SLWFzQ=Pu zf1T`HzfNcU=?jl|=I&nWCZT1(nc!W(|7MHiUtLQJk)|J#zxsF|y}z_MqB17$*cSG` zK4r$oT0SjHp1IN6NXGCtlKX>6%-*dB~_80f8 zdbmNyk)fi^!l`n zrw3+Tn$({8oHJ_b!tQs=Hx)+NKG-P*R1~_8v?Z5Kq z*md7q_PsHeOpSfjv-Xe`nX)-JP4y1b?iR7{~eObLl{`Y;4_w`MW&%a3f z#VPQwIOXE^mkNKC?=tx2J#j4&p6_n{*~sdMX^FP^h1@+tH^UO1*(D^43f+>prg_8C zSDoW0_wE?)^Nq_zW*y0pvE~1A)BF5o?vDS88Q+zvQZ0^4TD3lTb|g>y!s!d{f*z-m z1Z<_7UqnjiJmh})`wMfC1N*k?yLQa0k8>2+Ie}xk!=u#>OE`MUPgpmeJteX#c!l%A z>mpUL3(ZBUf){R2Vd4_D7Q86T@ZTp!XQ$qZSq-1O0_~jJI1^33!ZvlG%Mu6}iVWio@R%83lKN9n?KF1{}h`G1%A zDpUVjX1Ol&zI(R}x#mtzCgj2x!0G z(OJs6+WW|Ro402^i_B37O7Z6X_Tu$A`{qqAU$1ZVlf3ndA=5}bhw$kFplpvp9Hd z_$Bm9dFHX!dj{9mpWr@!?&Qs4(;4@c%13{DqG2XF^&!WZZOYEqORoMbOM4M@U+*|~ zNo?DfcUJfF4CP9aY#w}QbyhI5d@cFet*vcVOx^PPt)9sT0$)p?yTBpQ7Pshx;hHvzvjmD>^`Ykf7evYNbOIk(&evW7W>5)R&no})|-_e>Ey9`!@rs-bJ;?gyeH1v zet>T;$815CbGjC<)_UAJ6nFgq)8~U9kAG30aG~MA@8B?6`x0Vh)oT)*z6m2e8!r-4KCAVj%_~tZr9}!y-zQkq#aij<%;@BdR>X; zuwvU2Td&iu_?qvFP0&^D1DCr!RxWSonf`gh^-*!7Ocioqj3dnY57JX-B;#K>CMb>7T_U|y0y-kbvr{{LiFf|TMJ)a%L9h)EtB}(V;f>b0%+KI^tJe z_5SM1y^|kV{7nB|vTKtf!wHCee{P^yWmJfNN?+^a{^m=bm#eA82?~k+p*|A`eNIn0FpX{ME9Q><( z7zAm#87_OIBo}0`?t!wF*~3X))&)2FwTlkB|E-8PsQl@3a?!`fT6T^8(;f!@*wS>~ za(ejwpWwWUL@=tGY?H|F-p8n2Q28*ycV z+pND;CHwPSpV;_*xp{bE%YjWBGI>q;B7Zqt$*{?NsjS>~b;seEas}zTzj(~?`ZeeQ#wn(^Eb7BRO~EI;CQCrF1*$U2r(RpVf_`}o6!3og|e*L5{LY2*DVz3aSMj`BA3#aiAD zuaB6W3OFNZedtH!ijprpDQ}glQRRO@mMAH*UM9{mTr_y>#3XOa(1C& z<{PH<8ZC2O->votzI9&Wujg%*|3dozn0Lkqefwtox9xRb(|SXTUk4oQcwDre{gq++1a1RxI?P0Yrf`>oo(?Crb{VR%xV*ybEQDWKm3C> z@BU-?EYGTUT-AJCWO6F_o!*>fC$m)+>_6*T&{W@_$G=@g$gL+b*>m6hlMlZ$owl8^ zePf1dj-N`LkHz(c_7D1*qUy`!E~=J4e|2(~`q6)$2j`pqVXeRV!Cdmr{>Q7@>K|ym zKJxYqcXp>k0rI7m5PX=v#{%-uEA7;?& zIf2#QB4g&p1pDgChPH_;)AfCI;^$6ok3HTe{db$1iDB?6?QoY?H7(bvN=&m>um!LD z_KQ76cymFh;AT@p_cN((U6oxcE*`1zj8XX9tdzB`Qe)}4)-}D8tu`&VxT$e6tBI7U z|Mz45M=B+Dt4ST56!5oXS8(S{v0WE8x7WwHyM!;h;(PS4h~zb4-D?3xX-D3!^f`TE zYHzWD(UdJS=6G{w#Vj=5^hex!ZRM_e72nRS$@MEtSSV-o=1rMl{-RisvS8J_Z&`M+hr_^13m0;)kw0G^S&Zvs1r;cwiI6H^sx~`m`IkT5>@v;Xlo1Vwb6W#RY z+SA&=%{>!W=;iZ=HT{|Gbh&Hm^fON{-}Va8Qd{Zwv^2JU`DL?iv(@giU)u4!QtRd2Xa)I*U>v!#QEVfrZP6_H4T5$8`pS<$yb@m=? zVofv79k~0b@t5+7M?Lzs-on^_Tjui(7pE*zJp7Vrr=D-cjI%x$8=bUz zx1Ig6_{_-=&r|Q6Sg%gov4PvSM8&_G^LU#6uPIY)E^nUZ+dug|x7574&g$6PWlwBQ z9a>hYWO?Yc-;0F5b$2*^&R1{XH|0ncXDKT-V@{n@o_f~w-1n5T+7|a`o35{KnSX!J z_To2+ODFDc+JBUH@r;iRhcBJpctnwH~9oRex1N?8M7M z%Pvh#j<~Yq+6vysE8ecwlx=??u|rWn=4kKZ6|a>)Yl!tHowS%1bZwK!H21>Jv`HcQDZS#nro(Y)UaA4}}~_DJQIp~IE_qP&C& zf`&VaISvP`SUt7;o_87%cQpdr-UcFl~bhapIDy|r&?|1 zuZuGz4s$iV5C}^VR6D3qzU_^J=-qYB%O3|^5Pdv@>A80OBMX)NeO7!cKPk=#+pRb^ zK9%Q**Z2Fadvv(dQzK_K^Jyqe6uda;*=+5%OJ;=riI&aaS>yR|S>T$p;@j1|@7(FJ zunW5UNKU!I_{VMGfZ&Mfhkl8eEh+e%`#mwOLT2`_u%1WLv_me6WcVe1wwZ#H;&KQp6XS1YTf3vz5u?A--=N&Cmy6&}QN$zP0r3;(5 z%EJ{IL) zSN>Vuls~_zw|{ZSLD_?TtzMx&#eA*rJWpW`xGkXJo%s9ijHeMg>efNdFD9h*FAP2u zF-5ebIg8zJzT>=>&DT!4gl7u=SQGfv*?etUaFp*)i?X09*3jNZ+y1<8*?eT`@}rzK zhac|xTn}mZDSnZh{C(jC5kzxOC17TBC~XM3ilU%MH}^mW0lsQ#+! z+F$K9c6n`#bh>!#w?p>c{EK00-ECjXe+zc~`!}s@^4+tOgg*a#vbXa6-*@-Ff3MCz z|M&U9c7`M2df|5o?dn``HZ*TpeG%x;) zwf@70OKoHxKP;2<+~ebB9(V4r?B@dYxP$TKCo5Frj;gGm_EGAN?4j(LUrH7C%uC(t zcue}E+P%tR)prM@XM9+@rzTo8siIo-Q3X4Hvf`c7x8G0ssJAEj7(?{LBlXo473*8R zw|@91U?*^h-TB9a9<`bo{C0;f^?CnT(Nns^Uya{h?crk~KaU?R4p$SeMkGcUUVU*r z*!*>y+J*(i5w>gGO0`eD=4G1dBYgd`-|jqaom1;`Y84*8n6~q{*|HfvXFK1$e5bJN z^bDP}nax#7$*XEem zC;iTD*_F4xVgK2#;49)~ua;e#>dBY!Ew8lUbHLq`nKxJ8vRYp}yY5?%!%G8Sq5Ksu zx450IU!C?bP|oNtfSKPt#ky7$wzPfGgc!eudH zobx9Y1ReUD@^;G0OwQ#jdgs|MpM7zzF;Vx}uIFE0a0ZtenXSBSG#i3KFhT&VRe()7VY{QeL5$#LY6)-DdW`9Y<+R9C+~=9^g)($8WjTRn(KY9bu^v- zP-Shm`hlX4)(;u}`Oo+2Kj`M#*P^fegKMAG!)&g7eZ^e+8uPs>A`Wi<(9x8i9CWB$ zq(=O{Fo(&~klTSDYX3C!oMLV$xxVR;yw{J3P4dRq{XYbA+6R9q{^NA8zVc7d!Sx?j zG#&qt&ALDF?|#=NgUjnAXB~diV&AnRRbJJx|8coc-TDXoKNdHse^6(wKNjDygU5g~ zFgNU2$Msp$f@d4%Uk=_H;;^;Pb#jIfM`?D}Eu(0USMfI=?tl26Yu=G12QIyQQJU`K z?w=LxWEuA4kRRWtPdB@!Zke9s_TW@~q@!}dU)5CnUE0)_@i%*&x z%~pSD+Qh;wv8#+-8UvFJb$!LJYVBGjRJ^aL>+THa^m8j?&t^%d2S=YddGAT(b%Xq$ zG1H#wo=s)kRNc2sws&38{IuJx;z#s8ol*R6Vj7w7m3Pg~(sQ%A6*sQv;d2V=3TJy* zS!lT=psBeqPh-lN)YL2f_rrzmhgRpz&3o+ek$K^|`Y*Xt%3mK#=gIgfQy$gX!hKDt z;JMz6n+Ig~tuQ#%lBl}OH~RFl+&Q~5Wq&s0?C_XBn=eAc?rUYK=aH_)!=4<0Z-e)~ z-}WLkGH6<>KDx4@cJkCqEKd|r0PhhM3DnfXNP%bQQkeRnTGNBA%OsFBLf=vP@F9NX~w=&Tox2mP6>lx_Dlb8MK$^;5^G_ACDarS8gf z#qV?7mTnK)G$Vd*Lz|A+yk+J3Z+~stk;C&^deaKI!&$ck_PmtUnRVc)wUqjX3LeE- zS$^{l3C&u6LdoZgceU-ptKXeI$=A2vzwVX&pJiI9uKeK>Yt(e+8!bF4|LwU;Cuht| z<+b~|IKt8jO$Ac}U(3cFesuVsam6(L#Qo}TZ{6E-R5;?|qj`4G3seR8<{T_#O3rw? z{xz$uzO(K@AyvU3A-+ko=b2i%K77FPs;d8gxskf%1lL+I-ZlOIUT!cf4|upTwo<0O zK8i_o(PEWLnQ3yqap?xY>cQ&-&HzF~L& z2P=mTUx8b0ncpQIzTrD`jnnD6=A9<@3%%~0pE&E^91VUU>b=2#jr;r?U3D9Ie;;L( z5%E0Yd08>hS@e6N!yIQHn;yr)dGoIJCwtg%#{LmL{D^6i-ZFN@$;(nzYRwgYuw1<& zw@T0cWS)ZVT8>FeqAz-HW0kmS`NsW7@{7g6je&*ySFf!-Qtfl6_wSRb{QjL;dl=X~ zPF0%hn#643Q6Ix~u{yn7LrClGnzkCo-zqICCHB3npUo%7_DwJ-VC+^sqH<)u+wBc4 z%jy&V?-x|n$~f{&-LW||TEm2M{TqSO(*hxfBiGnRZmSaQS9pGKiiA{qOqJ~6cQ#Ci zZM_d2;rq2}+1|8@`ny|hGyjCNOW-S@);xG{oVAvTfkASz{|dAESbt$hk+%Dp+hcd# zWxAIC$7$syv6R#8DlCD{R}+H1FkNPOzwC5?*f!mpxmW9-@QTm!Fqu{Hveo`nMOs;= z_sWI7myL_dp4XnME=&7<{=WQv2AzbP4l^D|J~df0y}nO7?ByZ7@;lSi&061o)>`Yqt{oG%J}TPx{L1jmsdDR* z4C1f;RV%;yXx;|?kSOuEi%<9I*R*YY6Ir_M%7;~935R|?_;}d)VWgt!W#7eCQ5!cp zyB_oMi`|oVRqIgoY3+4IS2yg8el}0}^M^%o)`n|;>)u}0lBim}>u}<#VmVSaKQ` zvWENiJZj<;))Z!&q?Y$+TAym$OGeq5JKA2?8`&gDysxMZzA0WdIq}hdiLIWgK9{7Y zE)dsm+EU`MdCL~(g2~}%Zu&{1>;>GcGFc5_tP**Ttu%qD}di z?b|#)NlMEflwBqDVa)__<=Yz<&zm=Ww}s)IsWL+M4_}cqocXdg;qOt&JMWeI_|)ny z-22$~!&>QiXRw#e-Ft8H46XfT-V}!&l{t3x-DUM|g)M>q8Kl9DW_aQZJJZs+Pn3Z{ zT%UnK0W>l?S#LF8eI#d1$knU%>D$aJZMHdZD0eRwIw2=y=BZ)UqHs_^gYizOIP4Pgc-ETBa(4c+STBiqZVsrQT+Ec1GPG)C9A_ndddO26{YMw!#H_c$$|S+noL`YSuG zoiDYrJ+j)QZn9tc$E>+>&$v^boc$E4AD?ZKcR}++s@3|ZZgZt7=Kk3eFzf3j6W>M4 zE1Ku)U)mA5%=}e}?e-H7)a>)8{nM?t%6}MUpFeeGuF~H!#hlA4C)|JayzFIp#-8Bi zqBR?j{OR{6AHS~XUs1Am{(bGgyh;~-o9qi*9=9<| ze}BD@@qLxE>?Z#f_zC`-knuV3=PlJM=GlJ)d-E@9Dsn&i6BxNQJi~6;X78Gd+Gpkd z?Kn37!)Lp>>z;I{>d&a#|7H8HpOfqMojpHa=+|x2e_M{#mm5g>UTn#2JIuQ`?0M>| z^ebKFEoWU0c^R-?Gh4U%{Ix~~2GlTWyhS5>XCxIE`s#Gd7=)bq+(*RHx-xOx5g zu5i=Uo@>68A1!k~Y`D3*KC@2m(6X&7D{n46zoq)MV$u?2ojK>vZcQjQ;}x5m`n9}m za_5Do*LDTmSoQwR7NO4Gv@0Q-LZ3dmP;rSh;d!)ZSKFJbKKc4}%zN)eOb+gj-8A>) zWr5e5W-K#nUlitTbSd%Z_E|GT_>Wkf{ZM8sH|hRL$Nsz0P0yb_yL0oS>5}W#^^d1z zMrS*7&dyBr8nd&w+sPYO*EE_6-*W)pleb90kh>mxVkRAw6;GO^WJwf^j^D?jvj%=_ijqN=>K^=EA0 zvd-T0`Bs39@|6|m+HTdjukf!sJncZ|RrUJQLQ?m6wfnp>{U>}h|~xT@DdeZfw%E6J)k zABxJkdAN*ro4Nj;WLCE6OovPKafUtlx732=ZdeN$oSmm|RZ6wfV%JqOYyI09-!$iB z{*ml`Uw`q%hGXnA(qi+DI^Si!DRxJwn=w+n_j1*uOO_ue9eUaH<_?P>*XDy8u6dOl zbFS^{w~bwBv1RVF565eEtg>8kW`XsZ>&KN0?yT9!XnbKh->e5aT2~+I+Pll|@%g@0 zGr8hb!<^>qUQ@9sX?cju#I>$6%MWsB87W`CN6y`Lb!pn4 zME1!6rZc4dZ?39l)m50gt5|2H+x_EeYZuO2k*WUpM$Jdf3f~QE4U;y!IaZf&UW_?! z+oOpAN{WIF5;Es`yLPd3Z#I6+w_?pY-Dx+Us$6clE9!kqa?h%@*N;9Dyu3}cQN8C0 zyIrlU$CJoocVzlKqv9s>)VIp|-8pWOtkifWBKc5auv*q@qkrMrvliVjn)jyp;$}}Z zYlo~3SEV$OkLe8>V*ajkkIirPbne_1AaY!yq*Q$Rn}(>3F5Q|3PQTuCXxft76@0%N z0=!kOeq_@8c>4ZL?$SqM4YtYY>uesf-7&3_)bn#&&*AuZbMdjrZR~r(uJqOOr_5Qv z)3Y@6L{hKOV!wnGKJ}%N1#W7w9(R`f%snMFT}3m-nQ7A@oqfF*Q;wWUsoXy4g7TS- z54uXO>CDma(AsmLuIg_Vt`))>EV&9E3Giz)EUG0sh+z^|4 zVwr-t^pC8p^fmbk+S`pn`+g}|KYwPnuwGcEU`zDD`?6xoUoT@i+;p^C-1zGgn>m-& zfBsLeD*dWIZCTW;S%I3uyEI%1img#o7<>D&i^eM4FmsaZ9o30OjcHCsW z=%Lk*d@9~b#MbQ7sXLviV|RJ;!K?dIN~TZU=-dm^HH-417 zdUMl@ZnnEl@}@7+4za%QX1jm7oyYFX_sl=3KR=2#zklx7++HCN`d)g$-l!R}hCejy z8ALakxY1Xoqdp4C$Lkq+DyCSAmgr2&VM!>JpQA8$HD#&j?MBe0RUQ0}W8B8S=P zyZ7gQDF3mWt-gPLN`2LB&sLAOa}S7ZOn6d1`M`tspZQJxEj(!dD1C<6oT%i&xsu|` zB=0s`hBbcP{3p4Y?~*w0KhFPG9z0J7dUsc^HEKohTE-`4gYKg;NOknMj{oXL;rf3%zHb>sIp zGQVW)62Oe3}5)&Pu??k??j0%lkZ)rr+NPACh^A9rGI$;leIZs zHl{h)O)vkCG2t&e{%EV?N&Ej- ze#Eo=kCs_{RA_3@kBmR^&GCu-$JR^ziMLDqkp0JMS-G|7+Jnk^Mlo-S7K)sT+#&g8 z)#=P$iH9(L1|E9W9aU9@ht1g%ulxEd#5#1`5sBT}r8Sv2+GEES!f zNpp@(H44h!!DGj_Xa1iViBTo9M8(&Myv+2JUa>Iy+@FO?y?RRvrnME{dr+t#J@IC1 zw%GEudq3XDd!AKqlbUn4<@f0p4;kjpHC?htOV%w4zuWi3E9lM@m0G>#r&Wed8}BCH zOx`*_EXL^H$&7Cni`KZ$n0eGv`~QQLZ_bsRoM|)hum5}BpO24(l^^Y?THNn%^}@*C z|N7tast+Sp&)rtEGdpzt%w2o0J>S!=74txbU7~R1*40u9a~iVG*q*7^^jYvgMPr3Y zN14;%SCixK`~CXzl=0LqmU!#yQ%+<@ZCZbN%hFSa8<;Kg(=DbQ=vc2UDmd?vP-WI^ zJ2Uy!%O84{<@|lY9qCvY?8o!7p!oI1YSC?}{u}4o2%pi+o8d9PGDO>c?di<6JNd^i z6=f`RNnUdPSns{-YtPA*y3an4^Ss`L`?-jHvGs~+w-3%P>MH$Z?&+^o!n)>lo4R_0 z&g17XiTl;WHVZPP-FKT(vv!;0_M^GJiX>3f-{`X}AtcDOa|(}~A>-dfyTxldV;TRqqN(O;E*HX;46{gXd_e&U!v_p^_= zY`wso1#TJ}&0<{-&r1^*D80Axe#pk7CLEU&+>!%B4ko(Kiacs5H#x*a<;W$aylso! z;?Hfln|8vjwfV5a(X=o%{WD$x$?-GNpVzTX{F~O}w=|9+^@@Jr?KSg$hRqe6q;4bT z)pch^UF6wSe1)r49x*1^}_na%H)f>OWD#(5h< zUo*V=)-m~~+46N^s6IGv2Ejuas?cbNT zenO#Qj?U{P^I1RWK1pCL@{gGNmsPT-@2RlHxo<~reBZxvZ(35aPM&F-uIAwlSC_1~ zn!miRZ+o4ZZH7U8+vhLOx?`T%yk~bSG=38onc&MVVTJU#Y8{iRt?hl#s~I`7|C zn;d8D5PJ<_a)A{87K9DbO%Z$-48qRmhTj0e6Mge_MPU3nye>JKQ&yBWl()CD^a;GX~Hvk zg~j#P)a4oPZ~WwFwfmZ}&%tksR?Dxwj(ey5fz^ipzGwIH%N_@UA4Gq8r(BY^R_p@X zOPlk{GlLFT=YCYs&ET#`U9sY=mAt&f&uKZ^KM1tU;W`|{z^K2V>gw*PH@7jXxR_n> zYDzL+aG776|H91@R^3I~E9cznEDb+A;d;W=t5-VeZ0q;7N4>DhVm7dTQT1x^_oSn| zGj<9x+-2Tg?=W+ZwA$I_tzT4ki67%^c&=#06a4MrZ@UXwTbid`oNlPS?)L1$vvI$; zczPw6m;cTTI9X@Q%V?DMrdm;!Rh+*p-k1M^!4KOGQ*Tdc#_0KO)h1e3UMTj;rSH33d;)g!SL-lR5z1|6nTzRo_v)=`#2>$N*%hoS{^d&P#mPq(jFb}d-3ac7EsDDz_P+n=Uqdad1bt&E>-+V*YL+EKR~LjyNov-Z)x#e7fE z>i><0Jg;PY-#56FUsTy8&G=o?qW-;H&;9NzMf?KgGp;eP{tj92E5xIoIjYieZ_~a` zeNQW1$+yxkqO}Z9O=nr@U0WN?`ng%F^i%yogWGrSFMPkuM8;8n;_k#5VM^DsR3)#z zT^#x%Y^%d-RnbR>+NWD9Mm*R%`P{@0s|%gp`~E(m!JpxtxwU)Fgx{4vE2i@`{ui84 z|5HPxwjqsq%T>qqVZ?9F8}Bt|F>VoO$na*^80C<~t8j&F$(ts1y=MJ& zO)I}$D1PvTXTet;zwOTtygklwdHw-=d)5W@YzqHn{{30{DMS9jt+wLN$7f8Rpv`o) z_{Q4l&l*3uz1i8at>K@zgST#MOX&Wl{5+Po>tC8n+~z+2Z`QoSUuAzi%kN*8?T+nd>%ErorMlNF!$Y~G=~=Q*!-JD*N{YAGCT%?Qi{)bpzh70yp478l!B z-eq53tbD1C@zYZF@qugj`{NkG4f5$$@F$z!rGgUK`*{12fl}BE^ z)Ur6szs|ZAr}agj$Spnngk$3q?K1(^N}U@w?2Tzss%l9JSbt63{?`P56}5YeU+ist z3S0aZ**=g~s_vMyHEQK5c|HCN=Pl7mi~lqDuKT)reZ&77jT8Hmk27j2e|n-kq1>nM zl&powq6ykuE?)E7oBu|Ax&BCCzuDx~+Z3LkD6F69{@-<76))${QZ1)L5shmK8F#Ok zcz4UZ+AYn0ubj0qndK7r#q-PGoC{NJTGu^VS)%((`ojMC%Qb`Z8P9dE5N-P}{$?}N z)8qR?Ww$byKB?a@zwPd!FIr`ybM8+u{N>xQvUtf|mQ0rCl^Qm2?)%EpH_eMWxu|i+ zvUyvsXJ|e0POh)(J$GG$DW*T+^P7MPp6PDQK|gH%$)Bp88nepdgpA;AkLk}Ji1^%A zT*6@_fBc*1?~HE-u{Y=a_frp_ddkq;<-Ju{l}7Us%}LuT^)hYxpMAP{il^;xqv`?A z&evi>vGY2DZ^v-TwyxM!GU49d`C?O_#hZGBzdye1=k*o+O_%;;*9#W^KB;lGp5N}< z#AlWca^Ev}Rv67V&wQKJq`7;;ZzqdFLEU3FR)}1U4Ek{*_F0|rp&+?6!S0W8H#D}S zUM!Kgc0Y(s=WK5LyPZ>)O$lGo^mP}rvcBSvXUZ49$;)l8l>E74(z0Svv-OTUx3-9V zxU^=`QjNzCl@>hj5L&?@QROOHuj@DQMH?q~tFLHqpKEgV{NzTn z<5j&8s>_##MYS0nwXZV$uu|7+3WsAm%ZCz|3k*T*DN_E^cX8@`u5{~46|I{2`4r>i z*$a~c)*lw=PA_uoJG$?3v`sg6aCdgF-GjO-os-9wj29Jc#hQI|D; zqhHC>d(V33YTQmyev-rY%!uvzvs$5K1)Fn%Rd(Xb_bc4()jlZ~Q&Te4^y&WHjbF|O z-22anIu`t4zty*VCI$wR&ALZtGBI*(K7RZ$BO}*j*>94YkDSzFXXKh(_)T&%&&6*n zNQ*62*{WiIxSxnwS6C$e=O`VF6W+-I(vqi@n+-C^Z&km_x1e!`2CCv zm`+(3}k;bcDed~3?YYblKPc4@?61Rna!@PBt>;A4QzO!L3|DKCn-}ByozQ*@mCaOC{ z$D*W$?P=8Q>?q%U`7JrGyN~<(<($9O`=@)`@00bJWj1~~9kcUp9sIR)a=KUQ&o`Oz zc~W|@?-Z}iG10P$`j>O(Y4)j~tDZT%%vzsSQWE~DN5fj_Ygz1%j{BRJEPnO)X7P)< z?@Fs&4!gSQyn5TWJ%4}6i+Ap!;x^vP4Hs}+m*~-!Ykjun*S^}G^Uoh%-G3`8c75pg zZLhDc-Ftm@{_1+Rl!O@vXE^P8_=_=rtHhFXMqj4>WJ^iB(O@%^X{Mrw^n}Hl!T*1T zDjYwmoMYDa<}ZWVhxL;V{STMD&aij*UuLJH$0GiyvG`-Ig!m)TH}4kb75@_X!YyKZ#&5whKZ}JDrJbB27x!K` zCVZn%R7I`XN6YcuAzM)oA2!X!$KEhH@jFZVYdM-ornqqy#q%yYsZhLP+c>VW!;pdY7=jr}@ z@;JhXEr&<&Si^)I9u^MmB{ya~y5_t!r$ceArFZ&ohijV4g&&B_x_GH%iFWR+3GYfS z%$y;XBW1o&_*TjLy}#3+T>e&h&w9yZ3yr^y@2lp0|NZ8PO)v7^V` zxx&X$^q$t^T&^aImlvC+N735w^g3O%o` ztdQq_|GZoN!9&kwbp|c`AODEVubC0<-~NH;{PW5RvzGo3e*)F&d&1@U9}3&lPipsX z{UCFG{PsW!=1!{wH?S zuSl@ock0P{O^?Sy&2eD{&5^9(AHE92O}VgPzqO^sg}a6(H}2jyH!`_kJW1k(e+e%S zpEt*Mnd^R8ZzXlD@6Fqyt8Be5`p_Rgjds3`iOHoqN{RfWx zg_V+ql?C@tOv}CPKFN8n&@|bXemyGezu9+b3D(yKU2hEJ$ zc0RIPxqrct(gPLoh&XZCLIkB+ihynX(rEi!kr?cbc4 z+q66(b6aBC%b>e6GAGV?Ty^SReuT-aYg1a*UM%`>Td{2JwP4m=ZV8Qk#=f(3-xzMH zicc&G+0M2#u>P9qo#bU(&M2NWs(3HA>F&CiPns_uGO20t%$>hw>y^$p-RJjK-%L*7 ztzO^qRW$0??!3c_oIr7dv8})cb)KS{({pF;FiC%DdG^wG=}NCP7nz!Q zBHLPAFY@*^tjXKX&s$RL@G0$}*Hov_MH;TGpNyWJaPhu=iRqF|{U)Ol#pJA)E$X^X zZqtM!ud8*JO}KdXX3W8|zVg#Q+Ips^?D2Uge?517)e`BsQ&{7iY<~Su>0HCjKS9%d zv3tIrp8b+My=^|nre8~(W%hFU(<;+#-kWpo3Keo?T(gLbey-d+#X!b`(|5bDM&ij8 z{Qq=M9SRransB)6!W@;^&nMRZzLOA;yQcfznmcUvwV~USmj5zwyZNyAz2C%3zh;D; zxbq^$`aQ?X4*if5m*jN<7A{|@(dWT2FU3PLTywp~M&Hx#Og~j7>E2we;womnb;puL zN@kllIM4pyU3P*if1_7N*az#|X63s#UU?V7^Juopt@XQRe$$m}3#pO5zwlV>rpo#S z6Snqx?v2P2ii(}9r2656gr;!hezW~{lgu(_o4)O+o3$!kd8#kx>iQ|xQ@h?js@8cc zWjfz_jhyKE!>>bS4rGVQxNPU@Ewyc0thMg(ZxxldnpgRB*RTG;7#BG4xTmOnif5_} z=h=AyAC;f|Fcf~h_sEkLH~qj(1}h(_^Bv0+t+!7#`>LoseTl}4zLxohU!SM4u>TPE z`JpQOs%DpJ<%Y{TDVGj;-&v%zyhbK#=Hx>QrEdoB4=U`*{cFnnpKX8WN9(x1a_%bw zm!6)L(I%=UKfkqBIr2`Q=lbR5Qi0)nW+ME7Mp*zT7Fu) zqI;{ul0UkhTz9RKp2!q>-P>KL!MDS^&}`%F?e~+Gw2EhOs?D5r;V0{i^Y1xoty6NB zGmF_vdfhMh>iTWTkZ|NQ27x8Ho{>sa4f+x`ySa{v8J^UM2AZ;tOa*q$BLzB9RdW|hU+&z@!cRh^sr z%jT|FD0;zwJ+p!@^zg=luR2V{9DL^&rHOso((rou#l)C)mflsxocRJ5wn}I)_0>Cz zZMk-X$LW01PnoRt!(IcCLf9J* z&ovg#tLj_4r!RVC&l2Q&aB`sP<^5r^7MGk_Z__Ii)orjkBTw=9(drY6*Iu{G*GSh} zn8%h|vT0&bI@{aJAA>v&D;dpg*&+Xj^PDe@xPl{XP%W-LS#Oq+7TBdBOJ$^$~e^##EJvaJj46kr*kO!wScW{c2 zgr$u~xoFUBrFPaXz7CBnv5^0Z!E zdh$x?p>EUvhyR&S`xIAFySe2V7#L(HFXpxte4?dwR{P``->pxXpyx+2@_0Z`S&rwC zWaQdh$)Q8z|LuFb2(T-g}8CV!N9#fP-! zTQseD@=Mu(dQIC6x&Z+K?>j^n>TY2b+|b}OwOfSC(euOoZLzPNZmQmPtzn&iDExp+ zvscoe`PqP96_wI}+- z^{RYXs~dS*Ez~!1T5nU*k&{(1S3`;?C2qTZ^G`mv_Z;1g-QU+5?hvjDOUw{#S~_>_ zmL!|Wmn$c2QT^I8Cw?+-=$me*?F&v96uw%zQo?vuph0-~C07r&`+JsYx+&?4b8$uX zS`_hw99n3xcV_ZwuJB;FdQRub>(y={Vwlct|}wrEdo zEmz-hp4rbQv7Xy_Y>iLh-p(#XwKm5#2i@lqOG0appU^N~<*NogmO_>5a!4JFl0i~+W3EF;)Y53jY)>A|wukkrHby0Fvh{m=s;$UqSytD<&EmXI_Z5rHoyD?E@afDs zCpB7~5=^`ztwNj=zuZjSmAvXFN9fcQ8|sCbw4TpNGWs&5tS6+(`Q(iDbZ=Lg(^t0p zwS3zawBEA4NGI27tJr%d-`e$ITjbAuuU4w}XVx>@@xRpY;pPR4y6ax(etDf6a-jC^rJ=haP_Jvnl+Dz6n}Z$1`U z$8fEy{ukd#iFK3BrN7GVRk&l~&tiYzE9bip=~s4t;GMVh-}?+}hIsyo%M?$1ySSsA zA@eW8y{`c?w(a}p?0R{gYuJSh;e;H)wK<$`by^vsH?CmGRd)|jE8xEC;~HitV!-rqUzZ}^#~WROr5}yD6K}me z#B|nk`xkc9e7scBW%1-*Mc?`@D-`U)SsJwq8oHE@xqMJm5%rzmR*|@AOS=aB{NgYPHI%Ti15Ij_}`^bK~mL+WPsd zZC7O7E&j!}P25=V{iBg{(aF_9Hp_XmZ-4cTwtGBVFVb(y96;c7ul!IuGsP-m{(f%gly7L@r%d8 zp1*JXnQpW3QK$XYlz*oZHU{T@{J3ahNlbEt-67fI$>~jY7s{4hb%-^unWD>cY}IyM z?QhQRUynM>K0jrZK{wB)tR3@Q&3R!@W+vaPx{Ale!F-KTZ?dZgAe9 zat&L`42yI1H;vE8?Kge#xz|3l?cz3R+c*2T3hQ{}txSK_XUxcu|ChZhxA5iXr&nJ! z%f^2)D&PLrIj+Ho>r2eCm%K~e9lnZq#$E`SKXGaM7WXBYCh0!g*w5pgvCWYO0Msosw91*o5MNV&}7pb zK8a=vaU;3Qd|iEa%2lp+KTB5$X^WlD$Dqx);X+9+W3gg@=X1|X9{U=+6{`%_+zhz# zD16D8+Eoj~Zirnv)43#T%L%v1bHZEW`6|DkbU*4p^Qi5HyUdd7T#bCTT4?gH9$&UZ zTY}F>inA1-ySUFvgnj@f;(a{hdC$*=Fmg%h7OF+I8bg*_vQ=~zB$dhO}<75+21 zQN^pi=yr&}zrM9kc5J$2waimm;Q`xn&zjES?AbRmy(h(WN{ioNn^QDd^y-R@OZ#*# z?_=se5Ise5hKSLHf6WhND?}u|dE_Ns_j_V6_u=`SZ*Fe>{dT$S>c5}o$Ja3%w6`1i zC4Xe$^)_nTaAM+Q#l%QAvFV3*G_97A?>ftMd{w}1HRt+crG3(hcb@D}eQaho$*`fc zZ%>bgnFW_jx#X|8`8`!NZHYShH>dg>4corD%5AmOOw-k2!Drv@Nqkivx_jMi%S&-) zK8JT6Dk#1b|F@Jke9zrQ(`VmGnQ(1Q?%an{1aeHWQt$3tK5ey1=QCa3wRx+yDSq=^ zsPe#wXYDI~-RS*^H|k55-_S76HPYDb8@&Dcs;s^1Cf{15f1)DXStK*UI^eC7U%Czt z^R&p4klUIzWjv>!{AfwM5M90R#RbLa=*d6bUv1A?wrbW?pNkuLH&1#!#pkE<`whMl zO{-!Buaw?coS(k)m&>H>ANVq&Gj69GJWwn@?VH9OBrzt-jd3_Dx+( zpVHxT(kHe53#8q>!)-HH@bDUmXA+P0-btR&9d`JdM!Jg=U-=6k?suYdj&?L9&Uv`w z_yjw#<&Qqqvd;c7<*_lVYL4NNKR-e~Fw8gB`B}9q|J{sh!kfL*=GngSIB40!84_=( z!e722DO}3*Zpk|Pt6$RO=48+6F)dc9k5%0}V|v5J&X2#2m^eRCh~$3izUx^*%~}W7 z$cifxdOzE?)Ok1@zRTYdt0gA>Kf3S*>xAb;Pdl?-zir^No?-njd%63w`Rm-(`j#Kr za4*>P)z`q2tCqd|T2)inCU?Dt|9$1D&sPh2vf8>DHF$EFR%MCaO|-brb@}v^@bYL^ zc8>aKEKMKd1ab-m=07wm+yDC5DQOMcwXD0t{gl@$FD&v~85!I;ZK`I#WQw{tTq!cxLrS40@qw;NwnS}!GD^E}GW-;y#oOW0u+N~?rtuJ=zwt}mz z`yMpjYG0ScG?}G7a?P>~QHL3IL7YoYJkwaG*qfQd56lcCpwd^@SW!fo+#ile-GP5*7QR5Mf1-+O4e-9&-fQK>Awuxd8AvkR!8|V zF)+MmVPJ5ZoG2(d7bq~{~zeqpYbE1=9|3a$H(X1u{FD9KXQJ4?vCa6JJo*a_Vxci z2p&)~u1*4O;3 zxp04SmHV5@Ihxy>`aYDkhCQ33w)vvAsL(TMr76DlQ|eYIm8#sH7*@Al@C$#dSl|Lq zzsuj3=2a;1sEXTUvhI5RZOe4k+?rV36eZMxg(Z*%NY(Q5}8 z&g;T;=Y1!9edx3Gr0K!LB~0~)Uq~{|iOt_sziHjA`|1MMMQ%@gv8PUrFZkl~U3+g> zPnf&HZq7=x+&ldTm6zsS>HU0dcB#|T_zNu`x4rtQBqi}Nx_(xgfadwXPj6h?@E~`Y z)|TeRcPEyg@|Z1|wLPs%Mx@~6L8%z_*9DwQ@2`~cNjk;$``3&5|2K=@bSfOW;@ZX0 zz4)$@&$9O^_39bl{y2DFo^MclaJHd-${!xz2npBoc{l#F7K+vvM@Ae|x3jD%vJ^TV z^VW7v`JRmdPfYVCePNwm`Cf&=XTh0?J*}A=(@Lf#SEhbtnfZ3-_7i7iXV-q4v3cf< zl{o@mL@TXa8}}VtC~ugpyV57}Y@U>H;c}yOpUyp!l!-Z9`fO&VubS176%%XVF}#dWQiwjR&P34BY8OVchjNx$3O(d7|X;9Mwf z6SU?*)gAu-ZO?z0S6IB-Ydm>LE>q^uC)2;*yHo!Ct7`q9&tJDQM15@Ssk)=On6cb@ zhr64m*%V=y$EnKtg>gcAUi9qpbgDOMV&rV=alN6lm?`?ll&*vgOlmrAQj-F^tAAde z_TbctV+AbAMoBlclBM50p8Y%ZP7k}p$AcVlNhiK>-DzsCtaLfFxaO}!ynS4w`i9s; zlYM?oX<4pnqr4!(d0pbnz3XykcygW>OnJ+~QCl`^Szh@Plj9d<8>i`=_S>eCt2^;h zee@&E#Y+!M$y_<(GClE?dFHmox4YFZ#cK+DQ{~XH;$7+Qd_(l3%m#)|btS{b2_C0p z!i!5e&kJu|@1)PnGOPQw732I+*=s?W+cs^=-fXsJ>ylXItCvzO^zKgmF69|qeA&z} z&gN;=(*JWWok{UdD3{(GojIfJwpzi0y0$p&cPr~3_0635k++sX(~$ zz2u6Cp8x({+srnzMX5hSpKcbO;o9+0_wKELgu6L?t!cY$e}zpC5sZkkPoBAX@~-OU zXHRrA*XHjyY+T=`(H>+~z4DB=<*As{vKQWNbzG_89A{xXzw+f|@wW=vDtiwf=#9#i-xH7;&iPVA}EMsZP^fxtvj4qpwRw3D${yhe11W~>dytUEM-MvI;ZY= zBQj(5>UU+guWc*r{Cw4$OYdkZ*P@KD3r$P8rY#ITSQNA9f!i9v`i{9#bA5!?+>*N9 zyh4wE-Rz)}^}k|+)$%^f}d5;gV0M*kPIoA;!2e~d`YA-?}2^F4pW zIOvAiaPd9daA0Zr4Pn-(<&kG6cRUkmFg?3Mm&4@Tl4Yz}%df9m!TWsGn#)&n&u-1B zm-=y(J8D6m)Y`M}Wv&!t@&>PAH+{8#y7&y0*SnXAiSSNmVor)%sCnc}@UEF9>^6~e zuY6YD&%?1sRVa9caZ-j@$i~(*_lic@ ztg}A%C{=q}5dXUwFMTv$oLuSlG?l}4+lkDXHamCMH$3h>ziLln?W&2M{F29a^rr@C z{A&6hA6o1Dk9&if^lG2tnF5hLaUCY=TM*m(ld+oQ7dU4!Ga#h8V ziz~a9&)I%?!RNC2S*7>*%a z)t1eNp7&%I=suVm5&Up&#C4(fM{Z54Qom;I@?Ca^-i3F%lMY4LUaU7fQN8hjgx0Us zQ!bd#xEe3@SLorr^#;E+&i&FeYddx3>zqH?R@09j3k+>4J(BTG@lnL9$Ux_N4He>( zEF5O-?~f`J$bIBo($#Ony{h(QBzM&YuIrQYR=<>SI?2lYvWD4;IoG`67PGgaq7?lt5v(Aspcye3dpx=gk_ds*U(EAggib{|(AG!BVsykfx(Yj8k{y})*q0iw{YBqI$+BW-9OxNQlJLOJ=oI5Yv$bWkSb9Q0y z1XgZ=zPV4-ub)*9)O$E>e_*jtSGmQ0p^%L2Y!B;ix%g<_RB%u3_5JMZuE^)lc|&_1 zQ?6Z@+0&FeVj{gg`xa!Rtl{o*JN7p2;)j*;$3nsn`zff1$ z@qbmp1;6`y&+IdD@_eVj`_KHy!Oe<4?NMt#l_UEWEoEY0_`=4(V8g%wzHDvsZzHSv zT>r}fBFF!iOW(aFDyh}c@8fclc@ytM#TA_A+9lLyB^VqG7r%C9);qC$>qQ@X^S@mF z;Uv_0M7)l{e#*x?+s-h0vz?ywZqDuEy5}3;&fmYkj(Nt>NqsCuR+CPsdunNvM!9pD zU%lBgsjG0x;~A+J=IEX;a*^3C(H8&Xleb=M@Vfe{JI0bd%bjLy$|}BY8r!yWma_EG zwkM^xb@Fb7ZG2@iJLXFEGy~@SCzU6tb`@P0npQr4;iR|h6QYwlLg!jNHD1CK9(9&C zc;6#wv$=EDSFo99Ub0m?-FeK>RsD@{+rg3_)Fz) z>I~aTW=XZG?ahg=Bo1>*&E0V4FYBehnfW)DaRr~6R}o#ZUv%vKK# zE@kVPC8d(tv4ZpBNrOy(kM0ZgTIatBoD{E9+U1nsl;HNu>7^?Z_dd^w6`QibY zbk8PzO`XN}Eqhuo92HpglzVr5M{V|JlU@AV?jF2&ONRG(;lbw@rnSsT7nyH#AmJbT zqTLc2KJT4=*KvG5c|4WruvwnL5lv5ZO{Y((J?#&w6Pr9)m&rVCUpU{o$Y4zo_VQHg-%TvPUp?+QU~pimWAF|!C%H+fCK)&6Zk$_~GD}vp%*-n1 zQvRMv>mIkoU!3xO=F(Y>oJTS&R3!|*vT7%?y!st_Nc57rh{D_-Xv1M4EZ%mLUz!Ff zEGc}nLuHCt%qi6+n!b0vZ#ii0EzlHo6Z+A5eSC7XnQr}&y%s_zR$egBD!(35 z)wA+Ma!hLpXX~ z9?&V?JM%?suDA4<-Hrf&dC2Q8g$yvTjJR))!vfpFEdxJQ0$!2c6r9-3-$fM zQh7-c2luo^M+9tGk;r+Pr?_$Enmr$UHl}f2*WSLWZbssU>Cvn1rp>UDdtSG9MPt-* zP0NgL&-`x$x1FqCxwdIHPx8Uyd9!oR7oI8N-!+F*s^*o{`m1t#KC-O;;CA}Y>6Fl2 zD|cO4`S6Z`&-Jrs&tA}#vpu$Vitz5Q@$cRjX4h}Nx3sKiU5V0&7_ zymHE%icc+q3l*gp4ohzGYT>v%>ymoe!IE#HinT@J5B>i|UWn}4tP^6^q;fj3qb9TK zqGZ&0=C^aNa0otU<@tT4JH#tpBx`fgd7g&eBcY>`ddiPKzge)p zSL@Y$LA6zOSy4C5UG6LHWls%`GIE-E{GRg8_8-ggSIOVb*ES73d0?49@@3gwN1g93 zT3`(>)Us5BE=G^0;j@aO-FhOQkJYmHTk7RPqqKpXO! zq59y=dAj> zJ?fvHDx4C<;u0v>y~X`>;F0+XQrSK|9BLYD|D)GUFRIv^{f=*O|0Cfa`YKGFYIY6p zmlT#o3*=08ntblvnR7Lt&z^br_t)pY>J64QFJ0|@<{sJ7XVT@QyVPLuV<{cp%~mEN zts2~h(+}l7v|j&kU0XE|r`$D(O{Z`FQQmIz?)sXo^%f<6Z!tOhU+B1dVENfauXleG zIvld^?)tky5$OTij#m>UBFbvhQWb+4Byc#wa-iQ9$znX*N-oES=iYtmpZi4C@@i`DT)P`wR~PuqVmB!3 zU!AQasXk$n?~gn7bTyS*<9QcdD%;mT$71 zM@rC+)|F;yAusdXUnr*u3q?7`onmr(S|cL$RW_!{&v;?H+E;PZrbW7A;if4}3=9>l zli!=_PQLI)Y_gprcYSLrx9CExD2Fu{f>JaUTBZni2v1TA^~v)1Vm8G$GN$b0yJOCdfXm|MV%K{*H1RwcXOSF*xHX5D(#=m{=V;fY1;mp>i>cVl)_5BB)hfiiSt(S zZng?JbMooLw#uEp*RE_>u<*!)nC-FFcM<|VwZ^h-ee^b($JzAu)_L3d>c8py-+7~0 z!#L)%)S;WA`*a^$tZZX1J22sr4jBrZ4+N#Nt*HMum1(rLY?iBaxUlF@@}Q9H;!0PzPvfHA#Np?UhC3~2}+Z7 zlxNS_%TVvmcU)kt=gcQum!3$=GUO$+=uG}}q}|?mq0NR+oAyQf8kg;BU6pg@uhiNV zH-ld+ekCciXRht!cbY<3znQOyzhUZBS~xjZYmrOu@t5_R8Rs2P@K-u*>hsy|$<96@ z`2#}!t}WB7eUqIo?QXp-cvAO{V!!ZC)t-lXSI;Q5S3g<#q|r~k*Y}$!+v_z|Ro%xV z`;SMe?r}0RjsC-u+gJDeMfQK!$sz4dQO711PBh(QBQ_;gKVup5jwkaE)cRc9*TgPp z*WNyH?lIp@$y46DYcd{w;_FedtACm1f{u;vQIl+fZ(S%069dBz76t|*_#mX|TfzFN z!T0ko1&I9f(-h$@Zn%BLQdH1fLi*}n$sRQ!U!N0cO*aqU)4Q-i@9DKWWp4k~<7+M+ zVgJwYU*qvk-Pv~)9A|BL?!N!?-1l>C|NHm(vv>pZmfV!U%@dt<`;VKwsz^#a?$kV? z`k|+OmFEeQS;tv6OZUVa$~r&!-NT)SgzoaDex_IJ?Pp8ZD1CrC%963=wcj0@>y9q{uMN6zzO239wwg=4W&}W{m zEGk>uv&TW`n)F`dkDeC$CL}MH*YxkRJ}c~Wk6T|sa^bP4r#yWdgieUeZdF@2=SO(S z{4<$G%ilh#FHGAJ>8v=Ry>XAg@2Yz?-tRRhXr7R^+_b^_MyAfQ%4-+hb8G6nR{ZCm zmGHf}*tFz+)vqh&X$HBrzJg+(SXO`3%6YdvS}e--&BC0-`5U&M$+5Y$|E&z~xjTt2 z77=xCTW&pixX#48uPJ>-M@Ge}{r6rev28xJKaB6!ri2%w4F&bh%I&%v&%XQD@Ud5x z+04G!%2QS3hQ1oZw$%+My#o3=wQ__f@r6sy+7)`Trv2wvsk2c&n)l@)u z-D5wW8u8h4)bH#Lx!#q$Z@uqX*S&`{MRhy<)ZK`N!FN`!j zW`D?c+w2n`X6LS%VHTeASjz0SF0cMm^i>oEXCrtgTe-DxPL+=5HqX2BLVxpdxB18? z91ASAWfv1-V93#AU{HgmD7MK9JUQw!6Jm}|{O2`mrg>G>w$z)OY!h-GGQXZ?xNXDJ zU^@m$Z?kC|C-R?(sG8&^cfMn$;5G}V9ft(_1o{$$nHm$?S(He!TAQz1bJfypZht6HxA79$Fe&diDBM|Mjxf-vk;WKZVFyecYJ! zuRh##|MiVx^D}-l^Xc1N{HXbFMe#3V-v7%V`v3gFYj=I&V{X~XA3=u`WtBfZuaP-; zvF6Qj!>cmaTSUUUf2g`2mpFO#$l~NZ6@MQE?>D{rL)3L%U+kjas_|zfR!J^QbNiJl zQaX`of6uig0mn;f4$V#NQA;kJ@<4dM$j0e~t0dQ3)T^yfTfj1B$&-0&W_5b`cfX%f zW1~O$#)B1VlS{97Y*btRYKC^O$;?$JO=Lf(?&^!O^bI_BVTsG}q$)?R(km;cN@-qR z5_7yr^+WE=C)2sAT(z!xO^si5RnIuIc$ePhCp@OJ)}EYGvu2vq{y8g8#+c4ozHQCd z(=|)KGws(2*)N{CsXoHpnDw-f%u|n76)dOLq)Dzn8MI#~xJ>u@#?Y`87bEK|qbr}w z#J);hs`vbq)_#)!;d$*QuQo+p`|;Ff>yEI=YK?*NoijG3K1{I5JI4ArtX$RUqDQcj zSl1T)?sqS^jx}{=_)IQsI(fROaI>9|x$?&VrIOB>zA73Uc3%E@PTZ&7!hVyj&|S%m z;@4S{3yrT$;ZXDOy;gj@*nh(|M}u3bznB~Yoi*g1U;CC7yXJ1xBHhwlPUE!m$4oQD zdbXyW<2w4NbJ@GxE7|S_m%JFg&u+^&b7t1{l;l&4rPj@c#>w}6oBs54p1osmH@eAi z_4PHYmcj0Is6e>MdM zM&Dd&>nXYT(hBLO*d-^kxwg7Db-t6(jhVP}*MWbMd~UZ^=Q4f{cTIkK_3g%l>>F$H zINMjr-VSS3TDJDhAJ-|CRuX*f$Sn4HpcxsnzopJKQO{E#p zliWhje-7&6&$m7tbmQZigl`kv{G>&mPkCglytXH|Ue3q1Sz%U>$lDNKfrBgi z<~flK5vDr>He}s+bJ*(0NoGx_jshl)IB`jj8JVihEIV7*=W#}z{gW-7$FsXr^6sR$ zC*$YZ`E6UisHvVyoKHybJj)z4W5+gQqjWJI_8^lt7gJVu@kC9ru$RkuUdeXJf62Pl z-Hf^Ff)5XMq&Ymlk+J4#k81I;d7-CDkDf7m%`wTCHS^S3uA@`;?Yw)p~ce4p+~{MAzX zuJ3`~!7DlTyWBo)(P{Q`FuQ-2$NW$E(|N{U_C7qc{G{tF7So$P$t=tvNG|SucCHxitpG zU9{Yt##eAIbWS=?dvQSIL=i*(&JX$uvukI+_PzKnf;(He^~7T~&s9N1Ja@XHdG0hw z^WItGcK_g8mlch==Qxj9@90(2ZQIh7`Jj4-e}Ik18@@>gw-_$*y|uHsWJTNdnEJC5 zuJ>k_F5h8odNa=>qD(?);tIvsB11vd-ye87IS(5w-*jn0O9{7D`yIo*A3~&Koo=jM zbEo9tA>F5KZ>H=}+`Z)Z1n;Lt&U(|eIb>D4A1~!QdT5oA^FGCJtws4#MN?yZE4Ey_ zx+&^t?vB>b9^>$xOIP(2&S#4``6|a%N32(}zNj~->d%8M9Ierz$2i{Z3R`FVB)Vv? zqPd3q9gT2_qRBP4C(M4D<(zl$ZQC8K?UJ8lRkeQKVLQ4>ar^1=$cUW>mUQ)s8=WhS zJ!4Y2uIX}nq!_P_`jqVV0cYp7-BB%9?=9J2yyrO(5g{Swam)W4_92ompR ztrjsdR;kzO;@#6+Z;-M*M!!L^`bnJgKK<_*Me`fYpR%{znSXR1Q?|2Qz{6)V<>t$s z?68t%jjco) z=gqy%jdq-G}1j$kIMcAXGyBBBfas1>q$ynFS*G8~MwX3{MNcO0)R(go!53zOEpDb^)(dy6qWIUBG z@ZhpUFP%QOL$*hCFM23RbOl^o*O$=p?1+=@QC(S^jbd#Pb3U&8wrST|<5l~N65bxZ z{-n_Po3^Xkw4At_pY_kyoqly_O7+oYS5_3gp0+8-dENx|msb>%J5|3=QtWK2u{$pv zbfh!x(&5hX@8#PPu3fL6%fsH{|G{m(v5k)GmlXLtyL9_ItfKMHD~)6}oUi#Zeg2Gl zs$aR-8xB@2ig<3PwAe4j@J-m{v-ReBQoex3@2Ko|_z3zo$C-PUqD{ld7%@m9=m^HxV}5HRHo{o9Nj6 z**zs@!G7EJ<)4u`W^MIaxJj&Q%dFj3nr}Hzes#6*+V0uQq8}tLU6`=)_QjgJdq2;; ztx>nGs_a)&SeuY}OzQjv9E&CDm1b4_nYLq<-KM)f8|Fy{#Ba}DxM5|%DRDF9x1D_2 zJ}(>U|70vNl=75IXmp)vlH7Vpe|xOs>CC*1&&6)++%r?s=IzFe^6PCAZY?*keSLL0 zlW4ken_rf?(q;$c%GZ(Ec6njqeD$oG3~WoJCRAnipYw?Sy}R|(^&;bYLfoqMb)_rS z|HX(;Zhy&gzijhyrzaDcyLla-@~rPN-*q>?Hg`kDpZYs>d;jttI=)a=_FH&MV|(#0 zPJYG{FXN@ucB#H|(5bwA=l@MBxX7Q58GApx_vic=>7%W~_&7(&y+P`2{V}<9_fKzZ z|NH&tadR8d#TV|FXC&Djt@t(Z`W^ngJKtnJ`JxzKz;KMQC*#HO6VEnrSvCarKCRVw zzoE0)1Rk1 zPdu`n>XSY>v+HQdD%aN^t(J&LfA|$tGI{=yE4CU+UrmDEJJ#7R`>f$t-Ke9o>Z|5v z=6!Z&PAuGgOf%9h-QC-I&(jm@uIhN5UASk}CV5qnkf?}j-9@f3_qw^R`mg!Q{%7xs zJH3bM8|*XnLJ#_8?OJs)dUE)brtHa-bLKCZ&AHt=Z| z+TH%jk;J_1G1Hd?lHp0pmlK4ObB*PWiP`jWf4qL9E581*(jMp@$ z9Wj669HUu(!1R;ky29fh&dN%57@qL^0kgjmemx@I-FFyRryt(|wX-oN6 zPa@wuKCya}=FD1|x5xTt779O6wrQGgV7~m+?;o0`XOAYIEZM%I?%2i0b0Qm>k~OYR zSpG1J_ji9nUz_34&FMY%O+tNri{`Cui*;XdF;U0rOvWFf<PAO$VhqcBdKXJiuL$i4sT|1_4 z%bs(4&4*_UX{J-m!{kq`t)xG4s^>Yuw){-?QqQ)9%uL%~dcAF4m|eYEmyO8ns+7X8onG(O)q zF@4#WxxQ!B7hbSD`}xOpZ=Nq2w!sm*B-wR!z8VYv`k8g}w`zv!;hS@wR~l`1XW@+(4rWZL(vbL(@j**3#UHBIwqgn-wIh-o65 z<~W532$@8C#VMShxGAnzCg-~7uaIiF15+CA^UnEIAlCZ!@RP=;iw>SX{+;blYr6aq z%R8-FSF|_kE8m~Amp$sCmtO@_CF5TH=g+i$&FtYQJzT#g$V~ffjh2+oTeX!F7talQ z5_%x4R)E(u?pS+Lrp%d3QjjmJS4XX+Ox7!9 zp8sjGv?F8ZzJli5Ddx?4Za((dBH4fcjK!V@ogqANr%nXDm~y;=)8MkVr0V7k^4T-y zJ3dQqdAW76WRZFCllr=2cNLG_%$JP+-}C$fkILqc zn{*CpZ{k_+WnHIf{c+Zvw(Cz-_b9G^VfDVfjbxPtTL4-RU-uu&P|~@pHxG$md%(xjmh|_T>8DS$}j5&)$3Z-Xi_< z3;&Zps;h!iuk%V&%53#3+q*Pz-PDBriBXLedzgMbVC6Nv_9M6Z1&5fBGymfhrDuUY zTRxQdyeqUiIr}J=OzPQWRUPBU+{F*Cc7N3^|KA`uAH51+|x+-={yUnSl*`tMb9 zzq`KpgYA*c!SgIa?gbQP1m^WFKT&+D`9@^mlbNBfw>sQ?J;lGVE+6S~@qp_gkrj zE^|1N{PO8akEHX}VWv~EEBCj#+I~#p{&*!((;`_xl+Yip!Vtw;;&hv9A|NQ?< z=Pvg9cKFcTpZjCWrzO5QbK>{>E5ezbTbWq6tgAQ96>m(Jx7q2Rn3ecLq0EN0_(Sx{ z2KP@pRP~NWD9!nELFp$)Aa}OApnu}Zh~w!o;`0l{H}`Lxf8Oq#-NAjfvmfat?w|Zu z@0+dM+&y!5^z1*rdHaaWfAZh#H|sw=`LM;hkoV>K)Oy*MVZxemAD{k( z%->JudnY+LBwb*#LyEv==a|dvj9i<=Q5cYNew#A6<;nj)fi^L*eO6|Q zQ<;3RPIj`zCr}urepY7kQw95F{%18tuF1zfD>H@aOg5aaj}aOHMY|B!nxWVssXy6p zzVu|zr{auUlNG-xGx1nXcKj+fIp&K9l9v$oWH2x&q3HhxQZ8cxyEOwn8bC){gHN<( zLyv}Tr^$|AWhNJ_5XNwA81hlWD7FQ=PImkXN-EMvC3#>nOB(&7!NIWPs}LjCiT{gjL8 zZN+2>9&IFH(aCbp_?XNpC+j@}#iZLaWv0~1$rE^tC(nBZN{ZKIdYZ-V7GJC&mM} z^P>!M6x{8c{7^%Aa>5H<3w;*clj%QMBarLA6LADF^S~U}j(_<%X;lg6UY&7(WrLyy2xH()=}eP50ytFGZQQ zPM!Qv!(%f4E99(*Sb599U<)$}9Cv9mz^28$QbIBfyi{p&|0_|ZiSxnICtoQdxec`R zV-*tv!x1)g(T1ku(E;dF<~%a@DgHR@VyS=0RWfc=5+u7 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index aa991fc..332218b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index 44800a2..5f3ae97 100644 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -3,11 +3,13 @@ package me.melontini.recipebookispain; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; import net.minecraft.client.recipebook.RecipeBookGroup; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemGroup; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.spongepowered.asm.mixin.Unique; import java.util.HashMap; import java.util.List; @@ -15,16 +17,25 @@ import java.util.Map; @Environment(EnvType.CLIENT) public class RecipeBookIsPainClient implements ClientModInitializer { - @Unique - public static List CRAFTING_SEARCH_LIST; - @Unique - public static List CRAFTING_LIST; public static final Logger LOGGER = LogManager.getLogger("RBIP"); + public static final boolean isOwOLoaded = FabricLoader.getInstance().isModLoaded("owo"); + public static final boolean isDarkMatterContentLoaded = FabricLoader.getInstance().isModLoaded("dark-matter-content"); + public static List CRAFTING_SEARCH_LIST; + public static List CRAFTING_LIST; public static Map RECIPE_BOOK_GROUP_TO_ITEM_GROUP = new HashMap<>(); public static Map ITEM_GROUP_TO_RECIPE_BOOK_GROUP = new HashMap<>(); @Override public void onInitializeClient() { } + + public static boolean renderDarkMatter(MatrixStack matrices, int i, RecipeGroupButtonWidget widget, ItemGroup group) { + if (group.dm$shouldAnimateIcon()) { + group.dm$getIconAnimation().animateIcon(matrices, widget.x + 9 + i, widget.y + 5, widget.isToggled(), false); + return true; + } + return false; + } + } diff --git a/src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java b/src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java deleted file mode 100644 index 9f143fe..0000000 --- a/src/main/java/me/melontini/recipebookispain/access/RecipeBookWidgetAccess.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.melontini.recipebookispain.access; - -public interface RecipeBookWidgetAccess { - default void updatePages() { - throw new IllegalStateException("Interface not implemented"); - } - - default void updatePageSwitchButtons() { - throw new IllegalStateException("Interface not implemented"); - } - - default int getPage() { - throw new IllegalStateException("Interface not implemented"); - } - - default void setPage(int page) { - throw new IllegalStateException("Interface not implemented"); - } - - default int getPageCount() { - throw new IllegalStateException("Interface not implemented"); - } -} diff --git a/src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java b/src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java deleted file mode 100644 index 1ed4489..0000000 --- a/src/main/java/me/melontini/recipebookispain/access/RecipeGroupButtonAccess.java +++ /dev/null @@ -1,11 +0,0 @@ -package me.melontini.recipebookispain.access; - -public interface RecipeGroupButtonAccess { - default int getPage() { - throw new IllegalStateException("Interface not implemented"); - } - - default void setPage(int page) { - throw new IllegalStateException("Interface not implemented"); - } -} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java b/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java deleted file mode 100644 index 304f99c..0000000 --- a/src/main/java/me/melontini/recipebookispain/mixin/MixinConfigPlugin.java +++ /dev/null @@ -1,70 +0,0 @@ -package me.melontini.recipebookispain.mixin; - -import net.fabricmc.loader.api.FabricLoader; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.MethodNode; -import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; -import org.spongepowered.asm.mixin.extensibility.IMixinInfo; - -import java.util.List; -import java.util.Objects; -import java.util.Set; - -public class MixinConfigPlugin implements IMixinConfigPlugin { - public static final Logger LOGGER = LogManager.getLogger("RBIP-Mixin-Plugin"); - @Override - public void onLoad(String mixinPackage) { - - } - - @Override - public String getRefMapperConfig() { - return null; - } - - @Override - public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { - String[] strings = mixinClassName.split("\\."); - if (mixinClassName.contains("MouseWheelieCompatMixin") && !FabricLoader.getInstance().isModLoaded("mousewheelie")) { - return false; - } - if ((mixinClassName.contains("widget.RecipeGroupButtonMixin") || mixinClassName.contains("widget.RecipeBookWidgetMixin")) && (FabricLoader.getInstance().isModLoaded("cracker-util-recipe-book") || FabricLoader.getInstance().isModLoaded("dark-matter-recipe-book"))) { - LOGGER.warn("[RBIP] CrackerUtil Recipe Book is loaded, skipping {} application", strings[strings.length - 1]); - return false; - } - if (mixinClassName.contains("MouseWheelieCompatMixin")) { - LOGGER.warn("[RBIP] MouseWheelie is loaded, applying {}", strings[strings.length - 1]); - } - return true; - } - - @Override - public void acceptTargets(Set myTargets, Set otherTargets) { - - } - - @Override - public List getMixins() { - return null; - } - - @Override - public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - - } - - @Override - public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) { - if (mixinClassName.contains("groups.RecipeBookGroupMixin")) { - for (MethodNode method : targetClass.methods) { - if (Objects.equals(method.name, "rbip$extend")) { - method.access = (method.access & ~Opcodes.ACC_PRIVATE) | Opcodes.ACC_PUBLIC; - //bitwise the private away. - } - } - } - } -} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java index 18d07c1..1eea6f0 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/MouseWheelieCompatMixin.java @@ -2,15 +2,11 @@ package me.melontini.recipebookispain.mixin; import de.siphalor.mousewheelie.client.mixin.gui.other.MixinRecipeBookWidget; import de.siphalor.mousewheelie.client.util.ScrollAction; -import me.melontini.recipebookispain.access.RecipeBookWidgetAccess; -import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; +import net.minecraft.client.gui.screen.recipebook.RecipeBookResults; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Dynamic; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Pseudo; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -23,17 +19,26 @@ public abstract class MouseWheelieCompatMixin { @Nullable private RecipeGroupButtonWidget currentTab; + @Shadow @Final private RecipeBookResults recipesArea; + @SuppressWarnings("ReferenceToMixin") @Dynamic(mixin = MixinRecipeBookWidget.class) - @Inject(at = @At(value = "INVOKE", target = "net/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget.setToggled (Z)V", ordinal = 1, shift = At.Shift.AFTER), method = "mouseWheelie_scrollRecipeBook") + @Inject(at = @At(value = "INVOKE", target = "net/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget.setToggled (Z)V", ordinal = 1, shift = At.Shift.AFTER), method = "mouseWheelie_scrollRecipeBook", require = 0) private void rbip$scrollPages(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { - RecipeBookWidget bookWidget = (RecipeBookWidget) (Object) this; - RecipeBookWidgetAccess widgetAccess = ((RecipeBookWidgetAccess) bookWidget); - RecipeGroupButtonAccess buttonAccess = ((RecipeGroupButtonAccess) this.currentTab); + if (this.currentTab == null) return;//how tho? + this.recipesArea.hideAlternates(); - assert buttonAccess != null; - if (widgetAccess.getPage() != buttonAccess.getPage()) { - widgetAccess.setPage(buttonAccess.getPage()); + RecipeBookWidget bookWidget = (RecipeBookWidget) (Object) this; + if (bookWidget.dm$getPage() != currentTab.dm$getPage()) { + bookWidget.dm$setPage(currentTab.dm$getPage()); } } + + @SuppressWarnings("ReferenceToMixin") + @Dynamic(mixin = MixinRecipeBookWidget.class) + @Inject(at = @At(value = "INVOKE", target = "de/siphalor/mousewheelie/client/util/accessors/IRecipeBookResults.mouseWheelie_refreshResultButtons ()V", shift = At.Shift.BEFORE), method = "mouseWheelie_scrollRecipeBook", require = 0) + private void rbip$hideAlternatives(double mouseX, double mouseY, double scrollAmount, CallbackInfoReturnable cir) { + this.recipesArea.hideAlternates(); + } + } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeBookWidgetMixin.java deleted file mode 100644 index 634bcf3..0000000 --- a/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeBookWidgetMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.melontini.recipebookispain.mixin.cracker_compat; - -import me.melontini.recipebookispain.access.RecipeBookWidgetAccess; -import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(RecipeBookWidget.class) //What's this? an empty mixin to ensure that RecipeBookWidgetAccess is always implemented -public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { -} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeGroupButtonMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeGroupButtonMixin.java deleted file mode 100644 index 3e6f57c..0000000 --- a/src/main/java/me/melontini/recipebookispain/mixin/cracker_compat/RecipeGroupButtonMixin.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.melontini.recipebookispain.mixin.cracker_compat; - -import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; -import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; -import org.spongepowered.asm.mixin.Mixin; - -@Mixin(RecipeGroupButtonWidget.class) //What's this? an empty mixin to ensure that RecipeGroupButtonAccess is always implemented -public class RecipeGroupButtonMixin implements RecipeGroupButtonAccess { -} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java index 507383a..82df21d 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java @@ -1,13 +1,14 @@ package me.melontini.recipebookispain.mixin.groups; +import me.melontini.dark_matter.api.recipe_book.RecipeBookHelper; import me.melontini.recipebookispain.RecipeBookIsPainClient; -import me.melontini.recipebookispain.util.EnumUtils; import net.minecraft.client.recipebook.ClientRecipeBook; import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.recipe.Recipe; import net.minecraft.recipe.RecipeType; +import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -30,28 +31,14 @@ public class ClientRecipeBookMixin { Arrays.stream(ItemGroup.GROUPS).filter(itemGroup -> itemGroup != ItemGroup.HOTBAR && itemGroup != ItemGroup.INVENTORY && itemGroup != ItemGroup.SEARCH) .forEach(itemGroup -> { try { - String name = "P_CRAFTING_" + itemGroup.getIndex(); - RecipeBookGroup recipeBookGroup = EnumUtils.callRecipeBookEnumInvoker(name, itemGroup.getIcon()); + RecipeBookGroup recipeBookGroup = RecipeBookHelper.createGroup(new Identifier("rbip", "crafting_" + itemGroup.getIndex()), itemGroup.getIcon()); RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.put(recipeBookGroup, itemGroup); RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.put(itemGroup, recipeBookGroup); CRAFTING_LIST.add(recipeBookGroup); CRAFTING_SEARCH_LIST.add(recipeBookGroup); } catch (Exception e) { - String info; - try { - info = String.format("%s item group", itemGroup.getName()); - } catch (Throwable t) { - try { - info = String.format("%s item group", itemGroup.getDisplayName().asString()); - } catch (Throwable t1) { - try { - info = String.format("item group with %s icon", itemGroup.getIcon().toString()); - } catch (Throwable t2) { - info = "item group"; - } - } - } + String info = String.format("%s item group", itemGroup.getName()); RecipeBookIsPainClient.LOGGER.error(String.format("Error while processing %s", info), e); } }); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/groups/RecipeBookGroupMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/groups/RecipeBookGroupMixin.java index 560ee29..5545bf1 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/groups/RecipeBookGroupMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/groups/RecipeBookGroupMixin.java @@ -1,63 +1,24 @@ package me.melontini.recipebookispain.mixin.groups; -import me.melontini.recipebookispain.util.EnumUtils; import net.minecraft.client.recipebook.RecipeBookGroup; -import net.minecraft.item.ItemStack; import net.minecraft.recipe.book.RecipeBookCategory; -import org.apache.commons.lang3.ArrayUtils; -import org.spongepowered.asm.mixin.*; -import org.spongepowered.asm.mixin.gen.Invoker; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import static me.melontini.recipebookispain.RecipeBookIsPainClient.CRAFTING_LIST; @Mixin(RecipeBookGroup.class) @Unique public class RecipeBookGroupMixin { - //me when I can't use Fabric ASM - - @Invoker("") - static RecipeBookGroup newGroup(String internalName, int internalId, ItemStack... stacks) { - throw new IllegalStateException(); - } - - @Shadow - @Final - @Mutable - private static RecipeBookGroup[] field_1805; - - - @Shadow - @Final - @Mutable - public static Map> SEARCH_MAP; - - @Unique - private static RecipeBookGroup rbip$extend(String internalName, ItemStack... stacks) { - RecipeBookGroup last = field_1805[field_1805.length - 1]; - RecipeBookGroup enumConst = newGroup(internalName, last.ordinal() + 1, stacks); - field_1805 = ArrayUtils.add(field_1805, enumConst); - EnumUtils.clearEnumCache(RecipeBookGroup.class); - return enumConst; - } @Inject(at = @At("HEAD"), method = "getGroups", cancellable = true) private static void rbip$getGroups(RecipeBookCategory category, CallbackInfoReturnable> cir) { if (category == RecipeBookCategory.CRAFTING) cir.setReturnValue(CRAFTING_LIST); } - @Inject(at = @At("TAIL"), method = "") - private static void rbip$makeMutable(CallbackInfo ci) { - Map> groupListMap = new HashMap<>(); - SEARCH_MAP.forEach((group, groups) -> groupListMap.put(group, new ArrayList<>(groups))); - SEARCH_MAP = groupListMap; - } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java index 0dcd9c5..934ab9a 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java @@ -4,6 +4,7 @@ import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; +import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.item.ItemGroup; import net.minecraft.text.Text; @@ -26,7 +27,7 @@ public class RecipeBookTooltipMixin { private void rbip$renderTooltip(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { if (client.currentScreen != null) { this.tabButtons.stream().filter(widget -> widget.visible && widget.isHovered()).forEach(widget -> { - if (widget.getCategory().name().contains("_SEARCH")) { + if (RecipeBookGroup.SEARCH_MAP.containsKey(widget.getCategory())) { client.currentScreen.renderTooltip(matrices, ItemGroup.SEARCH.getDisplayName(), mouseX, mouseY); } else { if (RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.containsKey(widget.getCategory())) { diff --git a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookWidgetMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookWidgetMixin.java deleted file mode 100644 index 97ca44c..0000000 --- a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookWidgetMixin.java +++ /dev/null @@ -1,183 +0,0 @@ -package me.melontini.recipebookispain.mixin.widget; - -import me.melontini.recipebookispain.access.RecipeBookWidgetAccess; -import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; -import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; -import net.minecraft.client.gui.widget.ToggleButtonWidget; -import net.minecraft.client.recipebook.ClientRecipeBook; -import net.minecraft.client.recipebook.RecipeBookGroup; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.screen.AbstractRecipeScreenHandler; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.MathHelper; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.List; - -@Mixin(RecipeBookWidget.class) -public abstract class RecipeBookWidgetMixin implements RecipeBookWidgetAccess { - @Shadow - @Final - protected static Identifier TEXTURE; - @Shadow - protected MinecraftClient client; - @Shadow - protected AbstractRecipeScreenHandler craftingScreenHandler; - @Shadow - private int parentWidth; - @Shadow - private int parentHeight; - @Shadow - private int leftOffset; - @Shadow - @Final - private List tabButtons; - @Shadow - private ClientRecipeBook recipeBook; - @Unique - private int page = 0; - @Unique - private int pages; - @Unique - private ToggleButtonWidget nextPageButton; - @Unique - private ToggleButtonWidget prevPageButton; - @Shadow - private @Nullable RecipeGroupButtonWidget currentTab; - - @Shadow - public abstract boolean isOpen(); - - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/recipebook/RecipeGroupButtonWidget;setToggled(Z)V", shift = At.Shift.BEFORE), method = "reset") - private void rbip$reset(CallbackInfo ci) { - int a = (this.parentWidth - 147) / 2 - this.leftOffset; - int s = (this.parentHeight + 166) / 2; - this.nextPageButton = new ToggleButtonWidget(a + 14, s, 12, 17, false); - this.nextPageButton.setTextureUV(1, 208, 13, 18, TEXTURE); - this.prevPageButton = new ToggleButtonWidget(a - 35, s, 12, 17, true); - this.prevPageButton.setTextureUV(1, 208, 13, 18, TEXTURE); - this.page = 0; - } - - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V", shift = At.Shift.BEFORE), method = "render") - private void rbip$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { - rbip$renderPageText(matrices); - this.prevPageButton.render(matrices, mouseX, mouseY, delta); - this.nextPageButton.render(matrices, mouseX, mouseY, delta); - } - - @Unique - private void rbip$renderPageText(MatrixStack matrices) { - int x = (this.parentWidth - 135) / 2 - this.leftOffset - 30; - int y = (this.parentHeight + 169) / 2 + 3; - int displayPage = this.page + 1; - int displayPages = this.pages; - if (this.pages > 1) { - String string = "" + displayPage + "/" + displayPages; - int textLength = this.client.textRenderer.getWidth(string); - this.client.textRenderer.draw(matrices, string, (x - textLength / 2F + 20F), y, -1); - } - } - - @Unique - @Override - public void updatePages() { - for (RecipeGroupButtonWidget widget : this.tabButtons) { - if (((RecipeGroupButtonAccess)widget).getPage() == this.page) { - RecipeBookGroup recipeBookGroup = widget.getCategory(); - if (recipeBookGroup.name().contains("_SEARCH")) { - widget.visible = true; - } else if (widget.hasKnownRecipes(recipeBook)) { - widget.visible = true; - widget.checkForNewRecipes(this.client); - } - } else { - widget.visible = false; - } - } - } - - @Inject(at = @At("HEAD"), method = "mouseClicked", cancellable = true) - private void rbip$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { - if (this.client.player != null) if (this.isOpen() && !this.client.player.isSpectator()) { - if (this.nextPageButton.mouseClicked(mouseX, mouseY, button)) { - if (this.page < (this.pages - 1)) setPage(++this.page); - cir.setReturnValue(true); - } else if (this.prevPageButton.mouseClicked(mouseX, mouseY, button)) { - if (this.page > 0) setPage(--this.page); - cir.setReturnValue(true); - } - } - } - - @Unique - @Override - public void updatePageSwitchButtons() { - if (this.nextPageButton != null) this.nextPageButton.visible = this.pages > 1 && this.page < (this.pages - 1); - if (this.prevPageButton != null) this.prevPageButton.visible = this.pages > 1 && this.page != 0; - } - - @Inject(at = @At("HEAD"), method = "refreshTabButtons", cancellable = true) - private void rbip$refresh(CallbackInfo ci) { - this.pages = 0; - int wc = 0; - int x = (this.parentWidth - 147) / 2 - this.leftOffset - 30; - int y = (this.parentHeight - 166) / 2 + 3; - int index = 0; - - this.tabButtons.clear(); - this.tabButtons.addAll(RecipeBookGroup.getGroups(this.craftingScreenHandler.getCategory()) - .stream().map(RecipeGroupButtonWidget::new) - .filter(widget -> widget.getCategory().name().contains("_SEARCH") || widget.hasKnownRecipes(this.recipeBook)) - .toList()); - this.currentTab = this.currentTab == null ? this.tabButtons.get(0) : this.tabButtons.stream() - .filter(button -> button.getCategory().equals(this.currentTab.getCategory())) - .findFirst().orElse(null); - this.currentTab.setToggled(true); - - for (RecipeGroupButtonWidget widget : this.tabButtons) { - ((RecipeGroupButtonAccess)widget).setPage(MathHelper.fastFloor(wc / 6f)); - widget.setPos(x, y + 27 * index++); - if (index == 6) index = 0; - wc++; - } - - this.pages = (int) Math.ceil(wc / 6f); - updatePages(); - updatePageSwitchButtons(); - ci.cancel(); - } - - @Unique - @Override - public int getPage() { - return this.page; - } - - @Unique - @Override - public void setPage(int page) { - if (page < 0) page = 0; - if (page > pages - 1) page = pages - 1; - - this.page = page; - updatePages(); - updatePageSwitchButtons(); - } - - @Unique - @Override - public int getPageCount() { - return this.pages; - } -} diff --git a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java index aca87e3..aae6649 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java @@ -1,22 +1,62 @@ package me.melontini.recipebookispain.mixin.widget; -import me.melontini.recipebookispain.access.RecipeGroupButtonAccess; +import me.melontini.recipebookispain.RecipeBookIsPainClient; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; +import net.minecraft.client.gui.widget.ToggleButtonWidget; +import net.minecraft.client.recipebook.RecipeBookGroup; +import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.ItemGroup; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(RecipeGroupButtonWidget.class) -public class RecipeGroupButtonMixin implements RecipeGroupButtonAccess { - @Unique - private int page = -1; +public abstract class RecipeGroupButtonMixin extends ToggleButtonWidget { + @Shadow + @Final + private RecipeBookGroup category; + @Shadow + private float bounce; - @Override - public int getPage() { - return page; + public RecipeGroupButtonMixin(int x, int y, int width, int height, boolean toggled) { + super(x, y, width, height, toggled); } - @Override - public void setPage(int page) { - this.page = page; + @Inject(at = @At("HEAD"), method = "renderIcons", cancellable = true) + private void rbip$render(ItemRenderer itemRenderer, CallbackInfo ci) { + ItemGroup group = RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.get(this.category); + if (group == null) return; + + int i = this.toggled ? -2 : 0; + MatrixStack matrices = new MatrixStack(); + + if (this.bounce > 0.0F) { + float f = 1.0F + 0.1F * (float) Math.sin(this.bounce / 15.0F * (float) Math.PI); + matrices.push(); + matrices.translate((float) (this.x + 8), (float) (this.y + 12), 0.0F); + matrices.scale(1.0F, f, 1.0F); + matrices.translate((float) (-(this.x + 8)), (float) (-(this.y + 12)), 0.0F); + } + + /*if (RecipeBookIsPainClient.isOwOLoaded) { + if (RecipeBookIsPainClient.rbip$renderOwo(matrices, i, (RecipeGroupButtonWidget) (Object) this, group)) { + ci.cancel(); + return; + } + }*/ + + if (RecipeBookIsPainClient.isDarkMatterContentLoaded) { + if (RecipeBookIsPainClient.renderDarkMatter(matrices, i, (RecipeGroupButtonWidget) (Object) this, group)) { + ci.cancel(); + } + } + + if (this.bounce > 0.0F) { + matrices.pop(); + } } } diff --git a/src/main/java/me/melontini/recipebookispain/util/EnumUtils.java b/src/main/java/me/melontini/recipebookispain/util/EnumUtils.java deleted file mode 100644 index a552b6f..0000000 --- a/src/main/java/me/melontini/recipebookispain/util/EnumUtils.java +++ /dev/null @@ -1,62 +0,0 @@ -package me.melontini.recipebookispain.util; - -import me.melontini.recipebookispain.RecipeBookIsPainClient; -import net.minecraft.client.recipebook.RecipeBookGroup; -import net.minecraft.item.ItemStack; -import sun.misc.Unsafe; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; - -public class EnumUtils { - private static final Unsafe UNSAFE; - - static { - Unsafe unsafe; - try { - Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); - unsafeField.setAccessible(true); - unsafe = (Unsafe) unsafeField.get(null); - } catch (NoSuchFieldException | IllegalAccessException e) { - try { - Constructor constructor = Unsafe.class.getDeclaredConstructor(); - constructor.setAccessible(true); - unsafe = constructor.newInstance(); - } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | - IllegalAccessException ex) { - throw new RuntimeException("Couldn't access Unsafe", ex); - } - } - UNSAFE = unsafe; - } - - public static synchronized void clearEnumCache(Class> cls) { - try { - writeField(Class.class.getDeclaredField("enumConstants"), cls, null); - } catch (Exception e) { - RecipeBookIsPainClient.LOGGER.error("Couldn't clear enumConstants. This shouldn't really happen", e); - } - - try { - writeField(Class.class.getDeclaredField("enumConstantDirectory"), cls, null); - } catch (Exception e) { - RecipeBookIsPainClient.LOGGER.error("Couldn't clear enumConstantDirectory. This shouldn't really happen", e); - } - } - - @SuppressWarnings("unchecked") - public static > T callRecipeBookEnumInvoker(String internalName, ItemStack... params) { - try { - return (T) RecipeBookGroup.class.getMethod("rbip$extend", String.class, ItemStack[].class).invoke(RecipeBookGroup.class, internalName, params); - } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new RuntimeException(e); - } - } - - public static void writeField(Field field, Object o, Object value) { - long l = Modifier.isStatic(field.getModifiers()) ? UNSAFE.staticFieldOffset(field) : UNSAFE.objectFieldOffset(field); - UNSAFE.putObject(o, l, value); - } -} diff --git a/src/main/resources/recipe-book-is-pain.mixins.json b/src/main/resources/recipe-book-is-pain.mixins.json index f722f49..baf1f34 100644 --- a/src/main/resources/recipe-book-is-pain.mixins.json +++ b/src/main/resources/recipe-book-is-pain.mixins.json @@ -3,17 +3,13 @@ "minVersion": "0.8", "package": "me.melontini.recipebookispain.mixin", "compatibilityLevel": "JAVA_17", - "plugin": "me.melontini.recipebookispain.mixin.MixinConfigPlugin", "mixins": [ ], "client": [ "MouseWheelieCompatMixin", - "cracker_compat.RecipeBookWidgetMixin", - "cracker_compat.RecipeGroupButtonMixin", "groups.ClientRecipeBookMixin", "groups.RecipeBookGroupMixin", "widget.RecipeBookTooltipMixin", - "widget.RecipeBookWidgetMixin", "widget.RecipeGroupButtonMixin" ], "injectors": { -- 2.51.2 From c2860ca9b4514d2f04ea90c2675c81317d1195ce Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:32:35 +0700 Subject: [PATCH 45/47] 1.19.3 port --- .../RecipeBookIsPainClient.java | 2 +- .../mixin/groups/ClientRecipeBookMixin.java | 27 ++++++++++++++----- .../mixin/widget/RecipeBookTooltipMixin.java | 4 +-- .../mixin/widget/RecipeGroupButtonMixin.java | 8 +++--- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java index e36f540..9a2fd29 100644 --- a/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java +++ b/src/main/java/me/melontini/recipebookispain/RecipeBookIsPainClient.java @@ -46,7 +46,7 @@ public class RecipeBookIsPainClient implements ClientModInitializer { public static boolean renderDarkMatter(MatrixStack matrices, int i, RecipeGroupButtonWidget widget, ItemGroup group) { if (group.dm$shouldAnimateIcon()) { - group.dm$getIconAnimation().animateIcon(matrices, widget.x + 9 + i, widget.y + 5, widget.isToggled(), false); + group.dm$getIconAnimation().animateIcon(matrices, widget.getX() + 9 + i, widget.getY() + 5, widget.isToggled(), false); return true; } return false; diff --git a/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java index 82df21d..2a24076 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java @@ -2,12 +2,16 @@ package me.melontini.recipebookispain.mixin.groups; import me.melontini.dark_matter.api.recipe_book.RecipeBookHelper; import me.melontini.recipebookispain.RecipeBookIsPainClient; +import me.melontini.recipebookispain.access.ItemAccess; import net.minecraft.client.recipebook.ClientRecipeBook; import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemGroups; import net.minecraft.item.ItemStack; import net.minecraft.recipe.Recipe; import net.minecraft.recipe.RecipeType; +import net.minecraft.resource.featuretoggle.FeatureFlags; +import net.minecraft.resource.featuretoggle.FeatureSet; import net.minecraft.util.Identifier; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -16,7 +20,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.ArrayList; -import java.util.Arrays; import static me.melontini.recipebookispain.RecipeBookIsPainClient.CRAFTING_LIST; import static me.melontini.recipebookispain.RecipeBookIsPainClient.CRAFTING_SEARCH_LIST; @@ -25,24 +28,34 @@ import static me.melontini.recipebookispain.RecipeBookIsPainClient.CRAFTING_SEAR public class ClientRecipeBookMixin { @Inject(at = @At("HEAD"), method = "") private static void rbip$clinit(CallbackInfo ci) { + ItemGroups.updateDisplayParameters(FeatureSet.of(FeatureFlags.BUNDLE, FeatureFlags.UPDATE_1_20, FeatureFlags.VANILLA), true); CRAFTING_SEARCH_LIST = new ArrayList<>(); CRAFTING_LIST = new ArrayList<>(); - Arrays.stream(ItemGroup.GROUPS).filter(itemGroup -> itemGroup != ItemGroup.HOTBAR && itemGroup != ItemGroup.INVENTORY && itemGroup != ItemGroup.SEARCH) + ItemGroups.getGroups().stream().filter(itemGroup -> itemGroup.getType() != ItemGroup.Type.INVENTORY && itemGroup.getType() != ItemGroup.Type.HOTBAR && itemGroup.getType() != ItemGroup.Type.SEARCH) + .forEach(group -> group.getSearchTabStacks().forEach(stack -> { + if (((ItemAccess) stack.getItem()).rbip$getPossibleGroup() == ItemGroups.getDefaultTab()) { + ((ItemAccess) stack.getItem()).rbip$setPossibleGroup(group); + } + })); + + ItemGroups.getGroups().stream().filter(itemGroup -> itemGroup.getType() != ItemGroup.Type.HOTBAR && itemGroup.getType() != ItemGroup.Type.INVENTORY && itemGroup.getType() != ItemGroup.Type.SEARCH) .forEach(itemGroup -> { try { - RecipeBookGroup recipeBookGroup = RecipeBookHelper.createGroup(new Identifier("rbip", "crafting_" + itemGroup.getIndex()), itemGroup.getIcon()); + RecipeBookGroup recipeBookGroup = RecipeBookHelper.createGroup(new Identifier("rbip", "crafting_" + ItemGroups.getGroups().indexOf(itemGroup)), itemGroup.getIcon()); RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.put(recipeBookGroup, itemGroup); RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.put(itemGroup, recipeBookGroup); CRAFTING_LIST.add(recipeBookGroup); CRAFTING_SEARCH_LIST.add(recipeBookGroup); } catch (Exception e) { - String info = String.format("%s item group", itemGroup.getName()); + String info = String.format("%s item group", itemGroup.getDisplayName()); RecipeBookIsPainClient.LOGGER.error(String.format("Error while processing %s", info), e); } }); CRAFTING_LIST.add(0, RecipeBookGroup.CRAFTING_SEARCH); + CRAFTING_LIST.add(RecipeBookGroup.CRAFTING_MISC); + CRAFTING_SEARCH_LIST.add(RecipeBookGroup.CRAFTING_MISC); RecipeBookGroup.SEARCH_MAP.get(RecipeBookGroup.CRAFTING_SEARCH).clear(); RecipeBookGroup.SEARCH_MAP.get(RecipeBookGroup.CRAFTING_SEARCH).addAll(CRAFTING_SEARCH_LIST); @@ -54,16 +67,16 @@ public class ClientRecipeBookMixin { RecipeType recipeType = recipe.getType(); if (recipeType == RecipeType.CRAFTING) { ItemStack itemStack = recipe.getOutput(); - ItemGroup group = itemStack.getItem().getGroup(); + ItemGroup group = ((ItemAccess) itemStack.getItem()).rbip$getPossibleGroup(); if (group != null) { - if (group != ItemGroup.HOTBAR && group != ItemGroup.INVENTORY && group != ItemGroup.SEARCH) { + if (group.getType() != ItemGroup.Type.INVENTORY && group.getType() != ItemGroup.Type.HOTBAR && group.getType() != ItemGroup.Type.SEARCH) { if (RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.containsKey(group)) { cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(group)); return; } } } - cir.setReturnValue(RecipeBookIsPainClient.ITEM_GROUP_TO_RECIPE_BOOK_GROUP.get(ItemGroup.MISC)); + cir.setReturnValue(RecipeBookGroup.CRAFTING_MISC); } } } diff --git a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java index 934ab9a..2d83136 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeBookTooltipMixin.java @@ -6,7 +6,7 @@ import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; import net.minecraft.client.gui.screen.recipebook.RecipeGroupButtonWidget; import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemGroups; import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -28,7 +28,7 @@ public class RecipeBookTooltipMixin { if (client.currentScreen != null) { this.tabButtons.stream().filter(widget -> widget.visible && widget.isHovered()).forEach(widget -> { if (RecipeBookGroup.SEARCH_MAP.containsKey(widget.getCategory())) { - client.currentScreen.renderTooltip(matrices, ItemGroup.SEARCH.getDisplayName(), mouseX, mouseY); + client.currentScreen.renderTooltip(matrices, ItemGroups.getSearchGroup().getDisplayName(), mouseX, mouseY); } else { if (RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.containsKey(widget.getCategory())) { Text text = RecipeBookIsPainClient.RECIPE_BOOK_GROUP_TO_ITEM_GROUP.get(widget.getCategory()).getDisplayName(); diff --git a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java index aae6649..46a1652 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java @@ -37,17 +37,17 @@ public abstract class RecipeGroupButtonMixin extends ToggleButtonWidget { if (this.bounce > 0.0F) { float f = 1.0F + 0.1F * (float) Math.sin(this.bounce / 15.0F * (float) Math.PI); matrices.push(); - matrices.translate((float) (this.x + 8), (float) (this.y + 12), 0.0F); + matrices.translate((float) (this.getX() + 8), (float) (this.getY() + 12), 0.0F); matrices.scale(1.0F, f, 1.0F); - matrices.translate((float) (-(this.x + 8)), (float) (-(this.y + 12)), 0.0F); + matrices.translate((float) (-(this.getX() + 8)), (float) (-(this.getY() + 12)), 0.0F); } - /*if (RecipeBookIsPainClient.isOwOLoaded) { + if (RecipeBookIsPainClient.isOwOLoaded) { if (RecipeBookIsPainClient.rbip$renderOwo(matrices, i, (RecipeGroupButtonWidget) (Object) this, group)) { ci.cancel(); return; } - }*/ + } if (RecipeBookIsPainClient.isDarkMatterContentLoaded) { if (RecipeBookIsPainClient.renderDarkMatter(matrices, i, (RecipeGroupButtonWidget) (Object) this, group)) { -- 2.51.2 From 24a4c40fd139e27734a3199d103cf2462da3767e Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:50:47 +0700 Subject: [PATCH 46/47] missed this field --- .../recipebookispain/mixin/widget/RecipeGroupButtonMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java index 16cc277..8a3912d 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/widget/RecipeGroupButtonMixin.java @@ -37,7 +37,7 @@ public abstract class RecipeGroupButtonMixin extends ToggleButtonWidget { return; } } - if (RecipeBookIsPainClient.isCrackerContentLoaded) { + if (RecipeBookIsPainClient.isDarkMatterContentLoaded) { if (RecipeBookIsPainClient.renderDarkMatter(matrices, i, (RecipeGroupButtonWidget) (Object) this, group)) { ci.cancel(); } -- 2.51.2 From 1153cab94009bdd3be29729c8216242c2a9e8c6a Mon Sep 17 00:00:00 2001 From: melontini <104443436+melontini@users.noreply.github.com> Date: Mon, 14 Aug 2023 20:59:53 +0700 Subject: [PATCH 47/47] 1.19.4 --- .../recipebookispain/mixin/groups/ClientRecipeBookMixin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java b/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java index e3b80f6..94abc51 100644 --- a/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java +++ b/src/main/java/me/melontini/recipebookispain/mixin/groups/ClientRecipeBookMixin.java @@ -28,9 +28,10 @@ import static me.melontini.recipebookispain.RecipeBookIsPainClient.CRAFTING_SEAR @Mixin(value = ClientRecipeBook.class, priority = 999) public class ClientRecipeBookMixin { - private static final CombinedDynamicRegistries RBIP$THANKS = ClientDynamicRegistryType.createCombinedDynamicRegistries(); + private static CombinedDynamicRegistries RBIP$THANKS ; @Inject(at = @At("HEAD"), method = "") private static void rbip$clinit(CallbackInfo ci) { + RBIP$THANKS = ClientDynamicRegistryType.createCombinedDynamicRegistries(); ItemGroups.updateDisplayContext(FeatureSet.of(FeatureFlags.BUNDLE, FeatureFlags.UPDATE_1_20, FeatureFlags.VANILLA), true, RBIP$THANKS.getCombinedRegistryManager()); CRAFTING_SEARCH_LIST = new ArrayList<>(); CRAFTING_LIST = new ArrayList<>(); -- 2.51.2