diff --git a/pom.xml b/pom.xml
index 696be69..a19e790 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,6 +26,18 @@
4.12test
+
+ com.minecraft.moonlake
+ Validate
+ 1.0
+ compile
+
+
+ com.google.guava
+ guava
+ 21.0
+ provided
+ com.google.code.gsonGson
diff --git a/src/main/java/com/minecraft/moonlake/chat/ChatClickEvent.java b/src/main/java/com/minecraft/moonlake/chat/ChatClickEvent.java
new file mode 100644
index 0000000..805308a
--- /dev/null
+++ b/src/main/java/com/minecraft/moonlake/chat/ChatClickEvent.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2017 The MoonLake Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.minecraft.moonlake.chat;
+
+public class ChatClickEvent {
+
+ private final Action action;
+ private final String value;
+
+ public ChatClickEvent(Action action, String value) {
+ this.action = action;
+ this.value = value;
+ }
+
+ public Action getAction() {
+ return action;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj instanceof ChatClickEvent) {
+ ChatClickEvent other = (ChatClickEvent) obj;
+ return action == other.action && value != null ? value.equals(other.value) : other.value == null;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = action != null ? action.hashCode() : 0;
+ result = 31 * result + (value != null ? value.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ChatClickEvent{" +
+ "action=" + action +
+ ", value='" + value + '\'' +
+ '}';
+ }
+
+ public enum Action {
+
+ OPEN_URL,
+ OPEN_FILE,
+ RUN_COMMAND,
+ SUGGEST_COMMAND,
+ CHANGE_PAGE,
+ ;
+
+ public static Action fromName(String name) {
+ return Action.valueOf(name.toUpperCase());
+ }
+ }
+}
diff --git a/src/main/java/com/minecraft/moonlake/chat/ChatColor.java b/src/main/java/com/minecraft/moonlake/chat/ChatColor.java
new file mode 100644
index 0000000..f4f36fa
--- /dev/null
+++ b/src/main/java/com/minecraft/moonlake/chat/ChatColor.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 The MoonLake Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.minecraft.moonlake.chat;
+
+public enum ChatColor {
+
+ BLACK('0'),
+ DARK_BLUE('1'),
+ DARK_GREEN('2'),
+ DARK_AQUA('3'),
+ DARK_RED('4'),
+ DARK_PURPLE('5'),
+ GOLD('6'),
+ GRAY('7'),
+ DARK_GRAY('8'),
+ BLUE('9'),
+ GREEN('a'),
+ AQUA('b'),
+ RED('c'),
+ LIGHT_PURPLE('d'),
+ YELLOW('e'),
+ WHITE('f'),
+ OBFUSCATED('k', true),
+ BOLD('l', true),
+ STRIKETHROUGH('m', true),
+ UNDERLINE('n', true),
+ ITALIC('o', true),
+ RESET('r'),
+ ;
+
+ private final char code;
+ private final boolean format;
+
+ ChatColor(char code) {
+ this(code, false);
+ }
+
+ ChatColor(char code, boolean format) {
+ this.code = code;
+ this.format = format;
+ }
+
+ public char getCode() {
+ return code;
+ }
+
+ public boolean isFormat() {
+ return format;
+ }
+
+ public static ChatColor fromName(String name) {
+ return ChatColor.valueOf(name.toUpperCase());
+ }
+}
diff --git a/src/main/java/com/minecraft/moonlake/chat/ChatComponent.java b/src/main/java/com/minecraft/moonlake/chat/ChatComponent.java
new file mode 100644
index 0000000..e35e16a
--- /dev/null
+++ b/src/main/java/com/minecraft/moonlake/chat/ChatComponent.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 The MoonLake Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.minecraft.moonlake.chat;
+
+import java.util.List;
+
+public interface ChatComponent {
+
+ ChatStyle getStyle();
+
+ ChatComponent setStyle(ChatStyle style);
+
+ List getExtras();
+
+ int getExtraSize();
+
+ ChatComponent append(String text);
+
+ ChatComponent append(ChatComponent extra);
+
+ String toJson();
+
+ String toRaw();
+
+ String toRaw(boolean color);
+}
diff --git a/src/main/java/com/minecraft/moonlake/chat/ChatComponentBase.java b/src/main/java/com/minecraft/moonlake/chat/ChatComponentBase.java
new file mode 100644
index 0000000..1af9aab
--- /dev/null
+++ b/src/main/java/com/minecraft/moonlake/chat/ChatComponentBase.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2017 The MoonLake Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.minecraft.moonlake.chat;
+
+import com.minecraft.moonlake.validate.Validate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class ChatComponentBase implements ChatComponent {
+
+ private ChatStyle style;
+ private List extras;
+
+ ChatComponentBase() {
+ this.extras = new ArrayList<>();
+ }
+
+ @Override
+ public ChatComponent setStyle(ChatStyle style) {
+ Validate.notNull(style, "The chat style object is null.");
+ this.style = style;
+ for(ChatComponent component : extras)
+ component.getStyle().setParent(getStyle());
+ return this;
+ }
+
+ @Override
+ public ChatStyle getStyle() {
+ if(style == null) {
+ this.style = new ChatStyle();
+ for(ChatComponent component : extras)
+ component.getStyle().setParent(style);
+ }
+ return style;
+ }
+
+ @Override
+ public final List getExtras() {
+ return extras;
+ }
+
+ @Override
+ public final int getExtraSize() {
+ return extras.size();
+ }
+
+ @Override
+ public ChatComponent append(String text) {
+ Validate.notNull(text, "The text object is null.");
+ return append(new ChatComponentText(text));
+ }
+
+ @Override
+ public ChatComponent append(ChatComponent extra) {
+ Validate.notNull(extra, "The extra component object is null.");
+ extra.getStyle().setParent(getStyle());
+ extras.add(extra);
+ return this;
+ }
+
+ @Override
+ public String toJson() {
+ return ChatSerializer.toJson(this);
+ }
+
+ @Override
+ public String toRaw() {
+ return ChatSerializer.toRaw(this);
+ }
+
+ @Override
+ public String toRaw(boolean color) {
+ return ChatSerializer.toRaw(this, color);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj instanceof ChatComponentBase) {
+ ChatComponentBase other = (ChatComponentBase) obj;
+ return getStyle().equals(other.getStyle()) && extras.equals(other.extras);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = style != null ? style.hashCode() : 0;
+ result = 31 * result + (extras != null ? extras.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ChatComponentBase{" +
+ "style=" + style +
+ ", extras=" + extras +
+ '}';
+ }
+}
diff --git a/src/main/java/com/minecraft/moonlake/chat/ChatComponentFancy.java b/src/main/java/com/minecraft/moonlake/chat/ChatComponentFancy.java
new file mode 100644
index 0000000..30f5a38
--- /dev/null
+++ b/src/main/java/com/minecraft/moonlake/chat/ChatComponentFancy.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017 The MoonLake Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.minecraft.moonlake.chat;
+
+import com.minecraft.moonlake.validate.Validate;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class ChatComponentFancy {
+
+ private List extras;
+
+ public ChatComponentFancy(String text) {
+ this.extras = new ArrayList<>();
+ this.then(text);
+ }
+
+ public ChatComponentFancy then(String text) {
+ Validate.notNull(text, "The text object is null.");
+ return then(new ChatComponentText(text));
+ }
+
+ public ChatComponentFancy then(ChatComponent component) {
+ Validate.notNull(component, "The component object is null.");
+ extras.add(component);
+ return this;
+ }
+
+ public ChatComponentFancy color(ChatColor color) {
+ Validate.notNull(color, "The chat color object is null.");
+ getLast().getStyle().setColor(color);
+ return this;
+ }
+
+ public ChatComponentFancy file(String path) {
+ Validate.notNull(path, "The path object is null.");
+ getLast().getStyle().setClickEvent(new ChatClickEvent(ChatClickEvent.Action.OPEN_FILE, path));
+ return this;
+ }
+
+ public ChatComponentFancy link(String url) {
+ Validate.notNull(url, "The url object is null.");
+ getLast().getStyle().setClickEvent(new ChatClickEvent(ChatClickEvent.Action.OPEN_URL, url));
+ return this;
+ }
+
+ public ChatComponentFancy suggest(String command) {
+ Validate.notNull(command, "The command object is null.");
+ getLast().getStyle().setClickEvent(new ChatClickEvent(ChatClickEvent.Action.SUGGEST_COMMAND, command));
+ return this;
+ }
+
+ public ChatComponentFancy command(String command) {
+ Validate.notNull(command, "The command object is null.");
+ getLast().getStyle().setClickEvent(new ChatClickEvent(ChatClickEvent.Action.RUN_COMMAND, command));
+ return this;
+ }
+
+ public ChatComponentFancy insert(String insertion) {
+ Validate.notNull(insertion, "The insertion object is null.");
+ getLast().getStyle().setInsertion(insertion);
+ return this;
+ }
+
+ public ChatComponentFancy tooltipText(String text) {
+ Validate.notNull(text, "The text object is null.");
+ getLast().getStyle().setHoverEvent(new ChatHoverEvent(ChatHoverEvent.Action.SHOW_TEXT, new ChatComponentText(text)));
+ return this;
+ }
+
+ public ChatComponentFancy tooltipTexts(String... texts) {
+ Validate.notNull(texts, "The texts object is null.");
+ StringBuilder builder = new StringBuilder();
+ for(int i = 0; i < texts.length; i++) {
+ builder.append(texts[i]);
+ if(i != texts.length - 1)
+ builder.append('\n');
+ }
+ return tooltipText(builder.toString());
+ }
+
+ public ChatComponentFancy tooltipTexts(Collection extends String> collection) {
+ Validate.notNull(collection, "The collection object is null.");
+ return tooltipTexts(collection.toArray(new String[collection.size()]));
+ }
+
+ public ChatComponentFancy tooltipItem(String item) {
+ Validate.notNull(item, "The item object is null.");
+ getLast().getStyle().setHoverEvent(new ChatHoverEvent(ChatHoverEvent.Action.SHOW_ITEM, new ChatComponentText(item)));
+ return this;
+ }
+
+ public ChatComponentFancy join(ChatComponentFancy componentFancy) {
+ Validate.notNull(componentFancy, "The component fancy object is null.");
+ extras.addAll(componentFancy.extras);
+ return this;
+ }
+
+ public ChatComponent build() {
+ ChatComponent component = new ChatComponentText("");
+ component.getExtras().addAll(extras);
+ return component;
+ }
+
+ protected ChatComponent getLast() {
+ return extras.get(extras.size() - 1);
+ }
+}
diff --git a/src/main/java/com/minecraft/moonlake/chat/ChatComponentKeybind.java b/src/main/java/com/minecraft/moonlake/chat/ChatComponentKeybind.java
new file mode 100644
index 0000000..dcda5d0
--- /dev/null
+++ b/src/main/java/com/minecraft/moonlake/chat/ChatComponentKeybind.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 The MoonLake Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.minecraft.moonlake.chat;
+
+public class ChatComponentKeybind extends ChatComponentBase {
+
+ private String keybind;
+
+ public ChatComponentKeybind() {
+ }
+
+ public ChatComponentKeybind(String keybind) {
+ this.keybind = keybind;
+ }
+
+ public String getKeybind() {
+ return keybind;
+ }
+
+ public ChatComponentKeybind setKeybind(String keyBind) {
+ this.keybind = keyBind;
+ return this;
+ }
+
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj instanceof ChatComponentKeybind) {
+ ChatComponentKeybind other = (ChatComponentKeybind) obj;
+ return super.equals(obj) && keybind != null ? keybind.equals(other.keybind) : other.keybind == null;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (keybind != null ? keybind.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ChatComponentText{" +
+ "keybind='" + keybind + '\'' +
+ ", style=" + getStyle() +
+ ", extras=" + getExtras() +
+ '}';
+ }
+}
diff --git a/src/main/java/com/minecraft/moonlake/chat/ChatComponentScore.java b/src/main/java/com/minecraft/moonlake/chat/ChatComponentScore.java
new file mode 100644
index 0000000..8fc597a
--- /dev/null
+++ b/src/main/java/com/minecraft/moonlake/chat/ChatComponentScore.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 The MoonLake Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.minecraft.moonlake.chat;
+
+public class ChatComponentScore extends ChatComponentBase {
+
+ private String name;
+ private String objective;
+ private String value;
+
+ public ChatComponentScore() {
+ }
+
+ public ChatComponentScore(String name, String objective) {
+ this.name = name;
+ this.objective = objective;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public ChatComponentScore setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public String getObjective() {
+ return objective;
+ }
+
+ public ChatComponentScore setObjective(String objective) {
+ this.objective = objective;
+ return this;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public ChatComponentScore setValue(String value) {
+ this.value = value;
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj instanceof ChatComponentScore) {
+ ChatComponentScore other = (ChatComponentScore) obj;
+ return super.equals(obj) && name != null ? name.equals(other.name) : other.name == null && objective != null ? objective.equals(other.objective) : other.objective == null;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ result = 31 * result + (objective != null ? objective.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ChatComponentScore{" +
+ "name='" + name + '\'' +
+ ", objective='" + objective + '\'' +
+ ", style=" + getStyle() +
+ ", extras=" + getExtras() +
+ '}';
+ }
+}
diff --git a/src/main/java/com/minecraft/moonlake/chat/ChatComponentSelector.java b/src/main/java/com/minecraft/moonlake/chat/ChatComponentSelector.java
new file mode 100644
index 0000000..646d07e
--- /dev/null
+++ b/src/main/java/com/minecraft/moonlake/chat/ChatComponentSelector.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2017 The MoonLake Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.minecraft.moonlake.chat;
+
+public class ChatComponentSelector extends ChatComponentBase {
+
+ private String selector;
+
+ public ChatComponentSelector() {
+ }
+
+ public ChatComponentSelector(String selector) {
+ this.selector = selector;
+ }
+
+ public String getSelector() {
+ return selector;
+ }
+
+ public ChatComponentSelector setSelector(String selector) {
+ if(selector.startsWith("@"))
+ this.selector = selector;
+ else
+ this.selector = "@" + selector;
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj instanceof ChatComponentSelector) {
+ ChatComponentSelector other = (ChatComponentSelector) obj;
+ return super.equals(obj) && selector != null ? selector.equals(other.selector) : other.selector == null;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (selector != null ? selector.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ChatComponentScore{" +
+ "selector='" + selector + '\'' +
+ ", style=" + getStyle() +
+ ", extras=" + getExtras() +
+ '}';
+ }
+}
diff --git a/src/main/java/com/minecraft/moonlake/chat/ChatComponentText.java b/src/main/java/com/minecraft/moonlake/chat/ChatComponentText.java
new file mode 100644
index 0000000..0e5ce3f
--- /dev/null
+++ b/src/main/java/com/minecraft/moonlake/chat/ChatComponentText.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 The MoonLake Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.minecraft.moonlake.chat;
+
+public class ChatComponentText extends ChatComponentBase {
+
+ private String text;
+
+ public ChatComponentText(String text) {
+ this.text = text;
+ }
+
+ public ChatComponentText(ChatComponentText text) {
+ this.text = text.getText();
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public ChatComponentText setText(String text) {
+ this.text = text;
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if(obj == this)
+ return true;
+ if(obj instanceof ChatComponentText) {
+ ChatComponentText other = (ChatComponentText) obj;
+ return super.equals(obj) && text != null ? text.equals(other.text) : other.text == null;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = super.hashCode();
+ result = 31 * result + (text != null ? text.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ChatComponentText{" +
+ "text='" + text + '\'' +
+ ", style=" + getStyle() +
+ ", extras=" + getExtras() +
+ '}';
+ }
+}
diff --git a/src/main/java/com/minecraft/moonlake/chat/ChatComponentTranslation.java b/src/main/java/com/minecraft/moonlake/chat/ChatComponentTranslation.java
new file mode 100644
index 0000000..383186d
--- /dev/null
+++ b/src/main/java/com/minecraft/moonlake/chat/ChatComponentTranslation.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 The MoonLake Authors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package com.minecraft.moonlake.chat;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ChatComponentTranslation extends ChatComponentBase {
+
+ private String key;
+ private List