diff --git a/1_10_R1/pom.xml b/1_10_R1/pom.xml
index e95dda13..10e24863 100644
--- a/1_10_R1/pom.xml
+++ b/1_10_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_10_R1
diff --git a/1_11_R1/pom.xml b/1_11_R1/pom.xml
index 40b1cad2..7950f992 100644
--- a/1_11_R1/pom.xml
+++ b/1_11_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_11_R1
diff --git a/1_12_R1/pom.xml b/1_12_R1/pom.xml
index 969039d0..6451b034 100644
--- a/1_12_R1/pom.xml
+++ b/1_12_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_12_R1
diff --git a/1_13_R1/pom.xml b/1_13_R1/pom.xml
index 1c63b8ec..70f0cf83 100644
--- a/1_13_R1/pom.xml
+++ b/1_13_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_13_R1
diff --git a/1_13_R2/pom.xml b/1_13_R2/pom.xml
index 1710d997..e8c0edcf 100644
--- a/1_13_R2/pom.xml
+++ b/1_13_R2/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_13_R2
diff --git a/1_14_4_R1/pom.xml b/1_14_4_R1/pom.xml
index 7150704b..c461a7cc 100644
--- a/1_14_4_R1/pom.xml
+++ b/1_14_4_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_14_4_R1
diff --git a/1_14_R1/pom.xml b/1_14_R1/pom.xml
index e12d3b10..9e5007e6 100644
--- a/1_14_R1/pom.xml
+++ b/1_14_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_14_R1
diff --git a/1_15_R1/pom.xml b/1_15_R1/pom.xml
index e430c5ed..4038688b 100644
--- a/1_15_R1/pom.xml
+++ b/1_15_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_15_R1
diff --git a/1_16_R1/pom.xml b/1_16_R1/pom.xml
index 2421b353..bb507f01 100644
--- a/1_16_R1/pom.xml
+++ b/1_16_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_16_R1
diff --git a/1_16_R2/pom.xml b/1_16_R2/pom.xml
index 272535ef..7c9be6a6 100644
--- a/1_16_R2/pom.xml
+++ b/1_16_R2/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_16_R2
diff --git a/1_16_R3/pom.xml b/1_16_R3/pom.xml
index 0429af11..3ea7da5e 100644
--- a/1_16_R3/pom.xml
+++ b/1_16_R3/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_16_R3
diff --git a/1_17_1_R1/pom.xml b/1_17_1_R1/pom.xml
index cc15c41d..7f253e31 100644
--- a/1_17_1_R1/pom.xml
+++ b/1_17_1_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_17_1_R1
diff --git a/1_17_R1/pom.xml b/1_17_R1/pom.xml
index bf56f3cb..eb73d963 100644
--- a/1_17_R1/pom.xml
+++ b/1_17_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_17_R1
diff --git a/1_18_R1/pom.xml b/1_18_R1/pom.xml
index 34f3aa7b..66a4e1eb 100644
--- a/1_18_R1/pom.xml
+++ b/1_18_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_18_R1
diff --git a/1_18_R2/pom.xml b/1_18_R2/pom.xml
index 5c3a6716..db19cac9 100644
--- a/1_18_R2/pom.xml
+++ b/1_18_R2/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_18_R2
diff --git a/1_19_1_R1/pom.xml b/1_19_1_R1/pom.xml
index f03f07a1..9034cda5 100644
--- a/1_19_1_R1/pom.xml
+++ b/1_19_1_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_19_1_R1
diff --git a/1_19_R1/pom.xml b/1_19_R1/pom.xml
index d0d5c81f..a9e27802 100644
--- a/1_19_R1/pom.xml
+++ b/1_19_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_19_R1
diff --git a/1_19_R2/pom.xml b/1_19_R2/pom.xml
index 7041c4b9..e278ac24 100644
--- a/1_19_R2/pom.xml
+++ b/1_19_R2/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_19_R2
diff --git a/1_19_R3/pom.xml b/1_19_R3/pom.xml
index f1a82b4b..7bbc5450 100644
--- a/1_19_R3/pom.xml
+++ b/1_19_R3/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_19_R3
diff --git a/1_20_R1/pom.xml b/1_20_R1/pom.xml
index 6c676488..3f1aca12 100644
--- a/1_20_R1/pom.xml
+++ b/1_20_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_20_R1
diff --git a/1_20_R2/pom.xml b/1_20_R2/pom.xml
index 7bf99c0f..304550dd 100644
--- a/1_20_R2/pom.xml
+++ b/1_20_R2/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_20_R2
diff --git a/1_20_R3/pom.xml b/1_20_R3/pom.xml
index f032105a..be9c042d 100644
--- a/1_20_R3/pom.xml
+++ b/1_20_R3/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_20_R3
diff --git a/1_20_R4/pom.xml b/1_20_R4/pom.xml
index 7e3ff600..850bf19c 100644
--- a/1_20_R4/pom.xml
+++ b/1_20_R4/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_20_R4
diff --git a/1_21_R1/pom.xml b/1_21_R1/pom.xml
index a3b1e6c9..ba58733e 100644
--- a/1_21_R1/pom.xml
+++ b/1_21_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_21_R1
diff --git a/1_21_R2/pom.xml b/1_21_R2/pom.xml
index 15f6181a..83a429fb 100644
--- a/1_21_R2/pom.xml
+++ b/1_21_R2/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_21_R2
diff --git a/1_21_R3/pom.xml b/1_21_R3/pom.xml
index 2f0a2751..acecf294 100644
--- a/1_21_R3/pom.xml
+++ b/1_21_R3/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_21_R3
diff --git a/1_21_R4/pom.xml b/1_21_R4/pom.xml
index 08e67374..efdd6f71 100644
--- a/1_21_R4/pom.xml
+++ b/1_21_R4/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_21_R4
diff --git a/1_21_R5/pom.xml b/1_21_R5/pom.xml
index ab220010..9e00d8c0 100644
--- a/1_21_R5/pom.xml
+++ b/1_21_R5/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_21_R5
diff --git a/1_21_R6/pom.xml b/1_21_R6/pom.xml
index ef39e5dc..8181fcee 100644
--- a/1_21_R6/pom.xml
+++ b/1_21_R6/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_21_R6
diff --git a/1_21_R7/pom.xml b/1_21_R7/pom.xml
new file mode 100644
index 00000000..a974a384
--- /dev/null
+++ b/1_21_R7/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+
+
+ net.wesjd
+ anvilgui-parent
+ 1.10.11-SNAPSHOT
+
+
+ anvilgui-1_21_R7
+
+
+
+ org.spigotmc
+ spigot
+ 1.21.11-R0.1-SNAPSHOT
+ provided
+
+
+ net.wesjd
+ anvilgui-abstraction
+ ${project.parent.version}
+ provided
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 21
+ 21
+
+
+
+
+
\ No newline at end of file
diff --git a/1_21_R7/src/main/java/net/wesjd/anvilgui/version/Wrapper1_21_R7.java b/1_21_R7/src/main/java/net/wesjd/anvilgui/version/Wrapper1_21_R7.java
new file mode 100644
index 00000000..39e58858
--- /dev/null
+++ b/1_21_R7/src/main/java/net/wesjd/anvilgui/version/Wrapper1_21_R7.java
@@ -0,0 +1,177 @@
+package net.wesjd.anvilgui.version;
+
+import java.lang.reflect.Method;
+import net.minecraft.core.BlockPosition;
+import net.minecraft.core.component.DataComponents;
+import net.minecraft.network.chat.IChatBaseComponent;
+import net.minecraft.network.protocol.game.PacketPlayOutCloseWindow;
+import net.minecraft.network.protocol.game.PacketPlayOutExperience;
+import net.minecraft.network.protocol.game.PacketPlayOutOpenWindow;
+import net.minecraft.server.level.EntityPlayer;
+import net.minecraft.world.IInventory;
+import net.minecraft.world.entity.player.EntityHuman;
+import net.minecraft.world.inventory.*;
+import org.bukkit.craftbukkit.v1_21_R7.CraftWorld;
+import org.bukkit.craftbukkit.v1_21_R7.entity.CraftPlayer;
+import org.bukkit.craftbukkit.v1_21_R7.event.CraftEventFactory;
+import org.bukkit.craftbukkit.v1_21_R7.util.CraftChatMessage;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+
+public final class Wrapper1_21_R7 implements VersionWrapper {
+ private int getRealNextContainerId(Player player) {
+ return toNMS(player).nextContainerCounter();
+ }
+
+ /**
+ * Turns a {@link Player} into an NMS one
+ *
+ * @param player The player to be converted
+ * @return the NMS EntityPlayer
+ */
+ private EntityPlayer toNMS(Player player) {
+ return ((CraftPlayer) player).getHandle();
+ }
+
+ @Override
+ public int getNextContainerId(Player player, AnvilContainerWrapper container) {
+ return ((AnvilContainer) container).getContainerId();
+ }
+
+ @Override
+ public void handleInventoryCloseEvent(Player player) {
+ try {
+ // As of 1.21.5, this method only exists on Spigot, not on Paper.
+ // It was removed from Paper here:
+ // https://github.com/PaperMC/Paper/commit/f00727c57e564f3a8cb875183a54142feb693db7
+ CraftEventFactory.handleInventoryCloseEvent(toNMS(player));
+ } catch (NoSuchMethodError ignored) {
+ // Workaround for Paper servers
+ try {
+ Class> inventoryCloseEventReasonClass =
+ Class.forName("org.bukkit.event.inventory.InventoryCloseEvent$Reason");
+ Method handleInventoryCloseEventMethod = CraftEventFactory.class.getMethod(
+ "handleInventoryCloseEvent", EntityHuman.class, inventoryCloseEventReasonClass);
+ handleInventoryCloseEventMethod.invoke(
+ null,
+ toNMS(player),
+ inventoryCloseEventReasonClass.getField("UNKNOWN").get(null));
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ toNMS(player).s(); // s -> doCloseContainer
+ }
+
+ @Override
+ public void sendPacketOpenWindow(Player player, int containerId, Object inventoryTitle) {
+ toNMS(player).g.b(new PacketPlayOutOpenWindow(containerId, Containers.i, (IChatBaseComponent)
+ inventoryTitle)); // g -> connection, b -> send
+ }
+
+ @Override
+ public void sendPacketCloseWindow(Player player, int containerId) {
+ toNMS(player).g.b(new PacketPlayOutCloseWindow(containerId)); // g -> connection, b -> send
+ }
+
+ @Override
+ public void sendPacketExperienceChange(Player player, int experienceLevel) {
+ toNMS(player).g.b(new PacketPlayOutExperience(0f, 0, experienceLevel)); // g -> connection, b -> send
+ }
+
+ @Override
+ public void setActiveContainerDefault(Player player) {
+ toNMS(player).cn = toNMS(player).cm; // cn -> containerMenu, cm -> inventoryMenu
+ }
+
+ @Override
+ public void setActiveContainer(Player player, AnvilContainerWrapper container) {
+ toNMS(player).cn = (Container) container; // cn -> containerMenu
+ }
+
+ @Override
+ public void setActiveContainerId(AnvilContainerWrapper container, int containerId) {}
+
+ @Override
+ public void addActiveContainerSlotListener(AnvilContainerWrapper container, Player player) {
+ toNMS(player).a((Container) container); // a -> initMenu
+ }
+
+ @Override
+ public AnvilContainerWrapper newContainerAnvil(Player player, Object title) {
+ return new AnvilContainer(player, getRealNextContainerId(player), (IChatBaseComponent) title);
+ }
+
+ @Override
+ public Object literalChatComponent(String content) {
+ return IChatBaseComponent.b(content); // IChatBaseComponent.b -> Component.literal
+ }
+
+ @Override
+ public Object jsonChatComponent(String json) {
+ return CraftChatMessage.fromJSON(json);
+ }
+
+ private static class AnvilContainer extends ContainerAnvil implements AnvilContainerWrapper {
+ public AnvilContainer(Player player, int containerId, IChatBaseComponent guiTitle) {
+ super(
+ containerId,
+ ((CraftPlayer) player).getHandle().gK(), // gK -> getInventory
+ ContainerAccess.a( // a -> create
+ ((CraftWorld) player.getWorld()).getHandle(), new BlockPosition(0, 0, 0)));
+ this.checkReachable = false;
+ setTitle(guiTitle);
+ }
+
+ @Override
+ public void l() {
+ // If the output is empty copy the left input into the output
+ Slot output = this.b(2); // b -> getSlot
+ if (!output.h()) { // h -> hasItem
+ output.f(this.b(0).g().v()); // f -> set, g -> getItem, v -> copy
+ }
+
+ this.y.a(0); // y -> cost, a -> set
+
+ // Sync to the client
+ this.b(); // b -> sendAllDataToRemote
+ this.d(); // d -> broadcastChanges
+ }
+
+ @Override
+ public void a(EntityHuman player) {}
+
+ @Override
+ protected void a(EntityHuman player, IInventory container) {}
+
+ public int getContainerId() {
+ return this.l; // l -> containerId
+ }
+
+ @Override
+ public String getRenameText() {
+ return this.x; // x -> itemName
+ }
+
+ @Override
+ public void setRenameText(String text) {
+ // If an item is present in the left input slot change its hover name to the literal text.
+ Slot inputLeft = b(0);
+ if (inputLeft.h()) {
+ inputLeft
+ .g()
+ .b( // b -> set
+ DataComponents.h,
+ IChatBaseComponent.b(text)); // DataComponents.h -> DataComponents.CUSTOM_NAME
+ }
+ }
+
+ @Override
+ public Inventory getBukkitInventory() {
+ // NOTE: We need to call Container#getBukkitView() instead of ContainerAnvil#getBukkitView()
+ // because ContainerAnvil#getBukkitView() had an ABI breakage in the middle of the Minecraft 1.21
+ // development cycle for Spigot. For more info, see: https://github.com/WesJD/AnvilGUI/issues/342
+ return ((Container) this).getBukkitView().getTopInventory();
+ }
+ }
+}
diff --git a/1_7_R4/pom.xml b/1_7_R4/pom.xml
index de9d647c..7d9b8e6e 100644
--- a/1_7_R4/pom.xml
+++ b/1_7_R4/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_7_R4
diff --git a/1_8_R1/pom.xml b/1_8_R1/pom.xml
index b37f635b..aedf47ef 100644
--- a/1_8_R1/pom.xml
+++ b/1_8_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_8_R1
diff --git a/1_8_R2/pom.xml b/1_8_R2/pom.xml
index 0bfd2c0b..7a28c2f4 100644
--- a/1_8_R2/pom.xml
+++ b/1_8_R2/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_8_R2
diff --git a/1_8_R3/pom.xml b/1_8_R3/pom.xml
index 88a71d6c..0dd81994 100644
--- a/1_8_R3/pom.xml
+++ b/1_8_R3/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_8_R3
diff --git a/1_9_R1/pom.xml b/1_9_R1/pom.xml
index 0e95fb3a..8e64ca7e 100644
--- a/1_9_R1/pom.xml
+++ b/1_9_R1/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_9_R1
diff --git a/1_9_R2/pom.xml b/1_9_R2/pom.xml
index dc28938d..29827f4c 100644
--- a/1_9_R2/pom.xml
+++ b/1_9_R2/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-1_9_R2
diff --git a/README.md b/README.md
index ea2c4aaa..c65fc89e 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ AnvilGUI requires the usage of Maven or a Maven compatible build system.
net.wesjd
anvilgui
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
diff --git a/abstraction/pom.xml b/abstraction/pom.xml
index 1960ad07..54e2030d 100644
--- a/abstraction/pom.xml
+++ b/abstraction/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui-abstraction
diff --git a/api/pom.xml b/api/pom.xml
index a0abdf42..3bc2e68f 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -7,7 +7,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
anvilgui
@@ -235,6 +235,12 @@
${project.parent.version}
compile
+
+ net.wesjd
+ anvilgui-1_21_R7
+ ${project.parent.version}
+ compile
+
org.geysermc.geyser
api
diff --git a/api/src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java b/api/src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java
index 75370233..bbba6f86 100644
--- a/api/src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java
+++ b/api/src/main/java/net/wesjd/anvilgui/version/VersionMatcher.java
@@ -32,10 +32,11 @@ public class VersionMatcher {
this.put("1.21.8", "1_21_R5");
this.put("1.21.9", "1_21_R6");
this.put("1.21.10", "1_21_R6");
+ this.put("1.21.11", "1_21_R7");
}
};
/* This needs to be updated to reflect the newest available version wrapper */
- private static final String FALLBACK_REVISION = "1_21_R6";
+ private static final String FALLBACK_REVISION = "1_21_R7";
/**
* Matches the server version to it's {@link VersionWrapper}
diff --git a/pom.xml b/pom.xml
index 846b6451..914a7888 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
net.wesjd
anvilgui-parent
- 1.10.10-SNAPSHOT
+ 1.10.11-SNAPSHOT
pom
@@ -51,6 +51,7 @@
1_21_R4
1_21_R5
1_21_R6
+ 1_21_R7