diff --git a/SpeckleGrasshopper/SpeckleGrasshopper.csproj b/SpeckleGrasshopper/SpeckleGrasshopper.csproj
index a0566c2..53c8239 100644
--- a/SpeckleGrasshopper/SpeckleGrasshopper.csproj
+++ b/SpeckleGrasshopper/SpeckleGrasshopper.csproj
@@ -73,6 +73,8 @@
+
+
diff --git a/SpeckleGrasshopper/UserDataUtils/StreamApplyDelta.cs b/SpeckleGrasshopper/UserDataUtils/StreamApplyDelta.cs
new file mode 100644
index 0000000..a187a6c
--- /dev/null
+++ b/SpeckleGrasshopper/UserDataUtils/StreamApplyDelta.cs
@@ -0,0 +1,116 @@
+//extern alias SpeckleNewtonsoft;
+using System;
+using System.Collections.Generic;
+
+using Grasshopper.Kernel;
+using Rhino.Geometry;
+//using Newtonsoft.Json;
+using System.Windows.Forms;
+using SpeckleCore;
+using System.IO;
+using Grasshopper.Kernel.Parameters;
+using System.Reflection;
+
+namespace SpeckleGrasshopper
+{
+ public class StreamApplyDelta : GH_Component
+ {
+
+ ///
+ /// Initializes a new instance of the MyComponent1 class.
+ ///
+ public StreamApplyDelta()
+ : base("Applies a delta to a stream", "DELTADIFF",
+ "Applies a delta to a stream and returns a response. Make sure that the delta's revisionA matches with the input stream!",
+ "Speckle", "User Data Utils")
+ {
+ }
+
+ public override void AppendAdditionalMenuItems(ToolStripDropDown menu)
+ {
+ base.AppendAdditionalMenuItems(menu);
+ }
+
+ ///
+ /// Registers all the input parameters for this component.
+ ///
+ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
+ {
+ //pManager.AddGenericParameter("Client", "C", "Client.", GH_ParamAccess.item);
+ pManager.AddTextParameter("StreamID", "StreamID", "StreamID.", GH_ParamAccess.item);
+ pManager.AddGenericParameter("Delta", "Delta", "Delta to apply.", GH_ParamAccess.item);
+ }
+
+ ///
+ /// Registers all the output parameters for this component.
+ ///
+ protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
+ {
+ pManager.AddGenericParameter("Success", "Success", "True if the delta was applied onto the input stream.", GH_ParamAccess.item);
+ }
+
+ ///
+ /// This is the method that actually does the work.
+ ///
+ /// The DA object is used to retrieve from inputs and store in outputs.
+ protected override void SolveInstance(IGH_DataAccess DA)
+ {
+ SpeckleCore.SpeckleApiClient myClient = null;
+
+ Account account = null;
+ try
+ {
+ account = LocalContext.GetDefaultAccount();
+ var RestApi = account.RestApi;
+ var myToken = account.Token;
+ myClient = new SpeckleApiClient(account.RestApi);
+ myClient.AuthToken = myToken;
+ }
+ catch (Exception err)
+ {
+ }
+
+ string StreamID = null;
+ SpeckleCore.SpeckleDelta Delta = null;
+
+ DA.GetData(0, ref StreamID);
+ DA.GetData(1, ref Delta);
+
+ if (StreamID != null && Delta != null)
+ {
+ // TODO add exception for streams != Delta.RevisionA.id
+ var testApplyDelta = myClient.StreamApplyDeltaAsync(StreamID, Delta).Result;
+
+ var settings = new Newtonsoft.Json.JsonSerializerSettings()
+ {
+ ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore,
+ Formatting = Newtonsoft.Json.Formatting.Indented
+ };
+
+ DA.SetData(0, testApplyDelta.Success);
+ Message = testApplyDelta.Message;
+
+ }
+
+ }
+
+ ///
+ /// Provides an Icon for the component.
+ ///
+ protected override System.Drawing.Bitmap Icon
+ {
+ get
+ {
+ return Properties.Resources.Convert;
+ }
+ }
+
+ ///
+ /// Gets the unique ID for this component. Do not change this ID after release.
+ ///
+ public override Guid ComponentGuid
+ {
+ get { return new Guid("{a314b496-4426-4f92-94b0-8176fe6577bc}"); }
+ }
+ }
+}
diff --git a/SpeckleGrasshopper/UserDataUtils/StreamGetDelta.cs b/SpeckleGrasshopper/UserDataUtils/StreamGetDelta.cs
new file mode 100644
index 0000000..778e746
--- /dev/null
+++ b/SpeckleGrasshopper/UserDataUtils/StreamGetDelta.cs
@@ -0,0 +1,145 @@
+//extern alias SpeckleNewtonsoft;
+using System;
+using System.Collections.Generic;
+
+using Grasshopper.Kernel;
+using Rhino.Geometry;
+using Newtonsoft.Json;
+using Rhino.Collections;
+using Grasshopper.Kernel.Types;
+using System.Windows.Forms;
+using SpeckleCore;
+using System.IO;
+using Grasshopper.Kernel.Parameters;
+
+namespace SpeckleGrasshopper
+{
+ public class DiffingStreamsDelta : GH_Component
+ {
+ string serialisedUDs;
+ ///
+ /// Initializes a new instance of the MyComponent1 class.
+ ///
+ public DiffingStreamsDelta()
+ : base("Diffing between two streams (delta)", "DELTADIFF",
+ "Operates a diffing between two different streams and returns the delta as response",
+ "Speckle", "User Data Utils")
+ {
+ }
+
+ public override void AppendAdditionalMenuItems(ToolStripDropDown menu)
+ {
+ base.AppendAdditionalMenuItems(menu);
+ }
+
+ ///
+ /// Registers all the input parameters for this component.
+ ///
+ protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
+ {
+ //pManager.AddGenericParameter("Client", "C", "Client.", GH_ParamAccess.item);
+ pManager.AddTextParameter("StreamID", "StreamID_A", "StreamID.", GH_ParamAccess.item);
+ pManager.AddTextParameter("OtherStreamID", "StreamID_B", "OtherStreamID.", GH_ParamAccess.item);
+ }
+
+ ///
+ /// Registers all the output parameters for this component.
+ ///
+ protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
+ {
+ pManager.AddGeometryParameter("inA", "Deleted", "Objects only in A.", GH_ParamAccess.list);
+ pManager.AddGeometryParameter("inB", "Created", "Objects only in B.", GH_ParamAccess.list);
+ pManager.AddGeometryParameter("Common", "Common", "Objects common to A and B.", GH_ParamAccess.list);
+ pManager.AddGenericParameter("Delta", "Delta", "Computed Delta", GH_ParamAccess.item);
+ pManager.AddGenericParameter("DeltaJSON", "DeltaJSON", "Computed Delta", GH_ParamAccess.item);
+ }
+
+ ///
+ /// This is the method that actually does the work.
+ ///
+ /// The DA object is used to retrieve from inputs and store in outputs.
+ protected override void SolveInstance(IGH_DataAccess DA)
+ {
+ SpeckleCore.SpeckleApiClient myClient = null;
+
+ Account account = null;
+ try
+ {
+ account = LocalContext.GetDefaultAccount();
+ var RestApi = account.RestApi;
+ var myToken = account.Token;
+ myClient = new SpeckleApiClient(account.RestApi);
+ }
+ catch (Exception err)
+ {
+ }
+
+ string StreamID = null;
+ string OtherStreamID = null;
+
+ DA.GetData(0, ref StreamID);
+ DA.GetData(1, ref OtherStreamID);
+
+ if (StreamID != null && OtherStreamID != null)
+ {
+ //var test = myClient.StreamDeltaDiffAsync(StreamID, OtherStreamID).Result;
+ //var testDiff = myClient.StreamDiffAsync(StreamID, OtherStreamID).Result.Objects;
+ var testDelta = myClient.StreamDeltaDiffAsync(StreamID, OtherStreamID).Result.Delta;
+
+ List deletedIds = new List();
+ foreach (var obj in testDelta.Deleted)
+ deletedIds.Add(obj._id);
+ string[] deleted = deletedIds.ToArray();
+ List