{"modules":{"0.39612602144740094":{"definition":"//\n// construct object\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2018\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'construct object'\n//\n// initialization\n//\nvar init = function() {\n mod.in0.value = '{\"module\":1,\"angle\":0.3490658503988659,\"teeth\":10,\"rp\":5,\"rb\":4.698463103929543,\"ha\":1,\"hd\":1.1,\"ai\":0.014904383867336446,\"ap\":0.6283185307179586}'\n mod.in1.value = '{}'\n mod.out0.value = '{rz:-180*in0.ai/Math.PI}'\n mod.out1.value = '{}'\n }\n//\n// inputs\n//\nvar inputs = {\n in0:{type:'',label:'input 0',\n event:function(evt) {\n mod.in0.value = JSON.stringify(evt.detail)\n construct_output()\n }},\n in1:{type:'',label:'input 1',\n event:function(evt) {\n mod.in1.value = JSON.stringify(evt.detail)\n construct_output()\n }}}\n//\n// outputs\n//\nvar outputs = {\n out0:{type:'',label:'output 0',\n event:function(arg){\n mods.output(mod,'out0',arg)\n }},\n out1:{type:'',label:'output 1',\n event:function(arg){\n mods.output(mod,'out1',arg)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // inputs\n //\n div.appendChild(document.createTextNode('input 0:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.in0 = text\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('input 1:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.in1 = text\n div.appendChild(document.createElement('br'))\n //\n // outputs\n //\n div.appendChild(document.createTextNode('output 0:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.out0 = text\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('output 1:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.out1 = text\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n construct_output()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\nfunction construct_output() {\n var in0 = JSON.parse(mod.in0.value)\n var in1 = JSON.parse(mod.in1.value)\n eval('out0 ='+mod.out0.value)\n eval('out1 ='+mod.out1.value)\n outputs.out0.event(out0)\n outputs.out1.event(out1)\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"244.48240841643232","left":"475.15591820277274","inputs":{},"outputs":{}},"0.8412077289031379":{"definition":"//\n// frep rotate\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep rotate'\n//\n// initialization\n//\nvar init = function() {\n mod.rx.value = ''\n mod.ry.value = ''\n mod.rz.value = '-0.8539582918412502'\n mod.ox.value = '0'\n mod.oy.value = '0'\n mod.oz.value = '0'\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }},\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n var ox = parseFloat(mod.ox.value)\n var oy = parseFloat(mod.oy.value)\n var oz = parseFloat(mod.oz.value)\n if (mod.rx.value != '') {\n var rx = parseFloat(mod.rx.value)*Math.PI/180\n var yvar = variables[1]\n var zvar = variables[2]\n var yre = new RegExp(yvar,'g')\n var zre = new RegExp(zvar,'g')\n fn = fn.replace(yre,\n `((${oy})+(${yvar}-(${oy}))*Math.cos(${rx})+(TEMP-(${oz}))*Math.sin(${rx}))`)\n fn = fn.replace(zre,\n `((${oz})-(${yvar}-(${oy}))*Math.sin(${rx})+(${zvar}-(${oz}))*Math.cos(${rx}))`)\n fn = fn.replace(/TEMP/g,zvar)\n var y0 = limits[1][0]\n var y1 = limits[1][1]\n var z0 = limits[2][0]\n var z1 = limits[2][1]\n limits[1][0] = Math.min(\n oy+(y0-oy)*Math.cos(rx)-(z0-oz)*Math.sin(rx),\n oy+(y0-oy)*Math.cos(rx)-(z1-oz)*Math.sin(rx),\n oy+(y1-oy)*Math.cos(rx)-(z0-oz)*Math.sin(rx),\n oy+(y1-oy)*Math.cos(rx)-(z1-oz)*Math.sin(rx))\n limits[1][1] = Math.max(\n oy+(y0-oy)*Math.cos(rx)-(z0-oz)*Math.sin(rx),\n oy+(y0-oy)*Math.cos(rx)-(z1-oz)*Math.sin(rx),\n oy+(y1-oy)*Math.cos(rx)-(z0-oz)*Math.sin(rx),\n oy+(y1-oy)*Math.cos(rx)-(z1-oz)*Math.sin(rx))\n limits[2][0] = Math.min(\n oz+(y0-oy)*Math.sin(rx)+(z0-oz)*Math.cos(rx),\n oz+(y0-oy)*Math.sin(rx)+(z1-oz)*Math.cos(rx),\n oz+(y1-oy)*Math.sin(rx)+(z0-oz)*Math.cos(rx),\n oz+(y1-oy)*Math.sin(rx)+(z1-oz)*Math.cos(rx))\n limits[2][1] = Math.max(\n oz+(y0-oy)*Math.sin(rx)+(z0-oz)*Math.cos(rx),\n oz+(y0-oy)*Math.sin(rx)+(z1-oz)*Math.cos(rx),\n oz+(y1-oy)*Math.sin(rx)+(z0-oz)*Math.cos(rx),\n oz+(y1-oy)*Math.sin(rx)+(z1-oz)*Math.cos(rx))\n }\n if (mod.ry.value != '') {\n var ry = parseFloat(mod.ry.value)*Math.PI/180\n var xvar = variables[0]\n var zvar = variables[2]\n var xre = new RegExp(xvar,'g')\n var zre = new RegExp(zvar,'g')\n fn = fn.replace(xre,\n `((${ox})+(${xvar}-(${ox}))*Math.cos(${ry})+(TEMP-(${oz}))*Math.sin(${ry}))`)\n fn = fn.replace(zre,\n `((${oz})-(${xvar}-(${ox}))*Math.sin(${ry})+(${zvar}-(${oz}))*Math.cos(${ry}))`)\n fn = fn.replace(/TEMP/g,zvar)\n var x0 = limits[0][0]\n var x1 = limits[0][1]\n var z0 = limits[2][0]\n var z1 = limits[2][1]\n limits[0][0] = Math.min(\n ox+(x0-ox)*Math.cos(ry)-(z0-oz)*Math.sin(ry),\n ox+(x0-ox)*Math.cos(ry)-(z1-oz)*Math.sin(ry),\n ox+(x1-ox)*Math.cos(ry)-(z0-oz)*Math.sin(ry),\n ox+(x1-ox)*Math.cos(ry)-(z1-oz)*Math.sin(ry))\n limits[0][1] = Math.max(\n ox+(x0-ox)*Math.cos(ry)-(z0-oz)*Math.sin(ry),\n ox+(x0-ox)*Math.cos(ry)-(z1-oz)*Math.sin(ry),\n ox+(x1-ox)*Math.cos(ry)-(z0-oz)*Math.sin(ry),\n ox+(x1-ox)*Math.cos(ry)-(z1-oz)*Math.sin(ry))\n limits[2][0] = Math.min(\n oz+(x0-ox)*Math.sin(ry)+(z0-oz)*Math.cos(ry),\n oz+(x0-ox)*Math.sin(ry)+(z1-oz)*Math.cos(ry),\n oz+(x1-ox)*Math.sin(ry)+(z0-oz)*Math.cos(ry),\n oz+(x1-ox)*Math.sin(ry)+(z1-oz)*Math.cos(ry))\n limits[2][1] = Math.max(\n oz+(x0-ox)*Math.sin(ry)+(z0-oz)*Math.cos(ry),\n oz+(x0-ox)*Math.sin(ry)+(z1-oz)*Math.cos(ry),\n oz+(x1-ox)*Math.sin(ry)+(z0-oz)*Math.cos(ry),\n oz+(x1-ox)*Math.sin(ry)+(z1-oz)*Math.cos(ry))\n }\n if (mod.rz.value != '') {\n var rz = parseFloat(mod.rz.value)*Math.PI/180\n var xvar = variables[0]\n var yvar = variables[1]\n var xre = new RegExp(xvar,'g')\n var yre = new RegExp(yvar,'g')\n fn = fn.replace(xre,\n `((${ox})+(${xvar}-(${ox}))*Math.cos(${rz})+(TEMP-(${oy}))*Math.sin(${rz}))`)\n fn = fn.replace(yre,\n `((${oy})-(${xvar}-(${ox}))*Math.sin(${rz})+(${yvar}-(${oy}))*Math.cos(${rz}))`)\n fn = fn.replace(/TEMP/g,yvar)\n var x0 = limits[0][0]\n var x1 = limits[0][1]\n var y0 = limits[1][0]\n var y1 = limits[1][1]\n limits[0][0] = Math.min(\n ox+(x0-ox)*Math.cos(rz)-(y0-oy)*Math.sin(rz),\n ox+(x0-ox)*Math.cos(rz)-(y1-oy)*Math.sin(rz),\n ox+(x1-ox)*Math.cos(rz)-(y0-oy)*Math.sin(rz),\n ox+(x1-ox)*Math.cos(rz)-(y1-oy)*Math.sin(rz))\n limits[0][1] = Math.max(\n ox+(x0-ox)*Math.cos(rz)-(y0-oy)*Math.sin(rz),\n ox+(x0-ox)*Math.cos(rz)-(y1-oy)*Math.sin(rz),\n ox+(x1-ox)*Math.cos(rz)-(y0-oy)*Math.sin(rz),\n ox+(x1-ox)*Math.cos(rz)-(y1-oy)*Math.sin(rz))\n limits[1][0] = Math.min(\n oy+(x0-ox)*Math.sin(rz)+(y0-oy)*Math.cos(rz),\n oy+(x0-ox)*Math.sin(rz)+(y1-oy)*Math.cos(rz),\n oy+(x1-ox)*Math.sin(rz)+(y0-oy)*Math.cos(rz),\n oy+(x1-ox)*Math.sin(rz)+(y1-oy)*Math.cos(rz))\n limits[1][1] = Math.max(\n oy+(x0-ox)*Math.sin(rz)+(y0-oy)*Math.cos(rz),\n oy+(x0-ox)*Math.sin(rz)+(y1-oy)*Math.cos(rz),\n oy+(x1-ox)*Math.sin(rz)+(y0-oy)*Math.cos(rz),\n oy+(x1-ox)*Math.sin(rz)+(y1-oy)*Math.cos(rz))\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n div.appendChild(document.createTextNode('angle\\xa0\\xa0\\xa0 origin'))\n div.appendChild(document.createElement('br'))\n //\n // x\n //\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.rx = input\n div.appendChild(document.createTextNode(' x '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.ox = input\n div.appendChild(document.createElement('br'))\n //\n // y\n //\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.ry = input\n div.appendChild(document.createTextNode(' y '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.oy = input\n div.appendChild(document.createElement('br'))\n //\n // z\n //\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.rz = input\n div.appendChild(document.createTextNode(' z '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.oz = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"84.07557978880027","left":"778.1801696128496","inputs":{},"outputs":{}},"0.7387931740590231":{"definition":"//\n// construct object\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2018\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'construct object'\n//\n// initialization\n//\nvar init = function() {\n mod.in0.value = '{\"module\":1,\"angle\":0.3490658503988659,\"teeth\":10,\"rp\":5,\"rb\":4.698463103929543,\"ha\":1,\"hd\":1.1,\"ai\":0.014904383867336446,\"ap\":0.6283185307179586}'\n mod.in1.value = '{}'\n mod.out0.value = '{rz:180-180*in0.ai/Math.PI}'\n mod.out1.value = '{dx:2*in0.rp}'\n }\n//\n// inputs\n//\nvar inputs = {\n in0:{type:'',label:'input 0',\n event:function(evt) {\n mod.in0.value = JSON.stringify(evt.detail)\n construct_output()\n }},\n in1:{type:'',label:'input 1',\n event:function(evt) {\n mod.in1.value = JSON.stringify(evt.detail)\n construct_output()\n }}}\n//\n// outputs\n//\nvar outputs = {\n out0:{type:'',label:'output 0',\n event:function(arg){\n mods.output(mod,'out0',arg)\n }},\n out1:{type:'',label:'output 1',\n event:function(arg){\n mods.output(mod,'out1',arg)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // inputs\n //\n div.appendChild(document.createTextNode('input 0:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.in0 = text\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('input 1:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.in1 = text\n div.appendChild(document.createElement('br'))\n //\n // outputs\n //\n div.appendChild(document.createTextNode('output 0:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.out0 = text\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('output 1:'))\n div.appendChild(document.createElement('br'))\n var text = document.createElement('textarea')\n text.setAttribute('rows',1)\n text.setAttribute('cols',mods.ui.cols)\n div.appendChild(text)\n mod.out1 = text\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n construct_output()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\nfunction construct_output() {\n var in0 = JSON.parse(mod.in0.value)\n var in1 = JSON.parse(mod.in1.value)\n eval('out0 ='+mod.out0.value)\n eval('out1 ='+mod.out1.value)\n outputs.out0.event(out0)\n outputs.out1.event(out1)\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"548.2326872356177","left":"111.59471259466034","inputs":{},"outputs":{}},"0.1979915385145985":{"definition":"//\n// frep rotate\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep rotate'\n//\n// initialization\n//\nvar init = function() {\n mod.rx.value = ''\n mod.ry.value = ''\n mod.rz.value = '179.14604170815875'\n mod.ox.value = '0'\n mod.oy.value = '0'\n mod.oz.value = '0'\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }},\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n var ox = parseFloat(mod.ox.value)\n var oy = parseFloat(mod.oy.value)\n var oz = parseFloat(mod.oz.value)\n if (mod.rx.value != '') {\n var rx = parseFloat(mod.rx.value)*Math.PI/180\n var yvar = variables[1]\n var zvar = variables[2]\n var yre = new RegExp(yvar,'g')\n var zre = new RegExp(zvar,'g')\n fn = fn.replace(yre,\n `((${oy})+(${yvar}-(${oy}))*Math.cos(${rx})+(TEMP-(${oz}))*Math.sin(${rx}))`)\n fn = fn.replace(zre,\n `((${oz})-(${yvar}-(${oy}))*Math.sin(${rx})+(${zvar}-(${oz}))*Math.cos(${rx}))`)\n fn = fn.replace(/TEMP/g,zvar)\n var y0 = limits[1][0]\n var y1 = limits[1][1]\n var z0 = limits[2][0]\n var z1 = limits[2][1]\n limits[1][0] = Math.min(\n oy+(y0-oy)*Math.cos(rx)-(z0-oz)*Math.sin(rx),\n oy+(y0-oy)*Math.cos(rx)-(z1-oz)*Math.sin(rx),\n oy+(y1-oy)*Math.cos(rx)-(z0-oz)*Math.sin(rx),\n oy+(y1-oy)*Math.cos(rx)-(z1-oz)*Math.sin(rx))\n limits[1][1] = Math.max(\n oy+(y0-oy)*Math.cos(rx)-(z0-oz)*Math.sin(rx),\n oy+(y0-oy)*Math.cos(rx)-(z1-oz)*Math.sin(rx),\n oy+(y1-oy)*Math.cos(rx)-(z0-oz)*Math.sin(rx),\n oy+(y1-oy)*Math.cos(rx)-(z1-oz)*Math.sin(rx))\n limits[2][0] = Math.min(\n oz+(y0-oy)*Math.sin(rx)+(z0-oz)*Math.cos(rx),\n oz+(y0-oy)*Math.sin(rx)+(z1-oz)*Math.cos(rx),\n oz+(y1-oy)*Math.sin(rx)+(z0-oz)*Math.cos(rx),\n oz+(y1-oy)*Math.sin(rx)+(z1-oz)*Math.cos(rx))\n limits[2][1] = Math.max(\n oz+(y0-oy)*Math.sin(rx)+(z0-oz)*Math.cos(rx),\n oz+(y0-oy)*Math.sin(rx)+(z1-oz)*Math.cos(rx),\n oz+(y1-oy)*Math.sin(rx)+(z0-oz)*Math.cos(rx),\n oz+(y1-oy)*Math.sin(rx)+(z1-oz)*Math.cos(rx))\n }\n if (mod.ry.value != '') {\n var ry = parseFloat(mod.ry.value)*Math.PI/180\n var xvar = variables[0]\n var zvar = variables[2]\n var xre = new RegExp(xvar,'g')\n var zre = new RegExp(zvar,'g')\n fn = fn.replace(xre,\n `((${ox})+(${xvar}-(${ox}))*Math.cos(${ry})+(TEMP-(${oz}))*Math.sin(${ry}))`)\n fn = fn.replace(zre,\n `((${oz})-(${xvar}-(${ox}))*Math.sin(${ry})+(${zvar}-(${oz}))*Math.cos(${ry}))`)\n fn = fn.replace(/TEMP/g,zvar)\n var x0 = limits[0][0]\n var x1 = limits[0][1]\n var z0 = limits[2][0]\n var z1 = limits[2][1]\n limits[0][0] = Math.min(\n ox+(x0-ox)*Math.cos(ry)-(z0-oz)*Math.sin(ry),\n ox+(x0-ox)*Math.cos(ry)-(z1-oz)*Math.sin(ry),\n ox+(x1-ox)*Math.cos(ry)-(z0-oz)*Math.sin(ry),\n ox+(x1-ox)*Math.cos(ry)-(z1-oz)*Math.sin(ry))\n limits[0][1] = Math.max(\n ox+(x0-ox)*Math.cos(ry)-(z0-oz)*Math.sin(ry),\n ox+(x0-ox)*Math.cos(ry)-(z1-oz)*Math.sin(ry),\n ox+(x1-ox)*Math.cos(ry)-(z0-oz)*Math.sin(ry),\n ox+(x1-ox)*Math.cos(ry)-(z1-oz)*Math.sin(ry))\n limits[2][0] = Math.min(\n oz+(x0-ox)*Math.sin(ry)+(z0-oz)*Math.cos(ry),\n oz+(x0-ox)*Math.sin(ry)+(z1-oz)*Math.cos(ry),\n oz+(x1-ox)*Math.sin(ry)+(z0-oz)*Math.cos(ry),\n oz+(x1-ox)*Math.sin(ry)+(z1-oz)*Math.cos(ry))\n limits[2][1] = Math.max(\n oz+(x0-ox)*Math.sin(ry)+(z0-oz)*Math.cos(ry),\n oz+(x0-ox)*Math.sin(ry)+(z1-oz)*Math.cos(ry),\n oz+(x1-ox)*Math.sin(ry)+(z0-oz)*Math.cos(ry),\n oz+(x1-ox)*Math.sin(ry)+(z1-oz)*Math.cos(ry))\n }\n if (mod.rz.value != '') {\n var rz = parseFloat(mod.rz.value)*Math.PI/180\n var xvar = variables[0]\n var yvar = variables[1]\n var xre = new RegExp(xvar,'g')\n var yre = new RegExp(yvar,'g')\n fn = fn.replace(xre,\n `((${ox})+(${xvar}-(${ox}))*Math.cos(${rz})+(TEMP-(${oy}))*Math.sin(${rz}))`)\n fn = fn.replace(yre,\n `((${oy})-(${xvar}-(${ox}))*Math.sin(${rz})+(${yvar}-(${oy}))*Math.cos(${rz}))`)\n fn = fn.replace(/TEMP/g,yvar)\n var x0 = limits[0][0]\n var x1 = limits[0][1]\n var y0 = limits[1][0]\n var y1 = limits[1][1]\n limits[0][0] = Math.min(\n ox+(x0-ox)*Math.cos(rz)-(y0-oy)*Math.sin(rz),\n ox+(x0-ox)*Math.cos(rz)-(y1-oy)*Math.sin(rz),\n ox+(x1-ox)*Math.cos(rz)-(y0-oy)*Math.sin(rz),\n ox+(x1-ox)*Math.cos(rz)-(y1-oy)*Math.sin(rz))\n limits[0][1] = Math.max(\n ox+(x0-ox)*Math.cos(rz)-(y0-oy)*Math.sin(rz),\n ox+(x0-ox)*Math.cos(rz)-(y1-oy)*Math.sin(rz),\n ox+(x1-ox)*Math.cos(rz)-(y0-oy)*Math.sin(rz),\n ox+(x1-ox)*Math.cos(rz)-(y1-oy)*Math.sin(rz))\n limits[1][0] = Math.min(\n oy+(x0-ox)*Math.sin(rz)+(y0-oy)*Math.cos(rz),\n oy+(x0-ox)*Math.sin(rz)+(y1-oy)*Math.cos(rz),\n oy+(x1-ox)*Math.sin(rz)+(y0-oy)*Math.cos(rz),\n oy+(x1-ox)*Math.sin(rz)+(y1-oy)*Math.cos(rz))\n limits[1][1] = Math.max(\n oy+(x0-ox)*Math.sin(rz)+(y0-oy)*Math.cos(rz),\n oy+(x0-ox)*Math.sin(rz)+(y1-oy)*Math.cos(rz),\n oy+(x1-ox)*Math.sin(rz)+(y0-oy)*Math.cos(rz),\n oy+(x1-ox)*Math.sin(rz)+(y1-oy)*Math.cos(rz))\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n div.appendChild(document.createTextNode('angle\\xa0\\xa0\\xa0 origin'))\n div.appendChild(document.createElement('br'))\n //\n // x\n //\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.rx = input\n div.appendChild(document.createTextNode(' x '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.ox = input\n div.appendChild(document.createElement('br'))\n //\n // y\n //\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.ry = input\n div.appendChild(document.createTextNode(' y '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.oy = input\n div.appendChild(document.createElement('br'))\n //\n // z\n //\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.rz = input\n div.appendChild(document.createTextNode(' z '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.oz = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"680.5488895766132","left":"495.88811415852007","inputs":{},"outputs":{}},"0.6065252651057798":{"definition":"//\n// frep translate\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep translate'\n//\n// initialization\n//\nvar init = function() {\n mod.dx.value = '10'\n mod.dy.value = ''\n mod.dz.value = ''\n mod.xmin.value = ''\n mod.ymin.value = ''\n mod.zmin.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'',\n event:function(evt){\n mod.shape = evt.detail\n outputs.shape.event()\n }},\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var fn = mod.shape.function\n var variables = mod.shape.variables\n var type = mod.shape.type \n var limits = []\n for (var v = 0; v < mod.shape.limits.length; ++v) {\n limits[v] = []\n limits[v][0] = mod.shape.limits[v][0]\n limits[v][1] = mod.shape.limits[v][1]\n }\n if (mod.xmin.value != '') {\n var xmin = parseFloat(mod.xmin.value)\n var xvar = variables[0]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`((${limits[0][0]})+${xvar}-(${xmin}))`)\n var dx = limits[0][1]-limits[0][0]\n limits[0][0] = xmin\n limits[0][1] = xmin+dx\n }\n else if (mod.dx.value != '') {\n var dx = parseFloat(mod.dx.value)\n var xvar = variables[0]\n var re = new RegExp(xvar,'g')\n fn = fn.replace(re,`(${xvar}-(${dx}))`)\n var dx = parseFloat(mod.dx.value)\n limits[0][0] += dx\n limits[0][1] += dx\n }\n if (mod.ymin.value != '') {\n var ymin = parseFloat(mod.ymin.value)\n var yvar = variables[1]\n var re = new RegExp(yvar,'g')\n fn = fn.replace(re,`((${limits[1][0]})+${yvar}-(${ymin}))`)\n var dy = limits[1][1]-limits[1][0]\n limits[1][0] = ymin\n limits[1][1] = ymin+dy\n }\n else if (mod.dy.value != '') {\n var dy = parseFloat(mod.dy.value)\n var yvar = variables[1]\n var re = new RegExp(yvar,'g')\n fn = fn.replace(re,`(${yvar}-(${dy}))`)\n var dy = parseFloat(mod.dy.value)\n limits[1][0] += dy\n limits[1][1] += dy\n }\n if (mod.zmin.value != '') {\n var zmin = parseFloat(mod.zmin.value)\n var zvar = variables[2]\n var re = new RegExp(zvar,'g')\n fn = fn.replace(re,`((${limits[2][0]})+${zvar}-(${zmin}))`)\n var dz = limits[2][1]-limits[2][0]\n limits[2][0] = zmin\n limits[2][1] = zmin+dz\n }\n else if (mod.dz.value != '') {\n var dz = parseFloat(mod.dz.value)\n var zvar = variables[2]\n var re = new RegExp(zvar,'g')\n fn = fn.replace(re,`(${zvar}-(${dz}))`)\n var dz = parseFloat(mod.dz.value)\n limits[2][0] += dz\n limits[2][1] += dz\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // x\n //\n div.appendChild(document.createTextNode('xmin: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('input',function(){\n mod.dx.value = ''\n })\n div.appendChild(input)\n mod.xmin = input\n div.appendChild(document.createTextNode(' dx: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('input',function(){\n mod.xmin.value = ''\n })\n div.appendChild(input)\n mod.dx = input\n div.appendChild(document.createElement('br'))\n //\n // y\n //\n div.appendChild(document.createTextNode('ymin: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('input',function(){\n mod.dy.value = ''\n })\n div.appendChild(input)\n mod.ymin = input\n div.appendChild(document.createTextNode(' dy: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('input',function(){\n mod.ymin.value = ''\n })\n div.appendChild(input)\n mod.dy = input\n div.appendChild(document.createElement('br'))\n //\n // z\n //\n div.appendChild(document.createTextNode('zmin: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('input',function(){\n mod.dz.value = ''\n })\n div.appendChild(input)\n mod.zmin = input\n div.appendChild(document.createTextNode(' dz: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('input',function(){\n mod.zmin.value = ''\n })\n div.appendChild(input)\n mod.dz = input\n div.appendChild(document.createElement('br'))\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"501.12204740542757","left":"856.1559836116508","inputs":{},"outputs":{}},"0.5392744839952156":{"definition":"//\n// frep add\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2017\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep add'\n//\n// initialization\n//\nvar init = function() {\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = 'Math.max(Math.min(Math.min(5+1-Math.sqrt(((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))*((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))+((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))*((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))),(Math.PI+Math.atan2(((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444)),((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))))%0.6283185307179586-(Math.sqrt(Math.pow(Math.max(4.698463103929543,Math.sqrt(((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))*((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))+((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))*((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))))/4.698463103929543,2)-1)-Math.acos(4.698463103929543/Math.max(4.698463103929543,Math.sqrt(((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))*((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))+((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))*((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))))))),-(Math.sqrt(Math.pow(Math.max(4.698463103929543,Math.sqrt(((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))*((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))+((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))*((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))))/4.698463103929543,2)-1)-Math.acos(4.698463103929543/Math.max(4.698463103929543,Math.sqrt(((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))*((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))+((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))*((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))))))-(-0.3439680330936522+(Math.PI+Math.atan2(((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444)),((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))))%0.6283185307179586)),3.9-Math.sqrt(((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))*((0)+(X-(0))*Math.cos(-0.014904383867336444)+(Y-(0))*Math.sin(-0.014904383867336444))+((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))*((0)-(X-(0))*Math.sin(-0.014904383867336444)+(Y-(0))*Math.cos(-0.014904383867336444))))'\n mod.fn1.value = 'Math.max(Math.min(Math.min(5+1-Math.sqrt(((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))*((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))+((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))*((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))),(Math.PI+Math.atan2(((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565)),((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))))%0.6283185307179586-(Math.sqrt(Math.pow(Math.max(4.698463103929543,Math.sqrt(((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))*((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))+((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))*((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))))/4.698463103929543,2)-1)-Math.acos(4.698463103929543/Math.max(4.698463103929543,Math.sqrt(((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))*((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))+((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))*((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))))))),-(Math.sqrt(Math.pow(Math.max(4.698463103929543,Math.sqrt(((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))*((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))+((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))*((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))))/4.698463103929543,2)-1)-Math.acos(4.698463103929543/Math.max(4.698463103929543,Math.sqrt(((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))*((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))+((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))*((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))))))-(-0.3439680330936522+(Math.PI+Math.atan2(((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565)),((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))))%0.6283185307179586)),3.9-Math.sqrt(((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))*((0)+((X-(10))-(0))*Math.cos(3.1266882697224565)+(Y-(0))*Math.sin(3.1266882697224565))+((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))*((0)-((X-(10))-(0))*Math.sin(3.1266882697224565)+(Y-(0))*Math.cos(3.1266882697224565))))'\n }\n//\n// inputs\n//\nvar inputs = {\n shape0:{type:'',label:'shape 0',\n event:function(evt){\n mod.shape0 = evt.detail\n mod.fn0.value = evt.detail.function\n outputs.shape.event()\n }},\n shape1:{type:'',label:'shape 1',\n event:function(evt){\n mod.shape1 = evt.detail\n mod.fn1.value = evt.detail.function\n outputs.shape.event()\n }},\n clear:{type:'',\n event:function(evt){\n mod.shape0 = null\n mod.shape1 = null\n mod.fn0.value = ''\n mod.fn1.value = ''\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n if ((mod.shape0 != null) && (mod.shape1 != null)) {\n var fn = `Math.max(${mod.shape0.function},${mod.shape1.function})`\n var variables = mod.shape0.variables\n var type = mod.shape0.type \n var limits = []\n for (var v = 0; v < mod.shape0.limits.length; ++v) {\n limits[v] = []\n if (mod.shape0.limits[v][0] < mod.shape1.limits[v][0])\n limits[v][0] = mod.shape0.limits[v][0]\n else\n limits[v][0] = mod.shape1.limits[v][0]\n if (mod.shape0.limits[v][1] > mod.shape1.limits[v][1])\n limits[v][1] = mod.shape0.limits[v][1]\n else\n limits[v][1] = mod.shape1.limits[v][1]\n }\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}\n }\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // function 0\n //\n div.appendChild(document.createTextNode('function 0: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn0 = input\n div.appendChild(document.createElement('br'))\n //\n // function 1\n //\n div.appendChild(document.createTextNode('function 1: '))\n div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n div.appendChild(input)\n mod.fn1 = input\n div.appendChild(document.createElement('br'))\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"284.6451625177166","left":"1158.6632477519015","inputs":{},"outputs":{}},"0.6416839986031856":{"definition":"//\n// frep involute gear\n// todo: fillets\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep involute gear'\n//\n// initialization\n//\nvar init = function() {\n mod.module.value = '1'\n mod.angle.value = '20'\n mod.teeth.value = '10'\n mod.addendum.value = '1'\n mod.dedendum.value = '1.1'\n }\n//\n// inputs\n//\nvar inputs = {\n variables:{type:'',\n event:function(evt){\n for (var p in evt.detail)\n mod[p].value = evt.detail[p]\n outputs.variables.event()\n outputs.shape.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n shape:{type:'',\n event:function(){\n var module = parseFloat(mod.module.value)\n var angle = Math.PI*parseFloat(mod.angle.value)/180\n var teeth = parseFloat(mod.teeth.value)\n var addendum = parseFloat(mod.addendum.value)\n var dedendum = parseFloat(mod.dedendum.value)\n //\n // pitch radius\n //\n var rp = module*teeth/2 \n mod.info.innerHTML = `pitch radius: ${rp.toFixed(3)} mm
`\n //\n // base radius\n //\n var rb = rp*Math.cos(angle)\n mod.info.innerHTML += `base radius: ${rb.toFixed(3)} mm
`\n //\n // addendum height\n //\n var ha = addendum*module\n mod.info.innerHTML += `outer radius: ${(rp+ha).toFixed(3)} mm
`\n //\n // dedendum height\n //\n var hd = dedendum*module\n mod.info.innerHTML += `root radius: ${(rp-hd).toFixed(3)} mm
`\n //\n // involute angle\n //\n var ai = Math.tan(angle)-angle \n //\n // pitch angle\n //\n var ap = 2*Math.PI/teeth\n //\n // shapes\n //\n // must be inside tip\n //\n var fn = `${rp}+${ha}-Math.sqrt(X*X+Y*Y)`\n //\n // angle must be above bottom involute\n //\n var fn = `Math.min(${fn},(Math.PI+Math.atan2(Y,X))%${ap}-(Math.sqrt(Math.pow(Math.max(${rb},Math.sqrt(X*X+Y*Y))/${rb},2)-1)-Math.acos(${rb}/Math.max(${rb},Math.sqrt(X*X+Y*Y)))))`\n //\n // angle must be below top involute\n //\n var fn = `Math.min(${fn},-(Math.sqrt(Math.pow(Math.max(${rb},Math.sqrt(X*X+Y*Y))/${rb},2)-1)-Math.acos(${rb}/Math.max(${rb},Math.sqrt(X*X+Y*Y))))-(-${ap/2+2*ai}+(Math.PI+Math.atan2(Y,X))%${ap}))`\n //\n // root circle\n //\n var fn = `Math.max(${fn},${rp-hd}-Math.sqrt(X*X+Y*Y))`\n //\n // output\n //\n var variables = ['X','Y']\n var limits = [[-rp-ha,+rp+ha],[-rp-ha,+rp+ha]]\n var type = 'Magnitude'\n var shape = {function:fn,variables:variables,limits:limits,type:type}\n mods.output(mod,'shape',shape)}},\n variables:{type:'',\n event:function(){\n var module = parseFloat(mod.module.value)\n var angle = Math.PI*parseFloat(mod.angle.value)/180\n var teeth = parseFloat(mod.teeth.value)\n var addendum = parseFloat(mod.addendum.value)\n var dedendum = parseFloat(mod.dedendum.value)\n var rp = module*teeth/2 \n var rb = rp*Math.cos(angle)\n var ha = addendum*module\n var hd = dedendum*module\n var ai = Math.tan(angle)-angle \n var ap = 2*Math.PI/teeth\n var vars = {module:module,angle:angle,teeth:teeth,rp:rp,rb:rb,ha:ha,hd:hd,ai:ai,ap:ap}\n mods.output(mod,'variables',vars)}\n }}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // module\n //\n div.appendChild(document.createTextNode('module (m): '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.module = input\n div.appendChild(document.createTextNode(' (mm)'))\n div.appendChild(document.createElement('br'))\n //\n // addendum\n //\n div.appendChild(document.createTextNode('addendum: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.addendum = input\n div.appendChild(document.createTextNode(' (m)'))\n div.appendChild(document.createElement('br'))\n //\n // dedendum \n //\n div.appendChild(document.createTextNode('dedendum: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.dedendum = input\n div.appendChild(document.createTextNode(' (m)'))\n div.appendChild(document.createElement('br'))\n //\n // angle\n //\n div.appendChild(document.createTextNode('pressure angle: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.angle = input\n div.appendChild(document.createElement('br'))\n //\n // teeth \n //\n div.appendChild(document.createTextNode('number of teeth: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n div.appendChild(input)\n mod.teeth = input\n div.appendChild(document.createElement('br'))\n //\n // info\n //\n var info = document.createElement('span')\n div.appendChild(info)\n mod.info = info\n //\n // output button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('output'))\n btn.addEventListener('click',function(){\n outputs.variables.event()\n outputs.shape.event()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n;\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"118.84392929787097","left":"132.69194228471963","inputs":{},"outputs":{}},"0.5937982247344423":{"definition":"//\n// convert rgba png\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2018\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is \n// provided as is; no warranty is provided, and users accept all \n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'convert RGBA to PNG'\n//\n// initialization\n//\nvar init = function() {\n mod.name.value = 'file.png'\n }\n//\n// inputs\n//\nvar inputs = {\n image:{type:'RGBA',\n event:function(evt){\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = evt.detail.width\n ctx.canvas.height = evt.detail.height \n ctx.putImageData(evt.detail,0,0)\n mod.pxtext.nodeValue = evt.detail.width+' x '+evt.detail.height+' px'\n convert_image()\n }},\n imageInfo:{type:'object',\n event:function(evt){\n mod.name.value = evt.detail.name+'.png'\n mod.dpitext.nodeValue = parseFloat(evt.detail.dpi).toFixed(3)+' dpi'\n }}\n }\n//\n// outputs\n//\nvar outputs = {\n }\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // view button\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('view'))\n btn.addEventListener('click',function(){\n var win = window.open('')\n var btn = document.createElement('button')\n btn.appendChild(document.createTextNode('close'))\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.addEventListener('click',function(){\n win.close()\n })\n win.document.body.appendChild(btn)\n win.document.body.appendChild(document.createElement('br'))\n var canvas = document.createElement('canvas')\n canvas.width = mod.img.width\n canvas.height = mod.img.height\n win.document.body.appendChild(canvas)\n var ctx = canvas.getContext(\"2d\")\n ctx.drawImage(mod.img,0,0)\n })\n div.appendChild(btn)\n div.appendChild(document.createTextNode(' '))\n //\n // info div\n //\n var info = document.createElement('div')\n info.appendChild(document.createTextNode('file name: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n info.appendChild(input)\n mod.name = input\n info.appendChild(document.createElement('br'))\n var text = document.createTextNode('px')\n info.appendChild(text)\n mod.pxtext = text\n info.appendChild(document.createElement('br'))\n var text = document.createTextNode('dpi')\n info.appendChild(text)\n mod.dpitext = text\n div.appendChild(info)\n }\n//\n// local functions\n//\nfunction convert_image() {\n //\n // preview\n //\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n //\n // convert and save\n //\n mod.img.toBlob(function(blob){\n var url = URL.createObjectURL(blob)\n var link = document.createElement('a')\n link.download = mod.name.value\n link.href = url\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n URL.revokeObjectURL(url)\n },'image/png')\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"141.07676717899002","left":"2054.2766617787643","inputs":{},"outputs":{}},"0.7821426838930192":{"definition":"//\n// frep view slice\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2018\n//\n// This work may be reproduced, modified, distributed, performed, and\n// displayed for any purpose, but must acknowledge the mods\n// project. Copyright is retained and must be preserved. The work is\n// provided as is; no warranty is provided, and users accept all\n// liability.\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'frep view slice'\n//\n// initialization\n//\nvar init = function() {\n mod.mmunits.value = '25.4'\n mod.inunits.value = '1'\n mod.depth.value = '0.1'\n mod.width.value = '1000'\n mod.border.value = '0'\n }\n//\n// inputs\n//\nvar inputs = {\n shape:{type:'frep',\n event:function(evt){\n mod.frep = evt.detail\n limits()\n slice()\n }}}\n//\n// outputs\n//\nvar outputs = {\n image:{type:'RGBA',\n event:function(){\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n mods.output(mod,'image',img)\n }},\n imageInfo:{type:'',\n event:function(){\n var obj = {}\n obj.name = \"frep view slice\"\n obj.width = mod.img.width\n obj.height = mod.img.height\n obj.dpi = mod.img.width/(mod.dx*parseFloat(mod.inunits.value))\n obj.dpi = parseFloat(mod.width.value)/(mod.dx*parseFloat(mod.inunits.value))\n mods.output(mod,'imageInfo',obj)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen drawing canvas\n //\n var canvas = document.createElement('canvas')\n canvas.width = mods.ui.canvas\n canvas.height = mods.ui.canvas\n canvas.style.backgroundColor = 'rgb(255,255,255)'\n div.appendChild(canvas)\n mod.canvas = canvas\n div.appendChild(document.createElement('br'))\n //\n // off-screen image canvas\n //\n var canvas = document.createElement('canvas')\n mod.img = canvas\n //\n // frep units\n //\n div.appendChild(document.createTextNode('frep units: (enter)'))\n div.appendChild(document.createElement('br'))\n div.appendChild(document.createTextNode('mm: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function(){\n mod.inunits.value = parseFloat(mod.mmunits.value)/25.4\n limits()\n })\n div.appendChild(input)\n mod.mmunits = input\n div.appendChild(document.createTextNode(' in: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function(){\n mod.mmunits.value = parseFloat(mod.inunits.value)*25.4\n limits()\n })\n div.appendChild(input)\n mod.inunits = input\n div.appendChild(document.createElement('br'))\n //\n // frep size\n //\n div.appendChild(document.createTextNode('frep size:'))\n div.appendChild(document.createElement('br'))\n var text = document.createTextNode('XxYxZ (units)')\n div.appendChild(text)\n mod.meshsize = text\n div.appendChild(document.createElement('br'))\n var text = document.createTextNode('XxYxZ (mm)')\n div.appendChild(text)\n mod.mmsize = text\n div.appendChild(document.createElement('br'))\n var text = document.createTextNode('XxYxZ (in)')\n div.appendChild(text)\n mod.insize = text\n div.appendChild(document.createElement('br'))\n //\n // slice depth\n //\n div.appendChild(document.createTextNode('slice z depth: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('change',function(){\n limits()\n slice()\n })\n div.appendChild(input)\n mod.depth = input\n div.appendChild(document.createTextNode(' (units)'))\n div.appendChild(document.createElement('br'))\n //\n // slice border \n //\n div.appendChild(document.createTextNode('slice border: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function(){\n limits()\n slice()\n })\n div.appendChild(input)\n mod.border = input\n div.appendChild(document.createTextNode(' (units)'))\n div.appendChild(document.createElement('br'))\n //\n // slice width\n //\n div.appendChild(document.createTextNode('slice width: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 3\n input.addEventListener('change',function(){\n limits()\n slice()\n })\n div.appendChild(input)\n mod.width = input\n div.appendChild(document.createTextNode(' (pixels)'))\n div.appendChild(document.createElement('br'))\n //\n // view button\n //\n div.appendChild(document.createTextNode(' '))\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n btn.appendChild(document.createTextNode('view slice'))\n btn.addEventListener('click',function(){\n mod.win = window.open('')\n mod.win.document.body.style.overflow = 'hidden'\n mod.win.document.body.style.border = 0\n mod.win.document.body.style.padding = 0\n mod.win.document.body.style.margin = 0\n mod.win.addEventListener('unload',function() {\n mod.win = null\n })\n var canvas = document.createElement('canvas')\n canvas.setAttribute('id',mod.div.id+'canvas')\n mod.win.document.body.appendChild(canvas)\n var ctx = canvas.getContext(\"2d\")\n canvas.width = window.innerWidth\n canvas.height = window.innerWidth\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var wd = canvas.width\n var hd = canvas.width*h/w\n }\n else {\n var wd = canvas.height*w/h\n var hd = canvas.height\n }\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,canvas.width,canvas.height)\n ctx.drawImage(mod.img,0,0,wd,hd)\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n// limits\n//\nfunction limits() {\n var limits = mod.frep.limits\n var ins = parseFloat(mod.inunits.value)\n var mms = parseFloat(mod.mmunits.value)\n var border = parseFloat(mod.border.value)\n mod.dx = 2*border+limits[0][1]-limits[0][0]\n mod.dy = 2*border+limits[1][1]-limits[1][0]\n if (mod.frep.variables.length == 2) {\n mod.meshsize.nodeValue =\n (mod.dx).toFixed(3)+' x '+\n (mod.dy).toFixed(3)+' (units)'\n mod.mmsize.nodeValue =\n (mms*mod.dx).toFixed(3)+' x '+\n (mms*mod.dy).toFixed(3)+' (mm)'\n mod.insize.nodeValue = \n (ins*mod.dx).toFixed(3)+' x '+\n (ins*mod.dy).toFixed(3)+' (in)'\n }\n else if (mod.frep.variables.length > 2) {\n mod.dz = limits[2][1]-limits[2][0]\n mod.meshsize.nodeValue =\n (mod.dx).toFixed(3)+' x '+\n (mod.dy).toFixed(3)+' x '+\n (mod.dz).toFixed(3)+' (units)'\n mod.mmsize.nodeValue =\n (mms*mod.dx).toFixed(3)+' x '+\n (mms*mod.dy).toFixed(3)+' x '+\n (mms*mod.dz).toFixed(3)+' (mm)'\n mod.insize.nodeValue = \n (ins*mod.dx).toFixed(3)+' x '+\n (ins*mod.dy).toFixed(3)+' x '+\n (ins*mod.dz).toFixed(3)+' (in)'\n }\n outputs.imageInfo.event()\n mods.fit(mod.div)\n }\n//\n// slice\n//\nfunction slice() { \n var fn = mod.frep.function\n var vars = mod.frep.variables\n var limits = mod.frep.limits\n var type = mod.frep.type\n var depth = parseFloat(mod.depth.value)\n var border = parseFloat(mod.border.value)\n var xvar = vars[0]\n var xlimits = limits[0]\n var yvar = vars[1]\n var ylimits = limits[1]\n if (vars.length == 2) {\n var zvar = ''\n var zlimits = []\n }\n else if (vars.length == 3) {\n var zvar = vars[2]\n var zlimits = limits[2]\n }\n var w = parseInt(mod.width.value)\n var h = Math.floor(w*(ylimits[1]-ylimits[0])/(xlimits[1]-xlimits[0]))\n mod.img.height = h\n mod.img.width = w\n var blob = new Blob(['('+worker.toString()+'())'])\n var url = window.URL.createObjectURL(blob)\n var webworker = new Worker(url)\n webworker.addEventListener('message',function(evt) {\n window.URL.revokeObjectURL(url)\n var h = mod.img.height\n var w = mod.img.width\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var imgdata = new ImageData(buf,w,h)\n var ctx = mod.img.getContext(\"2d\")\n ctx.putImageData(imgdata,0,0)\n if (w > h) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-h/w)\n var wd = mod.canvas.width\n var hd = mod.canvas.width*h/w\n }\n else {\n var x0 = mod.canvas.width*.5*(1-w/h)\n var y0 = 0\n var wd = mod.canvas.height*w/h\n var hd = mod.canvas.height\n }\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n if (mod.win != null) {\n var canvas = mod.win.document.getElementById(mod.div.id+'canvas')\n var ctx = canvas.getContext(\"2d\")\n canvas.width = window.innerWidth\n canvas.height = window.innerWidth\n var h = mod.img.height\n var w = mod.img.width\n if (w > h) {\n var wd = canvas.width\n var hd = canvas.width*h/w\n }\n else {\n var wd = canvas.height*w/h\n var hd = canvas.height\n }\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,canvas.width,canvas.height)\n ctx.drawImage(mod.img,0,0,wd,hd)\n }\n webworker.terminate()\n outputs.image.event()\n })\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,mod.canvas.width,mod.canvas.height)\n var ctx = mod.img.getContext(\"2d\")\n ctx.fillStyle = '#dddddd'\n ctx.fillRect(0,0,mod.img.width,mod.img.height)\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n webworker.postMessage({\n height:img.height,width:img.width,\n xvar:xvar,yvar:yvar,zvar:zvar,\n xlimits:xlimits,ylimits:ylimits,zlimits:zlimits,\n depth:depth,border:border,function:fn,\n buffer:img.data.buffer},\n [img.data.buffer])\n }\n//\n// worker\n//\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var xvar = evt.data.xvar\n var yvar = evt.data.yvar\n var zvar = evt.data.zvar\n var xlimits = evt.data.xlimits\n var ylimits = evt.data.ylimits\n var zlimits = evt.data.zlimits\n var depth = evt.data.depth\n var border = evt.data.border\n xlimits[0] -= border\n xlimits[1] += border\n ylimits[0] -= border\n ylimits[1] += border\n var zval = depth\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var f = new Function(xvar,yvar,zvar,'return ('+evt.data.function+')')\n var x,y,v\n for (var row = 0; row < h; ++row) {\n y = ylimits[0]+(ylimits[1]-ylimits[0])*row/(h-1)\n for (var col = 0; col < w; ++col) {\n x = xlimits[0]+(xlimits[1]-xlimits[0])*col/(w-1)\n v = (f(x,y,zval) >= 0) ? 255 : 0\n buf[(h-1-row)*w*4+col*4+0] = v\n buf[(h-1-row)*w*4+col*4+1] = v\n buf[(h-1-row)*w*4+col*4+2] = v\n buf[(h-1-row)*w*4+col*4+3] = 255\n }\n }\n self.postMessage({buffer:buf.buffer},[buf.buffer])\n })\n }\n//\n// return values\n//\nreturn ({\n mod:mod,\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"145.27554869259492","left":"1487.4411574421224","inputs":{},"outputs":{}}},"links":["{\"source\":\"{\\\"id\\\":\\\"0.39612602144740094\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"out0\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.8412077289031379\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"variables\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.7387931740590231\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"out0\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.1979915385145985\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"variables\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.8412077289031379\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.5392744839952156\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.6065252651057798\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.5392744839952156\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape1\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.1979915385145985\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.6065252651057798\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.6416839986031856\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.8412077289031379\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.6416839986031856\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"variables\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.39612602144740094\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"in0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.6416839986031856\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"variables\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.7387931740590231\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"in0\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.6416839986031856\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.1979915385145985\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.7387931740590231\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"out1\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.6065252651057798\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"variables\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.5392744839952156\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"shape\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.7821426838930192\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"shape\\\"}\"}"]}