ClusterInstance is working a bit

This commit is contained in:
Pascal Serrarens 2026-01-21 20:39:07 +01:00
parent 8b8e5fc33c
commit f0da7c9c9b
10 changed files with 168 additions and 118 deletions

View File

@ -4,7 +4,7 @@ using Unity.Mathematics;
using static Unity.Mathematics.math; using static Unity.Mathematics.math;
[CreateAssetMenu(menuName = "Passer/Cluster")] [CreateAssetMenu(menuName = "Passer/Cluster")]
public class Cluster : ScriptableObject, INucleus { public class Cluster : ScriptableObject {
public Cluster cluster => this; public Cluster cluster => this;
@ -14,9 +14,9 @@ public class Cluster : ScriptableObject, INucleus {
[SerializeReference] [SerializeReference]
public List<IReceptor> nuclei = new(); public List<IReceptor> nuclei = new();
public List<Cluster> subClusters = new(); // public List<Cluster> subClusters = new();
public void AddSubCluster(Cluster subCluster) { public void AddSubCluster(ClusterInstance subCluster) {
this.subClusters.Add(subCluster); this.nuclei.Add(subCluster);
} }
public INucleus output => this.nuclei[0] as INucleus; public INucleus output => this.nuclei[0] as INucleus;
@ -45,19 +45,19 @@ public class Cluster : ScriptableObject, INucleus {
get { return this.output.receivers; } get { return this.output.receivers; }
set { this.output.receivers = value; } set { this.output.receivers = value; }
} }
public List<Cluster> clusterReceivers { // public List<Cluster> clusterReceivers {
get { return this.output.clusterReceivers; } // get { return this.output.clusterReceivers; }
set { this.output.clusterReceivers = clusterReceivers; } // set { this.output.clusterReceivers = clusterReceivers; }
} // }
public IEnumerable<INucleus> allReceivers { // public IEnumerable<INucleus> allReceivers {
get => output.allReceivers; // get => output.allReceivers;
} // }
public INucleus Clone() { // public INucleus Clone() {
Cluster clone = CreateInstance<Cluster>(); // Cluster clone = CreateInstance<Cluster>();
// Lots to add here... // // Lots to add here...
return clone; // return clone;
} // }
// Call this function to ensure that there is at least one nucleus // Call this function to ensure that there is at least one nucleus
// This is an invariant and should be ensured before the nucleus is used // This is an invariant and should be ensured before the nucleus is used
@ -67,7 +67,7 @@ public class Cluster : ScriptableObject, INucleus {
if (nuclei.Count == 0) if (nuclei.Count == 0)
new Neuron(this, "Output"); // Every cluster should have at least 1 neuron new Neuron(this, "Output"); // Every cluster should have at least 1 neuron
} }
/*
public void AddReceiver(INucleus receivingNucleus) { public void AddReceiver(INucleus receivingNucleus) {
//output.AddReceiver(receiver); //output.AddReceiver(receiver);
this.output.receivers.Add(receivingNucleus); this.output.receivers.Add(receivingNucleus);
@ -92,7 +92,7 @@ public class Cluster : ScriptableObject, INucleus {
synapses.Add(synapse); synapses.Add(synapse);
return synapse; return synapse;
} }
*/
public void GarbageCollection() { public void GarbageCollection() {
HashSet<INucleus> visitedNuclei = new(); HashSet<INucleus> visitedNuclei = new();
MarkNuclei(visitedNuclei, this.output); MarkNuclei(visitedNuclei, this.output);
@ -117,9 +117,9 @@ public class Cluster : ScriptableObject, INucleus {
} }
nucleus.synapses.RemoveAll(synapse => visitedSynapses.Contains(synapse) == false); nucleus.synapses.RemoveAll(synapse => visitedSynapses.Contains(synapse) == false);
} }
if (nucleus.allReceivers != null) { if (nucleus.receivers != null) {
HashSet<INucleus> visitedReceivers = new(); HashSet<INucleus> visitedReceivers = new();
foreach (INucleus receiver in nucleus.allReceivers) { foreach (INucleus receiver in nucleus.receivers) {
if (receiver != null && receiver != null) { if (receiver != null && receiver != null) {
visitedReceivers.Add(receiver); visitedReceivers.Add(receiver);
visitedNuclei.Add(receiver); visitedNuclei.Add(receiver);

View File

@ -1,51 +1,90 @@
public class ClusterInstance { using System;
// The ScriptableObject asset from which the runtime object has been created using System.Collections.Generic;
public readonly Cluster asset; using UnityEngine;
using Unity.Mathematics;
using static Unity.Mathematics.math;
public ClusterInstance parent; [System.Serializable]
public class ClusterInstance : INucleus {
// The ScriptableObject asset from which the runtime object has been created
public Cluster asset;
public Cluster cluster => this.asset;
public INucleus output => this.asset.nuclei[0] as INucleus;
public float3 outputValue => this.output.outputValue;
public ClusterInstance(Cluster asset) { public ClusterInstance(Cluster asset) {
this.asset = asset; this.asset = asset;
} }
public NucleusArray array; public INucleus Clone() {
ClusterInstance clone = new(this.asset);
return clone;
}
#region Properties
public string name {
get { return asset.name; }
set { asset.name = value; }
}
public bool isSleeping => lengthsq(this.outputValue) == 0;
public NucleusArray array { get; set; }
#endregion Properties
#region Synapses #region Synapses
private Synapse[] _synapses = new Synapse[0]; private Synapse[] _synapses = new Synapse[0];
public Synapse[] synapses => _synapses; public List<Synapse> synapses => new(_synapses);
public void AddSynapse(IReceptor sendingNucleus) { public Synapse AddSynapse(IReceptor sendingNucleus, string nucleusName = null) {
if (nucleusName == null) {
this.asset.inputs[0].AddSynapse(sendingNucleus);
} else {
INucleus receptor = (INucleus)this.asset.nuclei.Find(nucleus => nucleus is INucleus n && nucleus.name == nucleusName);
receptor.AddSynapse(sendingNucleus);
}
// Add synapse to which neuron?
return null;
} }
// Does this even exist already? // Does this even exist already?
public void RemoveSynapse() { public void RemoveSynapse() {
} }
#endregion Synapses #endregion Synapses
#region Receivers #region Receivers
private INucleus[] _nucleiReceivers = new INucleus[0]; [SerializeReference]
public INucleus[] nucleiReceivers => _nucleiReceivers; private List<INucleus> _receivers = new();
public List<INucleus> receivers {
get { return _receivers; }
set { _receivers = value; }
}
public void AddReceiver(INucleus receivingNucleus) { public void AddReceiver(INucleus receivingNucleus) {
int newLength = this._nucleiReceivers.Length + 1; int newLength = this._receivers.Count + 1;
INucleus[] newReceivers = new INucleus[newLength]; INucleus[] newReceivers = new INucleus[newLength];
// Copy the existing receivers // Copy the existing receivers
for (int ix = 0; ix < this._nucleiReceivers.Length; ix++) for (int ix = 0; ix < this._receivers.Count; ix++)
newReceivers[ix] = this._nucleiReceivers[ix]; newReceivers[ix] = this._receivers[ix];
// Add the new receivers // Add the new receivers
newReceivers[this._nucleiReceivers.Length] = receivingNucleus; newReceivers[this._receivers.Count] = receivingNucleus;
// Replace the receivers with the new receivers // Replace the receivers with the new receivers
this._nucleiReceivers = newReceivers; this._receivers = new(newReceivers);
receivingNucleus.AddSynapse(this);
} }
public void RemoveReceiver(INucleus receivingNucleus) { public void RemoveReceiver(INucleus receivingNucleus) {
int newLength = this._nucleiReceivers.Length - 1; int newLength = this._receivers.Count - 1;
if (newLength < 0) if (newLength < 0)
// Array was empty, so we cannot remove anything // Array was empty, so we cannot remove anything
return; return;
@ -54,8 +93,8 @@ public class ClusterInstance {
int newIx = 0; int newIx = 0;
// Copy all receivers except receivingNucleus // Copy all receivers except receivingNucleus
for (int ix = 0; ix < this._nucleiReceivers.Length; ix++) { for (int ix = 0; ix < this._receivers.Count; ix++) {
if (this._nucleiReceivers[ix] == receivingNucleus) if (this._receivers[ix] == receivingNucleus)
// skip the receiver we want to remote // skip the receiver we want to remote
continue; continue;
@ -64,11 +103,22 @@ public class ClusterInstance {
// the receivingNucleus is not found // the receivingNucleus is not found
// and the original array is returned // and the original array is returned
return; return;
newReceivers[newIx] = this._nucleiReceivers[ix]; newReceivers[newIx] = this._receivers[ix];
newIx++; newIx++;
} }
this._nucleiReceivers = newReceivers; this._receivers = new(newReceivers);
} }
#endregion Receivers #endregion Receivers
#region Update
public void UpdateState() { }
public void UpdateNuclei() {
foreach (IReceptor nucleus in this.asset.nuclei)
nucleus.UpdateNuclei();
}
#endregion Update
} }

View File

@ -10,8 +10,8 @@ public interface INucleus : IReceptor {
// Senders // Senders
public List<Synapse> synapses { get; } public List<Synapse> synapses { get; }
public Synapse AddSynapse(IReceptor sender); public Synapse AddSynapse(IReceptor sender, string nucleusName = null);
public Synapse AddClusterSynapse(Cluster clusterSender); // public Synapse AddClusterSynapse(Cluster clusterSender);
public NucleusArray array { get; set; } public NucleusArray array { get; set; }
@ -34,11 +34,11 @@ public interface IReceptor {
// Receivers // Receivers
public List<INucleus> receivers { get; set; } public List<INucleus> receivers { get; set; }
public List<Cluster> clusterReceivers { get; set; } // public List<Cluster> clusterReceivers { get; set; }
public IEnumerable<INucleus> allReceivers { get; } // public IEnumerable<INucleus> allReceivers { get; }
public void AddReceiver(INucleus receiver); public void AddReceiver(INucleus receiver);
public void AddClusterReceiver(Cluster clusterReceiver); // public void AddClusterReceiver(Cluster clusterReceiver);
public void RemoveReceiver(INucleus receiverNucleus); public void RemoveReceiver(INucleus receiverNucleus);
#endregion static #endregion static

View File

@ -12,6 +12,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 60a957541c24c57e78018c202ebb1d9b, type: 3} m_Script: {fileID: 11500000, guid: 60a957541c24c57e78018c202ebb1d9b, type: 3}
m_Name: Identity m_Name: Identity
m_EditorClassIdentifier: Assembly-CSharp::Cluster m_EditorClassIdentifier: Assembly-CSharp::Cluster
asset: {fileID: 0}
nuclei: nuclei:
- rid: 2243601242842202241 - rid: 2243601242842202241
subClusters: [] subClusters: []

View File

@ -25,21 +25,21 @@ public class Neuron : INucleus {
get { return _receivers; } get { return _receivers; }
set { _receivers = value; } set { _receivers = value; }
} }
private List<Cluster> _clusterReceivers = new(); // private List<Cluster> _clusterReceivers = new();
public List<Cluster> clusterReceivers { // public List<Cluster> clusterReceivers {
get { return _clusterReceivers; } // get { return _clusterReceivers; }
set { _clusterReceivers = value; } // set { _clusterReceivers = value; }
} // }
public IEnumerable<INucleus> allReceivers { //=> _receivers.Concat(_clusterReceivers); // public IEnumerable<INucleus> allReceivers { //=> _receivers.Concat(_clusterReceivers);
get { // get {
if (_receivers == null) // if (_receivers == null)
return _clusterReceivers; // return _clusterReceivers;
else if (_clusterReceivers == null) // else if (_clusterReceivers == null)
return _receivers; // return _receivers;
else // else
return _receivers.Concat(_clusterReceivers); // return _receivers.Concat(_clusterReceivers);
} // }
} // }
[SerializeReference] [SerializeReference]
private NucleusArray _array; private NucleusArray _array;
@ -152,7 +152,7 @@ public class Neuron : INucleus {
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus); Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
clonedSynapse.weight = synapse.weight; clonedSynapse.weight = synapse.weight;
} }
foreach (INucleus receiver in this.allReceivers) { foreach (INucleus receiver in this.receivers) {
clone.AddReceiver(receiver); clone.AddReceiver(receiver);
} }
return clone; return clone;
@ -162,10 +162,10 @@ public class Neuron : INucleus {
this._receivers.Add(receivingNucleus); this._receivers.Add(receivingNucleus);
receivingNucleus.AddSynapse(this); receivingNucleus.AddSynapse(this);
} }
public void AddClusterReceiver(Cluster receivingCluster) { // public void AddClusterReceiver(Cluster receivingCluster) {
this._clusterReceivers.Add(receivingCluster); // this._clusterReceivers.Add(receivingCluster);
receivingCluster.AddSynapse(this); // receivingCluster.AddSynapse(this);
} // }
public void RemoveReceiver(INucleus receiverNucleus) { public void RemoveReceiver(INucleus receiverNucleus) {
this._receivers.RemoveAll(receiver => receiver == receiverNucleus); this._receivers.RemoveAll(receiver => receiver == receiverNucleus);
@ -185,7 +185,7 @@ public class Neuron : INucleus {
} }
} }
} }
foreach (INucleus receiver in nucleus.allReceivers) { foreach (INucleus receiver in nucleus.receivers) {
if (receiver != null && receiver.synapses != null) if (receiver != null && receiver.synapses != null)
receiver.synapses.RemoveAll(s => s.nucleus == nucleus); receiver.synapses.RemoveAll(s => s.nucleus == nucleus);
} }
@ -196,16 +196,16 @@ public class Neuron : INucleus {
} }
} }
public Synapse AddSynapse(IReceptor sendingNucleus) { public Synapse AddSynapse(IReceptor sendingNucleus, string nucleusName = null) {
Synapse synapse = new(sendingNucleus); Synapse synapse = new(sendingNucleus);
this.synapses.Add(synapse); this.synapses.Add(synapse);
return synapse; return synapse;
} }
public Synapse AddClusterSynapse(Cluster sendingCluster) { // public Synapse AddClusterSynapse(Cluster sendingCluster) {
Synapse synapse = new(sendingCluster); // Synapse synapse = new(sendingCluster);
this.synapses.Add(synapse); // this.synapses.Add(synapse);
return synapse; // return synapse;
} // }
public virtual void UpdateState() { public virtual void UpdateState() {
float3 sum = new(0, 0, 0); float3 sum = new(0, 0, 0);
@ -250,7 +250,7 @@ public class Neuron : INucleus {
// } // }
this.outputValue = result; this.outputValue = result;
foreach (INucleus receiver in this.allReceivers) foreach (INucleus receiver in this.receivers)
receiver.UpdateState(); receiver.UpdateState();
} }

View File

@ -9,12 +9,12 @@ public class NucleusArray {
private Cluster[] _clusters; private Cluster[] _clusters;
public IEnumerable<INucleus> nuclei { public IEnumerable<INucleus> nuclei {
get { get {
if (_nuclei == null) // if (_nuclei == null)
return _clusters; // return _clusters;
else if (_clusters == null) // else if (_clusters == null)
return _nuclei; return _nuclei;
else // else
return _nuclei.Concat(_clusters); // return _nuclei.Concat(_clusters);
} }
} }
public string name; public string name;

View File

@ -30,12 +30,12 @@ public class Receptor : IReceptor {
get { return _receivers; } get { return _receivers; }
set { _receivers = value; } set { _receivers = value; }
} }
private List<Cluster> _clusterReceivers = new(); // private List<Cluster> _clusterReceivers = new();
public List<Cluster> clusterReceivers { // public List<Cluster> clusterReceivers {
get { return _clusterReceivers; } // get { return _clusterReceivers; }
set { _clusterReceivers = value; } // set { _clusterReceivers = value; }
} // }
public IEnumerable<INucleus> allReceivers => _receivers.Concat(_clusterReceivers); // public IEnumerable<INucleus> allReceivers => _receivers.Concat(_clusterReceivers);
protected int[] thingIds; // every receiver can handle a thing with this id protected int[] thingIds; // every receiver can handle a thing with this id
@ -43,10 +43,10 @@ public class Receptor : IReceptor {
this._receivers.Add(receivingNucleus); this._receivers.Add(receivingNucleus);
receivingNucleus.AddSynapse(this); receivingNucleus.AddSynapse(this);
} }
public void AddClusterReceiver(Cluster receivingCluster) { // public void AddClusterReceiver(Cluster receivingCluster) {
this._clusterReceivers.Add(receivingCluster); // this._clusterReceivers.Add(receivingCluster);
receivingCluster.AddSynapse(this); // receivingCluster.AddSynapse(this);
} // }
public void RemoveReceiver(INucleus receiverNucleus) { public void RemoveReceiver(INucleus receiverNucleus) {
this._receivers.RemoveAll(receiver => receiver == receiverNucleus); this._receivers.RemoveAll(receiver => receiver == receiverNucleus);
@ -116,7 +116,7 @@ public class Receptor : IReceptor {
int receiverIx = 0; int receiverIx = 0;
INucleus selectedReceiver = null; INucleus selectedReceiver = null;
int selectedReceiverIx = 0; int selectedReceiverIx = 0;
foreach (INucleus receiver in this.allReceivers) { foreach (INucleus receiver in this.receivers) {
// selectedReceiver = receiver; // selectedReceiver = receiver;
// receiverIx++; // receiverIx++;

View File

@ -5,14 +5,15 @@ using UnityEditor;
[Serializable] [Serializable]
public class Synapse { public class Synapse {
// Support access to cluster of basic nucleus // Support access to cluster of basic nucleus
public IReceptor nucleus => clusterNucleus != null ? clusterNucleus : basicNucleus; public IReceptor nucleus => basicNucleus; // clusterNucleus != null ? clusterNucleus : basicNucleus;
[SerializeReference] [SerializeReference]
private IReceptor basicNucleus; private IReceptor basicNucleus;
// The Cluster is a ScriptableObject and can therefore not be serialized using [SerializeReference] // The Cluster is a ScriptableObject and can therefore not be serialized using [SerializeReference]
private Cluster clusterNucleus; // private ClusterInstance clusterNucleus;
public Cluster cluster; [SerializeReference]
public ClusterInstance cluster;
public float weight; public float weight;
@ -29,10 +30,10 @@ public class Synapse {
this.basicNucleus = nucleus; this.basicNucleus = nucleus;
this.weight = weight; this.weight = weight;
} }
public Synapse(Cluster cluster, float weight = 1.0f) { // public Synapse(ClusterInstance cluster, float weight = 1.0f) {
this.clusterNucleus = cluster.asset; // this.clusterNucleus = cluster;
this.weight = weight; // this.weight = weight;
} // }
public static class Presets { public static class Presets {
private const int samples = 32; private const int samples = 32;

View File

@ -156,8 +156,8 @@ public class ClusterInspector : Editor {
return; return;
NeuroidLayer currentLayer = new() { ix = layerIx }; NeuroidLayer currentLayer = new() { ix = layerIx };
if (selectedNucleus.allReceivers != null) { if (selectedNucleus.receivers != null) {
foreach (INucleus receiver in selectedNucleus.allReceivers) { foreach (INucleus receiver in selectedNucleus.receivers) {
INucleus outputNeuroid = receiver; INucleus outputNeuroid = receiver;
if (outputNeuroid != null) { if (outputNeuroid != null) {
AddToLayer(currentLayer, outputNeuroid); AddToLayer(currentLayer, outputNeuroid);
@ -272,12 +272,12 @@ public class ClusterInspector : Editor {
} }
private void DrawReceivers(INucleus nucleus, Vector3 parentPos, float size) { private void DrawReceivers(INucleus nucleus, Vector3 parentPos, float size) {
int nodeCount = nucleus.allReceivers.Count(); int nodeCount = nucleus.receivers.Count();
// Determine the maximum value in this layer // Determine the maximum value in this layer
// This is used to 'scale' the output value colors of the nuclei // This is used to 'scale' the output value colors of the nuclei
float maxValue = 0; float maxValue = 0;
foreach (INucleus receiver in nucleus.allReceivers) { foreach (INucleus receiver in nucleus.receivers) {
if (receiver is Neuron neuroid) { if (receiver is Neuron neuroid) {
float value = length(neuroid.outputValue); float value = length(neuroid.outputValue);
if (value > maxValue) if (value > maxValue)
@ -290,7 +290,7 @@ public class ClusterInspector : Editor {
float margin = 10 + spacing / 2; float margin = 10 + spacing / 2;
int row = 0; int row = 0;
foreach (INucleus receiver in nucleus.allReceivers) { foreach (INucleus receiver in nucleus.receivers) {
INucleus receiverNucleus = receiver; INucleus receiverNucleus = receiver;
if (receiverNucleus == null) if (receiverNucleus == null)
continue; continue;
@ -405,7 +405,7 @@ public class ClusterInspector : Editor {
Handles.Label(labelPos, nucleus.name, style); Handles.Label(labelPos, nucleus.name, style);
} }
if (nucleus is Cluster cluster) { if (nucleus is ClusterInstance cluster) {
Handles.color = Color.white; Handles.color = Color.white;
Handles.DrawWireDisc(position, Vector3.forward, size + 10); Handles.DrawWireDisc(position, Vector3.forward, size + 10);
} }
@ -552,7 +552,7 @@ public class ClusterInspector : Editor {
if (GUILayout.Button("Delete this neuron")) if (GUILayout.Button("Delete this neuron"))
DeleteNeuron(this.currentNucleus); DeleteNeuron(this.currentNucleus);
if (this.currentNucleus is Cluster subCluster) { if (this.currentNucleus is ClusterInstance subCluster) {
if (GUILayout.Button("Edit Cluster")) if (GUILayout.Button("Edit Cluster"))
EditCluster(subCluster); EditCluster(subCluster);
} }
@ -588,7 +588,7 @@ public class ClusterInspector : Editor {
return; return;
if (nucleus.cluster != null) if (nucleus.cluster != null)
this.currentNucleus = nucleus.cluster.output; this.currentNucleus = nucleus.cluster.output;
foreach (INucleus receiver in nucleus.allReceivers) { foreach (INucleus receiver in nucleus.receivers) {
if (receiver != null) { if (receiver != null) {
this.currentNucleus = receiver; this.currentNucleus = receiver;
break; break;
@ -603,17 +603,16 @@ public class ClusterInspector : Editor {
} }
private void OnClusterPicked(INucleus nucleus, Cluster subCluster) { private void OnClusterPicked(INucleus nucleus, Cluster subCluster) {
Cluster clusterInstance = Instantiate(subCluster); ClusterInstance clusterInstance = new(subCluster);
clusterInstance.asset = subCluster; this.cluster.AddSubCluster(clusterInstance);
this.cluster.AddSubCluster(subCluster);
clusterInstance.AddReceiver(nucleus); clusterInstance.AddReceiver(nucleus);
} }
private void EditCluster(Cluster subCluster) { private void EditCluster(ClusterInstance subCluster) {
//var currentActiveObject = Selection.activeObject; //var currentActiveObject = Selection.activeObject;
Selection.activeObject = subCluster; Selection.activeObject = subCluster.asset;
EditorGUIUtility.PingObject(subCluster); EditorGUIUtility.PingObject(subCluster.asset);
var editor = Editor.CreateEditor(subCluster); var editor = Editor.CreateEditor(subCluster.asset);
//Selection.activeObject = currentActiveObject; //Selection.activeObject = currentActiveObject;
} }

View File

@ -14,19 +14,18 @@ MonoBehaviour:
m_EditorClassIdentifier: Assembly-CSharp::Cluster m_EditorClassIdentifier: Assembly-CSharp::Cluster
asset: {fileID: 0} asset: {fileID: 0}
nuclei: nuclei:
- rid: 2243601242842202259 - rid: 2243601249170358341
subClusters: []
references: references:
version: 2 version: 2
RefIds: RefIds:
- rid: 2243601242842202259 - rid: 2243601249170358341
type: {class: Neuron, ns: , asm: Assembly-CSharp} type: {class: Neuron, ns: , asm: Assembly-CSharp}
data: data:
_name: Output _name: Output
_synapses: [] _synapses: []
_receivers: [] _receivers: []
_array: _array:
rid: 2243601242842202260 rid: 2243601249170358342
_curvePreset: 0 _curvePreset: 0
curve: curve:
serializedVersion: 2 serializedVersion: 2
@ -54,9 +53,9 @@ MonoBehaviour:
m_RotationOrder: 4 m_RotationOrder: 4
curveMax: 1 curveMax: 1
average: 0 average: 0
- rid: 2243601242842202260 - rid: 2243601249170358342
type: {class: NucleusArray, ns: , asm: Assembly-CSharp} type: {class: NucleusArray, ns: , asm: Assembly-CSharp}
data: data:
_nuclei: _nuclei:
- rid: 2243601242842202259 - rid: 2243601249170358341
name: Output name: Output