UNPKG

gitbook-plugin-webpd

Version:
1,591 lines (1,384 loc) 445 kB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ exports.parse = require('pd-fileutils.parser').parse exports.renderSvg = require('./lib/svg-rendering').render exports.renderPd = require('./lib/pd-rendering').render exports.Patch = require('./lib/Patch') if (typeof window !== 'undefined') window.pdfu = exports },{"./lib/Patch":2,"./lib/pd-rendering":3,"./lib/svg-rendering":4,"pd-fileutils.parser":10}],2:[function(require,module,exports){ /* * Copyright (c) 2012-2015 Sébastien Piquemal <sebpiq@gmail.com> * * BSD Simplified License. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. * * See https://github.com/sebpiq/pd-fileutils for documentation * */ var _ = require('underscore') var Patch = module.exports = function(obj) { _.extend(this, obj) } _.extend(Patch.prototype, { getNode: function(id) { return _.find(this.nodes, function(node) { return node.id === id }) || null }, guessPortlets: function() { var self = this _.each(this.nodes, function(node) { node.outlets = _.reduce(self.connections, function(memo, conn) { if (conn.source.id === node.id) { return Math.max(memo, conn.source.port) } else return memo }, -1) + 1 node.inlets = _.reduce(self.connections, function(memo, conn) { if (conn.sink.id === node.id) { return Math.max(memo, conn.sink.port) } else return memo }, -1) + 1 }) }, getSinks: function(node) { var conns = _.filter(this.connections, function(conn) { return conn.source.id === node.id }) , sinkIds = _.uniq(_.map(conns, function(conn) { return conn.sink.id })) , self = this return _.map(sinkIds, function(sinkId) { return self.getNode(sinkId) }) }, getSources: function(node) { var conns = _.filter(this.connections, function(conn) { return conn.sink.id === node.id }) , sourceIds = _.uniq(_.map(conns, function(conn) { return conn.source.id })) , self = this return _.map(sourceIds, function(sourceId) { return self.getNode(sourceId) }) }, addNode: function(node) { if (node.id === undefined) node.id = this.nextId() else if (this.getNode(node.id) !== null) return this.nodes.push(node) }, nextId: function() { if (this.nodes.length) { return Math.max.apply(Math, _.pluck(this.nodes, 'id')) + 1 } else return 0 } }) },{"underscore":11}],3:[function(require,module,exports){ /* * Copyright (c) 2012-2015 Sébastien Piquemal <sebpiq@gmail.com> * * BSD Simplified License. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. * * See https://github.com/sebpiq/pd-fileutils for documentation * */ var mustache = require('mustache') , _ = require('underscore') exports.render = function(patch) { // Render the graph canvas var rendered = '' , layout = _.clone(patch.layout || {}) _.defaults(layout, {x: 0, y: 0, width: 500, height: 500}) rendered += mustache.render(canvasTpl, {args: patch.args, layout: layout}) + ';\n' // Render all nodes _.forEach(patch.nodes.sort(function(n1, n2){return n1.id - n2.id}), function(node) { var layout = _.clone(node.layout || {}) _.defaults(layout, {x: 0, y: 0}) rendered += mustache.render(objTpl, {args: node.args, layout: layout, proto: node.proto}) + ';\n' }) // Render all connections _.forEach(patch.connections, function(conn) { rendered += mustache.render(connectTpl, conn) + ';\n' }) return rendered } var canvasTpl = '#N canvas {{{layout.x}}} {{{layout.y}}} {{{layout.width}}} {{{layout.height}}} {{{args.0}}}{{#layout.openOnLoad}} {{{.}}}{{/layout.openOnLoad}}' , connectTpl = '#X connect {{{source.id}}} {{{source.port}}} {{{sink.id}}} {{{sink.port}}}' var floatAtomTpl = '#X floatatom {{{layout.x}}} {{{layout.y}}} {{{layout.width}}} {{{args.0}}} {{{args.1}}} {{{layout.labelPos}}} {{{layout.label}}} {{{args.2}}} {{{args.3}}}' , symbolAtomTpl = '#X symbolatom {{{layout.x}}} {{{layout.y}}} {{{layout.width}}} {{{args.0}}} {{{args.1}}} {{{layout.labelPos}}} {{{layout.label}}} {{{args.2}}} {{{args.3}}}' , bngTpl = '#X obj {{{layout.x}}} {{{layout.y}}} bng {{{layout.size}}} {{{layout.hold}}} {{{layout.interrupt}}} {{{args.0}}} {{{args.1}}} {{{args.2}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}}' , nbxTpl = '#X obj {{{layout.x}}} {{{layout.y}}} nbx {{{layout.size}}} {{{layout.height}}} {{{args.0}}} {{{args.1}}} {{{layout.log}}} {{{args.2}}} {{{args.3}}} {{{args.4}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}} {{{layout.logHeight}}}' , vslTpl = '#X obj {{{layout.x}}} {{{layout.y}}} vsl {{{layout.width}}} {{{layout.height}}} {{{args.0}}} {{{args.1}}} {{{layout.log}}} {{{args.2}}} {{{args.3}}} {{{args.4}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}} {{{args.5}}} {{{layout.steadyOnClick}}}' , hslTpl = '#X obj {{{layout.x}}} {{{layout.y}}} hsl {{{layout.width}}} {{{layout.height}}} {{{args.0}}} {{{args.1}}} {{{layout.log}}} {{{args.2}}} {{{args.3}}} {{{args.4}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}} {{{args.5}}} {{{layout.steadyOnClick}}}' , vradioTpl = '#X obj {{{layout.x}}} {{{layout.y}}} vradio {{{layout.size}}} {{{args.0}}} {{{args.1}}} {{{args.2}}} {{{args.3}}} {{{args.4}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}} {{{args.5}}}' , hradioTpl = '#X obj {{{layout.x}}} {{{layout.y}}} hradio {{{layout.size}}} {{{args.0}}} {{{args.1}}} {{{args.2}}} {{{args.3}}} {{{args.4}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}} {{{args.5}}}' , vuTpl = '#X obj {{{layout.x}}} {{{layout.y}}} vu {{{layout.width}}} {{{layout.height}}} {{{args.0}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.labelColor}}} {{{layout.log}}} {{{args.1}}}' , cnvTpl = '#X obj {{{layout.x}}} {{{layout.y}}} cnv {{{layout.size}}} {{{layout.width}}} {{{layout.height}}} {{{args.0}}} {{{args.1}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.labelColor}}} {{{args.2}}}' , objTpl = '#X obj {{{layout.x}}} {{{layout.y}}} {{{proto}}}{{#args}} {{.}}{{/args}}' },{"mustache":9,"underscore":11}],4:[function(require,module,exports){ (function (__dirname){ /* * Copyright (c) 2012-2015 Sébastien Piquemal <sebpiq@gmail.com> * * BSD Simplified License. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. * * See https://github.com/sebpiq/pd-fileutils for documentation * */ var _ = require('underscore') , d3 = require('d3') , Patch = require('./Patch') , isBrowser = (typeof window !== 'undefined') if (!isBrowser) { var fs = require('fs') , path = require('path') , defaultStyle = fs.readFileSync(path.join(__dirname, 'svg-default-style.css')).toString() } var defaults = { portletWidth: 5, portletHeight: 3.5, objMinWidth: 25, objMinHeight: 20, ratio: 1.2, padding: 10, glyphWidth: 8, glyphHeight: 9, textPadding: 6, svgFile: true, style: isBrowser ? null : defaultStyle } exports.render = function(patch, opts) { opts = opts || {} _.defaults(opts, defaults) d3.select('svg').remove() var svgContainer = d3.select('body').append('div') , svg = svgContainer.append('svg') .attr('xmlns', 'http://www.w3.org/2000/svg') .attr('version', '1.1') , root = svg.append('g') , connections, nodes if (opts.style) { svg.append('style').text(opts.style) } // Creating all renderers patch = new Patch(patch) patch.guessPortlets() patch.nodes = _.map(patch.nodes, function(node) { var proto = node.proto if (proto === 'msg') return new MsgRenderer(node, opts) else if (proto === 'text') return new TextRenderer(node, opts) else if (proto === 'floatatom') return new FloatAtomRenderer(node, opts) else if (proto === 'symbolatom') return new SymbolAtomRenderer(node, opts) else if (proto === 'bng') return new BngRenderer(node, opts) else if (proto === 'tgl') return new TglRenderer(node, opts) else if (proto === 'nbx') return new NbxRenderer(node, opts) else if (proto === 'hsl') return new HslRenderer(node, opts) else if (proto === 'vsl') return new VslRenderer(node, opts) else if (proto === 'hradio') return new HRadioRenderer(node, opts) else if (proto === 'vradio') return new VRadioRenderer(node, opts) else if (proto === 'vu') return new VuRenderer(node, opts) else return new ObjectRenderer(node, opts) }) // Render the nodes nodes = root.selectAll('g.node') .data(patch.nodes) .enter() .append('g') .attr('transform', function(renderer) { return 'translate(' + renderer.getX() + ' ' + renderer.getY() + ')' }) .attr('class', 'node') .attr('id', function(node) { return node.id }) .each(function(renderer, i) { renderer.render(d3.select(this)) }) // Render the connections connections = root.selectAll('line.connection') .data(patch.connections) .enter() .append('line') .attr('class', 'connection') .attr('style', 'stroke:black;stroke-width:2px;') .each(function(conn) { var sourceRenderer = patch.getNode(conn.source.id) , sinkRenderer = patch.getNode(conn.sink.id) d3.select(this) .attr('x1', function(conn) { return sourceRenderer.getOutletX(conn.source.port) + opts.portletWidth/2 }) .attr('y1', function(conn) { return sourceRenderer.getOutletY(conn.source.port) + opts.portletHeight }) .attr('x2', function(conn) { return sinkRenderer.getInletX(conn.sink.port) + opts.portletWidth/2 }) .attr('y2', function(conn) { return sinkRenderer.getInletY(conn.sink.port) }) }) // Calculate width / height of the SVG var allX1 = [], allY1 = [], allX2 = [], allY2 = [] , topLeft = {}, bottomRight = {} _.forEach(patch.nodes, function(n) { allX1.push(n.getX()) allY1.push(n.getY()) allX2.push(n.getX() + n.getW()) allY2.push(n.getY() + n.getH()) }) topLeft.x = _.min(allX1) topLeft.y = _.min(allY1) bottomRight.x = _.max(allX2) bottomRight.y = _.max(allY2) svg.attr('width', bottomRight.x - topLeft.x + opts.padding * 2) svg.attr('height', bottomRight.y - topLeft.y + opts.padding * 2) root.attr('transform', 'translate(' + (-topLeft.x + opts.padding) + ' ' + (-topLeft.y + opts.padding) + ')' ) // Finally rendering to a string var rendered = svgContainer[0][0].innerHTML if (opts.svgFile) { rendered = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ' + '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' + rendered } else { svgContainer.remove() } return rendered } //==================== Node renderers ====================// // Simple helper to memoize some method calls var memoized = function(obj, methodName) { var originalMethod = obj[methodName] , cache = undefined if (originalMethod.length > 0) throw new Error('This memoization is valid only for methods with 0 arguments') obj[methodName] = function() { cache = originalMethod.apply(obj, arguments) obj[methodName] = function() { return cache } return cache } } var NodeRenderer = function(node, opts) { this.opts = opts this.node = node this.id = node.id memoized(this, 'getX') memoized(this, 'getY') } _.extend(NodeRenderer.prototype, { // Returns node X in the canvas getX: function() { return this.node.layout.x * this.opts.ratio }, // Returns node Y in the canvas getY: function() { return this.node.layout.y * this.opts.ratio }, // Returns outlet's absolute X in the canvas getOutletX: function(outlet) { return this.getOutletRelX(outlet) + this.getX() }, // Returns intlet's absolute X in the canvas getInletX: function(inlet) { return this.getInletRelX(inlet) + this.getX() }, // Returns outlet's Y in the canvas getOutletY: function(outlet) { return this.getOutletRelY(outlet) + this.getY() }, // Returns inlet's Y in the canvas getInletY: function(inlet) { return this.getInletRelY(inlet) + this.getY() }, // ---- Methods to implement ---- // // Do the actual rendering in svg group `g`. render: function(g) { throw new Error('Implement me') }, // Returns the width of the bounding box of the node getW: function() { throw new Error('Implement me') }, // Returns the height of the bounding box of the node getH: function() { throw new Error('Implement me') }, // Returns outlet X relatively to the node getOutletRelX: function(outlet) { throw new Error('Implement me') }, // Returns inlet X relatively to the node getInletRelX: function(inlet) { throw new Error('Implement me') }, // Returns outlet Y relatively to the node getOutletRelY: function(outlet) { throw new Error('Implement me') }, // Returns inlet Y relatively to the node getInletRelY: function(inlet) { throw new Error('Implement me') }, }) var ObjectRenderer = function() { NodeRenderer.prototype.constructor.apply(this, arguments) memoized(this, 'getW') memoized(this, 'getH') } _.extend(ObjectRenderer.prototype, NodeRenderer.prototype, { render: function(g) { this.renderBox(g) this.renderText(g) this.renderOutlets(g) this.renderInlets(g) }, renderBox: function(g) { g.append('rect') .attr('class', 'box') .attr('width', this.getW()) .attr('height', this.getH()) .attr('style', 'stroke:black;fill:white;') }, renderText: function(g) { g.append('text') .attr('class', 'proto') .text(this.getText()) .attr('dy', this.getTextY()) .attr('dx', this.opts.textPadding) }, renderInlets: function(g) { this._genericRenderPortlets('inlet', g) }, renderOutlets: function(g) { this._genericRenderPortlets('outlet', g) }, _genericRenderPortlets: function(portletType, g) { var portletTypeCap = portletType.substr(0, 1).toUpperCase() + portletType.substr(1) , self = this g.selectAll('rect.' + portletType) .data(_.range(this.node[portletType+'s'])) .enter() .append('rect') .classed(portletType, true) .classed('portlet', true) .attr('width', this.opts.portletWidth) .attr('height', this.opts.portletHeight) .attr('x', function(i) { return self['get' + portletTypeCap + 'RelX'](i) }) .attr('y', function(i) { return self['get' + portletTypeCap + 'RelY'](i) }) }, // Returns object height getH: function() { return this.opts.objMinHeight }, // Returns object width getW: function() { var maxPortlet = Math.max(this.node.inlets, this.node.outlets) , textLength = this.getText().length * this.opts.glyphWidth + this.opts.textPadding * 2 return Math.max((maxPortlet-1) * this.opts.objMinWidth, this.opts.objMinWidth, textLength) }, // Returns text to display on the object getText: function() { return this.node.proto + ' ' + this.node.args.join(' ') }, // Returns text Y relatively to the object getTextY: function() { return this.getH()/2 + this.opts.glyphHeight/2 }, // ---- Implement virtual methods ---- // getOutletRelX: function(outlet) { return this._genericPortletRelX('outlets', outlet) }, getInletRelX: function(inlet) { return this._genericPortletRelX('inlets', inlet) }, getOutletRelY: function(outlet) { return this.getH() - this.opts.portletHeight }, getInletRelY: function(inlet) { return 0 }, _genericPortletRelX: function(inOrOutlets, portlet) { var width = this.getW() , n = this.node[inOrOutlets] if (portlet === 0) return 0; else if (portlet === n-1) return width - this.opts.portletWidth else { // Space between portlets var a = (width - n*this.opts.portletWidth) / (n-1) return portlet * (this.opts.portletWidth + a) } } }) var MsgRenderer = function() { ObjectRenderer.prototype.constructor.apply(this, arguments) } _.extend(MsgRenderer.prototype, ObjectRenderer.prototype, { renderBox: function(g) { var r = this.getH() * 0.75 , teta = Math.asin(this.getH() / (2 * r)) , arcPath = d3.svg.arc()({ innerRadius: r, outerRadius: r, startAngle: -Math.PI / 2 - teta, endAngle: -Math.PI / 2 + teta }) , linePath = d3.svg.line()([ [this.getW(), 0], [0, 0], [0, this.getH()], [this.getW(), this.getH()] ]) g.append('svg:path') .attr('d', linePath) .attr('style', 'stroke:black;fill:white;') g.append('svg:path') .attr('d', arcPath) .attr('transform', 'translate(' + (this.getW() + r * Math.cos(teta)) + ' ' + this.getH()/2 + ')') .attr('style', 'stroke:black;fill:white;') }, getText: function() { return this.node.args.join(' ') } }) var AtomBoxRenderer = function() { ObjectRenderer.prototype.constructor.apply(this, arguments) } _.extend(AtomBoxRenderer.prototype, ObjectRenderer.prototype, { renderBox: function(g) { var r = this.getH() * 0.4 , arcPath = d3.svg.arc()({ innerRadius: r, outerRadius: r, startAngle: 0, endAngle: Math.PI / 2 }) , linePath = d3.svg.line()([ [this.getW() - r, 0], [0, 0], [0, this.getH()], [this.getW(), this.getH()], [this.getW(), r] ]) g.append('svg:path') .attr('d', linePath) .attr('style', 'stroke:black;fill:white;') g.append('svg:path') .attr('d', arcPath) .attr('transform', 'translate(' + (this.getW() - r) + ' ' + r + ')') .attr('style', 'stroke:black;fill:white;') } }) var FloatAtomRenderer = function() { AtomBoxRenderer.prototype.constructor.apply(this, arguments) } _.extend(FloatAtomRenderer.prototype, AtomBoxRenderer.prototype, { getText: function() { return '0' } }) var SymbolAtomRenderer = function() { AtomBoxRenderer.prototype.constructor.apply(this, arguments) } _.extend(SymbolAtomRenderer.prototype, AtomBoxRenderer.prototype, { getText: function() { return 'symbol' } }) var BngRenderer = function() { ObjectRenderer.prototype.constructor.apply(this, arguments) } _.extend(BngRenderer.prototype, ObjectRenderer.prototype, { render: function(g) { g.append('rect') .attr('class', 'box') .attr('width', this.getW()) .attr('height', this.getH()) .attr('style', 'stroke:black;fill:white;') g.append('circle') .attr('cx', this.getW()/2) .attr('cy', this.getH()/2) .attr('r', this.getW()/3) .attr('style', 'stroke:black;fill:white;') this.renderOutlets(g) this.renderInlets(g) }, getW: function() { return 20 }, getH: function() { return 20 } }) var TglRenderer = function() { ObjectRenderer.prototype.constructor.apply(this, arguments) } _.extend(TglRenderer.prototype, ObjectRenderer.prototype, { render: function(g) { var crossPath = d3.svg.symbol() .size(this.getW() * this.getH() / 3.5) .type('cross')([1]) g.append('rect') .attr('class', 'box') .attr('width', this.getW()) .attr('height', this.getH()) .attr('style', 'stroke:black;fill:white;') g.append('svg:path') .attr('d', crossPath) .attr('transform', 'rotate(' + 45 + ' ' + this.getW()/2 + ' ' + this.getH()/2 + ') translate(' + this.getW()/2 + ' ' + this.getH()/2 + ')') .attr('style', 'stroke:black;fill:white;') this.renderOutlets(g) this.renderInlets(g) }, getW: function() { return 20 }, getH: function() { return 20 } }) var NbxRenderer = function() { AtomBoxRenderer.prototype.constructor.apply(this, arguments) } _.extend(NbxRenderer.prototype, AtomBoxRenderer.prototype, { renderBox: function(g) { AtomBoxRenderer.prototype.renderBox.apply(this, arguments) var trianglePath = d3.svg.line()([ [0, 0], [this.getW()/6, this.getH()/2], [0, this.getH()] ]) g.append('svg:path') .attr('d', trianglePath) .attr('style', 'stroke:black;fill:white;') }, getText: function() { return '0' } }) var HslRenderer = function() { ObjectRenderer.prototype.constructor.apply(this, arguments) } _.extend(HslRenderer.prototype, ObjectRenderer.prototype, { renderBox: function(g) { ObjectRenderer.prototype.renderBox.apply(this, arguments) var cursorPath = d3.svg.line()([ [5, 0], [10, 0], [10, this.getH()], [5, this.getH()], [5, 0] ]) g.append('svg:path') .attr('d', cursorPath) .attr('style', 'stroke:black;fill:black;') }, getText: function() { return '' }, getW: function() { return 200 }, getH: function() { return 20 } }) var VslRenderer = function() { ObjectRenderer.prototype.constructor.apply(this, arguments) } _.extend(VslRenderer.prototype, ObjectRenderer.prototype, { renderBox: function(g) { ObjectRenderer.prototype.renderBox.apply(this, arguments) var cursorPath = d3.svg.line()([ [0, 5], [0, 10], [this.getW(), 10], [this.getW(), 5], [0, 5] ]) g.append('svg:path') .attr('d', cursorPath) .attr('style', 'stroke:black;fill:black;') }, getText: function() { return '' }, getW: function() { return 20 }, getH: function() { return 200 } }) var HRadioRenderer = function() { ObjectRenderer.prototype.constructor.apply(this, arguments) } _.extend(HRadioRenderer.prototype, ObjectRenderer.prototype, { renderBox: function(g) { var nBoxes = this.getNBoxes(), i , enabledSize = this.getBoxSize() / 1.5 for (i = 0; i < nBoxes; i++) { g.append('rect') .attr('width', this.getBoxSize()) .attr('height', this.getBoxSize()) .attr('transform', 'translate(' + i * this.getBoxSize() + ' ' + 0 + ')') .attr('style', 'stroke:black;fill:white;') } g.append('rect') .attr('width', enabledSize) .attr('height', enabledSize) .attr('transform', 'translate(' + (this.getBoxSize() - enabledSize) / 2 + ' ' + (this.getBoxSize() - enabledSize) / 2 + ')') .attr('style', 'stroke:black;fill:black;') }, getW: function() { return this.getBoxSize() * this.getNBoxes() }, getH: function() { return this.getBoxSize() }, getBoxSize: function() { return 20 }, getNBoxes: function() { return this.node.args[2] }, getText: function() { return '' } }) var VRadioRenderer = function() { ObjectRenderer.prototype.constructor.apply(this, arguments) } _.extend(VRadioRenderer.prototype, ObjectRenderer.prototype, { renderBox: function(g) { var nBoxes = this.getNBoxes(), i , enabledSize = this.getBoxSize() / 1.5 for (i = 0; i < nBoxes; i++) { g.append('rect') .attr('width', this.getBoxSize()) .attr('height', this.getBoxSize()) .attr('transform', 'translate(' + 0 + ' ' + i * this.getBoxSize() + ')') .attr('style', 'stroke:black;fill:white;') } g.append('rect') .attr('width', enabledSize) .attr('height', enabledSize) .attr('transform', 'translate(' + (this.getBoxSize() - enabledSize) / 2 + ' ' + (this.getBoxSize() - enabledSize) / 2 + ')') .attr('style', 'stroke:black;fill:black;') }, getW: function() { return this.getBoxSize() }, getH: function() { return this.getBoxSize() * this.getNBoxes() }, getBoxSize: function() { return 20 }, getNBoxes: function() { return this.node.args[2] }, getText: function() { return '' } }) var VuRenderer = function() { ObjectRenderer.prototype.constructor.apply(this, arguments) } _.extend(VuRenderer.prototype, ObjectRenderer.prototype, { renderBox: function(g) { g.append('rect') .attr('class', 'box') .attr('width', this.getW()) .attr('height', this.getH()) .attr('style', 'stroke:black;fill:grey;') }, getText: function() { return '' }, getW: function() { return 20 }, getH: function() { return 200 } }) var TextRenderer = function() { NodeRenderer.prototype.constructor.apply(this, arguments) } _.extend(TextRenderer.prototype, NodeRenderer.prototype, { render: function(g) { g.append('text') .attr('class', 'comment') .text(this.node.args[0]) .attr('dy', this.getH()/2 + this.opts.glyphHeight/2) }, getW: function() { return this.node.args[0].length * this.opts.glyphWidth + this.opts.textPadding * 2 }, getH: function() { return this.opts.objMinHeight } }) }).call(this,"/lib") },{"./Patch":2,"d3":8,"fs":5,"path":6,"underscore":11}],5:[function(require,module,exports){ },{}],6:[function(require,module,exports){ (function (process){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. // resolves . and .. elements in a path array with directory names there // must be no slashes, empty elements, or device names (c:\) in the array // (so also no leading and trailing slashes - it does not distinguish // relative and absolute paths) function normalizeArray(parts, allowAboveRoot) { // if the path tries to go above the root, `up` ends up > 0 var up = 0; for (var i = parts.length - 1; i >= 0; i--) { var last = parts[i]; if (last === '.') { parts.splice(i, 1); } else if (last === '..') { parts.splice(i, 1); up++; } else if (up) { parts.splice(i, 1); up--; } } // if the path is allowed to go above the root, restore leading ..s if (allowAboveRoot) { for (; up--; up) { parts.unshift('..'); } } return parts; } // Split a filename into [root, dir, basename, ext], unix version // 'root' is just a slash, or nothing. var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; var splitPath = function(filename) { return splitPathRe.exec(filename).slice(1); }; // path.resolve([from ...], to) // posix version exports.resolve = function() { var resolvedPath = '', resolvedAbsolute = false; for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { var path = (i >= 0) ? arguments[i] : process.cwd(); // Skip empty and invalid entries if (typeof path !== 'string') { throw new TypeError('Arguments to path.resolve must be strings'); } else if (!path) { continue; } resolvedPath = path + '/' + resolvedPath; resolvedAbsolute = path.charAt(0) === '/'; } // At this point the path should be resolved to a full absolute path, but // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { return !!p; }), !resolvedAbsolute).join('/'); return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; }; // path.normalize(path) // posix version exports.normalize = function(path) { var isAbsolute = exports.isAbsolute(path), trailingSlash = substr(path, -1) === '/'; // Normalize the path path = normalizeArray(filter(path.split('/'), function(p) { return !!p; }), !isAbsolute).join('/'); if (!path && !isAbsolute) { path = '.'; } if (path && trailingSlash) { path += '/'; } return (isAbsolute ? '/' : '') + path; }; // posix version exports.isAbsolute = function(path) { return path.charAt(0) === '/'; }; // posix version exports.join = function() { var paths = Array.prototype.slice.call(arguments, 0); return exports.normalize(filter(paths, function(p, index) { if (typeof p !== 'string') { throw new TypeError('Arguments to path.join must be strings'); } return p; }).join('/')); }; // path.relative(from, to) // posix version exports.relative = function(from, to) { from = exports.resolve(from).substr(1); to = exports.resolve(to).substr(1); function trim(arr) { var start = 0; for (; start < arr.length; start++) { if (arr[start] !== '') break; } var end = arr.length - 1; for (; end >= 0; end--) { if (arr[end] !== '') break; } if (start > end) return []; return arr.slice(start, end - start + 1); } var fromParts = trim(from.split('/')); var toParts = trim(to.split('/')); var length = Math.min(fromParts.length, toParts.length); var samePartsLength = length; for (var i = 0; i < length; i++) { if (fromParts[i] !== toParts[i]) { samePartsLength = i; break; } } var outputParts = []; for (var i = samePartsLength; i < fromParts.length; i++) { outputParts.push('..'); } outputParts = outputParts.concat(toParts.slice(samePartsLength)); return outputParts.join('/'); }; exports.sep = '/'; exports.delimiter = ':'; exports.dirname = function(path) { var result = splitPath(path), root = result[0], dir = result[1]; if (!root && !dir) { // No dirname whatsoever return '.'; } if (dir) { // It has a dirname, strip trailing slash dir = dir.substr(0, dir.length - 1); } return root + dir; }; exports.basename = function(path, ext) { var f = splitPath(path)[2]; // TODO: make this comparison case-insensitive on windows? if (ext && f.substr(-1 * ext.length) === ext) { f = f.substr(0, f.length - ext.length); } return f; }; exports.extname = function(path) { return splitPath(path)[3]; }; function filter (xs, f) { if (xs.filter) return xs.filter(f); var res = []; for (var i = 0; i < xs.length; i++) { if (f(xs[i], i, xs)) res.push(xs[i]); } return res; } // String.prototype.substr - negative index don't work in IE8 var substr = 'ab'.substr(-1) === 'b' ? function (str, start, len) { return str.substr(start, len) } : function (str, start, len) { if (start < 0) start = str.length + start; return str.substr(start, len); } ; }).call(this,require('_process')) },{"_process":7}],7:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; var queue = []; var draining = false; function drainQueue() { if (draining) { return; } draining = true; var currentQueue; var len = queue.length; while(len) { currentQueue = queue; queue = []; var i = -1; while (++i < len) { currentQueue[i](); } len = queue.length; } draining = false; } process.nextTick = function (fun) { queue.push(fun); if (!draining) { setTimeout(drainQueue, 0); } }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); }; // TODO(shtylman) process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}],8:[function(require,module,exports){ !function() { var d3 = { version: "3.5.3" }; if (!Date.now) Date.now = function() { return +new Date(); }; var d3_arraySlice = [].slice, d3_array = function(list) { return d3_arraySlice.call(list); }; var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window; try { d3_array(d3_documentElement.childNodes)[0].nodeType; } catch (e) { d3_array = function(list) { var i = list.length, array = new Array(i); while (i--) array[i] = list[i]; return array; }; } try { d3_document.createElement("div").style.setProperty("opacity", 0, ""); } catch (error) { var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; d3_element_prototype.setAttribute = function(name, value) { d3_element_setAttribute.call(this, name, value + ""); }; d3_element_prototype.setAttributeNS = function(space, local, value) { d3_element_setAttributeNS.call(this, space, local, value + ""); }; d3_style_prototype.setProperty = function(name, value, priority) { d3_style_setProperty.call(this, name, value + "", priority); }; } d3.ascending = d3_ascending; function d3_ascending(a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } d3.descending = function(a, b) { return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; }; d3.min = function(array, f) { var i = -1, n = array.length, a, b; if (arguments.length === 1) { while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; } while (++i < n) if ((b = array[i]) != null && a > b) a = b; } else { while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { a = b; break; } while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; } return a; }; d3.max = function(array, f) { var i = -1, n = array.length, a, b; if (arguments.length === 1) { while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; } while (++i < n) if ((b = array[i]) != null && b > a) a = b; } else { while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { a = b; break; } while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; } return a; }; d3.extent = function(array, f) { var i = -1, n = array.length, a, b, c; if (arguments.length === 1) { while (++i < n) if ((b = array[i]) != null && b >= b) { a = c = b; break; } while (++i < n) if ((b = array[i]) != null) { if (a > b) a = b; if (c < b) c = b; } } else { while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) { a = c = b; break; } while (++i < n) if ((b = f.call(array, array[i], i)) != null) { if (a > b) a = b; if (c < b) c = b; } } return [ a, c ]; }; function d3_number(x) { return x === null ? NaN : +x; } function d3_numeric(x) { return !isNaN(x); } d3.sum = function(array, f) { var s = 0, n = array.length, a, i = -1; if (arguments.length === 1) { while (++i < n) if (d3_numeric(a = +array[i])) s += a; } else { while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a; } return s; }; d3.mean = function(array, f) { var s = 0, n = array.length, a, i = -1, j = n; if (arguments.length === 1) { while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j; } else { while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j; } if (j) return s / j; }; d3.quantile = function(values, p) { var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; return e ? v + e * (values[h] - v) : v; }; d3.median = function(array, f) { var numbers = [], n = array.length, a, i = -1; if (arguments.length === 1) { while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a); } else { while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a); } if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5); }; d3.variance = function(array, f) { var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0; if (arguments.length === 1) { while (++i < n) { if (d3_numeric(a = d3_number(array[i]))) { d = a - m; m += d / ++j; s += d * (a - m); } } } else { while (++i < n) { if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) { d = a - m; m += d / ++j; s += d * (a - m); } } } if (j > 1) return s / (j - 1); }; d3.deviation = function() { var v = d3.variance.apply(this, arguments); return v ? Math.sqrt(v) : v; }; function d3_bisector(compare) { return { left: function(a, x, lo, hi) { if (arguments.length < 3) lo = 0; if (arguments.length < 4) hi = a.length; while (lo < hi) { var mid = lo + hi >>> 1; if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; } return lo; }, right: function(a, x, lo, hi) { if (arguments.length < 3) lo = 0; if (arguments.length < 4) hi = a.length; while (lo < hi) { var mid = lo + hi >>> 1; if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; } return lo; } }; } var d3_bisect = d3_bisector(d3_ascending); d3.bisectLeft = d3_bisect.left; d3.bisect = d3.bisectRight = d3_bisect.right; d3.bisector = function(f) { return d3_bisector(f.length === 1 ? function(d, x) { return d3_ascending(f(d), x); } : f); }; d3.shuffle = function(array, i0, i1) { if ((m = arguments.length) < 3) { i1 = array.length; if (m < 2) i0 = 0; } var m = i1 - i0, t, i; while (m) { i = Math.random() * m-- | 0; t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t; } return array; }; d3.permute = function(array, indexes) { var i = indexes.length, permutes = new Array(i); while (i--) permutes[i] = array[indexes[i]]; return permutes; }; d3.pairs = function(array) { var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; return pairs; }; d3.zip = function() { if (!(n = arguments.length)) return []; for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { zip[j] = arguments[j][i]; } } return zips; }; function d3_zipLength(d) { return d.length; } d3.transpose = function(matrix) { return d3.zip.apply(d3, matrix); }; d3.keys = function(map) { var keys = []; for (var key in map) keys.push(key); return keys; }; d3.values = function(map) { var values = []; for (var key in map) values.push(map[key]); return values; }; d3.entries = function(map) { var entries = []; for (var key in map) entries.push({ key: key, value: map[key] }); return entries; }; d3.merge = function(arrays) { var n = arrays.length, m, i = -1, j = 0, merged, array; while (++i < n) j += arrays[i].length; merged = new Array(j); while (--n >= 0) { array = arrays[n]; m = array.length; while (--m >= 0) { merged[--j] = array[m]; } } return merged; }; var abs = Math.abs; d3.range = function(start, stop, step) { if (arguments.length < 3) { step = 1; if (arguments.length < 2) { stop = start; start = 0; } } if ((stop - start) / step === Infinity) throw new Error("infinite range"); var range = [], k = d3_range_integerScale(abs(step)), i = -1, j; start *= k, stop *= k, step *= k; if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); return range; }; function d3_range_integerScale(x) { var k = 1; while (x * k % 1) k *= 10; return k; } function d3_class(ctor, properties) { for (var key in properties) { Object.defineProperty(ctor.prototype, key, { value: properties[key], enumerable: false }); } } d3.map = function(object, f) { var map = new d3_Map(); if (object instanceof d3_Map) { object.forEach(function(key, value) { map.set(key, value); }); } else if (Array.isArray(object)) { var i = -1, n = object.length, o; if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o); } else { for (var key in object) map.set(key, object[key]); } return map; }; function d3_Map() { this._ = Object.create(null); } var d3_map_proto = "__proto__", d3_map_zero = "\x00"; d3_class(d3_Map, { has: d3_map_has, get: function(key) { return this._[d3_map_escape(key)]; }, set: function(key, value) { return this._[d3_map_escape(key)] = value; }, remove: d3_map_remove, keys: d3_map_keys, values: function() { var values = []; for (var key in this._) values.push(this._[key]); return values; }, entries: function() { var entries = []; for (var key in this._) entries.push({ key: d3_map_unescape(key), value: this._[key] }); return entries; }, size: d3_map_size, empty: d3_map_empty, forEach: function(f) { for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]); } }); function d3_map_escape(key) { return (key += "") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key; } function d3_map_unescape(key) { return (key += "")[0] === d3_map_zero ? key.slice(1) : key; } function d3_map_has(key) { return d3_map_escape(key) in this._; } function d3_map_remove(key) { return (key = d3_map_escape(key)) in this._ && delete this._[key]; } function d3_map_keys() { var keys = []; for (var key in this._) keys.push(d3_map_unescape(key)); return keys; } function d3_map_size() { var size = 0; for (var key in this._) ++size; return size; } function d3_map_empty() { for (var key in this._) return false; return true; } d3.nest = function() { var nest = {}, keys = [], sortKeys = [], sortValues, rollup; function map(mapType, array, depth) { if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; while (++i < n) { if (values = valuesByKey.get(keyValue = key(object = array[i]))) { values.push(object); } else { valuesByKey.set(keyValue, [ object ]); } } if (mapType) { object = mapType(); setter = function(keyValue, values) { object.set(keyValue, map(mapType, values, depth)); }; } else { object = {}; setter = function(keyValue, values) { object[keyValue] = map(mapType, values, depth); }; } valuesByKey.forEach(setter); return object; } function entries(map, depth) { if (depth >= keys.length) return map; var array = [], sortKey = sortKeys[depth++]; map.forEach(function(key, keyMap) { array.push({ key: key, values: entries(keyMap, depth) }); }); return sortKey ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array; } nest.map = function(array, mapType) { return map(mapType, array, 0); }; nest.entries = function(array) { return entries(map(d3.map, array, 0), 0); }; nest.key = function(d) { keys.push(d); return nest; }; nest.sortKeys = function(order) { sortKeys[keys.length - 1] = order; return nest; }; nest.sortValues = function(order) { sortValues = order; return nest; }; nest.rollup = function(f) { rollup = f; return nest; }; return nest; }; d3.set = function(array) { var set = new d3_Set(); if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); return set; }; function d3_Set() { this._ = Object.create(null); } d3_class(d3_Set, { has: d3_map_has, add: function(key) { this._[d3_map_escape(key += "")] = true; return key; }, remove: d3_map_remove, values: d3_map_keys, size: d3_map_size, empty: d3_map_empty, forEach: function(f) { for (var key in this._) f.call(this, d3_map_unescape(key)); } }); d3.behavior = {}; d3.rebind = function(target, source) { var i = 1, n = arguments.length, method; while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); return target; }; function d3_rebind(target, source, method) { return function() { var value = method.apply(source, arguments); return value === source ? target : value; }; } function d3_vendorSymbol(object, name) { if (name in object) return name; name = name.charAt(0).toUpperCase() + name.slice(1); for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { var prefixName = d3_vendorPrefixes[i] + name; if (prefixName in object) return prefixName; } } var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; function d3_noop() {} d3.dispatch = function() { var dispatch = new d3_dispatch(), i = -1, n = arguments.length; while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); return dispatch; }; function d3_dispatch() {} d3_dispatch.prototype.on = function(type, listener) { var i = type.indexOf("."), name = ""; if (i >= 0) { name = type.slice(i + 1); type = type.slice(0, i); } if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); if (arguments.length === 2) { if (listener == null) for (type in this) { if (this.hasOwnProperty(type)) this[type].on(name, null); } return this; } }; function d3_dispatch_event(dispatch) { var listeners = [], listenerByName = new d3_Map(); function event() { var z = listeners, i = -1, n = z.length, l; while (++i < n) if (l = z[i].on) l.apply(this, arguments); return dispatch; } event.on = function(name, listener) { var l = listenerByName.get(name), i; if (arguments.length < 2) return l && l.on; if (l) { l.on = null; listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); listenerByName.remove(name); } if (listener) listeners.push(listenerByName.set(name, { on: listener })); return dispatch; }; return event; } d3.event = null; function d3_eventPreventDefault() { d3.event.preventDefault(); } function d3_eventSource() { var e = d3.event, s; while (s = e.sourceEvent) e = s; return e; } function d3_eventDispatch(target) { var dispatch = new d3_dispatch(), i = 0, n = arguments.length; while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); dispatch.of = function(thiz, argumentz) { return function(e1) { try { var e0 = e1.sourceEvent = d3.event; e1.target = target; d3.event = e1; dispatch[e1.type].apply(thiz, argumentz); } finally { d3.event = e0; } }; }; return dispatch; } d3.requote = func