From 59a8e5c04ee1dff19bc55a21dbe0a21498ca4aee Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 10 Sep 2022 13:13:17 +0200 Subject: [PATCH 01/44] Move forge resource loading to client package --- .../dev/kosmx/playerAnim/impl/forge/ForgeClientEvent.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/minecraft/forge/src/main/java/dev/kosmx/playerAnim/impl/forge/ForgeClientEvent.java b/minecraft/forge/src/main/java/dev/kosmx/playerAnim/impl/forge/ForgeClientEvent.java index a030bbe..887e66e 100644 --- a/minecraft/forge/src/main/java/dev/kosmx/playerAnim/impl/forge/ForgeClientEvent.java +++ b/minecraft/forge/src/main/java/dev/kosmx/playerAnim/impl/forge/ForgeClientEvent.java @@ -18,14 +18,14 @@ public class ForgeClientEvent { public static void resourceLoadingListener(@NotNull RegisterClientReloadListenersEvent event) { event.registerReloadListener((ResourceManagerReloadListener) manager -> { PlayerAnimationRegistry.clearAnimation(); - for (var resource: manager.listResources("player_animation", location -> location.getPath().endsWith(".json")).entrySet()) { - try (var input = resource.getValue().open()) { + for (var resource: manager.listResources("player_animation", location -> location.endsWith(".json"))) { + try (var input = manager.getResource(resource).getInputStream()) { //Deserialize the animation json. GeckoLib animation json can contain multiple animations. for (var animation : AnimationSerializing.deserializeAnimation(input)) { //Save the animation for later use. - PlayerAnimationRegistry.addAnimation(new ResourceLocation(resource.getKey().getNamespace(), PlayerAnimationRegistry.serializeTextToString((String) animation.extraData.get("name"))), animation); + PlayerAnimationRegistry.addAnimation(new ResourceLocation(resource.getNamespace(), PlayerAnimationRegistry.serializeTextToString((String) animation.extraData.get("name"))), animation); } } catch(IOException e) { throw new RuntimeException(e);//Somehow handle invalid animations From 309f129e68a10fd9f9175d2eea9a58f9af084c11 Mon Sep 17 00:00:00 2001 From: KosmX Date: Tue, 13 Sep 2022 20:36:45 +0200 Subject: [PATCH 02/44] 1.18 port --- .../playerAnim/minecraftApi/PlayerAnimationRegistry.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/minecraftApi/PlayerAnimationRegistry.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/minecraftApi/PlayerAnimationRegistry.java index 802439f..5ebbb08 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/minecraftApi/PlayerAnimationRegistry.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/minecraftApi/PlayerAnimationRegistry.java @@ -88,17 +88,17 @@ public static Map getModAnimations(String modid) { @ApiStatus.Internal public static void resourceLoaderCallback(@NotNull ResourceManager manager, Logger logger) { animations.clear(); - for (var resource: manager.listResources("player_animation", location -> location.getPath().endsWith(".json")).entrySet()) { - try (var input = resource.getValue().open()) { + for (var resource: manager.listResources("player_animation", location -> location.endsWith(".json"))) { + try (var input = manager.getResource(resource).getInputStream()) { //Deserialize the animation json. GeckoLib animation json can contain multiple animations. for (var animation : AnimationSerializing.deserializeAnimation(input)) { //Save the animation for later use. - animations.put(new ResourceLocation(resource.getKey().getNamespace(), PlayerAnimationRegistry.serializeTextToString((String) animation.extraData.get("name")).toLowerCase(Locale.ROOT)), animation); + animations.put(new ResourceLocation(resource.getNamespace(), PlayerAnimationRegistry.serializeTextToString((String) animation.extraData.get("name")).toLowerCase(Locale.ROOT)), animation); } } catch(IOException e) { - logger.error("Error while loading payer animation: " + resource.getKey()); + logger.error("Error while loading payer animation: " + resource); logger.error(e.getMessage()); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); From a6b67b0be29350267f73dbe3c9de9e091aa4532a Mon Sep 17 00:00:00 2001 From: KosmX Date: Wed, 16 Nov 2022 21:30:02 +0100 Subject: [PATCH 03/44] remove 1.19 testing dependencies --- minecraft/fabric/build.gradle | 2 +- minecraft/forge/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/minecraft/fabric/build.gradle b/minecraft/fabric/build.gradle index 372ff62..2a8fe17 100644 --- a/minecraft/fabric/build.gradle +++ b/minecraft/fabric/build.gradle @@ -53,7 +53,7 @@ dependencies { common(shadowCommon(project(path: ":coreLib")) {transitive false}) {transitive false} //Why can I nest these? //Testing libraries - //* + /* modLocalRuntime "io.github.kosmx.bendy-lib:bendy-lib-fabric:${project.bendy_lib}" modLocalRuntime "maven.modrinth:3dskinlayers:1.5.2-fabric-1.19" modLocalRuntime "maven.modrinth:emotecraft:2.2.6-SNAPSHOT-build.44-MC1.19.2-fabric" diff --git a/minecraft/forge/build.gradle b/minecraft/forge/build.gradle index af98ad8..a084e49 100644 --- a/minecraft/forge/build.gradle +++ b/minecraft/forge/build.gradle @@ -39,7 +39,7 @@ dependencies { common(shadowCommon(project(path: ":coreLib")) {transitive false}) {transitive false} //Why can I nest these? //Testing libraries - //* + /* modLocalRuntime "io.github.kosmx.bendy-lib:bendy-lib-forge:${project.bendy_lib}" modLocalRuntime "maven.modrinth:3dskinlayers:1.5.2-forge-1.19" modLocalRuntime "maven.modrinth:emotecraft:2.2.6-SNAPSHOT-build.44-MC1.19.2-forge" From b2e33d07e024865b0ff9e48e01266a51598451c4 Mon Sep 17 00:00:00 2001 From: KosmX Date: Tue, 6 Dec 2022 15:44:38 +0100 Subject: [PATCH 04/44] internal refactor --- .../api/layered/KeyframeAnimationPlayer.java | 2 +- .../modifier/AbstractFadeModifier.java | 4 +- .../dev/kosmx/playerAnim/core/util/Ease.java | 44 +++++++--- .../kosmx/playerAnim/core/util/Easing.java | 85 +++---------------- 4 files changed, 45 insertions(+), 90 deletions(-) diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java index 48e6953..0b63d7f 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java @@ -311,7 +311,7 @@ protected final float getValueFromKeyframes(KeyframeAnimation.KeyFrame before, K } if (tickBefore == tickAfter) return before.value; float f = (currentTick + tickDelta - (float) tickBefore) / (tickAfter - tickBefore); - return MathHelper.lerp(Easing.easingFromEnum(data.isEasingBefore ? after.ease : before.ease, f), before.value, after.value); + return MathHelper.lerp((data.isEasingBefore ? after.ease : before.ease).invoke(f), before.value, after.value); } } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java index 9a7b803..8c9c556 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java @@ -3,10 +3,8 @@ import dev.kosmx.playerAnim.api.TransformType; import dev.kosmx.playerAnim.api.layered.IAnimation; import dev.kosmx.playerAnim.core.util.Ease; -import dev.kosmx.playerAnim.core.util.Easing; import dev.kosmx.playerAnim.core.util.Vec3f; import lombok.Setter; - import org.jetbrains.annotations.Nullable; /** @@ -89,7 +87,7 @@ public static AbstractFadeModifier standardFadeIn(int length, Ease ease) { return new AbstractFadeModifier(length) { @Override protected float getAlpha(String modelName, TransformType type, float progress) { - return Easing.easingFromEnum(ease, progress); + return ease.invoke(progress); } }; } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java index 0c40466..8efd652 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java @@ -5,33 +5,51 @@ * + constant + linear */ public enum Ease { - LINEAR(0), CONSTANT(1), - INSINE(6), OUTSINE(7), INOUTSINE(8), INCUBIC(9), OUTCUBIC(10), INOUTCUBIC(11), - INQUAD(12), OUTQUAD(13), INOUTQUAD(14), INQUART(15), OUTQUART(16), INOUTQUART(17), - INQUINT(18), OUTQUINT(19), INOUTQUINT(20), INEXPO(21), OUTEXPO(22), INOUTEXPO(23), - INCIRC(24), OUTCIRC(25), INOUTCIRC(26), INBACK(27), OUTBACK(28), INOUTBACK(29), - INELASTIC(30), OUTELASTIC(31), INOUTELASTIC(32), INBOUNCE(33), OUTBOUNCE(34), INOUTBOUNCE(35); + LINEAR(0, f -> f), CONSTANT(1, f -> 0f), + INSINE(6, Easing::inSine), OUTSINE(7, Easing::outSine), INOUTSINE(8, Easing::inOutSine), + INCUBIC(9, Easing::inCubic), OUTCUBIC(10, Easing::outCubic), INOUTCUBIC(11, Easing::inOutCubic), + INQUAD(12, Easing::inQuad), OUTQUAD(13, Easing::outQuad), INOUTQUAD(14, Easing::inOutQuad), + INQUART(15, Easing::inQuart), OUTQUART(16, Easing::outQuart), INOUTQUART(17, Easing::inOutQuart), + INQUINT(18, Easing::inQuint), OUTQUINT(19, Easing::outQuint), INOUTQUINT(20, Easing::inOutQuint), + INEXPO(21, Easing::inExpo), OUTEXPO(22, Easing::outExpo), INOUTEXPO(23, Easing::inOutExpo), + INCIRC(24, Easing::inCirc), OUTCIRC(25, Easing::outCirc), INOUTCIRC(26, Easing::inOutCirc), + INBACK(27, Easing::inBack), OUTBACK(28, Easing::outBack), INOUTBACK(29, Easing::inOutBack), + INELASTIC(30, Easing::inElastic), OUTELASTIC(31, Easing::outElastic), INOUTELASTIC(32, Easing::inOutElastic), + INBOUNCE(33, Easing::inBounce), OUTBOUNCE(34, Easing::outBack), INOUTBOUNCE(35, Easing::inOutBounce); final byte id; + private final _F impl; /** - * @param id id + * @param id id + * @param impl implementation */ - Ease(byte id){ + Ease(byte id, _F impl){ this.id = id; + this.impl = impl; } /** - * @param id id + * @param id id + * @param impl implementation */ - Ease(int id) { - this((byte) id); + Ease(int id, _F impl) { + this((byte) id, impl); } public byte getId() { return id; } + /** + * Run the easing + * @param f float between 0 and 1 + * @return ease(f) + */ + public float invoke(float f) { + return impl.invoke(f); + } + //To be able to send these as bytes instead of String names. public static Ease getEase(byte b){ for(Ease ease:Ease.values()){ @@ -39,4 +57,8 @@ public static Ease getEase(byte b){ } return LINEAR; } + + private interface _F { + float invoke(float f); + } } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java index 72f49bc..88851e9 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java @@ -1,86 +1,22 @@ package dev.kosmx.playerAnim.core.util; +import org.jetbrains.annotations.Nullable; + public class Easing { - /* + /** * Easing functions from easings.net * All function have a string codename * EasingFromString - * + *

* All function needs an input between 0 and 1 * except + * @deprecated Just use {@link Ease#invoke(float)} */ - public static float easingFromEnum(Ease type, float f){ - switch(type){ - case INOUTSINE: - return inOutSine(f); - case INSINE: - return inSine(f); - case OUTSINE: - return outSine(f); - case INCUBIC: - return inCubic(f); - case OUTCUBIC: - return outCubic(f); - case LINEAR: - return f; - case INOUTCUBIC: - return inOutCubic(f); - case INQUAD: - return inQuad(f); - case INQUART: - return inQuart(f); - case OUTQUAD: - return outQuad(f); - case OUTQUART: - return outQuart(f); - case INOUTQUAD: - return inOutQuad(f); - case INOUTQUART: - return inOutQuart(f); - case INBACK: - return inBack(f); - case INCIRC: - return inCirc(f); - case INEXPO: - return inExpo(f); - case INQUINT: - return inQuint(f); - case OUTBACK: - return outBack(f); - case OUTCIRC: - return outCirc(f); - case OUTEXPO: - return outExpo(f); - case INBOUNCE: - return inBounce(f); - case OUTQUINT: - return outQuint(f); - case INELASTIC: - return inElastic(f); - case INOUTBACK: - return inOutBack(f); - case INOUTCIRC: - return inOutCirc(f); - case INOUTEXPO: - return inOutExpo(f); - case OUTBOUNCE: - return outBounce(f); - case INOUTQUINT: - return inOutQuint(f); - case OUTELASTIC: - return outElastic(f); - case INOUTBOUNCE: - return inOutBounce(f); - case INOUTELASTIC: - return inOutElastic(f); - case CONSTANT: - return 0; - default: - //CommonData.logger.warn("easing function unknown: " + type); - return f; - } + @Deprecated + public static float easingFromEnum(@Nullable Ease type, float f) { + return type != null ? type.invoke(f) : f; } /** @@ -90,11 +26,11 @@ public static float easingFromEnum(Ease type, float f){ public static Ease easeFromString(String string){ try{ if(string.equals("step"))return Ease.CONSTANT; - if(string.substring(0, 4).toUpperCase().equals("EASE")){ + if(string.substring(0, 4).equalsIgnoreCase("EASE")){ string = string.substring(4); } return Ease.valueOf(string.toUpperCase()); - }catch(Exception exception){ + } catch(Exception exception){ //Main.log(Level.ERROR, "Ease name unknown: \"" + string + "\" using linear", true); //Main.log(Level.WARN, exception.toString()); return Ease.LINEAR; @@ -195,7 +131,6 @@ public static float inOutCirc(float x){ } public static float inBack(float x){ - return c3 * x * x * x - c1 * x * x; } From fe2f8c2584948f540ccd40b7677072037320f88d Mon Sep 17 00:00:00 2001 From: KosmX Date: Wed, 14 Dec 2022 13:06:31 +0100 Subject: [PATCH 05/44] Update issue templates --- .github/ISSUE_TEMPLATE/api-bug-report.md | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/api-bug-report.md diff --git a/.github/ISSUE_TEMPLATE/api-bug-report.md b/.github/ISSUE_TEMPLATE/api-bug-report.md new file mode 100644 index 0000000..0be617d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/api-bug-report.md @@ -0,0 +1,36 @@ +--- +name: API bug report +about: Issue about the API (not the buildscript) +title: "[API]" +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. + +**Setup config (minecraft, modloader, libraries):** + - Minecraft version: [e.g. 1.19.3] + - Mod loader: [e.g. Fabric 0.14.11] + - PlayerAnimator Library version [e.g. 0.4.0+1.19.3] + - MC library version (e.g. Fabric API version) + +**Other mods (If you use other mods, please specify! it might be an incompatibility):** + +*Optional:* +** Used library methods, ideas (If you're a developer, what function is not working as expected)** +Add any other context about the problem here. From d31ed632c5f0196f1abdb381156854f782acf6f1 Mon Sep 17 00:00:00 2001 From: KosmX Date: Wed, 14 Dec 2022 13:25:08 +0100 Subject: [PATCH 06/44] Update issue templates --- .github/ISSUE_TEMPLATE/api-bug-report.md | 2 +- .github/ISSUE_TEMPLATE/buildscript-error.md | 33 +++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 +++++++++++++ .github/ISSUE_TEMPLATE/library-crash.md | 32 ++++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/buildscript-error.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/library-crash.md diff --git a/.github/ISSUE_TEMPLATE/api-bug-report.md b/.github/ISSUE_TEMPLATE/api-bug-report.md index 0be617d..426fa3f 100644 --- a/.github/ISSUE_TEMPLATE/api-bug-report.md +++ b/.github/ISSUE_TEMPLATE/api-bug-report.md @@ -3,7 +3,7 @@ name: API bug report about: Issue about the API (not the buildscript) title: "[API]" labels: bug -assignees: '' +assignees: KosmX --- diff --git a/.github/ISSUE_TEMPLATE/buildscript-error.md b/.github/ISSUE_TEMPLATE/buildscript-error.md new file mode 100644 index 0000000..76f4162 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/buildscript-error.md @@ -0,0 +1,33 @@ +--- +name: Buildscript error +about: Something is wrong with buildscript +title: '' +labels: build +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**Buildscript content or link to content (If you don't share your code, I cannot debug it):** +https://github.com/KosmX/fabricPlayerAnimatorExample/blob/1.19/build.gradle + +**To Reproduce** +Steps to reproduce the behavior: +1. Run `gradle runClient` +2. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Environment (please complete the following information):** + - OS: [e.g. Windows 11, Archlinux, Ubuntu 22.04] + - IDE [e.g. IntelliJ, Eclipse, vim+bash] + - Gradle version [e.g. 7.5.1] + - JDK version [e.g. 17.0.5 - Adoptium] + - gradle plugin [e.g. Fabric loom, ForgeGradle] (if I don't see it in your project) + - Minecraft, Loader: (Fabric 0.14.11+1.19.2) + +**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..11fc491 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +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. diff --git a/.github/ISSUE_TEMPLATE/library-crash.md b/.github/ISSUE_TEMPLATE/library-crash.md new file mode 100644 index 0000000..addee12 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/library-crash.md @@ -0,0 +1,32 @@ +--- +name: Library crash +about: User crash report +title: '' +labels: bug, library +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 + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Crash report (please copy the whole crash report!)** +``` +Minecraft 1.19.3 +... +``` + +**Logs (if you have logs from that run, please share it):** +``` +... +``` From 3027bb95e161bf641226ec74bfca22ca6c724dd8 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 21 Jan 2023 00:02:44 +0100 Subject: [PATCH 07/44] change 1.19 to 1.19.2 --- .../dev/kosmx/playerAnim/core/util/MathHelper.java | 5 +++++ gradle.properties | 10 +++++----- minecraft/fabric/build.gradle | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/MathHelper.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/MathHelper.java index 1d1a976..36401c1 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/MathHelper.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/MathHelper.java @@ -22,6 +22,11 @@ public static int colorHelper(int r, int g, int b, int a){ return ((a & 255) << 24) | ((r & 255) << 16) | ((g & 255) << 8) | (b & 255); //Sometimes minecraft uses ints as color... } + /** + * Clamp f to -Pi until Pi range + * @param f radians + * @return radians + */ public static float clampToRadian(float f){ final double a = Math.PI*2; double b = ((f + Math.PI)%a); diff --git a/gradle.properties b/gradle.properties index f93c840..bbda3f2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ -org.gradle.jvmargs=-Xmx2048M +org.gradle.jvmargs=-Xmx4G -minecraft_version=1.19 +minecraft_version=1.19.2 enabled_platforms=fabric,forge archives_base_name=player-animation-lib @@ -9,9 +9,9 @@ mod_version=0.4.0 maven_group=dev.kosmx.player-anim -fabric_loader_version=0.14.9 -fabric_api_version=0.58.0+1.19 +fabric_loader_version=0.14.12 +fabric_api_version=0.73.0+1.19.2 -forge_version=1.19-41.1.0 +forge_version=1.19.2-43.2.3 bendy_lib=2.1.3-test2 diff --git a/minecraft/fabric/build.gradle b/minecraft/fabric/build.gradle index 84c083f..a8db268 100644 --- a/minecraft/fabric/build.gradle +++ b/minecraft/fabric/build.gradle @@ -57,7 +57,7 @@ dependencies { modLocalRuntime "io.github.kosmx.bendy-lib:bendy-lib-fabric:${project.bendy_lib}" modLocalRuntime "maven.modrinth:3dskinlayers:1.5.2-fabric-1.19" modLocalRuntime "maven.modrinth:emotecraft:2.2.6-SNAPSHOT-build.44-MC1.19.2-fabric" - modLocalRuntime "maven.modrinth:modmenu:4.0.4" + modLocalRuntime "maven.modrinth:modmenu:4.1.2" modLocalRuntime "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" //*/ From 2769dca3a48c6c089c94f32cb80758cf829a24ee Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 21 Jan 2023 00:56:22 +0100 Subject: [PATCH 08/44] Now with clamp guards(tm) - fix neck twist bug in multiplayer --- .../kosmx/playerAnim/impl/animation/AnimationApplier.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/AnimationApplier.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/AnimationApplier.java index cd88f3f..90349be 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/AnimationApplier.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/AnimationApplier.java @@ -4,6 +4,7 @@ import dev.kosmx.playerAnim.api.TransformType; import dev.kosmx.playerAnim.api.layered.IAnimation; import dev.kosmx.playerAnim.core.impl.AnimationProcessor; +import dev.kosmx.playerAnim.core.util.MathHelper; import dev.kosmx.playerAnim.core.util.Pair; import dev.kosmx.playerAnim.core.util.Vec3f; import net.minecraft.client.model.geom.ModelPart; @@ -20,7 +21,10 @@ public void updatePart(String partName, ModelPart part) { part.x = pos.getX(); part.y = pos.getY(); part.z = pos.getZ(); - Vec3f rot = this.get3DTransform(partName, TransformType.ROTATION, new Vec3f(part.xRot, part.yRot, part.zRot)); + Vec3f rot = this.get3DTransform(partName, TransformType.ROTATION, new Vec3f( // clamp guards + MathHelper.clampToRadian(part.xRot), + MathHelper.clampToRadian(part.yRot), + MathHelper.clampToRadian(part.zRot))); part.setRotation(rot.getX(), rot.getY(), rot.getZ()); if (!partName.equals("head")) { if (partName.equals("torso")) { From 2ec13c10570758b5e686521e539f51fb7dba1813 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 21 Jan 2023 00:57:49 +0100 Subject: [PATCH 09/44] Now with clamp guards(tm) - fix neck twist bug in multiplayer --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index bbda3f2..cf090ee 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ enabled_platforms=fabric,forge archives_base_name=player-animation-lib #Major: API break, Minor: non-breaking but significant, Patch: minor bugfix/change + MC implementation fix -mod_version=0.4.0 +mod_version=0.4.2-test0 maven_group=dev.kosmx.player-anim From 22f192b9314fd2a8b7c42cc7156183bee00af6cb Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 21 Jan 2023 02:00:20 +0100 Subject: [PATCH 10/44] Update gradle.properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index cf090ee..90dd1a9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ enabled_platforms=fabric,forge archives_base_name=player-animation-lib #Major: API break, Minor: non-breaking but significant, Patch: minor bugfix/change + MC implementation fix -mod_version=0.4.2-test0 +mod_version=0.4.2 maven_group=dev.kosmx.player-anim From de152fc83d46abf9350f20dd14f71216399f46d2 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 21 Jan 2023 13:45:58 +0100 Subject: [PATCH 11/44] Set license in fabric.mod.json and forge mods.toml --- minecraft/fabric/src/main/resources/fabric.mod.json | 2 +- minecraft/forge/src/main/resources/META-INF/mods.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/minecraft/fabric/src/main/resources/fabric.mod.json b/minecraft/fabric/src/main/resources/fabric.mod.json index 91d3f46..d7e1b99 100644 --- a/minecraft/fabric/src/main/resources/fabric.mod.json +++ b/minecraft/fabric/src/main/resources/fabric.mod.json @@ -11,7 +11,7 @@ "homepage": "kosmx.dev", "sources": "https://github.com/KosmX/fabricPlayerAnimation" }, - "license": "Insert License Here", + "license": "MIT", "environment": "*", "entrypoints": { "client": ["dev.kosmx.playerAnim.fabric.client.FabricClientInitializer"] diff --git a/minecraft/forge/src/main/resources/META-INF/mods.toml b/minecraft/forge/src/main/resources/META-INF/mods.toml index e9ce1d6..fd7d6a5 100644 --- a/minecraft/forge/src/main/resources/META-INF/mods.toml +++ b/minecraft/forge/src/main/resources/META-INF/mods.toml @@ -1,7 +1,7 @@ modLoader = "javafml" loaderVersion = "[37.1.1,)" #issueTrackerURL = "" -license = "Insert License Here" +license = "MIT" [[mods]] modId = "playeranimator" From 719389dabd967d96c913961d9ece1c3fd1b7410e Mon Sep 17 00:00:00 2001 From: KosmX Date: Fri, 24 Feb 2023 23:41:55 +0100 Subject: [PATCH 12/44] Some proto first person animation stuff --- coreLib/build.gradle | 8 +-- .../dev/kosmx/playerAnim/api/AnimUtils.java | 5 +- .../firstPerson/FirstPersonConfiguration.java | 17 +++++ .../api/firstPerson/FirstPersonMode.java | 52 ++++++++++++++ .../api/layered/AnimationContainer.java | 26 +++++-- .../api/layered/AnimationStack.java | 26 ++++++- .../playerAnim/api/layered/IAnimation.java | 23 +++++- .../api/layered/KeyframeAnimationPlayer.java | 66 ++++++++++++++---- .../playerAnim/api/layered/ModifierLayer.java | 31 ++++++-- .../api/layered/PlayerAnimationFrame.java | 3 +- .../modifier/AbstractFadeModifier.java | 3 +- .../api/layered/modifier/MirrorModifier.java | 17 ++++- .../api/layered/modifier/SpeedModifier.java | 3 +- .../core/impl/AnimationProcessor.java | 15 ++++ .../kosmx/playerAnim/core/util/Easing.java | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 61574 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 18 +++-- gradlew.bat | 15 ++-- .../playerAnim/mixin/PlayerRendererMixin.java | 49 ++++++++++++- .../mixin/firstPerson/CameraAccessor.java | 11 +++ .../EntityRenderDispatcherMixin.java | 25 +++++++ .../firstPerson/ItemInHandRendererMixin.java | 52 ++++++++++++++ .../mixin/firstPerson/LevelRendererMixin.java | 53 ++++++++++++++ .../LivingEntityRendererMixin.java | 31 ++++++++ .../playerAnimator-common.mixins.json | 9 ++- .../animatorTestmod/PlayerAnimTestmod.java | 8 ++- 27 files changed, 518 insertions(+), 53 deletions(-) create mode 100644 coreLib/src/main/java/dev/kosmx/playerAnim/api/firstPerson/FirstPersonConfiguration.java create mode 100644 coreLib/src/main/java/dev/kosmx/playerAnim/api/firstPerson/FirstPersonMode.java create mode 100644 minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/CameraAccessor.java create mode 100644 minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/EntityRenderDispatcherMixin.java create mode 100644 minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java create mode 100644 minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java create mode 100644 minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LivingEntityRendererMixin.java diff --git a/coreLib/build.gradle b/coreLib/build.gradle index 256607a..9b233a9 100644 --- a/coreLib/build.gradle +++ b/coreLib/build.gradle @@ -12,11 +12,11 @@ dependencies { testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2' - compileOnly 'org.projectlombok:lombok:1.18.24' - annotationProcessor 'org.projectlombok:lombok:1.18.24' + compileOnly 'org.projectlombok:lombok:1.18.26' + annotationProcessor 'org.projectlombok:lombok:1.18.26' - testCompileOnly 'org.projectlombok:lombok:1.18.24' - testAnnotationProcessor 'org.projectlombok:lombok:1.18.24' + testCompileOnly 'org.projectlombok:lombok:1.18.26' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.26' compileOnly 'org.jetbrains:annotations:23.0.0' } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/AnimUtils.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/AnimUtils.java index 06167f5..4af8a44 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/AnimUtils.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/AnimUtils.java @@ -19,8 +19,9 @@ public static AnimationStack getPlayerAnimLayer(Object player) throws IllegalArg } /** - * Disable first person animation see-through. - * Has no effect if using mod like FirstPersonModel + * Unused, use proper first person library instead + * will be removed after next release (1.1) */ + @Deprecated public static boolean disableFirstPersonAnim = true; } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/firstPerson/FirstPersonConfiguration.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/firstPerson/FirstPersonConfiguration.java new file mode 100644 index 0000000..167307c --- /dev/null +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/firstPerson/FirstPersonConfiguration.java @@ -0,0 +1,17 @@ +package dev.kosmx.playerAnim.api.firstPerson; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +public class FirstPersonConfiguration { + boolean showRightArm = false; + boolean showLeftArm = false; + boolean showRightItem = true; + boolean showLeftItem = true; +} diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/firstPerson/FirstPersonMode.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/firstPerson/FirstPersonMode.java new file mode 100644 index 0000000..1894a0b --- /dev/null +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/firstPerson/FirstPersonMode.java @@ -0,0 +1,52 @@ +package dev.kosmx.playerAnim.api.firstPerson; + +import lombok.Getter; +import org.jetbrains.annotations.ApiStatus; + +public enum FirstPersonMode { + + /** + * The animation does not decide first person mode, this way, the animation will be transparent in first person mode. + */ + NONE(false), + /** + * Use the vanilla renderer, most of the time broken, if you use this, please check your animation + */ + VANILLA(true), + + /** + * Use the 3rd person player model (only arms/items) to render accurate first-person perspective + */ + THIRD_PERSON_MODEL(true), + + /** + * First person animation is DISABLED, vanilla idle will be active. + */ + DISABLED(false), + +; + @Getter + private final boolean enabled; + + + FirstPersonMode(boolean enabled) { + this.enabled = enabled; + } + + + + private static final ThreadLocal firstPersonPass = ThreadLocal.withInitial(() -> false); + + + /** + * @return is the current render pass a first person pass + */ + public static boolean isFirstPersonPass() { + return firstPersonPass.get(); + } + + @ApiStatus.Internal + public static void setFirstPersonPass(boolean newValue) { + firstPersonPass.set(newValue); + } +} diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationContainer.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationContainer.java index ec4dd53..db4dc6a 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationContainer.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationContainer.java @@ -1,19 +1,24 @@ package dev.kosmx.playerAnim.api.layered; import dev.kosmx.playerAnim.api.TransformType; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonConfiguration; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; import dev.kosmx.playerAnim.core.util.Vec3f; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * A container to make swapping animation object easier * It will clone the behaviour of the held animation - * + *

* you can put endless AnimationContainer into each other * @param Nullable animation */ public class AnimationContainer implements IAnimation { + @Nullable protected T anim; - public AnimationContainer(T anim) { + public AnimationContainer(@Nullable T anim) { this.anim = anim; } @@ -21,11 +26,11 @@ public AnimationContainer() { this.anim = null; } - public void setAnim(T newAnim) { + public void setAnim(@Nullable T newAnim) { this.anim = newAnim; } - public T getAnim() { + public @Nullable T getAnim() { return this.anim; } @@ -40,7 +45,7 @@ public void tick() { } @Override - public Vec3f get3DTransform(String modelName, TransformType type, float tickDelta, Vec3f value0) { + public @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0) { return anim == null ? value0 : anim.get3DTransform(modelName, type, tickDelta, value0); } @@ -48,4 +53,15 @@ public Vec3f get3DTransform(String modelName, TransformType type, float tickDelt public void setupAnim(float tickDelta) { if (this.anim != null) this.anim.setupAnim(tickDelta); } + + @Override + public @NotNull FirstPersonMode getFirstPersonMode(float tickDelta) { + return anim != null ? anim.getFirstPersonMode(tickDelta) : FirstPersonMode.NONE; + } + + // Override candidate + @Override + public @NotNull FirstPersonConfiguration getFirstPersonConfiguration(float tickDelta) { + return anim != null ? anim.getFirstPersonConfiguration(tickDelta) : IAnimation.super.getFirstPersonConfiguration(tickDelta); + } } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java index 9811768..8848f70 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java @@ -1,8 +1,11 @@ package dev.kosmx.playerAnim.api.layered; import dev.kosmx.playerAnim.api.TransformType; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonConfiguration; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; import dev.kosmx.playerAnim.core.util.Pair; import dev.kosmx.playerAnim.core.util.Vec3f; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -37,7 +40,7 @@ public void tick() { } @Override - public Vec3f get3DTransform(String modelName, TransformType type, float tickDelta, Vec3f value0) { + public @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0) { for (Pair layer : layers) { if (layer.getRight().isActive()) { value0 = layer.getRight().get3DTransform(modelName, type, tickDelta, value0); @@ -88,4 +91,25 @@ public boolean removeLayer(int layerLevel) { return layers.removeIf(integerIAnimationPair -> integerIAnimationPair.getLeft() == layerLevel); } + @Override + public @NotNull FirstPersonMode getFirstPersonMode(float tickDelta) { + for (Pair layer : layers) { + if (layer.getRight().isActive()) { // layer.right.requestFirstPersonMode(tickDelta).takeIf{ it != NONE }?.let{ return@requestFirstPersonMode it } + FirstPersonMode mode = layer.getRight().getFirstPersonMode(tickDelta); + if (mode != FirstPersonMode.NONE) return mode; + } + } + return FirstPersonMode.NONE; + } + + @Override + public @NotNull FirstPersonConfiguration getFirstPersonConfiguration(float tickDelta) { + for (Pair layer : layers) { + if (layer.getRight().isActive()) { // layer.right.requestFirstPersonMode(tickDelta).takeIf{ it != NONE }?.let{ return@requestFirstPersonMode it } + FirstPersonMode mode = layer.getRight().getFirstPersonMode(tickDelta); + if (mode != FirstPersonMode.NONE) layer.getRight().getFirstPersonConfiguration(tickDelta); + } + } + return IAnimation.super.getFirstPersonConfiguration(tickDelta); + } } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/IAnimation.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/IAnimation.java index e8d554e..dd1957d 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/IAnimation.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/IAnimation.java @@ -2,7 +2,10 @@ import dev.kosmx.playerAnim.api.TransformType; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonConfiguration; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; import dev.kosmx.playerAnim.core.util.Vec3f; +import org.jetbrains.annotations.NotNull; /** * An entry in {@link AnimationStack}, used to get the animated parts current transform @@ -30,7 +33,7 @@ default void tick(){} * @param value0 The value before the transform. For identity transform return with it. * @return The new transform value */ - Vec3f get3DTransform(String modelName, TransformType type, float tickDelta, Vec3f value0); + @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0); /** * Called before rendering a character @@ -38,4 +41,22 @@ default void tick(){} */ void setupAnim(float tickDelta); + /** + * Active animation can request first person render mode. + * @param tickDelta current tickDelta + * @return {@link FirstPersonMode} + */ + @NotNull + default FirstPersonMode getFirstPersonMode(float tickDelta) { + return FirstPersonMode.NONE; + } + + /** + * @param tickDelta + * @return current first person configuration, only requested when playing this animation + */ + @NotNull + default FirstPersonConfiguration getFirstPersonConfiguration(float tickDelta) { + return new FirstPersonConfiguration(); + } } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java index 0b63d7f..c898dc1 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java @@ -1,16 +1,33 @@ package dev.kosmx.playerAnim.api.layered; import dev.kosmx.playerAnim.api.TransformType; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonConfiguration; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; import dev.kosmx.playerAnim.core.data.KeyframeAnimation; import dev.kosmx.playerAnim.core.util.*; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; /** - * Animation player for EmoteX emote format, - * It does not mean, you can not use it, It means Emotecraft uses this too! + *

KeyframeAnimationPlayer

+ * If you're here, you're probably looking for this (except if you want to animate from code)
+ * It plays {@link KeyframeAnimation} + *

+ * {@code new KeyframeAnimationPlayer(animation)} + * + *


+ * New FirstPerson mode is supported with chainable setters :D
+ * + * new KeyframeAnimationPlayer(animation)
+ * .setFirstPersonConfiguration(new FirstPersonConfiguration())
+ * .setFirstPersonMode(FirstPersonMode.THIRD_PERSON_MODEL);
+ *
+ * */ @SuppressWarnings({"unused", "ConstantConditions"}) public class KeyframeAnimationPlayer implements IAnimation { @@ -27,19 +44,42 @@ public class KeyframeAnimationPlayer implements IAnimation { public final HashMap bodyParts; public int perspective = 0; + + @Setter + @Accessors(chain = true) + @NotNull + private FirstPersonConfiguration firstPersonConfiguration = new FirstPersonConfiguration(); + + + @Override + public @NotNull FirstPersonConfiguration getFirstPersonConfiguration(float tickDelta) { + return firstPersonConfiguration; + } + + @Setter + @Accessors(chain = true) + @NotNull + private FirstPersonMode firstPersonMode = FirstPersonMode.THIRD_PERSON_MODEL; + + + @Override + public @NotNull FirstPersonMode getFirstPersonMode(float tickDelta) { + return firstPersonMode; + } + /** * - * @param emote emote to play + * @param animation animation to play * @param t begin playing from tick * @param mutable if true, the part data will be copied as a construction step. * The copied version can be changed while playing the animation but the copy takes time. */ - public KeyframeAnimationPlayer(KeyframeAnimation emote, int t, boolean mutable) { - if (emote == null) throw new IllegalArgumentException("Animation can not be null"); - this.data = emote; + public KeyframeAnimationPlayer(@NotNull KeyframeAnimation animation, int t, boolean mutable) { + if (animation == null) throw new IllegalArgumentException("Animation can not be null"); + this.data = animation; - this.bodyParts = new HashMap<>(emote.getBodyParts().size()); - for(Map.Entry part:emote.getBodyParts().entrySet()){ + this.bodyParts = new HashMap<>(animation.getBodyParts().size()); + for(Map.Entry part:animation.getBodyParts().entrySet()){ this.bodyParts.put(part.getKey(), new BodyPart(mutable ? part.getValue().copy() : part.getValue())); } @@ -52,14 +92,14 @@ public KeyframeAnimationPlayer(KeyframeAnimation emote, int t, boolean mutable) /** * - * @param emote emote to play + * @param animation {@link KeyframeAnimation} to play * @param t begin playing from tick */ - public KeyframeAnimationPlayer(KeyframeAnimation emote, int t) { - this(emote, t, false); + public KeyframeAnimationPlayer(@NotNull KeyframeAnimation animation, int t) { + this(animation, t, false); } - public KeyframeAnimationPlayer(KeyframeAnimation animation) { + public KeyframeAnimationPlayer(@NotNull KeyframeAnimation animation) { this(animation, 0); } @@ -92,7 +132,7 @@ public boolean isActive() { } @Override - public Vec3f get3DTransform(String modelName, TransformType type, float tickDelta, Vec3f value0) { + public @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0) { BodyPart part = bodyParts.get(modelName); if (part == null) return value0; switch (type) { diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/ModifierLayer.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/ModifierLayer.java index 0ae6cae..2983ad2 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/ModifierLayer.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/ModifierLayer.java @@ -1,12 +1,15 @@ package dev.kosmx.playerAnim.api.layered; import dev.kosmx.playerAnim.api.TransformType; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonConfiguration; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; import dev.kosmx.playerAnim.api.layered.modifier.AbstractFadeModifier; import dev.kosmx.playerAnim.api.layered.modifier.AbstractModifier; import dev.kosmx.playerAnim.core.util.Ease; import dev.kosmx.playerAnim.core.util.Vec3f; import lombok.Getter; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; @@ -49,17 +52,17 @@ public void tick() { } else if (animation != null) animation.tick(); } - public void addModifier(AbstractModifier modifier, int idx) { + public void addModifier(@NotNull AbstractModifier modifier, int idx) { modifier.setHost(this); modifiers.add(idx, modifier); this.linkModifiers(); } - public void addModifierBefore(AbstractModifier modifier) { + public void addModifierBefore(@NotNull AbstractModifier modifier) { this.addModifier(modifier, 0); } - public void addModifierLast(AbstractModifier modifier) { + public void addModifierLast(@NotNull AbstractModifier modifier) { this.addModifier(modifier, modifiers.size()); } @@ -80,7 +83,7 @@ public void setAnimation(@Nullable T animation) { * @param fadeModifier Fade modifier, use {@link AbstractFadeModifier#standardFadeIn(int, Ease)} for simple fade. * @param newAnimation New animation, can be null to fade into default state. */ - public void replaceAnimationWithFade(AbstractFadeModifier fadeModifier, @Nullable T newAnimation) { + public void replaceAnimationWithFade(@NotNull AbstractFadeModifier fadeModifier, @Nullable T newAnimation) { replaceAnimationWithFade(fadeModifier, newAnimation, false); } @@ -90,7 +93,7 @@ public void replaceAnimationWithFade(AbstractFadeModifier fadeModifier, @Nullabl * @param newAnimation New animation, can be null to fade into default state. * @param fadeFromNothing Do fade even if we go from nothing. (for KeyframeAnimation, it can be false by default) */ - public void replaceAnimationWithFade(AbstractFadeModifier fadeModifier, @Nullable T newAnimation, boolean fadeFromNothing) { + public void replaceAnimationWithFade(@NotNull AbstractFadeModifier fadeModifier, @Nullable T newAnimation, boolean fadeFromNothing) { if (fadeFromNothing || getAnimation() != null && getAnimation().isActive()) { fadeModifier.setBeginAnimation(this.getAnimation()); addModifierLast(fadeModifier); @@ -125,7 +128,7 @@ public boolean isActive() { } @Override - public Vec3f get3DTransform(String modelName, TransformType type, float tickDelta, Vec3f value0) { + public @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0) { if (modifiers.size() > 0) { return modifiers.get(0).get3DTransform(modelName, type, tickDelta, value0); } else if (animation != null) return animation.get3DTransform(modelName, type, tickDelta, value0); @@ -138,4 +141,20 @@ public void setupAnim(float tickDelta) { modifiers.get(0).setupAnim(tickDelta); } else if (animation != null) animation.setupAnim(tickDelta); } + + @Override + public @NotNull FirstPersonMode getFirstPersonMode(float tickDelta) { + if (modifiers.size() > 0) { + return modifiers.get(0).getFirstPersonMode(tickDelta); + } else if (animation != null) return animation.getFirstPersonMode(tickDelta); + return IAnimation.super.getFirstPersonMode(tickDelta); + } + + @Override + public @NotNull FirstPersonConfiguration getFirstPersonConfiguration(float tickDelta) { + if (modifiers.size() > 0) { + return modifiers.get(0).getFirstPersonConfiguration(tickDelta); + } else if (animation != null) return animation.getFirstPersonConfiguration(tickDelta); + return IAnimation.super.getFirstPersonConfiguration(tickDelta); + } } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/PlayerAnimationFrame.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/PlayerAnimationFrame.java index 0f12516..1eabc36 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/PlayerAnimationFrame.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/PlayerAnimationFrame.java @@ -3,6 +3,7 @@ import dev.kosmx.playerAnim.api.TransformType; import dev.kosmx.playerAnim.core.util.Pair; import dev.kosmx.playerAnim.core.util.Vec3f; +import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Map; @@ -65,7 +66,7 @@ public void resetPose() { @Override - public Vec3f get3DTransform(String modelName, TransformType type, float tickDelta, Vec3f value0) { + public @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0) { PlayerPart part = parts.get(modelName); if (part == null) return value0; switch (type) { diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java index 8c9c556..c73a701 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java @@ -5,6 +5,7 @@ import dev.kosmx.playerAnim.core.util.Ease; import dev.kosmx.playerAnim.core.util.Vec3f; import lombok.Setter; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -53,7 +54,7 @@ public void tick() { } @Override - public Vec3f get3DTransform(String modelName, TransformType type, float tickDelta, Vec3f value0) { + public @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0) { if (calculateProgress(tickDelta) > 1) { return super.get3DTransform(modelName, type, tickDelta, value0); } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/MirrorModifier.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/MirrorModifier.java index c71d45a..3512243 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/MirrorModifier.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/MirrorModifier.java @@ -1,11 +1,13 @@ package dev.kosmx.playerAnim.api.layered.modifier; import dev.kosmx.playerAnim.api.TransformType; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonConfiguration; import dev.kosmx.playerAnim.core.util.Vec3f; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.jetbrains.annotations.NotNull; import java.util.Collections; import java.util.HashMap; @@ -25,7 +27,7 @@ public class MirrorModifier extends AbstractModifier { private boolean enabled = true; @Override - public Vec3f get3DTransform(String modelName, TransformType type, float tickDelta, Vec3f value0) { + public @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0) { if (!enabled) return super.get3DTransform(modelName, type, tickDelta, value0); if (mirrorMap.containsKey(modelName)) modelName = mirrorMap.get(modelName); @@ -35,6 +37,19 @@ public Vec3f get3DTransform(String modelName, TransformType type, float tickDelt return transformVector(vec3f, type); } + // Override candidate + @Override + public @NotNull FirstPersonConfiguration getFirstPersonConfiguration(float tickDelta) { + FirstPersonConfiguration configuration = super.getFirstPersonConfiguration(tickDelta); + if (enabled) { + return new FirstPersonConfiguration() + .setShowLeftArm(configuration.isShowRightArm()) + .setShowRightArm(configuration.isShowLeftArm()) + .setShowLeftItem(configuration.isShowRightItem()) + .setShowRightItem(configuration.isShowLeftItem()); + } else return configuration; + } + protected Vec3f transformVector(Vec3f value0, TransformType type) { switch (type) { case POSITION: diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/SpeedModifier.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/SpeedModifier.java index a6a2a83..4c4ea52 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/SpeedModifier.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/SpeedModifier.java @@ -3,6 +3,7 @@ import dev.kosmx.playerAnim.api.TransformType; import dev.kosmx.playerAnim.core.util.Vec3f; import lombok.NoArgsConstructor; +import org.jetbrains.annotations.NotNull; /** * Modifies the animation speed. @@ -49,7 +50,7 @@ protected void step(float delta) { } @Override - public Vec3f get3DTransform(String modelName, TransformType type, float tickDelta, Vec3f value0) { + public @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0) { return super.get3DTransform(modelName, type, shiftedDelta, value0); } } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/impl/AnimationProcessor.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/impl/AnimationProcessor.java index c77ba8f..4dee8a9 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/impl/AnimationProcessor.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/impl/AnimationProcessor.java @@ -2,10 +2,13 @@ import dev.kosmx.playerAnim.api.TransformType; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonConfiguration; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; import dev.kosmx.playerAnim.api.layered.IAnimation; import dev.kosmx.playerAnim.core.util.Pair; import dev.kosmx.playerAnim.core.util.Vec3f; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; /** * Tool to easily play animation to the player. @@ -37,6 +40,18 @@ public void setTickDelta(float tickDelta) { this.animation.setupAnim(tickDelta); } + public boolean isFirstPersonAnimationDisabled() { + return !animation.getFirstPersonMode(tickDelta).isEnabled(); + } + + public @NotNull FirstPersonMode getFirstPersonMode() { + return animation.getFirstPersonMode(tickDelta); + } + + public @NotNull FirstPersonConfiguration getFirstPersonConfiguration() { + return animation.getFirstPersonConfiguration(tickDelta); + } + public Pair getBend(String modelName) { Vec3f bendVec = this.get3DTransform(modelName, TransformType.BEND, Vec3f.ZERO); return new Pair<>(bendVec.getX(), bendVec.getY()); diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java index 88851e9..3051b59 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java @@ -11,7 +11,7 @@ public class Easing { * EasingFromString *

* All function needs an input between 0 and 1 - * except + * * @deprecated Just use {@link Ease#invoke(float)} */ @Deprecated diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927a4d4fb3f96a785543079b8df6723c946b..943f0cbfa754578e88a3dae77fce6e3dea56edbf 100644 GIT binary patch delta 36987 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 z zZ_Sdfsora*b1VWoWWGKpza6Tu`(EoW9@0X)?yl5>2p3WnwD1 z%*0fU2~`9k^J2681%u$N2+ySTZqQJYfUF=jkx&^|;z|w*vSQ|f^bT7OX(B=Ab7;?J zU8{9WM3^$~s_l}lXVB!Li$GY`O}%2BN#fS;Ax>nnftP5~E8&0&1ZIEE=opUTQo_|V z=cO52igb5SZPZhhpbTLF4KZMaR19i`rN!3I-wR28o5Ui=mq zpG)4f1s#k$+@y}6Kxim*1_d2c&(EqNYv1YBwsVi_V-QUr(R+8-1?2k#-Jd6p$UV3_ z5=P3eknuueT((aZzS1Rr=Q4UKa;lN}xWVi!_pM`G_p`8j#rGtA8b^tb4!A%F65A}J zY61HfInmmy+Ee~m0cP*~ofXGBet=;KnY(n!);Tim7Ce+L@PP6nS~*g%e1_PiR#I_h zV{9?Pj)nk}^xvd6%xJ%xqYp}|0-j*` zEb=K~?BxL~X|1KROv6%|EVm%|=ivjJ(^u-xZ;Hk3iu=!xAjy6upm34tOyE_KTA%5@ z{66%e5Jz`qR(!4SZDv@1;mb|UUOiDs_#_-<&VbS+G^XyQLiS$aUC0V zSb{%&X^~ORd9oBUB|AjUp2LQeY(E$RWsfS}w&cCD36@`R0!5E*p|=YDp}^qY^KxkF zE+mu(nW8nik5htkK^`_FxhAV6pOb0+4H}H=8U?@+fCEcKK~u2S6l}?*aZzW z*nZ&lBmVpQ;!xQye#G@U3)*+Jv>^ctrY5WmAhF|P$8%mKj0_=MdZ=-^m^rpMzMyKt zKr=I}>biiTa{bMFQ>HUrS2qSm@UsS;lGKSYxxlL2Nm0f*4?wJ;l8nLd+C2wv1nJoE zt`=G!6f{U&S`0M7`}USz9Z=4i71^&^Y9cHXuWXea5u~VSWcgQ(F=&u{A<%Qry6Q0s{3flpdXf>p*j;AY8ZPF}{9qTYgHzdIPq5-Q z9vNPrC-01_LTB5c`=}HD8xMW@czyvIFI?d=S908KyP=v}>@FT`6BSV;H}Md$(fQlz zn?&0_M#U7D$;7~DVRH~%=^s!v8A1*qnN3;ahu@m>p(bx}MOQpnxj(A?xB(9(RQOB6 zcG?tz0T<3dhwYysMTptHc0SZYUw@guPi4zA5+_dYLVo(um(^z4+9op{Zr6y%FOgg zl4R?bP;`gn@gcj24cm9*7(6_3Jej0H=%TkQf9A&jAt@^Fg*G$jzfi=rIMA1f2!O}m2mk1O=fkl));RbT>gF&7-3qPJg} z#|mcf0N5j?(|DoKdn>px!FzRyJu1VR2fyym(NML(dr!#ko#b!ArG@^CzNlxp!Yg7f zo_mIds*|pFGXC)_ zsFQXl!O+v@I%}i7e#_112zrb9?#oOwbH~F85?9yYl*D9j9;xf70lEGhfu}Cn21i~5 zRP{I&JYc^(%-CPJHG&=TofE|f-~FX2Y=dFy3st*N9d)Guw@M6Zo05~(eA_Am+``dK zveUM%+^q|8MOpLPDEFK*7${x~rNVKF*^-S9uR&_YfAo7p^J-76@swb8;PWxrR?z{E zO3D4;^);y_5U%doQ{y%V!U*|;v5E^kDNtDyTsMUhtx45YYP1dx9YdP$D(C0P5{AnC z3gh;Ve^bPOdisXxg+utf?m9_qT4oqyIcKD+R-8`;9&YrISDg0*gu~mV7HuDW$FWwZ zPkB$aaYAjCk0u8UFSnGMXYjm?qQ{)=Blp1pZU&rzF}ZPTo%X%FqW_#CTesgWuKJ)6 zLm_4lCW96Sw9eH>BI4rODReKZXpBi7YR;{~G-9vS*%Jr;8;3mhm;_iMZBCqkD&E}r9=aH@6PbZeKUQnL@4*v_kEP+zO zo?8*nBDG(C(`8$soNM1*PcV$&d`)BNx=>g1aUqF8K4cR53r{Z?yIcMetmfZ|`W#ST zHQfLa1cmH9lt#To#HlDLc4P zR%?c1F?F*gex>4omCT3^tRTm^Un|kSJ?UE@L&IY&2JtBD(E-3Zhg7=;0pBY5o>$_q^AwJ z`DM7MZxZVlQeO-1aU9<8<3A&gSPRn&QYg|>rpN+#p=UbS^apU~|DM2Hg`wKkyE^g# zLlN}OpU@e?hc&{b&~aW9e8IC*=+$bKVnyrdz6M2H=)P)2?dG7cXnZJ(XdvJ6`t+TQ zmDxcLvMPe9sW7=s#>rPSnrAVMqE1T0FdFD)jo-l#v*3ttCVs~fg|vZQHddKA##Tu+ z7voiCAQa>i)|`h{Xo2Di=R-;_*njbXOZ*B3u)f_*7TCPxA_8HYUHzX9j!-9vr3-vz zp%TwRL=}Nqf#h$O=P&!nbhjPR9uPHhBe(q5Gmq%G#H!|U2+wDi^+KV|=a&uPia49^ zAU3STZ6w4O{#sTgRv;{DYC@7*b-zV;GiQQgA&8Z+x2fj{ulB<=A3+j9guQrxi!<}T z4wDr1>H3GZMMB`hvW@Sk?_^nH;k(Rh4HIzlbCVlx9GSaiM0(H1)SMV;2hcNZWMb>? zt8bo`XS#cg<8bZ<5l=U~dyXuG?xy_vcj02hoIIB}kCG7)+4_MMd*L!>11gtza|_Ve z5r)MREVbKonv!r@?|J%h-IFxH4hJnO<%b68@?T8ueyk#2xW4pwTVoti>6*qb|I|E4 z^$@wF{PqFFUg#VY@HqzVi#qAeA;a|n(8t01@h7UE3qb?_)Shw+XQWVH-MpQ_Ioqt; zi+4XDJ}G>ArP+b-{DFz2+`2^R?!$;^xlN_BhN6;2XNEL+W538S7SJ=Gf)w&u9zAxAWROgL-@^A)wgMCw)=nT& z`U_v|XVgv6eynzvRZjx7)p@R&wER(7d{Ox2En@0YEV~(a-N)X5W~#lFMx zyG6@@a-fM|E2<$%+NW41d^@>={nqrT7)Zm*Sm>X8-c!jNiJy}pLi-9{;HmWI`tbmF z-;0B9$SaG~EeF8;f6|olaf#bM!azx-6f<@Jan%}mW&~&z@l=2 zRm@Fk1RYWI^1WR>?@c-6ezSUU?`kFvcoSrAfBZ8`_wDz%3!f->zhD7kH%baIuigYP zuUd4t;p&}$pI@`@Ln}+(2@cF_IcJ1mz21uo8Ir>=Y2KsutR%Vx_Q(%TYpBbN(e{Wk z_Nk86I2#VuXw0}wHmKa|_9({m>LI>N9Q>ud8O1~ISxn@5ySKyubyB(0#PIOWiP7yb z801r@PXoOf<-^!M9q(2TyK}_29sGQ_>~-}nz~8+chx+I!EJjC~cmtp`{GpMmUzt^D zC0WW3NeNY%>-WiMIS-O!_?$Nq>0F1UKE1UE$sQifT1aI4SV)7QP1KWi>AXpf+7*fi4- zR*>7R(gQtVlp3+$CXB|_XCP{lXWT>~BcTC}vB>t+3+tgE>q=vORmpI$0@#;++m4y~ z`U~@Rj~^5jE(Nj$#)KS4AiUvq%~RTwwNaJO$_ZbNa84=Dpzsa7`c%3hrf#Wbp!QlmeMWgYTz*%-%8|_Y|JS+ z4kLDccQ>Tig-|n0k$4uwZ@p*5nH|GeT5LPEa8y&FIsjw)o@_Wo*6s9AQCT}}yMSqi z;30W`NCR9gf&#%Vs9L+C-SS`4D$g95nmy-7f5kx&Jq8R`B7X7KtcoKQHKK(^q#fLR zP(3lw^oSB;N$?6@LfpP!C)DqcW5l#nNuze*5-LHf` zim>Pf@_;0~p7GAN%NM&pkYddgV}|t-C{5@>ZxUmN%BGAxzBibRH;7VToY=%{0FQeGiM6t;rk@ z$ozy5;{@JzG?Wqtw8~c$Mu*XH*3cN%lvyoDuB+syC(`2Gm|0U> zGjrwOZ1s!Snm@4k>U_F(y`Sf59TZ)RiwIe-t~^@)j7tFX430THk%^hkXRfnXz{PtTsGR zHICQeb&VqpLn`0YQ(HwA4|M8?BeY=d<23Pn+HKgI&OaJK1Ol-F2D4D5gJR}^%NNFi z5-0I>+0nY*X;b5^%(J=R>kNd7Twt7|mB}CjlxgaY>boPDq*|A337S zF~2fqPL{W1)oCfK6i+-1Dwa8cSk4-$oO40=3(7bp=2FcO!L7{sWqy^3hRK5=vI3SH zhG?cj(5jT0RIXcHyV}rH^f`Tcwspn!)W{q+Ils)48O}V^f^izAqQ~aJ3!Ju@&9ls3L?_NioMQe9^1Rup12y`vFM!JS+w7G~U%={+@# zf4L=HAu;6^4mUqA+RtFi^O%2XsN9E?XJ}gS%=j~K8~Uw)DhP=K+6)Wa(~T3%BG=1e zmSgV4e3p)TFNdQctY8o5X?MFKDNE`P=^sTX$-EC5UYc$iA%ScvDEY&>50XE#r}}h2 z+}WX%TcKi6D!>|1d>6y=>ghtgE0B=fr$VjJhie4;1;){LC`Wxw2b=2g@&>Bw1m=oti>8fkZ=;=zn zeP}-treWNp`qoPD>6o$TnxJbM32PREIl!MNO`8&K^AMPw+2)MVZp6`UhAeZf-!=MMv13&xhpiEW#^^u8zh( zQCK?Mpof(!YtpvhMXa5nxjw-QhT*s31jTki&Y#cFJK&Hf}YYHa+3r73A~6^4)%Ni<+{NVMZ z?n~*ys!ssYHW+>AidkDciGL7Mt`KV0WR9brr0cS+r4G~BqzlckgasgpsvKz6BuJ`J z(Jpij+k@t3#EwhPkP!_b|B|^!bvV58En{Hn?LK&?8^Yzez5Z5x)Py({gv2M7s1Fhh zDu&ByykRQvZJ(NhDQ_WD%bEP!$vn}fr{YsR`)SFWSfnWeY750uAd(-}vNkEM zWrOlst8ya7RcEQDtMJC{sp<=%5r5eBaVFj}l2$Pa!#{k`^_T+Wy}^(xXX$DD*8_-1 z3C`yPg4k0RAU4Y}w`N5!t&7N!!BJxtk*z_)N}=UFsd8j2t=2YlK>rqQ>L&WG)BP1} ziji&75nUYnCv4a2w5VApC2&dftS0gKY3Z4=Gn%EcM12Saz+q+W;hr*T55FVLH=5yNIyflf$3Hso z#F6Qdm*g^>8zy*krZOBf@|yIfFdQXsNWaJ3CK$5Idh#IY$+zeg8N<7$-1TvzxEa*T zysPW+*P}4?_M_HGD!3BUV77DOI`5_|m_N9msl zAPEjFCCI&2#(8uoQ6dRZ9vq=6O238)ubQlCn`pDFo~^5KT}Dtg7P@H*)Jl5LOBiXVP0{h5C}3)yPvRuiI=yTMua- zMPL&AT2+^ADe2wa)|8h0I8fyf5WC0*eqH*q$^_dgWff&dTO*-l!k9wyiuwAE(gvTL zw7O^7NO8cIZ~f;7Ei(Ia6ZT=FBGm0u|9mGEXIr}*8-n_0W7Jl#JTJ=E(qs^=pB+7d z9+h_{Z8mB)c^lkv0-sfd&zTiaohr{;C8ujF@6AVTT{o4IspT}1x|WVgOm+zvD**h1iO% zI+f+d6>gSiw6&#+!ZpJfj?pI7yiJo?V*cbujeK`ruHrm#xe&V;F)#KsBqIly>#;*; zd(z!EfdpK5B*o0xM>-6s#jG6~4XVn&K zO5p%Vb%OR-8^>~Vn+mdy0gm4>A)VPcJCpR=HaiPWuw@PoTkU^nGx86-jtfkI<{iiw zhW+p?EN8LCASGdb=qzlTaZLzkE8Xt|`bk>#vVC?>78`+Ac zL18T_Wd6>VPq1d6M4t8)AF1H9muWv1wl9o{?iIF=_P`FdFToA=ze7#-zw5sJE-J*y zOm)Z$-5+ZY4Vt}7eM{vo;3Ft*3M|Ndy?Ka8_BAPlh;3czP7Ov#?au8(bkOHRb+F;C zGGzSD4x-=WvtJ^FdAT0I$sWE66N>4uAfgaSJn}*fY}iM7EeWBzqk;g&jG{W=nPF5M zG{>UWv(wdbSe%yCeyI!pN{~pgMuqmUv)yFXlfE$8IOspPh0Px+9auU)^RSYaQnFPO z<=oJy98j>kEn5$rQ7it1|dcQLWVUW+r!!eb$+s-t^N?8D=ehH2Wo#6U5iM z7FceDV~sFA%#eJubLbfVMX2rcn9GhOX{wAv6jhDUf;{kX;VD%P33YL#PMxu^SW(*3 zLfzBwv(IxplD-Eks(*4w^|~Chg13Id_tK3HgIgnYK4kv> zBROO$J2?R`*jqvnzF*ijF(eSLiFIs4U~65wWM(;H{H46L6f-!d^eW4Yco~TQA=g$P zRv-&MmT$`=k$RPLCGjn{Oyr&Ki1(ueJoOXIQ`{iFUr0faXE)S1VMkUv;Y&$;PPx2Z z41c-2UJeJlfL{y`x`1CQiFFlF)7|mohK?XDz4`;VcGijHg=hvr|3ORr{d8t`dMUkeKF9QmM$D97AltnhQo)$Uu@p#NGAPM*PFXNqiEWThxvkfg%rq$ zxq}{{X4WSSmkVhn?*6ey~wh{-wm96S;S``{P8iQitVR6IW=0x%J36Ti+IS-g}F zstkPaBXvP3ic83sT7HIWH9VyEZM%9T4S@n}9QG(QJti^4_!CcjR z-th`YDIjl3+Pq*NTp0ongo|D%DCA{Ei81LijiO10Nlb z8If5gF%iRfF%ixcljn~UammkLO*E6{hcWm-8$JY0W-NyyNh!A=58xts1z%kutY#FN zbR=e|gHA5hTa;^qz+UCKk{U5PD^UwpaY0&Ls~ho?-;V!0PD4_Pw(S9dlAiKm?@9*a zmez+|^s|bjMy0*3jqv~Rk35XrT__%ac;rekNchR@{3DiPgnXnxa;q_{95DIrN1>p# z9{EEh5~`s`%?{IWh3qkntUjz$E2Puri;+ltI+%)$8>#P0Fnq%gIxHYJG=lhEUEXWy z4eYdTfxQ9$x3W~bzds%T3Ic)y`5#RBuY&00YQ<#bYGQ7m!dSryfUY@xh*m9OnomcP zgR6+G8mm5mE`#5ePb*`#F>E-j0>=ng+0yLU-sj;$Q{I-IHgZ)(3d?M6o~HqGex8;u z^Ls@7AoRu?!uUQomZ<2K7T(m$JOmItb9mCmBIBf?Dt})S=s0mX2AOp?Pj5R<*lRNq z=rqrV7`?XBsW`)d+eg|uX(&250DQ)Z*pPfD+y!~8}hbzLmO#gjfJ z|A=2#Iv({ach#E4L+|_d!(s`yF>ICpCoz6q!zR_^M0_3I!uW2Mn z_H3`2v;#+HK;tCRa5;QE@8k>?EPTsG@If-hoAwz9Cb_W%wD9dB_YVfyh0TS+Wh!c) zrSyxMJerg-&61N1(e!KlMjjXz7YHqdxWf<_G#WI>WJ<@w^aP5C^B)9R9TAtT{HEBq z-hOHuSe_|>$>BHlFBuE@CA_pkET)iFcj1=SRxz^>S63+BqErTv5**_XasQl?ev$85 zbu5~(6N0uFId-m4jgDIE2>WItlKFS!{CrYyN7ClOpN$GSsbeg(LdgX@5$Od2l23AY zDdnifmkZh`FwgiUSK*?HkgW3ikcF10b1U+kctu2jz+2-CZ~TKH?Kj4z)7d7K^&(jp z^7TX4;t2;vh|{uAg!BUr9?>8{HSS&QPb{*nrjq>pjBak0?KFJUz2OxcmaOvtUzkTCeP^4 zXYgcN>*Pjt?XdpCcWb&CvRJxpXC@eJ|ZpW8>LhB(mYtr1LVe^~PZ=S||taHUSz%9ka!E0!SxBgb6wIALB8 za_?Fggp!xoZTveGx4hfOK6#PuFqZVI)N%H)G$j+tW6-}Q2DPaz-OauzSZxN#I%%*K6ifhm$4fs z0%o4YU$2Oi=!KKDF6H0Vw^yyG(eaim>dhJ_hYQ|I5XPr^7%>r7tMX1vfndG6+9_(W z2F-bs%gC3_ndO|3#hP-gOD3c3*_r4_BfPVBo@|84dsQNdJ9r_dfBtN5+;fz!^Btwz z=-G+E068`miU^yzgoxLOf60%^31TEJW$`N_O*Kr>TqLZX`PC+ET0$fZehU&_NKf55 z+%qquM+U4k*R(mH0Qca`c?jf`r1I=tW5k4*8g6-b)8Oi#K!^jyqL3Ih{ zUhM-*zuXW~y4Nqpy`lTAHSxMgp_6?OL&H|H;v%nttK)^K3OhMh%qZ;dT)p7nVOhI5 zCH^IIdN$8QiR+Dn^f+x&suBL?LuH=LCtk&+i01BE<>X`9vVNw?wfVq_zg;|Q9D~ZV z1PmNU#dg3pFt<@-f9PPvFZ&iR@!Tg5orhd)gQLK<3^uOGx{rwkBqRzL6mhra{ka?W z@2KV}ohjt2T^}c9-mY!>!M2crn7!W-UNaWc+ogCkpHQ6zYebg%*%CEGcI{NK@Pvfo72pN>zcr_MiJdX+H*mjttOiF?hgpEIs5Yq)7+roB)SXo=o zkiKz3z8toLA-9RsQ(d<{dWf>zh7n8^cMK&MKp=grGq#PND5Gnb0v}GGxINBp29O5N zXqye0s8QNpvVLjNWf%Wu&A$p=Y>}bl6Sj?#Ahkrlw+f=hRFcRWD+rYli*8d!AIEn0 zz{B0P z04;LV;x?w!2Gygvl7M8MTL>Rl253x}##U(dSZ2)Ap_%TmGuPGB1|%4m3PsBK|=><47lPlNo4| z@Ovi9UqD4dh%NOuX5K_OF&5sdt*uq96ER&ot46{*Dc|WI<8?=T^PJJ%9kS;<6lc zIAk;yi|y|*f9^8X+qadk$6u!Oa^37~6`J%I^iH|3R&*Y(Np(*f$?34gYBsA>gSRpt z1|g0HwLjzR4H!c;hw|Rn*arT6^nueh^n%MRgRA}K?ip##ayvL=Bz!;QWt*xE{l_j$ zf9+P!m8yG6FKWPMiOeswKmwn6UnUF7PadIP(g5oj-;+V8pg0ld8Q7CZC}EKl!sawo z(>>1WM)O%L32#F-rA-gG3q;LMB7hsE1HM(FLSNNA)tvc@f5VXtl`0n013 z5C}#yhq$h-fss+L>g>KrAaW;-A17VZ;E%2cv5&^V@z;*Q#5<8tBH(2FC#f5jA}+AH z-*A5fDKw~r`++XRFuRWM1-WN+$8|1IZh%GW6S^^~;H;uzs?tbjNfEM`Ngy8YkW*y6 z5Qi8VW?qF%su_Z$e7ai!skU(s|!=2Y_ zHzbf)VD7sm6E1z72Mk~~86N{F1N*m+NbFxlgF=T^nVh-0W-fU+Smii7p*)(wk1Zc& zp@>UZ2wyPYEBmL$sy91~;kuP-d3b}`UiD>zj%ah&ycN{C=nhaFZcE}b!Nv_fofub* zwbl!qWC5ye;9ikeyHmxLUGpPkBHin)i`s({JWh16Ap!T;0Olr`$QcW<9}jY!v`8x} z2T~|xnI&8VsxlwrTIh7Qxy(YGSgSfAc-M+&)yd$EH$CXT-}mOC{0FItX~o*i-Q-Bc z#kB~S6fwo;VYsQj+U2bQ(J;Ma=nA7v%-)0^)04J+EN6;) zW<7bmN!T&$FEJL=@Lvq32>O9mceig4p+@Kf^HT<~tPrmFyK}jNz`hV{iIB|W5_TEu zuj)YnGuC?~AJqboNr|uHK?u~D_|xyQQFU*G@P+pc?Cb;5H}tugW~!9b4p9`t2DGlq znPia5X+Dikt?WpiD0uWQ?r(SFT0qQ#u_uPu0^79sJIv)0Yor4E#m9Z2H-yf?R&^8AkpBUOiNt@l^s= zR;P!+6%F@b8dO1td+28z6Omnqm6Z-Vew*)%b3hLihxy8!HikIuMwn_9CH1NyGApD; zJU+S`v5jlmK{h%4n`!P?8mp>Z2fQF+Pr*l~iLQG#239@#xs427Ws%+7M-gc}W0`Y$ zgxl`E3o%~OMz|ejMP2XxZ^u(xehd4Zuz%A)m^40EbZrd5sC#{})=t8)tm^g(c>rVR zi7$(2(~jAO*{=dkeb%o@>u2ubTB*#eQ69SQ{i>@u_sJ~&q)(+=g}0*-O|Q{7-;zWn z-ZNGurS;EwiUaMMyf)WPJB@;@uHLoNo=95#eS9cvm#SYixWu_Zb~6GqH1dV}@I{Kzp5pt{$&aZna3j9;)CoJ?=7#CkvZ>)9Fdio>?(~7E209Fs{6kb9+Z;ho zqMC{W8BhDqGdLX)7d1urH)prYCO?ce3#Fz!ezX}H$4u!0A9XsRx@nt;ZKv@iSL-5i zv(ovo_}%roIYJMqoB{h&akx`-AvZptGJR_>$2G>|ol8cE)E%PsGJ=XqoBrrj-=v=s zvjqjza!)eVzpf3ZeH2WstkIq`MJ1K!9)VKw&uL&2ZhUf_AV<~KCHKSf`lwYeSelaQ zHk|Ng`oqLg&o%c(RUa7&9F>FI;U{?_Br20;f6D#iv4~UNqdXS@a&Dm{brUCGATgY8 ziG}R3TeYX&G|CRWY%FP}qCRLMm8~<%Lztq@PCl|k>eyByX*AcmV>uxi9y%;MYN<)d zG$X5QW|V1l8VH&6X&I+jW(Z=j!lbfQoByVnhmuUik0~3oof)VzTaD;aT{XhYlNPnq zKTZfYXPwt`S|-QpVI){5tRMu4K`OozlP2;vRX&OH{PlFLh^m1pBG!Q81aZf3Yz*P5q@DK(ffJW- zf<`^}Jo@{kzpB^L)QsMdBZ7fuxN)_#a@DCKFrht=Qox!y;_>NEto|Q>{}xKph3x>P zj#lr4r6H6Gtg>FYz#2}*-rMVlyy*;oQ;b6VxD2E>(UH9T3d=zH+Xt^NGj*?d(zedT@%#7~$qMLGZ&O?v15|3wTC> zwg0b>vpF4Mtr+XqY4y(TyI^$5aM$5j(TVZnmU!0ShUU)S_W0x>Xx#vW;*Hwd^Ju!ndoVP_~+1s@&aZ53S*!>&C0AD^Y<0y^*?SytZHfGvAr-MahflC_-i@3djyv zJ0P6ZgGV`A5&lHcg*65fbV|Ytul9WKPjJDuH8g!OgN3esE5~Kl@EsOD9viIUpN;Zl zpa8-TR>vzp5&{S;Bu^s+qy^?zfhZ0+8N45Q1(JU3v@2&M@r0J~2`IgykLxz>+uytj z<4*A*{vnuv?aCdj0^!k=)Y+nXVO&s!)-h8!R4)UDlnshlQP$gNeq?3oj=`>Pm~5i* z2FXk+8NyCNRm{EGO^NzBsj&Kje^_-s$l{@kIIBv4^dxbgwzQA6Q^YP&@L0Ptayqrd z>zc_UoJpQS<2)nyf?!!gGP7BWBZQi!QQ}}5qw@wJVN}*IXo)rSkZ86hrewUUoSxQ6 z#X{AVBYT5}zH(O8qPPI6jTBo@-cWJ)WMfZ$V^is!dm%R+Sy{fOMiSg{sLd&Hb~rSk-Q7<#|sYkEn(bV z?20RZgzS~M1_JR_dV znYVWKif+r<@kN-Dx=k`QN!M&Ca8|ENG|n`C313oR91cZh@R4Zm_omDx-PO2=-YWc? zphmKmviTL8`}3dAn|B6c@Ha~48#Q`BkR=$J(xTgvILz4~?|LT>~_RbyZ6uk48O0Ma(N#Vn5<(WSYo8AI5*6V8DXr%yoV z3UTM$`1ZfVo<#4gr}<9fzjFd|m@Sjn$HafR#OPbbjO(jtq9xLi)x^uI@)s!x#G8O+(zB+LG`#N{53a<@S=)D6~Qgd-Su+*+JHE_1QB%$ zaT_PPT5wkR;t2NAbo_23)FVI@WC7JO_f7q~l4K|=f&BB^y;xZXd= zK+b$9=0?`UMxxg{l;^5wM)=%@VX_UP;@#*NYz2MXk?8(j=3RRxDPjMvfes!l28PE!&q{rR&@lPi77`9|Hiy%0y!G(Q^#)sbw32u=Z9|%JkWTc=j@~~zsUzy zxE61LS%aN;Q}G!{_Ig-0=IM+V2DO*wHLqIH?8}-4#LcWyf#?B#8QotfB}iLJgs8mm zeGyLhrs`Enjo~40NTr|bqRDL#7elcSjy|EkTRk!9ujhR$P->=5FmsAs^Jw@`g$z+A zwR$sH^Zh!$Tc3an9}FV@BOUb*14TbCQguTQ8b7SO(=B1UCm$pA*pOXH^Ln)Pb+!Cg z@WO{Jvg`Xe)imHon|?|><`yD&wt_2X$(RM*0A~w{sec#Yaz>^fSu00d)>e5L(?1Si z9Z(^tR+ZehuMY|}pLfGr*-?R@o3=N+>PRh3(JT*s>;xrcBz`$2oqr-EX!FK?ZBHt7 zMdzp!?q~_cxLK$!ETKBsBl&$2iBb-Qh5UM;hk+pNk3`!{*I@9GAezm7LHJnDJ_ z_nI^8suF3q1{Wgh^=7Q6*S8tr>f*u>@&!jJ$i?lRNx0&E&LSwpD5+kGH7IcJ6=0L! zpx}12eH@odwP8kjXoqmj0`U{dM=>Shn?d#wz%1({+KQtcC(!eAOJzUm>k4|9RoZUa z>wQ6jspPLftpAZF1R;~Jov@Q`Z~$@1_KK*&NTZeo4}TA2Wb?uNK+vrb_ljX)NT8+E z<fcjKXHhNXJx<`?LF+{3^V9ul`D#TA=P;t zBX2EgHPb0$swdWvK{H}~UM+X+XRYgIeGg*yJj}Dh_5BLMGoDV286B6KAH^6^VCtfR$Mb2#MY~0*5?_#NVNgh4)Um|y!ii^$<)?H5no=Gaj2F1nc&M)KJ9Q)i( zuO!tm`DDwOe?zTe#nKXl9aq2g`p3?m>@D~G)zPn0e{TJ^T+_3f?FguXFf+>N&k*U{ zdjocC!783%c}RVQFf(2Ym}o(w|~|;GE9?GiCQpJv3$af!55V5bAvAOGPNI8w%X) z9cf&AkN{^9!xSzk^c&!Wq!)pEiY?JLM1kQ`37;V-^z9))#{h=8ALM##kA=C9esNXg z;QEI40E@;yrSSV$fvW(^Jqj9azGrR(b2}wE<@c#%bH(sE2g#2O1N^H%gn&A!{IDI{p)t!^KN;#_~gCKTb#^A^(lPq zllT07al+qoca3QXQ4ju|bQ>8fDe5IBjJ{2CU=I__RVFmB@p|Zt4Y-Ed%VpUv*@fG# z`Hi7Sl@Z~}vR!0EJhO~);_K~2h8&@1_2b3G}_D&quQA-`5gcxWrg=m9o-aH~1q|DX#@p5y`Z85X0ZS8Qf zu+6b1VVx?v!NVcQLOtWHD%f0N)AMfUHPe&w_UaCND6nR?wN(2{O`^F$$C(4+zbEMv zgu0lR?Cc67I(uU?dpqrnrP*&tCW-c-q~V__#F9b2Lw3?21Nc*5xX3LtxwjhO`5BEX zihTMxST3XXxhwj954rytOZbAtQy8>6;dfptp1R0jW-u20WgXY{OIL@ds4c&-8E?y0 z@M0=AxXj49)!5=pWh=uvG3UT%V%t%REo&tuv}WGrW`o!xcSRMvQ^F`nfmJ?>{(`yD z$I#eCtqr0@8L+~>XPqHnUuY;Nv!X=UMnOnyk%&NZJz4!UPGNlGOCR&5Yj0X zlvPm0OF`wCNnvYJ*HJadPhPR#d7IF$SCNTh@V2xU7m{!^LP1Y|cX^D#I5x;cYTWQ{ zaCmk#EM2L=?Prtyt?SHuq9+Jf^TXXK7}0O^2K-KFiIeWpvO&?&&m|$h8N;GR)$Zfy z6G-B)&St-i49KdqBu$lvt^%a+rbb`y`_f(Fu;=qu6QI`({!_>MW2=rQ)&>*j&L3Pv zQ+x1EMs`WPj6h#k^#W|5oH#0tE@&ogjt4!Rr*unt{KAa-uV?5mRDw~tk*Q*z5@Ey| z9Uy4V@kmUXUQBfwADYkncw!C)`GP6;LXLXw*GcYOzes1cFd(~GNK)p9XOo#cP=LFx z+Na_iYyZg(`VG;ie#>j{Ng!FFTr!zu6^>3pm>=d(s=XO6U025G$>;w|{6lz{@RkxC za4d&4s*DX#zSaDYAK6j=0R2v>ubYjH1c?30VY!GJgZ7_@@)9U3i)9v7l#H#eqvmu8 zNiq)8EI3qKSyAx)P&rvlp7i75GR`c^d9E7TxE9t@)2>EYdFgdD-wO7za8DVH`t%KJ>*9&J-0?X7x+1*2q4m8^~YdSvTJp& z7AD)OZ??%$;vHc&0Q{1d|6RR#=X#xUv3Ih`FovnkRwtsvG$zxBYx-W=1JNg{>6b@t zc>($y6Qs2lg8E>C(<2>-D-^E7Az`|cz`HI^U4~W z$gIgLo=wD{%r5y9Zf!hyolx%ZM-?5N21Aj~n3fPL5@{?~*4%O8@_AMwTDJ76S<`jK0`TE^Ai;#Sz^)Bk2niWea7&kP;JYgONqJ zwAn&qh`5<`n3HPhoEoLXJP~itJWnR2XBNem}!h_>k79n<;;qqkZHctAjBxV zvxn#gorxx6(ibvcm?e@s{#=kan*)jM%G~$xw3f(sChjSsIoJkO=|+?b;;=vD)u@7; z2`0g?LuX$)($g;A)i5mDcc_zb;FGK~R799;+1Usak;a9TbTyY~B_LEbz3^NROhvvw zS($vXPa~_yZK94Z?x!YVs%LcBHaoC~$zVcWX>^v4pr>yj77JBw@)7 zZ72MIo|n5rjTaknd4$<#;0xqTGN_h^TBx#08^7Y5XAmkQ9rCX(9|zrsBLUmHDaE$y zMIgu6W{aVZIB|Ne2WUCu4!2HBos*-#DM`Ylu-LX#1!rr!6J){wPTN`XDM)l1T@W@R z#zCJSMszLfLjrgih0YE-KNO&^LFA=?nz=B8G{06A)#>e{2Dd<0M(1PM&Q zgFQP}+lY6c6O#vdll}Wg2V8q^G@=mT+)p*}4_jRz_O}odvHX}ZQVK!}3BOpi(Ctd#xfLv=@mu|rj=&6Ow_W%^SmR+wllV%TzFP2QTniJjot z;e*arY@u2e>iB;B)yhHf(V-!CW;G6CLX%VW^osOz4yWUaIr7R#IzuiLJiaxRRZdSU zWT3BQ=*}Vmdom^6ma_y-G=r%$6xSNbG@^ITrT1YK=Cht^%Mv5);ymSO+yh$uifc94 zOCRMYaG*I~I6NoWqYwVx`v&=MEwyAG155bhS;9{)g5`%hq@kIn9iNhKIRXJnz-hvO zn?(jAL$~lvKEqc6Q1jQ*D=8seN1_+dH-jVB2a2S|puq@B-|V#N{}Wj!-w^i$&mYkI zBNifK@=GdY#x*vrk!>KpL&b%*|kNP~=xbU{i~O$3$%#RTiY z1nQY9ocjuPx*RN?IUW-40Hr%4g=mj>lr)|i;@7JTJy;cF&cjs~GDh2uu}bT59R>r2 zGgk|PaCy9QGg3;1TDV`mIS%Wn6-jd{;_KEs+pWmJN$FF^h28f4F!7^s*(XWhGYuov za?U+b(Zm$t!r?;nCs@Vm{-a}5td&yv@hsWE&YA+vfW2VEfMyrITVseOJXe9K18ULq z#bu^gZWQlYdz-gf4Pru`stUjMXxrd567t5PkT9AX{AILHc8ZK#AvK*6U13{kIO^~{ zKxKoDNh80)9$MBcwnqnU8# z*_Q;M2+F|G{_W1Z*YvwECg7C*;h$wdpOt2FWr(aB$%yrQf z|E0cFS%dcJ8r}IiUbh_qKG{Da{PhErTA-C^z#GCiR&6pT?jwE=(I%TBnBbpB=&Kvc zrLG(JyppeLD_$T&#KcnKv8VZVPax}0pzTMcjMm;SQSrq*ag8}ER3kg&8awDqx-cN! zhH@}_N=Y>eC)h19;cAD)331>EX6sIB+|wUfLN~3SPe635W7%bwe1XG{V~rf8@FfWZ{m@52|3Pofc69r?F&*EVgkAC zjV4C8U5iF`zh#Lr{(Ct9GA-Tq0QuhwSb{B9lpIGa4`?nY63_$-qIC+4CK(aCAtpnY zPmu63Zfv&X?zzgmEOKzFF_?8(NCGv@x|o@o`LeL^ba=mCZ6gG- zaNY=vR|d6?bx&riEwUntk_J_+ca!^bi%OdJBUWLL}21mQ`D6cDUkjBN;Ro}aR1uPmoc06QDgnu9R9_?_TfVo2ApP?pW04Lmp7lP!sFtP;hPL&&W~uE zT!+0{@-^&72`-y`O&B$(+TY$5Cc5dFY6%SBkD6Kr3(R?xE(_^%`lZmrja0VL(>{qx zJ`M|I&!$u|#lSV%wC9O)!r^mb9h;un?zh}*M`+m}PLy z0M=Qj2>RGh@8bm3!{=LZ`7e55oCDwpdD!0oRvA`=U$&k0&S&>W%jY5ZhIcHUZI_}3 zfh;f&dZlOZC6YpqXwv#~YWayJ5zUgt)@+t?t&r1n0m3HfYVbX5Pb9*;`9(1`gGRVx ziT1zG;`tOnf{N>71Ip$IMNX_V40QHQ0Wqm0xN9*`qPEOzjX4NdAzYX&1d9mK@tdAx zt1-uxWNP91`3OL?!1Z%(_Q0;hO429N3sSv-vcx{j)$2-2`1{PkO)*tOy;axGlcaNwh*#k5!mEI7~}1|``ba-Ed9bRz>PK=AnGC>XLk;OGzUHvKae=2)8kcAn zqD5P zg+r#?z1fb7^``gBGXAR1`+UOyP^O3o76sE=FnC#(@cOaDWMX4&35@i?_TVZ!!suz3 z(MqK*3Q@p_dps`j=3zVe0f#^mbD(>CcPteL7Yv>!_FJxFtdC!~F`eUjs@$+fTa}MQ z6;395m4@o{Ww-IUr+QcI2KRyihumPtfRpQj;io&iX7^TMdiGzlgq3Rh+`SYeJ2o5h zt=_V+XVqM+jSIP4>o6^dxRJr*E z_@<ROYUn$j+Py7Vo7Z`2v)jQ8x}t9-Hu-MVU;3_qsr@tXHWxB zEv*1oN&kxgy?Bzr8QgK&ZzPMYO<2BMui0$E%DL)FxSrJpK!*e(qRk zHA7}HM9+E?O&sGRfooT1krdvZ4BI zRq^vj5AoW2;(pmF)+RhUhziagq|yd`%b05iW^pn_(^FR*5(m%8bVBN9L+>m2-y_Ey#Z zX*r|ud%ia)wW&--M3Y3STM1)$F_(sx%gbdg{VEQ9F2FzE^+=y`hyo0M|A}GDcro&O zBE-Hun7M)o5x3nJJ(=0$e%|y|uoMJ*-yr{?;DD`HrZ$?QuZFdZJD zA?_>jL$^m|nOxQvX+?G;H!dsz_`Ukg?Iin1UU=tFw*|-Fc!X&j=TJ1w)1spsk2Jbw1YCiQ@xb&JZw=;avUwkZ? zD_BZJPH_+3ic;hoS#bF$ga^Hf8ZaxL@VF<}GS1#_TnqvjJjDjd(RXYFG}ivzp+s6m z+ekd^4xm6#oj>X9S>sK}Ef>hC;IQBP)lXXDuoQQ{lI<>XWH=Xk+j{;=f`fId3&^rS zqMrRcT3e~#wJ)V<4hgy%E1QtY#^ppCOv?sdtZ|Q$^D*6j19AHuy9K=^)`P5%e?Gp8=J<@_J7J~ z%FL*+LwZ2><`EC-?Jpo?wxzF-)1G#~VRbHJslA)o$HvnebU)6tlc(T0+Fvle0+3#Q z2VS$_#k8a)hq#bt_5X+IdRw`{4nz~Hr>$6hF0tW zzFyQx+u9Y4XXdaxC}Z3w*nb(x??Po}?k9RdfeZx1|3AQ+IlxPvrNswSH;dO`&@#Y{ zCmi8^EQsZ{U!Y$AS#pS*B-ah><-riyZ zMSh=HhJpq`l=b=p$#QQgp=IQJq`$R9YmGB|YV9+mp=XiJF2SJuJ+ew2Jd4>z=kbHm z7$y~3$?WM97j*Zji%JG@@Rp{;(v8nKty_yWVkj33sga(@q38fS@D+-pYv{Ll^*~XS zB+NkxQWJQZuI|vYs4aCOjG$myG5>gg^VRWJRIFPY8*Q67s#}WnNtYMQxfr%mpK+vB zT^Bi+4fu|HO1^U!rp#oGJaLOpuv{SFT+|C9FvF3Z9C1V0EiD=2XiHsvcF~I}gzfbg> zFU$=L((LpnCRq%0ytQX0VQL4horofyb*y=74IQ0~s_vb#xbe~SqEfpr&@!^Ct~@qY zTAicrmt|oXhRtCLtu*F>OJLFp)calZ3U?){kt1_;a^+B}|KhBMlrtdKW~;c>z3Hpe z=YvMMZ++A?)i8N62=HmgUao6>J#s@i1xtJdi28@JRR`-weu z)8z2y@!ZE+!{b8plsL6paRkFoEuibD*Fu!R^-tC6F>TShp z!{iWj`n!XjR=f$FFB@jWl)>L`OGDexy5l_2x?=!aFbKQ+;McBXe>)ecSAXM7HhL@} zZ>^L~e-H^M-4N@3BMammy7%d!`3)d^qvcD#=n2tl@WCML)&D86TtfxdDbt=#jyy&S zWS=glhhm#4E(NzKTdgdIKdG!fSIaxIZ%&)0f_Rm2CP#fbULkR04#nR(W}V5`(G_?Q zGh5kh>|dEEjfg$k{>xm2>Mi)$P~Bhj3$`9WfmTfr4cP0@{^A028@<{+6!6WNUN^M$&ohl2(X zUr6QySMn)|%oE&bbpbUnKSG*NC@+Z=HA89iYWzzQw+5CN*o1Lnh(IlRm07Vn2&VxN zGxAf5WP4~iv}xcZ*4BxBH&;t_FIQ_7<$CCEnh)g)r`R)oJHy-+ebRsy|2*@UZ^JGY z&0AH<9B0O|AF1ZCIarnAK#5sxv&1ad6l(KTsY}drq&vpt4eVY~f9k z%=zTMl3kgiwMUhR=FG?~nqK!^)nY`IhB5PuhAq*c3@-OzQUf2{po?1o3o}xQ zLVqdO*Fv!sf?Z-sfJyri!SfBQ4mXhc73v)&l{tmgcM?x9+{j{J0Y};rDz=?|jo=S? zID_8X#-gV}Bj6{N!HxA!N+aX{P95+lyQDApc=V`l_%R-bvPPWd`vKo~>vRNVITL%i z+5J_Q#$iw`SG#?Hg$BNpC5=V^-aglHv?CJgj;b2q5C6VoY-E1D>_@EfEo@Ixz@YOj zZvYBlSJQdmUNgn7G3Kr{dtWd5;IM;WLTzRiH3)H|9@N%ZH31wJDL(g*a&?+gnPD%j zPuUeE+LNmfMa`-WV(+h*9Q8Vpq-mV|y{IHHf+F-9Z61idfCk5r*(QcAT3l@JZ!5EE z*l3B7ON05F3PR6>Sd{ALm+dHuS$N~2-QS58b0a|$~>Q@t!A(pN{tO#PaeD^pol7>>M!w{eaSi!UN5VMCY!K!Pc^o2^s8vJjI=S2-K50VfTY z`F(u>pc%tS@n9}INn@1KG*s?7k}#ah>#<4E&M5~O=5smpvo2zIZCK%kFL$yG`T*5h zpG{Wm*fNofMjO{vcKz^aGE;P@T$H0xE#4TwcOd81_ui&K3-V&+d3&%W3H3#^z%>&la0t4 zEpxmvwRvhXo#TQI8O73!?UKrkEdWoyY)pFwoMCmvqzx5^T;d6H(Id}8ioxHc2t+Gg zM4dwK{{kkEY2()rQ+b$nAh%qu@sEuHn@M@(2%>nF^QLQtnMZF*>!O~YsNZ#wUzJqS zSq2ZC^{^h)%g8yWN7Mc$&69GlR$@bhCupQ^K)B_wF#Tc%MW@4RkCcVDG6L|$i-*5{ zr9~RQk$swH@Oy(|Q~0!n7@uPeLgVDtZ+?O=d|ErMm%^w{Un(B9AuEgfoX_Znvz=N&OA0^*Vi~$8oU(mAfh0j*F~24<R%--nGX-W@_~_yu9Cizi-AT0v z;fC`m*O?_*LC`~1T;y2HkKnY%VCV1Z1LzBsXhgX$|EvF{1|};|`Ge@8A4LCu)!Pm` zIZ?6memhwThu#EvF}3`b>|Y`39w%yaar6QraB&((+|gt*4*DM#85hb}#T*lj=c<}d zY{i(VURXRdcrp!|94%FOq^X9ma=&|c=pI}4W^F3nhS^veo-*SScpdvx@O(XtVu#c8 z-*dt#6wxJL>yD00f>Q*&_umPp=98`6yl{y3{WnIhw=kk+%N5Fv(r0T{>{X>+BUSKs za4C2poHTk`3r~Pt?xzU^%wC=K1A^fe_YIC=n~<(r>GrTcbgn&_r~0b$ zU#&JtmpbF!h~A zBo{Br;u;<^9N*DZCKY6{j&)^aT7PJt?SN zkA_#*&bEN2?Gg`{T016&q=MNJ3Bm;=h$BDHij*9$yHMl;VjQ4B>_(YTsKu-WN{@cG zCv;+e7tB4yFYP()=q5Tfj$pD$<48a2=y`0NSz{rbxyGz;vPtIRUHmCcFT#{7^)?}yN94Lhu@wCXV z-}B7kkz6&bWG+SeF>C*;>6JmgJJt0A(#ju@a{edbZI6!p|GaZ|*ddb7xg^2AN6HQ3 znmD-QK;RE8L^H~Ofq;rYfq=OF=U@GQ55DmVgTnaZH3{$q1H%`NJd0QTe7hAK2#EDR z$Apd{l0W&807nzfDLP+f!us&;(~IyL(TDQ(IWIEOhpGcbns0) zY-nLru*~TL_Itc_d$r-daL@!RSdEh#AEa%3SF6=604}%BzaXNDbCFwr%BBndb={&2 zs`YNwZK-HkD$xor8)IpC_*-S8ZB zWH7qX0Ga{x$4?QO-Na{B?XwBdA;%5jkZ_E%YM!0}=Igjei`7Wx#K%}JmQkjs2d$T4 z%C&rgvU{l?++FhxPX6?3(Do-CwBbyf;Y_3=aC$-`LKq<;d~8gCaLkOUaCAnA#)p8- zGTvHEcM;HE^=7*~BUo76hW#1gqi`jzw-#d`fI-8pO^=J0l(RA0LSMwQ+7t2jN2+6E zydKvB`tSmTWcuzh+F4xq(K?hZ1qAz2jp?O@TL&>Fg;_>a6-MiHbox?uYWtAi zF*1K4tf6%vr$ou7&iuPhW!@2adz*Rkm#=lV<@PJdr7^)n1pl9dqz4YQ38 zTJ5)b>6P?BnBUb%5K>TFiN^$rS2@XLK{9##s%`*}8x*S|#&MVkkJLv<=9V&3X%DO5uuwa5kUS-|Kt<6JHkbgBIPyco zdBoQXR$whKq)AR2Vg11xRM@U9Y9WsJWf<7Cg>=?tON*==1aaM*c&h;r3uE z5y5~7@BIT?wW;x=#BlEp`IV*m-vvVndTsi=KmM1yFnx%Y{YzaqQTC0Nyw-TY6Ww>m znkyBn-aXF1I(jet0aryhq{p9xb#4Uv*_w#nOAgxY`Gyob{sbL+8E7sQgHc2gO0kW>^b-_ZC{8v#@S}5-mx(@Wg*h zCK>0SigV=7bZyuKVzc26f6eMxwSIe+g%}4KRKPHVl~^T^B-4>*XY>F8BoRiDYNRs{ zVHOT?@qrwSLg|w4h9U$-3;62Q`63E?gGzhDD($8|acaufRZok~u~E8n`IE1xQEc8p zmoP6tqDTso?P&_d;zrK^O~847h!jaC+2!s94m;ve2>+lciif80%A1NTbcJmokJE1w z|3d8`kKJQfo+63xJ*+qkQlN~Je?o`&SMB2yGlKnVRGYk8go9o81I#`?;N;ZyTRd4U zLPTdI**THDkq;w9pV6umwEZyukH6e}Z!jdXKtx1h?udM&Y09-EG4SA_yp&hxuTtvY zkqy`XMX8Z|fI3)mov0vS$8kXk?Ms0g4c0YqV~HCbnG*|lxd%Iz0!3bK%p!PwaGPPS zp5bU^(?jB$($H^y2=W`~o9dv0K6{HuIIH;4`y5VYCeOt~phl>XN! z$GMk@@u)~hg72O*qmT3$Th=I86K<^DfX!_3)!wVwZY840u4^e^0XBR<5MyHTmd#qC z%s`5&8QHd&`Ig*`=75%>7Z#J3=Wd zk`XkW6dm6`wp$2g1-FOwR+_6f!L*E!S}~q?8dYQ)mXQd%U_|E#F1{XR3@tm1q9Er* z(=C6>nx*V=-`N7tt}RNO5E0ak^zO6GCwonuKs|=b-B>TXW=(hOy)rLp?-w9b{*9Pr z^c>>K?zZFew!~?{WX~^;jBy86bxUJ+)uxM~BYsg}XPjT(Hf6{6x9<`UerD5Hj7uxv zGW75MUM-t!e6VFkq?K1?-}X5PMAJl{2EtpT(J6YMQwS*_g1%w;>MQUz4j+_5(3MA; z9Bqw}0;shra9llzJF8QD+%Mww5ocOQt|?InC2OrKj2#KJ_CP_-4>LQ5 zaYA%)_BdsA3aZ1Z4NrGTDG84I#OQd}OIUXtA2o)sAC;}|F!wfcPUA}z)W$X%NZMxBT zJ%m3Hp4bj(bTr^|J9~cW6g%oe$y3o&-Cf;%d39N_4&V0)DNq}5r$)eY+hFsh$=$^Rqp!63jbZUr}+8;FR)s00E_SaqB3ZVPkMXehu1&vcQMMmjJFz! zrWx}>E;))dzC2W9+U@nZuiD4H{DLl?7q4IVPHs4jRf%0-A@OF8=AH=B7rRodH0tIz zkZT@GVd|c;i`oZ3Ye;vl#IEC_D5v-hmQ#F~SDh6lqZo6Y;>X9BytezZ;LCkUs)3^H zJcCx1Ewgf*4gcP}GhT;VUU_D&SZvh9M_9&vsUj7Jda+n<)P?-UKJzdg#z&lHStix6 za+!fu-L;dU=@5=Rt7bgMuR0BUot zu8~X;q)Zr<(O|x3#OE*qexTt=E;28rN`evH%ouZZ3NsQMWhIyF9y~r7?A#=P!by6o zMB)~eDNhEVs_$5Qoxzmj5^Us0*}`tXTm>_AW?e~vqL7ncaUFG4tZx-&`fL6MBCIS* zMR2n6WTRibrBg`nZV%0BF+0L;jS<^oF#|KaA60r~zho=Pv>*d4JKbtEHI=n$W;y}v z&KttaYPusI{1F>9y~(tt8_Zm_T3uzh)!x!jYdrkphIRk9Qlqs&1yy|xXMj?Dr4Tx> z%-poKsoq18@mnMDHCS0$cfEvP8oOwr95-0Mc-$7IMKU<*3X5JZv7__P7dC>#-zt0H zdrfiE%jL@kBiprV2k3}O{0)sTlG2)s5AhUk9xMb&PmWNJ%$oQvu!%S36~7U0XY(mG zbbMyOztuY>zIJ-Mg{WTe0x7BnsRUh>3D*a@nAR*Az}3=Pk7+ixZW$DKSXCi?|IM2b zU2y{pNu)HbM@z=| z+&W2yZjyxh?7d1fq9gC1%GzzU(Nlti0xlZhBxRqKv?kV`K#o6zC@YrjND1?ioNUgn zaB&>h{b>fC2HJE>&KS+joc7veggNcBGJPVdX!73ci%3_HD2dTn#F>h8C4X2aBB}ia*;tjE&SX^5b18h%; zyf+YOA#}24RlOWb?mCjEKH)w*#qkd+i51*>q6TI-wYOtqnxJrqyx)nF^D!$?OzzXb z_*pzNfqObjLvQ{nG+JB}KGUh2$U_Ujl}o)}efYyC7F6;_-NtXB{#Wt44E;-Xf}Ij~ z&2%9OLL58OaGW2WM|rFdJ$nOXH%7f@2TvGMqy_#2+8+C^5+r!jjSv5OKDr24VA@l&_=XTRB7N?A$?q zX>-f%t^dLj?WKG+%TNJe#{6vEVPPesiH7eE0Wg`h=`jWp`yLvI_A)+Ox#S0N9zlk0 z<`3tA*oqP;?Hy+l=)YXkCvhEhXlSpEv=aA<^jwO%w3`fBqW~H%I!+yc2T|F!d z=cD;$eaD)Lpxj?-EJGJBF~C1eKQBds6|FR18*dbPJS0LtOpnjkfDx{hb6fG$*jd9` z*~?;dIk!-! z6peEi6hDZ$Ywd!m|E~Nu+9jCX(ddt5J~4;bR6v+rrrU*%uo7&pKy`HQjD1W#E5e`7 z6MQS-syXmh+wU`p+7J*+Pwh^t1M30i+gg$CM3?B7f}Yx*5`w$z`?Y^%#FZzWzz2=8 zgy=G7=+Fxo*=Q>f%{4XX_SM~tS}siTSw-;(g*jnE<><_~N$1nm@3W0{<4{#-?RA{O z8{y^ohZ_7tYFS-NA%8`a&zGH7y0S}kcTGzQj4C$f{kD4Ub2q30YJEK3f;GZXIQ7i) ze?t{v0Z6iZKGNDN1sb>H>hrLb4BKoA>MNWkFgbqI-Y5iGxwF6zt72vxX#%4l@k}<; zum#38ec?%KhlUf3wT|vgY`)6|E6>&Ngui7>{Qs8ILC`H(!xd~ONt%R6z5i+33OHzB zA^^Y}nfTps5`3(G%}5!(cZJ=py0C7ez>*6FxK~hq>0u^EoPq6lG>wWJCW6Mm3m?JN zMRNi=w;cWL>#aUE1A0E;2S$JPPCsde21U5OK_dc>of+a#bdp~Q(RptSY~98m4ksS* zZ3hm*$)BwAUE7{zVK>$8j-syAG%`6zs^~1|-3s%8>oWgS<|VSimhGV!D8sg9X7w{` z;#`xv*C*p7JBpJ@F8x{;9d3jpn~ zj(HF4cZd88vB&^LJlbbdAgud05qoo4? zAJ~yd2I5?f5Y+BWHbi_rzm9V9p%=|-sYxHoSqZpryWOZ-$Mk8CQ}!U2M%_f!hLL3Cu5 zkJL?|y#iBX1zjW5+5(o6vb^0#W3|h4GSda!m5qetXlgoID={wOdfPED%Zk;2N63$! z^3Aw`KtXE;^?rGq&dPb+WX+T^J&jMI;{}>86%X{)^Gp(V$>KZ|?PV|fybIp1eF3^s zhNRlsre4Iwhy_{Xvz5eYyG>6!3v)(=x;01f$mlXk<^Cr=IU^J~an$pA1X^c-jYlXG z(AEQxhu_$mCZvl-sHXO;1S1##zBt(1)wO8D1CnmpiRXIw{37ttc^Xoq39sgHYO8b; zHz{hKBRRWticoV@4=KvRg)oK=5X?#W$Z>naA6qCMf2{IKj>I&aZ)zuC%?-yhI~ej7 z$t}v1IY2C)&!%Ns=h1bC&r&T~llqL<#qady&3e6TZIYYt{80PiV63W#i!C;j5 z_`LnyGs@m&qr~g1H*C zuU0m+1w7VJ+FBB`gh*bheFaQpO=ga~2Jy)BR@YHOA3-%OF4T8$s!xgWXZt*z#vrY{ z0acLCJ<4PG{fcQb!@+j0Unku`C%uW5r4PCC)072s+|&0jtFmwpRQ#%1o!F4{bdRj4 zZ#Q)G3V8+mi?i77;i`MwGfEHEr%N|E;V0`bTesk)_{vT1h^8c&2z%fgKm&5mX+rPGa`!clEUXVjd-XoZfLPP8thI4+@e zopo7SAvvV;^lE%w`{()no_&A6_t`%0`~LB}JdfcqC7UmM@p^MCCdu|j*v03E9 zkB;Y$?<~6=b7W7p^O5qV4xbWoX3Kq-^464fI-#}IYrC>#tf_X7{m4|w6_ed(1YWNr zj&i$80eP=;TxVicvuRaRG?_7)rc_Vl%Vc@3_qVzx2~sl{L_bD0Qf?s`D7LP!D%KJE z(i0cZ2hP4qdZwV3n~K|4v-4RAg*ng77jRtrsI{@OmB$}Fw4ai&_NJhNlqT1=)3x2} zl*!3IeA@bNCt*_^s*W|OT;`L0bMx`j+>|3{wV&0J1gBLwLGmC@x2dm_=#4yjZWP4-dC8@Oxo;XHvvDhQZSDb6tEXv(= zt5D??N~nx{o1`62iVpnamG`F%Y2|QP%!JB|1}+VWp7M5nbWmf0maSB=a3tWaBq1e2 zS~)|0&2PZAWOT%Uzy1p4^U6o;oKUXt;Im~{bJG4yw!Xi~_x1;C`l%CdPrakp6mSK% z28SoJGPac@g}WjT_9FS$hWvV%E%u|nzqF)swmswoJ7w=?OOw3a)uvVL=5k9D z$(m7j_YYHd{~pkoMrJcD^m4|PL7!$?^4jaQ zrpn;5oCwk2LU!^_S?hJ14D+J!L;fDzG!f$t$G|(-(ZQn7Xn3H1SYH`_Ib5vgU*__m z@vrL@c_s9wx+rD+jxPb9Pfv^UAFBK(|D$wE!YQWee)T88zcV9KN|DLhbk5a$5--AJ zNm&4M7jt;-{w0Jsb%^ND%E22{8`%c4yw440AGHFf?Or)OfGOG_i`YyO#E>MJORowZ zdenPV+|F&cVM@V>&5-+?{PO%8X;PU)nm1yol6uvcH!*6y4j7saz03ycUOObz0<>j0fP_{e2vboIe=6Xq7|42SY+3#jVctq*f#MF>!g(Uw zj)NpnD<=ZeJ_@4aicPKUGeN(d;Q&KwW;nZ{uh19K6d>xGh5oqlvW6A%QkP-g#z4=) znLy_a5ykC-t0CbiqtDS#nVOL(_A;J~PianKCKS_+`I_-U}H z1qU%sVvxGsihz|DgSj1sNNEn7^a0!sB8n^h#94-)!7S@LtO;1n3>bx$Ck5D~Yo`^8 zD?7kho+tnnE(?ID(-QqL?W^I0yqxn8a>dqwOY>?7I0|{^i$EjY4M;nQ1T4u51PVi> z;3DRJEVrvr7!j~MS=MVqgnwy#-V(*K67WyE0iR`ioX7Ml*bjKQeEOJI6c?bzfo;VY zXt!bx2I2zLIMDbS1kFIK(hiBQ20bD3L7kF@9BzQ386bBpMlL)CfnDLqfhPcVSQ)MH VBfu2+*qg&~f-ihLS3eum{s(|${^$Sz diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae04661..f398c33 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c787..65dcd68 100644 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,10 +80,10 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' @@ -143,12 +143,16 @@ fi if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -205,6 +209,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd3..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerRendererMixin.java index 819a4c0..cd8e6cc 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerRendererMixin.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerRendererMixin.java @@ -2,11 +2,12 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; -import dev.kosmx.playerAnim.api.AnimUtils; import dev.kosmx.playerAnim.api.TransformType; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; import dev.kosmx.playerAnim.core.util.Vec3f; import dev.kosmx.playerAnim.impl.IAnimatedPlayer; import dev.kosmx.playerAnim.impl.IPlayerModel; +import net.minecraft.client.Minecraft; import net.minecraft.client.model.PlayerModel; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.client.player.AbstractClientPlayer; @@ -15,6 +16,7 @@ import net.minecraft.client.renderer.entity.LivingEntityRenderer; import net.minecraft.client.renderer.entity.player.PlayerRenderer; 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; @@ -24,6 +26,49 @@ public abstract class PlayerRendererMixin extends LivingEntityRenderer entityModel, float f) { super(context, entityModel, f); } + @Inject(method = "render(Lnet/minecraft/client/player/AbstractClientPlayer;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/LivingEntityRenderer;render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V")) + private void hideBonesInFirstPerson(AbstractClientPlayer entity, + float f, float g, PoseStack matrixStack, + MultiBufferSource vertexConsumerProvider, + int i, CallbackInfo ci) { + if (FirstPersonMode.isFirstPersonPass()) { + var animationApplier = ((IAnimatedPlayer) entity).playerAnimator_getAnimation(); + var config = animationApplier.getFirstPersonConfiguration(); + + if (entity == Minecraft.getInstance().getCameraEntity()) { + // Hiding all parts, because they should not be visible in first person + setAllPartsVisible(false); + // Showing arms based on configuration + var showRightArm = config.isShowRightArm(); + var showLeftArm = config.isShowLeftArm(); + this.model.rightArm.visible = showRightArm; + this.model.rightSleeve.visible = showRightArm; + this.model.leftArm.visible = showLeftArm; + this.model.leftSleeve.visible = showLeftArm; + } + } + + // No `else` case needed to show parts, since the default state should be correct already + } + + @Unique + private void setAllPartsVisible(boolean visible) { + this.model.head.visible = visible; + this.model.body.visible = visible; + this.model.leftLeg.visible = visible; + this.model.rightLeg.visible = visible; + this.model.rightArm.visible = visible; + this.model.leftArm.visible = visible; + + this.model.hat.visible = visible; + this.model.leftSleeve.visible = visible; + this.model.rightSleeve.visible = visible; + this.model.leftPants.visible = visible; + this.model.rightPants.visible = visible; + this.model.jacket.visible = visible; + } + @Inject(method = "setupRotations(Lnet/minecraft/client/player/AbstractClientPlayer;Lcom/mojang/blaze3d/vertex/PoseStack;FFF)V", at = @At("RETURN")) private void applyBodyTransforms(AbstractClientPlayer abstractClientPlayerEntity, PoseStack matrixStack, float f, float bodyYaw, float tickDelta, CallbackInfo ci){ @@ -44,7 +89,7 @@ private void applyBodyTransforms(AbstractClientPlayer abstractClientPlayerEntity @Inject(method = "renderHand", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/model/PlayerModel;setupAnim(Lnet/minecraft/world/entity/LivingEntity;FFFFF)V")) private void notifyModelOfFirstPerson(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, AbstractClientPlayer abstractClientPlayer, ModelPart modelPart, ModelPart modelPart2, CallbackInfo ci) { - if (this.getModel() instanceof IPlayerModel playerModel && AnimUtils.disableFirstPersonAnim) { + if (this.getModel() instanceof IPlayerModel playerModel && !((IAnimatedPlayer)abstractClientPlayer).playerAnimator_getAnimation().getFirstPersonMode().isEnabled()) { playerModel.playerAnimator_prepForFirstPersonRender(); } } diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/CameraAccessor.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/CameraAccessor.java new file mode 100644 index 0000000..8e63865 --- /dev/null +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/CameraAccessor.java @@ -0,0 +1,11 @@ +package dev.kosmx.playerAnim.mixin.firstPerson; + +import net.minecraft.client.Camera; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(Camera.class) +public interface CameraAccessor { + @Accessor + public void setDetached(boolean value); +} diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/EntityRenderDispatcherMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/EntityRenderDispatcherMixin.java new file mode 100644 index 0000000..e1985a2 --- /dev/null +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/EntityRenderDispatcherMixin.java @@ -0,0 +1,25 @@ +package dev.kosmx.playerAnim.mixin.firstPerson; + +import com.mojang.blaze3d.vertex.PoseStack; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.EntityRenderDispatcher; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.LevelReader; +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; + +@Mixin(EntityRenderDispatcher.class) +public class EntityRenderDispatcherMixin { + @Inject(method = "renderShadow", at = @At("HEAD"), cancellable = true) + private static void renderShadow_HEAD_PlayerAnimator(PoseStack matrices, MultiBufferSource vertexConsumers, Entity entity, float opacity, float tickDelta, LevelReader world, float radius, CallbackInfo ci) { + if (entity instanceof Player && FirstPersonMode.isFirstPersonPass()) { + // Shadow doesn't render in first person, + // so we don't want to make it appear during first person animation + ci.cancel(); + } + } +} diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java new file mode 100644 index 0000000..f5dfd25 --- /dev/null +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java @@ -0,0 +1,52 @@ +package dev.kosmx.playerAnim.mixin.firstPerson; + +import com.mojang.blaze3d.vertex.PoseStack; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; +import dev.kosmx.playerAnim.impl.IAnimatedPlayer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.client.renderer.ItemInHandRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +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; + +@Mixin(ItemInHandRenderer.class) +public class ItemInHandRendererMixin { + @Inject(method = "renderHandsWithItems", at = @At("HEAD"), cancellable = true) + private void disableDefaultItemIfNeeded(float f, PoseStack poseStack, MultiBufferSource.BufferSource bufferSource, LocalPlayer localPlayer, int i, CallbackInfo ci) { + if (((IAnimatedPlayer)localPlayer).playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { + ci.cancel(); + } + } + + /* AW needed, I may do it later + @Redirect(method = "renderHandsWithItems", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ItemInHandRenderer;evaluateWhichHandsToRender(Lnet/minecraft/client/player/LocalPlayer;)Lnet/minecraft/client/renderer/ItemInHandRenderer$HandRenderSelection;")) + private ItemInHandRenderer.HandRenderSelection selectHandsToRender(LocalPlayer localPlayer) { + + return null; + }*/ + + @Inject(method = "renderItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;renderStatic(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/client/renderer/block/model/ItemTransforms$TransformType;ZLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;Lnet/minecraft/world/level/Level;III)V"), cancellable = true) + private void cancelItemRender(LivingEntity entity, ItemStack itemStack, ItemTransforms.TransformType transformType, boolean bl, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, CallbackInfo ci) { + if (entity != Minecraft.getInstance().getCameraEntity()) { + return; + } + if (FirstPersonMode.isFirstPersonPass()) { + var config = ((IAnimatedPlayer)entity).playerAnimator_getAnimation().getFirstPersonConfiguration(); + if (transformType == ItemTransforms.TransformType.FIRST_PERSON_RIGHT_HAND || transformType == ItemTransforms.TransformType.THIRD_PERSON_RIGHT_HAND) { + if (!config.isShowRightItem()) { + ci.cancel(); + } + } else { + if (!config.isShowLeftItem()) { + ci.cancel(); + } + } + } + } +} diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java new file mode 100644 index 0000000..1dc6b05 --- /dev/null +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java @@ -0,0 +1,53 @@ +package dev.kosmx.playerAnim.mixin.firstPerson; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Matrix4f; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; +import dev.kosmx.playerAnim.impl.IAnimatedPlayer; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +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; + +@Mixin(LevelRenderer.class) +public class LevelRendererMixin { + + @Unique + private boolean defaultCameraState = false; + + // @Redirect(at = @At(target = "Lnet/minecraft/client/Camera;isDetached()Z")) is forbidden + + @Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;isDetached()Z")) + private void fakeThirdPersonMode(PoseStack poseStack, float f, long l, boolean bl, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f matrix4f, CallbackInfo ci) { + // mods may need to redirect that method, I want to avoid compatibility issues as long as possible + defaultCameraState = camera.isDetached(); + if (((IAnimatedPlayer)camera.getEntity()).playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { + FirstPersonMode.setFirstPersonPass(!camera.isDetached() && (!(camera.getEntity() instanceof LivingEntity) || !((LivingEntity)camera.getEntity()).isSleeping())); // this will cause a lot of pain + ((CameraAccessor)camera).setDetached(true); + } + } + @Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;isDetached()Z", shift = At.Shift.AFTER)) + private void resetThirdPerson(PoseStack poseStack, float f, long l, boolean bl, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f matrix4f, CallbackInfo ci) { + ((CameraAccessor)camera).setDetached(defaultCameraState); + } + + + + @Inject(method = "renderEntity", at = @At("TAIL")) + private void dontRenderEntity_End(Entity entity, double cameraX, double cameraY, double cameraZ, + float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumers, CallbackInfo ci) { + Camera camera = Minecraft.getInstance().gameRenderer.getMainCamera(); + if (entity == camera.getEntity()) { + FirstPersonMode.setFirstPersonPass(false); // Unmark this render cycle + } + } +} diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LivingEntityRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LivingEntityRendererMixin.java new file mode 100644 index 0000000..b5d162a --- /dev/null +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LivingEntityRendererMixin.java @@ -0,0 +1,31 @@ +package dev.kosmx.playerAnim.mixin.firstPerson; + +import com.mojang.blaze3d.vertex.PoseStack; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.client.renderer.entity.layers.PlayerItemInHandLayer; +import net.minecraft.world.entity.LivingEntity; +import org.objectweb.asm.Opcodes; +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.Redirect; + +import java.util.List; + +@Mixin(value = LivingEntityRenderer.class, priority = 2000) +public class LivingEntityRendererMixin { + @Shadow @Final protected List layers; + + @Redirect( + method = "render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", + at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/entity/LivingEntityRenderer;layers:Ljava/util/List;", opcode = Opcodes.GETFIELD)) + private List filterLayers(LivingEntityRenderer instance, LivingEntity entity, float f, float g, PoseStack poseStack, MultiBufferSource multiBufferSource, int i) { + if (entity instanceof LocalPlayer && FirstPersonMode.isFirstPersonPass()) { + return layers.stream().filter(layer -> layer instanceof PlayerItemInHandLayer).toList(); + } else return layers; + } +} diff --git a/minecraft/common/src/main/resources/playerAnimator-common.mixins.json b/minecraft/common/src/main/resources/playerAnimator-common.mixins.json index d293cf9..990c531 100644 --- a/minecraft/common/src/main/resources/playerAnimator-common.mixins.json +++ b/minecraft/common/src/main/resources/playerAnimator-common.mixins.json @@ -7,13 +7,18 @@ "client": [ "ArmorFeatureRendererMixin", "BipedEntityModelMixin", + "firstPerson.CameraAccessor", + "firstPerson.EntityRenderDispatcherMixin", "FeatureRendererMixin", "HeldItemMixin", + "firstPerson.ItemInHandRendererMixin", + "firstPerson.LevelRendererMixin", + "firstPerson.LivingEntityRendererMixin", + "LivingEntityRenderRedirect_bendOnly", "ModelPartMixin", "PlayerEntityMixin", "PlayerModelMixin", - "PlayerRendererMixin", - "LivingEntityRenderRedirect_bendOnly" + "PlayerRendererMixin" ], "mixins": [ ], diff --git a/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/PlayerAnimTestmod.java b/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/PlayerAnimTestmod.java index 6de6cfa..6aab78e 100644 --- a/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/PlayerAnimTestmod.java +++ b/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/PlayerAnimTestmod.java @@ -1,5 +1,7 @@ package dev.kosmx.animatorTestmod; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonConfiguration; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; import dev.kosmx.playerAnim.api.layered.IAnimation; import dev.kosmx.playerAnim.api.layered.KeyframeAnimationPlayer; import dev.kosmx.playerAnim.api.layered.ModifierLayer; @@ -78,7 +80,11 @@ public static void playTestAnimation() { } else { //Fade from current animation to a new one. //Will not fade if there is no animation currently. - testAnimation.replaceAnimationWithFade(AbstractFadeModifier.functionalFadeIn(20, (modelName, type, value) -> value), new KeyframeAnimationPlayer(PlayerAnimationRegistry.getAnimation(new ResourceLocation("testmod", "two_handed_slash_vertical_right")))); + testAnimation.replaceAnimationWithFade(AbstractFadeModifier.functionalFadeIn(20, (modelName, type, value) -> value), + new KeyframeAnimationPlayer(PlayerAnimationRegistry.getAnimation(new ResourceLocation("testmod", "two_handed_slash_vertical_right"))) + .setFirstPersonMode(FirstPersonMode.THIRD_PERSON_MODEL) + .setFirstPersonConfiguration(new FirstPersonConfiguration().setShowRightArm(true)) + ); } From 7757ead2e4745b19f38bc5b52d215deef9f8e161 Mon Sep 17 00:00:00 2001 From: KosmX Date: Fri, 24 Feb 2023 23:53:53 +0100 Subject: [PATCH 13/44] only maven upload --- .github/workflows/publish.yml | 11 ++++++++++- build.gradle | 7 +++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 31e1af7..c121e45 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,11 +7,19 @@ on: type: description: 'alpha/beta/release' required: false - default: 'alpha' + options: + - alpha + - beta + - release changelog: description: 'changelog' required: false default: '' + upload: + required: true + options: + - true + - false # A workflow run is made up of one or more jobs that can run sequentially or in parallel @@ -47,3 +55,4 @@ jobs: CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} CHANGELOG: ${{github.event.inputs.changelog}} RELEASE_TYPE: ${{github.event.inputs.type}} + UPLOAD_TO_PORTAL: ${{github.event.inputs.upload}} diff --git a/build.gradle b/build.gradle index b1d1647..197c505 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,7 @@ allprojects { tasks.withType(JavaCompile) { options.encoding = "UTF-8" - options.release = 16 + options.release = 17 } java { @@ -60,6 +60,7 @@ ext.ENV = System.getenv() ext.cfType = ENV.RELEASE_TYPE ? ENV.RELEASE_TYPE : "alpha" ext.changes = ENV.CHANGELOG ? ENV.CHANGELOG.replaceAll("\\\\n", "\n") : "" ext.ENV = System.getenv() +ext.upload = ENV.UPLOAD_TO_PORTAL ? ENV.UPLOAD_TO_PORTAL == "true" : false ext.keysExists = ENV.KOSMX_MAVEN_USER != null || project.getGradle().getStartParameter().isDryRun() @@ -81,6 +82,8 @@ if(keysExists) { } publish { - finalizedBy(':minecraft:publishMod') + if (ext.upload) { + finalizedBy(':minecraft:publishMod') + } } } \ No newline at end of file From 1b4688ced80969a0107c23d0db59873bf621732e Mon Sep 17 00:00:00 2001 From: KosmX Date: Fri, 24 Feb 2023 23:55:22 +0100 Subject: [PATCH 14/44] only maven upload attempt #2 --- .github/workflows/publish.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c121e45..72b359c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,8 +5,9 @@ on: workflow_dispatch: inputs: type: - description: 'alpha/beta/release' + description: 'release type' required: false + type: choice options: - alpha - beta @@ -17,6 +18,7 @@ on: default: '' upload: required: true + type: choice options: - true - false From da9648619fbf7b11ecd59b138bdefc8f0946853e Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 00:01:48 +0100 Subject: [PATCH 15/44] only maven upload attempt #3 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 197c505..dbab561 100644 --- a/build.gradle +++ b/build.gradle @@ -60,7 +60,7 @@ ext.ENV = System.getenv() ext.cfType = ENV.RELEASE_TYPE ? ENV.RELEASE_TYPE : "alpha" ext.changes = ENV.CHANGELOG ? ENV.CHANGELOG.replaceAll("\\\\n", "\n") : "" ext.ENV = System.getenv() -ext.upload = ENV.UPLOAD_TO_PORTAL ? ENV.UPLOAD_TO_PORTAL == "true" : false +boolean upload = ENV.UPLOAD_TO_PORTAL ? ENV.UPLOAD_TO_PORTAL == "true" : false ext.keysExists = ENV.KOSMX_MAVEN_USER != null || project.getGradle().getStartParameter().isDryRun() @@ -82,7 +82,7 @@ if(keysExists) { } publish { - if (ext.upload) { + if (upload) { finalizedBy(':minecraft:publishMod') } } From 160f1b3d64126b495aefa7f5a56d258e792da61d Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 00:10:41 +0100 Subject: [PATCH 16/44] only maven upload attempt #4 --- .github/workflows/publish.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 72b359c..5f5defc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -47,8 +47,13 @@ jobs: java-version: '17' # Runs a single command using the runners shell + - name: validate gradle wrapper + uses: gradle/wrapper-validation-action@v1 + - name: make gradle wrapper executable + if: ${{ runner.os != 'Windows' }} + run: chmod +x ./gradlew - name: Publish package - run: gradle publish --no-daemon + run: ./gradlew publish --no-daemon env: KOSMX_MAVEN_USER: ${{ secrets.MAVEN_USER }} KOSMX_MAVEN_TOKEN: ${{ secrets.MAVEN_PASS }} From 7d20f81bc6b3e5f2592891713e1574bccb3de1c3 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 00:20:03 +0100 Subject: [PATCH 17/44] only maven upload attempt #5 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 90dd1a9..1fae31b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ enabled_platforms=fabric,forge archives_base_name=player-animation-lib #Major: API break, Minor: non-breaking but significant, Patch: minor bugfix/change + MC implementation fix -mod_version=0.4.2 +mod_version=1.0.0-snapshot1 maven_group=dev.kosmx.player-anim From 31f37d6a75b90fa724f1354f745e2d65f6717efd Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 14:21:33 +0100 Subject: [PATCH 18/44] attempt to fix some small bugs --- .../kosmx/playerAnim/api/layered/AnimationStack.java | 11 ++++++----- .../api/layered/KeyframeAnimationPlayer.java | 2 +- gradle.properties | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java index 8848f70..3bc0786 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java @@ -8,7 +8,6 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -import java.util.List; /** * Player animation stack, can contain multiple active or passive layers, will always be evaluated from the lowest index. @@ -16,7 +15,7 @@ */ public class AnimationStack implements IAnimation { - private final List> layers = new ArrayList<>(); + private final ArrayList> layers = new ArrayList<>(); /** * @@ -42,7 +41,7 @@ public void tick() { @Override public @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0) { for (Pair layer : layers) { - if (layer.getRight().isActive()) { + if (layer.getRight().isActive() && (!FirstPersonMode.isFirstPersonPass() || layer.getRight().getFirstPersonMode(tickDelta).isEnabled())) { value0 = layer.getRight().get3DTransform(modelName, type, tickDelta, value0); } } @@ -93,7 +92,8 @@ public boolean removeLayer(int layerLevel) { @Override public @NotNull FirstPersonMode getFirstPersonMode(float tickDelta) { - for (Pair layer : layers) { + for (int i = layers.size(); i > 0;) { + Pair layer = layers.get(--i); if (layer.getRight().isActive()) { // layer.right.requestFirstPersonMode(tickDelta).takeIf{ it != NONE }?.let{ return@requestFirstPersonMode it } FirstPersonMode mode = layer.getRight().getFirstPersonMode(tickDelta); if (mode != FirstPersonMode.NONE) return mode; @@ -104,7 +104,8 @@ public boolean removeLayer(int layerLevel) { @Override public @NotNull FirstPersonConfiguration getFirstPersonConfiguration(float tickDelta) { - for (Pair layer : layers) { + for (int i = layers.size(); i > 0;) { + Pair layer = layers.get(--i); if (layer.getRight().isActive()) { // layer.right.requestFirstPersonMode(tickDelta).takeIf{ it != NONE }?.let{ return@requestFirstPersonMode it } FirstPersonMode mode = layer.getRight().getFirstPersonMode(tickDelta); if (mode != FirstPersonMode.NONE) layer.getRight().getFirstPersonConfiguration(tickDelta); diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java index c898dc1..d18c7b2 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java @@ -59,7 +59,7 @@ public class KeyframeAnimationPlayer implements IAnimation { @Setter @Accessors(chain = true) @NotNull - private FirstPersonMode firstPersonMode = FirstPersonMode.THIRD_PERSON_MODEL; + private FirstPersonMode firstPersonMode = FirstPersonMode.NONE; @Override diff --git a/gradle.properties b/gradle.properties index 1fae31b..0893946 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ enabled_platforms=fabric,forge archives_base_name=player-animation-lib #Major: API break, Minor: non-breaking but significant, Patch: minor bugfix/change + MC implementation fix -mod_version=1.0.0-snapshot1 +mod_version=1.0.0-snapshot2 maven_group=dev.kosmx.player-anim From 5e7bbc1a2d8cb37cf2f1ecb750b55dd15fa4726b Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 15:51:27 +0100 Subject: [PATCH 19/44] more testing --- .../java/dev/kosmx/animatorTestmod/PlayerAnimTestmod.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/PlayerAnimTestmod.java b/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/PlayerAnimTestmod.java index 6aab78e..14b0dc9 100644 --- a/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/PlayerAnimTestmod.java +++ b/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/PlayerAnimTestmod.java @@ -83,7 +83,7 @@ public static void playTestAnimation() { testAnimation.replaceAnimationWithFade(AbstractFadeModifier.functionalFadeIn(20, (modelName, type, value) -> value), new KeyframeAnimationPlayer(PlayerAnimationRegistry.getAnimation(new ResourceLocation("testmod", "two_handed_slash_vertical_right"))) .setFirstPersonMode(FirstPersonMode.THIRD_PERSON_MODEL) - .setFirstPersonConfiguration(new FirstPersonConfiguration().setShowRightArm(true)) + .setFirstPersonConfiguration(new FirstPersonConfiguration().setShowRightArm(true).setShowLeftItem(false)) ); } From c54e81a29deea8966e8132b914883562bfd16013 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 15:51:50 +0100 Subject: [PATCH 20/44] The tale of the missing return statement --- .../java/dev/kosmx/playerAnim/api/layered/AnimationStack.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java index 3bc0786..38b7c2b 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/AnimationStack.java @@ -108,7 +108,7 @@ public boolean removeLayer(int layerLevel) { Pair layer = layers.get(--i); if (layer.getRight().isActive()) { // layer.right.requestFirstPersonMode(tickDelta).takeIf{ it != NONE }?.let{ return@requestFirstPersonMode it } FirstPersonMode mode = layer.getRight().getFirstPersonMode(tickDelta); - if (mode != FirstPersonMode.NONE) layer.getRight().getFirstPersonConfiguration(tickDelta); + if (mode != FirstPersonMode.NONE) return layer.getRight().getFirstPersonConfiguration(tickDelta); } } return IAnimation.super.getFirstPersonConfiguration(tickDelta); From 1cec2f64a931397e35fc121e042cc8a2cb86d202 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 15:52:15 +0100 Subject: [PATCH 21/44] snapshot 3 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 0893946..03d3f2b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ enabled_platforms=fabric,forge archives_base_name=player-animation-lib #Major: API break, Minor: non-breaking but significant, Patch: minor bugfix/change + MC implementation fix -mod_version=1.0.0-snapshot2 +mod_version=1.0.0-snapshot3 maven_group=dev.kosmx.player-anim From fca5e41a76623de5f74b236686976b6ceb8d6b11 Mon Sep 17 00:00:00 2001 From: Zsolt Molnar Date: Sat, 25 Feb 2023 16:58:53 +0100 Subject: [PATCH 22/44] Add adjustment modifier --- .../layered/modifier/AdjustmentModifier.java | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java new file mode 100644 index 0000000..12d7800 --- /dev/null +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java @@ -0,0 +1,180 @@ +package dev.kosmx.playerAnim.api.layered.modifier; + +import dev.kosmx.playerAnim.api.TransformType; +import dev.kosmx.playerAnim.api.layered.IAnimation; +import dev.kosmx.playerAnim.api.layered.KeyframeAnimationPlayer; +import dev.kosmx.playerAnim.core.util.Vec3f; + +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; + +/** + * Adjusts body parts during animations. + * Make sure this instance is the very first one, over the KeyframeAnimationPlayer, in the animation stack. + * + * Example use (adjusting the vertical angle of a custom attack animation): + * new AdjustmentModifier((partName) -> { + * float rotationX = 0; + * float rotationY = 0; + * float rotationZ = 0; + * float offsetX = 0; + * float offsetY = 0; + * float offsetZ = 0; + * + * var pitch = player.getPitch() / 2F; + * pitch = (float) Math.toRadians(pitch); + * switch (partName) { + * case "body" -> { + * rotationX = (-1F) * pitch; + * } + * case "rightArm", "leftArm" -> { + * rotationX = pitch; + * } + * default -> { + * return Optional.empty(); + * } + * } + * + * return Optional.of(new AdjustmentModifier.PartModifier( + * new Vec3f(rotationX, rotationY, rotationZ), + * new Vec3f(offsetX, offsetY, offsetZ)) + * ); + * }); + */ +public final class AdjustmentModifier extends AbstractModifier { + public static final class PartModifier { + private final Vec3f rotation; + private final Vec3f offset; + + public PartModifier( + Vec3f rotation, + Vec3f offset + ) { + this.rotation = rotation; + this.offset = offset; + } + + public Vec3f rotation() { + return rotation; + } + + public Vec3f offset() { + return offset; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + PartModifier that = (PartModifier) obj; + return Objects.equals(this.rotation, that.rotation) && + Objects.equals(this.offset, that.offset); + } + + @Override + public int hashCode() { + return Objects.hash(rotation, offset); + } + + @Override + public String toString() { + return "PartModifier[" + + "rotation=" + rotation + ", " + + "offset=" + offset + ']'; + } + } + + public boolean enabled = true; + + private Function> source; + + public AdjustmentModifier(Function> source) { + this.source = source; + } + + private float getFadeIn(float delta) { + float fadeIn = 1; + IAnimation animation = this.getAnim(); + if(animation instanceof KeyframeAnimationPlayer) { + KeyframeAnimationPlayer player = (KeyframeAnimationPlayer)anim; + float currentTick = player.getTick() + delta; + fadeIn = currentTick / (float) player.getData().beginTick; + fadeIn = Math.min(fadeIn, 1F); + } + return fadeIn; + } + + @Override + public void tick() { + super.tick(); + + if (remainingFadeout > 0) { + remainingFadeout -= 1; + if(remainingFadeout <= 0) { + instructedFadeout = 0; + } + } + } + + private int instructedFadeout = 0; + private int remainingFadeout = 0; + + public void fadeOut(int fadeOut) { + instructedFadeout = fadeOut; + remainingFadeout = fadeOut + 1; + } + + private float getFadeOut(float delta) { + float fadeOut = 1; + if(remainingFadeout > 0 && instructedFadeout > 0) { + float current = Math.max(remainingFadeout - delta , 0); + fadeOut = current / ((float)instructedFadeout); + Math.min(fadeOut, 1F); + return fadeOut; + } + IAnimation animation = this.getAnim(); + if(animation instanceof KeyframeAnimationPlayer) { + KeyframeAnimationPlayer player = (KeyframeAnimationPlayer)anim; + + float currentTick = player.getTick() + delta; + float position = (-1F) * (currentTick - player.getData().stopTick); + float length = player.getData().stopTick - player.getData().endTick; + if (length > 0) { + fadeOut = position / length; + fadeOut = Math.min(fadeOut, 1F); + } + } + return fadeOut; + } + + @Override + public Vec3f get3DTransform(String modelName, TransformType type, float tickDelta, Vec3f value0) { + if (!enabled) { + return super.get3DTransform(modelName, type, tickDelta, value0); + } + + Optional partModifier = source.apply(modelName); + + Vec3f modifiedVector = value0; + float fade = getFadeIn(tickDelta) * getFadeOut(tickDelta); + if (partModifier.isPresent()) { + modifiedVector = super.get3DTransform(modelName, type, tickDelta, modifiedVector); + return transformVector(modifiedVector, type, partModifier.get(), fade); + } else { + return super.get3DTransform(modelName, type, tickDelta, value0); + } + } + + private Vec3f transformVector(Vec3f vector, TransformType type, PartModifier partModifier, float fade) { + switch (type) { + case POSITION: + return vector.add(partModifier.offset); + case ROTATION: + return vector.add(partModifier.rotation.scale(fade)); + case BEND: + break; + } + return vector; + } +} \ No newline at end of file From a49b8beb5b9f7c748def8257ce29eecc50958686 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 20:51:23 +0100 Subject: [PATCH 23/44] left handed helper --- .../api/layered/modifier/MirrorModifier.java | 4 ++-- .../layers/LeftHandedHelperModifier.java | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 minecraft/common/src/main/java/dev/kosmx/playerAnim/minecraftApi/layers/LeftHandedHelperModifier.java diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/MirrorModifier.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/MirrorModifier.java index 3512243..cfa412d 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/MirrorModifier.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/MirrorModifier.java @@ -28,7 +28,7 @@ public class MirrorModifier extends AbstractModifier { @Override public @NotNull Vec3f get3DTransform(@NotNull String modelName, @NotNull TransformType type, float tickDelta, @NotNull Vec3f value0) { - if (!enabled) return super.get3DTransform(modelName, type, tickDelta, value0); + if (!isEnabled()) return super.get3DTransform(modelName, type, tickDelta, value0); if (mirrorMap.containsKey(modelName)) modelName = mirrorMap.get(modelName); value0 = transformVector(value0, type); @@ -41,7 +41,7 @@ public class MirrorModifier extends AbstractModifier { @Override public @NotNull FirstPersonConfiguration getFirstPersonConfiguration(float tickDelta) { FirstPersonConfiguration configuration = super.getFirstPersonConfiguration(tickDelta); - if (enabled) { + if (isEnabled()) { return new FirstPersonConfiguration() .setShowLeftArm(configuration.isShowRightArm()) .setShowRightArm(configuration.isShowLeftArm()) diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/minecraftApi/layers/LeftHandedHelperModifier.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/minecraftApi/layers/LeftHandedHelperModifier.java new file mode 100644 index 0000000..1b08625 --- /dev/null +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/minecraftApi/layers/LeftHandedHelperModifier.java @@ -0,0 +1,22 @@ +package dev.kosmx.playerAnim.minecraftApi.layers; + +import dev.kosmx.playerAnim.api.layered.modifier.MirrorModifier; +import net.minecraft.world.entity.HumanoidArm; +import net.minecraft.world.entity.player.Player; + +/** + * Left-handedness helper + * If enabled, automatically mirror all animation if player is left-handed + */ +public class LeftHandedHelperModifier extends MirrorModifier { + private final Player player; + + public LeftHandedHelperModifier(Player player) { + this.player = player; + } + + @Override + public boolean isEnabled() { + return super.isEnabled() && player.getMainArm() == HumanoidArm.LEFT; + } +} From e49bb64ede44c8e802a299511245568d99d05bce Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 20:58:26 +0100 Subject: [PATCH 24/44] fix javadoc format --- .../api/layered/modifier/AdjustmentModifier.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java index 12d7800..94ac6f9 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java @@ -10,10 +10,12 @@ import java.util.function.Function; /** - * Adjusts body parts during animations. + * Adjusts body parts during animations.
* Make sure this instance is the very first one, over the KeyframeAnimationPlayer, in the animation stack. - * + *

* Example use (adjusting the vertical angle of a custom attack animation): + *

+ * {@code
  * new AdjustmentModifier((partName) -> {
  *     float rotationX = 0;
  *     float rotationY = 0;
@@ -41,6 +43,8 @@
  *             new Vec3f(offsetX, offsetY, offsetZ))
  *     );
  * });
+ * }
+ * 
*/ public final class AdjustmentModifier extends AbstractModifier { public static final class PartModifier { From 0fcfd3b1675ca964f28927eeffe32daf588412c2 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 21:01:26 +0100 Subject: [PATCH 25/44] fix some small stuff --- .../layered/modifier/AdjustmentModifier.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java index 94ac6f9..15d2711 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AdjustmentModifier.java @@ -46,7 +46,7 @@ * } * */ -public final class AdjustmentModifier extends AbstractModifier { +public class AdjustmentModifier extends AbstractModifier { public static final class PartModifier { private final Vec3f rotation; private final Vec3f offset; @@ -91,13 +91,13 @@ public String toString() { public boolean enabled = true; - private Function> source; + protected Function> source; public AdjustmentModifier(Function> source) { this.source = source; } - private float getFadeIn(float delta) { + protected float getFadeIn(float delta) { float fadeIn = 1; IAnimation animation = this.getAnim(); if(animation instanceof KeyframeAnimationPlayer) { @@ -121,7 +121,7 @@ public void tick() { } } - private int instructedFadeout = 0; + protected int instructedFadeout = 0; private int remainingFadeout = 0; public void fadeOut(int fadeOut) { @@ -129,12 +129,12 @@ public void fadeOut(int fadeOut) { remainingFadeout = fadeOut + 1; } - private float getFadeOut(float delta) { + protected float getFadeOut(float delta) { float fadeOut = 1; if(remainingFadeout > 0 && instructedFadeout > 0) { float current = Math.max(remainingFadeout - delta , 0); fadeOut = current / ((float)instructedFadeout); - Math.min(fadeOut, 1F); + fadeOut = Math.min(fadeOut, 1F); return fadeOut; } IAnimation animation = this.getAnim(); @@ -170,12 +170,12 @@ public Vec3f get3DTransform(String modelName, TransformType type, float tickDelt } } - private Vec3f transformVector(Vec3f vector, TransformType type, PartModifier partModifier, float fade) { + protected Vec3f transformVector(Vec3f vector, TransformType type, PartModifier partModifier, float fade) { switch (type) { case POSITION: - return vector.add(partModifier.offset); + return vector.add(partModifier.offset().scale(fade)); case ROTATION: - return vector.add(partModifier.rotation.scale(fade)); + return vector.add(partModifier.rotation().scale(fade)); case BEND: break; } From 70b141c6acd18508a09c3003eac366fee2548292 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 21:06:16 +0100 Subject: [PATCH 26/44] version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 03d3f2b..b894d89 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ enabled_platforms=fabric,forge archives_base_name=player-animation-lib #Major: API break, Minor: non-breaking but significant, Patch: minor bugfix/change + MC implementation fix -mod_version=1.0.0-snapshot3 +mod_version=1.0.0-rc1 maven_group=dev.kosmx.player-anim From 3bc3db655978383e55bec0846765a4cd199219e6 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 25 Feb 2023 21:28:34 +0100 Subject: [PATCH 27/44] set breaks better combat (api reimplementation) --- minecraft/fabric/src/main/resources/fabric.mod.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/minecraft/fabric/src/main/resources/fabric.mod.json b/minecraft/fabric/src/main/resources/fabric.mod.json index d7e1b99..58cbc3f 100644 --- a/minecraft/fabric/src/main/resources/fabric.mod.json +++ b/minecraft/fabric/src/main/resources/fabric.mod.json @@ -23,6 +23,9 @@ "minecraft": ">=1.19", "fabric-resource-loader-v0": "*" }, + "breaks": { + "bettercombat": "<1.6.0" + }, "custom": { "modmenu": { "badges": ["library"] From bbd9b7f4da93d00a3c83b1050a9b009ec75384a5 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sun, 26 Feb 2023 20:19:06 +0100 Subject: [PATCH 28/44] Update gradle.properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index b894d89..9cf095e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ enabled_platforms=fabric,forge archives_base_name=player-animation-lib #Major: API break, Minor: non-breaking but significant, Patch: minor bugfix/change + MC implementation fix -mod_version=1.0.0-rc1 +mod_version=1.0.0-rc2 maven_group=dev.kosmx.player-anim From bdf09a058b30a70f74e4b72309ea6dc414b813f5 Mon Sep 17 00:00:00 2001 From: KosmX Date: Sun, 26 Feb 2023 22:05:42 +0100 Subject: [PATCH 29/44] Update gradle.properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 9cf095e..e42a751 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ enabled_platforms=fabric,forge archives_base_name=player-animation-lib #Major: API break, Minor: non-breaking but significant, Patch: minor bugfix/change + MC implementation fix -mod_version=1.0.0-rc2 +mod_version=1.0.0 maven_group=dev.kosmx.player-anim From cf9f56cbf7264d5c834884d87b18bdf719e52aeb Mon Sep 17 00:00:00 2001 From: KosmX Date: Wed, 1 Mar 2023 23:19:33 +0100 Subject: [PATCH 30/44] Use safe cast to avoid crashes. --- gradle.properties | 2 +- .../mixin/firstPerson/ItemInHandRendererMixin.java | 6 +++--- .../playerAnim/mixin/firstPerson/LevelRendererMixin.java | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gradle.properties b/gradle.properties index e42a751..8b26dd7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ enabled_platforms=fabric,forge archives_base_name=player-animation-lib #Major: API break, Minor: non-breaking but significant, Patch: minor bugfix/change + MC implementation fix -mod_version=1.0.0 +mod_version=1.0.1 maven_group=dev.kosmx.player-anim diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java index f5dfd25..e00c156 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java @@ -19,7 +19,7 @@ public class ItemInHandRendererMixin { @Inject(method = "renderHandsWithItems", at = @At("HEAD"), cancellable = true) private void disableDefaultItemIfNeeded(float f, PoseStack poseStack, MultiBufferSource.BufferSource bufferSource, LocalPlayer localPlayer, int i, CallbackInfo ci) { - if (((IAnimatedPlayer)localPlayer).playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { + if (localPlayer instanceof IAnimatedPlayer player && player.playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { ci.cancel(); } } @@ -36,8 +36,8 @@ private void cancelItemRender(LivingEntity entity, ItemStack itemStack, ItemTran if (entity != Minecraft.getInstance().getCameraEntity()) { return; } - if (FirstPersonMode.isFirstPersonPass()) { - var config = ((IAnimatedPlayer)entity).playerAnimator_getAnimation().getFirstPersonConfiguration(); + if (FirstPersonMode.isFirstPersonPass() && entity instanceof IAnimatedPlayer player) { + var config = player.playerAnimator_getAnimation().getFirstPersonConfiguration(); if (transformType == ItemTransforms.TransformType.FIRST_PERSON_RIGHT_HAND || transformType == ItemTransforms.TransformType.THIRD_PERSON_RIGHT_HAND) { if (!config.isShowRightItem()) { ci.cancel(); diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java index 1dc6b05..f06130e 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java @@ -29,8 +29,8 @@ public class LevelRendererMixin { @Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;isDetached()Z")) private void fakeThirdPersonMode(PoseStack poseStack, float f, long l, boolean bl, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f matrix4f, CallbackInfo ci) { // mods may need to redirect that method, I want to avoid compatibility issues as long as possible - defaultCameraState = camera.isDetached(); - if (((IAnimatedPlayer)camera.getEntity()).playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { + if (camera.getEntity() instanceof IAnimatedPlayer player && player.playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { + defaultCameraState = camera.isDetached(); FirstPersonMode.setFirstPersonPass(!camera.isDetached() && (!(camera.getEntity() instanceof LivingEntity) || !((LivingEntity)camera.getEntity()).isSleeping())); // this will cause a lot of pain ((CameraAccessor)camera).setDetached(true); } From 2f766e7613c33de1b773d695e07c5b948183d519 Mon Sep 17 00:00:00 2001 From: KosmX Date: Thu, 2 Mar 2023 13:00:34 +0100 Subject: [PATCH 31/44] fix stupid issue --- .../kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java index f06130e..d35be20 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java @@ -29,8 +29,8 @@ public class LevelRendererMixin { @Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;isDetached()Z")) private void fakeThirdPersonMode(PoseStack poseStack, float f, long l, boolean bl, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f matrix4f, CallbackInfo ci) { // mods may need to redirect that method, I want to avoid compatibility issues as long as possible + defaultCameraState = camera.isDetached(); if (camera.getEntity() instanceof IAnimatedPlayer player && player.playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { - defaultCameraState = camera.isDetached(); FirstPersonMode.setFirstPersonPass(!camera.isDetached() && (!(camera.getEntity() instanceof LivingEntity) || !((LivingEntity)camera.getEntity()).isSleeping())); // this will cause a lot of pain ((CameraAccessor)camera).setDetached(true); } From 4eff6d3dae236c0c46a30c049f0c37f6cab76b5d Mon Sep 17 00:00:00 2001 From: KosmX Date: Thu, 2 Mar 2023 13:08:44 +0100 Subject: [PATCH 32/44] Update gradle.properties --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 8b26dd7..020e060 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,7 +5,7 @@ enabled_platforms=fabric,forge archives_base_name=player-animation-lib #Major: API break, Minor: non-breaking but significant, Patch: minor bugfix/change + MC implementation fix -mod_version=1.0.1 +mod_version=1.0.2 maven_group=dev.kosmx.player-anim From e1c4a584ea2298a6dd1199b980eaa950af7e93ca Mon Sep 17 00:00:00 2001 From: KosmX Date: Sat, 11 Mar 2023 13:09:35 +0100 Subject: [PATCH 33/44] update buildscript --- build.gradle | 5 +++-- gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 61608 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 4 ++-- minecraft/fabric/build.gradle | 10 ++++------ minecraft/forge/build.gradle | 10 ++++------ 6 files changed, 14 insertions(+), 17 deletions(-) diff --git a/build.gradle b/build.gradle index dbab561..a699dbf 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,11 @@ plugins { id "architectury-plugin" version "3.4-SNAPSHOT" - id "dev.architectury.loom" version "1.0.+" apply false + id "dev.architectury.loom" version "1.1.+" apply false //Publishing id 'com.matthewprenger.cursegradle' version '1.4.0' apply false - id "com.modrinth.minotaur" version "2.4.3" apply false + id "com.modrinth.minotaur" version "2.7.4" apply false + id 'com.github.johnrengelman.shadow' version '8.1.0' apply false } architectury { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..ccebba7710deaf9f98673a68957ea02138b60d0a 100644 GIT binary patch delta 5094 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 delta 5107 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 I6Xdi10eY*&F8}}l diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f398c33..bdc9a83 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 65dcd68..79a61d4 100644 --- a/gradlew +++ b/gradlew @@ -144,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac diff --git a/minecraft/fabric/build.gradle b/minecraft/fabric/build.gradle index a8db268..92d8824 100644 --- a/minecraft/fabric/build.gradle +++ b/minecraft/fabric/build.gradle @@ -1,7 +1,5 @@ -plugins { - id "com.github.johnrengelman.shadow" version "7.1.2" -} +apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'com.modrinth.minotaur' apply plugin: 'com.matthewprenger.cursegradle' @@ -79,18 +77,18 @@ shadowJar { exclude "architectury.common.json" configurations = [project.configurations.shadowCommon] - classifier "dev-shadow" + archiveClassifier.set("dev-shadow") } remapJar { injectAccessWidener = true inputFile.set shadowJar.archiveFile dependsOn shadowJar - classifier null + archiveClassifier.set(null) } jar { - classifier "dev" + archiveClassifier.set("dev") } sourcesJar { diff --git a/minecraft/forge/build.gradle b/minecraft/forge/build.gradle index a170063..3faf3f3 100644 --- a/minecraft/forge/build.gradle +++ b/minecraft/forge/build.gradle @@ -1,7 +1,5 @@ -plugins { - id "com.github.johnrengelman.shadow" version "7.1.2" -} +apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'com.modrinth.minotaur' apply plugin: 'com.matthewprenger.cursegradle' @@ -61,17 +59,17 @@ shadowJar { exclude "architectury.common.json" configurations = [project.configurations.shadowCommon] - classifier "dev-shadow" + archiveClassifier.set("dev-shadow") } remapJar { inputFile.set shadowJar.archiveFile dependsOn shadowJar - classifier null + archiveClassifier.set(null) } jar { - classifier "dev" + archiveClassifier.set("dev") } sourcesJar { From 85cff9e72c7c12832345259dbfda235af57d4dbc Mon Sep 17 00:00:00 2001 From: Amirhan-Taipovjan-Greatest-I <51203385+Amirhan-Taipovjan-Greatest-I@users.noreply.github.com> Date: Mon, 24 Jul 2023 09:53:00 +0300 Subject: [PATCH 34/44] Tatar ModMenu Description Translation. --- .../src/main/resources/assets/player-animator/lang/tt_ru.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 minecraft/fabric/src/main/resources/assets/player-animator/lang/tt_ru.json diff --git a/minecraft/fabric/src/main/resources/assets/player-animator/lang/tt_ru.json b/minecraft/fabric/src/main/resources/assets/player-animator/lang/tt_ru.json new file mode 100644 index 0000000..dc7e479 --- /dev/null +++ b/minecraft/fabric/src/main/resources/assets/player-animator/lang/tt_ru.json @@ -0,0 +1,3 @@ +{ + "modmenu.descriptionTranslation.player-animator": "Уенчыны гади анимацияләү өчен җиңел (авырлык буенча) китапханә" +} From 1cba387ea5eef0fe61cb5741566880b506a9816a Mon Sep 17 00:00:00 2001 From: KosmX Date: Thu, 3 Aug 2023 15:41:07 +0200 Subject: [PATCH 35/44] test and example of the use of coded animations --- .../java/dev/kosmx/animatorTestmod/CodedAnimation.java | 2 ++ .../java/dev/kosmx/animatorTestmod/SomeString.java | 10 ---------- .../mixin/AbstractClientPlayerMixin.java | 2 ++ 3 files changed, 4 insertions(+), 10 deletions(-) create mode 100644 minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/CodedAnimation.java delete mode 100644 minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/SomeString.java create mode 100644 minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/mixin/AbstractClientPlayerMixin.java diff --git a/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/CodedAnimation.java b/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/CodedAnimation.java new file mode 100644 index 0000000..d5eb31d --- /dev/null +++ b/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/CodedAnimation.java @@ -0,0 +1,2 @@ +package dev.kosmx.animatorTestmod;public class CodedAnimation { +} diff --git a/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/SomeString.java b/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/SomeString.java deleted file mode 100644 index 10bb6e7..0000000 --- a/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/SomeString.java +++ /dev/null @@ -1,10 +0,0 @@ -package dev.kosmx.animatorTestmod; - -/** - * 'Cause I could not load the animations from assets - * - * It is a base64 encoded version of it :D - */ -public class SomeString { - public final static String something = "ew0KICAgICJuYW1lIjogInR3b19oYW5kZWRfc2xhc2hfaG9yaXpvbnRhbF9yaWdodCIsDQogICAgImF1dGhvciI6ICJEYWVkZWx1cyIsDQogICAgImRlc2NyaXB0aW9uIjogIlR3byBoYW5kZWQgc2xhc2ggYXR0YWNrIHJpZ2h0IHRvIGxlZnQiLA0KICAgICJlbW90ZSI6ew0KICAgICAgICAiaXNMb29wIjogImZhbHNlIiwNCiAgICAgICAgInJldHVyblRpY2siOiAyLA0KICAgICAgICAiYmVnaW5UaWNrIjoxMCwNCiAgICAgICAgImVuZFRpY2siOjE4LA0KICAgICAgICAic3RvcFRpY2siOjI4LA0KICAgICAgICAiZGVncmVlcyI6ZmFsc2UsDQogICAgICAgICJtb3ZlcyI6Ww0KICAgICAgICAgICAgDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEwLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjotMC4wDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTEsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImhlYWQiOnsNCiAgICAgICAgICAgICAgICAgICAgInkiOi0wLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAieSI6LTAuMA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEzLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjotMC4wDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjotMC4wDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTgsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImhlYWQiOnsNCiAgICAgICAgICAgICAgICAgICAgInkiOi0wLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6LTAuMA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjExLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJ6IjotMC4wDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTIsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImhlYWQiOnsNCiAgICAgICAgICAgICAgICAgICAgInoiOi0wLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMywNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6LTAuMA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6LTAuMA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJ6IjotMC4wDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImhlYWQiOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOi0wLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMSwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6LTAuMA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJ4IjotMC4wDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTMsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImhlYWQiOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOi0wLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImhlYWQiOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOi0wLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxOCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6LTAuMA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEwLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJ5YXciOi0wLjMxMjE0NTUwMTM3NTE5ODM2DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTEsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImhlYWQiOnsNCiAgICAgICAgICAgICAgICAgICAgInlhdyI6MC4wMzAwNzgyNDM0NjQyMzE0OQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJ5YXciOjAuNjI5NzQ3MzkwNzQ3MDcwMw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEzLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJ5YXciOjEuMDU3NTY5MDI2OTQ3MDIxNQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjoxLjE4Njk3NTU5ODMzNTI2NjENCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxOCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjoxLjE4NTY0MTUyNzE3NTkwMzMNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAicm9sbCI6LTAuMDc4ODY5MDUyMjMxMzExOA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjExLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjotMC4wMTY1NDcwNDQ3MzkxMjcxNg0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjotMC4yMjk0MTE3ODA4MzQxOTgNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMywNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAicm9sbCI6LTAuMzMyNDk4NDAxNDAzNDI3MQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAicm9sbCI6LTAuMzMxNzY5MDE5MzY1MzEwNjcNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxOCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAicm9sbCI6LTAuMzM3MTY5MzQ5MTkzNTczDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImhlYWQiOnsNCiAgICAgICAgICAgICAgICAgICAgInBpdGNoIjowLjI1MzAyODEyNDU3MDg0NjU2DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTEsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImhlYWQiOnsNCiAgICAgICAgICAgICAgICAgICAgInBpdGNoIjotMC4wMzIwMTg3OTkzMzQ3NjQ0OA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJwaXRjaCI6LTAuMzY2MjYyMDE4NjgwNTcyNQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEzLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJoZWFkIjp7DQogICAgICAgICAgICAgICAgICAgICJwaXRjaCI6LTAuNDE5Njk0OTYwMTE3MzQwMQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0wLjQxNDM1NDYyMjM2NDA0NDINCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxOCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAiaGVhZCI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0wLjM3OTI5Mzk0ODQxMTk0MTUzDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInRvcnNvIjp7DQogICAgICAgICAgICAgICAgICAgICJ5YXciOi0wLjMyNDA5NDI2NTY5OTM4NjYNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMSwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgInlhdyI6MC4wMjU5OTIyMjk1ODA4NzkyMQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJ0b3JzbyI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjowLjY2MzAyNDg0MjczOTEwNTINCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInRvcnNvIjp7DQogICAgICAgICAgICAgICAgICAgICJ5YXciOjEuMjE1MDMxNTA0NjMxMDQyNQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJ0b3JzbyI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjoxLjIzMjUyNDk5MTAzNTQ2MTQNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOi01LjU0MTA5Mzk5NTQ0MDgyNWUtMTcNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMSwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOjAuMDA1MjEzOTI1NjE0OTUzMDQxDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTIsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInRvcnNvIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjowLjAxMDQyNzg1MTIyOTkwNjA4Mg0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOi0wLjE3MDI2OTQ1OTQ4NjAwNzcNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxOCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOi0wLjAzMjI5MjQ3Nzc4NjU0MDk4NQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEwLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJ0b3JzbyI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOjAuMjM4ODIwNzkxMjQ0NTA2ODQNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMSwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgInBpdGNoIjotMC4wMDg5NjMyNzE5NzU1MTcyNzMNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgInBpdGNoIjotMC4yODQ3NzgwODgzMzEyMjI1Mw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgInBpdGNoIjotMC4zMjIxNTI0MzU3Nzk1NzE1Mw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJ0b3JzbyI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0wLjE3OTkxNTQ1Nzk2Mzk0MzQ4DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInRvcnNvIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjowLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMSwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgInkiOjAuMA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJ0b3JzbyI6ew0KICAgICAgICAgICAgICAgICAgICAieSI6MC4wDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJ0b3JzbyI6ew0KICAgICAgICAgICAgICAgICAgICAieSI6MC4wDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTgsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInRvcnNvIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjowLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOjAuMA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjExLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJ0b3JzbyI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6MC4wDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTIsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInRvcnNvIjp7DQogICAgICAgICAgICAgICAgICAgICJ4IjowLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInRvcnNvIjp7DQogICAgICAgICAgICAgICAgICAgICJ4IjowLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxOCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAidG9yc28iOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOjAuMA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEwLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJ0b3JzbyI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6LTAuMDQ0NjA5MDM2Mjk2NjA2MDY0DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTEsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInRvcnNvIjp7DQogICAgICAgICAgICAgICAgICAgICJ6IjotMC4wNjU3NzAxMDQ1Mjc0NzM0NQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJ0b3JzbyI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6LTAuMDY0OTk5OTk3NjE1ODE0MjENCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInRvcnNvIjp7DQogICAgICAgICAgICAgICAgICAgICJ6IjotMC4xNDA5MzU5NDI1MzA2MzIwMg0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJ0b3JzbyI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6LTAuMTg3OTE0NTk1MDA3ODk2NDINCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInlhdyI6MC4yMzE3MDU5Nzg1MTI3NjM5OA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjowLjEwODUzMjcxOTMxNDA5ODM2DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjowLjA0OTkwNDEwMDU5NjkwNDc1NQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjowLjAzMTQ4OTY2MjgyNjA2MTI1DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjoxLjM3MDEzNzY5MTQ5NzgwMjcNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOjEuNjMxNDE3MTU1MjY1ODA4DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAicm9sbCI6MS42ODk4ODYwOTMxMzk2NDg0DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTgsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjoxLjY1NjA3NTAwMDc2MjkzOTUNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInkiOjMuMzg5ODc5MjI2Njg0NTcwMw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieSI6Mi44NjQ5MjE1Njk4MjQyMTg4DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieSI6Mi44NjQ5MjE1Njk4MjQyMTg4DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTgsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjoyLjg2NDkyMTU2OTgyNDIxODgNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInoiOjAuMDk1MTM2MDc2MjExOTI5MzINCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInoiOi0xLjYyMDAwOTE4Mzg4MzY2Nw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInoiOi0xLjYyMDAwOTE4Mzg4MzY2Nw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6LTEuNjIwMDA5MTgzODgzNjY3DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJ4IjotNS43MDM1NDg0MzEzOTY0ODQNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOi00LjQzMzEwOTc2MDI4NDQyNA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOi00LjQzMzEwOTc2MDI4NDQyNA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6LTQuNDMzMTA5NzYwMjg0NDI0DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJwaXRjaCI6MC4yODE4NTAwMTAxNTY2MzE0Nw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0xLjMwMzk4OTg4NzIzNzU0ODgNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJwaXRjaCI6LTEuODEzNzcxNzI0NzAwOTI3Nw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0yLjE1NzY0MDkzMzk5MDQ3ODUNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAicm9sbCI6MS4yNTMxNzAwMTM0Mjc3MzQ0DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTIsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOjEuNTkyNDIwMjIwMzc1MDYxDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjoxLjM5NTYwNTgwMjUzNjAxMDcNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxOCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAicm9sbCI6MS4yOTY3OTMyMjI0MjczNjgyDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInlhdyI6MC4wMDY0ODgzMjM2NzczMzEyMDkNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjowLjA5MDgxMDY1NjU0NzU0NjM5DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJ5YXciOjAuMjcwMDc2NDUzNjg1NzYwNQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJ5YXciOjAuMTE2NzEyOTEyOTE3MTM3MTUNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0wLjQ4NjYwNDMwMzEyMTU2NjgNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0wLjcxMjcyMjU5OTUwNjM3ODINCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInBpdGNoIjotMC45MDY5NTI2NzkxNTcyNTcxDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTgsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInBpdGNoIjotMS4yOTMxOTI3NDQyNTUwNjYNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieSI6Mi42Nzc4NzU1MTg3OTg4MjgNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieSI6Mi42Nzc4NzU1MTg3OTg4MjgNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInkiOjEuOTI1Nzk4NDE2MTM3Njk1Mw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjoyLjI3ODMyMzE3MzUyMjk0OQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEwLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJ6IjotMi43ODQyNTc0MTE5NTY3ODcNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6LTIuNzg0MjU3NDExOTU2Nzg3DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJ6IjotMy4yNjAyNDM0MTU4MzI1MTk1DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTgsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRBcm0iOnsNCiAgICAgICAgICAgICAgICAgICAgInoiOi0wLjk1NDcxNTM3MTEzMTg5Nw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEwLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJ4IjoyLjAzNTUxMDc3ODQyNzEyNA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0QXJtIjp7DQogICAgICAgICAgICAgICAgICAgICJ4IjoyLjAzNTUxMDc3ODQyNzEyNA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6NS4zNjMxOTM5ODg4MDAwNDkNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxOCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdEFybSI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6NS44NTg4NTAwMDIyODg4MTgNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInlhdyI6LTAuMjUyMjk0MTUyOTc1MDgyNA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjExLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjotMC4wMDA1ODc2NDkwNjEzNDQ1NjQNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInlhdyI6MC41MjE5NzUwNDA0MzU3OTENCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJ5YXciOjEuMTU3Nzk0MTE3OTI3NTUxMw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjoxLjE0MDM3NzQwMjMwNTYwMw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEwLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAicm9sbCI6LTAuMDMyMjQ4ODY5NTM4MzA3MTkNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMSwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOi0wLjAwODU2OTU1MzQ5NDQ1MzQzDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTIsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjotMC4xNjM3ODc0MDk2NjMyMDAzOA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOi0wLjA4MzY5NDUxMDE2MTg3NjY4DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTgsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjotMC4xMjA5Mjk3ODUwNzI4MDM1DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJwaXRjaCI6MC4yMTA5ODU4MDk1NjQ1OTA0NQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjExLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0wLjA0ODk0MzE0MzMzNzk2NTAxDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTIsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJwaXRjaCI6LTAuNDAzMTI3NDAyMDY3MTg0NDUNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJwaXRjaCI6LTAuMzE4MzgyMTQzOTc0MzA0Mg0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0wLjIxMjE0MDc4MzY2NzU2NDQNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOi0xLjkNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMSwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOi0xLjkzNDgzODY3NjQ1MjYzNjYNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOi0yLjM1OTkzMDY1ODM0MDQ1NA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgIngiOi0zLjIwNDMyNDE1MDA4NTQ0OQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6LTMuMjA0MzI0MTUwMDg1NDQ5DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjoxMi4wDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTEsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjoxMS4wMzI2MzQ3OTQ3MTIwNjcNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInkiOjExLjE5MjUwMzA5NDY3MzE1Nw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInkiOjExLjYwMjMzNDY3ODE3MzA2NQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieSI6MTEuNjAyMzM0Njc4MTczMDY1DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJ6IjowLjENCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMSwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInoiOi0xLjAzOTQwOTQyMjg3NDQ1MDYNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInoiOi0wLjI2NTM5MTE2NTAxODA4MTcNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJ6IjotMC4zMjUxMTk2OTgwNDc2Mzc5Ng0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6LTAuMzI1MTE5Njk4MDQ3NjM3OTYNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjotMC40NDY5MDk3MjU2NjYwNDYxNA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJ5YXciOjAuMDI2ODM5MTI0MDM4ODE1NQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjotMC4zMTc0NTA0MzM5Njk0OTc3DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTgsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInlhdyI6LTAuMzM0MjQyNTUyNTE4ODQ0Ng0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEwLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjotMC4xNjc1Mzc3NjM3MTQ3OTAzNA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjotMC4wMTAzMjE0NDM5MDA0NjU5NjUNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOjAuMDIwMTI4MDQ1MjMxMTAzODk3DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTgsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5PVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOi0wLjEwNDY5MzA4NDk1NTIxNTQ1DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInBpdGNoIjowLjU4Mzg0MTE0NTAzODYwNDcNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0wLjE1MDAyMjIyMzU5MTgwNDUNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInBpdGNoIjotMC4yMjcxMzMwNjU0NjIxMTI0Mw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJwaXRjaCI6LTAuMTg5NTUwNjgyOTAyMzM2MTINCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieSI6MTEuNzA5NzA1NjUwODA2NDI3DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTIsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInkiOjEyLjANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInkiOjExLjkxNDY2NDQ3NzEwOTkwOQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjoxMS45MTQ2NjQ0NzcxMDk5MDkNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6MC41MTIyMjM5MjMyMDYzMjk0DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTIsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInoiOi0wLjENCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxNCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VPVVRRVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgImxlZnRMZWciOnsNCiAgICAgICAgICAgICAgICAgICAgInoiOi0xLjAxMTIxNDA1MzYzMDgyOQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE4LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJ6IjotMS4wMTEyMTQwNTM2MzA4MjkNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6Mi4xMjg2NTIwMDA0MjcyNDYNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6MS45DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJsZWZ0TGVnIjp7DQogICAgICAgICAgICAgICAgICAgICJ4IjoyLjk2Njk0ODE3NTQzMDI5NzgNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxOCwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTk9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAibGVmdExlZyI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6Mi45NjY5NDgxNzU0MzAyOTc4DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0SXRlbSI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6MC44ODg2MzQ2MjIwOTcwMTU0DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTIsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0SXRlbSI6ew0KICAgICAgICAgICAgICAgICAgICAieCI6MC4xNDk3MDcxOTgxNDMwMDUzNw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRJdGVtIjp7DQogICAgICAgICAgICAgICAgICAgICJ4IjowLjEyMDg3ODQ4NzgyNTM5MzY4DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0SXRlbSI6ew0KICAgICAgICAgICAgICAgICAgICAieiI6LTEuMTE2NTQ4MDYxMzcwODQ5Ng0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEl0ZW0iOnsNCiAgICAgICAgICAgICAgICAgICAgInoiOi0xLjM3ODUwNjA2NDQxNDk3OA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRJdGVtIjp7DQogICAgICAgICAgICAgICAgICAgICJ6IjotMC4zNzEwOTM1NzExODYwNjU3DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0SXRlbSI6ew0KICAgICAgICAgICAgICAgICAgICAieSI6LTMuMDg2MDk1ODA5OTM2NTIzNA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjEyLA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRUlOUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEl0ZW0iOnsNCiAgICAgICAgICAgICAgICAgICAgInkiOi0xLjQ5NzAyNTQ4OTgwNzEyOQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRJdGVtIjp7DQogICAgICAgICAgICAgICAgICAgICJ5IjowLjA1MjI1ODM3MjMwNjgyMzczDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0SXRlbSI6ew0KICAgICAgICAgICAgICAgICAgICAicGl0Y2giOi0wLjY4NzMzNTYxMDM4OTcwOTUNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRJdGVtIjp7DQogICAgICAgICAgICAgICAgICAgICJwaXRjaCI6LTAuOTY3MzE0NTQxMzM5ODc0Mw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0sDQogICAgICAgICAgICB7DQogICAgICAgICAgICAgICAgInRpY2siOjE0LA0KICAgICAgICAgICAgICAgICJlYXNpbmciOiAiRUFTRU9VVFFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRJdGVtIjp7DQogICAgICAgICAgICAgICAgICAgICJwaXRjaCI6LTEuODEyMzM0NjU2NzE1MzkzDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0SXRlbSI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjowLjM5MDQxNzUxNjIzMTUzNjg3DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTIsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0SXRlbSI6ew0KICAgICAgICAgICAgICAgICAgICAieWF3IjowLjIwMDcxMTc3MTg0NTgxNzU3DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEl0ZW0iOnsNCiAgICAgICAgICAgICAgICAgICAgInlhdyI6LTAuMDAxODQ0ODUzMTYyNzY1NTAzDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTAsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFSU5RVUFEIiwNCiAgICAgICAgICAgICAgICAidHVybiI6IDAsDQogICAgICAgICAgICAgICAgInJpZ2h0SXRlbSI6ew0KICAgICAgICAgICAgICAgICAgICAicm9sbCI6LTIuNzA5OTYzNTYwMTA0MzcNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LA0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICJ0aWNrIjoxMiwNCiAgICAgICAgICAgICAgICAiZWFzaW5nIjogIkVBU0VJTlFVQUQiLA0KICAgICAgICAgICAgICAgICJ0dXJuIjogMCwNCiAgICAgICAgICAgICAgICAicmlnaHRJdGVtIjp7DQogICAgICAgICAgICAgICAgICAgICJyb2xsIjotMy4wOTY5MjUwMjAyMTc4OTU1DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAidGljayI6MTQsDQogICAgICAgICAgICAgICAgImVhc2luZyI6ICJFQVNFT1VUUVVBRCIsDQogICAgICAgICAgICAgICAgInR1cm4iOiAwLA0KICAgICAgICAgICAgICAgICJyaWdodEl0ZW0iOnsNCiAgICAgICAgICAgICAgICAgICAgInJvbGwiOi0zLjIyMDIyODY3MjAyNzU4OA0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgXQ0KICAgIH0NCn0NCg=="; -} diff --git a/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/mixin/AbstractClientPlayerMixin.java b/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/mixin/AbstractClientPlayerMixin.java new file mode 100644 index 0000000..4ecc54a --- /dev/null +++ b/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/mixin/AbstractClientPlayerMixin.java @@ -0,0 +1,2 @@ +package dev.kosmx.animatorTestmod.mixin;public class AbstractClientPlayerMixin { +} From 798edd6d262ae808b7883b0f9a5fc5c8284a1eeb Mon Sep 17 00:00:00 2001 From: KosmX Date: Thu, 28 Dec 2023 19:36:29 +0100 Subject: [PATCH 36/44] Update gradle and loom --- build.gradle | 6 ++--- gradle/wrapper/gradle-wrapper.jar | Bin 61608 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 3 ++- gradlew | 29 +++++++++++++---------- 4 files changed, 22 insertions(+), 16 deletions(-) mode change 100644 => 100755 gradlew diff --git a/build.gradle b/build.gradle index a699dbf..a926a73 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,11 @@ plugins { id "architectury-plugin" version "3.4-SNAPSHOT" - id "dev.architectury.loom" version "1.1.+" apply false + id "dev.architectury.loom" version "1.3.+" apply false //Publishing id 'com.matthewprenger.cursegradle' version '1.4.0' apply false - id "com.modrinth.minotaur" version "2.7.4" apply false - id 'com.github.johnrengelman.shadow' version '8.1.0' apply false + id "com.modrinth.minotaur" version "2.8.7" apply false + id 'com.github.johnrengelman.shadow' version '8.1.1' apply false } architectury { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index ccebba7710deaf9f98673a68957ea02138b60d0a..d64cd4917707c1f8861d8cb53dd15194d4248596 100644 GIT binary patch literal 43462 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 literal 61608 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bdc9a83..1af9e09 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 index 79a61d4..1aa94a4 --- a/gradlew +++ b/gradlew @@ -83,10 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,10 +131,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ From e436fbe62814b09b638ecad4478454030b66daad Mon Sep 17 00:00:00 2001 From: KosmX Date: Thu, 28 Dec 2023 21:13:11 +0100 Subject: [PATCH 37/44] Replace keyframe finding algorithm with binary search, this should make things a little bit faster. --- .../core/data/KeyframeAnimation.java | 11 +++-- .../core/data/KeyframeAnimationTest.java | 48 +++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 coreLib/src/test/java/dev/kosmx/playerAnim/core/data/KeyframeAnimationTest.java diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/data/KeyframeAnimation.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/data/KeyframeAnimation.java index d22407b..b2bfa7d 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/data/KeyframeAnimation.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/data/KeyframeAnimation.java @@ -449,9 +449,14 @@ public int length() { * @return given keyframe */ public int findAtTick(int tick) { - int i = -1; - while (this.keyFrames.size() > i + 1 && this.keyFrames.get(i + 1).tick <= tick) { - i++; + int i = Collections.binarySearch(this.keyFrames, null, (frame, ignore) -> Integer.compare(frame.tick, tick)); + if (i < 0) { + i = -i - 2; + } + + // small correction for edge-case: it is possible to have two keyframes with the same tick in the array, in that case, I should return the later one. + if (i + 1 < keyFrames.size() && keyFrames.get(i + 1).tick == tick) { + return i + 1; } return i; } diff --git a/coreLib/src/test/java/dev/kosmx/playerAnim/core/data/KeyframeAnimationTest.java b/coreLib/src/test/java/dev/kosmx/playerAnim/core/data/KeyframeAnimationTest.java new file mode 100644 index 0000000..bc089c4 --- /dev/null +++ b/coreLib/src/test/java/dev/kosmx/playerAnim/core/data/KeyframeAnimationTest.java @@ -0,0 +1,48 @@ +package dev.kosmx.playerAnim.core.data; + +import dev.kosmx.playerAnim.core.util.Ease; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Random; + +public class KeyframeAnimationTest { + @Test + public void testKeyframeAnimation() { + KeyframeAnimation.StateCollection.State state = new KeyframeAnimation.StateCollection(0).x; + // Easy case + state.addKeyFrame(1, 0, Ease.CONSTANT); + state.addKeyFrame(5, 0, Ease.CONSTANT); + state.addKeyFrame(10, 10, Ease.CONSTANT); + state.addKeyFrame(10, 10, Ease.CONSTANT); + + state.addKeyFrame(15, 10, Ease.CONSTANT); + + verify(state); + state.getKeyFrames().clear(); + + + // random case + Random random = new Random(); + + for (int i = 0; i < 10000; i += random.nextInt(100)) { + state.addKeyFrame(i, i, Ease.CONSTANT); + } + + verify(state); + } + + public static void verify(KeyframeAnimation.StateCollection.State state) { + + for (int t = 0; t < state.getKeyFrames().size(); t++) { + // Iterative, 100% works algorithm + + int i = -1; + while (state.getKeyFrames().size() > i + 1 && state.getKeyFrames().get(i + 1).tick <= t) { + i++; + } + + Assertions.assertEquals(i, state.findAtTick(t), "KeyframeAnimationTest failed at tick " + t); + } + } +} From eaee4eb4c323f9742e1ec093780885ed1abb926d Mon Sep 17 00:00:00 2001 From: KosmX Date: Thu, 28 Dec 2023 21:13:32 +0100 Subject: [PATCH 38/44] use lombok if possible --- .../src/main/java/dev/kosmx/playerAnim/core/util/Ease.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java index 8efd652..7c34d57 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java @@ -1,5 +1,7 @@ package dev.kosmx.playerAnim.core.util; +import lombok.Getter; + /** * Easings form easings.net
* + constant + linear @@ -17,6 +19,7 @@ public enum Ease { INELASTIC(30, Easing::inElastic), OUTELASTIC(31, Easing::outElastic), INOUTELASTIC(32, Easing::inOutElastic), INBOUNCE(33, Easing::inBounce), OUTBOUNCE(34, Easing::outBack), INOUTBOUNCE(35, Easing::inOutBounce); + @Getter final byte id; private final _F impl; @@ -37,10 +40,6 @@ public enum Ease { this((byte) id, impl); } - public byte getId() { - return id; - } - /** * Run the easing * @param f float between 0 and 1 From fdee49c5b61ec01706710694bfae7f3576ea3f30 Mon Sep 17 00:00:00 2001 From: KosmX Date: Thu, 28 Dec 2023 21:15:00 +0100 Subject: [PATCH 39/44] Skip bendy-lib linear algebra if not necessary, this alone should speed-up some stuff --- .../dev/kosmx/playerAnim/impl/animation/BendHelper.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/BendHelper.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/BendHelper.java index 18729cf..1487466 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/BendHelper.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/BendHelper.java @@ -14,8 +14,13 @@ public class BendHelper implements IBendHelper { @Override - public void bend(ModelPart modelPart, float a, float b){ - ModelPartAccessor.optionalGetCuboid(modelPart, 0).ifPresent(mutableCuboid -> ((BendableCuboid)mutableCuboid.getAndActivateMutator("bend")).applyBend(a, b)); + public void bend(ModelPart modelPart, float axis, float rotation){ + // Don't enable bend until rotation is bigger than epsilon. This should avoid unnecessary heavy calculations. + if (Math.abs(rotation) >= 0.0001f) { + ModelPartAccessor.optionalGetCuboid(modelPart, 0).ifPresent(mutableCuboid -> ((BendableCuboid) mutableCuboid.getAndActivateMutator("bend")).applyBend(axis, rotation)); + } else { + ModelPartAccessor.optionalGetCuboid(modelPart, 0).ifPresent(mutableCuboid -> mutableCuboid.getAndActivateMutator(null)); + } } @Override From 12e098d3dfd32217504de0b6b701f5500060a848 Mon Sep 17 00:00:00 2001 From: KosmX Date: Tue, 6 Dec 2022 15:44:38 +0100 Subject: [PATCH 40/44] internal refactor --- .../api/layered/KeyframeAnimationPlayer.java | 2 +- .../modifier/AbstractFadeModifier.java | 4 +- .../dev/kosmx/playerAnim/core/util/Ease.java | 44 +++++++--- .../kosmx/playerAnim/core/util/Easing.java | 85 +++---------------- 4 files changed, 45 insertions(+), 90 deletions(-) diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java index 48e6953..0b63d7f 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/KeyframeAnimationPlayer.java @@ -311,7 +311,7 @@ protected final float getValueFromKeyframes(KeyframeAnimation.KeyFrame before, K } if (tickBefore == tickAfter) return before.value; float f = (currentTick + tickDelta - (float) tickBefore) / (tickAfter - tickBefore); - return MathHelper.lerp(Easing.easingFromEnum(data.isEasingBefore ? after.ease : before.ease, f), before.value, after.value); + return MathHelper.lerp((data.isEasingBefore ? after.ease : before.ease).invoke(f), before.value, after.value); } } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java index 9a7b803..8c9c556 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/api/layered/modifier/AbstractFadeModifier.java @@ -3,10 +3,8 @@ import dev.kosmx.playerAnim.api.TransformType; import dev.kosmx.playerAnim.api.layered.IAnimation; import dev.kosmx.playerAnim.core.util.Ease; -import dev.kosmx.playerAnim.core.util.Easing; import dev.kosmx.playerAnim.core.util.Vec3f; import lombok.Setter; - import org.jetbrains.annotations.Nullable; /** @@ -89,7 +87,7 @@ public static AbstractFadeModifier standardFadeIn(int length, Ease ease) { return new AbstractFadeModifier(length) { @Override protected float getAlpha(String modelName, TransformType type, float progress) { - return Easing.easingFromEnum(ease, progress); + return ease.invoke(progress); } }; } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java index 0c40466..8efd652 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java @@ -5,33 +5,51 @@ * + constant + linear */ public enum Ease { - LINEAR(0), CONSTANT(1), - INSINE(6), OUTSINE(7), INOUTSINE(8), INCUBIC(9), OUTCUBIC(10), INOUTCUBIC(11), - INQUAD(12), OUTQUAD(13), INOUTQUAD(14), INQUART(15), OUTQUART(16), INOUTQUART(17), - INQUINT(18), OUTQUINT(19), INOUTQUINT(20), INEXPO(21), OUTEXPO(22), INOUTEXPO(23), - INCIRC(24), OUTCIRC(25), INOUTCIRC(26), INBACK(27), OUTBACK(28), INOUTBACK(29), - INELASTIC(30), OUTELASTIC(31), INOUTELASTIC(32), INBOUNCE(33), OUTBOUNCE(34), INOUTBOUNCE(35); + LINEAR(0, f -> f), CONSTANT(1, f -> 0f), + INSINE(6, Easing::inSine), OUTSINE(7, Easing::outSine), INOUTSINE(8, Easing::inOutSine), + INCUBIC(9, Easing::inCubic), OUTCUBIC(10, Easing::outCubic), INOUTCUBIC(11, Easing::inOutCubic), + INQUAD(12, Easing::inQuad), OUTQUAD(13, Easing::outQuad), INOUTQUAD(14, Easing::inOutQuad), + INQUART(15, Easing::inQuart), OUTQUART(16, Easing::outQuart), INOUTQUART(17, Easing::inOutQuart), + INQUINT(18, Easing::inQuint), OUTQUINT(19, Easing::outQuint), INOUTQUINT(20, Easing::inOutQuint), + INEXPO(21, Easing::inExpo), OUTEXPO(22, Easing::outExpo), INOUTEXPO(23, Easing::inOutExpo), + INCIRC(24, Easing::inCirc), OUTCIRC(25, Easing::outCirc), INOUTCIRC(26, Easing::inOutCirc), + INBACK(27, Easing::inBack), OUTBACK(28, Easing::outBack), INOUTBACK(29, Easing::inOutBack), + INELASTIC(30, Easing::inElastic), OUTELASTIC(31, Easing::outElastic), INOUTELASTIC(32, Easing::inOutElastic), + INBOUNCE(33, Easing::inBounce), OUTBOUNCE(34, Easing::outBack), INOUTBOUNCE(35, Easing::inOutBounce); final byte id; + private final _F impl; /** - * @param id id + * @param id id + * @param impl implementation */ - Ease(byte id){ + Ease(byte id, _F impl){ this.id = id; + this.impl = impl; } /** - * @param id id + * @param id id + * @param impl implementation */ - Ease(int id) { - this((byte) id); + Ease(int id, _F impl) { + this((byte) id, impl); } public byte getId() { return id; } + /** + * Run the easing + * @param f float between 0 and 1 + * @return ease(f) + */ + public float invoke(float f) { + return impl.invoke(f); + } + //To be able to send these as bytes instead of String names. public static Ease getEase(byte b){ for(Ease ease:Ease.values()){ @@ -39,4 +57,8 @@ public static Ease getEase(byte b){ } return LINEAR; } + + private interface _F { + float invoke(float f); + } } diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java index 72f49bc..88851e9 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Easing.java @@ -1,86 +1,22 @@ package dev.kosmx.playerAnim.core.util; +import org.jetbrains.annotations.Nullable; + public class Easing { - /* + /** * Easing functions from easings.net * All function have a string codename * EasingFromString - * + *

* All function needs an input between 0 and 1 * except + * @deprecated Just use {@link Ease#invoke(float)} */ - public static float easingFromEnum(Ease type, float f){ - switch(type){ - case INOUTSINE: - return inOutSine(f); - case INSINE: - return inSine(f); - case OUTSINE: - return outSine(f); - case INCUBIC: - return inCubic(f); - case OUTCUBIC: - return outCubic(f); - case LINEAR: - return f; - case INOUTCUBIC: - return inOutCubic(f); - case INQUAD: - return inQuad(f); - case INQUART: - return inQuart(f); - case OUTQUAD: - return outQuad(f); - case OUTQUART: - return outQuart(f); - case INOUTQUAD: - return inOutQuad(f); - case INOUTQUART: - return inOutQuart(f); - case INBACK: - return inBack(f); - case INCIRC: - return inCirc(f); - case INEXPO: - return inExpo(f); - case INQUINT: - return inQuint(f); - case OUTBACK: - return outBack(f); - case OUTCIRC: - return outCirc(f); - case OUTEXPO: - return outExpo(f); - case INBOUNCE: - return inBounce(f); - case OUTQUINT: - return outQuint(f); - case INELASTIC: - return inElastic(f); - case INOUTBACK: - return inOutBack(f); - case INOUTCIRC: - return inOutCirc(f); - case INOUTEXPO: - return inOutExpo(f); - case OUTBOUNCE: - return outBounce(f); - case INOUTQUINT: - return inOutQuint(f); - case OUTELASTIC: - return outElastic(f); - case INOUTBOUNCE: - return inOutBounce(f); - case INOUTELASTIC: - return inOutElastic(f); - case CONSTANT: - return 0; - default: - //CommonData.logger.warn("easing function unknown: " + type); - return f; - } + @Deprecated + public static float easingFromEnum(@Nullable Ease type, float f) { + return type != null ? type.invoke(f) : f; } /** @@ -90,11 +26,11 @@ public static float easingFromEnum(Ease type, float f){ public static Ease easeFromString(String string){ try{ if(string.equals("step"))return Ease.CONSTANT; - if(string.substring(0, 4).toUpperCase().equals("EASE")){ + if(string.substring(0, 4).equalsIgnoreCase("EASE")){ string = string.substring(4); } return Ease.valueOf(string.toUpperCase()); - }catch(Exception exception){ + } catch(Exception exception){ //Main.log(Level.ERROR, "Ease name unknown: \"" + string + "\" using linear", true); //Main.log(Level.WARN, exception.toString()); return Ease.LINEAR; @@ -195,7 +131,6 @@ public static float inOutCirc(float x){ } public static float inBack(float x){ - return c3 * x * x * x - c1 * x * x; } From 11dda4c6fe3eaafd084c6d01710bceb5ab052053 Mon Sep 17 00:00:00 2001 From: KosmX Date: Wed, 14 Dec 2022 13:06:31 +0100 Subject: [PATCH 41/44] Update issue templates --- .github/ISSUE_TEMPLATE/api-bug-report.md | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/api-bug-report.md diff --git a/.github/ISSUE_TEMPLATE/api-bug-report.md b/.github/ISSUE_TEMPLATE/api-bug-report.md new file mode 100644 index 0000000..0be617d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/api-bug-report.md @@ -0,0 +1,36 @@ +--- +name: API bug report +about: Issue about the API (not the buildscript) +title: "[API]" +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. + +**Setup config (minecraft, modloader, libraries):** + - Minecraft version: [e.g. 1.19.3] + - Mod loader: [e.g. Fabric 0.14.11] + - PlayerAnimator Library version [e.g. 0.4.0+1.19.3] + - MC library version (e.g. Fabric API version) + +**Other mods (If you use other mods, please specify! it might be an incompatibility):** + +*Optional:* +** Used library methods, ideas (If you're a developer, what function is not working as expected)** +Add any other context about the problem here. From d68ba26c9c2423eb72bdb422c4751b18cbd569a7 Mon Sep 17 00:00:00 2001 From: KosmX Date: Wed, 14 Dec 2022 13:25:08 +0100 Subject: [PATCH 42/44] Update issue templates --- .github/ISSUE_TEMPLATE/api-bug-report.md | 2 +- .github/ISSUE_TEMPLATE/buildscript-error.md | 33 +++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 +++++++++++++ .github/ISSUE_TEMPLATE/library-crash.md | 32 ++++++++++++++++++++ 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 .github/ISSUE_TEMPLATE/buildscript-error.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/library-crash.md diff --git a/.github/ISSUE_TEMPLATE/api-bug-report.md b/.github/ISSUE_TEMPLATE/api-bug-report.md index 0be617d..426fa3f 100644 --- a/.github/ISSUE_TEMPLATE/api-bug-report.md +++ b/.github/ISSUE_TEMPLATE/api-bug-report.md @@ -3,7 +3,7 @@ name: API bug report about: Issue about the API (not the buildscript) title: "[API]" labels: bug -assignees: '' +assignees: KosmX --- diff --git a/.github/ISSUE_TEMPLATE/buildscript-error.md b/.github/ISSUE_TEMPLATE/buildscript-error.md new file mode 100644 index 0000000..76f4162 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/buildscript-error.md @@ -0,0 +1,33 @@ +--- +name: Buildscript error +about: Something is wrong with buildscript +title: '' +labels: build +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**Buildscript content or link to content (If you don't share your code, I cannot debug it):** +https://github.com/KosmX/fabricPlayerAnimatorExample/blob/1.19/build.gradle + +**To Reproduce** +Steps to reproduce the behavior: +1. Run `gradle runClient` +2. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Environment (please complete the following information):** + - OS: [e.g. Windows 11, Archlinux, Ubuntu 22.04] + - IDE [e.g. IntelliJ, Eclipse, vim+bash] + - Gradle version [e.g. 7.5.1] + - JDK version [e.g. 17.0.5 - Adoptium] + - gradle plugin [e.g. Fabric loom, ForgeGradle] (if I don't see it in your project) + - Minecraft, Loader: (Fabric 0.14.11+1.19.2) + +**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..11fc491 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +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. diff --git a/.github/ISSUE_TEMPLATE/library-crash.md b/.github/ISSUE_TEMPLATE/library-crash.md new file mode 100644 index 0000000..addee12 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/library-crash.md @@ -0,0 +1,32 @@ +--- +name: Library crash +about: User crash report +title: '' +labels: bug, library +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 + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Crash report (please copy the whole crash report!)** +``` +Minecraft 1.19.3 +... +``` + +**Logs (if you have logs from that run, please share it):** +``` +... +``` From 8b5adb396b1ecead20ff8ea42f4df914ffd89002 Mon Sep 17 00:00:00 2001 From: Gcat101 Date: Sat, 12 Oct 2024 23:20:20 +0300 Subject: [PATCH 43/44] Start fixing conflicts --- .../java/dev/kosmx/playerAnim/core/util/MathHelper.java | 5 +++++ gradle.properties | 3 +-- minecraft/fabric/build.gradle | 6 +++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/MathHelper.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/MathHelper.java index 1d1a976..36401c1 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/MathHelper.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/MathHelper.java @@ -22,6 +22,11 @@ public static int colorHelper(int r, int g, int b, int a){ return ((a & 255) << 24) | ((r & 255) << 16) | ((g & 255) << 8) | (b & 255); //Sometimes minecraft uses ints as color... } + /** + * Clamp f to -Pi until Pi range + * @param f radians + * @return radians + */ public static float clampToRadian(float f){ final double a = Math.PI*2; double b = ((f + Math.PI)%a); diff --git a/gradle.properties b/gradle.properties index fef90ba..6876737 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -org.gradle.jvmargs=-Xmx2048M +org.gradle.jvmargs=-Xmx4G minecraft_version=1.16.5 enabled_platforms=fabric,forge @@ -8,7 +8,6 @@ archives_base_name=player-animation-lib mod_version=0.4.0 maven_group=dev.kosmx.player-anim - fabric_loader_version=0.14.9 fabric_api_version=0.42.0+1.16 diff --git a/minecraft/fabric/build.gradle b/minecraft/fabric/build.gradle index 428d14b..3b9601c 100644 --- a/minecraft/fabric/build.gradle +++ b/minecraft/fabric/build.gradle @@ -53,7 +53,11 @@ dependencies { common(shadowCommon(project(path: ":coreLib")) {transitive false}) {transitive false} //Why can I nest these? //Testing libraries - //modImplementation "io.github.kosmx.bendy-lib:bendy-lib-fabric:${project.bendy_lib}" + modLocalRuntime "io.github.kosmx.bendy-lib:bendy-lib-fabric:${project.bendy_lib}" + modLocalRuntime "maven.modrinth:3dskinlayers:1.6.7" + modLocalRuntime "maven.modrinth:emotecraft:2.2.6-SNAPSHOT-build.44-MC1.16.5-fabric" + modLocalRuntime "maven.modrinth:modmenu:1.16.23" + modLocalRuntime "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" modImplementation fabricApi.module("fabric-resource-loader-v0", project.fabric_api_version) From 16093a9e9bf4e46585691fdb4fabdf7455318796 Mon Sep 17 00:00:00 2001 From: Gcat101 Date: Tue, 22 Oct 2024 22:04:08 +0300 Subject: [PATCH 44/44] Backport 2.1.1 to 1.16.5 --- build.gradle | 2 +- .../dev/kosmx/playerAnim/core/util/Ease.java | 9 -- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../kosmx/playerAnim/impl/IBendHelper.java | 74 ---------- .../kosmx/playerAnim/impl/IMutableModel.java | 2 + .../impl/animation/AnimationApplier.java | 6 +- .../playerAnim/impl/animation/BendHelper.java | 81 ++--------- .../impl/animation/IBendHelper.java | 51 +++++++ .../mixin/BipedEntityModelMixin.java | 133 ++++-------------- .../LivingEntityRenderRedirect_bendOnly.java | 2 +- .../playerAnim/mixin/PlayerModelMixin.java | 91 ++++-------- .../playerAnim/mixin/PlayerRendererMixin.java | 14 +- .../firstPerson/ItemInHandRendererMixin.java | 10 +- .../mixin/firstPerson/LevelRendererMixin.java | 3 +- .../LivingEntityRendererMixin.java | 5 +- minecraft/fabric/build.gradle | 1 + .../animatorTestmod/AnimationRegistry.java | 43 ------ .../src/testmod/resources/testmod.mixins.json | 2 +- minecraft/forge/build.gradle | 3 +- 20 files changed, 148 insertions(+), 388 deletions(-) delete mode 100644 minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/IBendHelper.java create mode 100644 minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/IBendHelper.java delete mode 100644 minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/AnimationRegistry.java diff --git a/build.gradle b/build.gradle index 30b9e3f..ba8fbd3 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id "architectury-plugin" version "3.4-SNAPSHOT" - id "dev.architectury.loom" version "1.3.+" apply false + id "dev.architectury.loom" version "1.6-SNAPSHOT" apply false //Publishing id 'com.matthewprenger.cursegradle' version '1.4.0' apply false diff --git a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java index 69e0946..7c34d57 100644 --- a/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java +++ b/coreLib/src/main/java/dev/kosmx/playerAnim/core/util/Ease.java @@ -49,15 +49,6 @@ public float invoke(float f) { return impl.invoke(f); } - /** - * Run the easing - * @param f float between 0 and 1 - * @return ease(f) - */ - public float invoke(float f) { - return impl.invoke(f); - } - //To be able to send these as bytes instead of String names. public static Ease getEase(byte b){ for(Ease ease:Ease.values()){ diff --git a/gradle.properties b/gradle.properties index fa9b69d..90da2cb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,4 +13,4 @@ fabric_api_version=0.42.0+1.16 forge_version=1.16.5-36.2.39 -bendy_lib=1.2.1 +bendy_lib=2.1.1 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e09..a441313 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/IBendHelper.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/IBendHelper.java deleted file mode 100644 index e1a10e4..0000000 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/IBendHelper.java +++ /dev/null @@ -1,74 +0,0 @@ -package dev.kosmx.playerAnim.impl; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Vector3f; -import dev.kosmx.playerAnim.core.impl.AnimationProcessor; -import dev.kosmx.playerAnim.core.util.Pair; -import dev.kosmx.playerAnim.core.util.SetableSupplier; -import dev.kosmx.playerAnim.impl.animation.BendHelper; -import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.core.Direction; - -import javax.annotation.Nullable; - -public interface IBendHelper { - - static void rotateMatrixStack(PoseStack matrices, Pair pair){ - float offset = 0.375f; - matrices.translate(0, offset, 0); - float bend = pair.getRight(); - float axisf = - pair.getLeft(); - Vector3f axis = new Vector3f((float) Math.cos(axisf), 0, (float) Math.sin(axisf)); - //return this.setRotation(axis.getRadialQuaternion(bend)); - matrices.mulPose(axis.rotation(bend)); - matrices.translate(0, - offset, 0); - } - - static IBendHelper create(ModelPart modelPart, boolean isUpperPart, @Nullable SetableSupplier emote){ - return Helper.isBendEnabled() ? BendHelper.createNew(modelPart, isUpperPart, emote) : new DummyBendable(); - } - - static IBendHelper create(ModelPart modelPart, @Nullable SetableSupplier emote){ - return create(modelPart, false, emote); - } - - static IBendHelper create(ModelPart modelPart, boolean isUpperPart) { - return create(modelPart, isUpperPart, null); - } - - void addBendedCuboid(int i, int i1, int i2, int i3, int i4, int i5, float scale, Direction up); - - void setAnimation(SetableSupplier emoteSupplier); - - default void bend(Pair vec) { - this.bend(vec.getLeft(), vec.getRight()); - } - - void bend(float a, float b); - - void copyBend(IBendHelper torso); - - - class DummyBendable implements IBendHelper { - - @Override - public void addBendedCuboid(int i, int i1, int i2, int i3, int i4, int i5, float scale, Direction up) { - - } - - @Override - public void setAnimation(SetableSupplier emoteSupplier) { - - } - - @Override - public void bend(float a, float b) { - - } - - @Override - public void copyBend(IBendHelper torso) { - - } - } -} diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/IMutableModel.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/IMutableModel.java index d04dcbf..2e5a81a 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/IMutableModel.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/IMutableModel.java @@ -2,6 +2,8 @@ import dev.kosmx.playerAnim.core.impl.AnimationProcessor; import dev.kosmx.playerAnim.core.util.SetableSupplier; +import dev.kosmx.playerAnim.impl.animation.IBendHelper; + import org.jetbrains.annotations.ApiStatus; @ApiStatus.Internal diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/AnimationApplier.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/AnimationApplier.java index 90349be..9f81235 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/AnimationApplier.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/AnimationApplier.java @@ -25,7 +25,9 @@ public void updatePart(String partName, ModelPart part) { MathHelper.clampToRadian(part.xRot), MathHelper.clampToRadian(part.yRot), MathHelper.clampToRadian(part.zRot))); - part.setRotation(rot.getX(), rot.getY(), rot.getZ()); + part.xRot = rot.getX(); + part.yRot = rot.getY(); + part.zRot = rot.getZ(); if (!partName.equals("head")) { if (partName.equals("torso")) { Pair torsoBend = getBend(partName); @@ -37,4 +39,4 @@ public void updatePart(String partName, ModelPart part) { } } -} +} \ No newline at end of file diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/BendHelper.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/BendHelper.java index 91be3d7..72b8e8b 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/BendHelper.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/BendHelper.java @@ -1,28 +1,16 @@ package dev.kosmx.playerAnim.impl.animation; -import com.mojang.math.Matrix4f; -import dev.kosmx.playerAnim.core.impl.AnimationProcessor; -import dev.kosmx.playerAnim.core.util.SetableSupplier; -import dev.kosmx.playerAnim.impl.IBendHelper; -import dev.kosmx.playerAnim.impl.IUpperPartHelper; -import io.github.kosmx.bendylib.IModelPart; -import io.github.kosmx.bendylib.MutableModelPart; +import dev.kosmx.playerAnim.core.util.Pair; +import io.github.kosmx.bendylib.ModelPartAccessor; import io.github.kosmx.bendylib.impl.BendableCuboid; import net.minecraft.client.model.geom.ModelPart; import net.minecraft.core.Direction; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.NotNull; @ApiStatus.Internal -public class BendHelper extends MutableModelPart implements IBendHelper { - - @Nullable - protected SetableSupplier emote; - protected float axis = 0; - protected float angl = 0; - +public class BendHelper implements IBendHelper { @Override public void bend(ModelPart modelPart, float axis, float rotation){ @@ -35,61 +23,18 @@ public void bend(ModelPart modelPart, float axis, float rotation){ } @Override - public String modId(){ - return "playerAnimator"; - } - - - /** - * This mod has always 4 priority, but not always active. - * - * @return 0 - */ - @Override - public int getPriority(){ - return 4; - } - - public Matrix4f getMatrix4f(){ - return ((BendableCuboid) this.iCuboids.get(0)).getLastPosMatrix(); - } - - public BendableCuboid getCuboid(){ - return (BendableCuboid) this.iCuboids.get(0); - } - - @Override - public boolean isActive(){ - return this.emote != null && this.emote.get() != null && this.emote.get().isActive() && angl != 0; - } - - @Override - public void setAnimation(@Nullable SetableSupplier emote){ - this.emote = emote; - } - - @Nullable - public SetableSupplier getEmote(){ - return emote; - } - - @Override - public void bend(float a, float b){ - this.axis = a; - this.angl = b; - ((BendableCuboid) this.iCuboids.get(0)).applyBend(a, b); - } - - - public void copyBend(@NotNull IBendHelper mutableModelPart){ - if (mutableModelPart instanceof BendHelper) { - BendHelper modelPart = (BendHelper) mutableModelPart; - this.bend(modelPart.axis, modelPart.angl); + public void bend(ModelPart modelPart, @Nullable Pair pair){ + if(pair != null) { + this.bend(modelPart, pair.getLeft(), pair.getRight()); + } + else { + //ModelPartAccessor.getCuboid(modelPart, 0).getAndActivateMutator(null); + ModelPartAccessor.optionalGetCuboid(modelPart, 0).ifPresent(mutableCuboid -> mutableCuboid.getAndActivateMutator(null)); } } @Override - public void addBendedCuboid(int i, int i1, int i2, int i3, int i4, int i5, float scale, Direction up) { - this.addCuboid(i, i1, i2, i3, i4, i5, scale, up); + public void initBend(ModelPart modelPart, Direction direction) { + ModelPartAccessor.optionalGetCuboid(modelPart, 0).ifPresent(mutableModelPart -> mutableModelPart.registerMutator("bend", data -> new BendableCuboid.Builder().setDirection(direction).build(data))); } -} +} \ No newline at end of file diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/IBendHelper.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/IBendHelper.java new file mode 100644 index 0000000..e0cdf0b --- /dev/null +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/impl/animation/IBendHelper.java @@ -0,0 +1,51 @@ +package dev.kosmx.playerAnim.impl.animation; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Vector3f; +import dev.kosmx.playerAnim.core.util.Pair; +import dev.kosmx.playerAnim.impl.Helper; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.core.Direction; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +@ApiStatus.Internal +public interface IBendHelper { + + IBendHelper INSTANCE = Helper.isBendEnabled() ? new BendHelper() : new DummyBendable(); + static void rotateMatrixStack(PoseStack matrices, Pair pair){ + float offset = 0.375f; + matrices.translate(0, offset, 0); + float bend = pair.getRight(); + float axisf = - pair.getLeft(); + Vector3f axis = new Vector3f((float) Math.cos(axisf), 0, (float) Math.sin(axisf)); + //return this.setRotation(axis.getRadialQuaternion(bend)); + matrices.mulPose(axis.rotation(bend)); + matrices.translate(0, - offset, 0); + } + + void bend(ModelPart modelPart, float a, float b); + + void bend(ModelPart modelPart, @Nullable Pair pair); + + void initBend(ModelPart modelPart, Direction direction); + + class DummyBendable implements IBendHelper { + + @Override + public void bend(ModelPart modelPart, float a, float b) { + + } + + @Override + public void bend(ModelPart modelPart, @org.jetbrains.annotations.Nullable Pair pair) { + + } + + @Override + public void initBend(ModelPart modelPart, Direction direction) { + + } + } +} \ No newline at end of file diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/BipedEntityModelMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/BipedEntityModelMixin.java index 01e0623..ab853be 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/BipedEntityModelMixin.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/BipedEntityModelMixin.java @@ -6,67 +6,50 @@ import dev.kosmx.playerAnim.core.util.SetableSupplier; import dev.kosmx.playerAnim.impl.Helper; import dev.kosmx.playerAnim.impl.IMutableModel; -import dev.kosmx.playerAnim.impl.IBendHelper; +import dev.kosmx.playerAnim.impl.animation.IBendHelper; import dev.kosmx.playerAnim.impl.IUpperPartHelper; import net.minecraft.client.model.AgeableListModel; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.geom.ModelPart; -import net.minecraft.client.renderer.RenderType; import net.minecraft.core.Direction; -import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.LivingEntity; 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.CallbackInfo; -import java.util.function.Function; - @Mixin(HumanoidModel.class) public abstract class BipedEntityModelMixin extends AgeableListModel implements IMutableModel { + @Final @Shadow public ModelPart rightArm; + @Final @Shadow public ModelPart leftArm; + @Final + @Shadow + public ModelPart rightLeg; + @Final + @Shadow + public ModelPart leftLeg; @Unique private SetableSupplier animation = new SetableSupplier<>(); - @Unique - private IBendHelper mutatedTorso; - @Unique - private IBendHelper mutatedRightArm; - @Unique - private IBendHelper mutatedLeftArm; - @Unique - private IBendHelper mutatedLeftLeg; - @Unique - private IBendHelper mutatedRightLeg; - - @Inject(method = "(Ljava/util/function/Function;FFII)V", at = @At("RETURN")) - private void initBend(Function texturedLayerFactory, float scale, float pivotY, int textureWidth, int textureHeight, CallbackInfo ci){ - mutatedLeftArm = IBendHelper.create(this.leftArm, true); - mutatedLeftLeg = IBendHelper.create(this.leftLeg, false); - mutatedRightArm = IBendHelper.create(this.rightArm, true); - mutatedRightLeg = IBendHelper.create(this.rightLeg, false); - mutatedTorso = IBendHelper.create(this.body, false); - ((IUpperPartHelper) this.head).setUpperPart(true); - ((IUpperPartHelper) this.hat).setUpperPart(true); - - mutatedTorso.addBendedCuboid(- 4, 0, - 2, 8, 12, 4, scale, Direction.DOWN); - mutatedRightLeg.addBendedCuboid(- 2, 0, - 2, 4, 12, 4, scale, Direction.UP); - mutatedLeftLeg.addBendedCuboid(- 2, 0, - 2, 4, 12, 4, scale, Direction.UP); - - mutatedLeftArm.addBendedCuboid(- 1, - 2, - 2, 4, 12, 4, scale, Direction.UP); - mutatedRightArm.addBendedCuboid(- 3, - 2, - 2, 4, 12, 4, scale, Direction.UP); + @Inject(method = "(F)V", at = @At("RETURN")) + private void initBend(CallbackInfo ci){ + IBendHelper.INSTANCE.initBend(body, Direction.DOWN); + IBendHelper.INSTANCE.initBend(rightArm, Direction.UP); + IBendHelper.INSTANCE.initBend(leftArm, Direction.UP); + IBendHelper.INSTANCE.initBend(rightLeg, Direction.UP); + IBendHelper.INSTANCE.initBend(leftLeg, Direction.UP); + ((IUpperPartHelper)rightArm).setUpperPart(true); + ((IUpperPartHelper)leftArm).setUpperPart(true); + ((IUpperPartHelper)head).setUpperPart(true); + ((IUpperPartHelper)hat).setUpperPart(true); } @Override - public void setEmoteSupplier(SetableSupplier emoteSupplier) { - this.mutatedLeftLeg.setAnimation(emoteSupplier); - this.mutatedRightLeg.setAnimation(emoteSupplier); - this.mutatedLeftArm.setAnimation(emoteSupplier); - this.mutatedRightArm.setAnimation(emoteSupplier); - this.mutatedTorso.setAnimation(emoteSupplier); + public void setEmoteSupplier(SetableSupplier emoteSupplier){ this.animation = emoteSupplier; } @@ -74,15 +57,6 @@ public void setEmoteSupplier(SetableSupplier emoteSupplier) private void copyMutatedAttributes(HumanoidModel bipedEntityModel, CallbackInfo ci){ if(animation != null) { ((IMutableModel) bipedEntityModel).setEmoteSupplier(animation); - if (animation.get() != null && animation.get().isActive()) { - IMutableModel thisWithMixin = (IMutableModel) bipedEntityModel; - AnimationProcessor playedEmote = animation.get(); - thisWithMixin.getTorso().bend(playedEmote.getBend("torso")); - thisWithMixin.getLeftArm().bend(playedEmote.getBend("leftArm")); - thisWithMixin.getLeftLeg().bend(playedEmote.getBend("leftLeg")); - thisWithMixin.getRightArm().bend(playedEmote.getBend("rightArm")); - thisWithMixin.getRightLeg().bend(playedEmote.getBend("rightLeg")); - } } } @@ -118,72 +92,15 @@ public void renderToBuffer(PoseStack matrices, VertexConsumer vertices, int ligh } else super.renderToBuffer(matrices, vertices, light, overlay, red, green, blue, alpha); } + @Final @Shadow public ModelPart body; - @Shadow - public ModelPart head; + @Shadow @Final public ModelPart head; - @Shadow - public ModelPart hat; - - @Shadow - public ModelPart leftLeg; - - @Shadow - public ModelPart rightLeg; + @Shadow @Final public ModelPart hat; @Override public SetableSupplier getEmoteSupplier(){ return animation; } - - @Override - public IBendHelper getTorso() { - return mutatedTorso; - } - - @Override - public IBendHelper getRightArm() { - return mutatedRightArm; - } - - @Override - public IBendHelper getLeftArm() { - return mutatedLeftArm; - } - - @Override - public IBendHelper getRightLeg() { - return mutatedRightLeg; - } - - @Override - public IBendHelper getLeftLeg() { - return mutatedLeftLeg; - } - - @Override - public void setTorso(IBendHelper v) { - mutatedTorso = v; - } - - @Override - public void setRightArm(IBendHelper v) { - mutatedRightArm= v; - } - - @Override - public void setLeftArm(IBendHelper v) { - mutatedLeftArm = v; - } - - @Override - public void setRightLeg(IBendHelper v) { - mutatedRightLeg = v; - } - - @Override - public void setLeftLeg(IBendHelper v) { - mutatedLeftLeg = v; - } -} +} \ No newline at end of file diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/LivingEntityRenderRedirect_bendOnly.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/LivingEntityRenderRedirect_bendOnly.java index 4042c3a..045c8ca 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/LivingEntityRenderRedirect_bendOnly.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/LivingEntityRenderRedirect_bendOnly.java @@ -3,8 +3,8 @@ import com.mojang.blaze3d.vertex.PoseStack; import dev.kosmx.playerAnim.impl.IAnimatedPlayer; import dev.kosmx.playerAnim.impl.IUpperPartHelper; +import dev.kosmx.playerAnim.impl.animation.IBendHelper; import dev.kosmx.playerAnim.impl.Helper; -import dev.kosmx.playerAnim.impl.IBendHelper; import net.minecraft.client.model.EntityModel; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.EntityRenderDispatcher; diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerModelMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerModelMixin.java index bc62710..4f28fc2 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerModelMixin.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerModelMixin.java @@ -1,13 +1,13 @@ package dev.kosmx.playerAnim.mixin; import dev.kosmx.playerAnim.core.impl.AnimationProcessor; -import dev.kosmx.playerAnim.core.util.Pair; import dev.kosmx.playerAnim.core.util.SetableSupplier; import dev.kosmx.playerAnim.impl.IAnimatedPlayer; import dev.kosmx.playerAnim.impl.IMutableModel; import dev.kosmx.playerAnim.impl.IPlayerModel; +import dev.kosmx.playerAnim.impl.IUpperPartHelper; import dev.kosmx.playerAnim.impl.animation.AnimationApplier; -import dev.kosmx.playerAnim.impl.IBendHelper; +import dev.kosmx.playerAnim.impl.animation.IBendHelper; import net.minecraft.client.model.HumanoidModel; import net.minecraft.client.model.PlayerModel; import net.minecraft.client.model.geom.ModelPart; @@ -40,69 +40,34 @@ public class PlayerModelMixin extends HumanoidModel i @Unique private boolean firstPersonNext = false; - - //private BendableModelPart mutatedTorso; - @Unique - - private IBendHelper mutatedJacket; - @Unique - - private IBendHelper mutatedRightSleeve; - @Unique - - private IBendHelper mutatedLeftSleeve; - @Unique - - private IBendHelper mutatedRightPantLeg; - @Unique - - private IBendHelper mutatedLeftPantLeg; - - @Unique - private IMutableModel thisWithMixin; public PlayerModelMixin(float f) { super(f); } - //private BendHelper mutatedTorso; - //private MutableModelPart head :D ... it were be funny XD - @Inject(method = "", at = @At("RETURN")) - private void initBendableStuff(float scale, boolean thinArms, CallbackInfo ci){ - thisWithMixin = (IMutableModel) this; + private void initBendableStuff(float f, boolean bl, CallbackInfo ci){ + IMutableModel thisWithMixin = (IMutableModel) this; emoteSupplier.set(null); - this.mutatedJacket = IBendHelper.create(this.jacket, false, emoteSupplier); - this.mutatedRightSleeve = IBendHelper.create(this.rightSleeve, true, emoteSupplier); - this.mutatedLeftSleeve = IBendHelper.create(this.leftSleeve, true, emoteSupplier); - this.mutatedRightPantLeg = IBendHelper.create(this.rightPants, emoteSupplier); - this.mutatedLeftPantLeg = IBendHelper.create(this.leftPants, emoteSupplier); - - thisWithMixin.setLeftArm(IBendHelper.create(this.leftArm, true)); - thisWithMixin.setRightArm(IBendHelper.create(this.rightArm, true)); thisWithMixin.setEmoteSupplier(emoteSupplier); - thisWithMixin.setLeftLeg(IBendHelper.create(this.leftLeg, false, emoteSupplier)); - thisWithMixin.getLeftLeg().addBendedCuboid(- 2, 0, - 2, 4, 12, 4, scale, Direction.UP); - - mutatedJacket.addBendedCuboid(- 4, 0, - 2, 8, 12, 4, scale + 0.25f, Direction.DOWN); - mutatedRightPantLeg.addBendedCuboid(- 2, 0, - 2, 4, 12, 4, scale + 0.25f, Direction.UP); - mutatedLeftPantLeg.addBendedCuboid(- 2, 0, - 2, 4, 12, 4, scale + 0.25f, Direction.UP); - if(thinArms){ - thisWithMixin.getLeftArm().addBendedCuboid(- 1, - 2, - 2, 3, 12, 4, scale, Direction.UP); - thisWithMixin.getRightArm().addBendedCuboid(- 2, - 2, - 2, 3, 12, 4, scale, Direction.UP); - mutatedLeftSleeve.addBendedCuboid(- 1, - 2, - 2, 3, 12, 4, scale + 0.25f, Direction.UP); - mutatedRightSleeve.addBendedCuboid(- 2, - 2, - 2, 3, 12, 4, scale + 0.25f, Direction.UP); - }else{ - thisWithMixin.getLeftArm().addBendedCuboid(- 1, - 2, - 2, 4, 12, 4, scale, Direction.UP); - thisWithMixin.getRightArm().addBendedCuboid(- 3, - 2, - 2, 4, 12, 4, scale, Direction.UP); - mutatedLeftSleeve.addBendedCuboid(- 1, - 2, - 2, 4, 12, 4, scale + 0.25f, Direction.UP); - mutatedRightSleeve.addBendedCuboid(- 3, - 2, - 2, 4, 12, 4, scale + 0.25f, Direction.UP); - } + addBendMutator(this.jacket, Direction.DOWN); + addBendMutator(this.rightPants, Direction.UP); + addBendMutator(this.rightSleeve, Direction.UP); + addBendMutator(this.leftPants, Direction.UP); + addBendMutator(this.leftSleeve, Direction.UP); + + ((IUpperPartHelper)rightSleeve).setUpperPart(true); + ((IUpperPartHelper)leftSleeve).setUpperPart(true); } + @Unique + private void addBendMutator(ModelPart part, Direction d){ + IBendHelper.INSTANCE.initBend(part, d); + } + @Unique private void setDefaultPivot(){ this.leftLeg.setPos(1.9F, 12.0F, 0.0F); @@ -147,26 +112,22 @@ private void setEmote(T livingEntity, float f, float g, float h, float i, float emote.updatePart("torso", this.body); - Pair torsoBend = emote.getBend("torso"); - Pair bodyBend = emote.getBend("body"); - thisWithMixin.getTorso().bend(new Pair<>(torsoBend.getLeft() + bodyBend.getLeft(), torsoBend.getRight() + bodyBend.getRight())); - thisWithMixin.getLeftArm().bend(emote.getBend("leftArm")); - thisWithMixin.getLeftLeg().bend(emote.getBend("leftLeg")); - thisWithMixin.getRightArm().bend(emote.getBend("rightArm")); - thisWithMixin.getRightLeg().bend(emote.getBend("rightLeg")); - - mutatedJacket.copyBend(thisWithMixin.getTorso()); - mutatedLeftPantLeg.copyBend(thisWithMixin.getLeftLeg()); - mutatedRightPantLeg.copyBend(thisWithMixin.getRightLeg()); - mutatedLeftSleeve.copyBend(thisWithMixin.getLeftArm()); - mutatedRightSleeve.copyBend(thisWithMixin.getRightArm()); } else { firstPersonNext = false; emoteSupplier.set(null); + resetBend(this.body); + resetBend(this.leftArm); + resetBend(this.rightArm); + resetBend(this.leftLeg); + resetBend(this.rightLeg); } } + @Unique + private static void resetBend(ModelPart part) { + IBendHelper.INSTANCE.bend(part, null); + } /** * @author KosmX - Player Animator library diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerRendererMixin.java index cea7dd3..817d03b 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerRendererMixin.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/PlayerRendererMixin.java @@ -3,6 +3,7 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; import dev.kosmx.playerAnim.api.TransformType; +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonConfiguration; import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; import dev.kosmx.playerAnim.core.util.Vec3f; import dev.kosmx.playerAnim.impl.IAnimatedPlayer; @@ -35,15 +36,15 @@ private void hideBonesInFirstPerson(AbstractClientPlayer entity, MultiBufferSource vertexConsumerProvider, int i, CallbackInfo ci) { if (FirstPersonMode.isFirstPersonPass()) { - var animationApplier = ((IAnimatedPlayer) entity).playerAnimator_getAnimation(); - var config = animationApplier.getFirstPersonConfiguration(); + AnimationApplier animationApplier = ((IAnimatedPlayer) entity).playerAnimator_getAnimation(); + FirstPersonConfiguration config = animationApplier.getFirstPersonConfiguration(); if (entity == Minecraft.getInstance().getCameraEntity()) { // Hiding all parts, because they should not be visible in first person setAllPartsVisible(false); // Showing arms based on configuration - var showRightArm = config.isShowRightArm(); - var showLeftArm = config.isShowLeftArm(); + boolean showRightArm = config.isShowRightArm(); + boolean showLeftArm = config.isShowLeftArm(); this.model.rightArm.visible = showRightArm; this.model.rightSleeve.visible = showRightArm; this.model.leftArm.visible = showLeftArm; @@ -91,8 +92,9 @@ private void applyBodyTransforms(AbstractClientPlayer abstractClientPlayerEntity @Inject(method = "renderHand", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/model/PlayerModel;setupAnim(Lnet/minecraft/world/entity/LivingEntity;FFFFF)V")) private void notifyModelOfFirstPerson(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, AbstractClientPlayer abstractClientPlayer, ModelPart modelPart, ModelPart modelPart2, CallbackInfo ci) { - if (this.getModel() instanceof IPlayerModel playerModel && !((IAnimatedPlayer)abstractClientPlayer).playerAnimator_getAnimation().getFirstPersonMode().isEnabled()) { - playerModel.playerAnimator_prepForFirstPersonRender(); + PlayerModel m = this.getModel(); + if (m instanceof IPlayerModel && !((IAnimatedPlayer)abstractClientPlayer).playerAnimator_getAnimation().getFirstPersonMode().isEnabled()) { + ((IPlayerModel)m).playerAnimator_prepForFirstPersonRender(); } } } diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java index e00c156..4bf7d92 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/ItemInHandRendererMixin.java @@ -1,6 +1,8 @@ package dev.kosmx.playerAnim.mixin.firstPerson; import com.mojang.blaze3d.vertex.PoseStack; + +import dev.kosmx.playerAnim.api.firstPerson.FirstPersonConfiguration; import dev.kosmx.playerAnim.api.firstPerson.FirstPersonMode; import dev.kosmx.playerAnim.impl.IAnimatedPlayer; import net.minecraft.client.Minecraft; @@ -19,7 +21,7 @@ public class ItemInHandRendererMixin { @Inject(method = "renderHandsWithItems", at = @At("HEAD"), cancellable = true) private void disableDefaultItemIfNeeded(float f, PoseStack poseStack, MultiBufferSource.BufferSource bufferSource, LocalPlayer localPlayer, int i, CallbackInfo ci) { - if (localPlayer instanceof IAnimatedPlayer player && player.playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { + if (localPlayer instanceof IAnimatedPlayer && ((IAnimatedPlayer)localPlayer).playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { ci.cancel(); } } @@ -31,13 +33,13 @@ private ItemInHandRenderer.HandRenderSelection selectHandsToRender(LocalPlayer l return null; }*/ - @Inject(method = "renderItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;renderStatic(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/client/renderer/block/model/ItemTransforms$TransformType;ZLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;Lnet/minecraft/world/level/Level;III)V"), cancellable = true) + @Inject(method = "renderItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;renderStatic(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/client/renderer/block/model/ItemTransforms$TransformType;ZLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;Lnet/minecraft/world/level/Level;II)V"), cancellable = true) private void cancelItemRender(LivingEntity entity, ItemStack itemStack, ItemTransforms.TransformType transformType, boolean bl, PoseStack poseStack, MultiBufferSource multiBufferSource, int i, CallbackInfo ci) { if (entity != Minecraft.getInstance().getCameraEntity()) { return; } - if (FirstPersonMode.isFirstPersonPass() && entity instanceof IAnimatedPlayer player) { - var config = player.playerAnimator_getAnimation().getFirstPersonConfiguration(); + if (FirstPersonMode.isFirstPersonPass() && entity instanceof IAnimatedPlayer) { + FirstPersonConfiguration config = ((IAnimatedPlayer)entity).playerAnimator_getAnimation().getFirstPersonConfiguration(); if (transformType == ItemTransforms.TransformType.FIRST_PERSON_RIGHT_HAND || transformType == ItemTransforms.TransformType.THIRD_PERSON_RIGHT_HAND) { if (!config.isShowRightItem()) { ci.cancel(); diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java index d35be20..75703d2 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LevelRendererMixin.java @@ -30,7 +30,8 @@ public class LevelRendererMixin { private void fakeThirdPersonMode(PoseStack poseStack, float f, long l, boolean bl, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f matrix4f, CallbackInfo ci) { // mods may need to redirect that method, I want to avoid compatibility issues as long as possible defaultCameraState = camera.isDetached(); - if (camera.getEntity() instanceof IAnimatedPlayer player && player.playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { + Entity entity = camera.getEntity(); + if (entity instanceof IAnimatedPlayer && ((IAnimatedPlayer)entity).playerAnimator_getAnimation().getFirstPersonMode() == FirstPersonMode.THIRD_PERSON_MODEL) { FirstPersonMode.setFirstPersonPass(!camera.isDetached() && (!(camera.getEntity() instanceof LivingEntity) || !((LivingEntity)camera.getEntity()).isSleeping())); // this will cause a lot of pain ((CameraAccessor)camera).setDetached(true); } diff --git a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LivingEntityRendererMixin.java b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LivingEntityRendererMixin.java index b5d162a..8a1f27e 100644 --- a/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LivingEntityRendererMixin.java +++ b/minecraft/common/src/main/java/dev/kosmx/playerAnim/mixin/firstPerson/LivingEntityRendererMixin.java @@ -5,7 +5,7 @@ import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.LivingEntityRenderer; -import net.minecraft.client.renderer.entity.layers.PlayerItemInHandLayer; +import net.minecraft.client.renderer.entity.layers.ItemInHandLayer; import net.minecraft.world.entity.LivingEntity; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Final; @@ -15,6 +15,7 @@ import org.spongepowered.asm.mixin.injection.Redirect; import java.util.List; +import java.util.stream.Collectors; @Mixin(value = LivingEntityRenderer.class, priority = 2000) public class LivingEntityRendererMixin { @@ -25,7 +26,7 @@ public class LivingEntityRendererMixin { at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/entity/LivingEntityRenderer;layers:Ljava/util/List;", opcode = Opcodes.GETFIELD)) private List filterLayers(LivingEntityRenderer instance, LivingEntity entity, float f, float g, PoseStack poseStack, MultiBufferSource multiBufferSource, int i) { if (entity instanceof LocalPlayer && FirstPersonMode.isFirstPersonPass()) { - return layers.stream().filter(layer -> layer instanceof PlayerItemInHandLayer).toList(); + return layers.stream().filter(layer -> layer instanceof ItemInHandLayer).collect(Collectors.toList()); } else return layers; } } diff --git a/minecraft/fabric/build.gradle b/minecraft/fabric/build.gradle index 2aae8ef..0a4eb36 100644 --- a/minecraft/fabric/build.gradle +++ b/minecraft/fabric/build.gradle @@ -51,6 +51,7 @@ dependencies { common(shadowCommon(project(path: ":coreLib")) {transitive false}) {transitive false} //Why can I nest these? //Testing libraries + // modLocalRuntime files("../libs/bendy-lib-2.1.1-fabric.jar") modLocalRuntime "io.github.kosmx.bendy-lib:bendy-lib-fabric:${project.bendy_lib}" modLocalRuntime "maven.modrinth:3dskinlayers:1.6.7" modLocalRuntime "maven.modrinth:emotecraft:2.2.6-SNAPSHOT-build.44-MC1.16.5-fabric" diff --git a/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/AnimationRegistry.java b/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/AnimationRegistry.java deleted file mode 100644 index 9299ef5..0000000 --- a/minecraft/fabric/src/testmod/java/dev/kosmx/animatorTestmod/AnimationRegistry.java +++ /dev/null @@ -1,43 +0,0 @@ -package dev.kosmx.animatorTestmod; - -import dev.kosmx.playerAnim.core.data.KeyframeAnimation; -import dev.kosmx.playerAnim.core.data.gson.AnimationSerializing; -import net.minecraft.server.packs.resources.ResourceManager; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.*; - -public class AnimationRegistry { - // static final Logger LOGGER = LogUtils.getLogger(); - public static final Map animations = new HashMap<>(); - - public static void load(ResourceManager resourceManager) { - String dataFolder = "animations"; - - - /* - try (InputStream reader = AnimationRegistry.class.getResourceAsStream("assets\\testmod\\animations\\two_handed_slash_horizontal_right.json")) { - KeyframeAnimation animation = AnimationSerializing.deserializeAnimation(reader).get(0); - animations.put("two_handed_slash_horizontal_right", animation); - - } catch(IOException e) { - e.printStackTrace(); - } - */ - byte[] bytes = Base64.getDecoder().decode(SomeString.something); - try (InputStream reader = new ByteArrayInputStream(bytes)) { - KeyframeAnimation animation = AnimationSerializing.deserializeAnimation(reader).get(0); - KeyframeAnimation.AnimationBuilder modified = animation.mutableCopy(); - modified.getOrCreatePart("torso").fullyEnablePart(true); //crouching workaround - animations.put("two_handed_vertical_right_right", modified.build()); - - } catch(IOException e) { - e.printStackTrace(); - } - - - - } -} diff --git a/minecraft/fabric/src/testmod/resources/testmod.mixins.json b/minecraft/fabric/src/testmod/resources/testmod.mixins.json index ad6c412..0a52657 100644 --- a/minecraft/fabric/src/testmod/resources/testmod.mixins.json +++ b/minecraft/fabric/src/testmod/resources/testmod.mixins.json @@ -1,7 +1,7 @@ { "required": true, "package": "dev.kosmx.animatorTestmod.mixin", - "compatibilityLevel": "JAVA_16", + "compatibilityLevel": "JAVA_8", "client": [ "ClientPlayerMixin", "MinecraftClientMixin" diff --git a/minecraft/forge/build.gradle b/minecraft/forge/build.gradle index 356604b..8243639 100644 --- a/minecraft/forge/build.gradle +++ b/minecraft/forge/build.gradle @@ -38,10 +38,11 @@ dependencies { //Testing libraries /* + modLocalRuntime files("../libs/bendy-lib-2.1.1-forge.jar") modLocalRuntime "io.github.kosmx.bendy-lib:bendy-lib-forge:${project.bendy_lib}" modLocalRuntime "maven.modrinth:3dskinlayers:1.5.2-forge-1.19" modLocalRuntime "maven.modrinth:emotecraft:2.2.6-SNAPSHOT-build.44-MC1.19.2-forge" - //*/ + */ } project.archivesBaseName = rootProject.archives_base_name + "-" + project.name