diff --git a/docs/Instruction/images/matterport/mt_ex.mp4 b/docs/Instruction/images/matterport/mt_ex.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..878061522fa19983fc86c53b5cadedfc740d8bb8 Binary files /dev/null and b/docs/Instruction/images/matterport/mt_ex.mp4 differ diff --git a/docs/Instruction/images/proverXL/line_test_1:64.jpg b/docs/Instruction/images/proverXL/line_test_1:64.jpg deleted file mode 100644 index 2333661d54f82158a8908f864b24ed39e9b0faf4..0000000000000000000000000000000000000000 Binary files a/docs/Instruction/images/proverXL/line_test_1:64.jpg and /dev/null differ diff --git a/docs/Instruction/images/proverXL/mods/mill_2D_PCB_png.html b/docs/Instruction/images/proverXL/mods/mill_2D_PCB_png.html index 1624982511f1e1b9c4ea1db3d482f732daeb8014..9f1acb641e4267726980a7ee01addc2ed9d1c988 100644 --- a/docs/Instruction/images/proverXL/mods/mill_2D_PCB_png.html +++ b/docs/Instruction/images/proverXL/mods/mill_2D_PCB_png.html @@ -4,1910 +4,1910 @@ </head> <body link='black' alink='black' vlink='black'> <script> -// -// mods.js -// -// Neil Gershenfeld -// (c) Massachusetts Institute of Technology 2018 -// -// This work may be reproduced, modified, distributed, performed, and -// displayed for any purpose, but must acknowledge the mods -// project. Copyright is retained and must be preserved. The work is -// provided as is; no warranty is provided, and users accept all -// liability. -// -// closure -// -(function(){ -// -// globals -// -var mods = {} -mods.mod = {} -mods.globals = {} -mods.ui = {source:null, - progname:'', - padding:7, - bezier:100, - canvas:250, - rows:5, - cols:20, - link_color:'rgb(0,0,128)', - link_highlight:'rgb(255,0,0)', - header:50, - selected:{}, - mousedown:null, - menu:null, - top:null, - left:null, - xstart:null, - ystart:null, - xtrans:null, - ytrans:null - } -// -// UI -// -document.body.style.overflow = "hidden" -function mods_transform() { - var transform = document.body.style.transform - var m = new DOMMatrix(getComputedStyle(document.body).transform) - var s = m.m11 - var tx = m.m41/s - var ty = m.m42/s - var origin = document.body.style.transformOrigin - var pxx = origin.indexOf('px') - var ox = parseFloat(origin.slice(0,pxx)) - var pxy = origin.indexOf('px',pxx+2) - var oy = parseFloat(origin.slice(pxx+2,pxy)) - return({s:s,tx:tx,ty:ty,ox:ox,oy:oy}) - } -document.body.style.transform = 'scale(1) translate(0px,0px)' -document.body.style.transformOrigin = '0px 0px' -// -// scroll wheel event -// -window.addEventListener('wheel',function(evt) { - /* - (xw+tx-ox)*s+ox = xs - xw = ox-tx+(xs-ox)/s - (xw+tx0-ox0)*s+ox0 = (xw+tx1-ox1)*s+ox1 - (tx0-ox0)*s+ox0 = (tx1-ox1)*s+ox1 - tx0+(ox1-ox0)+(ox0-ox1)/s = tx1 - tx0+(ox1-ox0)*(1-1/s) = tx1 - */ - var el = document.elementFromPoint(evt.pageX,evt.pageY) - if ((el.tagName == "HTML") || (el.tagName == "BODY")) { - set_prompt('scroll to zoom') - evt.preventDefault() - evt.stopPropagation() - var t = mods_transform() - if (evt.deltaY > 0) - var scale = t.s*1.1 - else - var scale = t.s*0.9 - var tx = t.tx+(evt.pageX-t.ox)*(1-1/t.s) - var ty = t.ty+(evt.pageY-t.oy)*(1-1/t.s) - document.body.style.transform = `scale(${scale}) translate(${tx}px,${ty}px)` - document.body.style.transformOrigin = `${evt.pageX}px ${evt.pageY}px` - } - }) -// -// body mouse events -// -window.addEventListener('mousedown',function(evt) { - // - // get element mouse is over - // - var el = document.elementFromPoint(evt.pageX,evt.pageY) - // - // check if on body - // - if ((el.tagName == "HTML") || (el.tagName == "BODY")) { - // - // remember button - // - mods.ui.mousedown = evt.button - if (mods.ui.mousedown == 0) { - set_prompt('left-drag to pan, right-drag to select') - if (mods.ui.menu != null) { - document.body.removeChild(mods.ui.menu) - mods.ui.menu = null - } - } - else if (mods.ui.mousedown == 2) { - set_prompt('menu; left-drag to pan, right-drag to select') - } - // - // remember position - // - var t = mods_transform() - mods.ui.xstart = evt.pageX - mods.ui.ystart = evt.pageY - mods.ui.xtrans = t.tx - mods.ui.ytrans = t.ty - } - }) -window.addEventListener('mousemove',function(evt) { - // - // mouse move - // - if (mods.ui.mousedown != null) { - evt.preventDefault() - evt.stopPropagation() - var t = mods_transform() - if (mods.ui.mousedown == 0) { - // - // pan on left drag - // - xtrans = mods.ui.xtrans+(evt.pageX-mods.ui.xstart)/t.s - ytrans = mods.ui.ytrans+(evt.pageY-mods.ui.ystart)/t.s - document.body.style.transform = `scale(${t.s}) translate(${xtrans}px,${ytrans}px)` - } - else if (mods.ui.mousedown == 2) { - // - // select on right drag - // - var rect = document.getElementById('svgrect') - if (rect == undefined) { - // - // start dragging - // - if (mods.ui.menu != null) { - document.body.removeChild(mods.ui.menu) - mods.ui.menu = null - } - set_prompt('right-drag to select') - var t = mods_transform() - var rect = document.createElementNS('http://www.w3.org/2000/svg','rect') - rect.setAttribute('id','svgrect') - rect.setAttribute('x',t.ox-t.tx+(evt.pageX-t.ox)/t.s) - rect.setAttribute('y',t.oy-t.ty+(evt.pageY-t.oy)/t.s-mods.ui.header) - rect.setAttribute('width',0) - rect.setAttribute('height',0) - rect.setAttribute('fill','rgb(200,200,200)') - rect.setAttribute('stroke','none') - var svg = document.getElementById('svg') - svg.insertBefore(rect,svg.firstChild) - } - else { - // - // continue dragging - // - var rect = document.getElementById('svgrect') - var xp = t.ox-t.tx+(mods.ui.xstart-t.ox)/t.s - var yp = t.oy-t.ty+(mods.ui.ystart-t.oy)/t.s-mods.ui.header - var xw = t.ox-t.tx+(evt.pageX-t.ox)/t.s - var yw = t.oy-t.ty+(evt.pageY-t.oy)/t.s-mods.ui.header - if (xw < xp) { - rect.setAttribute('x',xw) - rect.setAttribute('width',xp-xw) - } - else - rect.setAttribute('width',xw-xp) - if (yw < yp) { - rect.setAttribute('y',yw) - rect.setAttribute('height',yp-yw) - } - else - rect.setAttribute('height',yw-yp) - } - } - } - }) -window.addEventListener('mouseup',function(evt) { - // - // mouse up - // - mods.ui.mousedown = null - // - // check for selection rectangle - // - var rect = document.getElementById('svgrect') - if (rect != null) { - // - // rectangle exists, selecting modules - // - var x = parseFloat(rect.getAttribute('x')) - var y = parseFloat(rect.getAttribute('y')) - var width = parseFloat(rect.getAttribute('width')) - var height = parseFloat(rect.getAttribute('height')) - svg.removeChild(rect) - var modules = document.getElementById('modules') - // - // loop to find selected modules - // - mods.ui.selected = {} - for (var module in modules.childNodes) { - var container = modules.childNodes[module] - var id = container.id - if (id != undefined) { - var name = container.firstChild - var left = parseFloat(container.dataset.left) - var top = parseFloat(container.dataset.top) - if ((x <= left) && (left <= x+width) && (y <= top) && (top <= y+height)) { - // - // module is in selection rectangle - // - name.style.fontWeight = "bold" - mods.ui.selected[id] = true - } - else { - // - // module is not in selection rectangle - // - name.style.fontWeight = "normal" - } - } - } - } - }) -// -// context menu -// -window.addEventListener('contextmenu',function(evt){ - evt.stopPropagation() - evt.preventDefault() - if (mods.ui.menu != null) { - document.body.removeChild(mods.ui.menu) - mods.ui.menu = null - } - var div = document.createElement('div') - make_menu(div) - add_menu(div,'modules',modules) - add_menu(div,'programs',programs) - add_menu(div,'edit',edit) - add_menu(div,'options',options) - document.body.appendChild(div) - function make_menu(div) { - mods.ui.menu = div - div.style.position = "absolute" - var t = mods_transform() - div.style.top = t.oy-t.ty+(evt.pageY-t.oy)/t.s - div.style.left = t.ox-t.tx+(evt.pageX-t.ox)/t.s - div.style.zIndex = 0 - div.style.cursor = 'default' - div.style.backgroundColor = "rgb(220,255,255)" - div.style.padding = 1.5*mods.ui.padding - div.style.textAlign = 'left' - div.style.border = '2px solid' - div.style.borderRadius = '10px' - } - function add_menu(div,text,click) { - var textdiv = document.createElement('div') - textdiv.appendChild(document.createTextNode(text)) - textdiv.appendChild(document.createElement('br')) - textdiv.addEventListener('mouseover',function(evt){ - evt.target.style.fontWeight = 'bold'}) - textdiv.addEventListener('mouseout',function(evt){ - evt.target.style.fontWeight = 'normal'}) - textdiv.addEventListener('mousedown',click) - textdiv.addEventListener('touchend',click) - div.appendChild(textdiv) - } - // - // modules menu - // - function modules(evt) { - evt.preventDefault() - evt.stopPropagation() - document.body.removeChild(evt.target.parentNode) - var div = document.createElement('div') - make_menu(div) - set_prompt('modules') - // - // open server module - // - add_menu(div,'open server module',function(evt){ - function module_label(label) { - var div = document.createElement('div') - var i = document.createElement('i') - i.appendChild(document.createTextNode(label)) - div.appendChild(i) - div.appendChild(document.createElement('br')) - menu.appendChild(div) - } - function module_menu(label,module) { - var div = document.createElement('div') - div.appendChild( - document.createTextNode('\u00A0\u00A0\u00A0'+label)) - div.addEventListener('mouseover',function(evt){ - evt.target.style.fontWeight = 'bold'}) - div.addEventListener('mouseout',function(evt){ - evt.target.style.fontWeight = 'normal'}) - div.addEventListener('mousedown',function(evt){ - evt.preventDefault() - evt.stopPropagation() - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - var t = mods_transform() - mod_message_handler(module, - t.oy-t.ty+(evt.pageY-t.oy)/t.s, - t.ox-t.tx+(evt.pageX-t.ox)/t.s)}) - div.appendChild(document.createElement('br')) - menu.appendChild(div) - } - document.body.removeChild(evt.target.parentNode) - var menu = document.createElement('div') - make_menu(menu) - document.body.appendChild(menu) - menu.style.width = mods.ui.canvas - menu.style.height = mods.ui.canvas - menu.style.overflow = 'auto' - var req = new XMLHttpRequest() - req.responseType = 'text' - req.onreadystatechange = function() { - if (req.readyState == XMLHttpRequest.DONE) { - var str = req.response - eval(str) - } - } - req.open('GET','modules/index.js'+'?rnd='+Math.random()) - req.send() - }) - // - // open local module - // - add_menu(div,'open local module',function(evt){ - var t = mods_transform() - mods.ui.top = t.oy-t.ty+(evt.pageY-t.oy)/t.s - mods.ui.left = t.ox-t.tx+(evt.pageX-t.ox)/t.s - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - var file = document.getElementById('mod_input') - file.value = null - file.click() - }) - // - // open remote module - // - add_menu(div,'open remote module',function(evt){ - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - set_prompt('remotes not yet implemented') - }) - document.body.appendChild(div) - } - // - // programs menu - // - function programs(evt) { - evt.preventDefault() - evt.stopPropagation() - document.body.removeChild(evt.target.parentNode) - var div = document.createElement('div') - make_menu(div) - set_prompt('programs') - // - // open local program - // - add_menu(div,'open local program',function(evt){ - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - var file = document.getElementById('prog_input') - file.value = null - file.click() - }) - // - // open server program - // - add_menu(div,'open server program',function(evt){ - function program_label(label) { - var div = document.createElement('div') - var i = document.createElement('i') - i.appendChild(document.createTextNode(label)) - div.appendChild(i) - div.appendChild(document.createElement('br')) - menu.appendChild(div) - } - function program_menu(label,program) { - var div = document.createElement('div') - div.appendChild( - document.createTextNode('\u00A0\u00A0\u00A0'+label)) - div.addEventListener('mouseover',function(evt){ - evt.target.style.fontWeight = 'bold'}) - div.addEventListener('mouseout',function(evt){ - evt.target.style.fontWeight = 'normal'}) - div.addEventListener('mousedown',function(evt){ - evt.preventDefault() - evt.stopPropagation() - if (location.port == 80) - var uri = 'http://'+location.hostname - +'?program='+program - else - var uri = 'http://'+location.hostname+':' - +location.port+'?program='+program - set_prompt('<a href='+uri+'>program link</a>') - prog_message_handler(program) - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - }) - div.appendChild(document.createElement('br')) - menu.appendChild(div) - } - document.body.removeChild(evt.target.parentNode) - var menu = document.createElement('div') - make_menu(menu) - document.body.appendChild(menu) - menu.style.width = mods.ui.canvas - menu.style.height = mods.ui.canvas - menu.style.overflow = 'auto' - var req = new XMLHttpRequest() - req.responseType = 'text' - req.onreadystatechange = function() { - if (req.readyState == XMLHttpRequest.DONE) { - var str = req.response - eval(str) - } - } - req.open('GET','programs/index.js'+'?rnd='+Math.random()) - req.send() - }) - // - // open remote program - // - add_menu(div,'open remote program',function(evt){ - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - set_prompt('remotes not yet implemented') - }) - // - // save local program - // - add_menu(div,'save local program',function(evt){ - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - save_program() - }) - // - // save local page - // - add_menu(div,'save local page',function(evt){ - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - save_page() - }) - document.body.appendChild(div) - } - // - // edit menu - // - function edit(evt) { - evt.preventDefault() - evt.stopPropagation() - document.body.removeChild(evt.target.parentNode) - var div = document.createElement('div') - make_menu(div) - set_prompt('edit') - // - // cut - // - add_menu(div,'cut',function(evt){ - evt.preventDefault() - evt.stopPropagation() - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - if ((Object.keys(mods.ui.selected).length) == 0) { - set_prompt("nothing selected") - } - else { - for (var id in mods.ui.selected) { - var div = document.getElementById(id) - delete_module(id) - mods.ui.selected = {} - } - } - }) - // - // copy - // - add_menu(div,'copy',function(evt){ - evt.preventDefault() - evt.stopPropagation() - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - set_prompt('copy not yet implemented') - }) - // - // paste - // - add_menu(div,'paste',function(evt){ - evt.preventDefault() - evt.stopPropagation() - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - set_prompt('paste not yet implemented') - }) - document.body.appendChild(div) - } - // - // options menu - // - function options(evt) { - evt.preventDefault() - evt.stopPropagation() - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - var div = document.createElement('div') - make_menu(div) - set_prompt('options') - // - // view files - // - add_menu(div,'view files',function(evt){ - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - var win = window.open('files.html') - }) - document.body.appendChild(div) - // - // view project - // - add_menu(div,'view project',function(evt){ - document.body.removeChild(evt.target.parentNode) - mods.ui.menu = null - var win = window.open('https://gitlab.cba.mit.edu/pub/mods') - }) - document.body.appendChild(div) - } - }) -// -// prompt -// -document.body.appendChild(document.createTextNode(' ')) -var span = document.createElement('span') - span.setAttribute('id','logo') - span.style.display = 'inline-block' - span.style.verticalAlign = 'middle' - span.style.width = 20 - span.style.height = 20 - span.style.padding = mods.ui.padding - span.appendChild(logo(1)) - document.body.appendChild(span) -document.body.appendChild(document.createTextNode(' ')) -var span = document.createElement('span') - span.setAttribute('id','prompt') - span.style.display = 'inline-block' - span.style.verticalAlign = 'middle' - var innerspan = document.createElement('span') - span.appendChild(innerspan) - document.body.appendChild(span) -function logo(size) { - var x = 0 - var y = 2.8*size/3.8 - var svgNS = "http://www.w3.org/2000/svg" - var logo = document.createElementNS(svgNS,"svg") - logo.setAttributeNS("http://www.w3.org/2000/xmlns/", - "xmlns:xlink","http://www.w3.org/1999/xlink") - logo.setAttributeNS(null,'viewBox',"0 0 "+size+" "+size) - var new_rect = document.createElementNS(svgNS,"rect"); - new_rect.setAttribute("width",size/3.8) - new_rect.setAttribute("height",size/3.8) - new_rect.setAttribute("x",x) - new_rect.setAttribute("y",y) - new_rect.setAttribute("fill","blue") - logo.appendChild(new_rect) - var new_rect = document.createElementNS(svgNS,"rect"); - new_rect.setAttribute("width",size/3.8) - new_rect.setAttribute("height",size/3.8) - new_rect.setAttribute("x",x+1.4*size/3.8) - new_rect.setAttribute("y",y) - new_rect.setAttribute("fill","blue") - logo.appendChild(new_rect) - var new_rect = document.createElementNS(svgNS,"rect"); - new_rect.setAttribute("width",size/3.8) - new_rect.setAttribute("height",size/3.8) - new_rect.setAttribute("x",x+2.8*size/3.8) - new_rect.setAttribute("y",y) - new_rect.setAttribute("fill","blue") - logo.appendChild(new_rect) - var new_rect = document.createElementNS(svgNS, "rect"); - new_rect.setAttribute("width",size/3.8) - new_rect.setAttribute("height",size/3.8) - new_rect.setAttribute("x",x) - new_rect.setAttribute("y",y-1.4*size/3.8) - new_rect.setAttribute("fill","blue") - logo.appendChild(new_rect) - var new_rect = document.createElementNS(svgNS, "rect"); - new_rect.setAttribute("width", size / 3.8) - new_rect.setAttribute("height", size / 3.8) - new_rect.setAttribute("x", x + 2.8 * size / 3.8) - new_rect.setAttribute("y", y - 1.4 * size / 3.8) - new_rect.setAttribute("fill", "blue") - logo.appendChild(new_rect) - var new_rect = document.createElementNS(svgNS, "rect"); - new_rect.setAttribute("width", size / 3.8) - new_rect.setAttribute("height", size / 3.8) - new_rect.setAttribute("x", x + 1.4 * size / 3.8) - new_rect.setAttribute("y", y - 2.8 * size / 3.8) - new_rect.setAttribute("fill", "blue") - logo.appendChild(new_rect) - var new_rect = document.createElementNS(svgNS, "rect"); - new_rect.setAttribute("width", size / 3.8) - new_rect.setAttribute("height", size / 3.8) - new_rect.setAttribute("x", x + 2.8 * size / 3.8) - new_rect.setAttribute("y", y - 2.8 * size / 3.8) - new_rect.setAttribute("fill", "blue") - logo.appendChild(new_rect) - var new_circ = document.createElementNS(svgNS, "circle"); - new_circ.setAttribute("r", size / (2 * 3.8)) - new_circ.setAttribute("cx", x + size / (2 * 3.8)) - new_circ.setAttribute("cy", y + size / (2 * 3.8) - 2.8 * size / 3.8) - new_circ.setAttribute("fill", "red") - logo.appendChild(new_circ) - var new_circ = document.createElementNS(svgNS, "circle"); - new_circ.setAttribute("r", size / (2 * 3.8)) - new_circ.setAttribute("cx", x + size / (2 * 3.8) + 1.4 * size / 3.8) - new_circ.setAttribute("cy", y + size / (2 * 3.8) - 1.4 * size / 3.8) - new_circ.setAttribute("fill", "red") - logo.appendChild(new_circ) - return logo - } -set_prompt('right click/two finger/long press for menu; scroll for zoom, drag for pan') -// -// SVG canvas for drawing -// -var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg") - svg.style.position = 'absolute' - svg.style.backgroundColor = 'rgb(255,255,255)' - svg.style.top = mods.ui.header - svg.style.left = 0 - svg.style.zIndex = 0 - svg.style.overflow = 'visible' - svg.setAttribute('width',40) - svg.setAttribute('height',40) - svg.setAttribute('id','svg') - svg.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink") - document.body.appendChild(svg) -// -// link container -// -var svg = document.getElementById('svg') -var g = document.createElementNS('http://www.w3.org/2000/svg','g') - g.setAttribute('id','links') - svg.appendChild(g) -// -// file reading controls -// -var file = document.createElement('input') - file.setAttribute('type','file') - file.setAttribute('id','mod_input') - file.style.position = 'absolute' - file.style.left = 0 - file.style.top = 0 - file.style.width = 0 - file.style.height = 0 - file.style.opacity = 0 - file.addEventListener('change',function() { - mod_read_handler() - }) - document.body.appendChild(file) -var file = document.createElement('input') - file.setAttribute('type','file') - file.setAttribute('id','prog_input') - file.style.position = 'absolute' - file.style.left = 0 - file.style.top = 0 - file.style.width = 0 - file.style.height = 0 - file.style.opacity = 0 - file.addEventListener('change',function() { - prog_read_handler() - }) - document.body.appendChild(file) -// -// module container -// -var div = document.createElement('div') - div.setAttribute('id','modules') - document.body.appendChild(div) -// -// check for program load query -// -if (location.search.length > 0) { - var args = location.search.slice(1).split('&') - for (var a in args) { - var arg = args[a].split('=') - if (arg[0] == 'program') - prog_message_handler(arg[1]) - } - } -// -// program routines -// -function prog_read_handler(event) { - var file = document.getElementById('prog_input') - var file_reader = new FileReader() - file_reader.onload = prog_load_handler - file_reader.readAsText(file.files[0]) - mods.ui.progname = file.files[0].name - } -function prog_message_handler(filename) { - var req = new XMLHttpRequest() - req.responseType = 'text' - req.onreadystatechange = function() { - if (req.readyState == XMLHttpRequest.DONE) { - prog = JSON.parse(req.response) - prog_load(prog) - } - } - var index = filename.lastIndexOf('/') - if (index != -1) { - mods.ui.progname = filename.slice(index+1) - } - else - mods.ui.progname = filename - // - // send request, with random query to prevent caching - // - req.open('GET',filename+'?rnd='+Math.random()) - req.send() - } -function prog_load_handler(event) { - prog = JSON.parse(event.target.result) - prog_load(prog) - } -function prog_load(prog) { - // - // load modules - // - for (var idnumber in prog.modules) { - var module = prog.modules[idnumber] - var str = module.definition - try { - eval('var args = '+str) - } - catch (err) { - console.log(err.message) - return - } - args.definition = str - args.id = idnumber - var t = mods_transform() - var xw = t.ox-t.tx+(mods.ui.xstart-t.ox)/t.s - var yw = t.oy-t.ty+(mods.ui.ystart-t.oy)/t.s-mods.ui.header - args.top = parseFloat(module.top)+yw - args.left = parseFloat(module.left)+xw - args.filename = module.filename - add_module(args) - } - // - // load links - // - for (var linkid in prog.links) { - var str = prog.links[linkid] - eval('var link = '+str) - eval('var linksrc = '+link.source) - eval('var linkdst = '+link.dest) - var src = document.getElementById( - JSON.stringify({id:linksrc.id,type:linksrc.type,name:linksrc.name})) - var dst = document.getElementById( - JSON.stringify({id:linkdst.id,type:linkdst.type,name:linkdst.name})) - add_link(src,dst) - } - } -function save_program() { - set_prompt('program name? ') - get_prompt(mods.ui.progname,function(filename){ - mods.ui.progname = filename - var prog = {modules:{},links:[]} - var modules = document.getElementById('modules') - // - // save modules - // - for (var c = 0; c < modules.childNodes.length; ++c) { - var module = modules.childNodes[c] - var idnumber = module.id - prog.modules[idnumber] = { - definition:update_module_definition( - idnumber,module.dataset.definition), - top:module.dataset.top, - left:module.dataset.left, - filename: module.dataset.filename, - inputs:{}, - outputs:{} - } - } - // - // save links - // - var svg = document.getElementById('svg') - var links = svg.getElementById('links') - for (var l = 0; l < links.childNodes.length; ++l) { - var link = links.childNodes[l] - var linkid = link.id - prog.links.push(linkid) - } - // - // download - // - var text = JSON.stringify(prog) - var a = document.createElement('a') - a.setAttribute('href','data:text/plain;charset=utf-8,'+ - encodeURIComponent(text)) - a.setAttribute('download',filename) - a.style.display = 'none' - document.body.appendChild(a) - a.click() - document.body.removeChild(a) - }) - } -function save_page() { - set_prompt('page name? ') - get_prompt(mods.ui.progname+".html",function(filename){ - mods.ui.progname = filename - var prog = {modules:{},links:[]} - var modules = document.getElementById('modules') - // - // save modules - // - for (var c = 0; c < modules.childNodes.length; ++c) { - var module = modules.childNodes[c] - var idnumber = module.id - prog.modules[idnumber] = { - definition:update_module_definition( - idnumber,module.dataset.definition), - top:module.dataset.top, - left:module.dataset.left, - filename: module.dataset.filename, - inputs:{}, - outputs:{} - } - } - // - // save links - // - var svg = document.getElementById('svg') - var links = svg.getElementById('links') - for (var l = 0; l < links.childNodes.length; ++l) { - var link = links.childNodes[l] - var linkid = link.id - prog.links.push(linkid) - } - // - // read mods.js - // - var req = new XMLHttpRequest() - req.responseType = 'text' - req.onreadystatechange = function() { - if (req.readyState == XMLHttpRequest.DONE) { - // - // construct page - // - var str = req.response - var text ="<html>\n" - text += "<head><meta charset='utf-8'>\n" - text += "<title>mods</title>\n" - text += "</head>\n" - text += "<body link='black' alink='black' vlink='black'>\n" - text += "<"+"script"+">\n" - text += str - text += "var prog = JSON.parse(JSON.stringify("+JSON.stringify(prog)+"))\n" - text += "window.mods_prog_load(prog)\n" - text += "</"+"script"+">\n" - text += "</body>\n" - text += "</html>\n" - // - // download page - // - var a = document.createElement('a') - a.setAttribute('href','data:text/plain;charset=utf-8,'+ - encodeURIComponent(text)) - a.setAttribute('download',filename) - a.style.display = 'none' - document.body.appendChild(a) - a.click() - document.body.removeChild(a) - } - } - // - // send request, with random query to prevent caching - // - req.open('GET','js/mods.js'+'?rnd='+Math.random()) - req.send() - }) - } -// -// add program load to window -// -window.mods_prog_load = function(prog) { - prog_load(prog) - } -// -// module routines -// -function mod_read_handler(event) { - var file = document.getElementById('mod_input') - var file_reader = new FileReader() - file_reader.onload = mod_load_handler - file_reader.readAsText(file.files[0]) - } -function mod_message_handler(filename,top,left) { - var req = new XMLHttpRequest() - req.responseType = 'text' - req.onreadystatechange = function() { - if (req.readyState == XMLHttpRequest.DONE) { - var str = req.response - try { - eval('var args = '+str) - } - catch (err) { - console.log(err.message) - return - } - args.definition = str - args.id = String(Math.random()) - args.top = top - args.left = left - args.filename = filename - add_module(args) - } - } - // - // send request, with random query to prevent caching - // - req.open('GET',filename+'?rnd='+Math.random()) - req.send() - } -function mod_load_handler(event) { - str = event.target.result - try { - eval('var args = '+str) - } - catch (err) { - console.log(err.message) - return - } - args.definition = str - args.id = String(Math.random()) - args.top = mods.ui.top - args.left = mods.ui.left - args.filename = "" - var div = add_module(args) - return(div) - } -function add_module(args) { - var idnumber = args.id - mods.mod[idnumber] = args.mod - var modules = document.getElementById('modules') - // - // container - // - var container = document.createElement('div') - container.setAttribute("id",idnumber) - container.style.position = "absolute" - container.style.top = args.top - container.style.left = args.left - container.dataset.top = args.top - container.dataset.left = args.left - container.dataset.filename = args.filename - container.dataset.name = args.name - container.style.zIndex = 0 - container.style.width = window.innerWidth - container.dataset.definition = args.definition - modules.appendChild(container) - // - // name - // - var divname = document.createElement('div') - divname.appendChild(document.createTextNode(args.name)) - divname.addEventListener('mouseover',name_over) - divname.addEventListener('mouseout',name_out) - divname.addEventListener('mousedown',name_mousedown) - divname.addEventListener('touchstart',name_touchdown) - divname.style.backgroundColor = "rgb(210,240,210)" - divname.style.padding = 1.5*mods.ui.padding - divname.style.position = "absolute" - divname.style.cursor = 'default' - divname.style.top = 0 - divname.style.left = 0 - divname.style.textAlign = 'center' - divname.style.border = '2px solid' - divname.style.borderRadius = '10px' - container.appendChild(divname) - // - // controls - // - var divctrl = document.createElement('div') - var editspan = document.createElement('span') - editspan.innerHTML = 'edit' - editspan.style.fontWeight = 'normal' - editspan.addEventListener('mouseover',function(event){ - set_prompt('click to edit') - editspan.style.fontWeight = 'bold'}) - editspan.addEventListener('mouseout',function(event){ - set_prompt('') - editspan.style.fontWeight = 'normal'}) - editspan.addEventListener('mousedown',edit_module) - divctrl.appendChild(editspan) - var delspan = document.createElement('span') - delspan.innerHTML = ' delete ' - delspan.addEventListener('mouseover',function(event){ - set_prompt('click to delete') - delspan.style.fontWeight = 'bold'}) - delspan.addEventListener('mouseout',function(event){ - set_prompt('') - delspan.style.fontWeight = 'normal'}) - delspan.addEventListener('mousedown',function(event){ - delete_module(event.target.parentNode.parentNode.id)}) - divctrl.appendChild(delspan) - divctrl.style.backgroundColor = "rgb(240,220,220)" - divctrl.style.padding = mods.ui.padding - divctrl.style.position = "absolute" - divctrl.style.cursor = 'default' - divctrl.style.top = divname.clientHeight - divctrl.style.left = 0 - divctrl.style.textAlign = 'center' - divctrl.style.border = '2px solid' - divctrl.style.borderRadius = '10px' - container.appendChild(divctrl) - divctrl.style.left = divname.clientWidth/2-divctrl.clientWidth/2 - // - // interface - // - var divint = document.createElement('div') - divint.style.backgroundColor = "rgb(240,240,240)" - divint.style.padding = mods.ui.padding - divint.style.position = "absolute" - divint.style.top = divname.clientHeight+divctrl.clientHeight - divint.style.textAlign = 'center' - divint.style.border = '2px solid' - divint.style.borderRadius = '10px' - divint.setAttribute('id',JSON.stringify({id:idnumber,type:'interface'})) - divint.dataset.id = idnumber - divint.dataset.divNameSize = divname.clientWidth - args.interface(divint) - container.appendChild(divint) - divint.style.left = divname.clientWidth/2-divint.clientWidth/2 - // - // inputs - // - var divin = document.createElement('div') - divin.setAttribute('id',JSON.stringify({id:idnumber,type:'inputs'})) - var b = document.createElement('b') - b.appendChild(document.createTextNode('inputs')) - divin.appendChild(b) - divin.style.backgroundColor = "rgb(240,240,210)" - divin.style.padding = mods.ui.padding - divin.style.paddingLeft = '2px' - divin.style.position= "absolute" - divin.style.top = divname.clientHeight+divctrl.clientHeight - divin.style.textAlign = 'left' - divin.style.border = '2px solid' - divin.style.borderRadius = '10px' - divin.setAttribute('id',JSON.stringify({id:idnumber,type:'inputs'})) - divin.style.cursor = 'default' - divin.addEventListener('mousedown',nothing) - divin.addEventListener('touchstart',nothing) - divin.addEventListener('mouseup',nothing) - divin.addEventListener('touchend',nothing) - for (var v in args.inputs) { - var div = document.createElement('div') - if (args.inputs[v].label != undefined) - div.innerHTML += args.inputs[v].label - else - div.innerHTML += v - if (args.inputs[v].type != '') - div.innerHTML += ' ('+args.inputs[v].type+')' - div.setAttribute('id',JSON.stringify({id:idnumber,type:'inputs',name:v})) - div.addEventListener('mouseover',input_over) - div.addEventListener('mouseout',input_out) - div.addEventListener('mousedown',input_mousedown) - div.addEventListener('touchstart',input_touchdown) - div.dataset.links = JSON.stringify([]) - div.dataset.name = v - divin.appendChild(div) - div.dataset.id = JSON.stringify( - {id:idnumber,type:'input',name:v, - rnd:Math.random()}) // randomize for unique events - window.addEventListener(div.dataset.id,args.inputs[v].event) - } - container.appendChild(divin) - if ((Object.keys(args.inputs).length) == 0) - divin.style.visibility = 'hidden' - divin.style.left = divname.clientWidth/2 - -divint.clientWidth/2-divin.clientWidth - for (var i = 1; i < divin.childNodes.length; ++i) { - divin.childNodes[i].dataset.dx = divin.offsetLeft - +divin.childNodes[i].offsetLeft - divin.childNodes[i].dataset.dy = divin.offsetTop - +divin.childNodes[i].offsetTop - +divin.childNodes[i].offsetHeight/2 - } - // - // outputs - // - var divout = document.createElement('div') - divout.setAttribute('id',JSON.stringify({id:idnumber,type:'outputs'})) - var b = document.createElement('b') - b.appendChild(document.createTextNode('outputs')) - divout.appendChild(b) - divout.style.backgroundColor = "rgb(240,240,210)" - divout.style.padding = mods.ui.padding - divout.style.paddingRight = '2px' - divout.style.position = "absolute" - divout.style.top = divname.clientHeight+divctrl.clientHeight - divout.style.textAlign = 'right' - divout.addEventListener('mousedown',nothing) - divout.style.border = '2px solid' - divout.style.borderRadius = '10px' - divout.setAttribute('id',JSON.stringify({id:idnumber,type:'outputs'})) - divout.style.cursor = 'default' - divout.addEventListener('touchstart',nothing) - divout.addEventListener('mouseup',nothing) - divout.addEventListener('touchend',nothing) - for (var v in args.outputs) { - var div = document.createElement('div') - if (args.outputs[v].label != undefined) - div.innerHTML += args.outputs[v].label - else - div.innerHTML += v - if (args.outputs[v].type != '') - div.innerHTML += ' ('+args.outputs[v].type+')' - div.setAttribute('id',JSON.stringify({id:idnumber,type:'outputs',name:v})) - div.addEventListener('mouseover',output_over) - div.addEventListener('mouseout',output_out) - div.addEventListener('mousedown',output_mousedown) - div.addEventListener('touchstart',output_touchdown) - div.dataset.links = JSON.stringify([]) - div.dataset.name = v - divout.appendChild(div) - div.dataset.id = JSON.stringify( - {id:idnumber,type:'output',name:v, - rnd:Math.random()}) // randomize for unique events - window.addEventListener(div.dataset.id,args.outputs[v].event) - } - container.appendChild(divout) - if ((Object.keys(args.outputs).length) == 0) - divout.style.visibility = 'hidden' - divout.style.left = divname.clientWidth/2 - +divint.clientWidth/2 - for (var i = 1; i < divout.childNodes.length; ++i) { - divout.childNodes[i].dataset.dx = divout.offsetLeft - +divout.childNodes[i].offsetLeft - +divout.childNodes[i].offsetWidth - divout.childNodes[i].dataset.dy = divout.offsetTop - +divout.childNodes[i].offsetTop - +divout.childNodes[i].offsetHeight/2 - } - // - // initialization - // - args.init() - // - // resize to contents - // - container.style.width = divint.clientWidth+divin.clientWidth+divout.clientWidth - mods.fit(divint) - // - // return container - // - return(container) - } -function delete_module(idnumber) { - // - // delete links - // - var ins = document.getElementById( - JSON.stringify({id:idnumber,type:'inputs'})) - var outs = document.getElementById( - JSON.stringify({id:idnumber,type:'outputs'})) - for (var i = 1; i < ins.childNodes.length; ++i) { - var links = JSON.parse(ins.childNodes[i].dataset.links) - for (var l in links) - delete_link(links[l]) - } - for (var i = 1; i < outs.childNodes.length; ++i) { - var links = JSON.parse(outs.childNodes[i].dataset.links) - for (var l in links) - delete_link(links[l]) - } - // - // delete container - // - var modules = document.getElementById('modules') - var container = document.getElementById(idnumber) - modules.removeChild(container) - // - // clear prompt - // - set_prompt('') - } -function update_module_definition(id) { - // - // get definition - // - var module = document.getElementById(id) - var def = module.dataset.definition - // - // check for mod - // - if (mods.mod[id] == undefined) - return def - // - // split definition - // - var lines = def.split('\n') - // - // find init function - // - var line = 0 - while (line < lines.length) { - if (lines[line].indexOf("var init") == 0) - break - line += 1 - } - // - // read initializations up to inputs function - // - while (line < lines.length) { - if (lines[line].indexOf(".value =") != -1) { - var start = 4+lines[line].indexOf("mod.") - var end = lines[line].indexOf(".value") - var key = lines[line].slice(start,end) - var value = mods.mod[id][key]['value'] - if (value.indexOf('\n') != -1) - value = value.replace(/\n/g,"\\n") - lines[line] = " mod."+key+".value = '"+value+"'" - } - else if (lines[line].indexOf(".checked =") != -1) { - var start = 4+lines[line].indexOf("mod.") - var end = lines[line].indexOf(".checked") - var key = lines[line].slice(start,end) - var value = mods.mod[id][key]['checked'] - lines[line] = " mod."+key+".checked = "+value - } - if (lines[line].indexOf("var inputs") == 0) - break - line += 1 - } - return(lines.join('\n')) - } -function edit_module(evt) { - var mod = evt.target.parentNode.parentNode - var idnumber = mod.id - var def = update_module_definition(idnumber) - // - // open edit window - // - var top = mod.dataset.top - var left = mod.dataset.left - var name = mod.dataset.name - var filename = mod.dataset.filename - var fontsize = 100 - var win = window.open('') - var file = document.createElement('input') - file.setAttribute('type','file') - file.setAttribute('id','edit_module_file') - file.style.position = 'absolute' - file.style.left = 0 - file.style.top = 0 - file.style.width = 0 - file.style.height = 0 - file.style.opacity = 0 - file.addEventListener('change',function() { - edit_module_read_handler() - }) - win.document.body.appendChild(file) - function edit_module_read_handler() { - var file = win.document.getElementById('edit_module_file') - var file_reader = new FileReader() - file_reader.onload = edit_module_load_handler - file_reader.readAsText(file.files[0]) - } - function edit_module_load_handler(event) { - str = event.target.result - var text = win.document.getElementById('edit_module_text') - text.value = str - update_module(idnumber) - win.close() - } - if (filename != "undefined" && filename != "") { - var btn = document.createElement('button') - btn.appendChild(document.createTextNode('reload from server')) - btn.style.padding = mods.ui.padding - btn.style.margin = 1 - btn.addEventListener('click',function(){ - var req = new XMLHttpRequest() - req.responseType = 'text' - req.onreadystatechange = function() { - if (req.readyState == XMLHttpRequest.DONE) { - text.value = req.response - update_module(idnumber) - } - } - req.open('GET',filename+'?rnd='+Math.random()) - req.send() - win.close() - }) - win.document.body.appendChild(btn) - } - var btn = document.createElement('button') - btn.appendChild(document.createTextNode('load from file')) - btn.style.padding = mods.ui.padding - btn.style.margin = 1 - btn.addEventListener('click',function(){ - var file = win.document.getElementById('edit_module_file') - file.value = null - file.click() - }) - win.document.body.appendChild(btn) - var btn = document.createElement('button') - btn.appendChild(document.createTextNode('update and close')) - btn.style.padding = mods.ui.padding - btn.style.margin = 1 - btn.addEventListener('click',function(){ - update_module(idnumber) - win.close() - }) - win.document.body.appendChild(btn) - var btn = document.createElement('button') - btn.appendChild(document.createTextNode('update')) - btn.style.padding = mods.ui.padding - btn.style.margin = 1 - btn.addEventListener('click',function(){ - update_module(idnumber) - }) - win.document.body.appendChild(btn) - var btn = document.createElement('button') - btn.appendChild(document.createTextNode('close')) - btn.style.padding = mods.ui.padding - btn.style.margin = 1 - btn.addEventListener('click',function(){ - win.close() - }) - win.document.body.appendChild(btn) - var btn = document.createElement('button') - btn.appendChild(document.createTextNode('save')) - btn.style.padding = mods.ui.padding - btn.style.margin = 1 - btn.addEventListener('click',function(){ - var a = document.createElement('a') - a.setAttribute('href','data:text/plain;charset=utf-8,'+ - encodeURIComponent(text.value)) - a.setAttribute('download',name) - a.style.display = 'none' - document.body.appendChild(a) - a.click() - document.body.removeChild(a) - }) - win.document.body.appendChild(btn) - var btn = document.createElement('button') - btn.appendChild(document.createTextNode('increase font')) - btn.style.padding = mods.ui.padding - btn.style.margin = 1 - btn.addEventListener('click',function(){ - fontsize *= 1.2 - text.style.fontSize = fontsize+'%' - }) - win.document.body.appendChild(btn) - var btn = document.createElement('button') - btn.appendChild(document.createTextNode('decrease font')) - btn.style.padding = mods.ui.padding - btn.style.margin = 1 - btn.addEventListener('click',function(){ - fontsize /= 1.2 - text.style.fontSize = fontsize+'%' - }) - win.document.body.appendChild(btn) - win.document.body.appendChild(document.createElement('br')) - var text = document.createElement('textarea') - text.setAttribute('id','edit_module_text') - text.style.width = '100%' - text.style.height= '100%' - text.value = def - win.document.body.appendChild(text) - function reload_module(idnumber) { - } - function update_module(idnumber) { - // - // save links - // - var ins = document.getElementById( - JSON.stringify({id:idnumber,type:'inputs'})) - var inlinks = [] - for (var i = 1; i < ins.childNodes.length; ++i) { - var links = JSON.parse(ins.childNodes[i].dataset.links) - for (var l in links) - inlinks.push(links[l]) - } - var outs = document.getElementById( - JSON.stringify({id:idnumber,type:'outputs'})) - var outlinks = [] - for (var i = 1; i < outs.childNodes.length; ++i) { - var links = JSON.parse(outs.childNodes[i].dataset.links) - for (var l in links) - outlinks.push(links[l]) - } - // - // delete module - // - delete_module(idnumber) - // - // add module - // - var def = text.value - try { - eval('var args = '+def) - } - catch (err) { - console.log(err.message) - return - } - args.definition = def - args.id = idnumber - args.top = top - args.left = left - args.filename = filename - add_module(args) - // - // add links - // - for (var l in inlinks) { - eval('var link = '+inlinks[l]) - eval('var linksrc = '+link.source) - eval('var linkdst = '+link.dest) - var src = document.getElementById( - JSON.stringify( - {id:linksrc.id,type:linksrc.type,name:linksrc.name})) - var dst = document.getElementById( - JSON.stringify( - {id:linkdst.id,type:linkdst.type,name:linkdst.name})) - add_link(src,dst) - } - for (var l in outlinks) { - eval('var link = '+outlinks[l]) - eval('var linksrc = '+link.source) - eval('var linkdst = '+link.dest) - var src = document.getElementById( - JSON.stringify( - {id:linksrc.id,type:linksrc.type,name:linksrc.name})) - var dst = document.getElementById( - JSON.stringify( - {id:linkdst.id,type:linkdst.type,name:linkdst.name})) - add_link(src,dst) - } - } - } -// -// UI routines -// -function set_prompt(txt) { - var span = document.getElementById('prompt') - span.childNodes[0].innerHTML = ' '+txt - } -function get_prompt(txt,fn) { - var div = document.getElementById('prompt') - if (div.childNodes.length > 2) - // - // already getting a prompt - // - return - var text = document.createElement('input') - text.type = 'text' - text.size = 20 - text.value = txt - text.addEventListener('keydown',function(evt){ - if (evt.key == 'Enter') { - var div = document.getElementById('prompt') - div.removeChild(div.childNodes[1]) - div.removeChild(div.childNodes[1]) - set_prompt('') - fn(text.value) - } - }) - div.appendChild(text) - div.appendChild(document.createTextNode(' (enter)')) - text.focus() - } -function nothing(evt) { - evt.preventDefault() - evt.stopPropagation() - } -// -// link routines -// -mods.add_link = function(src,dst) { - add_link(src,dst) - } -function add_link(src,dst) { - // - // link order from out to in - // - if (src.id.indexOf('outputs') == -1) { - var tmp = src - src = dst - dst = tmp - } - // - // check if link exists - // - var id = JSON.stringify({source:src.id,dest:dst.id}) - var link = document.getElementById(id) - if (link != null) { - // - // yes, remove it and return - // - delete_link(id) - return - } - // - // no, add link - // - var links = JSON.parse(src.dataset.links) - links.push(id) - src.dataset.links = JSON.stringify(links) - var links = JSON.parse(dst.dataset.links) - links.push(id) - dst.dataset.links = JSON.stringify(links) - // - // draw link - // - xsrc = src.parentNode.parentNode.offsetLeft - +parseFloat(src.dataset.dx) - ysrc = src.parentNode.parentNode.offsetTop - +parseFloat(src.dataset.dy) - -mods.ui.header - xdst = dst.parentNode.parentNode.offsetLeft - +parseFloat(dst.dataset.dx) - ydst = dst.parentNode.parentNode.offsetTop - +parseFloat(dst.dataset.dy) - -mods.ui.header - var links = document.getElementById('links') - var path = document.createElementNS('http://www.w3.org/2000/svg','path') - path.setAttribute('id',id) - path.setAttribute('d','M'+xsrc+','+ysrc+' C'+(xsrc+mods.ui.bezier)+',' - +ysrc+' '+(xdst-mods.ui.bezier)+','+ydst+' '+xdst+','+ydst) - path.setAttribute('fill','none') - path.setAttribute('stroke','rgb(0,0,128)') - path.setAttribute('stroke-width',3) - links.appendChild(path) - /* - // - // don't trigger link - // - eval('var evtid = '+src.id) - evtid.type = 'output' - var evtstr = JSON.stringify(evtid) - var evt = new CustomEvent(evtstr) - window.dispatchEvent(evt) - */ - } -function delete_link(linkid) { - // - // delete a link - // - var links = document.getElementById('links') - links.removeChild(document.getElementById(linkid)) - link = JSON.parse(linkid) - src = document.getElementById(link.source) - dst = document.getElementById(link.dest) - var links = JSON.parse(src.dataset.links) - var index = links.indexOf(linkid) - links.splice(index,1) - src.dataset.links = JSON.stringify(links) - var links = JSON.parse(dst.dataset.links) - var index = links.indexOf(linkid) - links.splice(index,1) - dst.dataset.links = JSON.stringify(links) - } -function draw_links(idnumber,color) { - // - // draw a module's links - // - var ins = document.getElementById( - JSON.stringify({id:idnumber,type:'inputs'})) - var outs = document.getElementById( - JSON.stringify({id:idnumber,type:'outputs'})) - for (var i = 1; i < ins.childNodes.length; ++i) { - var links = JSON.parse(ins.childNodes[i].dataset.links) - for (var l in links) - draw_link(links[l],color) - } - for (var i = 1; i < outs.childNodes.length; ++i) { - var links = JSON.parse(outs.childNodes[i].dataset.links) - for (var l in links) - draw_link(links[l],color) - } - } -function draw_link(id,color) { - // - // draw a link - // - var link = JSON.parse(id) - src = document.getElementById(link.source) - dst = document.getElementById(link.dest) - var path = document.getElementById(id) - xsrc = src.parentNode.parentNode.offsetLeft - +parseFloat(src.dataset.dx) - ysrc = src.parentNode.parentNode.offsetTop - +parseFloat(src.dataset.dy) - -mods.ui.header - xdst = dst.parentNode.parentNode.offsetLeft - +parseFloat(dst.dataset.dx) - ydst = dst.parentNode.parentNode.offsetTop - +parseFloat(dst.dataset.dy) - -mods.ui.header - path.setAttribute('d','M'+xsrc+','+ysrc+' C'+(xsrc+mods.ui.bezier)+',' - +ysrc+' '+(xdst-mods.ui.bezier)+','+ydst+' '+xdst+','+ydst) - path.setAttribute('stroke',color) - } -// -// mods routines to be called from modules -// -mods.fit = function(div) { - // - // fit a module - // - div.style.left = div.dataset.divNameSize/2-div.clientWidth/2 - var divin = document.getElementById( - JSON.stringify( - {id:div.dataset.id,type:'inputs'})) - divin.style.left = div.dataset.divNameSize/2-div.clientWidth/2-divin.clientWidth - var divout = document.getElementById( - JSON.stringify( - {id:div.dataset.id,type:'outputs'})) - divout.style.left = div.dataset.divNameSize/2+div.clientWidth/2 - } -mods.output = function(mod,varname,val) { - // - // send module outputs - // - var div = mod.div - var key = JSON.parse(div.id) - var idnumber = key.id - var out = document.getElementById( - JSON.stringify( - {id:idnumber,type:'outputs',name:varname})) - var links = JSON.parse(out.dataset.links) - for (var l in links) { - var link = JSON.parse(links[l]) - var dest = JSON.parse(link.dest) - var divin = document.getElementById(JSON.stringify( - {id:dest.id,type:'inputs',name:dest.name})) - var evt = new CustomEvent(divin.dataset.id,{detail:val}) - window.dispatchEvent(evt) - } - } -// -// module mod-ification calls -// -mods.module_create = function(args) { - var event = {target:{result:args}} - var div = mod_load_handler(event) - return(div) - } -mods.module_delete = function(id) { - delete_module(id) - } -mods.module_id = function(div) { - return div.parentNode.id - } -mods.module_left = function(id) { - var module = document.getElementById(id) - return (parseInt(module.style.left)) - } -mods.module_move = function(id,dx,dy) { - var module = document.getElementById(id) - var top = parseInt(module.style.top) - module.style.top = top+dy - module.dataset.top = top+dy - var left = parseInt(module.style.left) - module.style.left = left+dx - module.dataset.left = left+dx - draw_links(id,mods.ui.link_color) - } -mods.module_inputs = function(id,index) { - var module = document.getElementById(id) - var inputs = document.getElementById( - JSON.stringify({id:id,type:'inputs'})) - console.log(inputs.childNodes[index]) - } -mods.module_outputs = function(id,index) { - var module = document.getElementById(id) - var outputs = document.getElementById( - JSON.stringify({id:id,type:'outputs'})) - console.log(outputs.childNodes[index]) - } -mods.module_position = function(id,x,y) { - var module = document.getElementById(id) - var top = parseInt(module.style.top) - module.style.top = y - module.dataset.top = y - var left = parseInt(module.style.left) - module.style.left = x - module.dataset.left = x - draw_links(id,mods.ui.link_color) - } -mods.module_top = function(id) { - var module = document.getElementById(id) - return (parseInt(module.style.top)) - } -mods.module_width = function(id) { - var module = document.getElementById(id) - return (parseInt(module.clientWidth)) - } -// -// input event handlers -// -function input_over(evt) { - evt.target.style.fontWeight = 'bold' - var links = JSON.parse(evt.target.dataset.links) - for (var l in links) - draw_link(links[l],mods.ui.link_highlight) - if (mods.ui.source == null) - set_prompt('click to link') - } -function input_out(evt) { - evt.target.style.fontWeight = 'normal' - var links = JSON.parse(evt.target.dataset.links) - for (var l in links) - draw_link(links[l],mods.ui.link_color) - if (mods.ui.source == null) - set_prompt('') - } -function input_mousedown(evt) { - if (mods.ui.source == null) { - mods.ui.source = evt.target - set_prompt('variable to link/unlink to?') - } - else { - add_link(mods.ui.source,evt.target) - set_prompt('') - mods.ui.source = null - } - } -function input_touchdown(evt) { - if (mods.ui.source == null) { - mods.ui.source = evt.target - set_prompt('variable to link/unlink to?') - } - else { - add_link(mods.ui.source,evt.target) - set_prompt('') - mods.ui.source = null - } - } -// -// output event handlers -// -function output_over(evt) { - evt.target.style.fontWeight = 'bold' - var links = JSON.parse(evt.target.dataset.links) - for (var l in links) - draw_link(links[l],mods.ui.link_highlight) - if (mods.ui.source == null) - set_prompt('click to link') - } -function output_out(evt) { - evt.target.style.fontWeight = 'normal' - var links = JSON.parse(evt.target.dataset.links) - for (var l in links) - draw_link(links[l],mods.ui.link_color) - if (mods.ui.source == null) - set_prompt('') - } -function output_mousedown(evt) { - if (mods.ui.source == null) { - mods.ui.source = evt.target - set_prompt('variable to link/unlink to?') - } - else { - add_link(mods.ui.source,evt.target) - set_prompt('') - mods.ui.source = null - } - } -function output_touchdown(evt) { - if (mods.ui.source == null) { - mods.ui.source = evt.target - set_prompt('variable to link/unlink to?') - } - else { - add_link(mods.ui.source,evt.target) - set_prompt('') - mods.ui.source = null - } - } -// -// name event handlers -// -function name_over(evt) { - evt.target.style.fontWeight = 'bold' - if (mods.ui.source == null) - set_prompt('click and drag to move') - } -function name_out(evt) { - evt.target.style.fontWeight = 'normal' - if (mods.ui.source == null) - set_prompt('') - } -function name_mousedown(evt) { - evt.preventDefault() - evt.stopPropagation() - var div = document.getElementById(evt.target.parentNode.id) - div.style.zIndex = 1 - mods.ui.xstart = evt.clientX - mods.ui.ystart = evt.clientY - mods.ui.selected[evt.target.parentNode.id] = true - window.addEventListener('mousemove',name_mousemove) - window.addEventListener('mouseup',name_mouseup) - } -function name_mousemove(evt) { - evt.preventDefault() - evt.stopPropagation() - var t = mods_transform() - for (var id in mods.ui.selected) { - var div = document.getElementById(id) - var dx = (evt.clientX-mods.ui.xstart)/t.s - var dy = (evt.clientY-mods.ui.ystart)/t.s - var newleft = parseFloat(div.dataset.left)+dx - var newtop = parseFloat(div.dataset.top)+dy - div.style.left = newleft+'px' - div.style.top = newtop+'px' - draw_links(id,mods.ui.link_color) - } - } -function name_mouseup(evt) { - evt.preventDefault() - evt.stopPropagation() - var t = mods_transform() - for (var id in mods.ui.selected) { - var div = document.getElementById(id) - div.style.zIndex = 0 - div.childNodes[0].style.fontWeight = 'normal' - var dx = (evt.clientX-mods.ui.xstart)/t.s - var dy = (evt.clientY-mods.ui.ystart)/t.s - div.dataset.left = parseFloat(div.dataset.left)+dx - div.dataset.top = parseFloat(div.dataset.top)+dy - window.removeEventListener('mousemove',name_mousemove) - window.removeEventListener('mouseup',name_mouseup) - } - mods.ui.selected = {} - } -function name_touchdown(evt) { - evt.preventDefault() - evt.stopPropagation() - var div = document.getElementById(evt.target.parentNode.id) - div.style.zIndex = 1 - mods.ui.xstart = evt.changedTouches[0].pageX - mods.ui.ystart = evt.changedTouches[0].pageY - mods.ui.selected[evt.target.parentNode.id] = true - window.addEventListener('touchmove',name_touchmove) - window.addEventListener('touchend',name_touchup) - } -function name_touchmove(evt) { - evt.preventDefault() - evt.stopPropagation() - var t = mods_transform() - for (var id in mods.ui.selected) { - var div = document.getElementById(id) - var dx = (evt.changedTouches[0].pageX-mods.ui.xstart)/t.s - var dy = (evt.changedTouches[0].pageY-mods.ui.ystart)/t.s - var newleft = parseFloat(div.dataset.left)+dx - var newtop = parseFloat(div.dataset.top)+dy - div.style.left = newleft+'px' - div.style.top = newtop+'px' - draw_links(id,mods.ui.link_color) - } - } -function name_touchup(evt) { - evt.preventDefault() - evt.stopPropagation() - var t = mods_transform() - for (var id in mods.ui.selected) { - var div = document.getElementById(id) - div.style.zIndex = 0 - var dx = (evt.changedTouches[0].pageX-mods.ui.xstart)/t.s - var dy = (evt.changedTouches[0].pageY-mods.ui.ystart)/t.s - div.dataset.left = parseFloat(div.dataset.left)+dx - div.dataset.top = parseFloat(div.dataset.top)+dy - window.removeEventListener('touchmove',name_touchmove) - window.removeEventListener('touchend',name_touchup) - } - mods.ui.selected = {} - } -})() +// +// mods.js +// +// Neil Gershenfeld +// (c) Massachusetts Institute of Technology 2018 +// +// This work may be reproduced, modified, distributed, performed, and +// displayed for any purpose, but must acknowledge the mods +// project. Copyright is retained and must be preserved. The work is +// provided as is; no warranty is provided, and users accept all +// liability. +// +// closure +// +(function(){ +// +// globals +// +var mods = {} +mods.mod = {} +mods.globals = {} +mods.ui = {source:null, + progname:'', + padding:7, + bezier:100, + canvas:250, + rows:5, + cols:20, + link_color:'rgb(0,0,128)', + link_highlight:'rgb(255,0,0)', + header:50, + selected:{}, + mousedown:null, + menu:null, + top:null, + left:null, + xstart:null, + ystart:null, + xtrans:null, + ytrans:null + } +// +// UI +// +document.body.style.overflow = "hidden" +function mods_transform() { + var transform = document.body.style.transform + var m = new DOMMatrix(getComputedStyle(document.body).transform) + var s = m.m11 + var tx = m.m41/s + var ty = m.m42/s + var origin = document.body.style.transformOrigin + var pxx = origin.indexOf('px') + var ox = parseFloat(origin.slice(0,pxx)) + var pxy = origin.indexOf('px',pxx+2) + var oy = parseFloat(origin.slice(pxx+2,pxy)) + return({s:s,tx:tx,ty:ty,ox:ox,oy:oy}) + } +document.body.style.transform = 'scale(1) translate(0px,0px)' +document.body.style.transformOrigin = '0px 0px' +// +// scroll wheel event +// +window.addEventListener('wheel',function(evt) { + /* + (xw+tx-ox)*s+ox = xs + xw = ox-tx+(xs-ox)/s + (xw+tx0-ox0)*s+ox0 = (xw+tx1-ox1)*s+ox1 + (tx0-ox0)*s+ox0 = (tx1-ox1)*s+ox1 + tx0+(ox1-ox0)+(ox0-ox1)/s = tx1 + tx0+(ox1-ox0)*(1-1/s) = tx1 + */ + var el = document.elementFromPoint(evt.pageX,evt.pageY) + if ((el.tagName == "HTML") || (el.tagName == "BODY")) { + set_prompt('scroll to zoom') + evt.preventDefault() + evt.stopPropagation() + var t = mods_transform() + if (evt.deltaY > 0) + var scale = t.s*1.1 + else + var scale = t.s*0.9 + var tx = t.tx+(evt.pageX-t.ox)*(1-1/t.s) + var ty = t.ty+(evt.pageY-t.oy)*(1-1/t.s) + document.body.style.transform = `scale(${scale}) translate(${tx}px,${ty}px)` + document.body.style.transformOrigin = `${evt.pageX}px ${evt.pageY}px` + } + }) +// +// body mouse events +// +window.addEventListener('mousedown',function(evt) { + // + // get element mouse is over + // + var el = document.elementFromPoint(evt.pageX,evt.pageY) + // + // check if on body + // + if ((el.tagName == "HTML") || (el.tagName == "BODY")) { + // + // remember button + // + mods.ui.mousedown = evt.button + if (mods.ui.mousedown == 0) { + set_prompt('left-drag to pan, right-drag to select') + if (mods.ui.menu != null) { + document.body.removeChild(mods.ui.menu) + mods.ui.menu = null + } + } + else if (mods.ui.mousedown == 2) { + set_prompt('menu; left-drag to pan, right-drag to select') + } + // + // remember position + // + var t = mods_transform() + mods.ui.xstart = evt.pageX + mods.ui.ystart = evt.pageY + mods.ui.xtrans = t.tx + mods.ui.ytrans = t.ty + } + }) +window.addEventListener('mousemove',function(evt) { + // + // mouse move + // + if (mods.ui.mousedown != null) { + evt.preventDefault() + evt.stopPropagation() + var t = mods_transform() + if (mods.ui.mousedown == 0) { + // + // pan on left drag + // + xtrans = mods.ui.xtrans+(evt.pageX-mods.ui.xstart)/t.s + ytrans = mods.ui.ytrans+(evt.pageY-mods.ui.ystart)/t.s + document.body.style.transform = `scale(${t.s}) translate(${xtrans}px,${ytrans}px)` + } + else if (mods.ui.mousedown == 2) { + // + // select on right drag + // + var rect = document.getElementById('svgrect') + if (rect == undefined) { + // + // start dragging + // + if (mods.ui.menu != null) { + document.body.removeChild(mods.ui.menu) + mods.ui.menu = null + } + set_prompt('right-drag to select') + var t = mods_transform() + var rect = document.createElementNS('http://www.w3.org/2000/svg','rect') + rect.setAttribute('id','svgrect') + rect.setAttribute('x',t.ox-t.tx+(evt.pageX-t.ox)/t.s) + rect.setAttribute('y',t.oy-t.ty+(evt.pageY-t.oy)/t.s-mods.ui.header) + rect.setAttribute('width',0) + rect.setAttribute('height',0) + rect.setAttribute('fill','rgb(200,200,200)') + rect.setAttribute('stroke','none') + var svg = document.getElementById('svg') + svg.insertBefore(rect,svg.firstChild) + } + else { + // + // continue dragging + // + var rect = document.getElementById('svgrect') + var xp = t.ox-t.tx+(mods.ui.xstart-t.ox)/t.s + var yp = t.oy-t.ty+(mods.ui.ystart-t.oy)/t.s-mods.ui.header + var xw = t.ox-t.tx+(evt.pageX-t.ox)/t.s + var yw = t.oy-t.ty+(evt.pageY-t.oy)/t.s-mods.ui.header + if (xw < xp) { + rect.setAttribute('x',xw) + rect.setAttribute('width',xp-xw) + } + else + rect.setAttribute('width',xw-xp) + if (yw < yp) { + rect.setAttribute('y',yw) + rect.setAttribute('height',yp-yw) + } + else + rect.setAttribute('height',yw-yp) + } + } + } + }) +window.addEventListener('mouseup',function(evt) { + // + // mouse up + // + mods.ui.mousedown = null + // + // check for selection rectangle + // + var rect = document.getElementById('svgrect') + if (rect != null) { + // + // rectangle exists, selecting modules + // + var x = parseFloat(rect.getAttribute('x')) + var y = parseFloat(rect.getAttribute('y')) + var width = parseFloat(rect.getAttribute('width')) + var height = parseFloat(rect.getAttribute('height')) + svg.removeChild(rect) + var modules = document.getElementById('modules') + // + // loop to find selected modules + // + mods.ui.selected = {} + for (var module in modules.childNodes) { + var container = modules.childNodes[module] + var id = container.id + if (id != undefined) { + var name = container.firstChild + var left = parseFloat(container.dataset.left) + var top = parseFloat(container.dataset.top) + if ((x <= left) && (left <= x+width) && (y <= top) && (top <= y+height)) { + // + // module is in selection rectangle + // + name.style.fontWeight = "bold" + mods.ui.selected[id] = true + } + else { + // + // module is not in selection rectangle + // + name.style.fontWeight = "normal" + } + } + } + } + }) +// +// context menu +// +window.addEventListener('contextmenu',function(evt){ + evt.stopPropagation() + evt.preventDefault() + if (mods.ui.menu != null) { + document.body.removeChild(mods.ui.menu) + mods.ui.menu = null + } + var div = document.createElement('div') + make_menu(div) + add_menu(div,'modules',modules) + add_menu(div,'programs',programs) + add_menu(div,'edit',edit) + add_menu(div,'options',options) + document.body.appendChild(div) + function make_menu(div) { + mods.ui.menu = div + div.style.position = "absolute" + var t = mods_transform() + div.style.top = t.oy-t.ty+(evt.pageY-t.oy)/t.s + div.style.left = t.ox-t.tx+(evt.pageX-t.ox)/t.s + div.style.zIndex = 0 + div.style.cursor = 'default' + div.style.backgroundColor = "rgb(220,255,255)" + div.style.padding = 1.5*mods.ui.padding + div.style.textAlign = 'left' + div.style.border = '2px solid' + div.style.borderRadius = '10px' + } + function add_menu(div,text,click) { + var textdiv = document.createElement('div') + textdiv.appendChild(document.createTextNode(text)) + textdiv.appendChild(document.createElement('br')) + textdiv.addEventListener('mouseover',function(evt){ + evt.target.style.fontWeight = 'bold'}) + textdiv.addEventListener('mouseout',function(evt){ + evt.target.style.fontWeight = 'normal'}) + textdiv.addEventListener('mousedown',click) + textdiv.addEventListener('touchend',click) + div.appendChild(textdiv) + } + // + // modules menu + // + function modules(evt) { + evt.preventDefault() + evt.stopPropagation() + document.body.removeChild(evt.target.parentNode) + var div = document.createElement('div') + make_menu(div) + set_prompt('modules') + // + // open server module + // + add_menu(div,'open server module',function(evt){ + function module_label(label) { + var div = document.createElement('div') + var i = document.createElement('i') + i.appendChild(document.createTextNode(label)) + div.appendChild(i) + div.appendChild(document.createElement('br')) + menu.appendChild(div) + } + function module_menu(label,module) { + var div = document.createElement('div') + div.appendChild( + document.createTextNode('\u00A0\u00A0\u00A0'+label)) + div.addEventListener('mouseover',function(evt){ + evt.target.style.fontWeight = 'bold'}) + div.addEventListener('mouseout',function(evt){ + evt.target.style.fontWeight = 'normal'}) + div.addEventListener('mousedown',function(evt){ + evt.preventDefault() + evt.stopPropagation() + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + var t = mods_transform() + mod_message_handler(module, + t.oy-t.ty+(evt.pageY-t.oy)/t.s, + t.ox-t.tx+(evt.pageX-t.ox)/t.s)}) + div.appendChild(document.createElement('br')) + menu.appendChild(div) + } + document.body.removeChild(evt.target.parentNode) + var menu = document.createElement('div') + make_menu(menu) + document.body.appendChild(menu) + menu.style.width = mods.ui.canvas + menu.style.height = mods.ui.canvas + menu.style.overflow = 'auto' + var req = new XMLHttpRequest() + req.responseType = 'text' + req.onreadystatechange = function() { + if (req.readyState == XMLHttpRequest.DONE) { + var str = req.response + eval(str) + } + } + req.open('GET','modules/index.js'+'?rnd='+Math.random()) + req.send() + }) + // + // open local module + // + add_menu(div,'open local module',function(evt){ + var t = mods_transform() + mods.ui.top = t.oy-t.ty+(evt.pageY-t.oy)/t.s + mods.ui.left = t.ox-t.tx+(evt.pageX-t.ox)/t.s + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + var file = document.getElementById('mod_input') + file.value = null + file.click() + }) + // + // open remote module + // + add_menu(div,'open remote module',function(evt){ + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + set_prompt('remotes not yet implemented') + }) + document.body.appendChild(div) + } + // + // programs menu + // + function programs(evt) { + evt.preventDefault() + evt.stopPropagation() + document.body.removeChild(evt.target.parentNode) + var div = document.createElement('div') + make_menu(div) + set_prompt('programs') + // + // open local program + // + add_menu(div,'open local program',function(evt){ + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + var file = document.getElementById('prog_input') + file.value = null + file.click() + }) + // + // open server program + // + add_menu(div,'open server program',function(evt){ + function program_label(label) { + var div = document.createElement('div') + var i = document.createElement('i') + i.appendChild(document.createTextNode(label)) + div.appendChild(i) + div.appendChild(document.createElement('br')) + menu.appendChild(div) + } + function program_menu(label,program) { + var div = document.createElement('div') + div.appendChild( + document.createTextNode('\u00A0\u00A0\u00A0'+label)) + div.addEventListener('mouseover',function(evt){ + evt.target.style.fontWeight = 'bold'}) + div.addEventListener('mouseout',function(evt){ + evt.target.style.fontWeight = 'normal'}) + div.addEventListener('mousedown',function(evt){ + evt.preventDefault() + evt.stopPropagation() + if (location.port == 80) + var uri = 'http://'+location.hostname + +'?program='+program + else + var uri = 'http://'+location.hostname+':' + +location.port+'?program='+program + set_prompt('<a href='+uri+'>program link</a>') + prog_message_handler(program) + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + }) + div.appendChild(document.createElement('br')) + menu.appendChild(div) + } + document.body.removeChild(evt.target.parentNode) + var menu = document.createElement('div') + make_menu(menu) + document.body.appendChild(menu) + menu.style.width = mods.ui.canvas + menu.style.height = mods.ui.canvas + menu.style.overflow = 'auto' + var req = new XMLHttpRequest() + req.responseType = 'text' + req.onreadystatechange = function() { + if (req.readyState == XMLHttpRequest.DONE) { + var str = req.response + eval(str) + } + } + req.open('GET','programs/index.js'+'?rnd='+Math.random()) + req.send() + }) + // + // open remote program + // + add_menu(div,'open remote program',function(evt){ + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + set_prompt('remotes not yet implemented') + }) + // + // save local program + // + add_menu(div,'save local program',function(evt){ + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + save_program() + }) + // + // save local page + // + add_menu(div,'save local page',function(evt){ + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + save_page() + }) + document.body.appendChild(div) + } + // + // edit menu + // + function edit(evt) { + evt.preventDefault() + evt.stopPropagation() + document.body.removeChild(evt.target.parentNode) + var div = document.createElement('div') + make_menu(div) + set_prompt('edit') + // + // cut + // + add_menu(div,'cut',function(evt){ + evt.preventDefault() + evt.stopPropagation() + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + if ((Object.keys(mods.ui.selected).length) == 0) { + set_prompt("nothing selected") + } + else { + for (var id in mods.ui.selected) { + var div = document.getElementById(id) + delete_module(id) + mods.ui.selected = {} + } + } + }) + // + // copy + // + add_menu(div,'copy',function(evt){ + evt.preventDefault() + evt.stopPropagation() + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + set_prompt('copy not yet implemented') + }) + // + // paste + // + add_menu(div,'paste',function(evt){ + evt.preventDefault() + evt.stopPropagation() + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + set_prompt('paste not yet implemented') + }) + document.body.appendChild(div) + } + // + // options menu + // + function options(evt) { + evt.preventDefault() + evt.stopPropagation() + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + var div = document.createElement('div') + make_menu(div) + set_prompt('options') + // + // view files + // + add_menu(div,'view files',function(evt){ + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + var win = window.open('files.html') + }) + document.body.appendChild(div) + // + // view project + // + add_menu(div,'view project',function(evt){ + document.body.removeChild(evt.target.parentNode) + mods.ui.menu = null + var win = window.open('https://gitlab.cba.mit.edu/pub/mods') + }) + document.body.appendChild(div) + } + }) +// +// prompt +// +document.body.appendChild(document.createTextNode(' ')) +var span = document.createElement('span') + span.setAttribute('id','logo') + span.style.display = 'inline-block' + span.style.verticalAlign = 'middle' + span.style.width = 20 + span.style.height = 20 + span.style.padding = mods.ui.padding + span.appendChild(logo(1)) + document.body.appendChild(span) +document.body.appendChild(document.createTextNode(' ')) +var span = document.createElement('span') + span.setAttribute('id','prompt') + span.style.display = 'inline-block' + span.style.verticalAlign = 'middle' + var innerspan = document.createElement('span') + span.appendChild(innerspan) + document.body.appendChild(span) +function logo(size) { + var x = 0 + var y = 2.8*size/3.8 + var svgNS = "http://www.w3.org/2000/svg" + var logo = document.createElementNS(svgNS,"svg") + logo.setAttributeNS("http://www.w3.org/2000/xmlns/", + "xmlns:xlink","http://www.w3.org/1999/xlink") + logo.setAttributeNS(null,'viewBox',"0 0 "+size+" "+size) + var new_rect = document.createElementNS(svgNS,"rect"); + new_rect.setAttribute("width",size/3.8) + new_rect.setAttribute("height",size/3.8) + new_rect.setAttribute("x",x) + new_rect.setAttribute("y",y) + new_rect.setAttribute("fill","blue") + logo.appendChild(new_rect) + var new_rect = document.createElementNS(svgNS,"rect"); + new_rect.setAttribute("width",size/3.8) + new_rect.setAttribute("height",size/3.8) + new_rect.setAttribute("x",x+1.4*size/3.8) + new_rect.setAttribute("y",y) + new_rect.setAttribute("fill","blue") + logo.appendChild(new_rect) + var new_rect = document.createElementNS(svgNS,"rect"); + new_rect.setAttribute("width",size/3.8) + new_rect.setAttribute("height",size/3.8) + new_rect.setAttribute("x",x+2.8*size/3.8) + new_rect.setAttribute("y",y) + new_rect.setAttribute("fill","blue") + logo.appendChild(new_rect) + var new_rect = document.createElementNS(svgNS, "rect"); + new_rect.setAttribute("width",size/3.8) + new_rect.setAttribute("height",size/3.8) + new_rect.setAttribute("x",x) + new_rect.setAttribute("y",y-1.4*size/3.8) + new_rect.setAttribute("fill","blue") + logo.appendChild(new_rect) + var new_rect = document.createElementNS(svgNS, "rect"); + new_rect.setAttribute("width", size / 3.8) + new_rect.setAttribute("height", size / 3.8) + new_rect.setAttribute("x", x + 2.8 * size / 3.8) + new_rect.setAttribute("y", y - 1.4 * size / 3.8) + new_rect.setAttribute("fill", "blue") + logo.appendChild(new_rect) + var new_rect = document.createElementNS(svgNS, "rect"); + new_rect.setAttribute("width", size / 3.8) + new_rect.setAttribute("height", size / 3.8) + new_rect.setAttribute("x", x + 1.4 * size / 3.8) + new_rect.setAttribute("y", y - 2.8 * size / 3.8) + new_rect.setAttribute("fill", "blue") + logo.appendChild(new_rect) + var new_rect = document.createElementNS(svgNS, "rect"); + new_rect.setAttribute("width", size / 3.8) + new_rect.setAttribute("height", size / 3.8) + new_rect.setAttribute("x", x + 2.8 * size / 3.8) + new_rect.setAttribute("y", y - 2.8 * size / 3.8) + new_rect.setAttribute("fill", "blue") + logo.appendChild(new_rect) + var new_circ = document.createElementNS(svgNS, "circle"); + new_circ.setAttribute("r", size / (2 * 3.8)) + new_circ.setAttribute("cx", x + size / (2 * 3.8)) + new_circ.setAttribute("cy", y + size / (2 * 3.8) - 2.8 * size / 3.8) + new_circ.setAttribute("fill", "red") + logo.appendChild(new_circ) + var new_circ = document.createElementNS(svgNS, "circle"); + new_circ.setAttribute("r", size / (2 * 3.8)) + new_circ.setAttribute("cx", x + size / (2 * 3.8) + 1.4 * size / 3.8) + new_circ.setAttribute("cy", y + size / (2 * 3.8) - 1.4 * size / 3.8) + new_circ.setAttribute("fill", "red") + logo.appendChild(new_circ) + return logo + } +set_prompt('right click/two finger/long press for menu; scroll for zoom, drag for pan') +// +// SVG canvas for drawing +// +var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg") + svg.style.position = 'absolute' + svg.style.backgroundColor = 'rgb(255,255,255)' + svg.style.top = mods.ui.header + svg.style.left = 0 + svg.style.zIndex = 0 + svg.style.overflow = 'visible' + svg.setAttribute('width',40) + svg.setAttribute('height',40) + svg.setAttribute('id','svg') + svg.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink") + document.body.appendChild(svg) +// +// link container +// +var svg = document.getElementById('svg') +var g = document.createElementNS('http://www.w3.org/2000/svg','g') + g.setAttribute('id','links') + svg.appendChild(g) +// +// file reading controls +// +var file = document.createElement('input') + file.setAttribute('type','file') + file.setAttribute('id','mod_input') + file.style.position = 'absolute' + file.style.left = 0 + file.style.top = 0 + file.style.width = 0 + file.style.height = 0 + file.style.opacity = 0 + file.addEventListener('change',function() { + mod_read_handler() + }) + document.body.appendChild(file) +var file = document.createElement('input') + file.setAttribute('type','file') + file.setAttribute('id','prog_input') + file.style.position = 'absolute' + file.style.left = 0 + file.style.top = 0 + file.style.width = 0 + file.style.height = 0 + file.style.opacity = 0 + file.addEventListener('change',function() { + prog_read_handler() + }) + document.body.appendChild(file) +// +// module container +// +var div = document.createElement('div') + div.setAttribute('id','modules') + document.body.appendChild(div) +// +// check for program load query +// +if (location.search.length > 0) { + var args = location.search.slice(1).split('&') + for (var a in args) { + var arg = args[a].split('=') + if (arg[0] == 'program') + prog_message_handler(arg[1]) + } + } +// +// program routines +// +function prog_read_handler(event) { + var file = document.getElementById('prog_input') + var file_reader = new FileReader() + file_reader.onload = prog_load_handler + file_reader.readAsText(file.files[0]) + mods.ui.progname = file.files[0].name + } +function prog_message_handler(filename) { + var req = new XMLHttpRequest() + req.responseType = 'text' + req.onreadystatechange = function() { + if (req.readyState == XMLHttpRequest.DONE) { + prog = JSON.parse(req.response) + prog_load(prog) + } + } + var index = filename.lastIndexOf('/') + if (index != -1) { + mods.ui.progname = filename.slice(index+1) + } + else + mods.ui.progname = filename + // + // send request, with random query to prevent caching + // + req.open('GET',filename+'?rnd='+Math.random()) + req.send() + } +function prog_load_handler(event) { + prog = JSON.parse(event.target.result) + prog_load(prog) + } +function prog_load(prog) { + // + // load modules + // + for (var idnumber in prog.modules) { + var module = prog.modules[idnumber] + var str = module.definition + try { + eval('var args = '+str) + } + catch (err) { + console.log(err.message) + return + } + args.definition = str + args.id = idnumber + var t = mods_transform() + var xw = t.ox-t.tx+(mods.ui.xstart-t.ox)/t.s + var yw = t.oy-t.ty+(mods.ui.ystart-t.oy)/t.s-mods.ui.header + args.top = parseFloat(module.top)+yw + args.left = parseFloat(module.left)+xw + args.filename = module.filename + add_module(args) + } + // + // load links + // + for (var linkid in prog.links) { + var str = prog.links[linkid] + eval('var link = '+str) + eval('var linksrc = '+link.source) + eval('var linkdst = '+link.dest) + var src = document.getElementById( + JSON.stringify({id:linksrc.id,type:linksrc.type,name:linksrc.name})) + var dst = document.getElementById( + JSON.stringify({id:linkdst.id,type:linkdst.type,name:linkdst.name})) + add_link(src,dst) + } + } +function save_program() { + set_prompt('program name? ') + get_prompt(mods.ui.progname,function(filename){ + mods.ui.progname = filename + var prog = {modules:{},links:[]} + var modules = document.getElementById('modules') + // + // save modules + // + for (var c = 0; c < modules.childNodes.length; ++c) { + var module = modules.childNodes[c] + var idnumber = module.id + prog.modules[idnumber] = { + definition:update_module_definition( + idnumber,module.dataset.definition), + top:module.dataset.top, + left:module.dataset.left, + filename: module.dataset.filename, + inputs:{}, + outputs:{} + } + } + // + // save links + // + var svg = document.getElementById('svg') + var links = svg.getElementById('links') + for (var l = 0; l < links.childNodes.length; ++l) { + var link = links.childNodes[l] + var linkid = link.id + prog.links.push(linkid) + } + // + // download + // + var text = JSON.stringify(prog) + var a = document.createElement('a') + a.setAttribute('href','data:text/plain;charset=utf-8,'+ + encodeURIComponent(text)) + a.setAttribute('download',filename) + a.style.display = 'none' + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + }) + } +function save_page() { + set_prompt('page name? ') + get_prompt(mods.ui.progname+".html",function(filename){ + mods.ui.progname = filename + var prog = {modules:{},links:[]} + var modules = document.getElementById('modules') + // + // save modules + // + for (var c = 0; c < modules.childNodes.length; ++c) { + var module = modules.childNodes[c] + var idnumber = module.id + prog.modules[idnumber] = { + definition:update_module_definition( + idnumber,module.dataset.definition), + top:module.dataset.top, + left:module.dataset.left, + filename: module.dataset.filename, + inputs:{}, + outputs:{} + } + } + // + // save links + // + var svg = document.getElementById('svg') + var links = svg.getElementById('links') + for (var l = 0; l < links.childNodes.length; ++l) { + var link = links.childNodes[l] + var linkid = link.id + prog.links.push(linkid) + } + // + // read mods.js + // + var req = new XMLHttpRequest() + req.responseType = 'text' + req.onreadystatechange = function() { + if (req.readyState == XMLHttpRequest.DONE) { + // + // construct page + // + var str = req.response + var text ="<html>\n" + text += "<head><meta charset='utf-8'>\n" + text += "<title>mods</title>\n" + text += "</head>\n" + text += "<body link='black' alink='black' vlink='black'>\n" + text += "<"+"script"+">\n" + text += str + text += "var prog = JSON.parse(JSON.stringify("+JSON.stringify(prog)+"))\n" + text += "window.mods_prog_load(prog)\n" + text += "</"+"script"+">\n" + text += "</body>\n" + text += "</html>\n" + // + // download page + // + var a = document.createElement('a') + a.setAttribute('href','data:text/plain;charset=utf-8,'+ + encodeURIComponent(text)) + a.setAttribute('download',filename) + a.style.display = 'none' + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + } + } + // + // send request, with random query to prevent caching + // + req.open('GET','js/mods.js'+'?rnd='+Math.random()) + req.send() + }) + } +// +// add program load to window +// +window.mods_prog_load = function(prog) { + prog_load(prog) + } +// +// module routines +// +function mod_read_handler(event) { + var file = document.getElementById('mod_input') + var file_reader = new FileReader() + file_reader.onload = mod_load_handler + file_reader.readAsText(file.files[0]) + } +function mod_message_handler(filename,top,left) { + var req = new XMLHttpRequest() + req.responseType = 'text' + req.onreadystatechange = function() { + if (req.readyState == XMLHttpRequest.DONE) { + var str = req.response + try { + eval('var args = '+str) + } + catch (err) { + console.log(err.message) + return + } + args.definition = str + args.id = String(Math.random()) + args.top = top + args.left = left + args.filename = filename + add_module(args) + } + } + // + // send request, with random query to prevent caching + // + req.open('GET',filename+'?rnd='+Math.random()) + req.send() + } +function mod_load_handler(event) { + str = event.target.result + try { + eval('var args = '+str) + } + catch (err) { + console.log(err.message) + return + } + args.definition = str + args.id = String(Math.random()) + args.top = mods.ui.top + args.left = mods.ui.left + args.filename = "" + var div = add_module(args) + return(div) + } +function add_module(args) { + var idnumber = args.id + mods.mod[idnumber] = args.mod + var modules = document.getElementById('modules') + // + // container + // + var container = document.createElement('div') + container.setAttribute("id",idnumber) + container.style.position = "absolute" + container.style.top = args.top + container.style.left = args.left + container.dataset.top = args.top + container.dataset.left = args.left + container.dataset.filename = args.filename + container.dataset.name = args.name + container.style.zIndex = 0 + container.style.width = window.innerWidth + container.dataset.definition = args.definition + modules.appendChild(container) + // + // name + // + var divname = document.createElement('div') + divname.appendChild(document.createTextNode(args.name)) + divname.addEventListener('mouseover',name_over) + divname.addEventListener('mouseout',name_out) + divname.addEventListener('mousedown',name_mousedown) + divname.addEventListener('touchstart',name_touchdown) + divname.style.backgroundColor = "rgb(210,240,210)" + divname.style.padding = 1.5*mods.ui.padding + divname.style.position = "absolute" + divname.style.cursor = 'default' + divname.style.top = 0 + divname.style.left = 0 + divname.style.textAlign = 'center' + divname.style.border = '2px solid' + divname.style.borderRadius = '10px' + container.appendChild(divname) + // + // controls + // + var divctrl = document.createElement('div') + var editspan = document.createElement('span') + editspan.innerHTML = 'edit' + editspan.style.fontWeight = 'normal' + editspan.addEventListener('mouseover',function(event){ + set_prompt('click to edit') + editspan.style.fontWeight = 'bold'}) + editspan.addEventListener('mouseout',function(event){ + set_prompt('') + editspan.style.fontWeight = 'normal'}) + editspan.addEventListener('mousedown',edit_module) + divctrl.appendChild(editspan) + var delspan = document.createElement('span') + delspan.innerHTML = ' delete ' + delspan.addEventListener('mouseover',function(event){ + set_prompt('click to delete') + delspan.style.fontWeight = 'bold'}) + delspan.addEventListener('mouseout',function(event){ + set_prompt('') + delspan.style.fontWeight = 'normal'}) + delspan.addEventListener('mousedown',function(event){ + delete_module(event.target.parentNode.parentNode.id)}) + divctrl.appendChild(delspan) + divctrl.style.backgroundColor = "rgb(240,220,220)" + divctrl.style.padding = mods.ui.padding + divctrl.style.position = "absolute" + divctrl.style.cursor = 'default' + divctrl.style.top = divname.clientHeight + divctrl.style.left = 0 + divctrl.style.textAlign = 'center' + divctrl.style.border = '2px solid' + divctrl.style.borderRadius = '10px' + container.appendChild(divctrl) + divctrl.style.left = divname.clientWidth/2-divctrl.clientWidth/2 + // + // interface + // + var divint = document.createElement('div') + divint.style.backgroundColor = "rgb(240,240,240)" + divint.style.padding = mods.ui.padding + divint.style.position = "absolute" + divint.style.top = divname.clientHeight+divctrl.clientHeight + divint.style.textAlign = 'center' + divint.style.border = '2px solid' + divint.style.borderRadius = '10px' + divint.setAttribute('id',JSON.stringify({id:idnumber,type:'interface'})) + divint.dataset.id = idnumber + divint.dataset.divNameSize = divname.clientWidth + args.interface(divint) + container.appendChild(divint) + divint.style.left = divname.clientWidth/2-divint.clientWidth/2 + // + // inputs + // + var divin = document.createElement('div') + divin.setAttribute('id',JSON.stringify({id:idnumber,type:'inputs'})) + var b = document.createElement('b') + b.appendChild(document.createTextNode('inputs')) + divin.appendChild(b) + divin.style.backgroundColor = "rgb(240,240,210)" + divin.style.padding = mods.ui.padding + divin.style.paddingLeft = '2px' + divin.style.position= "absolute" + divin.style.top = divname.clientHeight+divctrl.clientHeight + divin.style.textAlign = 'left' + divin.style.border = '2px solid' + divin.style.borderRadius = '10px' + divin.setAttribute('id',JSON.stringify({id:idnumber,type:'inputs'})) + divin.style.cursor = 'default' + divin.addEventListener('mousedown',nothing) + divin.addEventListener('touchstart',nothing) + divin.addEventListener('mouseup',nothing) + divin.addEventListener('touchend',nothing) + for (var v in args.inputs) { + var div = document.createElement('div') + if (args.inputs[v].label != undefined) + div.innerHTML += args.inputs[v].label + else + div.innerHTML += v + if (args.inputs[v].type != '') + div.innerHTML += ' ('+args.inputs[v].type+')' + div.setAttribute('id',JSON.stringify({id:idnumber,type:'inputs',name:v})) + div.addEventListener('mouseover',input_over) + div.addEventListener('mouseout',input_out) + div.addEventListener('mousedown',input_mousedown) + div.addEventListener('touchstart',input_touchdown) + div.dataset.links = JSON.stringify([]) + div.dataset.name = v + divin.appendChild(div) + div.dataset.id = JSON.stringify( + {id:idnumber,type:'input',name:v, + rnd:Math.random()}) // randomize for unique events + window.addEventListener(div.dataset.id,args.inputs[v].event) + } + container.appendChild(divin) + if ((Object.keys(args.inputs).length) == 0) + divin.style.visibility = 'hidden' + divin.style.left = divname.clientWidth/2 + -divint.clientWidth/2-divin.clientWidth + for (var i = 1; i < divin.childNodes.length; ++i) { + divin.childNodes[i].dataset.dx = divin.offsetLeft + +divin.childNodes[i].offsetLeft + divin.childNodes[i].dataset.dy = divin.offsetTop + +divin.childNodes[i].offsetTop + +divin.childNodes[i].offsetHeight/2 + } + // + // outputs + // + var divout = document.createElement('div') + divout.setAttribute('id',JSON.stringify({id:idnumber,type:'outputs'})) + var b = document.createElement('b') + b.appendChild(document.createTextNode('outputs')) + divout.appendChild(b) + divout.style.backgroundColor = "rgb(240,240,210)" + divout.style.padding = mods.ui.padding + divout.style.paddingRight = '2px' + divout.style.position = "absolute" + divout.style.top = divname.clientHeight+divctrl.clientHeight + divout.style.textAlign = 'right' + divout.addEventListener('mousedown',nothing) + divout.style.border = '2px solid' + divout.style.borderRadius = '10px' + divout.setAttribute('id',JSON.stringify({id:idnumber,type:'outputs'})) + divout.style.cursor = 'default' + divout.addEventListener('touchstart',nothing) + divout.addEventListener('mouseup',nothing) + divout.addEventListener('touchend',nothing) + for (var v in args.outputs) { + var div = document.createElement('div') + if (args.outputs[v].label != undefined) + div.innerHTML += args.outputs[v].label + else + div.innerHTML += v + if (args.outputs[v].type != '') + div.innerHTML += ' ('+args.outputs[v].type+')' + div.setAttribute('id',JSON.stringify({id:idnumber,type:'outputs',name:v})) + div.addEventListener('mouseover',output_over) + div.addEventListener('mouseout',output_out) + div.addEventListener('mousedown',output_mousedown) + div.addEventListener('touchstart',output_touchdown) + div.dataset.links = JSON.stringify([]) + div.dataset.name = v + divout.appendChild(div) + div.dataset.id = JSON.stringify( + {id:idnumber,type:'output',name:v, + rnd:Math.random()}) // randomize for unique events + window.addEventListener(div.dataset.id,args.outputs[v].event) + } + container.appendChild(divout) + if ((Object.keys(args.outputs).length) == 0) + divout.style.visibility = 'hidden' + divout.style.left = divname.clientWidth/2 + +divint.clientWidth/2 + for (var i = 1; i < divout.childNodes.length; ++i) { + divout.childNodes[i].dataset.dx = divout.offsetLeft + +divout.childNodes[i].offsetLeft + +divout.childNodes[i].offsetWidth + divout.childNodes[i].dataset.dy = divout.offsetTop + +divout.childNodes[i].offsetTop + +divout.childNodes[i].offsetHeight/2 + } + // + // initialization + // + args.init() + // + // resize to contents + // + container.style.width = divint.clientWidth+divin.clientWidth+divout.clientWidth + mods.fit(divint) + // + // return container + // + return(container) + } +function delete_module(idnumber) { + // + // delete links + // + var ins = document.getElementById( + JSON.stringify({id:idnumber,type:'inputs'})) + var outs = document.getElementById( + JSON.stringify({id:idnumber,type:'outputs'})) + for (var i = 1; i < ins.childNodes.length; ++i) { + var links = JSON.parse(ins.childNodes[i].dataset.links) + for (var l in links) + delete_link(links[l]) + } + for (var i = 1; i < outs.childNodes.length; ++i) { + var links = JSON.parse(outs.childNodes[i].dataset.links) + for (var l in links) + delete_link(links[l]) + } + // + // delete container + // + var modules = document.getElementById('modules') + var container = document.getElementById(idnumber) + modules.removeChild(container) + // + // clear prompt + // + set_prompt('') + } +function update_module_definition(id) { + // + // get definition + // + var module = document.getElementById(id) + var def = module.dataset.definition + // + // check for mod + // + if (mods.mod[id] == undefined) + return def + // + // split definition + // + var lines = def.split('\n') + // + // find init function + // + var line = 0 + while (line < lines.length) { + if (lines[line].indexOf("var init") == 0) + break + line += 1 + } + // + // read initializations up to inputs function + // + while (line < lines.length) { + if (lines[line].indexOf(".value =") != -1) { + var start = 4+lines[line].indexOf("mod.") + var end = lines[line].indexOf(".value") + var key = lines[line].slice(start,end) + var value = mods.mod[id][key]['value'] + if (value.indexOf('\n') != -1) + value = value.replace(/\n/g,"\\n") + lines[line] = " mod."+key+".value = '"+value+"'" + } + else if (lines[line].indexOf(".checked =") != -1) { + var start = 4+lines[line].indexOf("mod.") + var end = lines[line].indexOf(".checked") + var key = lines[line].slice(start,end) + var value = mods.mod[id][key]['checked'] + lines[line] = " mod."+key+".checked = "+value + } + if (lines[line].indexOf("var inputs") == 0) + break + line += 1 + } + return(lines.join('\n')) + } +function edit_module(evt) { + var mod = evt.target.parentNode.parentNode + var idnumber = mod.id + var def = update_module_definition(idnumber) + // + // open edit window + // + var top = mod.dataset.top + var left = mod.dataset.left + var name = mod.dataset.name + var filename = mod.dataset.filename + var fontsize = 100 + var win = window.open('') + var file = document.createElement('input') + file.setAttribute('type','file') + file.setAttribute('id','edit_module_file') + file.style.position = 'absolute' + file.style.left = 0 + file.style.top = 0 + file.style.width = 0 + file.style.height = 0 + file.style.opacity = 0 + file.addEventListener('change',function() { + edit_module_read_handler() + }) + win.document.body.appendChild(file) + function edit_module_read_handler() { + var file = win.document.getElementById('edit_module_file') + var file_reader = new FileReader() + file_reader.onload = edit_module_load_handler + file_reader.readAsText(file.files[0]) + } + function edit_module_load_handler(event) { + str = event.target.result + var text = win.document.getElementById('edit_module_text') + text.value = str + update_module(idnumber) + win.close() + } + if (filename != "undefined" && filename != "") { + var btn = document.createElement('button') + btn.appendChild(document.createTextNode('reload from server')) + btn.style.padding = mods.ui.padding + btn.style.margin = 1 + btn.addEventListener('click',function(){ + var req = new XMLHttpRequest() + req.responseType = 'text' + req.onreadystatechange = function() { + if (req.readyState == XMLHttpRequest.DONE) { + text.value = req.response + update_module(idnumber) + } + } + req.open('GET',filename+'?rnd='+Math.random()) + req.send() + win.close() + }) + win.document.body.appendChild(btn) + } + var btn = document.createElement('button') + btn.appendChild(document.createTextNode('load from file')) + btn.style.padding = mods.ui.padding + btn.style.margin = 1 + btn.addEventListener('click',function(){ + var file = win.document.getElementById('edit_module_file') + file.value = null + file.click() + }) + win.document.body.appendChild(btn) + var btn = document.createElement('button') + btn.appendChild(document.createTextNode('update and close')) + btn.style.padding = mods.ui.padding + btn.style.margin = 1 + btn.addEventListener('click',function(){ + update_module(idnumber) + win.close() + }) + win.document.body.appendChild(btn) + var btn = document.createElement('button') + btn.appendChild(document.createTextNode('update')) + btn.style.padding = mods.ui.padding + btn.style.margin = 1 + btn.addEventListener('click',function(){ + update_module(idnumber) + }) + win.document.body.appendChild(btn) + var btn = document.createElement('button') + btn.appendChild(document.createTextNode('close')) + btn.style.padding = mods.ui.padding + btn.style.margin = 1 + btn.addEventListener('click',function(){ + win.close() + }) + win.document.body.appendChild(btn) + var btn = document.createElement('button') + btn.appendChild(document.createTextNode('save')) + btn.style.padding = mods.ui.padding + btn.style.margin = 1 + btn.addEventListener('click',function(){ + var a = document.createElement('a') + a.setAttribute('href','data:text/plain;charset=utf-8,'+ + encodeURIComponent(text.value)) + a.setAttribute('download',name) + a.style.display = 'none' + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + }) + win.document.body.appendChild(btn) + var btn = document.createElement('button') + btn.appendChild(document.createTextNode('increase font')) + btn.style.padding = mods.ui.padding + btn.style.margin = 1 + btn.addEventListener('click',function(){ + fontsize *= 1.2 + text.style.fontSize = fontsize+'%' + }) + win.document.body.appendChild(btn) + var btn = document.createElement('button') + btn.appendChild(document.createTextNode('decrease font')) + btn.style.padding = mods.ui.padding + btn.style.margin = 1 + btn.addEventListener('click',function(){ + fontsize /= 1.2 + text.style.fontSize = fontsize+'%' + }) + win.document.body.appendChild(btn) + win.document.body.appendChild(document.createElement('br')) + var text = document.createElement('textarea') + text.setAttribute('id','edit_module_text') + text.style.width = '100%' + text.style.height= '100%' + text.value = def + win.document.body.appendChild(text) + function reload_module(idnumber) { + } + function update_module(idnumber) { + // + // save links + // + var ins = document.getElementById( + JSON.stringify({id:idnumber,type:'inputs'})) + var inlinks = [] + for (var i = 1; i < ins.childNodes.length; ++i) { + var links = JSON.parse(ins.childNodes[i].dataset.links) + for (var l in links) + inlinks.push(links[l]) + } + var outs = document.getElementById( + JSON.stringify({id:idnumber,type:'outputs'})) + var outlinks = [] + for (var i = 1; i < outs.childNodes.length; ++i) { + var links = JSON.parse(outs.childNodes[i].dataset.links) + for (var l in links) + outlinks.push(links[l]) + } + // + // delete module + // + delete_module(idnumber) + // + // add module + // + var def = text.value + try { + eval('var args = '+def) + } + catch (err) { + console.log(err.message) + return + } + args.definition = def + args.id = idnumber + args.top = top + args.left = left + args.filename = filename + add_module(args) + // + // add links + // + for (var l in inlinks) { + eval('var link = '+inlinks[l]) + eval('var linksrc = '+link.source) + eval('var linkdst = '+link.dest) + var src = document.getElementById( + JSON.stringify( + {id:linksrc.id,type:linksrc.type,name:linksrc.name})) + var dst = document.getElementById( + JSON.stringify( + {id:linkdst.id,type:linkdst.type,name:linkdst.name})) + add_link(src,dst) + } + for (var l in outlinks) { + eval('var link = '+outlinks[l]) + eval('var linksrc = '+link.source) + eval('var linkdst = '+link.dest) + var src = document.getElementById( + JSON.stringify( + {id:linksrc.id,type:linksrc.type,name:linksrc.name})) + var dst = document.getElementById( + JSON.stringify( + {id:linkdst.id,type:linkdst.type,name:linkdst.name})) + add_link(src,dst) + } + } + } +// +// UI routines +// +function set_prompt(txt) { + var span = document.getElementById('prompt') + span.childNodes[0].innerHTML = ' '+txt + } +function get_prompt(txt,fn) { + var div = document.getElementById('prompt') + if (div.childNodes.length > 2) + // + // already getting a prompt + // + return + var text = document.createElement('input') + text.type = 'text' + text.size = 20 + text.value = txt + text.addEventListener('keydown',function(evt){ + if (evt.key == 'Enter') { + var div = document.getElementById('prompt') + div.removeChild(div.childNodes[1]) + div.removeChild(div.childNodes[1]) + set_prompt('') + fn(text.value) + } + }) + div.appendChild(text) + div.appendChild(document.createTextNode(' (enter)')) + text.focus() + } +function nothing(evt) { + evt.preventDefault() + evt.stopPropagation() + } +// +// link routines +// +mods.add_link = function(src,dst) { + add_link(src,dst) + } +function add_link(src,dst) { + // + // link order from out to in + // + if (src.id.indexOf('outputs') == -1) { + var tmp = src + src = dst + dst = tmp + } + // + // check if link exists + // + var id = JSON.stringify({source:src.id,dest:dst.id}) + var link = document.getElementById(id) + if (link != null) { + // + // yes, remove it and return + // + delete_link(id) + return + } + // + // no, add link + // + var links = JSON.parse(src.dataset.links) + links.push(id) + src.dataset.links = JSON.stringify(links) + var links = JSON.parse(dst.dataset.links) + links.push(id) + dst.dataset.links = JSON.stringify(links) + // + // draw link + // + xsrc = src.parentNode.parentNode.offsetLeft + +parseFloat(src.dataset.dx) + ysrc = src.parentNode.parentNode.offsetTop + +parseFloat(src.dataset.dy) + -mods.ui.header + xdst = dst.parentNode.parentNode.offsetLeft + +parseFloat(dst.dataset.dx) + ydst = dst.parentNode.parentNode.offsetTop + +parseFloat(dst.dataset.dy) + -mods.ui.header + var links = document.getElementById('links') + var path = document.createElementNS('http://www.w3.org/2000/svg','path') + path.setAttribute('id',id) + path.setAttribute('d','M'+xsrc+','+ysrc+' C'+(xsrc+mods.ui.bezier)+',' + +ysrc+' '+(xdst-mods.ui.bezier)+','+ydst+' '+xdst+','+ydst) + path.setAttribute('fill','none') + path.setAttribute('stroke','rgb(0,0,128)') + path.setAttribute('stroke-width',3) + links.appendChild(path) + /* + // + // don't trigger link + // + eval('var evtid = '+src.id) + evtid.type = 'output' + var evtstr = JSON.stringify(evtid) + var evt = new CustomEvent(evtstr) + window.dispatchEvent(evt) + */ + } +function delete_link(linkid) { + // + // delete a link + // + var links = document.getElementById('links') + links.removeChild(document.getElementById(linkid)) + link = JSON.parse(linkid) + src = document.getElementById(link.source) + dst = document.getElementById(link.dest) + var links = JSON.parse(src.dataset.links) + var index = links.indexOf(linkid) + links.splice(index,1) + src.dataset.links = JSON.stringify(links) + var links = JSON.parse(dst.dataset.links) + var index = links.indexOf(linkid) + links.splice(index,1) + dst.dataset.links = JSON.stringify(links) + } +function draw_links(idnumber,color) { + // + // draw a module's links + // + var ins = document.getElementById( + JSON.stringify({id:idnumber,type:'inputs'})) + var outs = document.getElementById( + JSON.stringify({id:idnumber,type:'outputs'})) + for (var i = 1; i < ins.childNodes.length; ++i) { + var links = JSON.parse(ins.childNodes[i].dataset.links) + for (var l in links) + draw_link(links[l],color) + } + for (var i = 1; i < outs.childNodes.length; ++i) { + var links = JSON.parse(outs.childNodes[i].dataset.links) + for (var l in links) + draw_link(links[l],color) + } + } +function draw_link(id,color) { + // + // draw a link + // + var link = JSON.parse(id) + src = document.getElementById(link.source) + dst = document.getElementById(link.dest) + var path = document.getElementById(id) + xsrc = src.parentNode.parentNode.offsetLeft + +parseFloat(src.dataset.dx) + ysrc = src.parentNode.parentNode.offsetTop + +parseFloat(src.dataset.dy) + -mods.ui.header + xdst = dst.parentNode.parentNode.offsetLeft + +parseFloat(dst.dataset.dx) + ydst = dst.parentNode.parentNode.offsetTop + +parseFloat(dst.dataset.dy) + -mods.ui.header + path.setAttribute('d','M'+xsrc+','+ysrc+' C'+(xsrc+mods.ui.bezier)+',' + +ysrc+' '+(xdst-mods.ui.bezier)+','+ydst+' '+xdst+','+ydst) + path.setAttribute('stroke',color) + } +// +// mods routines to be called from modules +// +mods.fit = function(div) { + // + // fit a module + // + div.style.left = div.dataset.divNameSize/2-div.clientWidth/2 + var divin = document.getElementById( + JSON.stringify( + {id:div.dataset.id,type:'inputs'})) + divin.style.left = div.dataset.divNameSize/2-div.clientWidth/2-divin.clientWidth + var divout = document.getElementById( + JSON.stringify( + {id:div.dataset.id,type:'outputs'})) + divout.style.left = div.dataset.divNameSize/2+div.clientWidth/2 + } +mods.output = function(mod,varname,val) { + // + // send module outputs + // + var div = mod.div + var key = JSON.parse(div.id) + var idnumber = key.id + var out = document.getElementById( + JSON.stringify( + {id:idnumber,type:'outputs',name:varname})) + var links = JSON.parse(out.dataset.links) + for (var l in links) { + var link = JSON.parse(links[l]) + var dest = JSON.parse(link.dest) + var divin = document.getElementById(JSON.stringify( + {id:dest.id,type:'inputs',name:dest.name})) + var evt = new CustomEvent(divin.dataset.id,{detail:val}) + window.dispatchEvent(evt) + } + } +// +// module mod-ification calls +// +mods.module_create = function(args) { + var event = {target:{result:args}} + var div = mod_load_handler(event) + return(div) + } +mods.module_delete = function(id) { + delete_module(id) + } +mods.module_id = function(div) { + return div.parentNode.id + } +mods.module_left = function(id) { + var module = document.getElementById(id) + return (parseInt(module.style.left)) + } +mods.module_move = function(id,dx,dy) { + var module = document.getElementById(id) + var top = parseInt(module.style.top) + module.style.top = top+dy + module.dataset.top = top+dy + var left = parseInt(module.style.left) + module.style.left = left+dx + module.dataset.left = left+dx + draw_links(id,mods.ui.link_color) + } +mods.module_inputs = function(id,index) { + var module = document.getElementById(id) + var inputs = document.getElementById( + JSON.stringify({id:id,type:'inputs'})) + console.log(inputs.childNodes[index]) + } +mods.module_outputs = function(id,index) { + var module = document.getElementById(id) + var outputs = document.getElementById( + JSON.stringify({id:id,type:'outputs'})) + console.log(outputs.childNodes[index]) + } +mods.module_position = function(id,x,y) { + var module = document.getElementById(id) + var top = parseInt(module.style.top) + module.style.top = y + module.dataset.top = y + var left = parseInt(module.style.left) + module.style.left = x + module.dataset.left = x + draw_links(id,mods.ui.link_color) + } +mods.module_top = function(id) { + var module = document.getElementById(id) + return (parseInt(module.style.top)) + } +mods.module_width = function(id) { + var module = document.getElementById(id) + return (parseInt(module.clientWidth)) + } +// +// input event handlers +// +function input_over(evt) { + evt.target.style.fontWeight = 'bold' + var links = JSON.parse(evt.target.dataset.links) + for (var l in links) + draw_link(links[l],mods.ui.link_highlight) + if (mods.ui.source == null) + set_prompt('click to link') + } +function input_out(evt) { + evt.target.style.fontWeight = 'normal' + var links = JSON.parse(evt.target.dataset.links) + for (var l in links) + draw_link(links[l],mods.ui.link_color) + if (mods.ui.source == null) + set_prompt('') + } +function input_mousedown(evt) { + if (mods.ui.source == null) { + mods.ui.source = evt.target + set_prompt('variable to link/unlink to?') + } + else { + add_link(mods.ui.source,evt.target) + set_prompt('') + mods.ui.source = null + } + } +function input_touchdown(evt) { + if (mods.ui.source == null) { + mods.ui.source = evt.target + set_prompt('variable to link/unlink to?') + } + else { + add_link(mods.ui.source,evt.target) + set_prompt('') + mods.ui.source = null + } + } +// +// output event handlers +// +function output_over(evt) { + evt.target.style.fontWeight = 'bold' + var links = JSON.parse(evt.target.dataset.links) + for (var l in links) + draw_link(links[l],mods.ui.link_highlight) + if (mods.ui.source == null) + set_prompt('click to link') + } +function output_out(evt) { + evt.target.style.fontWeight = 'normal' + var links = JSON.parse(evt.target.dataset.links) + for (var l in links) + draw_link(links[l],mods.ui.link_color) + if (mods.ui.source == null) + set_prompt('') + } +function output_mousedown(evt) { + if (mods.ui.source == null) { + mods.ui.source = evt.target + set_prompt('variable to link/unlink to?') + } + else { + add_link(mods.ui.source,evt.target) + set_prompt('') + mods.ui.source = null + } + } +function output_touchdown(evt) { + if (mods.ui.source == null) { + mods.ui.source = evt.target + set_prompt('variable to link/unlink to?') + } + else { + add_link(mods.ui.source,evt.target) + set_prompt('') + mods.ui.source = null + } + } +// +// name event handlers +// +function name_over(evt) { + evt.target.style.fontWeight = 'bold' + if (mods.ui.source == null) + set_prompt('click and drag to move') + } +function name_out(evt) { + evt.target.style.fontWeight = 'normal' + if (mods.ui.source == null) + set_prompt('') + } +function name_mousedown(evt) { + evt.preventDefault() + evt.stopPropagation() + var div = document.getElementById(evt.target.parentNode.id) + div.style.zIndex = 1 + mods.ui.xstart = evt.clientX + mods.ui.ystart = evt.clientY + mods.ui.selected[evt.target.parentNode.id] = true + window.addEventListener('mousemove',name_mousemove) + window.addEventListener('mouseup',name_mouseup) + } +function name_mousemove(evt) { + evt.preventDefault() + evt.stopPropagation() + var t = mods_transform() + for (var id in mods.ui.selected) { + var div = document.getElementById(id) + var dx = (evt.clientX-mods.ui.xstart)/t.s + var dy = (evt.clientY-mods.ui.ystart)/t.s + var newleft = parseFloat(div.dataset.left)+dx + var newtop = parseFloat(div.dataset.top)+dy + div.style.left = newleft+'px' + div.style.top = newtop+'px' + draw_links(id,mods.ui.link_color) + } + } +function name_mouseup(evt) { + evt.preventDefault() + evt.stopPropagation() + var t = mods_transform() + for (var id in mods.ui.selected) { + var div = document.getElementById(id) + div.style.zIndex = 0 + div.childNodes[0].style.fontWeight = 'normal' + var dx = (evt.clientX-mods.ui.xstart)/t.s + var dy = (evt.clientY-mods.ui.ystart)/t.s + div.dataset.left = parseFloat(div.dataset.left)+dx + div.dataset.top = parseFloat(div.dataset.top)+dy + window.removeEventListener('mousemove',name_mousemove) + window.removeEventListener('mouseup',name_mouseup) + } + mods.ui.selected = {} + } +function name_touchdown(evt) { + evt.preventDefault() + evt.stopPropagation() + var div = document.getElementById(evt.target.parentNode.id) + div.style.zIndex = 1 + mods.ui.xstart = evt.changedTouches[0].pageX + mods.ui.ystart = evt.changedTouches[0].pageY + mods.ui.selected[evt.target.parentNode.id] = true + window.addEventListener('touchmove',name_touchmove) + window.addEventListener('touchend',name_touchup) + } +function name_touchmove(evt) { + evt.preventDefault() + evt.stopPropagation() + var t = mods_transform() + for (var id in mods.ui.selected) { + var div = document.getElementById(id) + var dx = (evt.changedTouches[0].pageX-mods.ui.xstart)/t.s + var dy = (evt.changedTouches[0].pageY-mods.ui.ystart)/t.s + var newleft = parseFloat(div.dataset.left)+dx + var newtop = parseFloat(div.dataset.top)+dy + div.style.left = newleft+'px' + div.style.top = newtop+'px' + draw_links(id,mods.ui.link_color) + } + } +function name_touchup(evt) { + evt.preventDefault() + evt.stopPropagation() + var t = mods_transform() + for (var id in mods.ui.selected) { + var div = document.getElementById(id) + div.style.zIndex = 0 + var dx = (evt.changedTouches[0].pageX-mods.ui.xstart)/t.s + var dy = (evt.changedTouches[0].pageY-mods.ui.ystart)/t.s + div.dataset.left = parseFloat(div.dataset.left)+dx + div.dataset.top = parseFloat(div.dataset.top)+dy + window.removeEventListener('touchmove',name_touchmove) + window.removeEventListener('touchend',name_touchup) + } + mods.ui.selected = {} + } +})() var prog = JSON.parse(JSON.stringify({"modules":{"0.47383876715576023":{"definition":"//\n// distance transform \n// assumes thresholded image, with zero intensity exterior\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2015,6\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \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 = 'distance transform'\n//\n// initialization\n//\nvar init = function() {\n }\n//\n// inputs\n//\nvar inputs = {\n image:{type:'RGBA',\n event:function(evt){\n mod.input = evt.detail\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = mod.input.width\n ctx.canvas.height = mod.input.height \n ctx.putImageData(mod.input,0,0)\n distance_transform()}}}\n//\n// outputs\n//\nvar outputs = {\n distances:{type:'F32',\n event:function(){\n mod.distances.height = mod.input.height\n mod.distances.width = mod.input.width\n mods.output(mod,'distances',mod.distances)}}}\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 div.appendChild(document.createElement('br'))\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 }\n//\n// local functions\n//\n// distance transform function\n//\nfunction distance_transform() {\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 mod.distances = new Float32Array(evt.data.buffer)\n var imgbuf = new Uint8ClampedArray(h*w*4)\n var dmax = -Number.MAX_VALUE\n for (var y = 0; y < h; ++y) {\n for (var x = 0; x < w; ++x) {\n if (mod.distances[(h-1-y)*w+x] > dmax)\n dmax = mod.distances[(h-1-y)*w+x]\n }\n }\n var i\n for (var y = 0; y < h; ++y) {\n for (var x = 0; x < w; ++x) {\n i = 255*mod.distances[(h-1-y)*w+x]/dmax\n imgbuf[(h-1-y)*w*4+x*4+0] = i\n imgbuf[(h-1-y)*w*4+x*4+1] = i\n imgbuf[(h-1-y)*w*4+x*4+2] = i\n imgbuf[(h-1-y)*w*4+x*4+3] = 255\n }\n }\n var imgdata = new ImageData(imgbuf,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.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n webworker.terminate()\n outputs.distances.event()\n })\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n var ctx = mod.img.getContext(\"2d\")\n ctx.putImageData(mod.input,0,0)\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n webworker.postMessage({\n height:mod.input.height,width:mod.input.width,\n buffer:img.data.buffer},\n [img.data.buffer])\n }\n//\n// distance transform worker\n//\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var ny = evt.data.height\n var nx = evt.data.width\n var input = new Uint8ClampedArray(evt.data.buffer)\n var output = new Float32Array(nx*ny)\n function distance(g,x,y,i) {\n return ((y-i)*(y-i)+g[i][x]*g[i][x])\n }\n function intersection(g,x,y0,y1) {\n return ((g[y0][x]*g[y0][x]-g[y1][x]*g[y1][x]+y0*y0-y1*y1)/(2.0*(y0-y1)))\n }\n //\n // allocate arrays\n //\n var g = []\n for (var y = 0; y < ny; ++y)\n g[y] = new Uint32Array(nx)\n var h = []\n for (var y = 0; y < ny; ++y)\n h[y] = new Uint32Array(nx)\n var distances = []\n for (var y = 0; y < ny; ++y)\n distances[y] = new Uint32Array(nx)\n var starts = new Uint32Array(ny)\n var minimums = new Uint32Array(ny)\n var d\n //\n // column scan\n // \n for (var y = 0; y < ny; ++y) {\n //\n // right pass\n //\n var closest = -nx\n for (var x = 0; x < nx; ++x) {\n if (input[(ny-1-y)*nx*4+x*4+0] != 0) {\n g[y][x] = 0\n closest = x\n }\n else\n g[y][x] = (x-closest)\n }\n //\n // left pass\n //\n closest = 2*nx\n for (var x = (nx-1); x >= 0; --x) {\n if (input[(ny-1-y)*nx*4+x*4+0] != 0)\n closest = x\n else {\n d = (closest-x)\n if (d < g[y][x])\n g[y][x] = d\n }\n }\n }\n //\n // row scan\n //\n for (var x = 0; x < nx; ++x) {\n var segment = 0\n starts[0] = 0\n minimums[0] = 0\n //\n // down \n //\n for (var y = 1; y < ny; ++y) {\n while ((segment >= 0) &&\n (distance(g,x,starts[segment],minimums[segment]) > distance(g,x,starts[segment],y)))\n segment -= 1\n if (segment < 0) {\n segment = 0\n minimums[0] = y\n }\n else {\n newstart = 1+intersection(g,x,minimums[segment],y)\n if (newstart < ny) {\n segment += 1\n minimums[segment] = y\n starts[segment] = newstart\n }\n }\n }\n //\n // up \n //\n for (var y = (ny-1); y >= 0; --y) {\n d = Math.sqrt(distance(g,x,y,minimums[segment]))\n output[(ny-1-y)*nx+x] = d\n if (y == starts[segment])\n segment -= 1\n }\n }\n self.postMessage({buffer:output.buffer},[output.buffer])\n })\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"1287.611647642926","left":"4490.813999470311","filename":"undefined","inputs":{},"outputs":{}},"0.07944144280928633":{"definition":"//\n// edge detect\n// green = interior, blue = exterior, red = boundary\n// assumes input is thresholded\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2015,6\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \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 = 'edge detect'\n//\n// initialization\n//\nvar init = function() {\n }\n//\n// inputs\n//\nvar inputs = {\n image:{type:'RGBA',\n event:function(evt){\n mod.input = evt.detail\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = mod.input.width\n ctx.canvas.height = mod.input.height \n ctx.putImageData(mod.input,0,0)\n edge_detect()}}}\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// 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 win.document.body.appendChild(document.createTextNode('green:interior, blue:exterior, red:boundary'))\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 }\n//\n// local functions\n//\n// edge detect\n//\nfunction edge_detect() {\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.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n webworker.terminate()\n outputs.image.event()\n })\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n webworker.postMessage({worker:worker.toString(),\n height:mod.input.height,width:mod.input.width,\n buffer:mod.input.data.buffer},\n [mod.input.data.buffer])\n }\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var input = new Uint8ClampedArray(evt.data.buffer)\n var output = new Uint8ClampedArray(h*w*4)\n var i00,i0m,i0p,im0,ip0,imm,imp,ipm,ipp,row,col\n //\n // find edges - interior\n //\n for (row = 1; row < (h-1); ++row) {\n for (col = 1; col < (w-1); ++col) {\n i00 = (input[(h-1-row)*w*4+col*4+0] \n +input[(h-1-row)*w*4+col*4+1] \n +input[(h-1-row)*w*4+col*4+2])\n i0p = (input[(h-1-row)*w*4+(col+1)*4+0] \n +input[(h-1-row)*w*4+(col+1)*4+1] \n +input[(h-1-row)*w*4+(col+1)*4+2])\n ip0 = (input[(h-2-row)*w*4+col*4+0] \n +input[(h-2-row)*w*4+col*4+1] \n +input[(h-2-row)*w*4+col*4+2])\n ipp = (input[(h-2-row)*w*4+(col+1)*4+0] \n +input[(h-2-row)*w*4+(col+1)*4+1] \n +input[(h-2-row)*w*4+(col+1)*4+2])\n i0m = (input[(h-1-row)*w*4+(col-1)*4+0] \n +input[(h-1-row)*w*4+(col-1)*4+1] \n +input[(h-1-row)*w*4+(col-1)*4+2])\n im0 = (input[(h-row)*w*4+col*4+0] \n +input[(h-row)*w*4+col*4+1] \n +input[(h-row)*w*4+col*4+2])\n imm = (input[(h-row)*w*4+(col-1)*4+0] \n +input[(h-row)*w*4+(col-1)*4+1] \n +input[(h-row)*w*4+(col-1)*4+2])\n imp = (input[(h-row)*w*4+(col+1)*4+0] \n +input[(h-row)*w*4+(col+1)*4+1] \n +input[(h-row)*w*4+(col+1)*4+2])\n ipm = (input[(h-2-row)*w*4+(col-1)*4+0] \n +input[(h-2-row)*w*4+(col-1)*4+1] \n +input[(h-2-row)*w*4+(col-1)*4+2])\n if ((i00 != i0p) || (i00 != ip0) || (i00 != ipp) \n || (i00 != i0m) || (i00 != im0) || (i00 != imm)\n || (i00 != imp) || (i00 != ipm)) {\n output[(h-1-row)*w*4+col*4+0] = 255\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else if (i00 == 0) {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 255\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 255\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n }\n }\n //\n // left and right edges\n //\n for (row = 1; row < (h-1); ++row) {\n col = w-1\n i00 = (input[(h-1-row)*w*4+col*4+0] \n +input[(h-1-row)*w*4+col*4+1] \n +input[(h-1-row)*w*4+col*4+2])\n i0m = (input[(h-1-row)*w*4+(col-1)*4+0] \n +input[(h-1-row)*w*4+(col-1)*4+1] \n +input[(h-1-row)*w*4+(col-1)*4+2])\n imm = (input[(h-row)*w*4+(col-1)*4+0] \n +input[(h-row)*w*4+(col-1)*4+1] \n +input[(h-row)*w*4+(col-1)*4+2])\n ipm = (input[(h-2-row)*w*4+(col-1)*4+0] \n +input[(h-2-row)*w*4+(col-1)*4+1] \n +input[(h-2-row)*w*4+(col-1)*4+2])\n im0 = (input[(h-row)*w*4+col*4+0] \n +input[(h-row)*w*4+col*4+1] \n +input[(h-row)*w*4+col*4+2])\n ip0 = (input[(h-2-row)*w*4+col*4+0] \n +input[(h-2-row)*w*4+col*4+1] \n +input[(h-2-row)*w*4+col*4+2])\n if ((i00 != i0m) || (i00 != ip0) || (i00 != ipm) \n || (i00 != im0) || (i00 != imm)) {\n output[(h-1-row)*w*4+col*4+0] = 255\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else if (i00 == 0) {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 255\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 255\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n col = 0\n i00 = (input[(h-1-row)*w*4+col*4+0] \n +input[(h-1-row)*w*4+col*4+1] \n +input[(h-1-row)*w*4+col*4+2])\n i0p = (input[(h-1-row)*w*4+(col+1)*4+0] \n +input[(h-1-row)*w*4+(col+1)*4+1] \n +input[(h-1-row)*w*4+(col+1)*4+2])\n imp = (input[(h-row)*w*4+(col+1)*4+0] \n +input[(h-row)*w*4+(col+1)*4+1] \n +input[(h-row)*w*4+(col+1)*4+2])\n ipp = (input[(h-2-row)*w*4+(col+1)*4+0] \n +input[(h-2-row)*w*4+(col+1)*4+1] \n +input[(h-2-row)*w*4+(col+1)*4+2])\n im0 = (input[(h-row)*w*4+col*4+0] \n +input[(h-row)*w*4+col*4+1] \n +input[(h-row)*w*4+col*4+2])\n ip0 = (input[(h-2-row)*w*4+col*4+0] \n +input[(h-2-row)*w*4+col*4+1] \n +input[(h-2-row)*w*4+col*4+2])\n if ((i00 != i0p) || (i00 != ip0) || (i00 != ipp) \n || (i00 != im0) || (i00 != imp)) {\n output[(h-1-row)*w*4+col*4+0] = 255\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else if (i00 == 0) {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 255\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 255\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n }\n //\n // top and bottom edges\n //\n for (col = 1; col < (w-1); ++col) {\n row = h-1\n i00 = (input[(h-1-row)*w*4+col*4+0] \n +input[(h-1-row)*w*4+col*4+1] \n +input[(h-1-row)*w*4+col*4+2])\n i0m = (input[(h-1-row)*w*4+(col-1)*4+0] \n +input[(h-1-row)*w*4+(col-1)*4+1] \n +input[(h-1-row)*w*4+(col-1)*4+2])\n i0p = (input[(h-1-row)*w*4+(col+1)*4+0] \n +input[(h-1-row)*w*4+(col+1)*4+1] \n +input[(h-1-row)*w*4+(col+1)*4+2])\n imm = (input[(h-row)*w*4+(col-1)*4+0] \n +input[(h-row)*w*4+(col-1)*4+1] \n +input[(h-row)*w*4+(col-1)*4+2])\n im0 = (input[(h-row)*w*4+col*4+0] \n +input[(h-row)*w*4+col*4+1] \n +input[(h-row)*w*4+col*4+2])\n imp = (input[(h-row)*w*4+(col+1)*4+0] \n +input[(h-row)*w*4+(col+1)*4+1] \n +input[(h-row)*w*4+(col+1)*4+2])\n if ((i00 != i0m) || (i00 != i0p) || (i00 != imm) \n || (i00 != im0) || (i00 != imp)) {\n output[(h-1-row)*w*4+col*4+0] = 255\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else if (i00 == 0) {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 255\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 255\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n row = 0\n i00 = (input[(h-1-row)*w*4+col*4+0] \n +input[(h-1-row)*w*4+col*4+1] \n +input[(h-1-row)*w*4+col*4+2])\n i0m = (input[(h-1-row)*w*4+(col-1)*4+0] \n +input[(h-1-row)*w*4+(col-1)*4+1] \n +input[(h-1-row)*w*4+(col-1)*4+2])\n i0p = (input[(h-1-row)*w*4+(col+1)*4+0] \n +input[(h-1-row)*w*4+(col+1)*4+1] \n +input[(h-1-row)*w*4+(col+1)*4+2])\n ipm = (input[(h-2-row)*w*4+(col-1)*4+0] \n +input[(h-2-row)*w*4+(col-1)*4+1] \n +input[(h-2-row)*w*4+(col-1)*4+2])\n ip0 = (input[(h-2-row)*w*4+col*4+0] \n +input[(h-2-row)*w*4+col*4+1] \n +input[(h-2-row)*w*4+col*4+2])\n ipp = (input[(h-2-row)*w*4+(col+1)*4+0] \n +input[(h-2-row)*w*4+(col+1)*4+1] \n +input[(h-2-row)*w*4+(col+1)*4+2])\n if ((i00 != i0m) || (i00 != i0p) || (i00 != ipm) \n || (i00 != ip0) || (i00 != ipp)) {\n output[(h-1-row)*w*4+col*4+0] = 255\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else if (i00 == 0) {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 255\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 255\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n }\n //\n // corners\n //\n row = 0\n col = 0\n i00 = (input[(h-1-row)*w*4+col*4+0] \n +input[(h-1-row)*w*4+col*4+1] \n +input[(h-1-row)*w*4+col*4+2])\n i0p = (input[(h-1-row)*w*4+(col+1)*4+0] \n +input[(h-1-row)*w*4+(col+1)*4+1] \n +input[(h-1-row)*w*4+(col+1)*4+2])\n ip0 = (input[(h-2-row)*w*4+col*4+0] \n +input[(h-2-row)*w*4+col*4+1] \n +input[(h-2-row)*w*4+col*4+2])\n ipp = (input[(h-2-row)*w*4+(col+1)*4+0] \n +input[(h-2-row)*w*4+(col+1)*4+1] \n +input[(h-2-row)*w*4+(col+1)*4+2])\n if ((i00 != i0p) || (i00 != ip0) || (i00 != ipp)) {\n output[(h-1-row)*w*4+col*4+0] = 255\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else if (i00 == 0) {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 255\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 255\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n row = 0\n col = w-1\n i00 = (input[(h-1-row)*w*4+col*4+0] \n +input[(h-1-row)*w*4+col*4+1] \n +input[(h-1-row)*w*4+col*4+2])\n i0m = (input[(h-1-row)*w*4+(col-1)*4+0] \n +input[(h-1-row)*w*4+(col-1)*4+1] \n +input[(h-1-row)*w*4+(col-1)*4+2])\n ip0 = (input[(h-2-row)*w*4+col*4+0] \n +input[(h-2-row)*w*4+col*4+1] \n +input[(h-2-row)*w*4+col*4+2])\n ipm = (input[(h-2-row)*w*4+(col-1)*4+0] \n +input[(h-2-row)*w*4+(col-1)*4+1] \n +input[(h-2-row)*w*4+(col-1)*4+2])\n if ((i00 != i0m) || (i00 != ip0) || (i00 != ipm)) {\n output[(h-1-row)*w*4+col*4+0] = 255\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else if (i00 == 0) {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 255\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 255\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n row = h-1\n col = 0\n i00 = (input[(h-1-row)*w*4+col*4+0] \n +input[(h-1-row)*w*4+col*4+1] \n +input[(h-1-row)*w*4+col*4+2])\n i0p = (input[(h-1-row)*w*4+(col+1)*4+0] \n +input[(h-1-row)*w*4+(col+1)*4+1] \n +input[(h-1-row)*w*4+(col+1)*4+2])\n im0 = (input[(h-row)*w*4+col*4+0] \n +input[(h-row)*w*4+col*4+1] \n +input[(h-row)*w*4+col*4+2])\n imp = (input[(h-row)*w*4+(col+1)*4+0] \n +input[(h-row)*w*4+(col+1)*4+1] \n +input[(h-row)*w*4+(col+1)*4+2])\n if ((i00 != i0p) || (i00 != im0) || (i00 != imp)) {\n output[(h-1-row)*w*4+col*4+0] = 255\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else if (i00 == 0) {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 255\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 255\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n row = h-1\n col = w-1\n i00 = (input[(h-1-row)*w*4+col*4+0] \n +input[(h-1-row)*w*4+col*4+1] \n +input[(h-1-row)*w*4+col*4+2])\n i0m = (input[(h-1-row)*w*4+(col-1)*4+0] \n +input[(h-1-row)*w*4+(col-1)*4+1] \n +input[(h-1-row)*w*4+(col-1)*4+2])\n im0 = (input[(h-row)*w*4+col*4+0] \n +input[(h-row)*w*4+col*4+1] \n +input[(h-row)*w*4+col*4+2])\n imm = (input[(h-row)*w*4+(col-1)*4+0] \n +input[(h-row)*w*4+(col-1)*4+1] \n +input[(h-row)*w*4+(col-1)*4+2])\n if ((i00 != i0m) || (i00 != im0) || (i00 != imm)) {\n output[(h-1-row)*w*4+col*4+0] = 255\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else if (i00 == 0) {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 255\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 255\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n self.postMessage({buffer:output.buffer},[output.buffer])\n })\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"1904.6116476429258","left":"4948.813999470311","filename":"undefined","inputs":{},"outputs":{}},"0.8903773266711255":{"definition":"//\n// orient edges\n// input is green:interior, blue:exterior, red:boundary\n// output is red 128:north,64:south, green 128:east,64:west, blue 128:start,64:stop\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2016\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \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 = 'orient edges'\n//\n// initialization\n//\nvar init = function() {\n }\n//\n// inputs\n//\nvar inputs = {\n image:{type:'RGBA',\n event:function(evt){\n mod.input = evt.detail\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = mod.input.width\n ctx.canvas.height = mod.input.height \n ctx.putImageData(mod.input,0,0)\n var ctx = mod.display.getContext(\"2d\")\n ctx.canvas.width = mod.input.width\n ctx.canvas.height = mod.input.height \n orient_edges()\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// 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 // off-screen display canvas\n //\n var canvas = document.createElement('canvas')\n mod.display = 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 win.document.body.appendChild(document.createTextNode('red:north, dark red:south'))\n win.document.body.appendChild(document.createElement('br'))\n win.document.body.appendChild(document.createTextNode('green:east, dark green:west'))\n win.document.body.appendChild(document.createElement('br'))\n win.document.body.appendChild(document.createTextNode('blue:start, dark blue:stop'))\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.display,0,0)\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n// orient edges\n//\nfunction orient_edges() {\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 var disp = new Uint8ClampedArray(evt.data.display)\n var dispdata = new ImageData(disp,w,h)\n var ctx = mod.display.getContext(\"2d\")\n ctx.putImageData(dispdata,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 w = mod.canvas.width\n var h = mod.canvas.height\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,w,h)\n ctx.drawImage(mod.display,x0,y0,wd,hd)\n webworker.terminate()\n outputs.image.event()\n })\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n webworker.postMessage({\n height:mod.input.height,width:mod.input.width,\n buffer:mod.input.data.buffer},\n [mod.input.data.buffer])\n }\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var input = new Uint8ClampedArray(evt.data.buffer)\n var output = new Uint8ClampedArray(h*w*4)\n var row,col\n var boundary = 0\n var interior = 1\n var exterior = 2\n var alpha = 3\n var northsouth = 0\n var north = 128\n var south = 64\n var eastwest = 1\n var east = 128\n var west = 64\n var startstop = 2\n var start = 128\n var stop = 64\n //\n // orient body states\n //\n for (row = 1; row < (h-1); ++row) {\n for (col = 1; col < (w-1); ++col) {\n output[(h-1-row)*w*4+col*4+northsouth] = 0\n output[(h-1-row)*w*4+col*4+eastwest] = 0\n output[(h-1-row)*w*4+col*4+startstop] = 0\n output[(h-1-row)*w*4+col*4+alpha] = 255\n if (input[(h-1-(row))*w*4+(col)*4+boundary] != 0) {\n if ((input[(h-1-(row+1))*w*4+(col)*4+boundary] != 0)\n && ((input[(h-1-(row))*w*4+(col+1)*4+interior] != 0)\n || (input[(h-1-(row+1))*w*4+(col+1)*4+interior] != 0)))\n output[(h-1-row)*w*4+col*4+northsouth] |= north\n if ((input[(h-1-(row-1))*w*4+(col)*4+boundary] != 0)\n && ((input[(h-1-(row))*w*4+(col-1)*4+interior] != 0)\n || (input[(h-1-(row-1))*w*4+(col-1)*4+interior] != 0)))\n output[(h-1-row)*w*4+col*4+northsouth] |= south\n if ((input[(h-1-(row))*w*4+(col+1)*4+boundary] != 0)\n && ((input[(h-1-(row-1))*w*4+(col)*4+interior] != 0)\n || (input[(h-1-(row-1))*w*4+(col+1)*4+interior] != 0)))\n output[(h-1-row)*w*4+col*4+eastwest] |= east\n if ((input[(h-1-(row))*w*4+(col-1)*4+boundary] != 0)\n && ((input[(h-1-(row+1))*w*4+(col)*4+interior] != 0)\n || (input[(h-1-(row+1))*w*4+(col-1)*4+interior] != 0)))\n output[(h-1-row)*w*4+col*4+eastwest] |= west\n }\n }\n }\n //\n // orient edge states\n //\n for (col = 1; col < (w-1); ++col) {\n row = 0\n output[(h-1-row)*w*4+col*4+northsouth] = 0\n output[(h-1-row)*w*4+col*4+eastwest] = 0\n output[(h-1-row)*w*4+col*4+startstop] = 0\n output[(h-1-row)*w*4+col*4+alpha] = 255\n if (input[(h-1-(row))*w*4+(col)*4+boundary] != 0) {\n if ((input[(h-1-(row+1))*w*4+(col)*4+boundary] != 0)\n && (input[(h-1-(row))*w*4+(col+1)*4+interior] != 0)) {\n output[(h-1-row)*w*4+col*4+northsouth] |= north\n output[(h-1-row)*w*4+col*4+startstop] |= start\n }\n if (input[(h-1-(row))*w*4+(col-1)*4+interior] != 0)\n output[(h-1-row)*w*4+col*4+startstop] |= stop\n }\n row = h-1\n output[(h-1-row)*w*4+col*4+northsouth] = 0\n output[(h-1-row)*w*4+col*4+eastwest] = 0\n output[(h-1-row)*w*4+col*4+startstop] = 0\n output[(h-1-row)*w*4+col*4+alpha] = 255\n if (input[(h-1-(row))*w*4+(col)*4+boundary] != 0) {\n if (input[(h-1-(row))*w*4+(col+1)*4+interior] != 0)\n output[(h-1-row)*w*4+col*4+startstop] |= stop\n if ((input[(h-1-(row-1))*w*4+(col)*4+boundary] != 0)\n && (input[(h-1-(row))*w*4+(col-1)*4+interior] != 0)) {\n output[(h-1-row)*w*4+col*4+northsouth] |= south\n output[(h-1-row)*w*4+col*4+startstop] |= start\n }\n }\n }\n for (row = 1; row < (h-1); ++row) {\n col = 0\n output[(h-1-row)*w*4+col*4+northsouth] = 0\n output[(h-1-row)*w*4+col*4+eastwest] = 0\n output[(h-1-row)*w*4+col*4+startstop] = 0\n output[(h-1-row)*w*4+col*4+alpha] = 255\n if (input[(h-1-(row))*w*4+(col)*4+boundary] != 0) {\n if ((input[(h-1-(row))*w*4+(col+1)*4+boundary] != 0)\n && (input[(h-1-(row-1))*w*4+(col)*4+interior] != 0)) {\n output[(h-1-row)*w*4+col*4+eastwest] |= east\n output[(h-1-row)*w*4+col*4+startstop] |= start\n }\n if (input[(h-1-(row+1))*w*4+(col)*4+interior] != 0)\n output[(h-1-row)*w*4+col*4+startstop] |= stop\n }\n col = w-1\n output[(h-1-row)*w*4+col*4+northsouth] = 0\n output[(h-1-row)*w*4+col*4+eastwest] = 0\n output[(h-1-row)*w*4+col*4+startstop] = 0\n output[(h-1-row)*w*4+col*4+alpha] = 255\n if (input[(h-1-(row))*w*4+(col)*4+boundary] != 0) {\n if (input[(h-1-(row-1))*w*4+(col)*4+interior] != 0)\n output[(h-1-row)*w*4+col*4+startstop] |= stop\n if ((input[(h-1-(row))*w*4+(col-1)*4+boundary] != 0)\n && (input[(h-1-(row+1))*w*4+(col)*4+interior] != 0)) {\n output[(h-1-row)*w*4+col*4+eastwest] |= west\n output[(h-1-row)*w*4+col*4+startstop] |= start\n }\n }\n }\n //\n // orient corner states (todo)\n //\n row = 0\n col = 0\n output[(h-1-row)*w*4+col*4+northsouth] = 0\n output[(h-1-row)*w*4+col*4+eastwest] = 0\n output[(h-1-row)*w*4+col*4+startstop] = 0\n output[(h-1-row)*w*4+col*4+alpha] = 255\n row = h-1\n col = 0\n output[(h-1-row)*w*4+col*4+northsouth] = 0\n output[(h-1-row)*w*4+col*4+eastwest] = 0\n output[(h-1-row)*w*4+col*4+startstop] = 0\n output[(h-1-row)*w*4+col*4+alpha] = 255\n row = 0\n col = w-1\n output[(h-1-row)*w*4+col*4+northsouth] = 0\n output[(h-1-row)*w*4+col*4+eastwest] = 0\n output[(h-1-row)*w*4+col*4+startstop] = 0\n output[(h-1-row)*w*4+col*4+alpha] = 255\n row = h-1\n col = w-1\n output[(h-1-row)*w*4+col*4+northsouth] = 0\n output[(h-1-row)*w*4+col*4+eastwest] = 0\n output[(h-1-row)*w*4+col*4+startstop] = 0\n output[(h-1-row)*w*4+col*4+alpha] = 255\n //\n // invert background for display\n //\n var display = new Uint8ClampedArray(h*w*4)\n var r,g,b,i\n for (row = 0; row < h; ++row) {\n for (col = 0; col < w; ++col) {\n r = output[(h-1-row)*w*4+col*4+0]\n g = output[(h-1-row)*w*4+col*4+1]\n b = output[(h-1-row)*w*4+col*4+2]\n i = r+g+b\n if (i != 0) { \n display[(h-1-row)*w*4+col*4+0] = output[(h-1-row)*w*4+col*4+0]\n display[(h-1-row)*w*4+col*4+1] = output[(h-1-row)*w*4+col*4+1]\n display[(h-1-row)*w*4+col*4+2] = output[(h-1-row)*w*4+col*4+2]\n display[(h-1-row)*w*4+col*4+3] = output[(h-1-row)*w*4+col*4+3]\n }\n else {\n display[(h-1-row)*w*4+col*4+0] = 255\n display[(h-1-row)*w*4+col*4+1] = 255\n display[(h-1-row)*w*4+col*4+2] = 255\n display[(h-1-row)*w*4+col*4+3] = 255\n }\n }\n }\n //\n // return output\n //\n self.postMessage({buffer:output.buffer,display:display.buffer},[output.buffer,display.buffer])\n })\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"1774.611647642926","left":"4517.813999470311","filename":"undefined","inputs":{},"outputs":{}},"0.3135579179893032":{"definition":"//\n// distance transform \n// assumes thresholded image, with zero intensity exterior\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2015,6\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \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 = 'offset'\n//\n// initialization\n//\nvar init = function() {\n mod.offset.value = ''\n }\n//\n// inputs\n//\nvar inputs = {\n distances:{type:'F32',\n event:function(evt){\n mod.distances = evt.detail\n var h = mod.distances.height\n var w = mod.distances.width\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.height = mod.distances.height \n ctx.canvas.width = mod.distances.width\n if (mod.offset.value != '')\n offset()\n }},\n offset:{type:'number',\n event:function(evt){\n mod.offset.value = evt.detail\n offset()}}}\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// 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 // offset value\n //\n div.appendChild(document.createTextNode('offset (pixels): '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function(){\n offset()\n })\n div.appendChild(input)\n mod.offset = input\n //\n // view button\n //\n div.appendChild(document.createElement('br'))\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 }\n//\n// local functions\n//\n// offset\n//\nfunction offset() {\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.distances.height\n var w = mod.distances.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.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n webworker.terminate()\n outputs.image.event()\n })\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n var offset = parseFloat(mod.offset.value)\n webworker.postMessage({\n height:mod.distances.height,width:mod.distances.width,\n offset:offset,buffer:mod.distances.buffer})\n }\n//\n// offset worker\n//\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var offset = evt.data.offset\n var input = new Float32Array(evt.data.buffer)\n var output = new Uint8ClampedArray(4*h*w)\n for (var row = 0; row < h; ++row) {\n for (var col = 0; col < w; ++col) {\n if (input[(h-1-row)*w+col] <= offset) {\n output[(h-1-row)*w*4+col*4+0] = 255\n output[(h-1-row)*w*4+col*4+1] = 255\n output[(h-1-row)*w*4+col*4+2] = 255\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n else {\n output[(h-1-row)*w*4+col*4+0] = 0\n output[(h-1-row)*w*4+col*4+1] = 0\n output[(h-1-row)*w*4+col*4+2] = 0\n output[(h-1-row)*w*4+col*4+3] = 255\n }\n }\n }\n self.postMessage({buffer:output.buffer},[output.buffer])\n })\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"1387.611647642926","left":"4949.813999470311","filename":"undefined","inputs":{},"outputs":{}},"0.08127540142793499":{"definition":"//\n// read png\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2015,6\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \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 = 'read png'\n//\n// initialization\n//\nvar init = function() {\n }\n//\n// inputs\n//\nvar inputs = {\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 imageInfo:{type:'object',\n event:function(){\n var obj = {}\n obj.name = mod.name.nodeValue\n obj.dpi = parseFloat(mod.dpitext.value)\n obj.width = mod.img.width\n obj.height = mod.img.height\n mods.output(mod,'imageInfo',obj)}}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // file input control\n //\n var file = document.createElement('input')\n file.setAttribute('type','file')\n file.setAttribute('id',div.id+'file_input')\n file.style.position = 'absolute'\n file.style.left = 0\n file.style.top = 0\n file.style.width = 0\n file.style.height = 0\n file.style.opacity = 0\n file.addEventListener('change',function() {\n png_read_handler()\n })\n div.appendChild(file)\n mod.file = file\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 // file select 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('select png file'))\n btn.addEventListener('click',function(){\n var file = document.getElementById(div.id+'file_input')\n file.value = null\n file.click()\n })\n div.appendChild(btn)\n div.appendChild(document.createElement('br'))\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 // invert 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('invert'))\n btn.addEventListener('click',function(){\n invert_image()\n })\n div.appendChild(btn)\n div.appendChild(document.createElement('br'))\n //\n // info div\n //\n var info = document.createElement('div')\n info.setAttribute('id',div.id+'info')\n info.appendChild(document.createTextNode('dpi: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('input',function(){\n mod.dpi = parseFloat(mod.dpitext.value)\n mod.mmtext.nodeValue = (25.4*mod.img.width/mod.dpi).toFixed(3)\n +' x '+(25.4*mod.img.height/mod.dpi).toFixed(3)+' mm'\n mod.intext.nodeValue = (mod.img.width/mod.dpi).toFixed(3)\n +' x '+(mod.img.height/mod.dpi).toFixed(3)+' in'\n outputs.imageInfo.event()\n })\n info.appendChild(input)\n mod.dpitext = 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('mm: ')\n info.appendChild(text)\n mod.mmtext = text\n info.appendChild(document.createElement('br'))\n var text = document.createTextNode('in: ')\n info.appendChild(text)\n mod.intext = text\n info.appendChild(document.createElement('br'))\n var text = document.createTextNode('')\n info.appendChild(text)\n mod.name = text\n div.appendChild(info)\n }\n//\n// local functions\n//\n// read handler\n//\nfunction png_read_handler(event) {\n var file_reader = new FileReader()\n file_reader.onload = png_binary_handler\n input_file = mod.file.files[0]\n file_name = input_file.name\n mod.name.nodeValue = file_name\n file_reader.readAsArrayBuffer(input_file)\n }\n//\n// binary load handler\n//\nfunction png_binary_handler(event) {\n //\n // get DPI\n //\n // 8 header\n // 4 len, 4 type, data, 4 crc\n // pHYs 4 ppx, 4 ppy, 1 unit: 0 ?, 1 meter\n // IEND\n //\n var units = ppx = ppy = 0\n var buf = event.target.result\n var view = new DataView(buf)\n var ptr = 8\n if (!((view.getUint8(1) == 80) && (view.getUint8(2) == 78) && (view.getUint8(3) == 71))) {\n set_prompt(\"error: PNG header not found\")\n return\n }\n while (1) {\n var length = view.getUint32(ptr)\n ptr += 4\n var type = String.fromCharCode(\n view.getUint8(ptr),view.getUint8(ptr+1),\n view.getUint8(ptr+2),view.getUint8(ptr+3))\n ptr += 4\n if (type == \"pHYs\") {\n ppx = view.getUint32(ptr)\n ppy = view.getUint32(ptr + 4)\n units = view.getUint8(ptr + 8)\n }\n if (type == \"IEND\")\n break\n ptr += length + 4\n }\n if (units == 0) {\n set_prompt(\"no PNG units not found, assuming 72 DPI\")\n ppx = 72*1000/25.4\n }\n dpi = ppx*25.4/1000\n //\n // read as URL for display\n //\n var file_reader = new FileReader()\n file_reader.onload = png_URL_handler\n file_reader.readAsDataURL(input_file)\n }\n//\n// URL load handler\n//\nfunction png_URL_handler(event) {\n var img = new Image()\n img.setAttribute(\"src\",event.target.result)\n img.onload = function() {\n if (img.width > img.height) {\n var x0 = 0\n var y0 = mod.canvas.height*.5*(1-img.height/img.width)\n var w = mod.canvas.width\n var h = mod.canvas.width*img.height/img.width\n }\n else {\n var x0 = mod.canvas.width*.5*(1-img.width/img.height)\n var y0 = 0\n var w = mod.canvas.height*img.width/img.height\n var h = 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(img,x0,y0,w,h)\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = img.width\n ctx.canvas.height = img.height \n ctx.drawImage(img,0,0)\n mod.dpitext.value = dpi.toFixed(3)\n mod.pxtext.nodeValue = img.width+' x '+img.height+' px'\n mod.mmtext.nodeValue = (25.4*img.width/dpi).toFixed(3)\n +' x '+(25.4*img.height/dpi).toFixed(3)+' mm'\n mod.intext.nodeValue = (img.width/dpi).toFixed(3)\n +' x '+(img.height/dpi).toFixed(3)+' in'\n outputs.image.event()\n outputs.imageInfo.event()\n }\n }\n//\n// invert image\n//\nfunction invert_image() {\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.drawImage(mod.img,x0,y0,wd,hd)\n webworker.terminate()\n outputs.image.event()\n })\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n var h = mod.img.height\n var w = mod.img.width\n var ctx = mod.img.getContext(\"2d\")\n var img = ctx.getImageData(0,0,w,h)\n webworker.postMessage({\n height:img.height,width:img.width,buffer:img.data.buffer},\n [img.data.buffer])\n }\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var buf = new Uint8ClampedArray(evt.data.buffer)\n for (var row = 0; row < h; ++row) {\n for (var col = 0; col < w; ++col) {\n buf[(h-1-row)*w*4+col*4+0] \n = 255-buf[(h-1-row)*w*4+col*4+0] \n buf[(h-1-row)*w*4+col*4+1] \n = 255-buf[(h-1-row)*w*4+col*4+1] \n buf[(h-1-row)*w*4+col*4+2] \n = 255-buf[(h-1-row)*w*4+col*4+2] \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 name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"1229.611647642926","left":"2335.8139994703106","filename":"undefined","inputs":{},"outputs":{}},"0.6488303557466412":{"definition":"//\n// image threshold\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2015,6\n// \n// This work may be reproduced, modified, distributed, performed, and \n// displayed for any purpose, but must acknowledge the fab modules \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 = 'image threshold'\n//\n// initialization\n//\nvar init = function() {\n mod.threshold.value = 0.5\n }\n//\n// inputs\n//\nvar inputs = {\n image:{type:'RGBA',\n event:function(evt){\n mod.input = evt.detail\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = mod.input.width\n ctx.canvas.height = mod.input.height \n ctx.putImageData(mod.input,0,0)\n threshold_image()}}}\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// 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 // threshold value\n //\n div.appendChild(document.createTextNode('threshold (0-1): '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function(){\n threshold_image()\n })\n div.appendChild(input)\n mod.threshold = input\n div.appendChild(document.createElement('br'))\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 }\n//\n// local functions\n//\n// threshold image\n//\nfunction threshold_image() {\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.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n ctx.drawImage(mod.img,x0,y0,wd,hd)\n webworker.terminate()\n outputs.image.event()\n })\n var ctx = mod.canvas.getContext(\"2d\")\n ctx.clearRect(0,0,mod.canvas.width,mod.canvas.height)\n var t = parseFloat(mod.threshold.value)\n var ctx = mod.img.getContext(\"2d\")\n ctx.putImageData(mod.input,0,0)\n var img = ctx.getImageData(0,0,mod.img.width,mod.img.height)\n webworker.postMessage({\n height:mod.input.height,width:mod.input.width,threshold:t,\n buffer:img.data.buffer},\n [img.data.buffer])\n }\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var t = evt.data.threshold\n var buf = new Uint8ClampedArray(evt.data.buffer)\n var r,g,b,a,i\n for (var row = 0; row < h; ++row) {\n for (var col = 0; col < w; ++col) {\n r = buf[(h-1-row)*w*4+col*4+0] \n g = buf[(h-1-row)*w*4+col*4+1] \n b = buf[(h-1-row)*w*4+col*4+2] \n a = buf[(h-1-row)*w*4+col*4+3] \n i = (r+g+b)/(3*255)\n if (a == 0)\n val = 255\n else if (i > t)\n var val = 255\n else\n var val = 0\n buf[(h-1-row)*w*4+col*4+0] = val\n buf[(h-1-row)*w*4+col*4+1] = val\n buf[(h-1-row)*w*4+col*4+2] = val\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 name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"1420.611647642926","left":"3978.8139994703106","filename":"undefined","inputs":{},"outputs":{}},"0.2892270043957246":{"definition":"//\n// view toolpath\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2016\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// todo:\n// erase and update new path\n// show depth info\n// show size\n// calculate camera far\n//\n// closure\n//\n(function(){\n//\n// module globals\n//\nvar mod = {}\n//\n// name\n//\nvar name = 'view toolpath'\n//\n// initialization\n//\nvar init = function() {\n }\n//\n// inputs\n//\nvar inputs = {\n toolpath:{type:'object',\n event:function(evt){\n mod.path = evt.detail.path\n mod.name = evt.detail.name\n mod.dpi = evt.detail.dpi\n mod.width = evt.detail.width\n mod.height = evt.detail.height\n mod.depth = evt.detail.depth\n show_path_info()\n show_path()\n outputs.toolpath.event()\n }}}\n//\n// outputs\n//\nvar outputs = {\n toolpath:{type:'object',\n event:function(){\n cmd = {}\n cmd.path = mod.path\n cmd.name = mod.name\n cmd.dpi = mod.dpi\n cmd.width = mod.width\n cmd.height = mod.height\n mods.output(mod,'toolpath',cmd)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // info\n //\n var text = document.createTextNode('name: ')\n div.appendChild(text)\n mod.nametext = text\n div.appendChild(document.createElement('br'))\n var text = document.createTextNode('(mm)')\n div.appendChild(text)\n mod.mmtext = text\n div.appendChild(document.createElement('br'))\n var text = document.createTextNode('(in)')\n div.appendChild(text)\n mod.intext = text\n //\n // view\n // \n div.appendChild(document.createElement('br')) \n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n var span = document.createElement('span')\n var text = document.createTextNode('view')\n span.appendChild(text)\n btn.appendChild(span)\n btn.addEventListener('click',function(){\n open_view_window()\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n// show_path_info\n//\nfunction show_path_info() {\n mod.nametext.nodeValue = 'name: '+mod.name\n var width = (25.4*mod.width/mod.dpi).toFixed(3)\n var height = (25.4*mod.height/mod.dpi).toFixed(3)\n var depth = (25.4*mod.depth/mod.dpi).toFixed(3)\n if (mod.depth == undefined)\n mod.mmtext.nodeValue = width+' x '+height+' (mm)'\n else\n mod.mmtext.nodeValue = width+' x '+height+' x '+depth+' (mm)'\n var width = (mod.width/mod.dpi).toFixed(3)\n var height = (mod.height/mod.dpi).toFixed(3)\n var depth = (mod.depth/mod.dpi).toFixed(3)\n if (mod.depth == undefined)\n mod.intext.nodeValue = width+' x '+height+' (in)'\n else\n mod.intext.nodeValue = width+' x '+height+' x '+depth+' (in)'\n mods.fit(mod.div)\n }\n//\n// show_path\n//\nfunction show_path() {\n var scene = mod.scene\n var camera = mod.camera\n var renderer = mod.renderer\n //\n // check if view window open\n //\n if (mod.win == undefined) {\n open_view_window()\n return\n }\n //\n // check for path\n //\n if (mod.path == undefined)\n return\n //\n // clear scene, leave camera\n //\n var length = scene.children.length\n for (var c = (length-1); c > 1; --c) {\n scene.remove(scene.children[c])\n }\n //\n // fit camera\n //\n mod.thetaxy = 0\n mod.thetaz = 0\n mod.r = mod.height/2\n mod.x0 = mod.width/2\n mod.y0 = mod.height/2\n camera.position.set(mod.x0,mod.y0,mod.r)\n camera.up = new THREE.Vector3(0,1,0)\n camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0))\n camera.updateProjectionMatrix()\n //\n // draw segments\n //\n var arrow_size = 1+mod.width/200\n var path = mod.path\n for (var segment = 0; segment < path.length; ++segment) {\n if (segment > 0)\n add_arrow(path[segment-1][path[segment-1].length-1],path[segment][0],0xff0000,arrow_size) \n for (var point = 1; point < path[segment].length; ++point) {\n add_arrow(path[segment][point-1],path[segment][point],0x0000ff,arrow_size)\n }\n }\n //\n // add axes\n //\n var length = mod.height/10\n add_arrow([0,0,0],[length,0,0],0xff0000,arrow_size)\n add_arrow([0,0,0],[0,length,0],0x00ff00,arrow_size)\n add_arrow([0,0,0],[0,0,length],0x0000ff,arrow_size)\n //\n // render\n //\n update()\n //\n // add_arrow\n //\n function add_arrow(start,stop,color,size) {\n var origin = new THREE.Vector3().fromArray(start)\n if (mod.depth == undefined)\n origin.z = 0\n var end = new THREE.Vector3().fromArray(stop)\n if (mod.depth == undefined)\n end.z = 0\n var length = new THREE.Vector3().subVectors(end,origin).length()\n if (length <= size) {\n add_line(origin,end,color)\n //length = 1.1*size\n return\n }\n var direction = new THREE.Vector3().subVectors(end,origin).normalize()\n var arrow = new THREE.ArrowHelper(direction,origin,length,color,size,size)\n scene.add(arrow)\n }\n //\n // add_line\n //\n function add_line(start,stop,colorhex) {\n var geometry = new THREE.Geometry()\n geometry.vertices.push(start,stop)\n var material = new THREE.LineBasicMaterial({color:colorhex})\n var line = new THREE.Line(geometry,material)\n scene.add(line)\n }\n //\n // update\n //\n function update() {\n\t renderer.render(scene,camera)\n }\n }\n//\n// open_view_window\n//\nfunction open_view_window() {\n //\n // globals\n //\n var container,scene,camera,renderer,win,controls\n //\n // open the window\n //\n open_window()\n //\n // open_window\n //\n function open_window() {\n //\n // open window\n //\n win = window.open('')\n mod.win = win\n //\n // load three.js\n //\n var script = document.createElement('script')\n script.type = 'text/javascript'\n script.onload = init_window\n script.src = 'js/three.js/three.min.js'\n mod.div.appendChild(script)\n }\n //\n // init_window\n //\n function init_window() {\n //\n // close button\n //\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 mod.win = undefined\n })\n win.document.body.appendChild(btn)\n //\n // label text\n //\n var text = win.document.createTextNode(' left: pan, right: rotate, scroll: zoom')\n win.document.body.appendChild(text)\n //\n // GL container\n //\n win.document.body.appendChild(document.createElement('br')) \n container = win.document.createElement('div')\n container.style.overflow = 'hidden'\n win.document.body.appendChild(container)\n //\n // event handlers\n //\n container.addEventListener('contextmenu',context_menu)\n container.addEventListener('mousedown',mouse_down)\n container.addEventListener('mouseup',mouse_up)\n container.addEventListener('mousemove',mouse_move)\n container.addEventListener('wheel',mouse_wheel)\n //\n // add scene\n //\n\t scene = new THREE.Scene()\n\t mod.scene = scene\n\t var width = win.innerWidth\n\t var height = win.innerHeight\n\t var aspect = width/height\n\t var near = 0.1\n\t var far = 1000000\n\t camera = new THREE.PerspectiveCamera(90,aspect,near,far)\n\t mod.camera = camera\n\t scene.add(camera)\n\t //\n\t // add renderer\n\t //\n renderer = new THREE.WebGLRenderer({antialias:true})\n mod.renderer = renderer\n renderer.setClearColor(0xffffff)\n\t renderer.setSize(width,height)\n\t container.appendChild(renderer.domElement)\n //\n // show the path if available\n //\n show_path()\n }\n //\n // context_menu\n //\n function context_menu(evt) {\n evt.preventDefault()\n evt.stopPropagation()\n return (false)\n }\n //\n // mouse_down\n //\n function mouse_down(evt) {\n evt.preventDefault()\n evt.stopPropagation()\n mod.button = evt.button\n mod.x = evt.clientX\n mod.y = evt.clientY\n }\n //\n // mouse_up\n //\n function mouse_up(evt) {\n mod.button = undefined\n mod.x = evt.clientX\n mod.y = evt.clientY\n }\n //\n // mouse_move\n //\n function mouse_move(evt) {\n evt.preventDefault()\n evt.stopPropagation()\n var dx = evt.clientX-mod.x\n var dy = evt.clientY-mod.y\n mod.x = evt.clientX\n mod.y = evt.clientY\n if (mod.button == 0) {\n mod.x0 += \n Math.sin(mod.thetaz)*mod.height*dy/win.innerHeight\n -Math.cos(mod.thetaz)*mod.width*dx/win.innerWidth\n mod.y0 += \n Math.cos(mod.thetaz)*mod.height*dy/win.innerHeight\n +Math.sin(mod.thetaz)*mod.width*dx/win.innerWidth\n camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy)\n camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy)\n camera.position.z = mod.r*Math.cos(mod.thetaxy)\n camera.position.z = mod.r*Math.cos(mod.thetaxy)\n\t camera.up = new THREE.Vector3(Math.sin(mod.thetaz),Math.cos(mod.thetaz),0)\n\t camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0))\n camera.updateProjectionMatrix()\n\t renderer.render(scene,camera)\n\t }\n else if (mod.button == 2) {\n mod.thetaxy += dy/win.innerHeight\n mod.thetaz += dx/win.innerWidth\n camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy)\n camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy)\n camera.position.z = mod.r*Math.cos(mod.thetaxy)\n\t camera.up = new THREE.Vector3(Math.sin(mod.thetaz),Math.cos(mod.thetaz),0)\n\t camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0))\n camera.updateProjectionMatrix()\n\t renderer.render(scene,camera)\n\t }\n }\n //\n // mouse_wheel\n //\n function mouse_wheel(evt) {\n evt.preventDefault()\n evt.stopPropagation()\n var dy = evt.deltaY/win.innerHeight\n mod.r += mod.height*dy\n camera.position.x = mod.x0+Math.sin(mod.thetaz)*mod.r*Math.sin(mod.thetaxy)\n camera.position.y = mod.y0+Math.cos(mod.thetaz)*mod.r*Math.sin(mod.thetaxy)\n camera.position.z = mod.r*Math.cos(mod.thetaxy)\n\t camera.lookAt(new THREE.Vector3(mod.x0,mod.y0,0))\n camera.updateProjectionMatrix()\n\t renderer.render(scene,camera)\n }\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"2124.611647642926","left":"3308.8139994703106","filename":"undefined","inputs":{},"outputs":{}},"0.9557599338778935":{"definition":"//\n// mill raster 2D\n//\n// Neil Gershenfeld\n// (c) Massachusetts Institute of Technology 2016\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 = 'mill raster 2D'\n//\n// initialization\n//\nvar init = function() {\n mod.dia_in.value = 0.0156\n mod.dia_mm.value = 25.4*parseFloat(mod.dia_in.value)\n mod.cut_in.value = 0.004\n mod.cut_mm.value = 25.4*parseFloat(mod.cut_in.value)\n mod.max_in.value = 0.004\n mod.max_mm.value = 25.4*parseFloat(mod.max_in.value)\n mod.number.value = 4\n mod.stepover.value = 0.5\n mod.merge.value = 1\n mod.sort.checked = true\n }\n//\n// inputs\n//\nvar inputs = {\n imageInfo:{type:'object',\n event:function(evt){\n mod.name = evt.detail.name\n mod.dpi = evt.detail.dpi\n mod.width = evt.detail.width\n mod.height = evt.detail.height\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = mod.width\n ctx.canvas.height = mod.height\n }},\n path:{type:'array',\n event:function(evt){\n if (mod.label.nodeValue == 'calculating') {\n draw_path(evt.detail)\n accumulate_path(evt.detail)\n mod.offsetCount += 1\n if ((mod.offsetCount != parseInt(mod.number.value)) && (evt.detail.length > 0)) {\n mod.offset += parseFloat(mod.stepover.value)\n outputs.offset.event()\n }\n else {\n mod.label.nodeValue = 'calculate'\n mod.labelspan.style.fontWeight = 'normal'\n merge_path()\n clear_path()\n draw_path(mod.path)\n draw_connections()\n add_depth()\n outputs.toolpath.event()\n }\n }\n }\n },\n settings:{type:'object',\n event:function(evt){\n set_values(evt.detail)\n }\n }\n }\n//\n// outputs\n//\nvar outputs = {\n diameter:{type:'number',\n event:function(){\n mods.output(mod,'diameter',Math.ceil(mod.dpi*mod.dia_in.value))\n }\n },\n offset:{type:'number',\n event:function(){\n var pixels = mod.offset*parseFloat(mod.dia_in.value)*mod.dpi\n mods.output(mod,'offset',pixels)\n }\n },\n toolpath:{type:'object',\n event:function(){\n cmd = {}\n cmd.path = mod.path\n cmd.name = mod.name\n cmd.dpi = mod.dpi\n cmd.width = mod.width\n cmd.height = mod.height\n cmd.depth = mod.depth\n mods.output(mod,'toolpath',cmd)\n }\n }\n }\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // tool diameter\n //\n div.appendChild(document.createTextNode('tool diameter'))\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('input',function(){\n mod.dia_in.value = parseFloat(mod.dia_mm.value)/25.4\n })\n div.appendChild(input)\n mod.dia_mm = input\n div.appendChild(document.createTextNode(' in: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('input',function(){\n mod.dia_mm.value = parseFloat(mod.dia_in.value)*25.4\n })\n div.appendChild(input)\n mod.dia_in = input\n div.appendChild(document.createElement('br'))\n //\n // cut depth\n //\n div.appendChild(document.createTextNode('cut depth'))\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('input',function(){\n mod.cut_in.value = parseFloat(mod.cut_mm.value)/25.4\n })\n div.appendChild(input)\n mod.cut_mm = input\n div.appendChild(document.createTextNode(' in: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('input',function(){\n mod.cut_mm.value = parseFloat(mod.cut_in.value)*25.4\n })\n div.appendChild(input)\n mod.cut_in = input\n div.appendChild(document.createElement('br'))\n //\n // max depth\n //\n div.appendChild(document.createTextNode('max depth'))\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('input',function(){\n mod.max_in.value = parseFloat(mod.max_mm.value)/25.4\n })\n div.appendChild(input)\n mod.max_mm = input\n div.appendChild(document.createTextNode(' in: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('input',function(){\n mod.max_mm.value = parseFloat(mod.max_in.value)*25.4\n })\n div.appendChild(input)\n mod.max_in = input\n div.appendChild(document.createElement('br'))\n //\n // offset number\n //\n div.appendChild(document.createTextNode('offset number: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.number = input\n div.appendChild(document.createTextNode(' (0 = fill)'))\n div.appendChild(document.createElement('br'))\n //\n // offset stepover\n //\n div.appendChild(document.createTextNode('offset stepover: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.stepover = input\n div.appendChild(document.createTextNode(' (1 = diameter)'))\n div.appendChild(document.createElement('br'))\n //\n // direction\n //\n div.appendChild(document.createTextNode('direction: '))\n div.appendChild(document.createTextNode('climb'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'direction'\n input.id = mod.div.id+'climb'\n input.checked = true\n div.appendChild(input)\n mod.climb = input\n div.appendChild(document.createTextNode(' conventional'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'direction'\n input.id = mod.div.id+'conventional'\n div.appendChild(input)\n mod.conventional = input\n div.appendChild(document.createElement('br'))\n //\n // path merge\n //\n div.appendChild(document.createTextNode('path merge: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.merge = input\n div.appendChild(document.createTextNode(' (1 = diameter)'))\n div.appendChild(document.createElement('br'))\n //\n // path order\n //\n div.appendChild(document.createTextNode('path order: '))\n div.appendChild(document.createTextNode('forward'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'order'\n input.id = mod.div.id+'forward'\n input.checked = true\n div.appendChild(input)\n mod.forward = input\n div.appendChild(document.createTextNode(' reverse'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'order'\n input.id = mod.div.id+'reverse'\n div.appendChild(input)\n mod.reverse = input\n div.appendChild(document.createElement('br'))\n //\n // sort distance\n //\n div.appendChild(document.createTextNode('sort distance: '))\n var input = document.createElement('input')\n input.type = 'checkbox'\n input.id = mod.div.id+'sort'\n div.appendChild(input)\n mod.sort = input\n div.appendChild(document.createElement('br'))\n //\n // calculate\n //\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n var span = document.createElement('span')\n var text = document.createTextNode('calculate')\n mod.label = text\n span.appendChild(text)\n mod.labelspan = span\n btn.appendChild(span)\n btn.addEventListener('click',function(){\n mod.label.nodeValue = 'calculating'\n mod.labelspan.style.fontWeight = 'bold'\n mod.offset = 0.5\n mod.offsetCount = 0\n mod.path = []\n clear_path()\n outputs.diameter.event()\n outputs.offset.event()\n })\n div.appendChild(btn)\n div.appendChild(document.createTextNode(' '))\n //\n // view\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 svg = document.getElementById(mod.div.id+'svg')\n var clone = svg.cloneNode(true)\n clone.setAttribute('width',mod.img.width)\n clone.setAttribute('height',mod.img.height)\n win.document.body.appendChild(clone)\n })\n div.appendChild(btn)\n div.appendChild(document.createElement('br'))\n //\n // on-screen SVG\n //\n var svgNS = \"http://www.w3.org/2000/svg\"\n var svg = document.createElementNS(svgNS,\"svg\")\n svg.setAttribute('id',mod.div.id+'svg')\n svg.setAttributeNS(\"http://www.w3.org/2000/xmlns/\",\n \"xmlns:xlink\",\"http://www.w3.org/1999/xlink\")\n svg.setAttribute('width',mods.ui.canvas)\n svg.setAttribute('height',mods.ui.canvas)\n svg.style.backgroundColor = 'rgb(255,255,255)'\n var g = document.createElementNS(svgNS,'g')\n g.setAttribute('id',mod.div.id+'g')\n svg.appendChild(g)\n div.appendChild(svg)\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//\n// local functions\n//\n// set_values\n//\nfunction set_values(settings) {\n for (var s in settings) {\n switch(s) {\n case 'tool diameter (in)':\n mod.dia_in.value = settings[s]\n mod.dia_mm.value = parseFloat(mod.dia_in.value)*25.4\n break\n case 'cut depth (in)':\n mod.cut_in.value = settings[s]\n mod.cut_mm.value = parseFloat(mod.cut_in.value)*25.4\n break\n case 'max depth (in)':\n mod.max_in.value = settings[s]\n mod.max_mm.value = parseFloat(mod.max_in.value)*25.4\n break\n case 'offset number':\n mod.number.value = settings[s]\n break\n }\n }\n }\n//\n// clear_path\n//\nfunction clear_path() {\n var svg = document.getElementById(mod.div.id+'svg')\n svg.setAttribute('viewBox',\"0 0 \"+(mod.img.width-1)+\" \"+(mod.img.height-1))\n var g = document.getElementById(mod.div.id+'g')\n svg.removeChild(g)\n var g = document.createElementNS('http://www.w3.org/2000/svg','g')\n g.setAttribute('id',mod.div.id+'g')\n svg.appendChild(g)\n }\n//\n// accumulate_path\n// todo: replace inefficient insertion sort\n// todo: move sort out of main thread\n//\nfunction accumulate_path(path) {\n var forward = mod.forward.checked\n var conventional = mod.conventional.checked\n var sort = mod.sort.checked\n for (var segnew = 0; segnew < path.length; ++segnew) {\n if (conventional)\n path[segnew].reverse()\n if (mod.path.length == 0)\n mod.path.splice(0,0,path[segnew])\n else if (sort) {\n var xnew = path[segnew][0][0]\n var ynew = path[segnew][0][1]\n var dmin = Number.MAX_VALUE\n var segmin = -1\n for (var segold = 0; segold < mod.path.length; ++segold) {\n var xold = mod.path[segold][0][0]\n var yold = mod.path[segold][0][1]\n var dx = xnew-xold\n var dy = ynew-yold\n var d = Math.sqrt(dx*dx+dy*dy)\n if (d < dmin) {\n dmin = d\n segmin = segold\n }\n }\n if (forward)\n mod.path.splice(segmin+1,0,path[segnew])\n else\n mod.path.splice(segmin,0,path[segnew])\n }\n else {\n if (forward)\n mod.path.splice(mod.path.length,0,path[segnew])\n else\n mod.path.splice(0,0,path[segnew])\n }\n }\n }\n//\n// merge_path\n//\nfunction merge_path() {\n var dmerge = mod.dpi*parseFloat(mod.merge.value)*parseFloat(mod.dia_in.value)\n var seg = 0\n while (seg < (mod.path.length-1)) {\n var xold = mod.path[seg][mod.path[seg].length-1][0]\n var yold = mod.path[seg][mod.path[seg].length-1][1]\n var xnew = mod.path[seg+1][0][0]\n var ynew = mod.path[seg+1][0][1]\n var dx = xnew-xold\n var dy = ynew-yold\n var d = Math.sqrt(dx*dx+dy*dy)\n if (d < dmerge)\n mod.path.splice(seg,2,mod.path[seg].concat(mod.path[seg+1]))\n else\n seg += 1\n }\n }\n//\n// add_depth\n//\nfunction add_depth() {\n var cut = parseFloat(mod.cut_in.value)\n var max = parseFloat(mod.max_in.value)\n var newpath = []\n for (var seg = 0; seg < mod.path.length; ++seg) {\n var depth = cut\n if ((mod.path[seg][0][0] == mod.path[seg][mod.path[seg].length-1][0])\n && (mod.path[seg][0][0] == mod.path[seg][mod.path[seg].length-1][0])) {\n var newseg = []\n while (depth <= max) {\n var idepth = -Math.round(mod.dpi*depth)\n for (var pt = 0; pt < mod.path[seg].length; ++pt) {\n var point = mod.path[seg][pt].concat(idepth)\n newseg.splice(newseg.length,0,point)\n }\n if (depth == max)\n break\n depth += cut\n if (depth > max)\n depth = max\n }\n newpath.splice(newpath.length,0,newseg)\n }\n else {\n var newseg = []\n while (depth <= max) {\n var idepth = -Math.round(mod.dpi*depth)\n for (var pt = 0; pt < mod.path[seg].length; ++pt) {\n var point = mod.path[seg][pt].concat(idepth)\n newseg.splice(newseg.length,0,point)\n }\n newpath.splice(newpath.length,0,newseg)\n newseg = []\n if (depth == max)\n break\n depth += cut\n if (depth > max)\n depth = max\n }\n }\n }\n mod.path = newpath\n mod.depth = Math.round(parseFloat(mod.max_in.value)*mod.dpi)\n }\n//\n// draw_path\n//\nfunction draw_path(path) {\n var g = document.getElementById(mod.div.id+'g')\n var h = mod.img.height\n var w = mod.img.width\n var xend = null\n var yend = null\n //\n // loop over segments\n //\n for (var segment = 0; segment < path.length; ++segment) {\n if (path[segment].length > 1) {\n //\n // loop over points\n //\n for (var point = 1; point < path[segment].length; ++point) {\n var line = document.createElementNS('http://www.w3.org/2000/svg','line')\n line.setAttribute('stroke','black')\n line.setAttribute('stroke-width',1)\n line.setAttribute('stroke-linecap','round')\n var x1 = path[segment][point-1][0]\n var y1 = h-path[segment][point-1][1]-1\n var x2 = path[segment][point][0]\n var y2 = h-path[segment][point][1]-1\n xend = x2\n yend = y2\n line.setAttribute('x1',x1)\n line.setAttribute('y1',y1)\n line.setAttribute('x2',x2)\n line.setAttribute('y2',y2)\n var dx = x2-x1\n var dy = y2-y1\n var d = Math.sqrt(dx*dx+dy*dy)\n if (d > 0) {\n nx = 6*dx/d\n ny = 6*dy/d\n var tx = 3*dy/d\n var ty = -3*dx/d\n g.appendChild(line)\n triangle = document.createElementNS('http://www.w3.org/2000/svg','polygon')\n triangle.setAttribute('points',x2+','+y2+' '+(x2-nx+tx)+','+(y2-ny+ty)\n +' '+(x2-nx-tx)+','+(y2-ny-ty))\n triangle.setAttribute('fill','black')\n g.appendChild(triangle)\n }\n }\n }\n }\n }\n//\n// draw_connections\n//\nfunction draw_connections() {\n var g = document.getElementById(mod.div.id+'g')\n var h = mod.img.height\n var w = mod.img.width\n //\n // loop over segments\n //\n for (var segment = 1; segment < mod.path.length; ++segment) {\n //\n // draw connection from previous segment\n //\n var line = document.createElementNS('http://www.w3.org/2000/svg','line')\n line.setAttribute('stroke','red')\n line.setAttribute('stroke-width',1)\n line.setAttribute('stroke-linecap','round')\n var x1 = mod.path[segment-1][mod.path[segment-1].length-1][0]\n var y1 = h-mod.path[segment-1][mod.path[segment-1].length-1][1]-1\n var x2 = mod.path[segment][0][0]\n var y2 = h-mod.path[segment][0][1]-1\n line.setAttribute('x1',x1)\n line.setAttribute('y1',y1)\n line.setAttribute('x2',x2)\n line.setAttribute('y2',y2)\n var dx = x2-x1\n var dy = y2-y1\n var d = Math.sqrt(dx*dx+dy*dy)\n if (d > 0) {\n nx = 6*dx/d\n ny = 6*dy/d\n var tx = 3*dy/d\n var ty = -3*dx/d\n g.appendChild(line)\n triangle = document.createElementNS('http://www.w3.org/2000/svg','polygon')\n triangle.setAttribute('points',x2+','+y2+' '+(x2-nx+tx)+','+(y2-ny+ty)\n +' '+(x2-nx-tx)+','+(y2-ny-ty))\n triangle.setAttribute('fill','red')\n g.appendChild(triangle)\n }\n }\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n\n","top":"1345.611647642926","left":"3331.8139994703106","filename":"undefined","inputs":{},"outputs":{}},"0.10309904694903338":{"definition":"//\n// vectorize\n// input is red 128:north,64:south, green 128:east,64:west, blue 128:start,64:stop\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2016\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 = 'vectorize'\n//\n// initialization\n//\nvar init = function() {\n mod.error.value = 1\n mod.sort.checked = true\n }\n//\n// inputs\n//\nvar inputs = {\n image:{type:'RGBA',\n event:function(evt){\n mod.input = evt.detail\n var ctx = mod.img.getContext(\"2d\")\n ctx.canvas.width = mod.input.width\n ctx.canvas.height = mod.input.height \n ctx.putImageData(mod.input,0,0)\n vectorize()\n }}}\n//\n// outputs\n//\nvar outputs = {\n path:{type:'array',\n event:function(){\n mods.output(mod,'path',mod.path)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // on-screen SVG\n //\n var svgNS = \"http://www.w3.org/2000/svg\"\n var svg = document.createElementNS(svgNS,\"svg\")\n svg.setAttribute('id',mod.div.id+'svg')\n svg.setAttributeNS(\"http://www.w3.org/2000/xmlns/\",\n \"xmlns:xlink\",\"http://www.w3.org/1999/xlink\")\n svg.setAttribute('width',mods.ui.canvas)\n svg.setAttribute('height',mods.ui.canvas)\n svg.style.backgroundColor = 'rgb(255,255,255)'\n var g = document.createElementNS(svgNS,'g')\n g.setAttribute('id',mod.div.id+'g')\n svg.appendChild(g)\n div.appendChild(svg)\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 // error value\n //\n div.appendChild(document.createTextNode('vector fit (pixels): '))\n //div.appendChild(document.createElement('br'))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n input.addEventListener('change',function(){\n vectorize()\n })\n div.appendChild(input)\n mod.error = input\n div.appendChild(document.createElement('br'))\n //\n // sort\n //\n div.appendChild(document.createTextNode('sort distance: '))\n var input = document.createElement('input')\n input.type = 'checkbox'\n input.id = mod.div.id+'sort'\n div.appendChild(input)\n mod.sort = input\n div.appendChild(document.createElement('br'))\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 svg = document.getElementById(mod.div.id+'svg')\n var clone = svg.cloneNode(true)\n clone.setAttribute('width',mod.img.width)\n clone.setAttribute('height',mod.img.height)\n win.document.body.appendChild(clone)\n })\n div.appendChild(btn)\n }\n//\n// local functions\n//\n// vectorize\n//\nfunction vectorize() {\n //\n // draw path\n //\n function draw_path(path) {\n window.URL.revokeObjectURL(url)\n var svg = document.getElementById(mod.div.id+'svg')\n svg.setAttribute('viewBox',\"0 0 \"+(mod.img.width-1)+\" \"+(mod.img.height-1))\n var g = document.getElementById(mod.div.id+'g')\n svg.removeChild(g)\n var g = document.createElementNS('http://www.w3.org/2000/svg','g')\n g.setAttribute('id',mod.div.id+'g')\n var h = mod.img.height\n var w = mod.img.width\n var xend = null\n var yend = null\n //\n // loop over segments\n //\n for (var segment in path) {\n if (path[segment].length > 1) {\n if (xend != null) {\n //\n // draw connection from previous segment\n //\n var line = document.createElementNS('http://www.w3.org/2000/svg','line')\n line.setAttribute('stroke','red')\n line.setAttribute('stroke-width',1)\n line.setAttribute('stroke-linecap','round')\n var x1 = xend\n var y1 = yend\n var x2 = path[segment][0][0]\n var y2 = h-path[segment][0][1]-1\n line.setAttribute('x1',x1)\n line.setAttribute('y1',y1)\n line.setAttribute('x2',x2)\n line.setAttribute('y2',y2)\n var dx = x2-x1\n var dy = y2-y1\n var d = Math.sqrt(dx*dx+dy*dy)\n if (d > 0) {\n nx = 6*dx/d\n ny = 6*dy/d\n var tx = 3*dy/d\n var ty = -3*dx/d\n g.appendChild(line)\n triangle = document.createElementNS('http://www.w3.org/2000/svg','polygon')\n triangle.setAttribute('points',x2+','+y2+' '+(x2-nx+tx)+','+(y2-ny+ty)\n +' '+(x2-nx-tx)+','+(y2-ny-ty))\n triangle.setAttribute('fill','red')\n g.appendChild(triangle)\n }\n }\n //\n // loop over points\n //\n for (var point = 1; point < path[segment].length; ++point) {\n var line = document.createElementNS('http://www.w3.org/2000/svg','line')\n line.setAttribute('stroke','black')\n line.setAttribute('stroke-width',1)\n line.setAttribute('stroke-linecap','round')\n var x1 = path[segment][point-1][0]\n var y1 = h-path[segment][point-1][1]-1\n var x2 = path[segment][point][0]\n var y2 = h-path[segment][point][1]-1\n xend = x2\n yend = y2\n line.setAttribute('x1',x1)\n line.setAttribute('y1',y1)\n line.setAttribute('x2',x2)\n line.setAttribute('y2',y2)\n var dx = x2-x1\n var dy = y2-y1\n var d = Math.sqrt(dx*dx+dy*dy)\n if (d > 0) {\n nx = 6*dx/d\n ny = 6*dy/d\n var tx = 3*dy/d\n var ty = -3*dx/d\n g.appendChild(line)\n triangle = document.createElementNS('http://www.w3.org/2000/svg','polygon')\n triangle.setAttribute('points',x2+','+y2+' '+(x2-nx+tx)+','+(y2-ny+ty)\n +' '+(x2-nx-tx)+','+(y2-ny-ty))\n triangle.setAttribute('fill','black')\n g.appendChild(triangle)\n }\n }\n }\n }\n svg.appendChild(g)\n }\n //\n // set up worker\n //\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 webworker.terminate()\n mod.path = evt.data.path\n draw_path(mod.path)\n outputs.path.event()\n })\n //\n // call worker\n //\n webworker.postMessage({\n height:mod.input.height,width:mod.input.width,sort:mod.sort.checked,\n error:parseFloat(mod.error.value),\n buffer:mod.input.data.buffer})\n }\n//\n// vectorize worker\n//\nfunction worker() {\n self.addEventListener('message',function(evt) {\n var h = evt.data.height\n var w = evt.data.width\n var sort = evt.data.sort\n var input = new Uint8ClampedArray(evt.data.buffer)\n var northsouth = 0\n var north = 128\n var south = 64\n var eastwest = 1\n var east = 128\n var west = 64\n var startstop = 2\n var start = 128\n var stop = 64\n var path = []\n //\n // edge follower\n //\n function follow_edges(row,col) {\n if ((input[(h-1-row)*w*4+col*4+northsouth] != 0)\n || (input[(h-1-row)*w*4+col*4+eastwest] != 0)) {\n path[path.length] = [[col,row]]\n while (1) {\n if (input[(h-1-row)*w*4+col*4+northsouth] & north) {\n input[(h-1-row)*w*4+col*4+northsouth] =\n input[(h-1-row)*w*4+col*4+northsouth] & ~north\n row += 1\n path[path.length-1][path[path.length-1].length] = [col,row]\n }\n else if (input[(h-1-row)*w*4+col*4+northsouth] & south) {\n input[(h-1-row)*w*4+col*4+northsouth] =\n input[(h-1-row)*w*4+col*4+northsouth] & ~south\n row -= 1\n path[path.length-1][path[path.length-1].length] = [col,row]\n }\n else if (input[(h-1-row)*w*4+col*4+eastwest] & east) {\n input[(h-1-row)*w*4+col*4+eastwest] =\n input[(h-1-row)*w*4+col*4+eastwest] & ~east\n col += 1\n path[path.length-1][path[path.length-1].length] = [col,row]\n }\n else if (input[(h-1-row)*w*4+col*4+eastwest] & west) {\n input[(h-1-row)*w*4+col*4+eastwest] =\n input[(h-1-row)*w*4+col*4+eastwest] & ~west\n col -= 1\n path[path.length-1][path[path.length-1].length] = [col,row]\n }\n else\n break\n }\n }\n }\n //\n // follow boundary starts\n //\n for (var row = 1; row < (h-1); ++row) {\n col = 0\n follow_edges(row,col)\n col = w-1\n follow_edges(row,col)\n }\n for (var col = 1; col < (w-1); ++col) {\n row = 0\n follow_edges(row,col)\n row = h-1 \n follow_edges(row,col)\n }\n //\n // follow interior paths\n //\n for (var row = 1; row < (h-1); ++row) {\n for (var col = 1; col < (w-1); ++col) {\n follow_edges(row,col)\n }\n }\n //\n // vectorize path\n //\n var error = evt.data.error\n var vecpath = []\n for (var seg = 0; seg < path.length; ++seg) {\n var x0 = path[seg][0][0]\n var y0 = path[seg][0][1]\n vecpath[vecpath.length] = [[x0,y0]]\n var xsum = x0\n var ysum = y0\n var sum = 1\n for (var pt = 1; pt < path[seg].length; ++pt) {\n var xold = x\n var yold = y\n var x = path[seg][pt][0]\n var y = path[seg][pt][1]\n if (sum == 1) {\n xsum += x\n ysum += y\n sum += 1\n }\n else {\n var xmean = xsum/sum\n var ymean = ysum/sum\n var dx = xmean-x0\n var dy = ymean-y0\n var d = Math.sqrt(dx*dx+dy*dy)\n var nx = dy/d\n var ny = -dx/d\n var l = Math.abs(nx*(x-x0)+ny*(y-y0))\n if (l < error) {\n xsum += x\n ysum += y\n sum += 1\n }\n else {\n vecpath[vecpath.length-1][vecpath[vecpath.length-1].length] = [xold,yold]\n x0 = xold\n y0 = yold\n xsum = xold\n ysum = yold\n sum = 1\n }\n }\n if (pt == (path[seg].length-1)) {\n vecpath[vecpath.length-1][vecpath[vecpath.length-1].length] = [x,y]\n }\n }\n }\n //\n // sort path\n //\n if ((vecpath.length > 1) && (sort == true)) {\n var dmin = w*w+h*h\n segmin = null\n for (var seg = 0; seg < vecpath.length; ++seg) {\n var x = vecpath[seg][0][0]\n var y = vecpath[seg][0][0]\n var d = x*x+y*y\n if (d < dmin) {\n dmin = d\n segmin = seg\n }\n }\n if (segmin != null) {\n var sortpath = [vecpath[segmin]]\n vecpath.splice(segmin,1)\n }\n while (vecpath.length > 0) {\n var dmin = w*w+h*h\n var x0 = sortpath[sortpath.length-1][sortpath[sortpath.length-1].length-1][0]\n var y0 = sortpath[sortpath.length-1][sortpath[sortpath.length-1].length-1][1]\n segmin = null\n for (var seg = 0; seg < vecpath.length; ++seg) {\n var x = vecpath[seg][0][0]\n var y = vecpath[seg][0][1]\n var d = (x-x0)*(x-x0)+(y-y0)*(y-y0)\n if (d < dmin) {\n dmin = d\n segmin = seg\n }\n }\n if (segmin != null) {\n sortpath[sortpath.length] = vecpath[segmin]\n vecpath.splice(segmin,1)\n }\n }\n }\n else if (((vecpath.length > 1) && (sort == false)) || (vecpath.length == 1))\n sortpath = vecpath\n else\n sortpath = []\n //\n // return path\n //\n self.postMessage({path:sortpath})\n })\n }\n//\n// return values\n//\nreturn ({\n name:name,\n init:init,\n inputs:inputs,\n outputs:outputs,\n interface:interface\n })\n}())\n","top":"1890.6116476429258","left":"4022.8139994703106","filename":"undefined","inputs":{},"outputs":{}},"0.8622681794886853":{"definition":"//\n// save file\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2016\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 = 'save file'\n//\n// initialization\n//\nvar init = function() {\n }\n//\n// inputs\n//\nvar inputs = {\n file:{type:'object',\n event:function(evt){\n mod.name = evt.detail.name\n mod.contents = evt.detail.contents\n save_file()\n }}}\n//\n// outputs\n//\nvar outputs = {}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // info\n //\n var text = document.createTextNode('name:')\n div.appendChild(text)\n mod.nametext = text\n div.appendChild(document.createElement('br'))\n var text = document.createTextNode('size:')\n div.appendChild(text)\n mod.sizetext = text\n div.appendChild(document.createElement('br'))\n }\n//\n// local functions\n//\nfunction save_file() {\n var a = document.createElement('a')\n a.setAttribute('href','data:text/plain;charset=utf-8,'+ \n encodeURIComponent(mod.contents))\n a.setAttribute('download',mod.name)\n a.style.display = 'none'\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n mod.nametext.nodeValue = 'name: '+mod.name\n mods.fit(mod.div)\n mod.sizetext.nodeValue = 'size: '+mod.contents.length\n mods.fit(mod.div)\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":"2112.9754468998394","left":"2827.7533689104926","filename":"modules/file/save","inputs":{},"outputs":{}},"0.992472539363189":{"definition":"//\n// set 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 = 'set PCB defaults'\n//\n// initialization\n//\nvar init = function() {\n //\n add_output('mill traces (1/64)')\n add_variable('tool diameter (in)','var00')\n mod.var00.value = '0.0156'\n add_variable('cut depth (in)','var01')\n mod.var01.value = '0.008'\n add_variable('max depth (in)','var02')\n mod.var02.value = '0.008'\n add_variable('offset number','var03')\n mod.var03.value = '4'\n //\n add_output('mill outline (1/32)')\n add_variable('tool diameter (in)','var10')\n mod.var10.value = '0.027559055118110236'\n add_variable('cut depth (in)','var11')\n mod.var11.value = '0.027559055118110236'\n add_variable('max depth (in)','var12')\n mod.var12.value = '0.072'\n add_variable('offset number','var13')\n mod.var13.value = '1'\n //\n }\n//\n// inputs\n//\nvar inputs = {}\n//\n// outputs\n//\nvar outputs = {\n settings:{type:'',\n event:function(vars){\n mods.output(mod,'settings',vars)\n }\n }\n }\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n }\n//\n// local functions\n//\nfunction add_output(label) {\n if (mod.settings == undefined) {\n mod.settings = {}\n }\n var btn = document.createElement('button')\n btn.style.padding = mods.ui.padding\n btn.style.margin = 1\n var span = document.createElement('span')\n var text = document.createTextNode(label)\n span.appendChild(text)\n btn.appendChild(span)\n var f = function(label) {\n btn.addEventListener('click',function() {\n for (var s in mod.settings)\n mod.settings[s].span.style.fontWeight = 'normal'\n mod.settings[label].span.style.fontWeight = 'bold'\n var vars = {}\n for (var v in mod.settings[label].variables)\n vars[v] = mod.settings[label].variables[v].value\n outputs.settings.event(vars)\n })\n }(label)\n mod.settings[label] = {span:span,variables:{}}\n mod.div.appendChild(btn)\n mod.setting = label\n mod.div.appendChild(document.createElement('br'))\n }\nfunction add_variable(label,variable) {\n var text = document.createTextNode(label)\n mod.div.appendChild(text)\n mod.div.appendChild(document.createTextNode(': '))\n input = document.createElement('input')\n input.type = 'text'\n input.size = 10\n mod[variable] = input\n mod.div.appendChild(input)\n mod.settings[mod.setting].variables[label] = input \n mod.div.appendChild(document.createElement('br'))\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":"1265.611647642926","left":"2787.8139994703106","filename":"undefined","inputs":{},"outputs":{}},"0.8764917270856811":{"definition":"//\n// path to G-code\n//\n// Neil Gershenfeld \n// (c) Massachusetts Institute of Technology 2018\n// \n// Updated: Steven Chew\n// Date: Feb 20 2019\n// Comments: Added option to output in inch or mm\n// Date:... Oct 28 2019\n// Comments: Corrected feedrate conversion\n// - inch/s to inch/min\n//...........- mm/s to mm/min\n//\n// Updated: Neil Gershenfeld\n// Date: Oct 28 2020\n// Comments: added mm/s vs mm/min option\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 = 'path to G-code'\n//\n// initialization\n//\nvar init = function() {\n mod.cutspeed.value = '2.5'\n mod.plungespeed.value = '2.5'\n mod.jogheight.value = '2'\n mod.spindlespeed.value = '11000'\n mod.tool.value = '1'\n mod.coolantoff.checked = true\n mod.formatMm.checked = true\n mod.unitMinutes.checked = true\n }\n//\n// inputs\n//\nvar inputs = {\n path:{type:'',\n event:function(evt){\n mod.name = evt.detail.name\n mod.path = evt.detail.path\n mod.dpi = evt.detail.dpi\n mod.width = evt.detail.width\n mod.height = evt.detail.height\n make_path()\n }}}\n//\n// outputs\n//\nvar outputs = {\n file:{type:'',\n event:function(str){\n obj = {}\n obj.name = mod.name+\".nc\"\n obj.contents = str\n mods.output(mod,'file',obj)\n }}}\n//\n// interface\n//\nvar interface = function(div){\n mod.div = div\n //\n // cut speed\n //\n div.appendChild(document.createTextNode('cut speed: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.cutspeed = input\n div.appendChild(document.createTextNode(' (mm/s)'))\n div.appendChild(document.createElement('br'))\n //\n // plunge speed\n //\n div.appendChild(document.createTextNode('plunge speed: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.plungespeed = input\n div.appendChild(document.createTextNode(' (mm/s)'))\n div.appendChild(document.createElement('br'))\n //\n // jog height\n //\n div.appendChild(document.createTextNode('jog height: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.jogheight = input\n div.appendChild(document.createTextNode(' (mm)'))\n div.appendChild(document.createElement('br'))\n //\n // spindle speed\n //\n div.appendChild(document.createTextNode('spindle speed: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.spindlespeed = input\n div.appendChild(document.createTextNode(' (RPM)'))\n div.appendChild(document.createElement('br'))\n //\n // tool\n //\n div.appendChild(document.createTextNode('tool: '))\n var input = document.createElement('input')\n input.type = 'text'\n input.size = 6\n div.appendChild(input)\n mod.tool = input\n div.appendChild(document.createElement('br'))\n //\n // coolant\n //\n div.appendChild(document.createTextNode('coolant:'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'coolant'\n input.id = mod.div.id+'coolanton'\n div.appendChild(input)\n mod.coolanton = input\n div.appendChild(document.createTextNode('on'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'coolant'\n input.id = mod.div.id+'coolantoff'\n div.appendChild(input)\n mod.coolantoff = input\n div.appendChild(document.createTextNode('off'))\n div.appendChild(document.createElement('br'))\n //\n // inch or mm format\n //\n div.appendChild(document.createTextNode('format:'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'format'\n input.id = mod.div.id+'formatInch'\n input.checked = true\n div.appendChild(input)\n mod.formatInch = input\n div.appendChild(document.createTextNode('inch'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'format'\n input.id = mod.div.id+'formatMm'\n div.appendChild(input)\n mod.formatMm = input\n div.appendChild(document.createTextNode('mm'))\n div.appendChild(document.createElement('br'))\n //\n // second or minute rate units \n //\n div.appendChild(document.createTextNode('rate units:'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'units'\n input.id = mod.div.id+'unitSeconds'\n input.checked = true\n div.appendChild(input)\n mod.unitSeconds = input\n div.appendChild(document.createTextNode('second'))\n var input = document.createElement('input')\n input.type = 'radio'\n input.name = mod.div.id+'units'\n input.id = mod.div.id+'unitMinutes'\n div.appendChild(input)\n mod.unitMinutes = input\n div.appendChild(document.createTextNode('minute'))\n }\n//\n// local functions\n//\nfunction make_path() {\n var dx = 25.4*mod.width/mod.dpi\n var cut_speed = parseFloat(mod.cutspeed.value)\n var plunge_speed = parseFloat(mod.plungespeed.value)\n var jog_height = parseFloat(mod.jogheight.value)\n var nx = mod.width\n var scale = dx/(nx-1)\n var in_mm_scale = 1\n if (mod.formatInch.checked) {\n dx /= 25.4\n scale /= 25.4\n cut_speed /= 25.4\n plunge_speed /= 25.4\n jog_height /= 25.4\n }\n if (mod.unitMinutes.checked) {\n cut_speed *= 60\n plunge_speed *= 60\n }\n var spindle_speed = parseFloat(mod.spindlespeed.value)\n var tool = parseInt(mod.tool.value)\n str = \"%\\n\" // tape start\n str += \"G17\\n\" // xy plane\n if (mod.formatInch.checked)\n str += \"G20\\n\" // inches\n if (mod.formatMm.checked)\n str += \"G21\\n\" // mm\n str += \"G40\\n\" // cancel tool radius compensation\n str += \"G49\\n\" // cancel tool length compensation\n str += \"G54\\n\" // coordinate system 1\n str += \"G80\\n\" // cancel canned cycles\n str += \"G90\\n\" // absolute coordinates\n str += \"G94\\n\" // feed/minute units\n str += \"T\"+tool+\"M06\\n\" // tool selection, tool change\n str += \"F\"+cut_speed.toFixed(4)+\"\\n\" // feed rate\n str += \"S\"+spindle_speed+\"\\n\" // spindle speed\n if (mod.coolanton.checked)\n str += \"M08\\n\" // coolant on\n str += \"G00Z\"+jog_height.toFixed(4)+\"\\n\" // move up before starting spindle\n str += \"M03\\n\" // spindle on clockwise\n //str += \"G04 P1\\n\" // give spindle 1 second to spin up...........................comment out\n //\n // follow segments\n //\n for (var seg = 0; seg < mod.path.length; ++seg) {\n //\n // move up to starting point\n //\n x = scale*mod.path[seg][0][0]\n y = scale*mod.path[seg][0][1]\n str += \"G00Z\"+jog_height.toFixed(4)+\"\\n\"\n str += \"G00X\"+x.toFixed(4)+\"Y\"+y.toFixed(4)+\"Z\"+jog_height.toFixed(4)+\"\\n\"\n //\n // move down\n //\n z = scale*mod.path[seg][0][2]\n str += \"G01Z\"+z.toFixed(4)+\" F\"+plunge_speed.toFixed(4)+\"\\n\"\n str += \"F\"+cut_speed.toFixed(4)+\"\\n\" //restore xy feed rate\n for (var pt = 1; pt < mod.path[seg].length; ++pt) {\n //\n // move to next point\n //\n x = scale*mod.path[seg][pt][0]\n y = scale*mod.path[seg][pt][1]\n z = scale*mod.path[seg][pt][2]\n str += \"G01X\"+x.toFixed(4)+\"Y\"+y.toFixed(4)+\"Z\"+z.toFixed(4)+\"\\n\"\n }\n }\n //\n // finish\n //\n str += \"G00Z\"+jog_height.toFixed(4)+\"\\n\" // move up before stopping spindle\n //\n str += \"G1X0Y0Z0\\n\" // movetoXYZ0\n //\n str += \"M05\\n\" // spindle stop\n if (mod.coolanton.checked)\n str += \"M09\\n\" // coolant off\n str += \"M30\\n\" // program end and reset\n str += \"%\\n\" // tape end\n //\n // output file\n //\n outputs.file.event(str)\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\n","top":"1644.892543840524","left":"2796.9482640838332","filename":"modules/path/formats/g-code","inputs":{},"outputs":{}}},"links":["{\"source\":\"{\\\"id\\\":\\\"0.07944144280928633\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.8903773266711255\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.47383876715576023\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"distances\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.3135579179893032\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"distances\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.3135579179893032\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.07944144280928633\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.08127540142793499\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.6488303557466412\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.6488303557466412\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.47383876715576023\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.08127540142793499\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"imageInfo\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9557599338778935\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"imageInfo\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.9557599338778935\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"offset\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.3135579179893032\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"offset\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.9557599338778935\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"toolpath\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.2892270043957246\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"toolpath\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.8903773266711255\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"image\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.10309904694903338\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"image\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.10309904694903338\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"path\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9557599338778935\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"path\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.992472539363189\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"settings\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.9557599338778935\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"settings\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.2892270043957246\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"toolpath\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.8764917270856811\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"path\\\"}\"}","{\"source\":\"{\\\"id\\\":\\\"0.8764917270856811\\\",\\\"type\\\":\\\"outputs\\\",\\\"name\\\":\\\"file\\\"}\",\"dest\":\"{\\\"id\\\":\\\"0.8622681794886853\\\",\\\"type\\\":\\\"inputs\\\",\\\"name\\\":\\\"file\\\"}\"}"]})) window.mods_prog_load(prog) </script> diff --git a/docs/Instruction/images/week02/fa2021-group-assignment-power-speed-ppi.svg b/docs/Instruction/images/week02/fa2021-group-assignment-power-speed-ppi.svg index 78b625e0e2bb2165fee88b7fd4177bf91f213c60..89c35bbc48e36173cd2565510b177335a12ea620 100644 --- a/docs/Instruction/images/week02/fa2021-group-assignment-power-speed-ppi.svg +++ b/docs/Instruction/images/week02/fa2021-group-assignment-power-speed-ppi.svg @@ -1,110 +1,110 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<!-- Creator: CorelDRAW 2018 (64-Bit) --> -<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="406.4mm" height="304.8mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" -viewBox="0 0 40640 30480" - xmlns:xlink="http://www.w3.org/1999/xlink"> - <defs> - <font id="FontID0" horiz-adv-x="667" font-variant="normal" style="fill-rule:nonzero" font-style="normal" font-weight="400"> - <font-face - font-family="Arial"> - <font-face-src> - <font-face-name name="Arial"/> - </font-face-src> - </font-face> - <missing-glyph><path d="M0 0z"/></missing-glyph> - <glyph unicode="0" horiz-adv-x="556" d="M41.9998 353.337c0,84.4957 8.66926,152.834 25.996,204.495 17.5039,51.8384 43.3345,91.665 77.669,119.503 34.1692,27.8267 77.3383,41.6691 129.33,41.6691 38.3384,0 71.9997,-7.67714 101.173,-23.1731 28.9959,-15.496 52.9959,-37.8306 71.669,-67.0037 18.6613,-28.9959 33.3306,-64.4997 43.9959,-106.322 10.8307,-41.8345 16.1692,-98.3382 16.1692,-169.169 0,-83.9997 -8.66926,-152.007 -25.8306,-203.668 -17.1732,-51.8384 -43.0038,-91.665 -77.3383,-119.669 -34.1692,-28.0038 -77.5036,-41.9998 -129.838,-41.9998 -68.8226,0 -123,24.496 -162.33,73.6651 -47.1612,59.9998 -70.6651,157.169 -70.6651,291.672zm89.9996 -0.342518c0,-117.826 13.6653,-196.157 41.1731,-234.826 27.496,-38.8345 61.4998,-58.1691 101.822,-58.1691 40.3345,0 74.3383,19.4999 101.834,58.3344 27.5078,38.9998 41.1731,117.165 41.1731,234.66 0,117.838 -13.6653,196.169 -41.1731,234.838 -27.3306,38.8345 -61.6651,58.1691 -102.826,58.1691 -40.3345,0 -72.6729,-17.1732 -96.8382,-51.3305 -30.1652,-43.4998 -45.1652,-124.169 -45.1652,-241.676z"/> - <glyph unicode="1" horiz-adv-x="556" d="M371.999 0l-88.0036 0 0 560.336c-21.1653,-20.3385 -48.9919,-40.4998 -83.3264,-60.673 -34.3345,-20.1613 -65.3383,-35.3266 -92.6689,-45.3305l0 85.0036c49.1691,22.996 92.1729,50.9998 128.999,83.9997 36.8384,32.8345 62.9998,64.6651 78.3304,95.6689l56.6691 0 0 -719.005z"/> - <glyph unicode="2" horiz-adv-x="556" d="M503.006 83.9997l0 -83.9997 -474.01 0c-0.661415,21.1653 2.83463,41.5038 10.3346,61.1691 12.1653,32.1613 31.6652,63.9919 58.4998,95.161 26.8345,31.1692 65.173,67.169 115.003,108 77.5036,63.8383 130.169,114.342 157.665,151.665 27.6731,37.3345 41.5038,72.6729 41.5038,106.004 0,34.8306 -12.5078,64.169 -37.4999,88.1689 -25.0038,23.8346 -57.673,35.8345 -97.8303,35.8345 -42.5077,0 -76.4997,-12.6732 -102,-37.9959 -25.5117,-25.1692 -38.3384,-60.1769 -38.6691,-105l-89.9996 8.99996c6.16533,67.3226 29.492,118.665 69.8265,153.992 40.4998,35.3384 94.665,53.0077 162.838,53.0077 68.669,0 123.165,-19.0039 163.169,-57.1769 40.1573,-38.1613 60.1651,-85.4997 60.1651,-141.826 0,-28.6652 -5.83462,-56.8344 -17.6692,-84.5075 -11.6692,-27.8267 -31.1692,-56.9998 -58.3344,-87.6611 -27.3306,-30.4959 -72.4958,-72.6611 -135.496,-126 -52.8305,-44.3384 -86.8343,-74.3383 -101.834,-90.165 -14.9999,-15.8385 -27.3306,-31.6652 -37.1691,-47.6691l351.506 0z"/> - <glyph unicode="3" horiz-adv-x="556" d="M41.9998 190.003l88.0036 12c10.1574,-50.0077 27.1652,-86.0075 51.3305,-108 24.1653,-22.0039 53.8344,-32.9999 88.9957,-32.9999 41.6691,0 76.8422,14.3267 105.165,42.992 28.3345,28.6652 42.5077,64.169 42.5077,106.5 0,40.3345 -13.1692,73.6769 -39.6731,100.004 -26.3267,26.1731 -59.8344,39.3306 -100.665,39.3306 -16.6653,0 -37.3345,-3.3307 -62.1612,-9.82673l9.82673 76.9958c5.83462,-0.661415 10.6653,-1.00393 14.1732,-1.00393 37.6652,0 71.3265,9.83854 101.492,29.3385 29.9999,19.4999 44.9998,49.4998 44.9998,89.9996 0,32.1731 -10.996,58.8305 -32.8227,79.9957 -21.8385,21.1771 -50.0077,31.677 -84.5075,31.677 -34.3345,0 -62.8344,-10.8425 -85.665,-32.5038 -22.8306,-21.6731 -37.4999,-54.1651 -43.9959,-97.4996l-88.0036 16.0039c10.8307,58.9958 35.1613,104.822 73.3344,137.326 37.9959,32.5038 85.4997,48.673 142.169,48.673 38.9998,0 74.9997,-8.33855 107.834,-25.1692 32.9999,-16.6653 58.1573,-39.5077 75.4958,-68.3383 17.5039,-28.9959 26.1613,-59.6691 26.1613,-92.1611 0,-30.8385 -8.32674,-58.8423 -24.8267,-84.165 -16.6653,-25.3345 -41.3384,-45.5077 -73.8304,-60.5076 42.3305,-9.66138 75.1651,-29.9999 98.6571,-60.8265 23.3385,-30.6731 35.0077,-69.3422 35.0077,-115.5 0,-62.5037 -22.8306,-115.677 -68.3383,-159.177 -45.6612,-43.4998 -103.334,-65.1612 -172.995,-65.1612 -62.8344,0 -115.003,18.8385 -156.507,56.3384 -41.6573,37.4999 -65.3265,85.9957 -71.1611,145.665z"/> - <glyph unicode="4" horiz-adv-x="556" d="M322.995 0l0 170.999 -310.995 0 0 80.9997 326.999 464.006 71.9997 0 0 -464.006 97.0036 0 0 -80.9997 -97.0036 0 0 -170.999 -88.0036 0zm0 251.999l0 322.168 -224.491 -322.168 224.491 0z"/> - <glyph unicode="5" horiz-adv-x="556" d="M41.9998 187.995l91.9957 7.00391c6.83856,-44.8345 22.6653,-78.4958 47.3384,-101.161 24.6613,-22.4999 54.8384,-33.8384 90.3304,-33.8384 42.8384,0 78.6729,16.0039 107.834,47.8345 28.9959,31.9959 43.4998,74.3383 43.4998,127.003 0,50.1612 -13.8307,89.6571 -41.6691,118.665 -27.8267,28.9959 -64.6651,43.4998 -110.492,43.4998 -28.4999,0 -53.9998,-6.50785 -76.6651,-19.4999 -22.4999,-13.0039 -40.1691,-29.8345 -53.173,-50.5037l-82.9957 12 68.9997 368.006 354.991 0 0 -83.9997 -284.822 0 -38.1731 -193.169c42.8384,30.1652 87.8382,45.1652 134.834,45.1652 62.3383,0 115.003,-21.6731 157.83,-65.0076 42.8384,-43.3227 64.3344,-98.9996 64.3344,-166.995 0,-64.8305 -18.8267,-120.838 -56.5037,-167.999 -45.8266,-58.0037 -108.496,-86.9997 -187.83,-86.9997 -64.9958,0 -118.003,18.3306 -159.165,54.8384 -41.1613,36.4959 -64.6651,84.8264 -70.4997,145.157z"/> - <glyph unicode="6" horiz-adv-x="556" d="M499.002 541.002l-86.9997 -7.00391c-7.83068,34.4999 -19.0039,59.6691 -33.5077,75.3304 -23.8227,25.1692 -53.3266,37.677 -88.3225,37.677 -28.1692,0 -53.173,-7.84249 -74.669,-23.5038 -27.6731,-20.1731 -49.3345,-49.4998 -65.5037,-88.1689 -16.0039,-38.8345 -24.3306,-94.0036 -25.0038,-165.495 21.1653,32.1613 47.173,56.1612 77.8343,71.6572 30.6731,15.6732 62.669,23.5038 96.3421,23.5038 58.6651,0 108.661,-21.6613 149.999,-64.8305 41.1613,-43.1691 61.8305,-98.8343 61.8305,-167.338 0,-44.9998 -9.67319,-86.669 -29.0078,-125.326 -19.4999,-38.6691 -45.9919,-68.173 -79.9957,-88.665 -33.8266,-20.5039 -72.3304,-30.8385 -115.334,-30.8385 -73.169,0 -133.003,26.9999 -179.326,80.8343 -46.1691,53.8344 -69.3422,142.665 -69.3422,266.338 0,138.33 25.6653,238.995 76.8422,301.83 44.6573,54.6612 104.834,82.0036 180.661,82.0036 56.3384,0 102.673,-15.8385 138.673,-47.3384 35.9999,-31.4999 57.6612,-74.9997 64.8305,-130.665zm-359.999 -308.999c0,-30.3306 6.49604,-59.3383 19.3346,-86.9997 12.8267,-27.6731 30.8267,-48.673 53.6573,-63.1651 23.0078,-14.5039 47.3384,-21.8385 73.169,-21.8385 37.4999,0 69.5076,14.9999 95.9996,44.9998 26.5038,29.9999 39.8384,70.6651 39.8384,122.173 0,49.4998 -13.1692,88.4997 -39.3306,117 -26.1731,28.4999 -59.5037,42.8266 -100.004,42.8266 -39.6731,0 -73.4997,-14.3267 -101.173,-42.8266 -27.6613,-28.4999 -41.492,-65.8344 -41.492,-112.169z"/> - <glyph unicode="7" horiz-adv-x="556" d="M46.9959 623.005l0 83.9997 463.002 0 0 -68.0076c-45.4959,-48.4959 -90.8264,-112.996 -135.496,-193.499 -44.8345,-80.5036 -79.3343,-163.334 -103.83,-248.503 -17.5039,-59.8344 -28.8424,-125.657 -33.6731,-196.995l-89.9996 0c1.00393,56.3384 12,124.5 33.1652,204.33 21.1653,80.0076 51.3305,157.003 90.8382,231.164 39.4959,74.1729 81.4957,136.677 126,187.511l-350.006 0z"/> - <glyph unicode="8" horiz-adv-x="556" d="M177.495 388.168c-36.4959,13.3346 -63.4958,32.5038 -81.165,57.1651 -17.4921,24.8385 -26.3267,54.4958 -26.3267,88.9957 0,52.1691 18.6613,95.8343 55.9958,131.338 37.4999,35.5038 87.165,53.3384 149.338,53.3384 62.3265,0 112.665,-18.1771 150.661,-54.5077 37.9959,-36.3306 56.9998,-80.4918 56.9998,-132.661 0,-33.1652 -8.66926,-62.173 -25.996,-86.669 -17.3385,-24.6731 -43.6652,-43.6652 -79.169,-56.9998 43.8305,-14.3385 76.9958,-37.3345 99.8382,-69.3304 22.8306,-31.8424 34.3345,-69.8383 34.3345,-114.165 0,-61.1691 -21.6731,-112.511 -64.8423,-154.169 -43.3345,-41.6691 -100.169,-62.5037 -170.669,-62.5037 -70.4997,0 -127.334,20.8346 -170.657,62.669 -43.1691,41.8345 -64.8423,93.9918 -64.8423,156.495 0,46.4998 11.8346,85.4997 35.5038,116.834 23.6692,31.4999 57.3305,52.8305 100.996,64.169zm-17.4921 149.338c0,-34.0038 10.8307,-61.6769 32.3266,-83.1729 21.6731,-21.496 50.0077,-32.3385 85.169,-32.3385 34.1692,0 61.8305,10.6771 83.3383,32.0077 21.496,21.3306 32.1613,47.5037 32.1613,78.4958 0,32.3385 -10.996,59.5037 -33.1652,81.5076 -22.0039,21.992 -49.8305,32.9999 -83.3383,32.9999 -33.8266,0 -61.6651,-10.8425 -83.6572,-32.3385 -21.8385,-21.496 -32.8345,-47.1612 -32.8345,-77.1611zm-29.0078 -331.003c0,-25.1692 5.83462,-49.3345 17.5039,-72.8383 11.6692,-23.3267 29.3385,-41.5038 52.9959,-54.3305 23.5038,-12.8385 48.8384,-19.3346 75.6729,-19.3346 42.3305,0 76.9958,13.4999 104.161,40.4998 27.1652,26.9999 40.6652,61.3344 40.6652,103.004 0,42.3305 -13.996,77.3265 -41.8227,105 -28.0038,27.6613 -63.3423,41.492 -105.838,41.492 -41.6691,0 -75.8383,-13.6653 -102.838,-40.9959 -26.9999,-27.3306 -40.4998,-61.4998 -40.4998,-102.496z"/> - <glyph unicode=":" horiz-adv-x="277" d="M89.9996 418.994l0 100.004 100.004 0 0 -100.004 -100.004 0zm0 -418.994l0 100.004 100.004 0 0 -100.004 -100.004 0z"/> - <glyph unicode="I" horiz-adv-x="277" d="M92.9996 0l0 716.005 94.9957 0 0 -716.005 -94.9957 0z"/> - <glyph unicode="P" horiz-adv-x="667" d="M76.9958 0l0 716.005 270.341 0c47.4919,0 83.8343,-2.33857 108.992,-6.83856 35.1731,-5.83462 64.6769,-16.996 88.4997,-33.3306 23.8346,-16.4999 43.0038,-39.5077 57.5076,-68.9997 14.4921,-29.5038 21.6613,-62.0076 21.6613,-97.4996 0,-60.673 -19.3346,-112.169 -58.1691,-154.169 -38.6573,-42.1652 -108.826,-63.1651 -210.165,-63.1651l-183.661 0 0 -292.003 -95.0075 0zm95.0075 376.002l184.995 0c61.3344,0 104.669,11.3267 130.499,34.1692 25.6653,22.8306 38.5038,54.8266 38.5038,96.3303 0,29.8345 -7.49997,55.4998 -22.6653,76.8304 -15.1653,21.3306 -35.1731,35.5038 -59.8344,42.3305 -16.0039,4.16927 -45.5077,6.34249 -88.3343,6.34249l-183.165 0 0 -256.003z"/> - <glyph unicode="S" horiz-adv-x="667" d="M46.0038 229.995l88.9957 8.00784c4.16927,-35.9999 13.996,-65.5037 29.5038,-88.665 15.496,-23.0078 39.4959,-41.6691 71.9997,-56.0077 32.492,-14.1614 69.1651,-21.3306 109.83,-21.3306 36.1652,0 67.9958,5.33856 95.6689,16.1692 27.6613,10.8307 48.1652,25.6653 61.6651,44.492 13.4999,18.8385 20.3385,39.3424 20.3385,61.3344 0,22.3346 -6.50785,41.8345 -19.4999,58.6769 -13.0039,16.6653 -34.5117,30.6613 -64.5116,42.1652 -19.1574,7.33462 -61.6651,18.9921 -127.499,34.8306 -65.8226,15.8267 -111.826,30.6613 -138.165,44.6691 -34.1692,17.9999 -59.4919,40.3345 -76.169,66.8265 -16.8306,26.5038 -25.1574,56.3384 -25.1574,89.1729 0,36.3306 10.3346,70.169 30.8267,101.492 20.5039,31.4999 50.3384,55.3344 89.8343,71.669 39.3306,16.3346 83.1729,24.5078 131.338,24.5078 52.9959,0 99.8264,-8.5039 140.326,-25.6771 40.4998,-16.996 71.669,-42.1652 93.5075,-75.4958 21.8267,-33.1652 33.4959,-70.8304 35.1613,-112.83l-90.9918 -7.00391c-4.8425,45.1652 -21.3424,79.3343 -49.5116,102.33 -28.1574,23.1731 -69.8265,34.677 -124.83,34.677 -57.3305,0 -99.165,-10.5 -125.326,-31.4999 -26.1731,-20.9999 -39.3424,-46.3345 -39.3424,-76.0036 0,-25.6653 9.34248,-46.8305 27.8385,-63.5076 18.3306,-16.4999 65.8344,-33.6613 142.83,-50.9998 77.0076,-17.4921 129.838,-32.6574 158.503,-45.6612 41.5038,-19.1692 72.3304,-43.3345 92.1611,-72.8383 19.8424,-29.3267 29.6692,-63.1651 29.6692,-101.492 0,-38.1731 -10.8307,-73.8422 -32.6692,-107.504 -21.8267,-33.6613 -52.9959,-59.8344 -93.8264,-78.4958 -40.8305,-18.6732 -86.669,-28.0038 -137.834,-28.0038 -64.6651,0 -118.83,9.49603 -162.495,28.3345 -43.8423,18.8267 -78.0115,47.1612 -102.838,85.169 -25.0038,37.8306 -37.9959,80.669 -39.3306,128.492z"/> - <glyph unicode="d" horiz-adv-x="556" d="M400.994 0l0 65.8344c-32.8227,-51.1652 -81.165,-76.8304 -144.992,-76.8304 -41.3384,0 -79.3343,11.3267 -113.834,34.1573 -34.6652,22.6771 -61.4998,54.5077 -80.669,95.1729 -19.0039,40.8305 -28.4999,87.6611 -28.4999,140.669 0,51.6612 8.66926,98.4917 25.8306,140.669 17.3385,41.9998 43.1691,74.3265 77.669,96.661 34.3345,22.4999 73.0036,33.6731 115.5,33.6731 31.3345,0 59.173,-6.6732 83.5036,-19.8424 24.3306,-13.1692 44.1612,-30.4959 59.4919,-51.6612l0 257.503 88.0036 0 0 -716.005 -82.0036 0zm-277.995 258.838c0,-66.3423 13.996,-115.842 42.1652,-148.677 28.0038,-32.8227 61.1691,-49.1573 99.3303,-49.1573 38.5038,0 71.1729,15.6614 98.1728,46.9959 26.8345,31.3345 40.3345,79.169 40.3345,143.503 0,70.6651 -13.6653,122.669 -41.1731,155.834 -27.3306,33.1652 -61.1572,49.6652 -101.326,49.6652 -39.1652,0 -71.8344,-15.8385 -98.1728,-47.6691 -26.1613,-31.8306 -39.3306,-82.0036 -39.3306,-150.495z"/> - <glyph unicode="e" horiz-adv-x="556" d="M419.998 167.999l91.0036 -12c-14.1732,-52.8305 -40.6652,-94.0036 -79.3343,-123.165 -38.6691,-29.1731 -88.0036,-43.8305 -148.169,-43.8305 -75.6611,0 -135.661,23.3267 -179.999,69.9919 -44.3384,46.4998 -66.4958,112.003 -66.4958,196.169 0,86.9997 22.3346,154.665 67.1572,202.665 44.8345,48.177 103.004,72.1769 174.507,72.1769 69.1651,0 125.669,-23.5038 169.499,-70.6769 43.8305,-47.1612 65.8344,-113.492 65.8344,-198.991 0,-5.17321 -0.165354,-13.0039 -0.496061,-23.3385l-386.502 0c3.3307,-56.8344 19.3346,-100.5 48.3305,-130.665 28.8306,-30.1652 64.9958,-45.3305 108.165,-45.3305 32.1731,0 59.6691,8.49209 82.3343,25.4999 22.8306,16.996 40.8305,44.1612 54.1651,81.4957zm-287.999 140.999l289.003 0c-3.83857,43.6652 -14.9999,76.3343 -33.1652,98.1728 -27.8385,33.8266 -64.169,50.8226 -108.673,50.8226 -40.3345,0 -74.1611,-13.4999 -101.669,-40.4998 -27.3306,-26.9999 -42.4959,-63.1651 -45.4959,-108.496z"/> - <glyph unicode="o" horiz-adv-x="556" d="M32.9999 259.499c0,95.8343 26.6692,166.83 80.1611,212.999 44.5038,38.3384 99.0114,57.5076 163.169,57.5076 71.1729,0 129.507,-23.3385 174.838,-70.0037 45.1652,-46.4998 67.8304,-111 67.8304,-193.169 0,-66.6612 -9.99209,-118.996 -29.9999,-157.169 -19.996,-38.1613 -49.1691,-67.8304 -87.4957,-88.9957 -38.1731,-21.1653 -80.0076,-31.6652 -125.173,-31.6652 -72.6611,0 -131.326,23.1613 -176.161,69.6611 -44.8345,46.4998 -67.169,113.503 -67.169,200.834zm89.9996 -0.165354c0,-66.3304 14.5039,-115.996 43.4998,-148.83 29.1731,-32.9999 65.669,-49.4998 109.83,-49.4998 43.6652,0 80.0076,16.4999 109.169,49.6652 28.9959,33.1652 43.4998,83.669 43.4998,151.499 0,64.0037 -14.6692,112.5 -43.8305,145.334 -29.1731,32.9999 -65.5037,49.4998 -108.838,49.4998 -44.1612,0 -80.6572,-16.3346 -109.83,-49.1691 -28.9959,-32.8345 -43.4998,-82.3343 -43.4998,-148.499z"/> - <glyph unicode="p" horiz-adv-x="556" d="M65.9997 -199.003l0 718.001 79.9957 0 0 -68.1611c18.8385,26.3267 40.1691,46.1573 64.0037,59.3265 23.6692,13.1692 52.4998,19.8424 86.3382,19.8424 44.3266,0 83.3264,-11.3385 117.165,-34.1692 33.8266,-22.6653 59.3265,-54.8384 76.6651,-96.165 17.1613,-41.5038 25.8306,-86.8343 25.8306,-136.334 0,-52.8423 -9.49603,-100.5 -28.4999,-143.007 -19.0039,-42.3305 -46.6652,-74.8344 -82.9957,-97.4996 -36.1652,-22.4999 -74.3383,-33.8266 -114.33,-33.8266 -29.3385,0 -55.6769,6.16533 -78.8383,18.496 -23.3385,12.3307 -42.3305,27.8385 -57.3305,46.6652l0 -253.168 -88.0036 0zm79.9957 455.337c0,-66.4958 13.4999,-115.665 40.3345,-147.495 26.9999,-31.8424 59.6691,-47.8345 98.0075,-47.8345 38.9998,0 72.3304,16.4999 99.9917,49.4998 27.8385,32.9999 41.6691,83.9997 41.6691,153.165 0,65.9997 -13.4999,115.334 -40.6652,148.169 -27.1652,32.8345 -59.5037,49.1573 -97.1689,49.1573 -37.3345,0 -70.3344,-17.4921 -98.9996,-52.3226 -28.8306,-35.0077 -43.1691,-85.6768 -43.1691,-152.338z"/> - <glyph unicode="r" horiz-adv-x="332" d="M64.9958 0l0 518.998 79.0036 0 0 -79.4997c20.1613,36.8384 38.8345,61.1691 55.9958,72.8383 17.1732,11.8346 35.9999,17.6692 56.5037,17.6692 29.6692,0 59.8344,-9.34248 90.4957,-27.8385l-31.3227 -81.165c-21.3424,12 -42.6731,17.9999 -64.0037,17.9999 -19.1692,0 -36.3306,-5.83462 -51.4959,-17.3385 -15.1771,-11.4921 -26.0078,-27.496 -32.5038,-47.9998 -9.83854,-31.1692 -14.6692,-65.3265 -14.6692,-102.496l0 -271.168 -88.0036 0z"/> - <glyph unicode="w" horiz-adv-x="722" d="M159.33 0l-156.826 518.998 91.9957 0 82.8304 -299.503 29.3385 -111.496c1.16929,5.50392 10.1693,41.1613 26.8345,106.996l82.169 304.003 90.165 0 78.165 -301.333 25.4999 -98.8343 29.8345 100.169 89.6689 299.999 85.4997 0 -162.838 -518.998 -91.0036 0 -82.3343 310.499 -20.8346 88.8304 -105 -399.329 -93.165 0z"/> - </font> - <style type="text/css"> - <![CDATA[ - @font-face { font-family:"Arial";font-variant:normal;font-style:normal;font-weight:normal;src:url("#FontID0") format(svg)} - .str4 {stroke:#FF6600;stroke-width:7.62;stroke-miterlimit:22.9256} - .str2 {stroke:fuchsia;stroke-width:7.62;stroke-miterlimit:22.9256} - .str0 {stroke:red;stroke-width:7.62;stroke-miterlimit:22.9256} - .str3 {stroke:aqua;stroke-width:7.62;stroke-miterlimit:22.9256} - .str1 {stroke:blue;stroke-width:7.62;stroke-miterlimit:22.9256} - .fil0 {fill:none} - .fil1 {fill:black} - .fnt0 {font-weight:normal;font-size:846.67px;font-family:'Arial'} - ]]> - </style> - </defs> - <g id="レイヤ_x0020_1"> - <metadata id="CorelCorpID_0Corel-Layer"/> - <rect class="fil0 str0" x="3000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="3000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="3000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="3000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="3000" y="15000" width="2000" height="2000"/> - <line class="fil0 str0" x1="-0" y1="0" x2="500" y2= "0" /> - <text x="1058.24" y="7272.62" class="fil1 fnt0">10</text> - <text x="1058.24" y="10264.61" class="fil1 fnt0">20</text> - <text x="1084.7" y="13272.63" class="fil1 fnt0">30</text> - <text x="1045.01" y="16259.4" class="fil1 fnt0">40</text> - <text x="1568.56" y="4306.48" class="fil1 fnt0">4</text> - <text x="1568.56" y="4306.48" class="fil1 fnt0">4</text> - <g transform="matrix(2.64845E-14 -1 1 2.64845E-14 -14323.7 26102.3)"> - <text x="20320" y="15240" class="fil1 fnt0">Speed</text> - </g> - <text x="2934.81" y="990.69" class="fil1 fnt0">Power</text> - <text x="3508.19" y="2299.3" class="fil1 fnt0">40</text> - <rect class="fil0 str0" x="6000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="6000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="6000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="6000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="6000" y="15000" width="2000" height="2000"/> - <text x="6508.19" y="2299.3" class="fil1 fnt0">50</text> - <rect class="fil0 str0" x="9000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="9000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="9000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="9000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="9000" y="15000" width="2000" height="2000"/> - <text x="9508.19" y="2299.3" class="fil1 fnt0">60</text> - <rect class="fil0 str0" x="12000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="12000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="12000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="12000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="12000" y="15000" width="2000" height="2000"/> - <text x="12508.19" y="2299.3" class="fil1 fnt0">70</text> - <rect class="fil0 str0" x="15000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="15000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="15000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="15000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="15000" y="15000" width="2000" height="2000"/> - <text x="15508.19" y="2299.3" class="fil1 fnt0">80</text> - <text x="1519.73" y="18591.56" class="fil1 fnt0">250PPI</text> - <rect class="fil0 str0" x="23000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="23000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="23000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="23000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="23000" y="15000" width="2000" height="2000"/> - <text x="20528.59" y="7316.82" class="fil1 fnt0">300</text> - <text x="20528.59" y="10239.63" class="fil1 fnt0">400</text> - <text x="20528.59" y="13202.97" class="fil1 fnt0">500</text> - <text x="20528.59" y="16303.6" class="fil1 fnt0">600</text> - <text x="20528.59" y="4350.68" class="fil1 fnt0">250</text> - <g transform="matrix(2.64845E-14 -1 1 2.64845E-14 4760 24702.7)"> - <text x="20320" y="15240" class="fil1 fnt0">PPI</text> - </g> - <text x="21961.05" y="885.64" class="fil1 fnt0">Power:</text> - <text x="21961.05" y="1831.51" class="fil1 fnt0">Speed:</text> - </g> -</svg> +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Creator: CorelDRAW 2018 (64-Bit) --> +<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="406.4mm" height="304.8mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" +viewBox="0 0 40640 30480" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <font id="FontID0" horiz-adv-x="667" font-variant="normal" style="fill-rule:nonzero" font-style="normal" font-weight="400"> + <font-face + font-family="Arial"> + <font-face-src> + <font-face-name name="Arial"/> + </font-face-src> + </font-face> + <missing-glyph><path d="M0 0z"/></missing-glyph> + <glyph unicode="0" horiz-adv-x="556" d="M41.9998 353.337c0,84.4957 8.66926,152.834 25.996,204.495 17.5039,51.8384 43.3345,91.665 77.669,119.503 34.1692,27.8267 77.3383,41.6691 129.33,41.6691 38.3384,0 71.9997,-7.67714 101.173,-23.1731 28.9959,-15.496 52.9959,-37.8306 71.669,-67.0037 18.6613,-28.9959 33.3306,-64.4997 43.9959,-106.322 10.8307,-41.8345 16.1692,-98.3382 16.1692,-169.169 0,-83.9997 -8.66926,-152.007 -25.8306,-203.668 -17.1732,-51.8384 -43.0038,-91.665 -77.3383,-119.669 -34.1692,-28.0038 -77.5036,-41.9998 -129.838,-41.9998 -68.8226,0 -123,24.496 -162.33,73.6651 -47.1612,59.9998 -70.6651,157.169 -70.6651,291.672zm89.9996 -0.342518c0,-117.826 13.6653,-196.157 41.1731,-234.826 27.496,-38.8345 61.4998,-58.1691 101.822,-58.1691 40.3345,0 74.3383,19.4999 101.834,58.3344 27.5078,38.9998 41.1731,117.165 41.1731,234.66 0,117.838 -13.6653,196.169 -41.1731,234.838 -27.3306,38.8345 -61.6651,58.1691 -102.826,58.1691 -40.3345,0 -72.6729,-17.1732 -96.8382,-51.3305 -30.1652,-43.4998 -45.1652,-124.169 -45.1652,-241.676z"/> + <glyph unicode="1" horiz-adv-x="556" d="M371.999 0l-88.0036 0 0 560.336c-21.1653,-20.3385 -48.9919,-40.4998 -83.3264,-60.673 -34.3345,-20.1613 -65.3383,-35.3266 -92.6689,-45.3305l0 85.0036c49.1691,22.996 92.1729,50.9998 128.999,83.9997 36.8384,32.8345 62.9998,64.6651 78.3304,95.6689l56.6691 0 0 -719.005z"/> + <glyph unicode="2" horiz-adv-x="556" d="M503.006 83.9997l0 -83.9997 -474.01 0c-0.661415,21.1653 2.83463,41.5038 10.3346,61.1691 12.1653,32.1613 31.6652,63.9919 58.4998,95.161 26.8345,31.1692 65.173,67.169 115.003,108 77.5036,63.8383 130.169,114.342 157.665,151.665 27.6731,37.3345 41.5038,72.6729 41.5038,106.004 0,34.8306 -12.5078,64.169 -37.4999,88.1689 -25.0038,23.8346 -57.673,35.8345 -97.8303,35.8345 -42.5077,0 -76.4997,-12.6732 -102,-37.9959 -25.5117,-25.1692 -38.3384,-60.1769 -38.6691,-105l-89.9996 8.99996c6.16533,67.3226 29.492,118.665 69.8265,153.992 40.4998,35.3384 94.665,53.0077 162.838,53.0077 68.669,0 123.165,-19.0039 163.169,-57.1769 40.1573,-38.1613 60.1651,-85.4997 60.1651,-141.826 0,-28.6652 -5.83462,-56.8344 -17.6692,-84.5075 -11.6692,-27.8267 -31.1692,-56.9998 -58.3344,-87.6611 -27.3306,-30.4959 -72.4958,-72.6611 -135.496,-126 -52.8305,-44.3384 -86.8343,-74.3383 -101.834,-90.165 -14.9999,-15.8385 -27.3306,-31.6652 -37.1691,-47.6691l351.506 0z"/> + <glyph unicode="3" horiz-adv-x="556" d="M41.9998 190.003l88.0036 12c10.1574,-50.0077 27.1652,-86.0075 51.3305,-108 24.1653,-22.0039 53.8344,-32.9999 88.9957,-32.9999 41.6691,0 76.8422,14.3267 105.165,42.992 28.3345,28.6652 42.5077,64.169 42.5077,106.5 0,40.3345 -13.1692,73.6769 -39.6731,100.004 -26.3267,26.1731 -59.8344,39.3306 -100.665,39.3306 -16.6653,0 -37.3345,-3.3307 -62.1612,-9.82673l9.82673 76.9958c5.83462,-0.661415 10.6653,-1.00393 14.1732,-1.00393 37.6652,0 71.3265,9.83854 101.492,29.3385 29.9999,19.4999 44.9998,49.4998 44.9998,89.9996 0,32.1731 -10.996,58.8305 -32.8227,79.9957 -21.8385,21.1771 -50.0077,31.677 -84.5075,31.677 -34.3345,0 -62.8344,-10.8425 -85.665,-32.5038 -22.8306,-21.6731 -37.4999,-54.1651 -43.9959,-97.4996l-88.0036 16.0039c10.8307,58.9958 35.1613,104.822 73.3344,137.326 37.9959,32.5038 85.4997,48.673 142.169,48.673 38.9998,0 74.9997,-8.33855 107.834,-25.1692 32.9999,-16.6653 58.1573,-39.5077 75.4958,-68.3383 17.5039,-28.9959 26.1613,-59.6691 26.1613,-92.1611 0,-30.8385 -8.32674,-58.8423 -24.8267,-84.165 -16.6653,-25.3345 -41.3384,-45.5077 -73.8304,-60.5076 42.3305,-9.66138 75.1651,-29.9999 98.6571,-60.8265 23.3385,-30.6731 35.0077,-69.3422 35.0077,-115.5 0,-62.5037 -22.8306,-115.677 -68.3383,-159.177 -45.6612,-43.4998 -103.334,-65.1612 -172.995,-65.1612 -62.8344,0 -115.003,18.8385 -156.507,56.3384 -41.6573,37.4999 -65.3265,85.9957 -71.1611,145.665z"/> + <glyph unicode="4" horiz-adv-x="556" d="M322.995 0l0 170.999 -310.995 0 0 80.9997 326.999 464.006 71.9997 0 0 -464.006 97.0036 0 0 -80.9997 -97.0036 0 0 -170.999 -88.0036 0zm0 251.999l0 322.168 -224.491 -322.168 224.491 0z"/> + <glyph unicode="5" horiz-adv-x="556" d="M41.9998 187.995l91.9957 7.00391c6.83856,-44.8345 22.6653,-78.4958 47.3384,-101.161 24.6613,-22.4999 54.8384,-33.8384 90.3304,-33.8384 42.8384,0 78.6729,16.0039 107.834,47.8345 28.9959,31.9959 43.4998,74.3383 43.4998,127.003 0,50.1612 -13.8307,89.6571 -41.6691,118.665 -27.8267,28.9959 -64.6651,43.4998 -110.492,43.4998 -28.4999,0 -53.9998,-6.50785 -76.6651,-19.4999 -22.4999,-13.0039 -40.1691,-29.8345 -53.173,-50.5037l-82.9957 12 68.9997 368.006 354.991 0 0 -83.9997 -284.822 0 -38.1731 -193.169c42.8384,30.1652 87.8382,45.1652 134.834,45.1652 62.3383,0 115.003,-21.6731 157.83,-65.0076 42.8384,-43.3227 64.3344,-98.9996 64.3344,-166.995 0,-64.8305 -18.8267,-120.838 -56.5037,-167.999 -45.8266,-58.0037 -108.496,-86.9997 -187.83,-86.9997 -64.9958,0 -118.003,18.3306 -159.165,54.8384 -41.1613,36.4959 -64.6651,84.8264 -70.4997,145.157z"/> + <glyph unicode="6" horiz-adv-x="556" d="M499.002 541.002l-86.9997 -7.00391c-7.83068,34.4999 -19.0039,59.6691 -33.5077,75.3304 -23.8227,25.1692 -53.3266,37.677 -88.3225,37.677 -28.1692,0 -53.173,-7.84249 -74.669,-23.5038 -27.6731,-20.1731 -49.3345,-49.4998 -65.5037,-88.1689 -16.0039,-38.8345 -24.3306,-94.0036 -25.0038,-165.495 21.1653,32.1613 47.173,56.1612 77.8343,71.6572 30.6731,15.6732 62.669,23.5038 96.3421,23.5038 58.6651,0 108.661,-21.6613 149.999,-64.8305 41.1613,-43.1691 61.8305,-98.8343 61.8305,-167.338 0,-44.9998 -9.67319,-86.669 -29.0078,-125.326 -19.4999,-38.6691 -45.9919,-68.173 -79.9957,-88.665 -33.8266,-20.5039 -72.3304,-30.8385 -115.334,-30.8385 -73.169,0 -133.003,26.9999 -179.326,80.8343 -46.1691,53.8344 -69.3422,142.665 -69.3422,266.338 0,138.33 25.6653,238.995 76.8422,301.83 44.6573,54.6612 104.834,82.0036 180.661,82.0036 56.3384,0 102.673,-15.8385 138.673,-47.3384 35.9999,-31.4999 57.6612,-74.9997 64.8305,-130.665zm-359.999 -308.999c0,-30.3306 6.49604,-59.3383 19.3346,-86.9997 12.8267,-27.6731 30.8267,-48.673 53.6573,-63.1651 23.0078,-14.5039 47.3384,-21.8385 73.169,-21.8385 37.4999,0 69.5076,14.9999 95.9996,44.9998 26.5038,29.9999 39.8384,70.6651 39.8384,122.173 0,49.4998 -13.1692,88.4997 -39.3306,117 -26.1731,28.4999 -59.5037,42.8266 -100.004,42.8266 -39.6731,0 -73.4997,-14.3267 -101.173,-42.8266 -27.6613,-28.4999 -41.492,-65.8344 -41.492,-112.169z"/> + <glyph unicode="7" horiz-adv-x="556" d="M46.9959 623.005l0 83.9997 463.002 0 0 -68.0076c-45.4959,-48.4959 -90.8264,-112.996 -135.496,-193.499 -44.8345,-80.5036 -79.3343,-163.334 -103.83,-248.503 -17.5039,-59.8344 -28.8424,-125.657 -33.6731,-196.995l-89.9996 0c1.00393,56.3384 12,124.5 33.1652,204.33 21.1653,80.0076 51.3305,157.003 90.8382,231.164 39.4959,74.1729 81.4957,136.677 126,187.511l-350.006 0z"/> + <glyph unicode="8" horiz-adv-x="556" d="M177.495 388.168c-36.4959,13.3346 -63.4958,32.5038 -81.165,57.1651 -17.4921,24.8385 -26.3267,54.4958 -26.3267,88.9957 0,52.1691 18.6613,95.8343 55.9958,131.338 37.4999,35.5038 87.165,53.3384 149.338,53.3384 62.3265,0 112.665,-18.1771 150.661,-54.5077 37.9959,-36.3306 56.9998,-80.4918 56.9998,-132.661 0,-33.1652 -8.66926,-62.173 -25.996,-86.669 -17.3385,-24.6731 -43.6652,-43.6652 -79.169,-56.9998 43.8305,-14.3385 76.9958,-37.3345 99.8382,-69.3304 22.8306,-31.8424 34.3345,-69.8383 34.3345,-114.165 0,-61.1691 -21.6731,-112.511 -64.8423,-154.169 -43.3345,-41.6691 -100.169,-62.5037 -170.669,-62.5037 -70.4997,0 -127.334,20.8346 -170.657,62.669 -43.1691,41.8345 -64.8423,93.9918 -64.8423,156.495 0,46.4998 11.8346,85.4997 35.5038,116.834 23.6692,31.4999 57.3305,52.8305 100.996,64.169zm-17.4921 149.338c0,-34.0038 10.8307,-61.6769 32.3266,-83.1729 21.6731,-21.496 50.0077,-32.3385 85.169,-32.3385 34.1692,0 61.8305,10.6771 83.3383,32.0077 21.496,21.3306 32.1613,47.5037 32.1613,78.4958 0,32.3385 -10.996,59.5037 -33.1652,81.5076 -22.0039,21.992 -49.8305,32.9999 -83.3383,32.9999 -33.8266,0 -61.6651,-10.8425 -83.6572,-32.3385 -21.8385,-21.496 -32.8345,-47.1612 -32.8345,-77.1611zm-29.0078 -331.003c0,-25.1692 5.83462,-49.3345 17.5039,-72.8383 11.6692,-23.3267 29.3385,-41.5038 52.9959,-54.3305 23.5038,-12.8385 48.8384,-19.3346 75.6729,-19.3346 42.3305,0 76.9958,13.4999 104.161,40.4998 27.1652,26.9999 40.6652,61.3344 40.6652,103.004 0,42.3305 -13.996,77.3265 -41.8227,105 -28.0038,27.6613 -63.3423,41.492 -105.838,41.492 -41.6691,0 -75.8383,-13.6653 -102.838,-40.9959 -26.9999,-27.3306 -40.4998,-61.4998 -40.4998,-102.496z"/> + <glyph unicode=":" horiz-adv-x="277" d="M89.9996 418.994l0 100.004 100.004 0 0 -100.004 -100.004 0zm0 -418.994l0 100.004 100.004 0 0 -100.004 -100.004 0z"/> + <glyph unicode="I" horiz-adv-x="277" d="M92.9996 0l0 716.005 94.9957 0 0 -716.005 -94.9957 0z"/> + <glyph unicode="P" horiz-adv-x="667" d="M76.9958 0l0 716.005 270.341 0c47.4919,0 83.8343,-2.33857 108.992,-6.83856 35.1731,-5.83462 64.6769,-16.996 88.4997,-33.3306 23.8346,-16.4999 43.0038,-39.5077 57.5076,-68.9997 14.4921,-29.5038 21.6613,-62.0076 21.6613,-97.4996 0,-60.673 -19.3346,-112.169 -58.1691,-154.169 -38.6573,-42.1652 -108.826,-63.1651 -210.165,-63.1651l-183.661 0 0 -292.003 -95.0075 0zm95.0075 376.002l184.995 0c61.3344,0 104.669,11.3267 130.499,34.1692 25.6653,22.8306 38.5038,54.8266 38.5038,96.3303 0,29.8345 -7.49997,55.4998 -22.6653,76.8304 -15.1653,21.3306 -35.1731,35.5038 -59.8344,42.3305 -16.0039,4.16927 -45.5077,6.34249 -88.3343,6.34249l-183.165 0 0 -256.003z"/> + <glyph unicode="S" horiz-adv-x="667" d="M46.0038 229.995l88.9957 8.00784c4.16927,-35.9999 13.996,-65.5037 29.5038,-88.665 15.496,-23.0078 39.4959,-41.6691 71.9997,-56.0077 32.492,-14.1614 69.1651,-21.3306 109.83,-21.3306 36.1652,0 67.9958,5.33856 95.6689,16.1692 27.6613,10.8307 48.1652,25.6653 61.6651,44.492 13.4999,18.8385 20.3385,39.3424 20.3385,61.3344 0,22.3346 -6.50785,41.8345 -19.4999,58.6769 -13.0039,16.6653 -34.5117,30.6613 -64.5116,42.1652 -19.1574,7.33462 -61.6651,18.9921 -127.499,34.8306 -65.8226,15.8267 -111.826,30.6613 -138.165,44.6691 -34.1692,17.9999 -59.4919,40.3345 -76.169,66.8265 -16.8306,26.5038 -25.1574,56.3384 -25.1574,89.1729 0,36.3306 10.3346,70.169 30.8267,101.492 20.5039,31.4999 50.3384,55.3344 89.8343,71.669 39.3306,16.3346 83.1729,24.5078 131.338,24.5078 52.9959,0 99.8264,-8.5039 140.326,-25.6771 40.4998,-16.996 71.669,-42.1652 93.5075,-75.4958 21.8267,-33.1652 33.4959,-70.8304 35.1613,-112.83l-90.9918 -7.00391c-4.8425,45.1652 -21.3424,79.3343 -49.5116,102.33 -28.1574,23.1731 -69.8265,34.677 -124.83,34.677 -57.3305,0 -99.165,-10.5 -125.326,-31.4999 -26.1731,-20.9999 -39.3424,-46.3345 -39.3424,-76.0036 0,-25.6653 9.34248,-46.8305 27.8385,-63.5076 18.3306,-16.4999 65.8344,-33.6613 142.83,-50.9998 77.0076,-17.4921 129.838,-32.6574 158.503,-45.6612 41.5038,-19.1692 72.3304,-43.3345 92.1611,-72.8383 19.8424,-29.3267 29.6692,-63.1651 29.6692,-101.492 0,-38.1731 -10.8307,-73.8422 -32.6692,-107.504 -21.8267,-33.6613 -52.9959,-59.8344 -93.8264,-78.4958 -40.8305,-18.6732 -86.669,-28.0038 -137.834,-28.0038 -64.6651,0 -118.83,9.49603 -162.495,28.3345 -43.8423,18.8267 -78.0115,47.1612 -102.838,85.169 -25.0038,37.8306 -37.9959,80.669 -39.3306,128.492z"/> + <glyph unicode="d" horiz-adv-x="556" d="M400.994 0l0 65.8344c-32.8227,-51.1652 -81.165,-76.8304 -144.992,-76.8304 -41.3384,0 -79.3343,11.3267 -113.834,34.1573 -34.6652,22.6771 -61.4998,54.5077 -80.669,95.1729 -19.0039,40.8305 -28.4999,87.6611 -28.4999,140.669 0,51.6612 8.66926,98.4917 25.8306,140.669 17.3385,41.9998 43.1691,74.3265 77.669,96.661 34.3345,22.4999 73.0036,33.6731 115.5,33.6731 31.3345,0 59.173,-6.6732 83.5036,-19.8424 24.3306,-13.1692 44.1612,-30.4959 59.4919,-51.6612l0 257.503 88.0036 0 0 -716.005 -82.0036 0zm-277.995 258.838c0,-66.3423 13.996,-115.842 42.1652,-148.677 28.0038,-32.8227 61.1691,-49.1573 99.3303,-49.1573 38.5038,0 71.1729,15.6614 98.1728,46.9959 26.8345,31.3345 40.3345,79.169 40.3345,143.503 0,70.6651 -13.6653,122.669 -41.1731,155.834 -27.3306,33.1652 -61.1572,49.6652 -101.326,49.6652 -39.1652,0 -71.8344,-15.8385 -98.1728,-47.6691 -26.1613,-31.8306 -39.3306,-82.0036 -39.3306,-150.495z"/> + <glyph unicode="e" horiz-adv-x="556" d="M419.998 167.999l91.0036 -12c-14.1732,-52.8305 -40.6652,-94.0036 -79.3343,-123.165 -38.6691,-29.1731 -88.0036,-43.8305 -148.169,-43.8305 -75.6611,0 -135.661,23.3267 -179.999,69.9919 -44.3384,46.4998 -66.4958,112.003 -66.4958,196.169 0,86.9997 22.3346,154.665 67.1572,202.665 44.8345,48.177 103.004,72.1769 174.507,72.1769 69.1651,0 125.669,-23.5038 169.499,-70.6769 43.8305,-47.1612 65.8344,-113.492 65.8344,-198.991 0,-5.17321 -0.165354,-13.0039 -0.496061,-23.3385l-386.502 0c3.3307,-56.8344 19.3346,-100.5 48.3305,-130.665 28.8306,-30.1652 64.9958,-45.3305 108.165,-45.3305 32.1731,0 59.6691,8.49209 82.3343,25.4999 22.8306,16.996 40.8305,44.1612 54.1651,81.4957zm-287.999 140.999l289.003 0c-3.83857,43.6652 -14.9999,76.3343 -33.1652,98.1728 -27.8385,33.8266 -64.169,50.8226 -108.673,50.8226 -40.3345,0 -74.1611,-13.4999 -101.669,-40.4998 -27.3306,-26.9999 -42.4959,-63.1651 -45.4959,-108.496z"/> + <glyph unicode="o" horiz-adv-x="556" d="M32.9999 259.499c0,95.8343 26.6692,166.83 80.1611,212.999 44.5038,38.3384 99.0114,57.5076 163.169,57.5076 71.1729,0 129.507,-23.3385 174.838,-70.0037 45.1652,-46.4998 67.8304,-111 67.8304,-193.169 0,-66.6612 -9.99209,-118.996 -29.9999,-157.169 -19.996,-38.1613 -49.1691,-67.8304 -87.4957,-88.9957 -38.1731,-21.1653 -80.0076,-31.6652 -125.173,-31.6652 -72.6611,0 -131.326,23.1613 -176.161,69.6611 -44.8345,46.4998 -67.169,113.503 -67.169,200.834zm89.9996 -0.165354c0,-66.3304 14.5039,-115.996 43.4998,-148.83 29.1731,-32.9999 65.669,-49.4998 109.83,-49.4998 43.6652,0 80.0076,16.4999 109.169,49.6652 28.9959,33.1652 43.4998,83.669 43.4998,151.499 0,64.0037 -14.6692,112.5 -43.8305,145.334 -29.1731,32.9999 -65.5037,49.4998 -108.838,49.4998 -44.1612,0 -80.6572,-16.3346 -109.83,-49.1691 -28.9959,-32.8345 -43.4998,-82.3343 -43.4998,-148.499z"/> + <glyph unicode="p" horiz-adv-x="556" d="M65.9997 -199.003l0 718.001 79.9957 0 0 -68.1611c18.8385,26.3267 40.1691,46.1573 64.0037,59.3265 23.6692,13.1692 52.4998,19.8424 86.3382,19.8424 44.3266,0 83.3264,-11.3385 117.165,-34.1692 33.8266,-22.6653 59.3265,-54.8384 76.6651,-96.165 17.1613,-41.5038 25.8306,-86.8343 25.8306,-136.334 0,-52.8423 -9.49603,-100.5 -28.4999,-143.007 -19.0039,-42.3305 -46.6652,-74.8344 -82.9957,-97.4996 -36.1652,-22.4999 -74.3383,-33.8266 -114.33,-33.8266 -29.3385,0 -55.6769,6.16533 -78.8383,18.496 -23.3385,12.3307 -42.3305,27.8385 -57.3305,46.6652l0 -253.168 -88.0036 0zm79.9957 455.337c0,-66.4958 13.4999,-115.665 40.3345,-147.495 26.9999,-31.8424 59.6691,-47.8345 98.0075,-47.8345 38.9998,0 72.3304,16.4999 99.9917,49.4998 27.8385,32.9999 41.6691,83.9997 41.6691,153.165 0,65.9997 -13.4999,115.334 -40.6652,148.169 -27.1652,32.8345 -59.5037,49.1573 -97.1689,49.1573 -37.3345,0 -70.3344,-17.4921 -98.9996,-52.3226 -28.8306,-35.0077 -43.1691,-85.6768 -43.1691,-152.338z"/> + <glyph unicode="r" horiz-adv-x="332" d="M64.9958 0l0 518.998 79.0036 0 0 -79.4997c20.1613,36.8384 38.8345,61.1691 55.9958,72.8383 17.1732,11.8346 35.9999,17.6692 56.5037,17.6692 29.6692,0 59.8344,-9.34248 90.4957,-27.8385l-31.3227 -81.165c-21.3424,12 -42.6731,17.9999 -64.0037,17.9999 -19.1692,0 -36.3306,-5.83462 -51.4959,-17.3385 -15.1771,-11.4921 -26.0078,-27.496 -32.5038,-47.9998 -9.83854,-31.1692 -14.6692,-65.3265 -14.6692,-102.496l0 -271.168 -88.0036 0z"/> + <glyph unicode="w" horiz-adv-x="722" d="M159.33 0l-156.826 518.998 91.9957 0 82.8304 -299.503 29.3385 -111.496c1.16929,5.50392 10.1693,41.1613 26.8345,106.996l82.169 304.003 90.165 0 78.165 -301.333 25.4999 -98.8343 29.8345 100.169 89.6689 299.999 85.4997 0 -162.838 -518.998 -91.0036 0 -82.3343 310.499 -20.8346 88.8304 -105 -399.329 -93.165 0z"/> + </font> + <style type="text/css"> + <![CDATA[ + @font-face { font-family:"Arial";font-variant:normal;font-style:normal;font-weight:normal;src:url("#FontID0") format(svg)} + .str4 {stroke:#FF6600;stroke-width:7.62;stroke-miterlimit:22.9256} + .str2 {stroke:fuchsia;stroke-width:7.62;stroke-miterlimit:22.9256} + .str0 {stroke:red;stroke-width:7.62;stroke-miterlimit:22.9256} + .str3 {stroke:aqua;stroke-width:7.62;stroke-miterlimit:22.9256} + .str1 {stroke:blue;stroke-width:7.62;stroke-miterlimit:22.9256} + .fil0 {fill:none} + .fil1 {fill:black} + .fnt0 {font-weight:normal;font-size:846.67px;font-family:'Arial'} + ]]> + </style> + </defs> + <g id="レイヤ_x0020_1"> + <metadata id="CorelCorpID_0Corel-Layer"/> + <rect class="fil0 str0" x="3000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="3000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="3000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="3000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="3000" y="15000" width="2000" height="2000"/> + <line class="fil0 str0" x1="-0" y1="0" x2="500" y2= "0" /> + <text x="1058.24" y="7272.62" class="fil1 fnt0">10</text> + <text x="1058.24" y="10264.61" class="fil1 fnt0">20</text> + <text x="1084.7" y="13272.63" class="fil1 fnt0">30</text> + <text x="1045.01" y="16259.4" class="fil1 fnt0">40</text> + <text x="1568.56" y="4306.48" class="fil1 fnt0">4</text> + <text x="1568.56" y="4306.48" class="fil1 fnt0">4</text> + <g transform="matrix(2.64845E-14 -1 1 2.64845E-14 -14323.7 26102.3)"> + <text x="20320" y="15240" class="fil1 fnt0">Speed</text> + </g> + <text x="2934.81" y="990.69" class="fil1 fnt0">Power</text> + <text x="3508.19" y="2299.3" class="fil1 fnt0">40</text> + <rect class="fil0 str0" x="6000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="6000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="6000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="6000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="6000" y="15000" width="2000" height="2000"/> + <text x="6508.19" y="2299.3" class="fil1 fnt0">50</text> + <rect class="fil0 str0" x="9000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="9000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="9000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="9000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="9000" y="15000" width="2000" height="2000"/> + <text x="9508.19" y="2299.3" class="fil1 fnt0">60</text> + <rect class="fil0 str0" x="12000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="12000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="12000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="12000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="12000" y="15000" width="2000" height="2000"/> + <text x="12508.19" y="2299.3" class="fil1 fnt0">70</text> + <rect class="fil0 str0" x="15000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="15000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="15000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="15000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="15000" y="15000" width="2000" height="2000"/> + <text x="15508.19" y="2299.3" class="fil1 fnt0">80</text> + <text x="1519.73" y="18591.56" class="fil1 fnt0">250PPI</text> + <rect class="fil0 str0" x="23000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="23000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="23000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="23000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="23000" y="15000" width="2000" height="2000"/> + <text x="20528.59" y="7316.82" class="fil1 fnt0">300</text> + <text x="20528.59" y="10239.63" class="fil1 fnt0">400</text> + <text x="20528.59" y="13202.97" class="fil1 fnt0">500</text> + <text x="20528.59" y="16303.6" class="fil1 fnt0">600</text> + <text x="20528.59" y="4350.68" class="fil1 fnt0">250</text> + <g transform="matrix(2.64845E-14 -1 1 2.64845E-14 4760 24702.7)"> + <text x="20320" y="15240" class="fil1 fnt0">PPI</text> + </g> + <text x="21961.05" y="885.64" class="fil1 fnt0">Power:</text> + <text x="21961.05" y="1831.51" class="fil1 fnt0">Speed:</text> + </g> +</svg> diff --git a/docs/images/week03/laser_1.png b/docs/images/week03/laser_1.png old mode 100755 new mode 100644 diff --git a/docs/images/week03/laser_2.png b/docs/images/week03/laser_2.png old mode 100755 new mode 100644 diff --git a/docs/images/week03/laser_3.png b/docs/images/week03/laser_3.png old mode 100755 new mode 100644 diff --git a/docs/images/week03/laser_4.png b/docs/images/week03/laser_4.png old mode 100755 new mode 100644 diff --git a/docs/images/week03/psr.svg b/docs/images/week03/psr.svg index 78b625e0e2bb2165fee88b7fd4177bf91f213c60..89c35bbc48e36173cd2565510b177335a12ea620 100644 --- a/docs/images/week03/psr.svg +++ b/docs/images/week03/psr.svg @@ -1,110 +1,110 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<!-- Creator: CorelDRAW 2018 (64-Bit) --> -<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="406.4mm" height="304.8mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" -viewBox="0 0 40640 30480" - xmlns:xlink="http://www.w3.org/1999/xlink"> - <defs> - <font id="FontID0" horiz-adv-x="667" font-variant="normal" style="fill-rule:nonzero" font-style="normal" font-weight="400"> - <font-face - font-family="Arial"> - <font-face-src> - <font-face-name name="Arial"/> - </font-face-src> - </font-face> - <missing-glyph><path d="M0 0z"/></missing-glyph> - <glyph unicode="0" horiz-adv-x="556" d="M41.9998 353.337c0,84.4957 8.66926,152.834 25.996,204.495 17.5039,51.8384 43.3345,91.665 77.669,119.503 34.1692,27.8267 77.3383,41.6691 129.33,41.6691 38.3384,0 71.9997,-7.67714 101.173,-23.1731 28.9959,-15.496 52.9959,-37.8306 71.669,-67.0037 18.6613,-28.9959 33.3306,-64.4997 43.9959,-106.322 10.8307,-41.8345 16.1692,-98.3382 16.1692,-169.169 0,-83.9997 -8.66926,-152.007 -25.8306,-203.668 -17.1732,-51.8384 -43.0038,-91.665 -77.3383,-119.669 -34.1692,-28.0038 -77.5036,-41.9998 -129.838,-41.9998 -68.8226,0 -123,24.496 -162.33,73.6651 -47.1612,59.9998 -70.6651,157.169 -70.6651,291.672zm89.9996 -0.342518c0,-117.826 13.6653,-196.157 41.1731,-234.826 27.496,-38.8345 61.4998,-58.1691 101.822,-58.1691 40.3345,0 74.3383,19.4999 101.834,58.3344 27.5078,38.9998 41.1731,117.165 41.1731,234.66 0,117.838 -13.6653,196.169 -41.1731,234.838 -27.3306,38.8345 -61.6651,58.1691 -102.826,58.1691 -40.3345,0 -72.6729,-17.1732 -96.8382,-51.3305 -30.1652,-43.4998 -45.1652,-124.169 -45.1652,-241.676z"/> - <glyph unicode="1" horiz-adv-x="556" d="M371.999 0l-88.0036 0 0 560.336c-21.1653,-20.3385 -48.9919,-40.4998 -83.3264,-60.673 -34.3345,-20.1613 -65.3383,-35.3266 -92.6689,-45.3305l0 85.0036c49.1691,22.996 92.1729,50.9998 128.999,83.9997 36.8384,32.8345 62.9998,64.6651 78.3304,95.6689l56.6691 0 0 -719.005z"/> - <glyph unicode="2" horiz-adv-x="556" d="M503.006 83.9997l0 -83.9997 -474.01 0c-0.661415,21.1653 2.83463,41.5038 10.3346,61.1691 12.1653,32.1613 31.6652,63.9919 58.4998,95.161 26.8345,31.1692 65.173,67.169 115.003,108 77.5036,63.8383 130.169,114.342 157.665,151.665 27.6731,37.3345 41.5038,72.6729 41.5038,106.004 0,34.8306 -12.5078,64.169 -37.4999,88.1689 -25.0038,23.8346 -57.673,35.8345 -97.8303,35.8345 -42.5077,0 -76.4997,-12.6732 -102,-37.9959 -25.5117,-25.1692 -38.3384,-60.1769 -38.6691,-105l-89.9996 8.99996c6.16533,67.3226 29.492,118.665 69.8265,153.992 40.4998,35.3384 94.665,53.0077 162.838,53.0077 68.669,0 123.165,-19.0039 163.169,-57.1769 40.1573,-38.1613 60.1651,-85.4997 60.1651,-141.826 0,-28.6652 -5.83462,-56.8344 -17.6692,-84.5075 -11.6692,-27.8267 -31.1692,-56.9998 -58.3344,-87.6611 -27.3306,-30.4959 -72.4958,-72.6611 -135.496,-126 -52.8305,-44.3384 -86.8343,-74.3383 -101.834,-90.165 -14.9999,-15.8385 -27.3306,-31.6652 -37.1691,-47.6691l351.506 0z"/> - <glyph unicode="3" horiz-adv-x="556" d="M41.9998 190.003l88.0036 12c10.1574,-50.0077 27.1652,-86.0075 51.3305,-108 24.1653,-22.0039 53.8344,-32.9999 88.9957,-32.9999 41.6691,0 76.8422,14.3267 105.165,42.992 28.3345,28.6652 42.5077,64.169 42.5077,106.5 0,40.3345 -13.1692,73.6769 -39.6731,100.004 -26.3267,26.1731 -59.8344,39.3306 -100.665,39.3306 -16.6653,0 -37.3345,-3.3307 -62.1612,-9.82673l9.82673 76.9958c5.83462,-0.661415 10.6653,-1.00393 14.1732,-1.00393 37.6652,0 71.3265,9.83854 101.492,29.3385 29.9999,19.4999 44.9998,49.4998 44.9998,89.9996 0,32.1731 -10.996,58.8305 -32.8227,79.9957 -21.8385,21.1771 -50.0077,31.677 -84.5075,31.677 -34.3345,0 -62.8344,-10.8425 -85.665,-32.5038 -22.8306,-21.6731 -37.4999,-54.1651 -43.9959,-97.4996l-88.0036 16.0039c10.8307,58.9958 35.1613,104.822 73.3344,137.326 37.9959,32.5038 85.4997,48.673 142.169,48.673 38.9998,0 74.9997,-8.33855 107.834,-25.1692 32.9999,-16.6653 58.1573,-39.5077 75.4958,-68.3383 17.5039,-28.9959 26.1613,-59.6691 26.1613,-92.1611 0,-30.8385 -8.32674,-58.8423 -24.8267,-84.165 -16.6653,-25.3345 -41.3384,-45.5077 -73.8304,-60.5076 42.3305,-9.66138 75.1651,-29.9999 98.6571,-60.8265 23.3385,-30.6731 35.0077,-69.3422 35.0077,-115.5 0,-62.5037 -22.8306,-115.677 -68.3383,-159.177 -45.6612,-43.4998 -103.334,-65.1612 -172.995,-65.1612 -62.8344,0 -115.003,18.8385 -156.507,56.3384 -41.6573,37.4999 -65.3265,85.9957 -71.1611,145.665z"/> - <glyph unicode="4" horiz-adv-x="556" d="M322.995 0l0 170.999 -310.995 0 0 80.9997 326.999 464.006 71.9997 0 0 -464.006 97.0036 0 0 -80.9997 -97.0036 0 0 -170.999 -88.0036 0zm0 251.999l0 322.168 -224.491 -322.168 224.491 0z"/> - <glyph unicode="5" horiz-adv-x="556" d="M41.9998 187.995l91.9957 7.00391c6.83856,-44.8345 22.6653,-78.4958 47.3384,-101.161 24.6613,-22.4999 54.8384,-33.8384 90.3304,-33.8384 42.8384,0 78.6729,16.0039 107.834,47.8345 28.9959,31.9959 43.4998,74.3383 43.4998,127.003 0,50.1612 -13.8307,89.6571 -41.6691,118.665 -27.8267,28.9959 -64.6651,43.4998 -110.492,43.4998 -28.4999,0 -53.9998,-6.50785 -76.6651,-19.4999 -22.4999,-13.0039 -40.1691,-29.8345 -53.173,-50.5037l-82.9957 12 68.9997 368.006 354.991 0 0 -83.9997 -284.822 0 -38.1731 -193.169c42.8384,30.1652 87.8382,45.1652 134.834,45.1652 62.3383,0 115.003,-21.6731 157.83,-65.0076 42.8384,-43.3227 64.3344,-98.9996 64.3344,-166.995 0,-64.8305 -18.8267,-120.838 -56.5037,-167.999 -45.8266,-58.0037 -108.496,-86.9997 -187.83,-86.9997 -64.9958,0 -118.003,18.3306 -159.165,54.8384 -41.1613,36.4959 -64.6651,84.8264 -70.4997,145.157z"/> - <glyph unicode="6" horiz-adv-x="556" d="M499.002 541.002l-86.9997 -7.00391c-7.83068,34.4999 -19.0039,59.6691 -33.5077,75.3304 -23.8227,25.1692 -53.3266,37.677 -88.3225,37.677 -28.1692,0 -53.173,-7.84249 -74.669,-23.5038 -27.6731,-20.1731 -49.3345,-49.4998 -65.5037,-88.1689 -16.0039,-38.8345 -24.3306,-94.0036 -25.0038,-165.495 21.1653,32.1613 47.173,56.1612 77.8343,71.6572 30.6731,15.6732 62.669,23.5038 96.3421,23.5038 58.6651,0 108.661,-21.6613 149.999,-64.8305 41.1613,-43.1691 61.8305,-98.8343 61.8305,-167.338 0,-44.9998 -9.67319,-86.669 -29.0078,-125.326 -19.4999,-38.6691 -45.9919,-68.173 -79.9957,-88.665 -33.8266,-20.5039 -72.3304,-30.8385 -115.334,-30.8385 -73.169,0 -133.003,26.9999 -179.326,80.8343 -46.1691,53.8344 -69.3422,142.665 -69.3422,266.338 0,138.33 25.6653,238.995 76.8422,301.83 44.6573,54.6612 104.834,82.0036 180.661,82.0036 56.3384,0 102.673,-15.8385 138.673,-47.3384 35.9999,-31.4999 57.6612,-74.9997 64.8305,-130.665zm-359.999 -308.999c0,-30.3306 6.49604,-59.3383 19.3346,-86.9997 12.8267,-27.6731 30.8267,-48.673 53.6573,-63.1651 23.0078,-14.5039 47.3384,-21.8385 73.169,-21.8385 37.4999,0 69.5076,14.9999 95.9996,44.9998 26.5038,29.9999 39.8384,70.6651 39.8384,122.173 0,49.4998 -13.1692,88.4997 -39.3306,117 -26.1731,28.4999 -59.5037,42.8266 -100.004,42.8266 -39.6731,0 -73.4997,-14.3267 -101.173,-42.8266 -27.6613,-28.4999 -41.492,-65.8344 -41.492,-112.169z"/> - <glyph unicode="7" horiz-adv-x="556" d="M46.9959 623.005l0 83.9997 463.002 0 0 -68.0076c-45.4959,-48.4959 -90.8264,-112.996 -135.496,-193.499 -44.8345,-80.5036 -79.3343,-163.334 -103.83,-248.503 -17.5039,-59.8344 -28.8424,-125.657 -33.6731,-196.995l-89.9996 0c1.00393,56.3384 12,124.5 33.1652,204.33 21.1653,80.0076 51.3305,157.003 90.8382,231.164 39.4959,74.1729 81.4957,136.677 126,187.511l-350.006 0z"/> - <glyph unicode="8" horiz-adv-x="556" d="M177.495 388.168c-36.4959,13.3346 -63.4958,32.5038 -81.165,57.1651 -17.4921,24.8385 -26.3267,54.4958 -26.3267,88.9957 0,52.1691 18.6613,95.8343 55.9958,131.338 37.4999,35.5038 87.165,53.3384 149.338,53.3384 62.3265,0 112.665,-18.1771 150.661,-54.5077 37.9959,-36.3306 56.9998,-80.4918 56.9998,-132.661 0,-33.1652 -8.66926,-62.173 -25.996,-86.669 -17.3385,-24.6731 -43.6652,-43.6652 -79.169,-56.9998 43.8305,-14.3385 76.9958,-37.3345 99.8382,-69.3304 22.8306,-31.8424 34.3345,-69.8383 34.3345,-114.165 0,-61.1691 -21.6731,-112.511 -64.8423,-154.169 -43.3345,-41.6691 -100.169,-62.5037 -170.669,-62.5037 -70.4997,0 -127.334,20.8346 -170.657,62.669 -43.1691,41.8345 -64.8423,93.9918 -64.8423,156.495 0,46.4998 11.8346,85.4997 35.5038,116.834 23.6692,31.4999 57.3305,52.8305 100.996,64.169zm-17.4921 149.338c0,-34.0038 10.8307,-61.6769 32.3266,-83.1729 21.6731,-21.496 50.0077,-32.3385 85.169,-32.3385 34.1692,0 61.8305,10.6771 83.3383,32.0077 21.496,21.3306 32.1613,47.5037 32.1613,78.4958 0,32.3385 -10.996,59.5037 -33.1652,81.5076 -22.0039,21.992 -49.8305,32.9999 -83.3383,32.9999 -33.8266,0 -61.6651,-10.8425 -83.6572,-32.3385 -21.8385,-21.496 -32.8345,-47.1612 -32.8345,-77.1611zm-29.0078 -331.003c0,-25.1692 5.83462,-49.3345 17.5039,-72.8383 11.6692,-23.3267 29.3385,-41.5038 52.9959,-54.3305 23.5038,-12.8385 48.8384,-19.3346 75.6729,-19.3346 42.3305,0 76.9958,13.4999 104.161,40.4998 27.1652,26.9999 40.6652,61.3344 40.6652,103.004 0,42.3305 -13.996,77.3265 -41.8227,105 -28.0038,27.6613 -63.3423,41.492 -105.838,41.492 -41.6691,0 -75.8383,-13.6653 -102.838,-40.9959 -26.9999,-27.3306 -40.4998,-61.4998 -40.4998,-102.496z"/> - <glyph unicode=":" horiz-adv-x="277" d="M89.9996 418.994l0 100.004 100.004 0 0 -100.004 -100.004 0zm0 -418.994l0 100.004 100.004 0 0 -100.004 -100.004 0z"/> - <glyph unicode="I" horiz-adv-x="277" d="M92.9996 0l0 716.005 94.9957 0 0 -716.005 -94.9957 0z"/> - <glyph unicode="P" horiz-adv-x="667" d="M76.9958 0l0 716.005 270.341 0c47.4919,0 83.8343,-2.33857 108.992,-6.83856 35.1731,-5.83462 64.6769,-16.996 88.4997,-33.3306 23.8346,-16.4999 43.0038,-39.5077 57.5076,-68.9997 14.4921,-29.5038 21.6613,-62.0076 21.6613,-97.4996 0,-60.673 -19.3346,-112.169 -58.1691,-154.169 -38.6573,-42.1652 -108.826,-63.1651 -210.165,-63.1651l-183.661 0 0 -292.003 -95.0075 0zm95.0075 376.002l184.995 0c61.3344,0 104.669,11.3267 130.499,34.1692 25.6653,22.8306 38.5038,54.8266 38.5038,96.3303 0,29.8345 -7.49997,55.4998 -22.6653,76.8304 -15.1653,21.3306 -35.1731,35.5038 -59.8344,42.3305 -16.0039,4.16927 -45.5077,6.34249 -88.3343,6.34249l-183.165 0 0 -256.003z"/> - <glyph unicode="S" horiz-adv-x="667" d="M46.0038 229.995l88.9957 8.00784c4.16927,-35.9999 13.996,-65.5037 29.5038,-88.665 15.496,-23.0078 39.4959,-41.6691 71.9997,-56.0077 32.492,-14.1614 69.1651,-21.3306 109.83,-21.3306 36.1652,0 67.9958,5.33856 95.6689,16.1692 27.6613,10.8307 48.1652,25.6653 61.6651,44.492 13.4999,18.8385 20.3385,39.3424 20.3385,61.3344 0,22.3346 -6.50785,41.8345 -19.4999,58.6769 -13.0039,16.6653 -34.5117,30.6613 -64.5116,42.1652 -19.1574,7.33462 -61.6651,18.9921 -127.499,34.8306 -65.8226,15.8267 -111.826,30.6613 -138.165,44.6691 -34.1692,17.9999 -59.4919,40.3345 -76.169,66.8265 -16.8306,26.5038 -25.1574,56.3384 -25.1574,89.1729 0,36.3306 10.3346,70.169 30.8267,101.492 20.5039,31.4999 50.3384,55.3344 89.8343,71.669 39.3306,16.3346 83.1729,24.5078 131.338,24.5078 52.9959,0 99.8264,-8.5039 140.326,-25.6771 40.4998,-16.996 71.669,-42.1652 93.5075,-75.4958 21.8267,-33.1652 33.4959,-70.8304 35.1613,-112.83l-90.9918 -7.00391c-4.8425,45.1652 -21.3424,79.3343 -49.5116,102.33 -28.1574,23.1731 -69.8265,34.677 -124.83,34.677 -57.3305,0 -99.165,-10.5 -125.326,-31.4999 -26.1731,-20.9999 -39.3424,-46.3345 -39.3424,-76.0036 0,-25.6653 9.34248,-46.8305 27.8385,-63.5076 18.3306,-16.4999 65.8344,-33.6613 142.83,-50.9998 77.0076,-17.4921 129.838,-32.6574 158.503,-45.6612 41.5038,-19.1692 72.3304,-43.3345 92.1611,-72.8383 19.8424,-29.3267 29.6692,-63.1651 29.6692,-101.492 0,-38.1731 -10.8307,-73.8422 -32.6692,-107.504 -21.8267,-33.6613 -52.9959,-59.8344 -93.8264,-78.4958 -40.8305,-18.6732 -86.669,-28.0038 -137.834,-28.0038 -64.6651,0 -118.83,9.49603 -162.495,28.3345 -43.8423,18.8267 -78.0115,47.1612 -102.838,85.169 -25.0038,37.8306 -37.9959,80.669 -39.3306,128.492z"/> - <glyph unicode="d" horiz-adv-x="556" d="M400.994 0l0 65.8344c-32.8227,-51.1652 -81.165,-76.8304 -144.992,-76.8304 -41.3384,0 -79.3343,11.3267 -113.834,34.1573 -34.6652,22.6771 -61.4998,54.5077 -80.669,95.1729 -19.0039,40.8305 -28.4999,87.6611 -28.4999,140.669 0,51.6612 8.66926,98.4917 25.8306,140.669 17.3385,41.9998 43.1691,74.3265 77.669,96.661 34.3345,22.4999 73.0036,33.6731 115.5,33.6731 31.3345,0 59.173,-6.6732 83.5036,-19.8424 24.3306,-13.1692 44.1612,-30.4959 59.4919,-51.6612l0 257.503 88.0036 0 0 -716.005 -82.0036 0zm-277.995 258.838c0,-66.3423 13.996,-115.842 42.1652,-148.677 28.0038,-32.8227 61.1691,-49.1573 99.3303,-49.1573 38.5038,0 71.1729,15.6614 98.1728,46.9959 26.8345,31.3345 40.3345,79.169 40.3345,143.503 0,70.6651 -13.6653,122.669 -41.1731,155.834 -27.3306,33.1652 -61.1572,49.6652 -101.326,49.6652 -39.1652,0 -71.8344,-15.8385 -98.1728,-47.6691 -26.1613,-31.8306 -39.3306,-82.0036 -39.3306,-150.495z"/> - <glyph unicode="e" horiz-adv-x="556" d="M419.998 167.999l91.0036 -12c-14.1732,-52.8305 -40.6652,-94.0036 -79.3343,-123.165 -38.6691,-29.1731 -88.0036,-43.8305 -148.169,-43.8305 -75.6611,0 -135.661,23.3267 -179.999,69.9919 -44.3384,46.4998 -66.4958,112.003 -66.4958,196.169 0,86.9997 22.3346,154.665 67.1572,202.665 44.8345,48.177 103.004,72.1769 174.507,72.1769 69.1651,0 125.669,-23.5038 169.499,-70.6769 43.8305,-47.1612 65.8344,-113.492 65.8344,-198.991 0,-5.17321 -0.165354,-13.0039 -0.496061,-23.3385l-386.502 0c3.3307,-56.8344 19.3346,-100.5 48.3305,-130.665 28.8306,-30.1652 64.9958,-45.3305 108.165,-45.3305 32.1731,0 59.6691,8.49209 82.3343,25.4999 22.8306,16.996 40.8305,44.1612 54.1651,81.4957zm-287.999 140.999l289.003 0c-3.83857,43.6652 -14.9999,76.3343 -33.1652,98.1728 -27.8385,33.8266 -64.169,50.8226 -108.673,50.8226 -40.3345,0 -74.1611,-13.4999 -101.669,-40.4998 -27.3306,-26.9999 -42.4959,-63.1651 -45.4959,-108.496z"/> - <glyph unicode="o" horiz-adv-x="556" d="M32.9999 259.499c0,95.8343 26.6692,166.83 80.1611,212.999 44.5038,38.3384 99.0114,57.5076 163.169,57.5076 71.1729,0 129.507,-23.3385 174.838,-70.0037 45.1652,-46.4998 67.8304,-111 67.8304,-193.169 0,-66.6612 -9.99209,-118.996 -29.9999,-157.169 -19.996,-38.1613 -49.1691,-67.8304 -87.4957,-88.9957 -38.1731,-21.1653 -80.0076,-31.6652 -125.173,-31.6652 -72.6611,0 -131.326,23.1613 -176.161,69.6611 -44.8345,46.4998 -67.169,113.503 -67.169,200.834zm89.9996 -0.165354c0,-66.3304 14.5039,-115.996 43.4998,-148.83 29.1731,-32.9999 65.669,-49.4998 109.83,-49.4998 43.6652,0 80.0076,16.4999 109.169,49.6652 28.9959,33.1652 43.4998,83.669 43.4998,151.499 0,64.0037 -14.6692,112.5 -43.8305,145.334 -29.1731,32.9999 -65.5037,49.4998 -108.838,49.4998 -44.1612,0 -80.6572,-16.3346 -109.83,-49.1691 -28.9959,-32.8345 -43.4998,-82.3343 -43.4998,-148.499z"/> - <glyph unicode="p" horiz-adv-x="556" d="M65.9997 -199.003l0 718.001 79.9957 0 0 -68.1611c18.8385,26.3267 40.1691,46.1573 64.0037,59.3265 23.6692,13.1692 52.4998,19.8424 86.3382,19.8424 44.3266,0 83.3264,-11.3385 117.165,-34.1692 33.8266,-22.6653 59.3265,-54.8384 76.6651,-96.165 17.1613,-41.5038 25.8306,-86.8343 25.8306,-136.334 0,-52.8423 -9.49603,-100.5 -28.4999,-143.007 -19.0039,-42.3305 -46.6652,-74.8344 -82.9957,-97.4996 -36.1652,-22.4999 -74.3383,-33.8266 -114.33,-33.8266 -29.3385,0 -55.6769,6.16533 -78.8383,18.496 -23.3385,12.3307 -42.3305,27.8385 -57.3305,46.6652l0 -253.168 -88.0036 0zm79.9957 455.337c0,-66.4958 13.4999,-115.665 40.3345,-147.495 26.9999,-31.8424 59.6691,-47.8345 98.0075,-47.8345 38.9998,0 72.3304,16.4999 99.9917,49.4998 27.8385,32.9999 41.6691,83.9997 41.6691,153.165 0,65.9997 -13.4999,115.334 -40.6652,148.169 -27.1652,32.8345 -59.5037,49.1573 -97.1689,49.1573 -37.3345,0 -70.3344,-17.4921 -98.9996,-52.3226 -28.8306,-35.0077 -43.1691,-85.6768 -43.1691,-152.338z"/> - <glyph unicode="r" horiz-adv-x="332" d="M64.9958 0l0 518.998 79.0036 0 0 -79.4997c20.1613,36.8384 38.8345,61.1691 55.9958,72.8383 17.1732,11.8346 35.9999,17.6692 56.5037,17.6692 29.6692,0 59.8344,-9.34248 90.4957,-27.8385l-31.3227 -81.165c-21.3424,12 -42.6731,17.9999 -64.0037,17.9999 -19.1692,0 -36.3306,-5.83462 -51.4959,-17.3385 -15.1771,-11.4921 -26.0078,-27.496 -32.5038,-47.9998 -9.83854,-31.1692 -14.6692,-65.3265 -14.6692,-102.496l0 -271.168 -88.0036 0z"/> - <glyph unicode="w" horiz-adv-x="722" d="M159.33 0l-156.826 518.998 91.9957 0 82.8304 -299.503 29.3385 -111.496c1.16929,5.50392 10.1693,41.1613 26.8345,106.996l82.169 304.003 90.165 0 78.165 -301.333 25.4999 -98.8343 29.8345 100.169 89.6689 299.999 85.4997 0 -162.838 -518.998 -91.0036 0 -82.3343 310.499 -20.8346 88.8304 -105 -399.329 -93.165 0z"/> - </font> - <style type="text/css"> - <![CDATA[ - @font-face { font-family:"Arial";font-variant:normal;font-style:normal;font-weight:normal;src:url("#FontID0") format(svg)} - .str4 {stroke:#FF6600;stroke-width:7.62;stroke-miterlimit:22.9256} - .str2 {stroke:fuchsia;stroke-width:7.62;stroke-miterlimit:22.9256} - .str0 {stroke:red;stroke-width:7.62;stroke-miterlimit:22.9256} - .str3 {stroke:aqua;stroke-width:7.62;stroke-miterlimit:22.9256} - .str1 {stroke:blue;stroke-width:7.62;stroke-miterlimit:22.9256} - .fil0 {fill:none} - .fil1 {fill:black} - .fnt0 {font-weight:normal;font-size:846.67px;font-family:'Arial'} - ]]> - </style> - </defs> - <g id="レイヤ_x0020_1"> - <metadata id="CorelCorpID_0Corel-Layer"/> - <rect class="fil0 str0" x="3000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="3000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="3000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="3000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="3000" y="15000" width="2000" height="2000"/> - <line class="fil0 str0" x1="-0" y1="0" x2="500" y2= "0" /> - <text x="1058.24" y="7272.62" class="fil1 fnt0">10</text> - <text x="1058.24" y="10264.61" class="fil1 fnt0">20</text> - <text x="1084.7" y="13272.63" class="fil1 fnt0">30</text> - <text x="1045.01" y="16259.4" class="fil1 fnt0">40</text> - <text x="1568.56" y="4306.48" class="fil1 fnt0">4</text> - <text x="1568.56" y="4306.48" class="fil1 fnt0">4</text> - <g transform="matrix(2.64845E-14 -1 1 2.64845E-14 -14323.7 26102.3)"> - <text x="20320" y="15240" class="fil1 fnt0">Speed</text> - </g> - <text x="2934.81" y="990.69" class="fil1 fnt0">Power</text> - <text x="3508.19" y="2299.3" class="fil1 fnt0">40</text> - <rect class="fil0 str0" x="6000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="6000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="6000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="6000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="6000" y="15000" width="2000" height="2000"/> - <text x="6508.19" y="2299.3" class="fil1 fnt0">50</text> - <rect class="fil0 str0" x="9000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="9000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="9000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="9000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="9000" y="15000" width="2000" height="2000"/> - <text x="9508.19" y="2299.3" class="fil1 fnt0">60</text> - <rect class="fil0 str0" x="12000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="12000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="12000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="12000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="12000" y="15000" width="2000" height="2000"/> - <text x="12508.19" y="2299.3" class="fil1 fnt0">70</text> - <rect class="fil0 str0" x="15000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="15000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="15000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="15000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="15000" y="15000" width="2000" height="2000"/> - <text x="15508.19" y="2299.3" class="fil1 fnt0">80</text> - <text x="1519.73" y="18591.56" class="fil1 fnt0">250PPI</text> - <rect class="fil0 str0" x="23000" y="3000" width="2000" height="2000"/> - <rect class="fil0 str1" x="23000" y="6000" width="2000" height="2000"/> - <rect class="fil0 str2" x="23000" y="9000" width="2000" height="2000"/> - <rect class="fil0 str3" x="23000" y="12000" width="2000" height="2000"/> - <rect class="fil0 str4" x="23000" y="15000" width="2000" height="2000"/> - <text x="20528.59" y="7316.82" class="fil1 fnt0">300</text> - <text x="20528.59" y="10239.63" class="fil1 fnt0">400</text> - <text x="20528.59" y="13202.97" class="fil1 fnt0">500</text> - <text x="20528.59" y="16303.6" class="fil1 fnt0">600</text> - <text x="20528.59" y="4350.68" class="fil1 fnt0">250</text> - <g transform="matrix(2.64845E-14 -1 1 2.64845E-14 4760 24702.7)"> - <text x="20320" y="15240" class="fil1 fnt0">PPI</text> - </g> - <text x="21961.05" y="885.64" class="fil1 fnt0">Power:</text> - <text x="21961.05" y="1831.51" class="fil1 fnt0">Speed:</text> - </g> -</svg> +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<!-- Creator: CorelDRAW 2018 (64-Bit) --> +<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="406.4mm" height="304.8mm" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" +viewBox="0 0 40640 30480" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <font id="FontID0" horiz-adv-x="667" font-variant="normal" style="fill-rule:nonzero" font-style="normal" font-weight="400"> + <font-face + font-family="Arial"> + <font-face-src> + <font-face-name name="Arial"/> + </font-face-src> + </font-face> + <missing-glyph><path d="M0 0z"/></missing-glyph> + <glyph unicode="0" horiz-adv-x="556" d="M41.9998 353.337c0,84.4957 8.66926,152.834 25.996,204.495 17.5039,51.8384 43.3345,91.665 77.669,119.503 34.1692,27.8267 77.3383,41.6691 129.33,41.6691 38.3384,0 71.9997,-7.67714 101.173,-23.1731 28.9959,-15.496 52.9959,-37.8306 71.669,-67.0037 18.6613,-28.9959 33.3306,-64.4997 43.9959,-106.322 10.8307,-41.8345 16.1692,-98.3382 16.1692,-169.169 0,-83.9997 -8.66926,-152.007 -25.8306,-203.668 -17.1732,-51.8384 -43.0038,-91.665 -77.3383,-119.669 -34.1692,-28.0038 -77.5036,-41.9998 -129.838,-41.9998 -68.8226,0 -123,24.496 -162.33,73.6651 -47.1612,59.9998 -70.6651,157.169 -70.6651,291.672zm89.9996 -0.342518c0,-117.826 13.6653,-196.157 41.1731,-234.826 27.496,-38.8345 61.4998,-58.1691 101.822,-58.1691 40.3345,0 74.3383,19.4999 101.834,58.3344 27.5078,38.9998 41.1731,117.165 41.1731,234.66 0,117.838 -13.6653,196.169 -41.1731,234.838 -27.3306,38.8345 -61.6651,58.1691 -102.826,58.1691 -40.3345,0 -72.6729,-17.1732 -96.8382,-51.3305 -30.1652,-43.4998 -45.1652,-124.169 -45.1652,-241.676z"/> + <glyph unicode="1" horiz-adv-x="556" d="M371.999 0l-88.0036 0 0 560.336c-21.1653,-20.3385 -48.9919,-40.4998 -83.3264,-60.673 -34.3345,-20.1613 -65.3383,-35.3266 -92.6689,-45.3305l0 85.0036c49.1691,22.996 92.1729,50.9998 128.999,83.9997 36.8384,32.8345 62.9998,64.6651 78.3304,95.6689l56.6691 0 0 -719.005z"/> + <glyph unicode="2" horiz-adv-x="556" d="M503.006 83.9997l0 -83.9997 -474.01 0c-0.661415,21.1653 2.83463,41.5038 10.3346,61.1691 12.1653,32.1613 31.6652,63.9919 58.4998,95.161 26.8345,31.1692 65.173,67.169 115.003,108 77.5036,63.8383 130.169,114.342 157.665,151.665 27.6731,37.3345 41.5038,72.6729 41.5038,106.004 0,34.8306 -12.5078,64.169 -37.4999,88.1689 -25.0038,23.8346 -57.673,35.8345 -97.8303,35.8345 -42.5077,0 -76.4997,-12.6732 -102,-37.9959 -25.5117,-25.1692 -38.3384,-60.1769 -38.6691,-105l-89.9996 8.99996c6.16533,67.3226 29.492,118.665 69.8265,153.992 40.4998,35.3384 94.665,53.0077 162.838,53.0077 68.669,0 123.165,-19.0039 163.169,-57.1769 40.1573,-38.1613 60.1651,-85.4997 60.1651,-141.826 0,-28.6652 -5.83462,-56.8344 -17.6692,-84.5075 -11.6692,-27.8267 -31.1692,-56.9998 -58.3344,-87.6611 -27.3306,-30.4959 -72.4958,-72.6611 -135.496,-126 -52.8305,-44.3384 -86.8343,-74.3383 -101.834,-90.165 -14.9999,-15.8385 -27.3306,-31.6652 -37.1691,-47.6691l351.506 0z"/> + <glyph unicode="3" horiz-adv-x="556" d="M41.9998 190.003l88.0036 12c10.1574,-50.0077 27.1652,-86.0075 51.3305,-108 24.1653,-22.0039 53.8344,-32.9999 88.9957,-32.9999 41.6691,0 76.8422,14.3267 105.165,42.992 28.3345,28.6652 42.5077,64.169 42.5077,106.5 0,40.3345 -13.1692,73.6769 -39.6731,100.004 -26.3267,26.1731 -59.8344,39.3306 -100.665,39.3306 -16.6653,0 -37.3345,-3.3307 -62.1612,-9.82673l9.82673 76.9958c5.83462,-0.661415 10.6653,-1.00393 14.1732,-1.00393 37.6652,0 71.3265,9.83854 101.492,29.3385 29.9999,19.4999 44.9998,49.4998 44.9998,89.9996 0,32.1731 -10.996,58.8305 -32.8227,79.9957 -21.8385,21.1771 -50.0077,31.677 -84.5075,31.677 -34.3345,0 -62.8344,-10.8425 -85.665,-32.5038 -22.8306,-21.6731 -37.4999,-54.1651 -43.9959,-97.4996l-88.0036 16.0039c10.8307,58.9958 35.1613,104.822 73.3344,137.326 37.9959,32.5038 85.4997,48.673 142.169,48.673 38.9998,0 74.9997,-8.33855 107.834,-25.1692 32.9999,-16.6653 58.1573,-39.5077 75.4958,-68.3383 17.5039,-28.9959 26.1613,-59.6691 26.1613,-92.1611 0,-30.8385 -8.32674,-58.8423 -24.8267,-84.165 -16.6653,-25.3345 -41.3384,-45.5077 -73.8304,-60.5076 42.3305,-9.66138 75.1651,-29.9999 98.6571,-60.8265 23.3385,-30.6731 35.0077,-69.3422 35.0077,-115.5 0,-62.5037 -22.8306,-115.677 -68.3383,-159.177 -45.6612,-43.4998 -103.334,-65.1612 -172.995,-65.1612 -62.8344,0 -115.003,18.8385 -156.507,56.3384 -41.6573,37.4999 -65.3265,85.9957 -71.1611,145.665z"/> + <glyph unicode="4" horiz-adv-x="556" d="M322.995 0l0 170.999 -310.995 0 0 80.9997 326.999 464.006 71.9997 0 0 -464.006 97.0036 0 0 -80.9997 -97.0036 0 0 -170.999 -88.0036 0zm0 251.999l0 322.168 -224.491 -322.168 224.491 0z"/> + <glyph unicode="5" horiz-adv-x="556" d="M41.9998 187.995l91.9957 7.00391c6.83856,-44.8345 22.6653,-78.4958 47.3384,-101.161 24.6613,-22.4999 54.8384,-33.8384 90.3304,-33.8384 42.8384,0 78.6729,16.0039 107.834,47.8345 28.9959,31.9959 43.4998,74.3383 43.4998,127.003 0,50.1612 -13.8307,89.6571 -41.6691,118.665 -27.8267,28.9959 -64.6651,43.4998 -110.492,43.4998 -28.4999,0 -53.9998,-6.50785 -76.6651,-19.4999 -22.4999,-13.0039 -40.1691,-29.8345 -53.173,-50.5037l-82.9957 12 68.9997 368.006 354.991 0 0 -83.9997 -284.822 0 -38.1731 -193.169c42.8384,30.1652 87.8382,45.1652 134.834,45.1652 62.3383,0 115.003,-21.6731 157.83,-65.0076 42.8384,-43.3227 64.3344,-98.9996 64.3344,-166.995 0,-64.8305 -18.8267,-120.838 -56.5037,-167.999 -45.8266,-58.0037 -108.496,-86.9997 -187.83,-86.9997 -64.9958,0 -118.003,18.3306 -159.165,54.8384 -41.1613,36.4959 -64.6651,84.8264 -70.4997,145.157z"/> + <glyph unicode="6" horiz-adv-x="556" d="M499.002 541.002l-86.9997 -7.00391c-7.83068,34.4999 -19.0039,59.6691 -33.5077,75.3304 -23.8227,25.1692 -53.3266,37.677 -88.3225,37.677 -28.1692,0 -53.173,-7.84249 -74.669,-23.5038 -27.6731,-20.1731 -49.3345,-49.4998 -65.5037,-88.1689 -16.0039,-38.8345 -24.3306,-94.0036 -25.0038,-165.495 21.1653,32.1613 47.173,56.1612 77.8343,71.6572 30.6731,15.6732 62.669,23.5038 96.3421,23.5038 58.6651,0 108.661,-21.6613 149.999,-64.8305 41.1613,-43.1691 61.8305,-98.8343 61.8305,-167.338 0,-44.9998 -9.67319,-86.669 -29.0078,-125.326 -19.4999,-38.6691 -45.9919,-68.173 -79.9957,-88.665 -33.8266,-20.5039 -72.3304,-30.8385 -115.334,-30.8385 -73.169,0 -133.003,26.9999 -179.326,80.8343 -46.1691,53.8344 -69.3422,142.665 -69.3422,266.338 0,138.33 25.6653,238.995 76.8422,301.83 44.6573,54.6612 104.834,82.0036 180.661,82.0036 56.3384,0 102.673,-15.8385 138.673,-47.3384 35.9999,-31.4999 57.6612,-74.9997 64.8305,-130.665zm-359.999 -308.999c0,-30.3306 6.49604,-59.3383 19.3346,-86.9997 12.8267,-27.6731 30.8267,-48.673 53.6573,-63.1651 23.0078,-14.5039 47.3384,-21.8385 73.169,-21.8385 37.4999,0 69.5076,14.9999 95.9996,44.9998 26.5038,29.9999 39.8384,70.6651 39.8384,122.173 0,49.4998 -13.1692,88.4997 -39.3306,117 -26.1731,28.4999 -59.5037,42.8266 -100.004,42.8266 -39.6731,0 -73.4997,-14.3267 -101.173,-42.8266 -27.6613,-28.4999 -41.492,-65.8344 -41.492,-112.169z"/> + <glyph unicode="7" horiz-adv-x="556" d="M46.9959 623.005l0 83.9997 463.002 0 0 -68.0076c-45.4959,-48.4959 -90.8264,-112.996 -135.496,-193.499 -44.8345,-80.5036 -79.3343,-163.334 -103.83,-248.503 -17.5039,-59.8344 -28.8424,-125.657 -33.6731,-196.995l-89.9996 0c1.00393,56.3384 12,124.5 33.1652,204.33 21.1653,80.0076 51.3305,157.003 90.8382,231.164 39.4959,74.1729 81.4957,136.677 126,187.511l-350.006 0z"/> + <glyph unicode="8" horiz-adv-x="556" d="M177.495 388.168c-36.4959,13.3346 -63.4958,32.5038 -81.165,57.1651 -17.4921,24.8385 -26.3267,54.4958 -26.3267,88.9957 0,52.1691 18.6613,95.8343 55.9958,131.338 37.4999,35.5038 87.165,53.3384 149.338,53.3384 62.3265,0 112.665,-18.1771 150.661,-54.5077 37.9959,-36.3306 56.9998,-80.4918 56.9998,-132.661 0,-33.1652 -8.66926,-62.173 -25.996,-86.669 -17.3385,-24.6731 -43.6652,-43.6652 -79.169,-56.9998 43.8305,-14.3385 76.9958,-37.3345 99.8382,-69.3304 22.8306,-31.8424 34.3345,-69.8383 34.3345,-114.165 0,-61.1691 -21.6731,-112.511 -64.8423,-154.169 -43.3345,-41.6691 -100.169,-62.5037 -170.669,-62.5037 -70.4997,0 -127.334,20.8346 -170.657,62.669 -43.1691,41.8345 -64.8423,93.9918 -64.8423,156.495 0,46.4998 11.8346,85.4997 35.5038,116.834 23.6692,31.4999 57.3305,52.8305 100.996,64.169zm-17.4921 149.338c0,-34.0038 10.8307,-61.6769 32.3266,-83.1729 21.6731,-21.496 50.0077,-32.3385 85.169,-32.3385 34.1692,0 61.8305,10.6771 83.3383,32.0077 21.496,21.3306 32.1613,47.5037 32.1613,78.4958 0,32.3385 -10.996,59.5037 -33.1652,81.5076 -22.0039,21.992 -49.8305,32.9999 -83.3383,32.9999 -33.8266,0 -61.6651,-10.8425 -83.6572,-32.3385 -21.8385,-21.496 -32.8345,-47.1612 -32.8345,-77.1611zm-29.0078 -331.003c0,-25.1692 5.83462,-49.3345 17.5039,-72.8383 11.6692,-23.3267 29.3385,-41.5038 52.9959,-54.3305 23.5038,-12.8385 48.8384,-19.3346 75.6729,-19.3346 42.3305,0 76.9958,13.4999 104.161,40.4998 27.1652,26.9999 40.6652,61.3344 40.6652,103.004 0,42.3305 -13.996,77.3265 -41.8227,105 -28.0038,27.6613 -63.3423,41.492 -105.838,41.492 -41.6691,0 -75.8383,-13.6653 -102.838,-40.9959 -26.9999,-27.3306 -40.4998,-61.4998 -40.4998,-102.496z"/> + <glyph unicode=":" horiz-adv-x="277" d="M89.9996 418.994l0 100.004 100.004 0 0 -100.004 -100.004 0zm0 -418.994l0 100.004 100.004 0 0 -100.004 -100.004 0z"/> + <glyph unicode="I" horiz-adv-x="277" d="M92.9996 0l0 716.005 94.9957 0 0 -716.005 -94.9957 0z"/> + <glyph unicode="P" horiz-adv-x="667" d="M76.9958 0l0 716.005 270.341 0c47.4919,0 83.8343,-2.33857 108.992,-6.83856 35.1731,-5.83462 64.6769,-16.996 88.4997,-33.3306 23.8346,-16.4999 43.0038,-39.5077 57.5076,-68.9997 14.4921,-29.5038 21.6613,-62.0076 21.6613,-97.4996 0,-60.673 -19.3346,-112.169 -58.1691,-154.169 -38.6573,-42.1652 -108.826,-63.1651 -210.165,-63.1651l-183.661 0 0 -292.003 -95.0075 0zm95.0075 376.002l184.995 0c61.3344,0 104.669,11.3267 130.499,34.1692 25.6653,22.8306 38.5038,54.8266 38.5038,96.3303 0,29.8345 -7.49997,55.4998 -22.6653,76.8304 -15.1653,21.3306 -35.1731,35.5038 -59.8344,42.3305 -16.0039,4.16927 -45.5077,6.34249 -88.3343,6.34249l-183.165 0 0 -256.003z"/> + <glyph unicode="S" horiz-adv-x="667" d="M46.0038 229.995l88.9957 8.00784c4.16927,-35.9999 13.996,-65.5037 29.5038,-88.665 15.496,-23.0078 39.4959,-41.6691 71.9997,-56.0077 32.492,-14.1614 69.1651,-21.3306 109.83,-21.3306 36.1652,0 67.9958,5.33856 95.6689,16.1692 27.6613,10.8307 48.1652,25.6653 61.6651,44.492 13.4999,18.8385 20.3385,39.3424 20.3385,61.3344 0,22.3346 -6.50785,41.8345 -19.4999,58.6769 -13.0039,16.6653 -34.5117,30.6613 -64.5116,42.1652 -19.1574,7.33462 -61.6651,18.9921 -127.499,34.8306 -65.8226,15.8267 -111.826,30.6613 -138.165,44.6691 -34.1692,17.9999 -59.4919,40.3345 -76.169,66.8265 -16.8306,26.5038 -25.1574,56.3384 -25.1574,89.1729 0,36.3306 10.3346,70.169 30.8267,101.492 20.5039,31.4999 50.3384,55.3344 89.8343,71.669 39.3306,16.3346 83.1729,24.5078 131.338,24.5078 52.9959,0 99.8264,-8.5039 140.326,-25.6771 40.4998,-16.996 71.669,-42.1652 93.5075,-75.4958 21.8267,-33.1652 33.4959,-70.8304 35.1613,-112.83l-90.9918 -7.00391c-4.8425,45.1652 -21.3424,79.3343 -49.5116,102.33 -28.1574,23.1731 -69.8265,34.677 -124.83,34.677 -57.3305,0 -99.165,-10.5 -125.326,-31.4999 -26.1731,-20.9999 -39.3424,-46.3345 -39.3424,-76.0036 0,-25.6653 9.34248,-46.8305 27.8385,-63.5076 18.3306,-16.4999 65.8344,-33.6613 142.83,-50.9998 77.0076,-17.4921 129.838,-32.6574 158.503,-45.6612 41.5038,-19.1692 72.3304,-43.3345 92.1611,-72.8383 19.8424,-29.3267 29.6692,-63.1651 29.6692,-101.492 0,-38.1731 -10.8307,-73.8422 -32.6692,-107.504 -21.8267,-33.6613 -52.9959,-59.8344 -93.8264,-78.4958 -40.8305,-18.6732 -86.669,-28.0038 -137.834,-28.0038 -64.6651,0 -118.83,9.49603 -162.495,28.3345 -43.8423,18.8267 -78.0115,47.1612 -102.838,85.169 -25.0038,37.8306 -37.9959,80.669 -39.3306,128.492z"/> + <glyph unicode="d" horiz-adv-x="556" d="M400.994 0l0 65.8344c-32.8227,-51.1652 -81.165,-76.8304 -144.992,-76.8304 -41.3384,0 -79.3343,11.3267 -113.834,34.1573 -34.6652,22.6771 -61.4998,54.5077 -80.669,95.1729 -19.0039,40.8305 -28.4999,87.6611 -28.4999,140.669 0,51.6612 8.66926,98.4917 25.8306,140.669 17.3385,41.9998 43.1691,74.3265 77.669,96.661 34.3345,22.4999 73.0036,33.6731 115.5,33.6731 31.3345,0 59.173,-6.6732 83.5036,-19.8424 24.3306,-13.1692 44.1612,-30.4959 59.4919,-51.6612l0 257.503 88.0036 0 0 -716.005 -82.0036 0zm-277.995 258.838c0,-66.3423 13.996,-115.842 42.1652,-148.677 28.0038,-32.8227 61.1691,-49.1573 99.3303,-49.1573 38.5038,0 71.1729,15.6614 98.1728,46.9959 26.8345,31.3345 40.3345,79.169 40.3345,143.503 0,70.6651 -13.6653,122.669 -41.1731,155.834 -27.3306,33.1652 -61.1572,49.6652 -101.326,49.6652 -39.1652,0 -71.8344,-15.8385 -98.1728,-47.6691 -26.1613,-31.8306 -39.3306,-82.0036 -39.3306,-150.495z"/> + <glyph unicode="e" horiz-adv-x="556" d="M419.998 167.999l91.0036 -12c-14.1732,-52.8305 -40.6652,-94.0036 -79.3343,-123.165 -38.6691,-29.1731 -88.0036,-43.8305 -148.169,-43.8305 -75.6611,0 -135.661,23.3267 -179.999,69.9919 -44.3384,46.4998 -66.4958,112.003 -66.4958,196.169 0,86.9997 22.3346,154.665 67.1572,202.665 44.8345,48.177 103.004,72.1769 174.507,72.1769 69.1651,0 125.669,-23.5038 169.499,-70.6769 43.8305,-47.1612 65.8344,-113.492 65.8344,-198.991 0,-5.17321 -0.165354,-13.0039 -0.496061,-23.3385l-386.502 0c3.3307,-56.8344 19.3346,-100.5 48.3305,-130.665 28.8306,-30.1652 64.9958,-45.3305 108.165,-45.3305 32.1731,0 59.6691,8.49209 82.3343,25.4999 22.8306,16.996 40.8305,44.1612 54.1651,81.4957zm-287.999 140.999l289.003 0c-3.83857,43.6652 -14.9999,76.3343 -33.1652,98.1728 -27.8385,33.8266 -64.169,50.8226 -108.673,50.8226 -40.3345,0 -74.1611,-13.4999 -101.669,-40.4998 -27.3306,-26.9999 -42.4959,-63.1651 -45.4959,-108.496z"/> + <glyph unicode="o" horiz-adv-x="556" d="M32.9999 259.499c0,95.8343 26.6692,166.83 80.1611,212.999 44.5038,38.3384 99.0114,57.5076 163.169,57.5076 71.1729,0 129.507,-23.3385 174.838,-70.0037 45.1652,-46.4998 67.8304,-111 67.8304,-193.169 0,-66.6612 -9.99209,-118.996 -29.9999,-157.169 -19.996,-38.1613 -49.1691,-67.8304 -87.4957,-88.9957 -38.1731,-21.1653 -80.0076,-31.6652 -125.173,-31.6652 -72.6611,0 -131.326,23.1613 -176.161,69.6611 -44.8345,46.4998 -67.169,113.503 -67.169,200.834zm89.9996 -0.165354c0,-66.3304 14.5039,-115.996 43.4998,-148.83 29.1731,-32.9999 65.669,-49.4998 109.83,-49.4998 43.6652,0 80.0076,16.4999 109.169,49.6652 28.9959,33.1652 43.4998,83.669 43.4998,151.499 0,64.0037 -14.6692,112.5 -43.8305,145.334 -29.1731,32.9999 -65.5037,49.4998 -108.838,49.4998 -44.1612,0 -80.6572,-16.3346 -109.83,-49.1691 -28.9959,-32.8345 -43.4998,-82.3343 -43.4998,-148.499z"/> + <glyph unicode="p" horiz-adv-x="556" d="M65.9997 -199.003l0 718.001 79.9957 0 0 -68.1611c18.8385,26.3267 40.1691,46.1573 64.0037,59.3265 23.6692,13.1692 52.4998,19.8424 86.3382,19.8424 44.3266,0 83.3264,-11.3385 117.165,-34.1692 33.8266,-22.6653 59.3265,-54.8384 76.6651,-96.165 17.1613,-41.5038 25.8306,-86.8343 25.8306,-136.334 0,-52.8423 -9.49603,-100.5 -28.4999,-143.007 -19.0039,-42.3305 -46.6652,-74.8344 -82.9957,-97.4996 -36.1652,-22.4999 -74.3383,-33.8266 -114.33,-33.8266 -29.3385,0 -55.6769,6.16533 -78.8383,18.496 -23.3385,12.3307 -42.3305,27.8385 -57.3305,46.6652l0 -253.168 -88.0036 0zm79.9957 455.337c0,-66.4958 13.4999,-115.665 40.3345,-147.495 26.9999,-31.8424 59.6691,-47.8345 98.0075,-47.8345 38.9998,0 72.3304,16.4999 99.9917,49.4998 27.8385,32.9999 41.6691,83.9997 41.6691,153.165 0,65.9997 -13.4999,115.334 -40.6652,148.169 -27.1652,32.8345 -59.5037,49.1573 -97.1689,49.1573 -37.3345,0 -70.3344,-17.4921 -98.9996,-52.3226 -28.8306,-35.0077 -43.1691,-85.6768 -43.1691,-152.338z"/> + <glyph unicode="r" horiz-adv-x="332" d="M64.9958 0l0 518.998 79.0036 0 0 -79.4997c20.1613,36.8384 38.8345,61.1691 55.9958,72.8383 17.1732,11.8346 35.9999,17.6692 56.5037,17.6692 29.6692,0 59.8344,-9.34248 90.4957,-27.8385l-31.3227 -81.165c-21.3424,12 -42.6731,17.9999 -64.0037,17.9999 -19.1692,0 -36.3306,-5.83462 -51.4959,-17.3385 -15.1771,-11.4921 -26.0078,-27.496 -32.5038,-47.9998 -9.83854,-31.1692 -14.6692,-65.3265 -14.6692,-102.496l0 -271.168 -88.0036 0z"/> + <glyph unicode="w" horiz-adv-x="722" d="M159.33 0l-156.826 518.998 91.9957 0 82.8304 -299.503 29.3385 -111.496c1.16929,5.50392 10.1693,41.1613 26.8345,106.996l82.169 304.003 90.165 0 78.165 -301.333 25.4999 -98.8343 29.8345 100.169 89.6689 299.999 85.4997 0 -162.838 -518.998 -91.0036 0 -82.3343 310.499 -20.8346 88.8304 -105 -399.329 -93.165 0z"/> + </font> + <style type="text/css"> + <![CDATA[ + @font-face { font-family:"Arial";font-variant:normal;font-style:normal;font-weight:normal;src:url("#FontID0") format(svg)} + .str4 {stroke:#FF6600;stroke-width:7.62;stroke-miterlimit:22.9256} + .str2 {stroke:fuchsia;stroke-width:7.62;stroke-miterlimit:22.9256} + .str0 {stroke:red;stroke-width:7.62;stroke-miterlimit:22.9256} + .str3 {stroke:aqua;stroke-width:7.62;stroke-miterlimit:22.9256} + .str1 {stroke:blue;stroke-width:7.62;stroke-miterlimit:22.9256} + .fil0 {fill:none} + .fil1 {fill:black} + .fnt0 {font-weight:normal;font-size:846.67px;font-family:'Arial'} + ]]> + </style> + </defs> + <g id="レイヤ_x0020_1"> + <metadata id="CorelCorpID_0Corel-Layer"/> + <rect class="fil0 str0" x="3000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="3000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="3000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="3000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="3000" y="15000" width="2000" height="2000"/> + <line class="fil0 str0" x1="-0" y1="0" x2="500" y2= "0" /> + <text x="1058.24" y="7272.62" class="fil1 fnt0">10</text> + <text x="1058.24" y="10264.61" class="fil1 fnt0">20</text> + <text x="1084.7" y="13272.63" class="fil1 fnt0">30</text> + <text x="1045.01" y="16259.4" class="fil1 fnt0">40</text> + <text x="1568.56" y="4306.48" class="fil1 fnt0">4</text> + <text x="1568.56" y="4306.48" class="fil1 fnt0">4</text> + <g transform="matrix(2.64845E-14 -1 1 2.64845E-14 -14323.7 26102.3)"> + <text x="20320" y="15240" class="fil1 fnt0">Speed</text> + </g> + <text x="2934.81" y="990.69" class="fil1 fnt0">Power</text> + <text x="3508.19" y="2299.3" class="fil1 fnt0">40</text> + <rect class="fil0 str0" x="6000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="6000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="6000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="6000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="6000" y="15000" width="2000" height="2000"/> + <text x="6508.19" y="2299.3" class="fil1 fnt0">50</text> + <rect class="fil0 str0" x="9000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="9000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="9000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="9000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="9000" y="15000" width="2000" height="2000"/> + <text x="9508.19" y="2299.3" class="fil1 fnt0">60</text> + <rect class="fil0 str0" x="12000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="12000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="12000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="12000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="12000" y="15000" width="2000" height="2000"/> + <text x="12508.19" y="2299.3" class="fil1 fnt0">70</text> + <rect class="fil0 str0" x="15000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="15000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="15000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="15000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="15000" y="15000" width="2000" height="2000"/> + <text x="15508.19" y="2299.3" class="fil1 fnt0">80</text> + <text x="1519.73" y="18591.56" class="fil1 fnt0">250PPI</text> + <rect class="fil0 str0" x="23000" y="3000" width="2000" height="2000"/> + <rect class="fil0 str1" x="23000" y="6000" width="2000" height="2000"/> + <rect class="fil0 str2" x="23000" y="9000" width="2000" height="2000"/> + <rect class="fil0 str3" x="23000" y="12000" width="2000" height="2000"/> + <rect class="fil0 str4" x="23000" y="15000" width="2000" height="2000"/> + <text x="20528.59" y="7316.82" class="fil1 fnt0">300</text> + <text x="20528.59" y="10239.63" class="fil1 fnt0">400</text> + <text x="20528.59" y="13202.97" class="fil1 fnt0">500</text> + <text x="20528.59" y="16303.6" class="fil1 fnt0">600</text> + <text x="20528.59" y="4350.68" class="fil1 fnt0">250</text> + <g transform="matrix(2.64845E-14 -1 1 2.64845E-14 4760 24702.7)"> + <text x="20320" y="15240" class="fil1 fnt0">PPI</text> + </g> + <text x="21961.05" y="885.64" class="fil1 fnt0">Power:</text> + <text x="21961.05" y="1831.51" class="fil1 fnt0">Speed:</text> + </g> +</svg>