summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Gunger <corechg@gmail.com>2020-04-15 15:09:41 -0400
committerKyle Gunger <corechg@gmail.com>2020-04-15 15:09:41 -0400
commitaed6ed909ee81beecac2836cb86654efe29e154b (patch)
tree84405cfa1b58a193335b9a47940fcaaa0ff764f6
parent2f8be08dc2d398d71c2325b545e8fc49ca4e214d (diff)
[Update] Version 0.5.1
More documentation, and an updated list of packets
-rw-r--r--gradle.properties2
-rw-r--r--src/main/java/net/transit/network/packet/IStaticPacket.java23
-rw-r--r--src/main/java/net/transit/network/packet/MetaPacket.java34
-rw-r--r--src/main/java/net/transit/network/packet/StaticPacket.java13
-rw-r--r--src/main/java/net/transit/network/packet/dynamic/ArrayPacket.java74
-rw-r--r--src/main/java/net/transit/network/packet/dynamic/DynamicPacket.java43
-rw-r--r--src/main/java/net/transit/network/packet/dynamic/IDynamicPacket.java16
-rw-r--r--src/main/java/net/transit/network/packet/dynamic/MetaDynamicPacket.java44
-rw-r--r--src/main/java/net/transit/network/system/INode.java45
-rw-r--r--src/main/java/net/transit/network/system/ISystem.java17
-rw-r--r--src/main/java/net/transit/network/system/swap/AcceptorNode.java14
-rw-r--r--src/main/java/net/transit/network/system/swap/ProviderNode.java10
-rw-r--r--src/main/java/net/transit/type/Type.java6
-rw-r--r--src/main/java/net/transit/type/group/TypeGroup.java32
-rw-r--r--src/main/java/net/transit/type/group/simple/SimpleGroups.java10
-rw-r--r--src/main/java/net/transit/type/simple/SimpleTypes.java10
-rw-r--r--src/main/resources/fabric.mod.json8
17 files changed, 338 insertions, 63 deletions
diff --git a/gradle.properties b/gradle.properties
index 16c44c5..dececde 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx1G
loader_version=0.6.1+build.164
# Mod Properties
- mod_version = 0.4.4
+ mod_version = 0.5.1
maven_group = net.transit
archives_base_name = transit-api
diff --git a/src/main/java/net/transit/network/packet/IStaticPacket.java b/src/main/java/net/transit/network/packet/IStaticPacket.java
new file mode 100644
index 0000000..01073d3
--- /dev/null
+++ b/src/main/java/net/transit/network/packet/IStaticPacket.java
@@ -0,0 +1,23 @@
+package net.transit.network.packet;
+
+import net.transit.type.Type;
+
+/** Interface describing an unchanging packet.
+ * @author Kyle Gunger
+ *
+ * @param <D> The data type (Object) that the packet transfers.
+ */
+public interface IStaticPacket<D>
+{
+ /**Get the packet's data.
+ *
+ * @return <D> The packet's data
+ */
+ public D getData();
+
+ /**Get the packet's type.
+ *
+ * @return IType<<D>> The type of the packet
+ */
+ public Type<D> getType();
+} \ No newline at end of file
diff --git a/src/main/java/net/transit/network/packet/MetaPacket.java b/src/main/java/net/transit/network/packet/MetaPacket.java
index 0240519..7e49318 100644
--- a/src/main/java/net/transit/network/packet/MetaPacket.java
+++ b/src/main/java/net/transit/network/packet/MetaPacket.java
@@ -2,32 +2,34 @@ package net.transit.network.packet;
import net.transit.type.Type;
-public class MetaPacket<D, M> implements Packet<D>
+/** Static packet with extra data attached.
+ * @author Kyle Gunger
+ *
+ * @param <D> The data type (Object) that the packet transfers
+ * @param <M> The type of metadata
+*/
+public class MetaPacket<D, M> extends StaticPacket<D>
{
-
- private D data;
private M metaData;
- private Type<D> type;
+ /** Constructor
+ *
+ * @param dat The data to store
+ * @param t The Type of the data
+ * @param meta The metadata to store
+ */
public MetaPacket(D dat, Type<D> t, M meta)
{
- data = dat;
- type = t;
+ super(dat, t);
metaData = meta;
}
-
- public D getData()
- {
- return data;
- }
+ /** Get the metadata of the packet.
+ *
+ * @return The packet's metadata
+ */
public M getMetaData()
{
return metaData;
}
-
- @Override
- public Type<D> getType() {
- return type;
- }
}
diff --git a/src/main/java/net/transit/network/packet/StaticPacket.java b/src/main/java/net/transit/network/packet/StaticPacket.java
index b14e442..eeeae3f 100644
--- a/src/main/java/net/transit/network/packet/StaticPacket.java
+++ b/src/main/java/net/transit/network/packet/StaticPacket.java
@@ -2,17 +2,28 @@ package net.transit.network.packet;
import net.transit.type.Type;
-public class StaticPacket<D> implements Packet<D>
+/** Simple packet which stores an unchanging value.
+ * @author Kyle Gunger
+ *
+ * @param <D> The data type (Object) that the packet transfers.
+ */
+public class StaticPacket<D> implements IStaticPacket<D>
{
private D data;
private Type<D> type;
+ /** Constructor. Stores the given data and uses the given type.
+ *
+ * @param dat The packet's data
+ * @param t The packet's type
+ */
public StaticPacket(D dat, Type<D> t)
{
data = dat;
type = t;
}
+ @Override
public D getData()
{
return data;
diff --git a/src/main/java/net/transit/network/packet/dynamic/ArrayPacket.java b/src/main/java/net/transit/network/packet/dynamic/ArrayPacket.java
new file mode 100644
index 0000000..0c27c80
--- /dev/null
+++ b/src/main/java/net/transit/network/packet/dynamic/ArrayPacket.java
@@ -0,0 +1,74 @@
+package net.transit.network.packet.dynamic;
+
+import java.util.ArrayList;
+
+import net.transit.type.Type;
+
+/** A packet type which stores multiple values which can be accessed. When getting data, pop and shift from the array.
+ * @author Kyle Gunger
+ *
+ * @param <D> The data type (Object) that the packet transfers
+ */
+public class ArrayPacket<D> implements IDynamicPacket<D>
+{
+ private ArrayList<D> arrayData;
+ private Type<D> type;
+
+ /** Constructor
+ * Create an array packet. Adds the starting value.
+ * @param startValue The starting value
+ * @param t The type of the packet
+ */
+ public ArrayPacket(D startValue, Type<D> t)
+ {
+ arrayData = new ArrayList<D>(0);
+ arrayData.add(startValue);
+ type = t;
+ }
+
+ /**
+ * Create an empty array packet of the desired type.
+ * @param t The type of the packet
+ */
+ public ArrayPacket(Type<D> t)
+ {
+ arrayData = new ArrayList<D>(0);
+ type = t;
+ }
+
+ /** Pop and shift data from the array.
+ */
+ @Override
+ public D getData()
+ {
+ D temp = null;
+
+ if(arrayData.size() > 0)
+ {
+ temp = arrayData.remove(0);
+ }
+
+ return temp;
+ }
+
+ /** Add data to the array.
+ * @param data The data to push
+ */
+ public void setData(D data)
+ {
+ arrayData.add(data);
+ }
+
+ /**
+ * @return The ammount of data the packet holds
+ */
+ public int dataStored()
+ {
+ return arrayData.size();
+ }
+
+ @Override
+ public Type<D> getType() {
+ return type;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/net/transit/network/packet/dynamic/DynamicPacket.java b/src/main/java/net/transit/network/packet/dynamic/DynamicPacket.java
new file mode 100644
index 0000000..0860487
--- /dev/null
+++ b/src/main/java/net/transit/network/packet/dynamic/DynamicPacket.java
@@ -0,0 +1,43 @@
+package net.transit.network.packet.dynamic;
+
+import net.transit.type.Type;
+
+/**
+ * Simple packet which stores a fluid value.
+ *
+ * @author Kyle Gunger
+ *
+ * @param <D> The data type (Object) that the packet transfers
+ */
+public class DynamicPacket<D> implements IDynamicPacket<D> {
+ private D data;
+ private Type<D> type;
+
+ /** Constructor. Stores the given data and uses the given type.
+ *
+ * @param dat The packet's data
+ * @param t The packet's type
+ */
+ public DynamicPacket(D dat, Type<D> t)
+ {
+ data = dat;
+ type = t;
+ }
+
+ @Override
+ public D getData()
+ {
+ return data;
+ }
+
+ @Override
+ public void setData(D dat)
+ {
+ data = dat;
+ }
+
+ @Override
+ public Type<D> getType() {
+ return type;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/net/transit/network/packet/dynamic/IDynamicPacket.java b/src/main/java/net/transit/network/packet/dynamic/IDynamicPacket.java
new file mode 100644
index 0000000..51b3c13
--- /dev/null
+++ b/src/main/java/net/transit/network/packet/dynamic/IDynamicPacket.java
@@ -0,0 +1,16 @@
+package net.transit.network.packet.dynamic;
+
+import net.transit.network.packet.IStaticPacket;
+
+/** Interface describing a fluid packet.
+ * @author Kyle Gunger
+ *
+ * @param <D> The data type (Object) that the packet transfers
+ */
+public interface IDynamicPacket<D> extends IStaticPacket<D>{
+ /**Set the packet's data.
+ *
+ * @return <D> The packet's data
+ */
+ public void setData(D dat);
+} \ No newline at end of file
diff --git a/src/main/java/net/transit/network/packet/dynamic/MetaDynamicPacket.java b/src/main/java/net/transit/network/packet/dynamic/MetaDynamicPacket.java
new file mode 100644
index 0000000..b6a3ec6
--- /dev/null
+++ b/src/main/java/net/transit/network/packet/dynamic/MetaDynamicPacket.java
@@ -0,0 +1,44 @@
+package net.transit.network.packet.dynamic;
+
+import net.transit.type.Type;
+
+/** Static packet with extra data attached.
+ * @author Kyle Gunger
+ *
+ * @param <D> The data type (Object) that the packet transfers
+ * @param <M> The type of metadata
+*/
+public class MetaDynamicPacket<D, M> extends DynamicPacket<D>
+{
+ private M metaData;
+
+ /** Constructor
+ *
+ * @param dat The data to store
+ * @param t The Type of the data
+ * @param meta The metadata to store
+ */
+ public MetaDynamicPacket(D dat, Type<D> t, M meta)
+ {
+ super(dat, t);
+ metaData = meta;
+ }
+
+ /** Get the metadata of the packet.
+ *
+ * @return The packet's metadata
+ */
+ public M getMetaData()
+ {
+ return metaData;
+ }
+
+ /** Set the metadata of the packet.
+ *
+ * @param meta The packet's new metadata
+ */
+ public void setMetaData(M meta)
+ {
+ metaData = meta;
+ }
+}
diff --git a/src/main/java/net/transit/network/system/INode.java b/src/main/java/net/transit/network/system/INode.java
new file mode 100644
index 0000000..9c42bf1
--- /dev/null
+++ b/src/main/java/net/transit/network/system/INode.java
@@ -0,0 +1,45 @@
+package net.transit.network.system;
+
+/**
+ * @author Kyle Gunger
+ * @apiNote A node inside or outside a system. Provides acceptors and providers to other nodes.
+ */
+public interface INode
+{
+
+ /**Returns the groupIDs of groups the node interacts with
+ *
+ * @return String[]
+ */
+ public String[] groupsProvided();
+
+
+ /**Get the system managing the node or {@code null} if there isn't one
+ *
+ * @return System
+ */
+ public System getSystem();
+
+
+ /** Get the data of one of the TypeGroups the Node supports
+ *
+ * @param groupID
+ * @return
+ */
+ public Object getData(String groupID);
+
+
+ /** Set the group data for the node
+ *
+ * @param dat
+ * @param groupID
+ */
+ public void setData(Object dat, String groupID);
+
+
+ /** Get the nodes that this node is connected to
+ *
+ * @return Node[]
+ */
+ public INode[] getConnections();
+}
diff --git a/src/main/java/net/transit/network/system/ISystem.java b/src/main/java/net/transit/network/system/ISystem.java
new file mode 100644
index 0000000..fd2fa51
--- /dev/null
+++ b/src/main/java/net/transit/network/system/ISystem.java
@@ -0,0 +1,17 @@
+package net.transit.network.system;
+
+
+/**ISystem - a group of nodes optimized for performance
+ *
+ * A node can exist without a system, but a system can not exist without at least one root node.
+ *
+ * @param T The object type stored in the system.
+ */
+public interface ISystem
+{
+ /**The nodes stored by the system
+ *
+ * @return INode[]
+ */
+ public INode[] getNodes();
+}
diff --git a/src/main/java/net/transit/network/system/swap/AcceptorNode.java b/src/main/java/net/transit/network/system/swap/AcceptorNode.java
index 2dfd7a5..14c672d 100644
--- a/src/main/java/net/transit/network/system/swap/AcceptorNode.java
+++ b/src/main/java/net/transit/network/system/swap/AcceptorNode.java
@@ -1,9 +1,9 @@
package net.transit.network.system.swap;
-import net.transit.network.packet.Packet;
-import net.transit.network.system.Node;
+import net.transit.network.packet.IStaticPacket;
+import net.transit.network.system.INode;
-public interface AcceptorNode extends Node
+public interface AcceptorNode extends INode
{
/** Link another node as a provider
@@ -12,7 +12,7 @@ public interface AcceptorNode extends Node
* @param group
* @return
*/
- public boolean linkProvider(Node requester, String group);
+ public boolean linkProvider(INode requester, String group);
/** Unlink a provider from the acceptor
@@ -20,13 +20,13 @@ public interface AcceptorNode extends Node
* @param toUnlink
* @return
*/
- public boolean unlinkProvider(Node toUnlink);
+ public boolean unlinkProvider(INode toUnlink);
/**
* @return Node[]
*/
- public Node[] getProviders();
+ public INode[] getProviders();
/** Accept a packet from a provider
@@ -35,5 +35,5 @@ public interface AcceptorNode extends Node
* @param group
* @return
*/
- public boolean accept(Packet<?> packet, String group);
+ public boolean accept(IStaticPacket<?> packet, String group);
}
diff --git a/src/main/java/net/transit/network/system/swap/ProviderNode.java b/src/main/java/net/transit/network/system/swap/ProviderNode.java
index 1ba1ef3..831c87f 100644
--- a/src/main/java/net/transit/network/system/swap/ProviderNode.java
+++ b/src/main/java/net/transit/network/system/swap/ProviderNode.java
@@ -1,8 +1,8 @@
package net.transit.network.system.swap;
-import net.transit.network.system.Node;
+import net.transit.network.system.INode;
-public interface ProviderNode extends Node{
+public interface ProviderNode extends INode{
/** Link another node as an acceptor
*
@@ -10,7 +10,7 @@ public interface ProviderNode extends Node{
* @param group
* @return boolean
*/
- public boolean linkAcceptor(Node requester, String group);
+ public boolean linkAcceptor(INode requester, String group);
/** Unlink a provider from the acceptor
@@ -18,12 +18,12 @@ public interface ProviderNode extends Node{
* @param toUnlink
* @return
*/
- public boolean unlinkAcceptor(Node toUnlink);
+ public boolean unlinkAcceptor(INode toUnlink);
/**
* @return Node[]
*/
- public Node[] getAcceptors();
+ public INode[] getAcceptors();
}
diff --git a/src/main/java/net/transit/type/Type.java b/src/main/java/net/transit/type/Type.java
index d140da5..2dcf81b 100644
--- a/src/main/java/net/transit/type/Type.java
+++ b/src/main/java/net/transit/type/Type.java
@@ -1,6 +1,6 @@
package net.transit.type;
-import net.transit.network.packet.Packet;
+import net.transit.network.packet.IStaticPacket;
import net.transit.network.packet.StaticPacket;
/**@author Kyle Gunger
@@ -24,7 +24,7 @@ public class Type<T>
* @param group The group asking for the conversion
* @return <T> The packet's data in the default type
*/
- public T toBase(Packet<T> packet, String group)
+ public T toBase(IStaticPacket<T> packet, String group)
{
return packet.getData();
}
@@ -35,7 +35,7 @@ public class Type<T>
* @param group The group that the data comes from
* @return IPacket<<T>> The packet
*/
- public Packet<T> fromBase(T base, String group)
+ public IStaticPacket<T> fromBase(T base, String group)
{
return new StaticPacket<T>(base, this);
}
diff --git a/src/main/java/net/transit/type/group/TypeGroup.java b/src/main/java/net/transit/type/group/TypeGroup.java
index 8929252..6cea6dd 100644
--- a/src/main/java/net/transit/type/group/TypeGroup.java
+++ b/src/main/java/net/transit/type/group/TypeGroup.java
@@ -5,7 +5,7 @@ import java.util.ArrayList;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import net.transit.network.packet.Packet;
+import net.transit.network.packet.*;
import net.transit.type.Type;
/**
@@ -18,7 +18,7 @@ public class TypeGroup<B>
private Type<B> baseType;
// The list of types.
- private final ArrayList<Type<?>> TYPES = new ArrayList<Type<?>>(0);
+ private final ArrayList<Type<B>> TYPES = new ArrayList<Type<B>>(0);
// Logger for events in the TypeGroup.
private static final Logger LOG = LogManager.getFormatterLogger("Transit|Group");
@@ -43,13 +43,14 @@ public class TypeGroup<B>
*/
public boolean addType(Type<B> type)
{
- if(!isInGroup(type.getGroup(), type.getType()) && !isInGroup(type))
+ if(!isInGroup(type.getGroup(), type.getType()))
{
TYPES.add(type);
- LOG.info(prefix + "Added type " + type.getType() + " to group " + getGroup());
+ LOG.info(prefix + "Added type " + type.getType() + ":" + type.getGroup() + " to group " + getGroup());
return true;
}
-
+
+ LOG.info(prefix + "Failed to add type " + type.getType() + ":" + type.getGroup() + " to group " + getGroup() + ". Was the type already added?");
return false;
}
@@ -60,8 +61,12 @@ public class TypeGroup<B>
*/
public boolean removeType(Type<B> type)
{
+ if(type.equals(baseType)) {
+ LOG.warn(prefix + "[WARN] Failed to remove type " + type.getGroup() + ":" + type.getType() + " from group " + getGroup() + ". This is the base type and can not be removed.");
+ return false;
+ }
- if(isInGroup(type) && TYPES.indexOf(type) != -1)
+ if(TYPES.indexOf(type) != -1)
{
LOG.info(prefix + "Removed type " + TYPES.remove(TYPES.indexOf(type)).getType() + " from group " + getGroup());
return true;
@@ -113,7 +118,7 @@ public class TypeGroup<B>
*/
public boolean isInGroup(Type<B> type)
{
- for(Type<?> t : TYPES)
+ for(Type<B> t : TYPES)
{
if(t.equals(type)) return true;
}
@@ -128,7 +133,7 @@ public class TypeGroup<B>
*/
public boolean isInGroup(String groupID, String typeID)
{
- for(Type<?> t : TYPES)
+ for(Type<B> t : TYPES)
{
if(t.getGroup().equals(groupID) && t.getType().equals(typeID)) return true;
}
@@ -152,12 +157,11 @@ public class TypeGroup<B>
* @param type
* @return Type
*/
- @SuppressWarnings("unchecked")
public Type<B> getType(String groupID, String typeID)
{
- for(Type<?> t : TYPES)
+ for(Type<B> t : TYPES)
{
- if(t.getGroup().equals(groupID) && t.getType().equals(typeID)) return (Type<B>) t;
+ if(t.getGroup().equals(groupID) && t.getType().equals(typeID)) return t;
}
return null;
@@ -177,7 +181,7 @@ public class TypeGroup<B>
* @param type
* @return
*/
- protected Packet<B> convertPacketRaw(Packet<B> packet, Type<B> type)
+ protected IStaticPacket<B> convertPacketRaw(IStaticPacket<B> packet, Type<B> type)
{
return type.fromBase(packet.getType().toBase(packet, getGroup()), getGroup());
}
@@ -188,7 +192,7 @@ public class TypeGroup<B>
* @param type The type to convert to
* @return Packet
*/
- public Packet<B> convertPacket(Packet<B> packet, Type<B> type)
+ public IStaticPacket<B> convertPacket(IStaticPacket<B> packet, Type<B> type)
{
if(isInGroup(packet.getType()) && isInGroup(type))
{
@@ -205,7 +209,7 @@ public class TypeGroup<B>
* @param typeID The typeID of the Type to convert to
* @return Packet
*/
- public Packet<B> convertPacket(Packet<B> packet, String groupID, String typeID)
+ public IStaticPacket<B> convertPacket(IStaticPacket<B> packet, String groupID, String typeID)
{
Type<B> toType = getType(groupID, typeID);
if(toType != null)
diff --git a/src/main/java/net/transit/type/group/simple/SimpleGroups.java b/src/main/java/net/transit/type/group/simple/SimpleGroups.java
index eb45a36..b4fcb76 100644
--- a/src/main/java/net/transit/type/group/simple/SimpleGroups.java
+++ b/src/main/java/net/transit/type/group/simple/SimpleGroups.java
@@ -1,16 +1,16 @@
package net.transit.type.group.simple;
-import net.minecraft.block.FluidBlock;
+import net.minecraft.fluid.Fluid;
import net.minecraft.item.Item;
import net.transit.type.group.GroupRegistry;
import net.transit.type.group.TypeGroup;
import net.transit.type.simple.SimpleTypes;
public final class SimpleGroups {
- public static final TypeGroup<Number> ENERGY_GROUP = new TypeGroup<Number>(SimpleTypes.ENERGY);
- public static final TypeGroup<Number> MANA_GROUP = new TypeGroup<Number>(SimpleTypes.MANA);
- public static final TypeGroup<Item> ITEM_GROUP = new TypeGroup<Item>(SimpleTypes.ITEM);
- public static final TypeGroup<FluidBlock> FLUID_GROUP = new TypeGroup<FluidBlock>(SimpleTypes.FLUID);
+ public static final TypeGroup<Number> ENERGY_GROUP = new TypeGroup<Number>(SimpleTypes.TransitJoule);
+ public static final TypeGroup<Number> MANA_GROUP = new TypeGroup<Number>(SimpleTypes.TransitMana);
+ public static final TypeGroup<Item> ITEM_GROUP = new TypeGroup<Item>(SimpleTypes.Item);
+ public static final TypeGroup<Fluid> FLUID_GROUP = new TypeGroup<Fluid>(SimpleTypes.Fluid);
public static final void init()
{
diff --git a/src/main/java/net/transit/type/simple/SimpleTypes.java b/src/main/java/net/transit/type/simple/SimpleTypes.java
index b1f1b98..db839aa 100644
--- a/src/main/java/net/transit/type/simple/SimpleTypes.java
+++ b/src/main/java/net/transit/type/simple/SimpleTypes.java
@@ -1,12 +1,12 @@
package net.transit.type.simple;
-import net.minecraft.block.FluidBlock;
+import net.minecraft.fluid.Fluid;
import net.minecraft.item.Item;
import net.transit.type.Type;
public final class SimpleTypes {
- public static final Type<Number> ENERGY = new Type<Number>("ENERGY", "ENERGY");
- public static final Type<Number> MANA = new Type<Number>("MANA", "MANA");
- public static final Type<Item> ITEM = new Type<Item>("ITEM", "ITEM");
- public static final Type<FluidBlock> FLUID = new Type<FluidBlock>("FLUID", "FLUID");
+ public static final Type<Number> TransitJoule = new Type<Number>("TJoule", "ENERGY");
+ public static final Type<Number> TransitMana = new Type<Number>("TMana", "MANA");
+ public static final Type<Item> Item = new Type<Item>("Item", "ITEM");
+ public static final Type<Fluid> Fluid = new Type<Fluid>("Fluid", "FLUID");
}
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
index 918da54..1a5136b 100644
--- a/src/main/resources/fabric.mod.json
+++ b/src/main/resources/fabric.mod.json
@@ -1,7 +1,7 @@
{
"schemaVersion": 1,
"id": "transit-api",
- "version": "${version}",
+ "version": "0.5.1",
"name": "Transit API",
"description": "General purpose API for transfering fluid, items, energy, anything.",
@@ -21,10 +21,6 @@
},
"depends": {
- "fabricloader": ">=0.4.0",
- "fabric": "*"
- },
- "suggests": {
- "flamingo": "*"
+ "fabricloader": ">=0.4.0"
}
}