diff --git a/examples/audio.json b/examples/audio.json
deleted file mode 100644
index 6945e8a..0000000
--- a/examples/audio.json
+++ /dev/null
@@ -1 +0,0 @@
-{"last_node_id":16,"last_link_id":16,"nodes":[{"id":9,"type":"widget/knob","pos":[440,81],"size":[80,100],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[8,9]}],"properties":{"min":0,"max":4,"value":0.24000000000000002,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":10,"type":"basic/watch","pos":[537,81],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"value","type":0,"link":9,"label":"0.000"}],"outputs":[{"name":"value","type":0,"links":null,"label":""}],"properties":{"value":0.24000000000000002}},{"id":1,"type":"audio/destination","pos":[699,83],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"in","type":"audio","link":1}],"properties":{}},{"id":6,"type":"widget/knob","pos":[116,179],"size":[80,100],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[5]}],"properties":{"min":0,"max":1,"value":0.5099999999999996,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":0,"type":"audio/source","pos":[272,192],"size":{"0":140,"1":86},"flags":{},"mode":0,"inputs":[{"name":"gain","type":"number","link":5},{"name":"Play","type":-1,"link":6},{"name":"Stop","type":-1,"link":7},{"name":"playbackRate","type":"number","link":8}],"outputs":[{"name":"out","type":"audio","links":[0]}],"properties":{"src":"demodata/audio.wav","gain":0.5,"loop":true,"autoplay":true,"playbackRate":0.24000000000000002},"boxcolor":"#AA4"},{"id":2,"type":"audio/biquadfilter","pos":[442,228],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"in","type":"audio","link":0},{"name":"frequency","type":"number","link":4}],"outputs":[{"name":"out","type":"audio","links":[1,2]}],"properties":{"frequency":350,"detune":0,"Q":1,"type":"lowpass"}},{"id":3,"type":"audio/analyser","pos":[704,231],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"in","type":"audio","link":2}],"outputs":[{"name":"freqs","type":"array","links":[3,10]},{"name":"samples","type":"array","links":null}],"properties":{"fftSize":2048,"minDecibels":-100,"maxDecibels":-10,"smoothingTimeConstant":0.5}},{"id":11,"type":"audio/signal","pos":[882,395],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"freqs","type":"array","link":10},{"name":"band","type":"number","link":11}],"outputs":[{"name":"signal","type":"number","links":[12]}],"properties":{"band":440,"amplitude":1,"samplerate":44100}},{"id":4,"type":"audio/visualization","pos":[885,503],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"freqs","type":"array","link":3},{"name":"mark","type":"number","link":13}],"properties":{"continuous":true,"mark":12000.000000000005,"samplerate":44100}},{"id":5,"type":"widget/knob","pos":[112,314],"size":[80,100],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[4]}],"properties":{"min":0,"max":20000,"value":14800.00000000001,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":13,"type":"basic/watch","pos":[110,458],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"value","type":0,"link":12,"label":"0.000"}],"outputs":[{"name":"value","type":0,"links":[14],"label":""}],"title":"Max. Signal","properties":{"value":0.3843137254901945}},{"id":14,"type":"widget/progress","pos":[300,460],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"","type":"number","link":14}],"properties":{"min":0,"max":1,"value":0.3843137254901945,"wcolor":"#AAF"}},{"id":12,"type":"widget/knob","pos":[460,458],"size":[80,100],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[11,13,15]}],"properties":{"min":0,"max":24000,"value":12000.000000000005,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":15,"type":"basic/watch","pos":[888,598],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"value","type":0,"link":15,"label":"0.000"}],"outputs":[{"name":"value","type":0,"links":null,"label":""}],"properties":{"value":12000.000000000005}},{"id":7,"type":"widget/button","pos":[113,83],"size":{"0":141,"1":60},"flags":{},"mode":0,"outputs":[{"name":"clicked","type":-1,"links":[6]}],"properties":{"text":"Play","font_size":30,"message":"","font":"40px Arial"}},{"id":8,"type":"widget/button","pos":[273,83],"size":{"0":143,"1":62},"flags":{},"mode":0,"outputs":[{"name":"clicked","type":-1,"links":[7]}],"properties":{"text":"Stop","font_size":30,"message":"","font":"40px Arial"}}],"links":[[0,0,0,2,0,null],[1,2,0,1,0,null],[2,2,0,3,0,null],[3,3,0,4,0,null],[4,5,0,2,1,null],[5,6,0,0,0,null],[6,7,0,0,1,null],[7,8,0,0,2,null],[8,9,0,0,3,null],[9,9,0,10,0,null],[10,3,0,11,0,null],[11,12,0,11,1,null],[12,11,0,13,0,null],[13,12,0,4,1,null],[14,13,0,14,0,null],[15,12,0,15,0,null]],"groups":[],"config":{}}
\ No newline at end of file
diff --git a/examples/audio_delay.json b/examples/audio_delay.json
deleted file mode 100644
index 1ba5c63..0000000
--- a/examples/audio_delay.json
+++ /dev/null
@@ -1 +0,0 @@
-{"iteration":27893,"last_node_id":7,"last_link_id":7,"links":{"0":{"id":0,"origin_id":0,"origin_slot":0,"target_id":1,"target_slot":0,"data":null},"1":{"id":1,"origin_id":0,"origin_slot":0,"target_id":2,"target_slot":0,"data":null},"2":{"id":2,"origin_id":2,"origin_slot":0,"target_id":1,"target_slot":2,"data":null},"3":{"id":3,"origin_id":1,"origin_slot":0,"target_id":3,"target_slot":0,"data":null},"4":{"id":4,"origin_id":4,"origin_slot":0,"target_id":1,"target_slot":1,"data":null},"5":{"id":5,"origin_id":5,"origin_slot":0,"target_id":1,"target_slot":3,"data":null},"6":{"id":6,"origin_id":6,"origin_slot":0,"target_id":2,"target_slot":1,"data":null}},"config":{},"nodes":[{"id":0,"title":"Source","type":"audio/source","pos":[195,187],"size":{"0":140,"1":20},"flags":{},"inputs":[{"name":"gain","type":"number","link":null}],"outputs":[{"name":"out","type":"audio","links":[0,1]}],"mode":0,"properties":{"src":"demodata/audio.wav","gain":0.5,"loop":true,"autoplay":true,"playbackRate":1}},{"id":1,"title":"Mixer","type":"audio/mixer","pos":[655,183],"size":{"0":140,"1":62},"flags":{},"inputs":[{"name":"in1","type":"audio","link":0},{"name":"in1 gain","type":"number","link":4},{"name":"in2","type":"audio","link":2},{"name":"in2 gain","type":"number","link":5}],"outputs":[{"name":"out","type":"audio","links":[3]}],"mode":0,"properties":{"gain1":0.5,"gain2":0.8}},{"id":3,"title":"Destination","type":"audio/destination","pos":[911,180],"size":{"0":140,"1":20},"flags":{},"inputs":[{"name":"in","type":"audio","link":3}],"mode":0,"properties":{}},{"id":4,"title":"Knob","type":"widget/knob","pos":[408,59],"size":[54,74],"flags":{},"outputs":[{"name":"","type":"number","links":[4]}],"mode":0,"properties":{"min":0,"max":1,"value":0.24000000000000007,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":5,"title":"Knob","type":"widget/knob","pos":[433,371],"size":[54,74],"flags":{},"outputs":[{"name":"","type":"number","links":[5]}],"mode":0,"properties":{"min":0,"max":1,"value":0.5199999999999996,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":2,"title":"Delay","type":"audio/delay","pos":[385,255],"size":{"0":142,"1":38},"flags":{},"inputs":[{"name":"in","type":"audio","link":1},{"name":"time","type":"number","link":6}],"outputs":[{"name":"out","type":"audio","links":[2]}],"mode":0,"properties":{"delayTime":0.5,"time":1}},{"id":6,"title":"Knob","type":"widget/knob","pos":[199,296],"size":[64,84],"flags":{},"outputs":[{"name":"","type":"number","links":[6]}],"mode":0,"properties":{"min":0,"max":2,"value":0.8799999999999999,"wcolor":"#7AF","size":50},"boxcolor":"rgba(112,112,112,1.0)"}]}
\ No newline at end of file
diff --git a/examples/audio_reverb.json b/examples/audio_reverb.json
deleted file mode 100644
index 511a4d1..0000000
--- a/examples/audio_reverb.json
+++ /dev/null
@@ -1 +0,0 @@
-{"iteration":48488,"last_node_id":8,"last_link_id":9,"links":{"0":{"id":0,"origin_id":0,"origin_slot":0,"target_id":1,"target_slot":0,"data":null},"1":{"id":1,"origin_id":0,"origin_slot":0,"target_id":2,"target_slot":0,"data":null},"3":{"id":3,"origin_id":1,"origin_slot":0,"target_id":3,"target_slot":0,"data":null},"4":{"id":4,"origin_id":4,"origin_slot":0,"target_id":1,"target_slot":1,"data":null},"5":{"id":5,"origin_id":5,"origin_slot":0,"target_id":1,"target_slot":3,"data":null},"6":{"id":6,"origin_id":6,"origin_slot":0,"target_id":2,"target_slot":1,"data":null},"7":{"id":7,"origin_id":0,"origin_slot":0,"target_id":7,"target_slot":0,"data":null},"8":{"id":8,"origin_id":7,"origin_slot":0,"target_id":1,"target_slot":2,"data":null}},"config":{},"nodes":[{"id":1,"title":"Mixer","type":"audio/mixer","pos":[655,183],"size":{"0":140,"1":62},"flags":{},"inputs":[{"name":"in1","type":"audio","link":0},{"name":"in1 gain","type":"number","link":4},{"name":"in2","type":"audio","link":8},{"name":"in2 gain","type":"number","link":5}],"outputs":[{"name":"out","type":"audio","links":[3]}],"mode":0,"properties":{"gain1":0.5,"gain2":0.8}},{"id":3,"title":"Destination","type":"audio/destination","pos":[911,180],"size":{"0":140,"1":20},"flags":{},"inputs":[{"name":"in","type":"audio","link":3}],"mode":0,"properties":{}},{"id":0,"title":"Source","type":"audio/source","pos":[195,187],"size":{"0":140,"1":20},"flags":{},"inputs":[{"name":"gain","type":"number","link":null}],"outputs":[{"name":"out","type":"audio","links":[0,7]}],"mode":0,"properties":{"src":"demodata/audio.wav","gain":0.5,"loop":true,"autoplay":true,"playbackRate":1}},{"id":7,"title":"Convolver","type":"audio/convolver","pos":[421,253],"size":{"0":140,"1":20},"flags":{},"inputs":[{"name":"in","type":"audio","link":7}],"outputs":[{"name":"out","type":"audio","links":[8]}],"mode":0,"properties":{"impulse_src":"demodata/impulse.wav","normalize":true}},{"id":5,"title":"Reverb","type":"widget/knob","pos":[398,311],"size":[84,100],"flags":{},"outputs":[{"name":"","type":"number","links":[5]}],"mode":0,"properties":{"min":0,"max":1,"value":0.4099999999999999,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":4,"title":"Main","type":"widget/knob","pos":[408,59],"size":[81,93],"flags":{},"outputs":[{"name":"","type":"number","links":[4]}],"mode":0,"properties":{"min":0,"max":1,"value":0.21000000000000002,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"}]}
\ No newline at end of file
diff --git a/examples/benchmark.json b/examples/benchmark.json
deleted file mode 100644
index ad2094e..0000000
--- a/examples/benchmark.json
+++ /dev/null
@@ -1 +0,0 @@
-{"last_node_id":60,"last_link_id":50,"nodes":[{"id":9,"type":"features/slots","pos":[846,473],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":6}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":8,"type":"features/slots","pos":[671,475],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":10}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":18,"type":"features/slots","pos":[751.5619834710739,854.9586776859505],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":16}],"outputs":[{"name":"A","type":"number","links":[17,18]},{"name":"B","type":"number","links":[]}],"properties":{}},{"id":28,"type":"features/slots","pos":[1386.361032999997,389.62936599999995],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":23}],"outputs":[{"name":"A","type":"number","links":[24,25]},{"name":"B","type":"number","links":[]}],"properties":{}},{"id":35,"type":"features/shape","pos":[1555.6387189504107,741.7260602148749],"size":{"0":140,"1":39},"flags":{},"mode":0,"inputs":[{"name":"","type":"number","link":26}],"outputs":[{"name":"","type":"number","links":null}],"properties":{}},{"id":38,"type":"features/slots","pos":[1461.838718950411,987.9260602148759],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":28}],"outputs":[{"name":"A","type":"number","links":[29,30]},{"name":"B","type":"number","links":[]}],"properties":{}},{"id":39,"type":"features/slots","pos":[1376.8387189504106,1088.9260602148756],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":29}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":40,"type":"features/slots","pos":[1551.838718950411,1086.9260602148754],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":30}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":45,"type":"features/slots","pos":[588.5619834710739,1055.9586776859496],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":33}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":46,"type":"features/slots","pos":[721.5619834710739,1058.9586776859496],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":34}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":19,"type":"features/slots","pos":[666.5619834710739,955.9586776859505],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":17}],"outputs":[{"name":"A","type":"number","links":[33]},{"name":"B","type":"number","links":[34]}],"properties":{}},{"id":47,"type":"features/slots","pos":[846.5619834710739,1060.9586776859496],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":35}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":48,"type":"features/slots","pos":[976.5619834710739,1059.9586776859496],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":36}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":20,"type":"features/slots","pos":[841.5619834710739,953.9586776859505],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":18}],"outputs":[{"name":"A","type":"number","links":[35]},{"name":"B","type":"number","links":[36]}],"properties":{}},{"id":29,"type":"features/slots","pos":[1307,490],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":24}],"outputs":[{"name":"A","type":"number","links":[37]},{"name":"B","type":"number","links":[38]}],"properties":{}},{"id":30,"type":"features/slots","pos":[1476.3610329999974,488.62936599999995],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":25}],"outputs":[{"name":"A","type":"number","links":[39]},{"name":"B","type":"number","links":[40]}],"properties":{}},{"id":7,"type":"features/slots","pos":[756,374],"size":[100,40],"flags":{"horizontal":true,"collapsed":false},"mode":0,"inputs":[{"name":"C","type":"number","link":13}],"outputs":[{"name":"A","type":"number","links":[10]},{"name":"B","type":"number","links":[6]}],"properties":{}},{"id":34,"type":"features/widgets","pos":[1054,349],"size":{"0":189,"1":176},"flags":{"collapsed":false},"mode":0,"outputs":[{"name":"","type":"number","links":[23]}],"properties":{}},{"id":12,"type":"input/gamepad","pos":[607,204],"size":{"0":155,"1":69},"flags":{"collapsed":false},"mode":0,"outputs":[{"name":"left_x_axis","type":"number","links":null},{"name":"left_y_axis","type":"number","links":null},{"name":"button_pressed","type":-1,"links":[12]}],"properties":{"gamepad_index":0,"threshold":0.1}},{"id":4,"type":"math/operation","pos":[604,106],"size":[164,51],"flags":{"collapsed":false},"mode":0,"inputs":[{"name":"A","type":"number","link":2},{"name":"B","type":"number","link":9}],"outputs":[{"name":"=","type":"number","links":[1]}],"properties":{"A":2,"B":0.5,"OP":"+"},"shape":2},{"id":2,"type":"features/shape","pos":[867,112],"size":{"0":140,"1":39},"flags":{},"mode":0,"inputs":[{"name":"","type":"number","link":1}],"outputs":[{"name":"","type":"number","links":null}],"properties":{}},{"id":13,"type":"events/log","pos":[868,215],"size":{"0":143,"1":30},"flags":{},"mode":0,"inputs":[{"name":"event","type":-1,"link":12}],"properties":{}},{"id":14,"type":"features/widgets","pos":[432,357],"size":{"0":209,"1":178},"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[13]}],"properties":{}},{"id":24,"type":"features/widgets","pos":[429,841],"size":{"0":184.9173583984375,"1":176.34710693359375},"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[16]}],"properties":{}},{"id":44,"type":"features/widgets","pos":[1154,942],"size":{"0":191,"1":174},"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[28]}],"properties":{}},{"id":36,"type":"math/operation","pos":[1333,729],"size":[144,45],"flags":{},"mode":0,"inputs":[{"name":"A","type":"number","link":27},{"name":"B","type":"number","link":null}],"outputs":[{"name":"=","type":"number","links":[26]}],"properties":{"A":2,"B":1,"OP":"+"},"shape":2},{"id":42,"type":"input/gamepad","pos":[1316,821],"size":{"0":182.3612823486328,"1":69.27394104003906},"flags":{"collapsed":false},"mode":0,"outputs":[{"name":"left_x_axis","type":"number","links":null},{"name":"left_y_axis","type":"number","links":null},{"name":"button_pressed","type":-1,"links":[]}],"properties":{"gamepad_index":0,"threshold":0.1}},{"id":43,"type":"events/log","pos":[1562,845],"size":{"0":142.16128540039062,"1":31.07394027709961},"flags":{},"mode":0,"inputs":[{"name":"event","type":-1,"link":null}],"properties":{}},{"id":41,"type":"widget/knob","pos":[1155,824],"size":[54,74],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[]}],"properties":{"min":0,"max":1,"value":0.5,"color":"#7AF","precision":2,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":37,"type":"math/operation","pos":[1138,739],"size":[148,44],"flags":{},"mode":0,"inputs":[{"name":"A","type":"number","link":null},{"name":"B","type":"number","link":null}],"outputs":[{"name":"=","type":"number","links":[27]}],"properties":{"A":1,"B":1,"OP":"+"},"color":"#233","bgcolor":"#355","shape":2},{"id":33,"type":"events/log","pos":[1493.3610329999974,224.629366],"size":{"0":147.6389617919922,"1":29.370634078979492},"flags":{},"mode":0,"inputs":[{"name":"event","type":-1,"link":32}],"properties":{}},{"id":26,"type":"math/operation","pos":[1268,128],"size":[144,50],"flags":{},"mode":0,"inputs":[{"name":"A","type":"number","link":22},{"name":"B","type":"number","link":31}],"outputs":[{"name":"=","type":"number","links":[21]}],"properties":{"A":2,"B":0.5,"OP":"+"},"shape":2},{"id":5,"type":"math/operation","pos":[437,114],"size":[140,48],"flags":{"collapsed":true},"mode":0,"inputs":[{"name":"A","type":"number","link":null},{"name":"B","type":"number","link":null}],"outputs":[{"name":"=","type":"number","links":[2]}],"properties":{"A":1,"B":1,"OP":"+"},"shape":2},{"id":27,"type":"math/operation","pos":[1061,129],"size":[144,44],"flags":{"collapsed":true},"mode":0,"inputs":[{"name":"A","type":"number","link":null},{"name":"B","type":"number","link":null}],"outputs":[{"name":"=","type":"number","links":[22]}],"properties":{"A":1,"B":1,"OP":"+"},"shape":2},{"id":49,"type":"features/slots","pos":[1210,589],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":37}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":50,"type":"features/slots","pos":[1342,591],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":38}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":51,"type":"features/slots","pos":[1471,590],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":39}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":52,"type":"features/slots","pos":[1597,588],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":40}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":25,"type":"features/shape","pos":[1500,116],"size":{"0":140,"1":39},"flags":{},"mode":0,"inputs":[{"name":"","type":"number","link":21}],"outputs":[{"name":"","type":"number","links":null}],"properties":{}},{"id":10,"type":"widget/knob","pos":[435,161],"size":[91,111],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[9]}],"properties":{"min":0,"max":1,"value":0.5,"color":"#7AF","precision":2,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":31,"type":"widget/knob","pos":[1058,182],"size":[95,114],"flags":{"collapsed":false},"mode":0,"outputs":[{"name":"","type":"number","links":[31]}],"properties":{"min":0,"max":1,"value":0.5,"color":"#7AF","precision":2,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":32,"type":"input/gamepad","pos":[1232,231],"size":{"0":191.6389617919922,"1":73.37063598632812},"flags":{"collapsed":false},"mode":0,"outputs":[{"name":"left_x_axis","type":"number","links":[46]},{"name":"left_y_axis","type":"number","links":[47]},{"name":"button_pressed","type":-1,"links":[32]}],"properties":{"gamepad_index":0,"threshold":0.1}},{"id":57,"type":"graphics/plot","pos":[1722,335],"size":{"0":140,"1":86},"flags":{},"mode":0,"inputs":[{"name":"A","type":"Number","link":48},{"name":"B","type":"Number","link":null},{"name":"C","type":"Number","link":null},{"name":"D","type":"Number","link":null}],"properties":{"scale":2}},{"id":21,"type":"widget/knob","pos":[435,591],"size":[72,90],"flags":{"collapsed":false},"mode":0,"outputs":[{"name":"","type":"number","links":[43]}],"properties":{"min":0,"max":1,"value":0.7297408895318863,"color":"#7AF","precision":2,"wcolor":"#7AF","size":50},"boxcolor":"rgba(186,186,186,1.0)"},{"id":16,"type":"math/operation","pos":[583,611],"size":[140,47],"flags":{"collapsed":false},"mode":0,"inputs":[{"name":"A","type":"number","link":43},{"name":"B","type":"number","link":45}],"outputs":[{"name":"=","type":"number","links":[44]}],"properties":{"A":0.7297408895318863,"B":5000,"OP":"*"},"shape":2},{"id":54,"type":"events/timer","pos":[764,620],"size":{"0":147,"1":30},"flags":{"collapsed":false},"mode":0,"inputs":[{"name":"interval","type":"number","link":44}],"outputs":[{"name":"on_tick","type":-1,"links":[42]}],"properties":{"interval":1000,"event":"tick"},"boxcolor":"#222","shape":2},{"id":23,"type":"events/log","pos":[961,622],"size":{"0":137,"1":28},"flags":{},"mode":0,"inputs":[{"name":"event","type":-1,"link":42}],"properties":{}},{"id":56,"type":"graph/subgraph","pos":[1543,336],"size":{"0":140,"1":86},"flags":{},"mode":0,"inputs":[{"name":"enabled","type":"boolean","link":49},{"name":"AxisX","type":0,"link":46},{"name":"AxisY","type":0,"link":47}],"outputs":[{"name":"sum","type":0,"links":[48]}],"properties":{"enabled":true},"subgraph":{"last_node_id":6,"last_link_id":4,"nodes":[{"id":4,"type":"graph/output","pos":[1655,311],"size":[180,60],"flags":{},"mode":0,"inputs":[{"name":"","type":0,"link":3}],"properties":{"name":"sum","type":0}},{"id":2,"type":"graph/input","pos":[1227,233],"size":[180,60],"flags":{},"mode":0,"outputs":[{"name":"","type":"","links":[1]}],"properties":{"name":"AxisX","type":""}},{"id":3,"type":"graph/input","pos":[1234,341],"size":[180,60],"flags":{},"mode":0,"outputs":[{"name":"","type":"","links":[2]}],"properties":{"name":"AxisY","type":""}},{"id":6,"type":"math/operation","pos":[1496,268],"size":[100,60],"flags":{},"mode":0,"inputs":[{"name":"A","type":"number","link":1},{"name":"B","type":"number","link":2}],"outputs":[{"name":"=","type":"number","links":[3]}],"properties":{"A":1,"B":1,"OP":"+"}}],"links":[[1,2,0,6,0,"number"],[2,3,0,6,1,"number"],[3,6,0,4,0,0]],"groups":[],"config":{},"version":0.4}},{"id":58,"type":"widget/toggle","pos":[1686,131],"size":[160,44],"flags":{},"mode":0,"inputs":[{"name":"","type":"boolean","link":null},{"name":"e","type":-1,"link":null}],"outputs":[{"name":"v","type":"boolean","links":[49]},{"name":"e","type":-1,"links":null}],"properties":{"font":"","value":true}},{"id":60,"type":"widget/number","pos":[626,706],"size":[74,54],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":null}],"properties":{"min":-1000,"max":1000,"value":1,"step":1}},{"id":55,"type":"basic/const","pos":[422,738],"size":{"0":139,"1":28},"flags":{"collapsed":false},"mode":0,"outputs":[{"name":"value","type":"number","links":[45],"label":"5000.000"}],"properties":{"value":5000}}],"links":[[1,4,0,2,0,"number"],[2,5,0,4,0,"number"],[6,7,1,9,0,"number"],[9,10,0,4,1,"number"],[10,7,0,8,0,"number"],[12,12,2,13,0,-1],[13,14,0,7,0,"number"],[16,24,0,18,0,"number"],[17,18,0,19,0,"number"],[18,18,0,20,0,"number"],[21,26,0,25,0,"number"],[22,27,0,26,0,"number"],[23,34,0,28,0,"number"],[24,28,0,29,0,"number"],[25,28,0,30,0,"number"],[26,36,0,35,0,"number"],[27,37,0,36,0,"number"],[28,44,0,38,0,"number"],[29,38,0,39,0,"number"],[30,38,0,40,0,"number"],[31,31,0,26,1,"number"],[32,32,2,33,0,-1],[33,19,0,45,0,"number"],[34,19,1,46,0,"number"],[35,20,0,47,0,"number"],[36,20,1,48,0,"number"],[37,29,0,49,0,"number"],[38,29,1,50,0,"number"],[39,30,0,51,0,"number"],[40,30,1,52,0,"number"],[42,54,0,23,0,-1],[43,21,0,16,0,"number"],[44,16,0,54,0,"number"],[45,55,0,16,1,"number"],[46,32,0,56,1,0],[47,32,1,56,2,0],[48,56,0,57,0,"Number"],[49,58,0,56,0,"boolean"]],"groups":[{"title":"Group","bounding":[417,292,564,255],"color":"#3f789e"},{"title":"Group","bounding":[1120,678,642,461],"color":"#A88"},{"title":"Group","bounding":[411,777,679,361],"color":"#8A8"}],"config":{},"version":0.4}
\ No newline at end of file
diff --git a/examples/features.json b/examples/features.json
deleted file mode 100644
index ead5a6d..0000000
--- a/examples/features.json
+++ /dev/null
@@ -1 +0,0 @@
-{"last_node_id":14,"last_link_id":14,"nodes":[{"id":9,"type":"features/slots","pos":[847,479],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":6}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":7,"type":"features/slots","pos":[757,380],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":13}],"outputs":[{"name":"A","type":"number","links":[10]},{"name":"B","type":"number","links":[6]}],"properties":{}},{"id":8,"type":"features/slots","pos":[672,481],"size":[100,40],"flags":{"horizontal":true},"mode":0,"inputs":[{"name":"C","type":"number","link":10}],"outputs":[{"name":"A","type":"number","links":null},{"name":"B","type":"number","links":null}],"properties":{}},{"id":5,"type":"math/operation","pos":[413,101],"size":[140,34],"flags":{"collapsed":true},"mode":0,"inputs":[{"name":"A","type":"number","link":null},{"name":"B","type":"number","link":null}],"outputs":[{"name":"=","type":"number","links":[2]}],"properties":{"A":1,"B":1,"OP":"+"},"shape":2},{"id":12,"type":"input/gamepad","pos":[593,208],"size":{"0":175,"1":74},"flags":{},"mode":0,"outputs":[{"name":"left_x_axis","type":"number","links":null},{"name":"left_y_axis","type":"number","links":null},{"name":"button_pressed","type":-1,"links":[12]}],"properties":{"gamepad_index":0,"threshold":0.1}},{"id":13,"type":"events/log","pos":[862,246],"size":{"0":144,"1":32},"flags":{},"mode":0,"inputs":[{"name":"event","type":-1,"link":12}],"properties":{}},{"id":14,"type":"features/widgets","pos":[441,365],"size":{"0":180,"1":170},"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[13]}],"properties":{}},{"id":10,"type":"widget/knob","pos":[421,197],"size":[74,92],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[9]}],"properties":{"min":0,"max":1,"value":0.5,"wcolor":"#7AF","size":50}},{"id":4,"type":"math/operation","pos":[596,116],"size":[148,48],"flags":{},"mode":0,"inputs":[{"name":"A","type":"number","link":2},{"name":"B","type":"number","link":9}],"outputs":[{"name":"=","type":"number","links":[1]}],"properties":{"A":1,"B":1,"OP":"+"},"shape":2},{"id":2,"type":"features/shape","pos":[850,97],"size":{"0":140,"1":39},"flags":{},"mode":0,"inputs":[{"name":"","type":"number","link":1}],"outputs":[{"name":"","type":"number","links":null}],"properties":{}}],"links":[[1,4,0,2,0,"number"],[2,5,0,4,0,"number"],[6,7,1,9,0,"number"],[9,10,0,4,1,"number"],[10,7,0,8,0,"number"],[12,12,2,13,0,-1],[13,14,0,7,0,"number"]],"groups":[{"title":"Group","bounding":[418,298,609,255],"color":"#3f789e"}],"config":{}}
\ No newline at end of file
diff --git a/examples/midi_generation.json b/examples/midi_generation.json
deleted file mode 100644
index 960c59f..0000000
--- a/examples/midi_generation.json
+++ /dev/null
@@ -1 +0,0 @@
-{"last_node_id":47,"last_link_id":64,"nodes":[{"id":8,"type":"midi/generator","pos":[548,390],"size":{"0":140,"1":66},"flags":{},"mode":0,"inputs":[{"name":"generate","type":-1,"link":11},{"name":"scale","type":"string","link":47},{"name":"octave","type":"number","link":null}],"outputs":[{"name":"note","type":-1,"links":[10,19]}],"properties":{"notes":"A,B,C","octave":2,"duration":0.5,"mode":"sequence"}},{"id":20,"type":"midi/transpose","pos":[726,489],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"in","type":-1,"link":19},{"name":"amount","type":"number","link":null}],"outputs":[{"name":"out","type":-1,"links":[21]}],"properties":{"amount":5}},{"id":32,"type":"midi/event","pos":[1465,656],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"send","type":-1,"link":null},{"name":"assign","type":-1,"link":44}],"outputs":[{"name":"on_midi","type":-1,"links":null},{"name":"note","type":"number","links":[45]}],"properties":{"channel":0,"cmd":128,"value1":0,"value2":0}},{"id":19,"type":"midi/play","pos":[1132,611],"size":{"0":140,"1":66},"flags":{},"mode":0,"inputs":[{"name":"note","type":-1,"link":53},{"name":"volume","type":"number","link":36},{"name":"duration","type":"number","link":null}],"outputs":[{"name":"note","type":-1,"links":[35,44]}],"properties":{"volume":0.3599999999999999,"duration":4,"value":0}},{"id":21,"type":"midi/quantize","pos":[903,589],"size":{"0":159.60000610351562,"1":46},"flags":{},"mode":0,"inputs":[{"name":"note","type":-1,"link":21},{"name":"scale","type":"string","link":49}],"outputs":[{"name":"out","type":-1,"links":[53]}],"properties":{"scale":"A,A#,B,C,C#,D,D#,E,F,F#,G,G#","amount":"A,B,C,D,E,F,G"}},{"id":37,"type":"basic/watch","pos":[547,615],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"value","type":0,"link":52,"label":"A,B,C,B"}],"properties":{}},{"id":35,"type":"basic/string","pos":[79,456],"size":[210,58],"flags":{},"mode":0,"outputs":[{"name":"value","type":"string","links":[50],"label":"A,B,C"}],"title":"NOTE SCALE","properties":{"value":"A,B,C,B"}},{"id":7,"type":"midi/generator","pos":[549,289],"size":{"0":140,"1":66},"flags":{},"mode":0,"inputs":[{"name":"generate","type":-1,"link":5},{"name":"scale","type":"string","link":48},{"name":"octave","type":"number","link":null}],"outputs":[{"name":"note","type":-1,"links":[7,12]}],"properties":{"notes":"A,B,C","octave":2,"duration":0.5,"mode":"random"}},{"id":41,"type":"midi/generator","pos":[552,189],"size":{"0":140,"1":66},"flags":{},"mode":0,"inputs":[{"name":"generate","type":-1,"link":57},{"name":"scale","type":"string","link":55},{"name":"octave","type":"number","link":null}],"outputs":[{"name":"note","type":-1,"links":[62]}],"properties":{"notes":"A,B,C","octave":3,"duration":0.5,"mode":"sequence"}},{"id":12,"type":"events/timer","pos":[180,284],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"interval","type":"number","link":null}],"outputs":[{"name":"on_tick","type":-1,"links":[11]}],"properties":{"interval":1200,"event":"tick"},"boxcolor":"#222"},{"id":34,"type":"logic/selector","pos":[351,468],"size":{"0":140,"1":106},"flags":{},"mode":0,"inputs":[{"name":"sel","type":"number","link":58},{"name":"A","type":0,"link":46},{"name":"B","type":0,"link":50},{"name":"C","type":0,"link":59},{"name":"D","type":0,"link":null}],"outputs":[{"name":"out","links":[47,48,49,52,55]}],"properties":{}},{"id":47,"type":"midi/keys","pos":[1153,88],"size":[423,104],"flags":{},"mode":0,"inputs":[{"name":"note","type":-1,"link":62},{"name":"reset","type":-1,"link":null}],"outputs":[{"name":"note","type":-1,"links":[63]}],"properties":{"num_octaves":2,"start_octave":3}},{"id":15,"type":"math/floor","pos":[505,85],"size":[140,26],"flags":{"collapsed":true},"mode":0,"inputs":[{"name":"in","type":"number","link":14}],"outputs":[{"name":"out","type":"number","links":[15]}],"properties":{}},{"id":14,"type":"math/rand","pos":[344,83],"size":[140,26],"flags":{"collapsed":true},"mode":0,"outputs":[{"name":"value","type":"number","links":[14],"label":"1.191"}],"properties":{"min":-1,"max":2}},{"id":16,"type":"math/operation","pos":[645,85],"size":[100,50],"flags":{"collapsed":true},"mode":0,"inputs":[{"name":"A","type":"number","link":15},{"name":"B","type":"number","link":null}],"outputs":[{"name":"=","type":"number","links":[16]}],"properties":{"A":1,"B":12,"OP":"*"}},{"id":10,"type":"basic/string","pos":[77,360],"size":[208,48],"flags":{},"mode":0,"outputs":[{"name":"value","type":"string","links":[46],"label":"A,B,C"}],"title":"NOTE SCALE","properties":{"value":"A,B,C,D,E,F,G"}},{"id":43,"type":"basic/string","pos":[79,556],"size":[210,58],"flags":{},"mode":0,"outputs":[{"name":"value","type":"string","links":[59],"label":"A,B,C"}],"title":"NOTE SCALE","properties":{"value":"D,E,F,G,F,E"}},{"id":44,"type":"math/rand","pos":[143,664],"size":[140,26],"flags":{},"mode":0,"outputs":[{"name":"value","type":"number","links":[58],"label":"0.750"}],"properties":{"min":0,"max":1}},{"id":11,"type":"midi/play","pos":[1135,496],"size":{"0":140,"1":66},"flags":{},"mode":0,"inputs":[{"name":"note","type":-1,"link":10},{"name":"volume","type":"number","link":18},{"name":"duration","type":"number","link":null}],"outputs":[{"name":"note","type":-1,"links":[34,43]}],"properties":{"volume":0.3599999999999999,"duration":4,"value":0}},{"id":13,"type":"midi/transpose","pos":[893,258],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"in","type":-1,"link":12},{"name":"amount","type":"number","link":16}],"outputs":[{"name":"out","type":-1,"links":[54]}],"properties":{"amount":12}},{"id":4,"type":"midi/play","pos":[1155,249],"size":{"0":140,"1":66},"flags":{},"mode":0,"inputs":[{"name":"note","type":-1,"link":54},{"name":"volume","type":"number","link":17},{"name":"duration","type":"number","link":null}],"outputs":[{"name":"note","type":-1,"links":[33,39]}],"properties":{"volume":0.21000000000000005,"duration":1,"value":0}},{"id":30,"type":"midi/event","pos":[1433,260],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"send","type":-1,"link":null},{"name":"assign","type":-1,"link":39}],"outputs":[{"name":"on_midi","type":-1,"links":null},{"name":"note","type":"number","links":[38]}],"properties":{"channel":0,"cmd":128,"value1":57,"value2":0}},{"id":28,"type":"midi/output","pos":[1428,414],"size":{"0":140,"1":66},"flags":{},"mode":0,"inputs":[{"name":"send","type":-1,"link":33},{"name":"send","type":-1,"link":34},{"name":"send","type":-1,"link":35}],"properties":{"port":0}},{"id":31,"type":"midi/event","pos":[1469,563],"size":{"0":140,"1":46},"flags":{},"mode":0,"inputs":[{"name":"send","type":-1,"link":null},{"name":"assign","type":-1,"link":43}],"outputs":[{"name":"on_midi","type":-1,"links":null},{"name":"note","type":"number","links":[42]}],"properties":{"channel":0,"cmd":128,"value1":50,"value2":0}},{"id":29,"type":"graphics/plot","pos":[1675,328],"size":{"0":348,"1":139},"flags":{},"mode":0,"inputs":[{"name":"A","type":"Number","link":38},{"name":"B","type":"Number","link":42},{"name":"C","type":"Number","link":45},{"name":"D","type":"Number","link":null}],"properties":{"scale":100}},{"id":46,"type":"math/rand","pos":[1455,42],"size":[140,26],"flags":{"collapsed":true},"mode":0,"outputs":[{"name":"value","type":"number","links":[60],"label":"0.007"}],"properties":{"min":0,"max":0.2}},{"id":39,"type":"midi/play","pos":[1656,116],"size":{"0":140,"1":66},"flags":{},"mode":0,"inputs":[{"name":"note","type":-1,"link":63},{"name":"volume","type":"number","link":60},{"name":"duration","type":"number","link":null}],"outputs":[{"name":"note","type":-1,"links":[]}],"properties":{"volume":0.006812153971126511,"duration":1,"value":0}},{"id":3,"type":"events/timer","pos":[178,212],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"interval","type":"number","link":null}],"outputs":[{"name":"on_tick","type":-1,"links":[5,57]}],"properties":{"interval":300,"event":"tick"},"boxcolor":"#222"},{"id":18,"type":"widget/knob","pos":[819,62],"size":[82.78512396694214,93.87603305785123],"flags":{},"mode":0,"outputs":[{"name":"","type":"number","links":[18,36]}],"properties":{"min":0,"max":1,"value":0.4504132231404958,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":17,"type":"widget/knob","pos":[916,62],"size":[78.34710743801656,94.70247933884298],"flags":{"collapsed":false},"mode":0,"outputs":[{"name":"","type":"number","links":[17]}],"properties":{"min":0,"max":1,"value":0.21000000000000005,"wcolor":"#7AF","size":50},"boxcolor":"rgba(128,128,128,1.0)"},{"id":6,"type":"midi/show","pos":[898,357],"size":[266.5950413223138,61.685950413223],"flags":{},"mode":0,"inputs":[{"name":"on_midi","type":-1,"link":7}],"properties":{}}],"links":[[5,3,0,7,0,-1],[7,7,0,6,0,-1],[10,8,0,11,0,-1],[11,12,0,8,0,-1],[12,7,0,13,0,-1],[14,14,0,15,0,"number"],[15,15,0,16,0,"number"],[16,16,0,13,1,"number"],[17,17,0,4,1,"number"],[18,18,0,11,1,"number"],[19,8,0,20,0,-1],[21,20,0,21,0,-1],[33,4,0,28,0,-1],[34,11,0,28,1,-1],[35,19,0,28,2,-1],[36,18,0,19,1,"number"],[38,30,1,29,0,"Number"],[39,4,0,30,1,-1],[42,31,1,29,1,"Number"],[43,11,0,31,1,-1],[44,19,0,32,1,-1],[45,32,1,29,2,"Number"],[46,10,0,34,1,0],[47,34,0,8,1,"string"],[48,34,0,7,1,"string"],[49,34,0,21,1,"string"],[50,35,0,34,2,0],[52,34,0,37,0,0],[53,21,0,19,0,-1],[54,13,0,4,0,-1],[55,34,0,41,1,"string"],[57,3,0,41,0,-1],[58,44,0,34,0,"number"],[59,43,0,34,3,0],[60,46,0,39,1,"number"],[62,41,0,47,0,-1],[63,47,0,39,0,-1]],"groups":[],"config":{}}
\ No newline at end of file
diff --git a/examples/subgraph.json b/examples/subgraph.json
deleted file mode 100644
index 27c1347..0000000
--- a/examples/subgraph.json
+++ /dev/null
@@ -1 +0,0 @@
-{"last_node_id":6,"last_link_id":5,"nodes":[{"id":3,"type":"basic/time","pos":[312,145],"size":{"0":140,"1":46},"flags":{},"mode":0,"outputs":[{"name":"in ms","type":"number","links":null},{"name":"in sec","type":"number","links":[1]}],"properties":{}},{"id":4,"type":"basic/watch","pos":[864,156],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"value","type":0,"link":2,"label":"5.000"}],"properties":{}},{"id":6,"type":"events/counter","pos":[864,229],"size":{"0":140,"1":66},"flags":{},"mode":0,"inputs":[{"name":"inc","type":-1,"link":4},{"name":"dec","type":-1,"link":null},{"name":"reset","type":-1,"link":null}],"outputs":[{"name":"change","type":-1,"links":null},{"name":"num","type":"number","links":null}],"properties":{}},{"id":2,"type":"graph/subgraph","pos":[573,168],"size":{"0":140,"1":86},"flags":{},"mode":0,"inputs":[{"name":"enabled","type":"boolean","link":null},{"name":"foo","type":"","link":1},{"name":"EV","type":-1,"link":3}],"outputs":[{"name":"faa","type":0,"links":[2]},{"name":"EV","type":-1,"links":[4]}],"properties":{"enabled":true},"subgraph":{"last_node_id":7,"last_link_id":6,"nodes":[{"id":3,"type":"graph/output","pos":[1119,139],"size":[180,60],"flags":{},"mode":0,"inputs":[{"name":"","type":0,"link":2}],"properties":{"name":"faa","type":0}},{"id":4,"type":"math/floor","pos":[872,194],"size":[112,28],"flags":{},"mode":0,"inputs":[{"name":"in","type":"number","link":1}],"outputs":[{"name":"out","type":"number","links":[2]}],"properties":{}},{"id":2,"type":"graph/input","pos":[440,149],"size":[180,60],"flags":{},"mode":0,"outputs":[{"name":"","type":"","links":[1]}],"properties":{"name":"foo","type":""}},{"id":5,"type":"graph/input","pos":[460,282],"size":[180,60],"flags":{},"mode":0,"outputs":[{"name":"","type":-1,"links":[4]}],"properties":{"name":"EV","type":-1}},{"id":6,"type":"graph/output","pos":[1054,293],"size":[180,60],"flags":{},"mode":0,"inputs":[{"name":"","type":-1,"link":5}],"properties":{"name":"EV","type":-1}},{"id":7,"type":"events/delay","pos":[742,300],"size":{"0":140,"1":26},"flags":{},"mode":0,"inputs":[{"name":"event","type":-1,"link":4}],"outputs":[{"name":"on_time","type":-1,"links":[5]}],"properties":{"time_in_ms":1000}}],"links":[[1,2,0,4,0,"number"],[2,4,0,3,0,0],[4,5,0,7,0,-1],[5,7,0,6,0,-1]],"groups":[],"config":{},"version":0.4}},{"id":5,"type":"events/timer","pos":[311,240],"size":{"0":140,"1":26},"flags":{},"mode":0,"outputs":[{"name":"on_tick","type":-1,"links":[3]}],"properties":{"interval":2000,"event":"tick"},"boxcolor":"#222"}],"links":[[1,3,1,2,1,0],[2,2,0,4,0,0],[3,5,0,2,2,-1],[4,2,1,6,0,-1]],"groups":[],"config":{},"version":0.4}
\ No newline at end of file
diff --git a/index.html b/index.html
index 22b92dc..5d1e792 100644
--- a/index.html
+++ b/index.html
@@ -49,12 +49,17 @@
+
+
+
+
+
@@ -66,6 +71,7 @@
+
@@ -74,6 +80,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/js/nodes/download_problem.js b/js/nodes/download_problem.js
index 4487851..17f08df 100644
--- a/js/nodes/download_problem.js
+++ b/js/nodes/download_problem.js
@@ -30,7 +30,7 @@ class DownloadProblem {
zip.file("ProjectParameters.json", new Blob([str]));
Object.entries(problem_files["materials"]).forEach(([key, value]) => {
- zip.file(value["name"]+".json", new Blob([JSON.stringify(value["data"])]));
+ zip.file(value["name"], new Blob([JSON.stringify(value["data"])]));
});
// var img = zip.folder("images");
diff --git a/js/nodes/input/interval.js b/js/nodes/input/interval.js
new file mode 100644
index 0000000..a0bc39a
--- /dev/null
+++ b/js/nodes/input/interval.js
@@ -0,0 +1,21 @@
+
+function Interval(){
+ this.addOutput("", "process_array");
+ this.widget_1 = this.addWidget("number","Initial", 0, function(v){}, {});
+ this.widget_2 = this.addWidget("text","Final", "End", function(v){}, {});
+
+
+};
+
+Interval.title = "Interval";
+Interval.desc = "Time interval";
+
+Interval.prototype.onExecute = function() {
+ this.setOutputData(0, [this.widget_1.value, this.widget_2.value])
+};
+
+LiteGraph.registerNodeType("processes/interval", Interval);
+
+console.log("Interval node created"); //helps to debug
+
+
\ No newline at end of file
diff --git a/js/nodes/materials/material_writer.js b/js/nodes/materials/material_writer.js
index 915571d..b5cb31d 100644
--- a/js/nodes/materials/material_writer.js
+++ b/js/nodes/materials/material_writer.js
@@ -1,7 +1,7 @@
class MaterialWriter {
constructor()
{
- this.material_file_name = this.addWidget("string","Materials Filenae", "Materials");
+ this.material_file_name = this.addWidget("combo","Materials Filename", "Materials.json",function(v){}, { values:["Materials.json","StructuralMaterials.json","StructuralMaterials_HROM.json"]});
this.addInput("Material List","material_array");
this.addOutput("Material","string");
this.size = this.computeSize();
diff --git a/js/nodes/materials/materials_list.js b/js/nodes/materials/materials_list.js
index d0b464c..cc6aa98 100644
--- a/js/nodes/materials/materials_list.js
+++ b/js/nodes/materials/materials_list.js
@@ -5,6 +5,17 @@ class MaterialsList extends InputList{
this.input_type = "material";
this.output_type = "material_array";
}
+ onExecute() {
+ if (!this._value) {
+ this._value = new Array();
+ }
+ this._value.length = this.inputs.length - 1;
+ for (let i = 0; i < this.inputs.length - 1; ++i) {
+ this._value[i] = this.getInputData(i);
+ }
+
+ this.setOutputData(0, {"properties":this._value});
+ }
};
MaterialsList.title = "Materials list";
diff --git a/js/nodes/materials/structural_material.js b/js/nodes/materials/structural_material.js
new file mode 100644
index 0000000..c9c5fb0
--- /dev/null
+++ b/js/nodes/materials/structural_material.js
@@ -0,0 +1,64 @@
+// TODO: Create a material base class
+class StructuralMaterial {
+ constructor()
+ {
+ this.addInput("model_part_name","string");
+ this.properties = {
+ "model_part_name" : "Structure.Parts_Solid_Solid_Auto1",
+ "properties_id" : 1,
+ "Material" : {
+ "constitutive_law" : {
+ "name" : "LinearElasticPlaneStress2DLaw"
+ },
+ "Variables" : {
+ "DENSITY" : 7850.0,
+ "YOUNG_MODULUS" : 206900000000.0,
+ "POISSON_RATIO" : 0.29,
+ "THICKNESS" : 0.1
+ },
+ "Tables" : {}
+ }
+ };
+
+ this.properties_id = this.addWidget("combo","Properties_ID", 1, function(v){}, { values:[1, 2, 3, 4, 5]} );
+ this.name = this.addWidget("combo","Name", "LinearElasticPlaneStress2DLaw", function(v){}, { values:["LinearElasticPlaneStress2DLaw","LinearElastic3DLaw"]} );
+ this.DENSITY= this.addWidget("number","Density", 7850.0, function(v){}, {});
+ this.YOUNG_MODULUS = this.addWidget("number","Young_Modulus", 206900000000.0, function(v){}, {});
+ this.POISSON_RATIO = this.addWidget("number","Poisson_Ratio", 0.29, function(v){}, {});
+ this.THICKNESS = this.addWidget("number","Thinckness", 0.1, function(v){}, {});
+ this.addInput("tables","process_array");
+ this.addOutput("Material","material");
+
+ this.size = this.computeSize();
+ }
+
+ onExecute()
+ {
+ this._value = Object.assign({}, this.properties);
+
+ // Current material model part
+ this._value["model_part_name"] = this.getInputData(0)
+
+ // Table
+ if (this.getInputData(7) != undefined) {
+ this._value["Material"]["Table"] = this.getInputData(7)
+ } else {
+ this._value["Material"]["Table"]= this.properties["Table"]
+ }
+ this._value["properties_id"] = this.properties_id.value
+ this._value["Material"]["constitutive_law"]["name"] = this.name.value
+ this._value["Material"]["Variables"]["DENSITY"] = this.DENSITY.value
+ this._value["Material"]["Variables"]["YOUNG_MODULUS"] = this.YOUNG_MODULUS.value
+ this._value["Material"]["Variables"]["POISSON_RATIO"] = this.POISSON_RATIO.value
+ this._value["Material"]["Variables"]["THICKNESS"] = this.THICKNESS.value
+
+ this.setOutputData(0, this._value);
+ }
+}
+
+StructuralMaterial.title = "Structural material";
+StructuralMaterial.desc = "Node to specify a Structurall material.";
+
+LiteGraph.registerNodeType("materials/StructuralMaterial", StructuralMaterial);
+
+console.log("StructuralMaterialNew node created"); //helps to debug
\ No newline at end of file
diff --git a/js/nodes/output_processes/gid_output_structural.js b/js/nodes/output_processes/gid_output_structural.js
new file mode 100644
index 0000000..d86befe
--- /dev/null
+++ b/js/nodes/output_processes/gid_output_structural.js
@@ -0,0 +1,61 @@
+
+//********************************************************************/
+//********************************************************************/
+//********************************************************************/
+//********************************************************************/
+function GiDStructural() {
+
+ this.addOutput("Process", "process");
+ this.properties = {
+ "python_module" : "gid_output_process",
+ "kratos_module" : "KratosMultiphysics",
+ "process_name" : "GiDOutputProcess",
+ "help" : "This process writes postprocessing files for GiD",
+ "Parameters" : {
+ "model_part_name" : "Structure",
+ "output_name" : "SWQ",
+ "postprocess_parameters" : {
+ "result_file_configuration" : {
+ "gidpost_flags" : {
+ "GiDPostMode" : "GiD_PostBinary",
+ "WriteDeformedMeshFlag" : "WriteDeformed",
+ "WriteConditionsFlag" : "WriteConditions",
+ "MultiFileFlag" : "SingleFile"
+ },
+ "file_label" : "step",
+ "output_control_type" : "step",
+ "output_interval" : 1,
+ "body_output" : true,
+ "node_output" : false,
+ "skin_output" : false,
+ "plane_output" : [],
+ "nodal_results" : ["DISPLACEMENT","REACTION"],
+ "gauss_point_results" : ["VON_MISES_STRESS"],
+ "nodal_nonhistorical_results" : []
+ },
+ "point_data_configuration" : []
+ }
+ }
+ }
+ this.model_part_name = this.addWidget("text","ModelPartName", "Structure", function(v){}, {} );
+ this.output_name = this.addWidget("text","OutputName", "SWQ", function(v){}, {} );
+
+ this.size = this.computeSize();
+}
+
+GiDStructural.title = "GiD structural";
+GiDStructural.desc = "Creates GiD structural";
+
+GiDStructural.prototype.onExecute = function () {
+ output = this.properties
+
+ output["Parameters"]["model_part_name"] = this.model_part_name.value;
+ output["Parameters"]["output_name"] = this.output_name.value;
+
+
+ this.setOutputData(0, output);
+};
+
+LiteGraph.registerNodeType("output_processes/GiDStructural", GiDStructural);
+
+console.log("GiD node created"); //helps to debug
\ No newline at end of file
diff --git a/js/nodes/output_processes/vtk_output_structural.js b/js/nodes/output_processes/vtk_output_structural.js
new file mode 100644
index 0000000..fbf0f7f
--- /dev/null
+++ b/js/nodes/output_processes/vtk_output_structural.js
@@ -0,0 +1,47 @@
+
+//********************************************************************/
+//********************************************************************/
+//********************************************************************/
+//********************************************************************/
+function VTKStructural() {
+
+ this.properties = {
+ "python_module" : "vtk_output_process",
+ "kratos_module" : "KratosMultiphysics",
+ "process_name" : "VtkOutputProcess",
+ "help" : "This process writes postprocessing files for Paraview",
+ "Parameters" : {
+ "model_part_name" : "Structure",
+ "output_control_type" : "step",
+ "output_interval" : 1,
+ "file_format" : "ascii",
+ "output_precision" : 7,
+ "output_sub_model_parts" : false,
+ "folder_name" : "vtk_output",
+ "save_output_files_in_folder" : true,
+ "nodal_solution_step_data_variables" : ["DISPLACEMENT","REACTION"],
+ "nodal_data_value_variables" : [],
+ "element_data_value_variables" : [],
+ "condition_data_value_variables" : [],
+ "gauss_point_variables_extrapolated_to_nodes" : ["VON_MISES_STRESS"]
+ }
+ }
+ this.addOutput("Process", "process");
+ this.model_part_name = this.addWidget("combo","ModelPartName", "Structure", function(v){}, {values:["Structure","Structure.VISUALIZE_HROM"]} );
+ this.size = this.computeSize();
+}
+
+VTKStructural.title = "VTK structural";
+VTKStructural.desc = "Creates VTK";
+
+VTKStructural.prototype.onExecute = function () {
+ output = this.properties
+
+ output["Parameters"]["model_part_name"] = this.model_part_name.value;
+
+ this.setOutputData(0, output);
+};
+
+LiteGraph.registerNodeType("output_processes/VTK_structural", VTKStructural);
+
+console.log("VTK node created"); //helps to debug
\ No newline at end of file
diff --git a/js/nodes/parsed_model_part.js b/js/nodes/parsed_model_part.js
index ba28e1a..4d198cc 100644
--- a/js/nodes/parsed_model_part.js
+++ b/js/nodes/parsed_model_part.js
@@ -8,7 +8,7 @@ class ParsedModelPart {
this.mp_select = this.addWidget("button", "Load Mdpa", "", function (value, widget, node) {
node.input_manager.click();
});
-
+ this.file_name = "dummy_name"
this.properties = {
"submodelpart_list" : []
};
@@ -18,9 +18,10 @@ class ParsedModelPart {
}
onExecute() {
- for (let i = 0; i < this.outputs.length; ++i) {
+ for (let i = 0; i < this.outputs.length -1; ++i) {
this.setOutputData(i, this.mp_name.value+this.outputs[i].name);
}
+ this.setOutputData(this.outputs.length-1, this.file_name);
}
onSelection(e) {
@@ -50,6 +51,7 @@ class ParsedModelPart {
// Obtain the name of the ModelPart to get complete routes
let sub_mdpa_namepath = ""
this.mp_name.value = file.name.slice(0, -5);
+ this.file_name = this.mp_name.value;
// Obtain the Submodelparts
this.addOutput(sub_mdpa_namepath, "string");
@@ -61,8 +63,8 @@ class ParsedModelPart {
if (match[0].includes("End")) {
sub_mdpa_namepath = sub_mdpa_namepath.split(".");
- sub_mdpa_namepath.pop();
- sub_mdpa_namepath = sub_mdpa_namepath.join(".");
+ sub_mdpa_namepath.pop(); // I think this is doing nothing
+ sub_mdpa_namepath = sub_mdpa_namepath.join("."); // I think this is doing nothing
}
}
@@ -77,6 +79,7 @@ class ParsedModelPart {
this.updateProblemModelParts();
this.updateModelNodes();
+ this.addOutput("File Name", "string")
}
}
diff --git a/js/nodes/processes/boolean_list.js b/js/nodes/processes/boolean_list.js
new file mode 100644
index 0000000..19e4e10
--- /dev/null
+++ b/js/nodes/processes/boolean_list.js
@@ -0,0 +1,18 @@
+
+function BooleanList (){
+ this.addOutput("", "process_array");
+ this.xposi = this.addWidget("toggle","x",true,);
+ this.yposi = this.addWidget("toggle","y",true,);
+ this.zposi = this.addWidget("toggle","z",true,);
+}
+BooleanList.title = "Boolean list";
+BooleanList.desc = "Merges several boolean into an array";
+
+BooleanList.prototype.onExecute = function() {
+ this.setOutputData(0, [this.xposi.value, this.yposi.value, this.zposi.value]);
+};
+
+
+LiteGraph.registerNodeType("processes/BooleanList", BooleanList);
+
+console.log("BooleanList node created"); //helps to debug
diff --git a/js/nodes/processes/constraints_process_list.js b/js/nodes/processes/constraints_process_list.js
new file mode 100644
index 0000000..9d803d1
--- /dev/null
+++ b/js/nodes/processes/constraints_process_list.js
@@ -0,0 +1,72 @@
+function AssignVectorVariableProcess () {
+ this.addInput("model_part_name","string");
+ this.addInput("interval","process_array");
+ this.addInput("constrained","process_array");
+ this.addInput("value","process_array")
+
+ this.properties = {
+
+ "python_module" : "assign_vector_variable_process",
+ "kratos_module" : "KratosMultiphysics",
+ "process_name" : "AssignVectorVariableProcess",
+ "Parameters" : {
+ "model_part_name" : "",
+ "variable_name" : "",
+ "interval" : [],
+ "constrained" : [],
+ "value" : []
+ }
+ };
+ var that = this;
+ this.variable_name = this.addWidget("text","VariableName", "DISPLACEMENT", function(v){}, {} );
+
+
+ this.addOutput("Process","process");
+
+ this.size = this.computeSize();
+ this.serialize_widgets = true;
+
+}
+
+
+AssignVectorVariableProcess.title = "Constraints process list";
+AssignVectorVariableProcess.desc = "Node to specify a boundary process.";
+
+AssignVectorVariableProcess.prototype.onExecute = function() {
+myoutput = this.properties
+ // model_part_name
+ if (this.getInputData(0) != undefined) {
+ myoutput["Parameters"]["model_part_name"] = this.getInputData(0)
+ } else {
+ myoutput["Parameters"]["model_part_name"] = this.properties["Parameters"]["model_part_name"]
+ }
+ // interval
+ if (this.getInputData(1) != undefined) {
+ myoutput["Parameters"]["interval"] = this.getInputData(1)
+ } else {
+ myoutput["Parameters"]["interval"] = this.properties["Parameters"]["interval"]
+ }
+
+ // constrained
+ if (this.getInputData(2) != undefined) {
+ myoutput["Parameters"]["constrained"] = this.getInputData(2)
+ } else {
+ myoutput["Parameters"]["constrained"] = this.properties["Parameters"]["constrained"]
+ }
+
+ // value
+ if (this.getInputData(3) != undefined) {
+ myoutput["Parameters"]["value"] = this.getInputData(3)
+ } else {
+ myoutput["Parameters"]["value"] = this.properties["Parameters"]["value"]
+ }
+
+
+myoutput["Parameters"]["variable_name"] = this.variable_name.value
+
+this.setOutputData(0, myoutput);
+};
+
+LiteGraph.registerNodeType("processes/AssignVectorVariableProcess", AssignVectorVariableProcess );
+
+console.log("ConstraintsProcessList node created"); //helps to debug
\ No newline at end of file
diff --git a/js/nodes/processes/load_process_list.js b/js/nodes/processes/load_process_list.js
new file mode 100644
index 0000000..2b688d3
--- /dev/null
+++ b/js/nodes/processes/load_process_list.js
@@ -0,0 +1,63 @@
+
+function AssignVectorByDirectionToConditionProcess() {
+ this.addInput("model_part_name","string");
+ this.addInput("interval","process_array");
+ this.addInput("direction","process_array");
+
+ this.properties = {
+ "python_module" : "assign_vector_by_direction_to_condition_process",
+ "kratos_module" : "KratosMultiphysics",
+ "check" : "DirectorVectorNonZero direction",
+ "process_name" : "AssignVectorByDirectionToConditionProcess",
+ "Parameters" : {
+ "model_part_name" : "",
+ "variable_name" : "",
+ "interval" : [],
+ "modulus" : 100000.0,
+ "direction" : []
+ }
+
+ };
+
+ var that = this;
+ this.variable_name = this.addWidget("text","VariableName", "LINE_LOAD", function(v){}, {} );
+ this.modulus = this.addWidget("number","Modulus", 100000, function(v){}, {});
+
+
+ this.addOutput("Process","process");
+
+ this.size = this.computeSize();
+ this.serialize_widgets = true;
+
+ }
+
+ AssignVectorByDirectionToConditionProcess.title = "Load process list";
+ AssignVectorByDirectionToConditionProcess.desc = "Node to specify a load process";
+
+ AssignVectorByDirectionToConditionProcess.prototype.onExecute = function() {
+ myoutput = this.properties
+ // model_part_name
+ if (this.getInputData(0) != undefined) {
+ myoutput["Parameters"]["model_part_name"] = this.getInputData(0)
+ } else {
+ myoutput["Parameters"]["model_part_name"] = this.properties["Parameters"]["model_part_name"]
+ }
+ // interval
+ if (this.getInputData(1) != undefined) {
+ myoutput["Parameters"]["interval"] = this.getInputData(1)
+ } else {
+ myoutput["Parameters"]["interval"] = this.properties["Parameters"]["interval"]
+ }
+ // direction
+ if (this.getInputData(2) != undefined) {
+ myoutput["Parameters"]["direction"] = this.getInputData(2)
+ } else {
+ myoutput["Parameters"]["direction"] = this.properties["Parameters"]["direction"]
+ }
+ myoutput["Parameters"]["variable_name"] = this.variable_name.value
+ myoutput["Parameters"]["modulus"] = this.modulus.value
+
+ this.setOutputData(0, myoutput);
+ };
+
+ LiteGraph.registerNodeType("processes/AssignVectorByDirectionToConditionProcess", AssignVectorByDirectionToConditionProcess);
\ No newline at end of file
diff --git a/js/nodes/processes/load_process_list_pressure.js b/js/nodes/processes/load_process_list_pressure.js
new file mode 100644
index 0000000..5f56585
--- /dev/null
+++ b/js/nodes/processes/load_process_list_pressure.js
@@ -0,0 +1,55 @@
+
+function AssignScalarVariableToConditionsProcess() {
+ this.addInput("model_part_name","string");
+ this.addInput("interval","process_array");
+
+ this.properties = {
+ "python_module" : "",
+ "kratos_module" : "",
+ "process_name" : "",
+ "Parameters" : {
+ "model_part_name" : "",
+ "variable_name" : "",
+ "value" : "",
+ "interval" : []
+ }
+
+ };
+
+ var that = this;
+ this.variable_name = this.addWidget("text","VariableName", "", function(v){}, {} );
+ this.value = this.addWidget("text","Value", "", function(v){}, {});
+
+
+ this.addOutput("Process","process");
+
+ this.size = this.computeSize();
+ this.serialize_widgets = true;
+
+ }
+
+ AssignScalarVariableToConditionsProcess.title = "Load process list pressure";
+ AssignScalarVariableToConditionsProcess.desc = "Node to specify a load process";
+
+ AssignScalarVariableToConditionsProcess.prototype.onExecute = function() {
+ myoutput = this.properties
+ // model_part_name
+ if (this.getInputData(0) != undefined) {
+ myoutput["Parameters"]["model_part_name"] = this.getInputData(0)
+ } else {
+ myoutput["Parameters"]["model_part_name"] = this.properties["Parameters"]["model_part_name"]
+ }
+ // interval
+ if (this.getInputData(1) != undefined) {
+ myoutput["Parameters"]["interval"] = this.getInputData(1)
+ } else {
+ myoutput["Parameters"]["interval"] = this.properties["Parameters"]["interval"]
+ }
+
+ myoutput["Parameters"]["variable_name"] = this.variable_name.value
+ myoutput["Parameters"]["value"] = this.value.value
+
+ this.setOutputData(0, myoutput);
+ };
+
+ LiteGraph.registerNodeType("processes/AssignScalarVariableToConditionsProcess", AssignScalarVariableToConditionsProcess);
\ No newline at end of file
diff --git a/js/nodes/processes/vector.js b/js/nodes/processes/vector.js
new file mode 100644
index 0000000..38521fe
--- /dev/null
+++ b/js/nodes/processes/vector.js
@@ -0,0 +1,23 @@
+
+function Vector () {
+ this.addOutput("", "process_array");
+ this.widget_1 = this.addWidget("number","X", 0, function(v){}, {});
+ this.widget_2 = this.addWidget("number","Y", 0, function(v){}, {});
+ this.widget_3 = this.addWidget("number","Z", 0, function(v){}, {});
+
+};
+
+Vector.title = "Vector";
+Vector.desc = "Merges several number into an array";
+
+LiteGraph.registerNodeType("processes/Vector", Vector);
+
+console.log("Vector node created"); //helps to debug
+
+
+Vector.prototype.onExecute = function() {
+ this.setOutputData(0, [this.widget_1.value, this.widget_2.value, this.widget_3.value])
+};
+
+
+
\ No newline at end of file
diff --git a/js/nodes/solver_settings/structural_mechanics_solver.js b/js/nodes/solver_settings/structural_mechanics_solver.js
new file mode 100644
index 0000000..c93b8b4
--- /dev/null
+++ b/js/nodes/solver_settings/structural_mechanics_solver.js
@@ -0,0 +1,54 @@
+class StructuralMechanicsSolver {
+ constructor() {
+ this.addInput("model_import_settings", "map"); // 0
+ this.addInput("material_import_settings", "map"); // 1
+ this.addOutput("solver_settings", "map");
+ this.properties = {
+ "solver_type" : "static",
+ "model_part_name" : "Structure",
+ "domain_size" : 2,
+ "echo_level" : 0,
+ "analysis_type" : "non_linear",
+ "model_import_settings" : {
+ "input_type" : "mdpa",
+ "input_filename" : "Ring"
+ },
+ "material_import_settings" : {
+ "materials_filename" : "StructuralMaterials.json"
+ },
+ "time_stepping" : {
+ "time_step" : 1
+ },
+ "line_search" : false,
+ "convergence_criterion" : "residual_criterion",
+ "displacement_relative_tolerance" : 0.0001,
+ "displacement_absolute_tolerance" : 1e-9,
+ "residual_relative_tolerance" : 0.0001,
+ "residual_absolute_tolerance" : 1e-9,
+ "max_iteration" : 10,
+ "rotation_dofs" : false,
+ "volumetric_strain_dofs" : false
+ },
+ this.domain_size = this.addWidget("combo","Domain Size", 2, function(v){}, { values:[2,3]} );
+
+ this.size = this.computeSize();
+ }
+
+ onExecute() {
+ this._value = Object.assign({}, this.properties);
+ this._value["domain_size"] = this.domain_size.value;
+ this._value["model_import_settings"] = this.getInputData(0);
+ this._value["material_import_settings"] = this.getInputData(1);
+
+ // Get the
+
+ this.setOutputData(0, this._value);
+ }
+}
+
+StructuralMechanicsSolver.title = "Structural mechanics solver";
+StructuralMechanicsSolver.desc = "Properties for the structural mechanics solver";
+
+LiteGraph.registerNodeType("solver_settings/StructuralMechanicsSolver", StructuralMechanicsSolver);
+
+console.log("StructuralMechanicsSolver node created"); //helps to debug
\ No newline at end of file
diff --git a/js/nodes/solver_settings_aux_nodes/model_import_settings.js b/js/nodes/solver_settings_aux_nodes/model_import_settings.js
index 5146733..bd5b81f 100644
--- a/js/nodes/solver_settings_aux_nodes/model_import_settings.js
+++ b/js/nodes/solver_settings_aux_nodes/model_import_settings.js
@@ -1,6 +1,7 @@
class ModelImportSettings {
constructor()
{
+ //this.input_filename = this.addWidget("text", "Input filename", "", function(v){}, {});
this.addInput("Input filename", "string");
this.input_type = this.addWidget("combo", "Input type", "mdpa", function (v) { }, { values: ["mdpa", "rest"] });
diff --git a/js/nodes/structural_project_parameters.js b/js/nodes/structural_project_parameters.js
new file mode 100644
index 0000000..335c1b0
--- /dev/null
+++ b/js/nodes/structural_project_parameters.js
@@ -0,0 +1,36 @@
+function StructuralProjectParameters() {
+ this.addInput("problem_data", "map");
+ this.addInput("solver_settings", "map");
+ this.addInput("constraints_process_list", "process_array");
+ this.addInput("loads_process_list", "process_array");
+ this.addInput("list_other_processes", "process_array");
+ this.addInput("gid_output", "process_array");
+ this.addInput("vtk_output", "process_array");
+
+
+ this.addOutput("project_parameters","map");
+ this.size = this.computeSize();
+}
+
+StructuralProjectParameters.title = "Structural Project Parameters";
+StructuralProjectParameters.desc = "Create a Project Paramaters";
+
+StructuralProjectParameters.prototype.onExecute = function() {
+ tmp = {};
+ tmp["processes"] = {};
+ tmp["output_processes"] = {};
+
+ tmp["problem_data"] = this.getInputData(0); //0
+ tmp["solver_settings"] = this.getInputData(1); //1
+ tmp["processes"]["constraints_process_list"] = this.getInputData(2); //2
+ tmp["processes"]["loads_process_list"] = this.getInputData(3); //3
+ tmp["processes"]["list_other_processes"] = this.getInputData(4); //4
+ tmp["output_processes"] ["gid_output"]= this.getInputData(5); //5
+ tmp["output_processes"] ["vtk_output"]= this.getInputData(6); //5
+
+ this.setOutputData(0, tmp);
+};
+
+LiteGraph.registerNodeType("parameters/StructuralProjectParameters", StructuralProjectParameters);
+
+console.log("ProjectParameters node created"); //helps to debug
diff --git a/resources/examples/StructuralMechanics.json b/resources/examples/StructuralMechanics.json
new file mode 100644
index 0000000..5afcab8
--- /dev/null
+++ b/resources/examples/StructuralMechanics.json
@@ -0,0 +1 @@
+{"last_node_id":223,"last_link_id":374,"nodes":[{"id":45,"type":"model_part/OutputView","pos":[1435,333],"size":{"0":479.251953125,"1":3110},"flags":{"collapsed":false},"order":9,"mode":0,"inputs":[{"name":"json","type":0,"link":313}],"properties":{}},{"id":206,"type":"parameters/StructuralProjectParameters","pos":[949,459],"size":{"0":362.79998779296875,"1":146},"flags":{},"order":7,"mode":0,"inputs":[{"name":"problem_data","type":"map","link":310},{"name":"solver_settings","type":"map","link":364},{"name":"constraints_process_list","type":"process_array","link":362},{"name":"loads_process_list","type":"process_array","link":360},{"name":"list_other_processes","type":"process_array","link":358},{"name":"gid_output","type":"process_array","link":356},{"name":"vtk_output","type":"process_array","link":357}],"outputs":[{"name":"project_parameters","type":"map","links":[312,313]}],"properties":{}},{"id":214,"type":"graph/subgraph","pos":[401,658],"size":[200,90],"flags":{"collapsed":false},"order":1,"mode":0,"inputs":[],"outputs":[{"name":"GiD Output","type":"process_array","links":[356]},{"name":"VTK Output","type":"process_array","links":[357]}],"title":"Output Processes","properties":{"enabled":true},"subgraph":{"last_node_id":7,"last_link_id":6,"nodes":[{"id":1,"type":"output_processes/GiDStructural","pos":[545,266],"size":{"0":210,"1":82},"flags":{},"order":0,"mode":0,"outputs":[{"name":"Process","type":"process","links":[1]}],"properties":{"python_module":"gid_output_process","kratos_module":"KratosMultiphysics","process_name":"GiDOutputProcess","help":"This process writes postprocessing files for GiD","Parameters":{"model_part_name":"Structure","output_name":"SWQ","postprocess_parameters":{"result_file_configuration":{"gidpost_flags":{"GiDPostMode":"GiD_PostBinary","WriteDeformedMeshFlag":"WriteDeformed","WriteConditionsFlag":"WriteConditions","MultiFileFlag":"SingleFile"},"file_label":"step","output_control_type":"step","output_interval":1,"body_output":true,"node_output":false,"skin_output":false,"plane_output":[],"nodal_results":["DISPLACEMENT","REACTION"],"gauss_point_results":["VON_MISES_STRESS"],"nodal_nonhistorical_results":[]},"point_data_configuration":[]}}}},{"id":2,"type":"output_processes/VTK_structural","pos":[566,492],"size":{"0":210,"1":58},"flags":{},"order":1,"mode":0,"outputs":[{"name":"Process","type":"process","links":[2]}],"properties":{"python_module":"vtk_output_process","kratos_module":"KratosMultiphysics","process_name":"VtkOutputProcess","help":"This process writes postprocessing files for Paraview","Parameters":{"model_part_name":"Structure","output_control_type":"step","output_interval":1,"file_format":"ascii","output_precision":7,"output_sub_model_parts":false,"folder_name":"vtk_output","save_output_files_in_folder":true,"nodal_solution_step_data_variables":["DISPLACEMENT","REACTION"],"nodal_data_value_variables":[],"element_data_value_variables":[],"condition_data_value_variables":[],"gauss_point_variables_extrapolated_to_nodes":["VON_MISES_STRESS"]}}},{"id":3,"type":"processes/list","pos":[1289,266],"size":{"0":140,"1":46},"flags":{},"order":2,"mode":0,"inputs":[{"name":"In0","type":"process","link":1},{"name":"In1","type":"process","link":null}],"outputs":[{"name":"array","type":"process_array","links":[5]},{"name":"size","type":"number","links":null}],"properties":{}},{"id":4,"type":"processes/list","pos":[1266,484],"size":{"0":140,"1":46},"flags":{},"order":3,"mode":0,"inputs":[{"name":"In0","type":"process","link":2},{"name":"In1","type":"process","link":null}],"outputs":[{"name":"array","type":"process_array","links":[6]},{"name":"size","type":"number","links":null}],"properties":{}},{"id":7,"type":"graph/output","pos":[1584,483],"size":[180,60],"flags":{},"order":5,"mode":0,"inputs":[{"name":"","type":"process_array","link":6}],"properties":{"name":"VTK Output","type":"process_array"}},{"id":6,"type":"graph/output","pos":[1592,266],"size":[180,60],"flags":{},"order":4,"mode":0,"inputs":[{"name":"","type":"process_array","link":5}],"properties":{"name":"GiD Output","type":"process_array"}}],"links":[[1,1,0,3,0,"process"],[2,2,0,4,0,"process"],[5,3,0,6,0,"process_array"],[6,4,0,7,0,0]],"groups":[],"config":{},"extra":{},"version":0.4}},{"id":220,"type":"graph/subgraph","pos":[389,323],"size":[200,70],"flags":{},"order":4,"mode":0,"inputs":[{"name":"model_part","type":"string","link":372}],"outputs":[{"name":"constraints","type":"process_array","links":[362]}],"title":"Constraints","properties":{"enabled":true},"subgraph":{"last_node_id":8,"last_link_id":11,"nodes":[{"id":7,"type":"graph/input","pos":[293,186],"size":[180,90],"flags":{},"order":0,"mode":0,"outputs":[{"name":"","type":"string","links":[7]}],"properties":{"name":"model_part","type":"string","value":""}},{"id":1,"type":"processes/interval","pos":[279,342],"size":{"0":210,"1":82},"flags":{},"order":1,"mode":0,"outputs":[{"name":"","type":"process_array","links":[8]}],"properties":{}},{"id":2,"type":"processes/BooleanList","pos":[278,501],"size":{"0":210,"1":106},"flags":{},"order":2,"mode":0,"outputs":[{"name":"","type":"process_array","links":[9]}],"properties":{}},{"id":3,"type":"processes/Vector","pos":[281,688],"size":{"0":210,"1":106},"flags":{},"order":3,"mode":0,"outputs":[{"name":"","type":"process_array","links":[10]}],"properties":{}},{"id":8,"type":"processes/AssignVectorVariableProcess","pos":[690,277],"size":{"0":210,"1":118},"flags":{},"order":4,"mode":0,"inputs":[{"name":"model_part_name","type":"string","link":7},{"name":"interval","type":"process_array","link":8},{"name":"constrained","type":"process_array","link":9},{"name":"value","type":"process_array","link":10}],"outputs":[{"name":"Process","type":"process","links":[11]}],"properties":{"python_module":"assign_vector_variable_process","kratos_module":"KratosMultiphysics","process_name":"AssignVectorVariableProcess","Parameters":{"model_part_name":"Structure.DISPLACEMENT_Ground","variable_name":"DISPLACEMENT","interval":[0,"End"],"constrained":[true,true,true],"value":[0,0,0]}},"widgets_values":["DISPLACEMENT"]},{"id":6,"type":"processes/list","pos":[1057,281],"size":{"0":140,"1":46},"flags":{},"order":5,"mode":0,"inputs":[{"name":"In0","type":"process","link":11},{"name":"In1","type":"process","link":null}],"outputs":[{"name":"array","type":"process_array","links":[5]},{"name":"size","type":"number","links":null}],"properties":{}},{"id":5,"type":"graph/output","pos":[1373,280],"size":[180,60],"flags":{},"order":6,"mode":0,"inputs":[{"name":"","type":"process_array","link":5}],"properties":{"name":"constraints","type":"process_array"}}],"links":[[5,6,0,5,0,"process_array"],[7,7,0,8,0,"string"],[8,1,0,8,1,"process_array"],[9,2,0,8,2,"process_array"],[10,3,0,8,3,"process_array"],[11,8,0,6,0,"process"]],"groups":[],"config":{},"extra":{},"version":0.4}},{"id":221,"type":"graph/subgraph","pos":[573,108],"size":[200,90],"flags":{},"order":6,"mode":0,"inputs":[{"name":"Main model part","type":"string","link":371},{"name":"File Name","type":"string","link":374}],"outputs":[{"name":"solver","type":"map","links":[364]}],"title":"Materials and Model","properties":{"enabled":true},"subgraph":{"last_node_id":10,"last_link_id":10,"nodes":[{"id":7,"type":"graph/input","pos":[19,652],"size":[180,90],"flags":{},"order":0,"mode":0,"outputs":[{"name":"","type":"string","links":[6]}],"properties":{"name":"Main model part","type":"string","value":""}},{"id":1,"type":"materials/StructuralMaterial","pos":[253,652],"size":{"0":210,"1":198},"flags":{},"order":2,"mode":0,"inputs":[{"name":"model_part_name","type":"string","link":6},{"name":"tables","type":"process_array","link":null}],"outputs":[{"name":"Material","type":"material","links":[1]}],"properties":{"model_part_name":"Structure.Parts_Solid_Solid_Auto1","properties_id":1,"Material":{"constitutive_law":{"name":"LinearElasticPlaneStress2DLaw"},"Variables":{"DENSITY":7850,"YOUNG_MODULUS":206900000000,"POISSON_RATIO":0.29,"THICKNESS":0.1},"Tables":{}}}},{"id":3,"type":"materials/materials_list","pos":[505,652],"size":{"0":140,"1":46},"flags":{},"order":4,"mode":0,"inputs":[{"name":"In0","type":"material","link":1},{"name":"In1","type":"material","link":null}],"outputs":[{"name":"array","type":"material_array","links":[2]},{"name":"size","type":"number","links":null}],"properties":{}},{"id":2,"type":"materials/Material Writer","pos":[689,652],"size":{"0":210,"1":58},"flags":{},"order":5,"mode":0,"inputs":[{"name":"Material List","type":"material_array","link":2}],"outputs":[{"name":"Material","type":"string","links":[3]}],"properties":{}},{"id":6,"type":"solver_settings_aux_nodes/MaterialImportSettings","pos":[944,650],"size":{"0":287.20001220703125,"1":26},"flags":{},"order":6,"mode":0,"inputs":[{"name":"Materials filename","type":"string","link":3}],"outputs":[{"name":"solver_settings","type":"map","links":[9]}],"properties":{"materials_filename":""}},{"id":9,"type":"graph/input","pos":[22,92],"size":[180,90],"flags":{},"order":1,"mode":0,"outputs":[{"name":"","type":"string","links":[7]}],"properties":{"name":"File Name","type":"string","value":""}},{"id":4,"type":"solver_settings_aux_nodes/ModelImportSettings","pos":[250,95],"size":{"0":253.60000610351562,"1":58},"flags":{},"order":3,"mode":0,"inputs":[{"name":"Input filename","type":"string","link":7}],"outputs":[{"name":"solver_settings","type":"map","links":[10]}],"properties":{"input_filename":""}},{"id":5,"type":"solver_settings/StructuralMechanicsSolver","pos":[1225,97],"size":{"0":337.6000061035156,"1":78},"flags":{},"order":7,"mode":0,"inputs":[{"name":"model_import_settings","type":"map","link":10},{"name":"material_import_settings","type":"map","link":9}],"outputs":[{"name":"solver_settings","type":"map","links":[8]}],"properties":{"solver_type":"static","model_part_name":"Structure","domain_size":2,"echo_level":0,"analysis_type":"non_linear","model_import_settings":{"input_type":"mdpa","input_filename":"Ring"},"material_import_settings":{"materials_filename":"StructuralMaterials.json"},"time_stepping":{"time_step":1},"line_search":false,"convergence_criterion":"residual_criterion","displacement_relative_tolerance":0.0001,"displacement_absolute_tolerance":1e-9,"residual_relative_tolerance":0.0001,"residual_absolute_tolerance":1e-9,"max_iteration":10,"rotation_dofs":false,"volumetric_strain_dofs":false}},{"id":10,"type":"graph/output","pos":[1656,97],"size":[180,60],"flags":{},"order":8,"mode":0,"inputs":[{"name":"","type":"map","link":8}],"properties":{"name":"solver","type":"map"}}],"links":[[1,1,0,3,0,"material"],[2,3,0,2,0,"material_array"],[3,2,0,6,0,"string"],[6,7,0,1,0,"string"],[7,9,0,4,0,"string"],[8,5,0,10,0,"map"],[9,6,0,5,1,"map"],[10,4,0,5,0,"map"]],"groups":[],"config":{},"extra":{},"version":0.4}},{"id":219,"type":"graph/subgraph","pos":[398,476],"size":[200,70],"flags":{},"order":5,"mode":0,"inputs":[{"name":"model_part","type":"string","link":373}],"outputs":[{"name":"Loads","type":"process_array","links":[360]}],"title":"Loads","properties":{"enabled":true},"subgraph":{"last_node_id":11,"last_link_id":10,"nodes":[{"id":5,"type":"processes/list","pos":[1188,304],"size":{"0":140,"1":46},"flags":{},"order":4,"mode":0,"inputs":[{"name":"In0","type":"process","link":10},{"name":"In1","type":"process","link":null}],"outputs":[{"name":"array","type":"process_array","links":[5]},{"name":"size","type":"number","links":null}],"properties":{}},{"id":7,"type":"graph/output","pos":[1525,301],"size":[180,60],"flags":{},"order":5,"mode":0,"inputs":[{"name":"","type":"process_array","link":5}],"properties":{"name":"Loads","type":"process_array"}},{"id":10,"type":"graph/input","pos":[403,132],"size":[180,90],"flags":{},"order":0,"mode":0,"outputs":[{"name":"","type":"string","links":[7]}],"properties":{"name":"model_part","type":"string","value":""}},{"id":3,"type":"processes/interval","pos":[388,314],"size":{"0":210,"1":82},"flags":{},"order":1,"mode":0,"outputs":[{"name":"","type":"process_array","links":[8]}],"properties":{}},{"id":11,"type":"processes/AssignVectorByDirectionToConditionProcess","pos":[837,303],"size":{"0":210,"1":122},"flags":{},"order":3,"mode":0,"inputs":[{"name":"model_part_name","type":"string","link":7},{"name":"interval","type":"process_array","link":8},{"name":"direction","type":"process_array","link":9}],"outputs":[{"name":"Process","type":"process","links":[10]}],"properties":{"python_module":"assign_vector_by_direction_to_condition_process","kratos_module":"KratosMultiphysics","check":"DirectorVectorNonZero direction","process_name":"AssignVectorByDirectionToConditionProcess","Parameters":{"model_part_name":"Structure.LineLoad2D_InterfaceStructure","variable_name":"LINE_LOAD","interval":[0,"End"],"modulus":100000,"direction":[0.9999999999999999,0,0]}},"widgets_values":["LINE_LOAD",100000]},{"id":1,"type":"processes/Vector","pos":[385,477],"size":{"0":210,"1":106},"flags":{},"order":2,"mode":0,"outputs":[{"name":"","type":"process_array","links":[9]}],"properties":{}}],"links":[[5,5,0,7,0,"process_array"],[7,10,0,11,0,"string"],[8,3,0,11,1,"process_array"],[9,1,0,11,2,"process_array"],[10,11,0,5,0,"process"]],"groups":[],"config":{},"extra":{},"version":0.4}},{"id":204,"type":"processes/list","pos":[632,558],"size":{"0":140,"1":46},"flags":{},"order":0,"mode":0,"inputs":[{"name":"In0","type":"process","link":null}],"outputs":[{"name":"array","type":"process_array","links":[358]},{"name":"size","type":"number","links":null}],"properties":{}},{"id":4,"type":"parameters/ProblemData","pos":[657,259],"size":{"0":140,"1":86},"flags":{"collapsed":false},"order":2,"mode":0,"outputs":[{"name":"problem_data","type":"map","links":[310]},{"name":"problem_name","type":"string","links":null},{"name":"start_time","type":"number","links":null},{"name":"end_time","type":"number","links":null}],"properties":{"problem_name":"SWQ","parallel_type":"OpenMP","echo_level":1,"start_time":0,"end_time":10}},{"id":223,"type":"model_part/ParsedModelPart","pos":[21,201],"size":{"0":262,"1":142},"flags":{},"order":3,"mode":0,"outputs":[{"name":".Parts_Solid_Structure","type":"string","links":[371]},{"name":".DISPLACEMENT_Ground","type":"string","links":[372]},{"name":".LineLoad2D_InterfaceStructure","type":"string","links":[373]},{"name":"File Name","type":"string","links":[374]}],"properties":{"submodelpart_list":[".Parts_Solid_Structure",".DISPLACEMENT_Ground",".LineLoad2D_InterfaceStructure"]},"widgets_values":["Structure",""]},{"id":32,"type":"basic/DownloadProblem","pos":[1412,72],"size":{"0":210,"1":78},"flags":{"collapsed":false},"order":8,"mode":0,"inputs":[{"name":"data","type":0,"link":312},{"name":"download","type":-1,"link":null}],"properties":{"filename":"data.json"}}],"links":[[310,4,0,206,0,"map"],[312,206,0,32,0,0],[313,206,0,45,0,0],[356,214,0,206,5,"process_array"],[357,214,1,206,6,"process_array"],[358,204,0,206,4,"process_array"],[360,219,0,206,3,"process_array"],[362,220,0,206,2,"process_array"],[364,221,0,206,1,"map"],[371,223,0,221,0,"string"],[372,223,1,220,0,"string"],[373,223,2,219,0,"string"],[374,223,3,221,1,"string"]],"groups":[],"config":{},"extra":{},"version":0.4}
\ No newline at end of file
diff --git a/resources/examples/Test.json.json b/resources/examples/Test.json.json
deleted file mode 100644
index cd6e325..0000000
--- a/resources/examples/Test.json.json
+++ /dev/null
@@ -1 +0,0 @@
-{"last_node_id":1,"last_link_id":0,"nodes":[{"id":1,"type":"model_part/ParsedModelPart","pos":[152,141],"size":{"0":210,"1":98},"flags":{},"order":0,"mode":0,"outputs":[{"name":"Parts_All","type":"string","links":null},{"name":"DISPLACEMENT_support","type":"string","links":null},{"name":"DISPLACEMENT_movement","type":"string","links":null}],"properties":{},"widgets_values":[""]}],"links":[],"groups":[],"config":{},"extra":{},"version":0.4}
\ No newline at end of file