├── .ackrc ├── .gitattributes ├── LICENSE ├── README.md ├── bower_components ├── d3 │ ├── .bower.json │ ├── LICENSE │ ├── README.md │ ├── bower.json │ ├── d3.js │ └── d3.min.js ├── dagre-d3 │ ├── .bower.json │ ├── LICENSE │ ├── bower.json │ ├── demo │ │ ├── arrows.html │ │ ├── clusters.html │ │ ├── demo.css │ │ ├── demo.js │ │ ├── dom.html │ │ ├── etl-status.html │ │ ├── graph-story-board.html │ │ ├── hover.html │ │ ├── interactive-demo.html │ │ ├── sentence-tokenization.html │ │ ├── shapes.html │ │ ├── style-attrs.html │ │ ├── svg-labels.html │ │ ├── tcp-state-diagram.html │ │ ├── tipsy.css │ │ ├── tipsy.js │ │ └── user-defined.html │ ├── dist │ │ ├── dagre-d3.core.js │ │ ├── dagre-d3.core.min.js │ │ └── dagre-d3.core.min.js.map │ └── gulpfile.js ├── dagre │ ├── .bower.json │ ├── LICENSE │ ├── bower.json │ └── dist │ │ ├── dagre.core.js │ │ └── dagre.core.min.js ├── graphlib │ ├── .bower.json │ ├── LICENSE │ ├── bower.json │ └── dist │ │ ├── graphlib.core.js │ │ └── graphlib.core.min.js └── lodash │ ├── .bower.json │ ├── LICENSE │ ├── bower.json │ ├── lodash.js │ └── lodash.min.js ├── bulk.jsx ├── calc.css ├── calc.jsx ├── calc.lua ├── calculator.js ├── data ├── core-0-10-2.lua ├── core-0-11-3.lua ├── core-0-12-33.lua ├── core-0-13-15.lua ├── core-0-13-20.lua ├── core-0-14-20.lua ├── core-0-14-22.lua ├── core-0-15-2.lua ├── core-0-15-9.lua ├── core-0-16-51.lua └── core-0-9-8.lua ├── dataloader.lua ├── datasource.jsx ├── explain.jsx ├── ffi.js ├── ffi.lua ├── graph.jsx ├── index.html ├── ingredients.jsx ├── input.jsx ├── lua.vm.js ├── options.jsx └── serve-github-pages.rb /.ackrc: -------------------------------------------------------------------------------- 1 | --ignore-file=is:lua.vm.js 2 | --ignore-dir=bower_components 3 | --ignore-dir=data 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Don't show diffs for lua.vm.js, we're not going to read them anyway. 2 | # https://www.git-scm.com/docs/gitattributes#_defining_macro_attributes 3 | /lua.vm.js binary 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | # factorio-calc 2 | 3 | The MIT License (MIT) 4 | 5 | Copyright (c) 2014 Ruy Asan 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | 25 | # lua.vm.js 26 | 27 | The MIT License (MIT) 28 | 29 | Copyright (c) 2013 Alon Zakai (kripken) 30 | Copyright (c) 2014-2016 Daurnimator 31 | 32 | Permission is hereby granted, free of charge, to any person obtaining a copy of 33 | this software and associated documentation files (the "Software"), to deal in 34 | the Software without restriction, including without limitation the rights to 35 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 36 | the Software, and to permit persons to whom the Software is furnished to do so, 37 | subject to the following conditions: 38 | 39 | The above copyright notice and this permission notice shall be included in all 40 | copies or substantial portions of the Software. 41 | 42 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 43 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 44 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 45 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 46 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 47 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | factorio-calc 2 | ============= 3 | 4 | For all your obsessive optimizing needs 5 | 6 | # Contribute a data source # 7 | 8 | Additional data sources are welcome - the calculator should work just fine with mods! 9 | 10 | - Fork this repository 11 | - Add a file containing the recipe dumps to the `data` folder: 12 | + Choose a short descriptive name without any periods (dashes are ok) 13 | + Concentrate all recipe files into one 14 | + e.g. `cat factorio/data/base/prototypes/recipe/*.lua > factorio-calc/data/core-2-0-0.lua` 15 | - Open up `index.html` and add the data source name (in the above example `core-2-0-0`) to the `DATALIBS` array near the top. 16 | - Send me a pull request form your branch, and that's it! 17 | 18 | 19 | ## See Also ## 20 | 21 | [Forum Thread](http://www.factorioforums.com/forum/viewtopic.php?f=5&t=4553) -------------------------------------------------------------------------------- /bower_components/d3/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d3", 3 | "description": "A JavaScript visualization library for HTML and SVG.", 4 | "main": "d3.js", 5 | "license": "BSD-3-Clause", 6 | "ignore": [], 7 | "homepage": "https://github.com/mbostock-bower/d3-bower", 8 | "version": "3.5.16", 9 | "_release": "3.5.16", 10 | "_resolution": { 11 | "type": "version", 12 | "tag": "v3.5.16", 13 | "commit": "f541593777ebe842059fda09d3ce1b6de8b29a7d" 14 | }, 15 | "_source": "git://github.com/mbostock-bower/d3-bower.git", 16 | "_target": "^3.3.8", 17 | "_originalSource": "d3" 18 | } -------------------------------------------------------------------------------- /bower_components/d3/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2016, Michael Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * The name Michael Bostock may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, 21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 24 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /bower_components/d3/README.md: -------------------------------------------------------------------------------- 1 | # Data-Driven Documents 2 | 3 | 4 | 5 | **D3.js** is a JavaScript library for manipulating documents based on data. **D3** helps you bring data to life using HTML, SVG, and CSS. **D3** emphasizes web standards and combines powerful visualization components with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers without tying yourself to a proprietary framework. 6 | 7 | Want to learn more? [See the wiki.](https://github.com/mbostock/d3/wiki) 8 | 9 | For examples, [see the gallery](https://github.com/mbostock/d3/wiki/Gallery) and [mbostock’s bl.ocks](http://bl.ocks.org/mbostock). 10 | -------------------------------------------------------------------------------- /bower_components/d3/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d3", 3 | "description": "A JavaScript visualization library for HTML and SVG.", 4 | "main": "d3.js", 5 | "license": "BSD-3-Clause", 6 | "ignore": [] 7 | } 8 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dagre-d3", 3 | "version": "0.4.17", 4 | "main": [ 5 | "dist/dagre-d3.core.js" 6 | ], 7 | "ignore": [ 8 | ".*", 9 | "README.md", 10 | "CHANGELOG.md", 11 | "Makefile", 12 | "browser.js", 13 | "build/**", 14 | "dist/dagre-d3.js", 15 | "dist/dagre-d3.min.js", 16 | "dist/dagre-d3.min.js.map", 17 | "dist/demo/**", 18 | "index.js", 19 | "karma*", 20 | "lib/**", 21 | "package.json", 22 | "src/**", 23 | "test/**" 24 | ], 25 | "dependencies": { 26 | "d3": "^3.3.8", 27 | "dagre": "^0.7.3", 28 | "graphlib": "^1.0.5", 29 | "lodash": "^3.10.0" 30 | }, 31 | "homepage": "https://github.com/cpettitt/dagre-d3", 32 | "_release": "0.4.17", 33 | "_resolution": { 34 | "type": "version", 35 | "tag": "v0.4.17", 36 | "commit": "88bea485d5556382c1c50f7012d9ebd2ec5c270f" 37 | }, 38 | "_source": "git://github.com/cpettitt/dagre-d3.git", 39 | "_target": "~0.4.3", 40 | "_originalSource": "dagre-d3" 41 | } -------------------------------------------------------------------------------- /bower_components/dagre-d3/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Chris Pettitt 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dagre-d3", 3 | "version": "0.4.17", 4 | "main": [ 5 | "dist/dagre-d3.core.js" 6 | ], 7 | "ignore": [ 8 | ".*", 9 | "README.md", 10 | "CHANGELOG.md", 11 | "Makefile", 12 | "browser.js", 13 | "build/**", 14 | "dist/dagre-d3.js", 15 | "dist/dagre-d3.min.js", 16 | "dist/dagre-d3.min.js.map", 17 | "dist/demo/**", 18 | "index.js", 19 | "karma*", 20 | "lib/**", 21 | "package.json", 22 | "src/**", 23 | "test/**" 24 | ], 25 | "dependencies": { 26 | "d3": "^3.3.8", 27 | "dagre": "^0.7.3", 28 | "graphlib": "^1.0.5", 29 | "lodash": "^3.10.0" 30 | } 31 | } -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/arrows.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Demo: Arrows 5 | 6 | 7 | 8 | 9 | 10 | 29 | 30 |

Dagre D3 Demo: Arrows

31 | 32 | 33 | 34 |
35 |

A sample that shows the different arrows available in dagre-d3. 36 |

37 | 38 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/clusters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Demo: Clusters 5 | 6 | 7 | 8 | 9 | 10 |

Dagre D3 Demo: Clusters

11 | 12 | 36 | 37 | 38 | 39 |
40 |

An example of visualizing clusters. This example shows 41 | how clusters can be applied to a rendered graph. 42 |

43 | 44 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | width: 960px; 3 | margin: 0 auto; 4 | color: #333; 5 | font-weight: 300; 6 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serf; 7 | } 8 | 9 | h1 { 10 | font-size: 3em; 11 | font-weight: 300; 12 | } 13 | 14 | h2 { 15 | font-size: 1.5em; 16 | font-weight: 300; 17 | } 18 | 19 | section { 20 | margin-bottom: 3em; 21 | } 22 | 23 | section p { 24 | text-align: justify; 25 | } 26 | 27 | svg { 28 | border: 1px solid #ccc; 29 | overflow: hidden; 30 | margin: 0 auto; 31 | } 32 | 33 | pre { 34 | border: 1px solid #ccc; 35 | } 36 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/demo.js: -------------------------------------------------------------------------------- 1 | var bodyElem = d3.select('body'), 2 | jsElem = d3.select('#js'), 3 | jsPanel = bodyElem.append('div').attr('id', 'jsPanel'); 4 | cssElem = d3.select('#css'), 5 | cssPanel = bodyElem.append('div').attr('id', 'cssPanel'); 6 | 7 | function setupPanel(panel, elem, title) { 8 | panel.append('h2').text(title); 9 | return panel.append('pre').append('code').text(elem.html().trim()); 10 | } 11 | 12 | var jsCode = setupPanel(jsPanel, jsElem, 'JavaScript'); 13 | var cssCode = setupPanel(cssPanel, cssElem, 'CSS'); 14 | 15 | var hljsRoot = 'http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1'; 16 | 17 | bodyElem.append('link') 18 | .attr('rel', 'stylesheet') 19 | .attr('href', hljsRoot + '/styles/xcode.min.css'); 20 | bodyElem.append('script') 21 | .attr('src', hljsRoot + '/highlight.min.js') 22 | .on('load', function() { 23 | hljs.highlightBlock(jsCode.node()); 24 | hljs.highlightBlock(cssCode.node()); 25 | }); 26 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/dom.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Demo: DOM Example 5 | 6 | 7 | 8 | 9 | 10 |

Dagre D3 Demo: DOM Example

11 | 12 | 54 | 55 | 56 | 57 |
58 |

A sample showing how to use DOM nodes in a graph. Note that IE does not 59 | support this technique. 60 |

61 | 62 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/etl-status.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Renderer Demo 5 | 6 | 7 | 8 | 9 | 150 | 151 | 152 |
153 | 154 |
155 | 156 | 285 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/graph-story-board.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Graph Storyboard. Add and Prune Dependencies Algorithm 5 | 6 | 7 | 8 | 9 | 58 | 59 | 87 | 88 | 207 | 208 |
209 |
210 |

WBS

211 | 212 |
213 | 214 |
215 |

Sequencing

216 | 217 |
218 |
219 | 220 |
221 |

Coherent Schedule Network

222 | 223 |
224 | 225 | 423 | 424 | 425 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/hover.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Demo: Tooltip on Hover 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

Dagre D3 Demo: Tooltip on Hover

16 | 17 | 52 | 53 | 54 | 55 |
56 |

The TCP state diagram 57 | (source: RFC 793) with 58 | hover support. Uses tipsy JS and CSS 59 | for the tooltip. 60 |

61 | 62 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/interactive-demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre Interactive Demo 5 | 6 | 7 | 8 | 9 | 10 | 41 | 42 | 60 | 61 | 62 | 63 |

Dagre Interactive Demo

64 | 65 |

Input

66 | 67 |
68 | 69 | 86 | 87 | Link for this graph 88 |
89 | 90 |

Graph Visualization

91 | 92 | 93 | 94 | 95 | 96 | 174 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/sentence-tokenization.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Demo: Sentence Tokenization 5 | 6 | 7 | 8 | 9 | 10 |

Dagre D3 Demo: Sentence Tokenization

11 | 12 | 35 | 36 | 37 | 38 |
39 |

An example of visualizing the tokenization of a sentence. This example shows 40 | how CSS classes can be applied to a rendered graph. 41 |

42 | 43 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/shapes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Demo: Shapes 5 | 6 | 7 | 8 | 9 | 10 | 30 | 31 |

Dagre D3 Demo: Shapes

32 | 33 | 34 | 35 |
36 |

A sample that shows the different node shapes available in dagre-d3. 37 |

38 | 39 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/style-attrs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Demo: Style Attributes 5 | 6 | 7 | 8 | 9 | 10 |

Dagre D3 Demo: Style Attributes

11 | 12 | 38 | 39 | 40 | 41 |
42 |

An example showing how styles that are set in the input graph can be applied 43 | to nodes, node labels, edges, and edge labels in the rendered graph. 44 |

45 | 46 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/svg-labels.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Demo: SVG Labels 5 | 6 | 7 | 8 | 9 | 10 |

Dagre D3 Demo: SVG Labels

11 | 12 | 30 | 31 | 32 | 33 |
34 |

An example of adding SVG labels. This allows the user to add any svg 35 | elements to the label. This allows for links to works in IE.

36 |
37 | 38 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/tcp-state-diagram.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Demo: TCP State Diagram 5 | 6 | 7 | 8 | 9 | 10 | 26 | 27 |

Dagre D3 Demo: TCP State Diagram

28 | 29 | 30 | 31 |
32 |

A sample rendering of a TCP state diagram 33 | (RFC 793). This example 34 | shows how to set custom styles in the input graph and how to set a custom 35 | initial zoom. 36 |

37 | 38 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/tipsy.css: -------------------------------------------------------------------------------- 1 | .tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; } 2 | .tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; } 3 | 4 | /* Rounded corners */ 5 | .tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; } 6 | 7 | /* Uncomment for shadow */ 8 | .tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; } 9 | 10 | .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; } 11 | 12 | /* Rules to colour arrows */ 13 | .tipsy-arrow-n { border-bottom-color: #000; } 14 | .tipsy-arrow-s { border-top-color: #000; } 15 | .tipsy-arrow-e { border-left-color: #000; } 16 | .tipsy-arrow-w { border-right-color: #000; } 17 | 18 | .tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } 19 | .tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} 20 | .tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} 21 | .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } 22 | .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } 23 | .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } 24 | .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } 25 | .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } 26 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/tipsy.js: -------------------------------------------------------------------------------- 1 | // tipsy, facebook style tooltips for jquery 2 | // version 1.0.0a 3 | // (c) 2008-2010 jason frame [jason@onehackoranother.com] 4 | // released under the MIT license 5 | 6 | (function($) { 7 | 8 | function maybeCall(thing, ctx) { 9 | return (typeof thing == 'function') ? (thing.call(ctx)) : thing; 10 | } 11 | 12 | function Tipsy(element, options) { 13 | this.$element = $(element); 14 | this.options = options; 15 | this.enabled = true; 16 | this.fixTitle(); 17 | } 18 | 19 | Tipsy.prototype = { 20 | show: function() { 21 | var title = this.getTitle(); 22 | if (title && this.enabled) { 23 | var $tip = this.tip(); 24 | 25 | $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); 26 | $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity 27 | $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body); 28 | 29 | var pos = $.extend({}, this.$element.offset(), { 30 | width: this.$element[0].offsetWidth || 0, 31 | height: this.$element[0].offsetHeight || 0 32 | }); 33 | 34 | if (typeof this.$element[0].nearestViewportElement == 'object') { 35 | // SVG 36 | var el = this.$element[0]; 37 | var rect = el.getBoundingClientRect(); 38 | pos.width = rect.width; 39 | pos.height = rect.height; 40 | } 41 | 42 | 43 | var actualWidth = $tip[0].offsetWidth, 44 | actualHeight = $tip[0].offsetHeight, 45 | gravity = maybeCall(this.options.gravity, this.$element[0]); 46 | 47 | var tp; 48 | switch (gravity.charAt(0)) { 49 | case 'n': 50 | tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; 51 | break; 52 | case 's': 53 | tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; 54 | break; 55 | case 'e': 56 | tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}; 57 | break; 58 | case 'w': 59 | tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}; 60 | break; 61 | } 62 | 63 | if (gravity.length == 2) { 64 | if (gravity.charAt(1) == 'w') { 65 | tp.left = pos.left + pos.width / 2 - 15; 66 | } else { 67 | tp.left = pos.left + pos.width / 2 - actualWidth + 15; 68 | } 69 | } 70 | 71 | $tip.css(tp).addClass('tipsy-' + gravity); 72 | $tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0); 73 | if (this.options.className) { 74 | $tip.addClass(maybeCall(this.options.className, this.$element[0])); 75 | } 76 | 77 | if (this.options.fade) { 78 | $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}); 79 | } else { 80 | $tip.css({visibility: 'visible', opacity: this.options.opacity}); 81 | } 82 | 83 | var t = this; 84 | var set_hovered = function(set_hover){ 85 | return function(){ 86 | t.$tip.stop(); 87 | t.tipHovered = set_hover; 88 | if (!set_hover){ 89 | if (t.options.delayOut === 0) { 90 | t.hide(); 91 | } else { 92 | setTimeout(function() { 93 | if (t.hoverState == 'out') t.hide(); }, t.options.delayOut); 94 | } 95 | } 96 | }; 97 | }; 98 | $tip.hover(set_hovered(true), set_hovered(false)); 99 | } 100 | }, 101 | 102 | hide: function() { 103 | if (this.options.fade) { 104 | this.tip().stop().fadeOut(function() { $(this).remove(); }); 105 | } else { 106 | this.tip().remove(); 107 | } 108 | }, 109 | 110 | fixTitle: function() { 111 | var $e = this.$element; 112 | 113 | if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') { 114 | $e.attr('original-title', $e.attr('title') || '').removeAttr('title'); 115 | } 116 | if (typeof $e.context.nearestViewportElement == 'object'){ 117 | if ($e.children('title').length){ 118 | $e.append('' + ($e.children('title').text() || '') + '') 119 | .children('title').remove(); 120 | } 121 | } 122 | }, 123 | 124 | getTitle: function() { 125 | 126 | var title, $e = this.$element, o = this.options; 127 | this.fixTitle(); 128 | 129 | if (typeof o.title == 'string') { 130 | var title_name = o.title == 'title' ? 'original-title' : o.title; 131 | if ($e.children(title_name).length){ 132 | title = $e.children(title_name).html(); 133 | } else{ 134 | title = $e.attr(title_name); 135 | } 136 | 137 | } else if (typeof o.title == 'function') { 138 | title = o.title.call($e[0]); 139 | } 140 | title = ('' + title).replace(/(^\s*|\s*$)/, ""); 141 | return title || o.fallback; 142 | }, 143 | 144 | tip: function() { 145 | if (!this.$tip) { 146 | this.$tip = $('
').html('
'); 147 | } 148 | return this.$tip; 149 | }, 150 | 151 | validate: function() { 152 | if (!this.$element[0].parentNode) { 153 | this.hide(); 154 | this.$element = null; 155 | this.options = null; 156 | } 157 | }, 158 | 159 | enable: function() { this.enabled = true; }, 160 | disable: function() { this.enabled = false; }, 161 | toggleEnabled: function() { this.enabled = !this.enabled; } 162 | }; 163 | 164 | $.fn.tipsy = function(options) { 165 | 166 | if (options === true) { 167 | return this.data('tipsy'); 168 | } else if (typeof options == 'string') { 169 | var tipsy = this.data('tipsy'); 170 | if (tipsy) tipsy[options](); 171 | return this; 172 | } 173 | 174 | options = $.extend({}, $.fn.tipsy.defaults, options); 175 | 176 | if (options.hoverlock && options.delayOut === 0) { 177 | options.delayOut = 100; 178 | } 179 | 180 | function get(ele) { 181 | var tipsy = $.data(ele, 'tipsy'); 182 | if (!tipsy) { 183 | tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options)); 184 | $.data(ele, 'tipsy', tipsy); 185 | } 186 | return tipsy; 187 | } 188 | 189 | function enter() { 190 | var tipsy = get(this); 191 | tipsy.hoverState = 'in'; 192 | if (options.delayIn === 0) { 193 | tipsy.show(); 194 | } else { 195 | tipsy.fixTitle(); 196 | setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn); 197 | } 198 | } 199 | 200 | function leave() { 201 | var tipsy = get(this); 202 | tipsy.hoverState = 'out'; 203 | if (options.delayOut === 0) { 204 | tipsy.hide(); 205 | } else { 206 | var to = function() { 207 | if (!tipsy.tipHovered || !options.hoverlock){ 208 | if (tipsy.hoverState == 'out') tipsy.hide(); 209 | } 210 | }; 211 | setTimeout(to, options.delayOut); 212 | } 213 | } 214 | 215 | if (options.trigger != 'manual') { 216 | var binder = options.live ? 'live' : 'bind', 217 | eventIn = options.trigger == 'hover' ? 'mouseenter' : 'focus', 218 | eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur'; 219 | this[binder](eventIn, enter)[binder](eventOut, leave); 220 | } 221 | 222 | return this; 223 | 224 | }; 225 | 226 | $.fn.tipsy.defaults = { 227 | className: null, 228 | delayIn: 0, 229 | delayOut: 0, 230 | fade: false, 231 | fallback: '', 232 | gravity: 'n', 233 | html: false, 234 | live: false, 235 | offset: 0, 236 | opacity: 0.8, 237 | title: 'title', 238 | trigger: 'hover', 239 | hoverlock: false 240 | }; 241 | 242 | // Overwrite this method to provide options on a per-element basis. 243 | // For example, you could store the gravity in a 'tipsy-gravity' attribute: 244 | // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' }); 245 | // (remember - do not modify 'options' in place!) 246 | $.fn.tipsy.elementOptions = function(ele, options) { 247 | return $.metadata ? $.extend({}, options, $(ele).metadata()) : options; 248 | }; 249 | 250 | $.fn.tipsy.autoNS = function() { 251 | return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n'; 252 | }; 253 | 254 | $.fn.tipsy.autoWE = function() { 255 | return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w'; 256 | }; 257 | 258 | /** 259 | * yields a closure of the supplied parameters, producing a function that takes 260 | * no arguments and is suitable for use as an autogravity function like so: 261 | * 262 | * @param margin (int) - distance from the viewable region edge that an 263 | * element should be before setting its tooltip's gravity to be away 264 | * from that edge. 265 | * @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer 266 | * if there are no viewable region edges effecting the tooltip's 267 | * gravity. It will try to vary from this minimally, for example, 268 | * if 'sw' is preferred and an element is near the right viewable 269 | * region edge, but not the top edge, it will set the gravity for 270 | * that element's tooltip to be 'se', preserving the southern 271 | * component. 272 | */ 273 | $.fn.tipsy.autoBounds = function(margin, prefer) { 274 | return function() { 275 | var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)}, 276 | boundTop = $(document).scrollTop() + margin, 277 | boundLeft = $(document).scrollLeft() + margin, 278 | $this = $(this); 279 | 280 | if ($this.offset().top < boundTop) dir.ns = 'n'; 281 | if ($this.offset().left < boundLeft) dir.ew = 'w'; 282 | if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e'; 283 | if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's'; 284 | 285 | return dir.ns + (dir.ew ? dir.ew : ''); 286 | }; 287 | }; 288 | })(jQuery); -------------------------------------------------------------------------------- /bower_components/dagre-d3/demo/user-defined.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dagre D3 Demo: User-defined Shapes and Arrows 5 | 6 | 7 | 8 | 9 | 10 | 30 | 31 |

Dagre D3 Demo: User-defined Shapes and Arrows

32 | 33 | 34 | 35 |
36 |

An example that shows how to create and use user-defined shapes and arrows. 37 |

38 | 39 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /bower_components/dagre-d3/dist/dagre-d3.core.min.js: -------------------------------------------------------------------------------- 1 | !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.dagreD3=t()}}(function(){return function t(e,r,n){function a(l,s){if(!r[l]){if(!e[l]){var o="function"==typeof require&&require;if(!s&&o)return o(l,!0);if(i)return i(l,!0);var d=new Error("Cannot find module '"+l+"'");throw d.code="MODULE_NOT_FOUND",d}var c=r[l]={exports:{}};e[l][0].call(c.exports,function(t){var r=e[l][1][t];return a(r?r:t)},c,c.exports,t,e,r,n)}return r[l].exports}for(var i="function"==typeof require&&require,l=0;lv?(v-y)/g:(v+y)/g,v=l*d-i*c,b=0>v?(v-y)/g:(v+y)/g,{x:x,y:b})}function a(t,e){return t*e>0}e.exports=n},{}],14:[function(t,e,r){function n(t,e){return t.intersect(e)}e.exports=n},{}],15:[function(t,e,r){function n(t,e,r){var n=t.x,i=t.y,l=[],s=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY;e.forEach(function(t){s=Math.min(s,t.x),o=Math.min(o,t.y)});for(var d=n-t.width/2-s,c=i-t.height/2-o,u=0;u1&&l.sort(function(t,e){var n=t.x-r.x,a=t.y-r.y,i=Math.sqrt(n*n+a*a),l=e.x-r.x,s=e.y-r.y,o=Math.sqrt(l*l+s*s);return o>i?-1:i===o?0:1}),l[0]):(console.log("NO INTERSECTION FOUND, RETURN NODE CENTER",t),t)}var a=t("./intersect-line");e.exports=n},{"./intersect-line":13}],16:[function(t,e,r){function n(t,e){var r,n,a=t.x,i=t.y,l=e.x-a,s=e.y-i,o=t.width/2,d=t.height/2;return Math.abs(s)*o>Math.abs(l)*d?(0>s&&(d=-d),r=0===s?0:d*l/s,n=d):(0>l&&(o=-o),r=o,n=0===l?0:o*s/l),{x:a+r,y:i+n}}e.exports=n},{}],17:[function(t,e,r){function n(t,e){var r=t.append("foreignObject").attr("width","100000"),n=r.append("xhtml:div");n.attr("xmlns","http://www.w3.org/1999/xhtml");var i=e.label;switch(typeof i){case"function":n.insert(i);break;case"object":n.insert(function(){return i});break;default:n.html(i)}a.applyStyle(n,e.labelStyle),n.style("display","inline-block"),n.style("white-space","nowrap");var l=n[0][0].getBoundingClientRect();return r.attr("width",l.width).attr("height",l.height),r}var a=t("../util");e.exports=n},{"../util":27}],18:[function(t,e,r){function n(t,e,r){var n=e.label,s=t.append("g");"svg"===e.labelType?l(s,e):"string"!=typeof n||"html"===e.labelType?i(s,e):a(s,e);var o,d=s.node().getBBox();switch(r){case"top":o=-e.height/2;break;case"bottom":o=e.height/2-d.height;break;default:o=-d.height/2}return s.attr("transform","translate("+-d.width/2+","+o+")"),s}var a=t("./add-text-label"),i=t("./add-html-label"),l=t("./add-svg-label");e.exports=n},{"./add-html-label":17,"./add-svg-label":19,"./add-text-label":20}],19:[function(t,e,r){function n(t,e){var r=t;return r.node().appendChild(e.label),a.applyStyle(r,e.labelStyle),r}var a=t("../util");e.exports=n},{"../util":27}],20:[function(t,e,r){function n(t,e){for(var r=t.append("text"),n=a(e.label).split("\n"),l=0;l")); 49 | }); 50 | 51 | gulp.task("js:build", function() { 52 | return makeJsBundleTask(false); 53 | }); 54 | 55 | gulp.task("js:watch", function() { 56 | return makeJsBundleTask(true); 57 | }); 58 | 59 | gulp.task("js:test", ["js:build"], function(cb) { 60 | karmaSingleRun(__dirname + "/karma.conf.js", cb); 61 | }); 62 | 63 | gulp.task("js:test:watch", ["js:build"], function(cb) { 64 | karma.start({ 65 | configFile: __dirname + "/karma.conf.js", 66 | singleRun: false, 67 | browsers: ["PhantomJS"] 68 | }); 69 | cb(); 70 | }); 71 | 72 | gulp.task("core-js:build", function() { 73 | return makeBundleTask("./index.js", "dagre-d3.core.js", false, { 74 | standalone: "dagreD3", 75 | bundleExternal: false, 76 | debug: true 77 | }); 78 | }); 79 | 80 | gulp.task("core-js:test", ["core-js:build"], function(cb) { 81 | karmaSingleRun(__dirname + "/karma.core.conf.js", cb); 82 | }); 83 | 84 | gulp.task("version:build", function() { 85 | var pkg = readPackageJson(); 86 | fs.writeFileSync("lib/version.js", generateVersionJs(pkg)); 87 | }); 88 | 89 | gulp.task("bower:build", function() { 90 | var pkg = readPackageJson(); 91 | fs.writeFileSync("bower.json", generateBowerJson(pkg)); 92 | }); 93 | 94 | gulp.task("build", ["demo:build", "js:build", "js:test", "core-js:build", "core-js:test", "demo:test"]); 95 | 96 | gulp.task("watch", ["demo:watch", "js:watch", "js:test:watch"]); 97 | 98 | gulp.task("serve", ["watch"], function() { 99 | browserSync.init({ 100 | files: BUILD_DIST_DIR + "/**/*", 101 | notify: false, 102 | open: false, 103 | reloadOnRestart: true, 104 | server: { 105 | baseDir: BUILD_DIST_DIR, 106 | directory: true 107 | } 108 | }); 109 | }); 110 | 111 | gulp.task("dist", ["version:build", "bower:build", "build"], function() { 112 | return gulp.src(BUILD_DIST_DIR + "/**/*") 113 | .pipe(gulp.dest(DIST_DIR)); 114 | }); 115 | 116 | gulp.task("release", ["dist"], function() { 117 | return gulp.src("src/release/release.sh") 118 | .pipe(shell("<%= (file.path) %>")); 119 | }); 120 | 121 | gulp.task("clean", function(cb) { 122 | del(BUILD_DIR, cb); 123 | }); 124 | 125 | gulp.task("default", ["build"]); 126 | 127 | function karmaSingleRun(conf, cb) { 128 | var args = { 129 | configFile: conf, 130 | singleRun: true 131 | }; 132 | 133 | if (process.env.BROWSERS) { 134 | args.browsers = process.env.BROWSERS.split(","); 135 | } 136 | 137 | karma.start(args, cb); 138 | } 139 | 140 | function makeJsBundleTask(watch) { 141 | return makeBundleTask("./index.js", "dagre-d3.js", watch, { 142 | standalone: "dagreD3", 143 | external: ["node_modules/d3/index.js", "node_modules/d3/d3.js"], 144 | debug: true 145 | }); 146 | } 147 | 148 | function makeBundleTask(src, name, watch, args) { 149 | var bundler = browserify(_.defaults(args, watchify.args)) 150 | .add(src); 151 | 152 | function bundle(changedFiles) { 153 | gutil.log("Starting '" + gutil.colors.cyan("browserify " + name) + "'..."); 154 | var start = process.hrtime(); 155 | var compileStream = bundler.bundle() 156 | .on("error", function(err) { 157 | gutil.log(gutil.colors.red("browserify error (" + name + "): " + err.message)); 158 | this.emit("end"); 159 | }) 160 | .on("end", function() { 161 | var end = process.hrtime(start); 162 | gutil.log("Finished '" + gutil.colors.cyan("browserify " + name) + "' after", 163 | gutil.colors.magenta(prettyTime(end))); 164 | }) 165 | .pipe(source(name)) 166 | .pipe(gulp.dest(BUILD_DIST_DIR)) 167 | .pipe(buffer()) 168 | .pipe(sourcemaps.init({ loadMaps: true })) 169 | .pipe(uglify({ preserveComments: "some" })) 170 | .pipe(rename({ suffix: ".min" })) 171 | .pipe(sourcemaps.write("./")) 172 | .pipe(gulp.dest(BUILD_DIST_DIR)); 173 | 174 | var lintStream; 175 | if (changedFiles) { 176 | lintStream = gulp.src(changedFiles); 177 | } else { 178 | lintStream = gulp.src(["index.js", "lib/**/*.js"]); 179 | } 180 | 181 | lintStream = lintStream 182 | .pipe(jshint()) 183 | .pipe(jshint.reporter(jshintStylish)); 184 | if (!watch) { 185 | lintStream = lintStream.pipe(jshint.reporter("fail")); 186 | } 187 | 188 | return merge(lintStream, compileStream); 189 | } 190 | 191 | if (watch) { 192 | bundler = watchify(bundler); 193 | bundler.on("update", bundle); 194 | } 195 | 196 | return bundle(); 197 | } 198 | 199 | function generateBowerJson(pkg) { 200 | return prettifyJson(applyTemplate("src/bower.json.tmpl", { pkg: pkg })); 201 | } 202 | 203 | function generateVersionJs(pkg) { 204 | return applyTemplate("src/version.js.tmpl", { pkg: pkg }); 205 | } 206 | 207 | function applyTemplate(templateFile, props) { 208 | var template = fs.readFileSync(templateFile); 209 | var compiled = _.template(template); 210 | return compiled(props); 211 | } 212 | 213 | /** 214 | * Read the contents of package.json in as JSON. Do not cache package.json, 215 | * because it may have changed (e.g. when running in watch mode). 216 | */ 217 | function readPackageJson() { 218 | var packageText = fs.readFileSync("package.json"); 219 | return JSON.parse(packageText); 220 | } 221 | 222 | /** 223 | * Given a JSON string return a prettified version of the string. 224 | */ 225 | function prettifyJson(str) { 226 | var json = JSON.parse(str); 227 | return JSON.stringify(json, null, 2); 228 | } 229 | -------------------------------------------------------------------------------- /bower_components/dagre/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dagre", 3 | "version": "0.7.4", 4 | "main": [ 5 | "dist/dagre.core.js", 6 | "dist/dagre.core.min.js" 7 | ], 8 | "ignore": [ 9 | ".*", 10 | "README.md", 11 | "CHANGELOG.md", 12 | "Makefile", 13 | "dist/dagre.js", 14 | "dist/dagre.min.js", 15 | "index.js", 16 | "karma*", 17 | "lib/**", 18 | "package.json", 19 | "src/**", 20 | "test/**" 21 | ], 22 | "dependencies": { 23 | "graphlib": "^1.0.5", 24 | "lodash": "^3.10.0" 25 | }, 26 | "homepage": "https://github.com/cpettitt/dagre", 27 | "_release": "0.7.4", 28 | "_resolution": { 29 | "type": "version", 30 | "tag": "v0.7.4", 31 | "commit": "6c65e75ad68f29c924bd0cd8f2e855bb551c46ee" 32 | }, 33 | "_source": "git://github.com/cpettitt/dagre.git", 34 | "_target": "^0.7.3", 35 | "_originalSource": "dagre" 36 | } -------------------------------------------------------------------------------- /bower_components/dagre/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2014 Chris Pettitt 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /bower_components/dagre/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dagre", 3 | "version": "0.7.4", 4 | "main": [ 5 | "dist/dagre.core.js", 6 | "dist/dagre.core.min.js" 7 | ], 8 | "ignore": [ 9 | ".*", 10 | "README.md", 11 | "CHANGELOG.md", 12 | "Makefile", 13 | "dist/dagre.js", 14 | "dist/dagre.min.js", 15 | "index.js", 16 | "karma*", 17 | "lib/**", 18 | "package.json", 19 | "src/**", 20 | "test/**" 21 | ], 22 | "dependencies": { 23 | "graphlib": "^1.0.5", 24 | "lodash": "^3.10.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /bower_components/graphlib/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "graphlib", 3 | "version": "1.0.7", 4 | "main": [ 5 | "dist/graphlib.core.js" 6 | ], 7 | "ignore": [ 8 | ".*", 9 | "README.md", 10 | "CHANGELOG.md", 11 | "Makefile", 12 | "browser.js", 13 | "dist/graphlib.js", 14 | "dist/graphlib.min.js", 15 | "index.js", 16 | "karma*", 17 | "lib/**", 18 | "package.json", 19 | "src/**", 20 | "test/**" 21 | ], 22 | "dependencies": { 23 | "lodash": "^3.10.0" 24 | }, 25 | "homepage": "https://github.com/cpettitt/graphlib", 26 | "_release": "1.0.7", 27 | "_resolution": { 28 | "type": "version", 29 | "tag": "v1.0.7", 30 | "commit": "fbd547f8f19bd743a4344d385ee1ec37eb34279f" 31 | }, 32 | "_source": "git://github.com/cpettitt/graphlib.git", 33 | "_target": "^1.0.5", 34 | "_originalSource": "graphlib" 35 | } -------------------------------------------------------------------------------- /bower_components/graphlib/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2014 Chris Pettitt 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /bower_components/graphlib/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "graphlib", 3 | "version": "1.0.7", 4 | "main": [ 5 | "dist/graphlib.core.js" 6 | ], 7 | "ignore": [ 8 | ".*", 9 | "README.md", 10 | "CHANGELOG.md", 11 | "Makefile", 12 | "browser.js", 13 | "dist/graphlib.js", 14 | "dist/graphlib.min.js", 15 | "index.js", 16 | "karma*", 17 | "lib/**", 18 | "package.json", 19 | "src/**", 20 | "test/**" 21 | ], 22 | "dependencies": { 23 | "lodash": "^3.10.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /bower_components/graphlib/dist/graphlib.core.js: -------------------------------------------------------------------------------- 1 | (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 0) { 202 | v = pq.removeMin(); 203 | vEntry = results[v]; 204 | if (vEntry.distance === Number.POSITIVE_INFINITY) { 205 | break; 206 | } 207 | 208 | edgeFn(v).forEach(updateNeighbors); 209 | } 210 | 211 | return results; 212 | } 213 | 214 | },{"../data/priority-queue":16,"../lodash":20}],7:[function(require,module,exports){ 215 | var _ = require("../lodash"), 216 | tarjan = require("./tarjan"); 217 | 218 | module.exports = findCycles; 219 | 220 | function findCycles(g) { 221 | return _.filter(tarjan(g), function(cmpt) { 222 | return cmpt.length > 1 || (cmpt.length === 1 && g.hasEdge(cmpt[0], cmpt[0])); 223 | }); 224 | } 225 | 226 | },{"../lodash":20,"./tarjan":14}],8:[function(require,module,exports){ 227 | var _ = require("../lodash"); 228 | 229 | module.exports = floydWarshall; 230 | 231 | var DEFAULT_WEIGHT_FUNC = _.constant(1); 232 | 233 | function floydWarshall(g, weightFn, edgeFn) { 234 | return runFloydWarshall(g, 235 | weightFn || DEFAULT_WEIGHT_FUNC, 236 | edgeFn || function(v) { return g.outEdges(v); }); 237 | } 238 | 239 | function runFloydWarshall(g, weightFn, edgeFn) { 240 | var results = {}, 241 | nodes = g.nodes(); 242 | 243 | nodes.forEach(function(v) { 244 | results[v] = {}; 245 | results[v][v] = { distance: 0 }; 246 | nodes.forEach(function(w) { 247 | if (v !== w) { 248 | results[v][w] = { distance: Number.POSITIVE_INFINITY }; 249 | } 250 | }); 251 | edgeFn(v).forEach(function(edge) { 252 | var w = edge.v === v ? edge.w : edge.v, 253 | d = weightFn(edge); 254 | results[v][w] = { distance: d, predecessor: v }; 255 | }); 256 | }); 257 | 258 | nodes.forEach(function(k) { 259 | var rowK = results[k]; 260 | nodes.forEach(function(i) { 261 | var rowI = results[i]; 262 | nodes.forEach(function(j) { 263 | var ik = rowI[k]; 264 | var kj = rowK[j]; 265 | var ij = rowI[j]; 266 | var altDistance = ik.distance + kj.distance; 267 | if (altDistance < ij.distance) { 268 | ij.distance = altDistance; 269 | ij.predecessor = kj.predecessor; 270 | } 271 | }); 272 | }); 273 | }); 274 | 275 | return results; 276 | } 277 | 278 | },{"../lodash":20}],9:[function(require,module,exports){ 279 | module.exports = { 280 | components: require("./components"), 281 | dijkstra: require("./dijkstra"), 282 | dijkstraAll: require("./dijkstra-all"), 283 | findCycles: require("./find-cycles"), 284 | floydWarshall: require("./floyd-warshall"), 285 | isAcyclic: require("./is-acyclic"), 286 | postorder: require("./postorder"), 287 | preorder: require("./preorder"), 288 | prim: require("./prim"), 289 | tarjan: require("./tarjan"), 290 | topsort: require("./topsort") 291 | }; 292 | 293 | },{"./components":3,"./dijkstra":6,"./dijkstra-all":5,"./find-cycles":7,"./floyd-warshall":8,"./is-acyclic":10,"./postorder":11,"./preorder":12,"./prim":13,"./tarjan":14,"./topsort":15}],10:[function(require,module,exports){ 294 | var topsort = require("./topsort"); 295 | 296 | module.exports = isAcyclic; 297 | 298 | function isAcyclic(g) { 299 | try { 300 | topsort(g); 301 | } catch (e) { 302 | if (e instanceof topsort.CycleException) { 303 | return false; 304 | } 305 | throw e; 306 | } 307 | return true; 308 | } 309 | 310 | },{"./topsort":15}],11:[function(require,module,exports){ 311 | var dfs = require("./dfs"); 312 | 313 | module.exports = postorder; 314 | 315 | function postorder(g, vs) { 316 | return dfs(g, vs, "post"); 317 | } 318 | 319 | },{"./dfs":4}],12:[function(require,module,exports){ 320 | var dfs = require("./dfs"); 321 | 322 | module.exports = preorder; 323 | 324 | function preorder(g, vs) { 325 | return dfs(g, vs, "pre"); 326 | } 327 | 328 | },{"./dfs":4}],13:[function(require,module,exports){ 329 | var _ = require("../lodash"), 330 | Graph = require("../graph"), 331 | PriorityQueue = require("../data/priority-queue"); 332 | 333 | module.exports = prim; 334 | 335 | function prim(g, weightFunc) { 336 | var result = new Graph(), 337 | parents = {}, 338 | pq = new PriorityQueue(), 339 | v; 340 | 341 | function updateNeighbors(edge) { 342 | var w = edge.v === v ? edge.w : edge.v, 343 | pri = pq.priority(w); 344 | if (pri !== undefined) { 345 | var edgeWeight = weightFunc(edge); 346 | if (edgeWeight < pri) { 347 | parents[w] = v; 348 | pq.decrease(w, edgeWeight); 349 | } 350 | } 351 | } 352 | 353 | if (g.nodeCount() === 0) { 354 | return result; 355 | } 356 | 357 | _.each(g.nodes(), function(v) { 358 | pq.add(v, Number.POSITIVE_INFINITY); 359 | result.setNode(v); 360 | }); 361 | 362 | // Start from an arbitrary node 363 | pq.decrease(g.nodes()[0], 0); 364 | 365 | var init = false; 366 | while (pq.size() > 0) { 367 | v = pq.removeMin(); 368 | if (_.has(parents, v)) { 369 | result.setEdge(v, parents[v]); 370 | } else if (init) { 371 | throw new Error("Input graph is not connected: " + g); 372 | } else { 373 | init = true; 374 | } 375 | 376 | g.nodeEdges(v).forEach(updateNeighbors); 377 | } 378 | 379 | return result; 380 | } 381 | 382 | },{"../data/priority-queue":16,"../graph":17,"../lodash":20}],14:[function(require,module,exports){ 383 | var _ = require("../lodash"); 384 | 385 | module.exports = tarjan; 386 | 387 | function tarjan(g) { 388 | var index = 0, 389 | stack = [], 390 | visited = {}, // node id -> { onStack, lowlink, index } 391 | results = []; 392 | 393 | function dfs(v) { 394 | var entry = visited[v] = { 395 | onStack: true, 396 | lowlink: index, 397 | index: index++ 398 | }; 399 | stack.push(v); 400 | 401 | g.successors(v).forEach(function(w) { 402 | if (!_.has(visited, w)) { 403 | dfs(w); 404 | entry.lowlink = Math.min(entry.lowlink, visited[w].lowlink); 405 | } else if (visited[w].onStack) { 406 | entry.lowlink = Math.min(entry.lowlink, visited[w].index); 407 | } 408 | }); 409 | 410 | if (entry.lowlink === entry.index) { 411 | var cmpt = [], 412 | w; 413 | do { 414 | w = stack.pop(); 415 | visited[w].onStack = false; 416 | cmpt.push(w); 417 | } while (v !== w); 418 | results.push(cmpt); 419 | } 420 | } 421 | 422 | g.nodes().forEach(function(v) { 423 | if (!_.has(visited, v)) { 424 | dfs(v); 425 | } 426 | }); 427 | 428 | return results; 429 | } 430 | 431 | },{"../lodash":20}],15:[function(require,module,exports){ 432 | var _ = require("../lodash"); 433 | 434 | module.exports = topsort; 435 | topsort.CycleException = CycleException; 436 | 437 | function topsort(g) { 438 | var visited = {}, 439 | stack = {}, 440 | results = []; 441 | 442 | function visit(node) { 443 | if (_.has(stack, node)) { 444 | throw new CycleException(); 445 | } 446 | 447 | if (!_.has(visited, node)) { 448 | stack[node] = true; 449 | visited[node] = true; 450 | _.each(g.predecessors(node), visit); 451 | delete stack[node]; 452 | results.push(node); 453 | } 454 | } 455 | 456 | _.each(g.sinks(), visit); 457 | 458 | if (_.size(visited) !== g.nodeCount()) { 459 | throw new CycleException(); 460 | } 461 | 462 | return results; 463 | } 464 | 465 | function CycleException() {} 466 | 467 | },{"../lodash":20}],16:[function(require,module,exports){ 468 | var _ = require("../lodash"); 469 | 470 | module.exports = PriorityQueue; 471 | 472 | /** 473 | * A min-priority queue data structure. This algorithm is derived from Cormen, 474 | * et al., "Introduction to Algorithms". The basic idea of a min-priority 475 | * queue is that you can efficiently (in O(1) time) get the smallest key in 476 | * the queue. Adding and removing elements takes O(log n) time. A key can 477 | * have its priority decreased in O(log n) time. 478 | */ 479 | function PriorityQueue() { 480 | this._arr = []; 481 | this._keyIndices = {}; 482 | } 483 | 484 | /** 485 | * Returns the number of elements in the queue. Takes `O(1)` time. 486 | */ 487 | PriorityQueue.prototype.size = function() { 488 | return this._arr.length; 489 | }; 490 | 491 | /** 492 | * Returns the keys that are in the queue. Takes `O(n)` time. 493 | */ 494 | PriorityQueue.prototype.keys = function() { 495 | return this._arr.map(function(x) { return x.key; }); 496 | }; 497 | 498 | /** 499 | * Returns `true` if **key** is in the queue and `false` if not. 500 | */ 501 | PriorityQueue.prototype.has = function(key) { 502 | return _.has(this._keyIndices, key); 503 | }; 504 | 505 | /** 506 | * Returns the priority for **key**. If **key** is not present in the queue 507 | * then this function returns `undefined`. Takes `O(1)` time. 508 | * 509 | * @param {Object} key 510 | */ 511 | PriorityQueue.prototype.priority = function(key) { 512 | var index = this._keyIndices[key]; 513 | if (index !== undefined) { 514 | return this._arr[index].priority; 515 | } 516 | }; 517 | 518 | /** 519 | * Returns the key for the minimum element in this queue. If the queue is 520 | * empty this function throws an Error. Takes `O(1)` time. 521 | */ 522 | PriorityQueue.prototype.min = function() { 523 | if (this.size() === 0) { 524 | throw new Error("Queue underflow"); 525 | } 526 | return this._arr[0].key; 527 | }; 528 | 529 | /** 530 | * Inserts a new key into the priority queue. If the key already exists in 531 | * the queue this function returns `false`; otherwise it will return `true`. 532 | * Takes `O(n)` time. 533 | * 534 | * @param {Object} key the key to add 535 | * @param {Number} priority the initial priority for the key 536 | */ 537 | PriorityQueue.prototype.add = function(key, priority) { 538 | var keyIndices = this._keyIndices; 539 | key = String(key); 540 | if (!_.has(keyIndices, key)) { 541 | var arr = this._arr; 542 | var index = arr.length; 543 | keyIndices[key] = index; 544 | arr.push({key: key, priority: priority}); 545 | this._decrease(index); 546 | return true; 547 | } 548 | return false; 549 | }; 550 | 551 | /** 552 | * Removes and returns the smallest key in the queue. Takes `O(log n)` time. 553 | */ 554 | PriorityQueue.prototype.removeMin = function() { 555 | this._swap(0, this._arr.length - 1); 556 | var min = this._arr.pop(); 557 | delete this._keyIndices[min.key]; 558 | this._heapify(0); 559 | return min.key; 560 | }; 561 | 562 | /** 563 | * Decreases the priority for **key** to **priority**. If the new priority is 564 | * greater than the previous priority, this function will throw an Error. 565 | * 566 | * @param {Object} key the key for which to raise priority 567 | * @param {Number} priority the new priority for the key 568 | */ 569 | PriorityQueue.prototype.decrease = function(key, priority) { 570 | var index = this._keyIndices[key]; 571 | if (priority > this._arr[index].priority) { 572 | throw new Error("New priority is greater than current priority. " + 573 | "Key: " + key + " Old: " + this._arr[index].priority + " New: " + priority); 574 | } 575 | this._arr[index].priority = priority; 576 | this._decrease(index); 577 | }; 578 | 579 | PriorityQueue.prototype._heapify = function(i) { 580 | var arr = this._arr; 581 | var l = 2 * i, 582 | r = l + 1, 583 | largest = i; 584 | if (l < arr.length) { 585 | largest = arr[l].priority < arr[largest].priority ? l : largest; 586 | if (r < arr.length) { 587 | largest = arr[r].priority < arr[largest].priority ? r : largest; 588 | } 589 | if (largest !== i) { 590 | this._swap(i, largest); 591 | this._heapify(largest); 592 | } 593 | } 594 | }; 595 | 596 | PriorityQueue.prototype._decrease = function(index) { 597 | var arr = this._arr; 598 | var priority = arr[index].priority; 599 | var parent; 600 | while (index !== 0) { 601 | parent = index >> 1; 602 | if (arr[parent].priority < priority) { 603 | break; 604 | } 605 | this._swap(index, parent); 606 | index = parent; 607 | } 608 | }; 609 | 610 | PriorityQueue.prototype._swap = function(i, j) { 611 | var arr = this._arr; 612 | var keyIndices = this._keyIndices; 613 | var origArrI = arr[i]; 614 | var origArrJ = arr[j]; 615 | arr[i] = origArrJ; 616 | arr[j] = origArrI; 617 | keyIndices[origArrJ.key] = i; 618 | keyIndices[origArrI.key] = j; 619 | }; 620 | 621 | },{"../lodash":20}],17:[function(require,module,exports){ 622 | "use strict"; 623 | 624 | var _ = require("./lodash"); 625 | 626 | module.exports = Graph; 627 | 628 | var DEFAULT_EDGE_NAME = "\x00", 629 | GRAPH_NODE = "\x00", 630 | EDGE_KEY_DELIM = "\x01"; 631 | 632 | // Implementation notes: 633 | // 634 | // * Node id query functions should return string ids for the nodes 635 | // * Edge id query functions should return an "edgeObj", edge object, that is 636 | // composed of enough information to uniquely identify an edge: {v, w, name}. 637 | // * Internally we use an "edgeId", a stringified form of the edgeObj, to 638 | // reference edges. This is because we need a performant way to look these 639 | // edges up and, object properties, which have string keys, are the closest 640 | // we're going to get to a performant hashtable in JavaScript. 641 | 642 | function Graph(opts) { 643 | this._isDirected = _.has(opts, "directed") ? opts.directed : true; 644 | this._isMultigraph = _.has(opts, "multigraph") ? opts.multigraph : false; 645 | this._isCompound = _.has(opts, "compound") ? opts.compound : false; 646 | 647 | // Label for the graph itself 648 | this._label = undefined; 649 | 650 | // Defaults to be set when creating a new node 651 | this._defaultNodeLabelFn = _.constant(undefined); 652 | 653 | // Defaults to be set when creating a new edge 654 | this._defaultEdgeLabelFn = _.constant(undefined); 655 | 656 | // v -> label 657 | this._nodes = {}; 658 | 659 | if (this._isCompound) { 660 | // v -> parent 661 | this._parent = {}; 662 | 663 | // v -> children 664 | this._children = {}; 665 | this._children[GRAPH_NODE] = {}; 666 | } 667 | 668 | // v -> edgeObj 669 | this._in = {}; 670 | 671 | // u -> v -> Number 672 | this._preds = {}; 673 | 674 | // v -> edgeObj 675 | this._out = {}; 676 | 677 | // v -> w -> Number 678 | this._sucs = {}; 679 | 680 | // e -> edgeObj 681 | this._edgeObjs = {}; 682 | 683 | // e -> label 684 | this._edgeLabels = {}; 685 | } 686 | 687 | /* Number of nodes in the graph. Should only be changed by the implementation. */ 688 | Graph.prototype._nodeCount = 0; 689 | 690 | /* Number of edges in the graph. Should only be changed by the implementation. */ 691 | Graph.prototype._edgeCount = 0; 692 | 693 | 694 | /* === Graph functions ========= */ 695 | 696 | Graph.prototype.isDirected = function() { 697 | return this._isDirected; 698 | }; 699 | 700 | Graph.prototype.isMultigraph = function() { 701 | return this._isMultigraph; 702 | }; 703 | 704 | Graph.prototype.isCompound = function() { 705 | return this._isCompound; 706 | }; 707 | 708 | Graph.prototype.setGraph = function(label) { 709 | this._label = label; 710 | return this; 711 | }; 712 | 713 | Graph.prototype.graph = function() { 714 | return this._label; 715 | }; 716 | 717 | 718 | /* === Node functions ========== */ 719 | 720 | Graph.prototype.setDefaultNodeLabel = function(newDefault) { 721 | if (!_.isFunction(newDefault)) { 722 | newDefault = _.constant(newDefault); 723 | } 724 | this._defaultNodeLabelFn = newDefault; 725 | return this; 726 | }; 727 | 728 | Graph.prototype.nodeCount = function() { 729 | return this._nodeCount; 730 | }; 731 | 732 | Graph.prototype.nodes = function() { 733 | return _.keys(this._nodes); 734 | }; 735 | 736 | Graph.prototype.sources = function() { 737 | return _.filter(this.nodes(), function(v) { 738 | return _.isEmpty(this._in[v]); 739 | }, this); 740 | }; 741 | 742 | Graph.prototype.sinks = function() { 743 | return _.filter(this.nodes(), function(v) { 744 | return _.isEmpty(this._out[v]); 745 | }, this); 746 | }; 747 | 748 | Graph.prototype.setNodes = function(vs, value) { 749 | var args = arguments; 750 | _.each(vs, function(v) { 751 | if (args.length > 1) { 752 | this.setNode(v, value); 753 | } else { 754 | this.setNode(v); 755 | } 756 | }, this); 757 | return this; 758 | }; 759 | 760 | Graph.prototype.setNode = function(v, value) { 761 | if (_.has(this._nodes, v)) { 762 | if (arguments.length > 1) { 763 | this._nodes[v] = value; 764 | } 765 | return this; 766 | } 767 | 768 | this._nodes[v] = arguments.length > 1 ? value : this._defaultNodeLabelFn(v); 769 | if (this._isCompound) { 770 | this._parent[v] = GRAPH_NODE; 771 | this._children[v] = {}; 772 | this._children[GRAPH_NODE][v] = true; 773 | } 774 | this._in[v] = {}; 775 | this._preds[v] = {}; 776 | this._out[v] = {}; 777 | this._sucs[v] = {}; 778 | ++this._nodeCount; 779 | return this; 780 | }; 781 | 782 | Graph.prototype.node = function(v) { 783 | return this._nodes[v]; 784 | }; 785 | 786 | Graph.prototype.hasNode = function(v) { 787 | return _.has(this._nodes, v); 788 | }; 789 | 790 | Graph.prototype.removeNode = function(v) { 791 | var self = this; 792 | if (_.has(this._nodes, v)) { 793 | var removeEdge = function(e) { self.removeEdge(self._edgeObjs[e]); }; 794 | delete this._nodes[v]; 795 | if (this._isCompound) { 796 | this._removeFromParentsChildList(v); 797 | delete this._parent[v]; 798 | _.each(this.children(v), function(child) { 799 | this.setParent(child); 800 | }, this); 801 | delete this._children[v]; 802 | } 803 | _.each(_.keys(this._in[v]), removeEdge); 804 | delete this._in[v]; 805 | delete this._preds[v]; 806 | _.each(_.keys(this._out[v]), removeEdge); 807 | delete this._out[v]; 808 | delete this._sucs[v]; 809 | --this._nodeCount; 810 | } 811 | return this; 812 | }; 813 | 814 | Graph.prototype.setParent = function(v, parent) { 815 | if (!this._isCompound) { 816 | throw new Error("Cannot set parent in a non-compound graph"); 817 | } 818 | 819 | if (_.isUndefined(parent)) { 820 | parent = GRAPH_NODE; 821 | } else { 822 | // Coerce parent to string 823 | parent += ""; 824 | for (var ancestor = parent; 825 | !_.isUndefined(ancestor); 826 | ancestor = this.parent(ancestor)) { 827 | if (ancestor === v) { 828 | throw new Error("Setting " + parent+ " as parent of " + v + 829 | " would create create a cycle"); 830 | } 831 | } 832 | 833 | this.setNode(parent); 834 | } 835 | 836 | this.setNode(v); 837 | this._removeFromParentsChildList(v); 838 | this._parent[v] = parent; 839 | this._children[parent][v] = true; 840 | return this; 841 | }; 842 | 843 | Graph.prototype._removeFromParentsChildList = function(v) { 844 | delete this._children[this._parent[v]][v]; 845 | }; 846 | 847 | Graph.prototype.parent = function(v) { 848 | if (this._isCompound) { 849 | var parent = this._parent[v]; 850 | if (parent !== GRAPH_NODE) { 851 | return parent; 852 | } 853 | } 854 | }; 855 | 856 | Graph.prototype.children = function(v) { 857 | if (_.isUndefined(v)) { 858 | v = GRAPH_NODE; 859 | } 860 | 861 | if (this._isCompound) { 862 | var children = this._children[v]; 863 | if (children) { 864 | return _.keys(children); 865 | } 866 | } else if (v === GRAPH_NODE) { 867 | return this.nodes(); 868 | } else if (this.hasNode(v)) { 869 | return []; 870 | } 871 | }; 872 | 873 | Graph.prototype.predecessors = function(v) { 874 | var predsV = this._preds[v]; 875 | if (predsV) { 876 | return _.keys(predsV); 877 | } 878 | }; 879 | 880 | Graph.prototype.successors = function(v) { 881 | var sucsV = this._sucs[v]; 882 | if (sucsV) { 883 | return _.keys(sucsV); 884 | } 885 | }; 886 | 887 | Graph.prototype.neighbors = function(v) { 888 | var preds = this.predecessors(v); 889 | if (preds) { 890 | return _.union(preds, this.successors(v)); 891 | } 892 | }; 893 | 894 | Graph.prototype.filterNodes = function(filter) { 895 | var copy = new this.constructor({ 896 | directed: this._isDirected, 897 | multigraph: this._isMultigraph, 898 | compound: this._isCompound 899 | }); 900 | 901 | copy.setGraph(this.graph()); 902 | 903 | _.each(this._nodes, function(value, v) { 904 | if (filter(v)) { 905 | copy.setNode(v, value); 906 | } 907 | }, this); 908 | 909 | _.each(this._edgeObjs, function(e) { 910 | if (copy.hasNode(e.v) && copy.hasNode(e.w)) { 911 | copy.setEdge(e, this.edge(e)); 912 | } 913 | }, this); 914 | 915 | var self = this; 916 | var parents = {}; 917 | function findParent(v) { 918 | var parent = self.parent(v); 919 | if (parent === undefined || copy.hasNode(parent)) { 920 | parents[v] = parent; 921 | return parent; 922 | } else if (parent in parents) { 923 | return parents[parent]; 924 | } else { 925 | return findParent(parent); 926 | } 927 | } 928 | 929 | if (this._isCompound) { 930 | _.each(copy.nodes(), function(v) { 931 | copy.setParent(v, findParent(v)); 932 | }); 933 | } 934 | 935 | return copy; 936 | }; 937 | 938 | /* === Edge functions ========== */ 939 | 940 | Graph.prototype.setDefaultEdgeLabel = function(newDefault) { 941 | if (!_.isFunction(newDefault)) { 942 | newDefault = _.constant(newDefault); 943 | } 944 | this._defaultEdgeLabelFn = newDefault; 945 | return this; 946 | }; 947 | 948 | Graph.prototype.edgeCount = function() { 949 | return this._edgeCount; 950 | }; 951 | 952 | Graph.prototype.edges = function() { 953 | return _.values(this._edgeObjs); 954 | }; 955 | 956 | Graph.prototype.setPath = function(vs, value) { 957 | var self = this, 958 | args = arguments; 959 | _.reduce(vs, function(v, w) { 960 | if (args.length > 1) { 961 | self.setEdge(v, w, value); 962 | } else { 963 | self.setEdge(v, w); 964 | } 965 | return w; 966 | }); 967 | return this; 968 | }; 969 | 970 | /* 971 | * setEdge(v, w, [value, [name]]) 972 | * setEdge({ v, w, [name] }, [value]) 973 | */ 974 | Graph.prototype.setEdge = function() { 975 | var v, w, name, value, 976 | valueSpecified = false, 977 | arg0 = arguments[0]; 978 | 979 | if (typeof arg0 === "object" && arg0 !== null && "v" in arg0) { 980 | v = arg0.v; 981 | w = arg0.w; 982 | name = arg0.name; 983 | if (arguments.length === 2) { 984 | value = arguments[1]; 985 | valueSpecified = true; 986 | } 987 | } else { 988 | v = arg0; 989 | w = arguments[1]; 990 | name = arguments[3]; 991 | if (arguments.length > 2) { 992 | value = arguments[2]; 993 | valueSpecified = true; 994 | } 995 | } 996 | 997 | v = "" + v; 998 | w = "" + w; 999 | if (!_.isUndefined(name)) { 1000 | name = "" + name; 1001 | } 1002 | 1003 | var e = edgeArgsToId(this._isDirected, v, w, name); 1004 | if (_.has(this._edgeLabels, e)) { 1005 | if (valueSpecified) { 1006 | this._edgeLabels[e] = value; 1007 | } 1008 | return this; 1009 | } 1010 | 1011 | if (!_.isUndefined(name) && !this._isMultigraph) { 1012 | throw new Error("Cannot set a named edge when isMultigraph = false"); 1013 | } 1014 | 1015 | // It didn't exist, so we need to create it. 1016 | // First ensure the nodes exist. 1017 | this.setNode(v); 1018 | this.setNode(w); 1019 | 1020 | this._edgeLabels[e] = valueSpecified ? value : this._defaultEdgeLabelFn(v, w, name); 1021 | 1022 | var edgeObj = edgeArgsToObj(this._isDirected, v, w, name); 1023 | // Ensure we add undirected edges in a consistent way. 1024 | v = edgeObj.v; 1025 | w = edgeObj.w; 1026 | 1027 | Object.freeze(edgeObj); 1028 | this._edgeObjs[e] = edgeObj; 1029 | incrementOrInitEntry(this._preds[w], v); 1030 | incrementOrInitEntry(this._sucs[v], w); 1031 | this._in[w][e] = edgeObj; 1032 | this._out[v][e] = edgeObj; 1033 | this._edgeCount++; 1034 | return this; 1035 | }; 1036 | 1037 | Graph.prototype.edge = function(v, w, name) { 1038 | var e = (arguments.length === 1 1039 | ? edgeObjToId(this._isDirected, arguments[0]) 1040 | : edgeArgsToId(this._isDirected, v, w, name)); 1041 | return this._edgeLabels[e]; 1042 | }; 1043 | 1044 | Graph.prototype.hasEdge = function(v, w, name) { 1045 | var e = (arguments.length === 1 1046 | ? edgeObjToId(this._isDirected, arguments[0]) 1047 | : edgeArgsToId(this._isDirected, v, w, name)); 1048 | return _.has(this._edgeLabels, e); 1049 | }; 1050 | 1051 | Graph.prototype.removeEdge = function(v, w, name) { 1052 | var e = (arguments.length === 1 1053 | ? edgeObjToId(this._isDirected, arguments[0]) 1054 | : edgeArgsToId(this._isDirected, v, w, name)), 1055 | edge = this._edgeObjs[e]; 1056 | if (edge) { 1057 | v = edge.v; 1058 | w = edge.w; 1059 | delete this._edgeLabels[e]; 1060 | delete this._edgeObjs[e]; 1061 | decrementOrRemoveEntry(this._preds[w], v); 1062 | decrementOrRemoveEntry(this._sucs[v], w); 1063 | delete this._in[w][e]; 1064 | delete this._out[v][e]; 1065 | this._edgeCount--; 1066 | } 1067 | return this; 1068 | }; 1069 | 1070 | Graph.prototype.inEdges = function(v, u) { 1071 | var inV = this._in[v]; 1072 | if (inV) { 1073 | var edges = _.values(inV); 1074 | if (!u) { 1075 | return edges; 1076 | } 1077 | return _.filter(edges, function(edge) { return edge.v === u; }); 1078 | } 1079 | }; 1080 | 1081 | Graph.prototype.outEdges = function(v, w) { 1082 | var outV = this._out[v]; 1083 | if (outV) { 1084 | var edges = _.values(outV); 1085 | if (!w) { 1086 | return edges; 1087 | } 1088 | return _.filter(edges, function(edge) { return edge.w === w; }); 1089 | } 1090 | }; 1091 | 1092 | Graph.prototype.nodeEdges = function(v, w) { 1093 | var inEdges = this.inEdges(v, w); 1094 | if (inEdges) { 1095 | return inEdges.concat(this.outEdges(v, w)); 1096 | } 1097 | }; 1098 | 1099 | function incrementOrInitEntry(map, k) { 1100 | if (map[k]) { 1101 | map[k]++; 1102 | } else { 1103 | map[k] = 1; 1104 | } 1105 | } 1106 | 1107 | function decrementOrRemoveEntry(map, k) { 1108 | if (!--map[k]) { delete map[k]; } 1109 | } 1110 | 1111 | function edgeArgsToId(isDirected, v_, w_, name) { 1112 | var v = "" + v_; 1113 | var w = "" + w_; 1114 | if (!isDirected && v > w) { 1115 | var tmp = v; 1116 | v = w; 1117 | w = tmp; 1118 | } 1119 | return v + EDGE_KEY_DELIM + w + EDGE_KEY_DELIM + 1120 | (_.isUndefined(name) ? DEFAULT_EDGE_NAME : name); 1121 | } 1122 | 1123 | function edgeArgsToObj(isDirected, v_, w_, name) { 1124 | var v = "" + v_; 1125 | var w = "" + w_; 1126 | if (!isDirected && v > w) { 1127 | var tmp = v; 1128 | v = w; 1129 | w = tmp; 1130 | } 1131 | var edgeObj = { v: v, w: w }; 1132 | if (name) { 1133 | edgeObj.name = name; 1134 | } 1135 | return edgeObj; 1136 | } 1137 | 1138 | function edgeObjToId(isDirected, edgeObj) { 1139 | return edgeArgsToId(isDirected, edgeObj.v, edgeObj.w, edgeObj.name); 1140 | } 1141 | 1142 | },{"./lodash":20}],18:[function(require,module,exports){ 1143 | // Includes only the "core" of graphlib 1144 | module.exports = { 1145 | Graph: require("./graph"), 1146 | version: require("./version") 1147 | }; 1148 | 1149 | },{"./graph":17,"./version":21}],19:[function(require,module,exports){ 1150 | var _ = require("./lodash"), 1151 | Graph = require("./graph"); 1152 | 1153 | module.exports = { 1154 | write: write, 1155 | read: read 1156 | }; 1157 | 1158 | function write(g) { 1159 | var json = { 1160 | options: { 1161 | directed: g.isDirected(), 1162 | multigraph: g.isMultigraph(), 1163 | compound: g.isCompound() 1164 | }, 1165 | nodes: writeNodes(g), 1166 | edges: writeEdges(g) 1167 | }; 1168 | if (!_.isUndefined(g.graph())) { 1169 | json.value = _.clone(g.graph()); 1170 | } 1171 | return json; 1172 | } 1173 | 1174 | function writeNodes(g) { 1175 | return _.map(g.nodes(), function(v) { 1176 | var nodeValue = g.node(v), 1177 | parent = g.parent(v), 1178 | node = { v: v }; 1179 | if (!_.isUndefined(nodeValue)) { 1180 | node.value = nodeValue; 1181 | } 1182 | if (!_.isUndefined(parent)) { 1183 | node.parent = parent; 1184 | } 1185 | return node; 1186 | }); 1187 | } 1188 | 1189 | function writeEdges(g) { 1190 | return _.map(g.edges(), function(e) { 1191 | var edgeValue = g.edge(e), 1192 | edge = { v: e.v, w: e.w }; 1193 | if (!_.isUndefined(e.name)) { 1194 | edge.name = e.name; 1195 | } 1196 | if (!_.isUndefined(edgeValue)) { 1197 | edge.value = edgeValue; 1198 | } 1199 | return edge; 1200 | }); 1201 | } 1202 | 1203 | function read(json) { 1204 | var g = new Graph(json.options).setGraph(json.value); 1205 | _.each(json.nodes, function(entry) { 1206 | g.setNode(entry.v, entry.value); 1207 | if (entry.parent) { 1208 | g.setParent(entry.v, entry.parent); 1209 | } 1210 | }); 1211 | _.each(json.edges, function(entry) { 1212 | g.setEdge({ v: entry.v, w: entry.w, name: entry.name }, entry.value); 1213 | }); 1214 | return g; 1215 | } 1216 | 1217 | },{"./graph":17,"./lodash":20}],20:[function(require,module,exports){ 1218 | /* global window */ 1219 | 1220 | var lodash; 1221 | 1222 | if (typeof require === "function") { 1223 | try { 1224 | lodash = require("lodash"); 1225 | } catch (e) {} 1226 | } 1227 | 1228 | if (!lodash) { 1229 | lodash = window._; 1230 | } 1231 | 1232 | module.exports = lodash; 1233 | 1234 | },{"lodash":undefined}],21:[function(require,module,exports){ 1235 | module.exports = '1.0.7'; 1236 | 1237 | },{}]},{},[1]); 1238 | -------------------------------------------------------------------------------- /bower_components/graphlib/dist/graphlib.core.min.js: -------------------------------------------------------------------------------- 1 | (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;o0){v=pq.removeMin();vEntry=results[v];if(vEntry.distance===Number.POSITIVE_INFINITY){break}edgeFn(v).forEach(updateNeighbors)}return results}},{"../data/priority-queue":16,"../lodash":20}],7:[function(require,module,exports){var _=require("../lodash"),tarjan=require("./tarjan");module.exports=findCycles;function findCycles(g){return _.filter(tarjan(g),function(cmpt){return cmpt.length>1||cmpt.length===1&&g.hasEdge(cmpt[0],cmpt[0])})}},{"../lodash":20,"./tarjan":14}],8:[function(require,module,exports){var _=require("../lodash");module.exports=floydWarshall;var DEFAULT_WEIGHT_FUNC=_.constant(1);function floydWarshall(g,weightFn,edgeFn){return runFloydWarshall(g,weightFn||DEFAULT_WEIGHT_FUNC,edgeFn||function(v){return g.outEdges(v)})}function runFloydWarshall(g,weightFn,edgeFn){var results={},nodes=g.nodes();nodes.forEach(function(v){results[v]={};results[v][v]={distance:0};nodes.forEach(function(w){if(v!==w){results[v][w]={distance:Number.POSITIVE_INFINITY}}});edgeFn(v).forEach(function(edge){var w=edge.v===v?edge.w:edge.v,d=weightFn(edge);results[v][w]={distance:d,predecessor:v}})});nodes.forEach(function(k){var rowK=results[k];nodes.forEach(function(i){var rowI=results[i];nodes.forEach(function(j){var ik=rowI[k];var kj=rowK[j];var ij=rowI[j];var altDistance=ik.distance+kj.distance;if(altDistance0){v=pq.removeMin();if(_.has(parents,v)){result.setEdge(v,parents[v])}else if(init){throw new Error("Input graph is not connected: "+g)}else{init=true}g.nodeEdges(v).forEach(updateNeighbors)}return result}},{"../data/priority-queue":16,"../graph":17,"../lodash":20}],14:[function(require,module,exports){var _=require("../lodash");module.exports=tarjan;function tarjan(g){var index=0,stack=[],visited={},results=[];function dfs(v){var entry=visited[v]={onStack:true,lowlink:index,index:index++};stack.push(v);g.successors(v).forEach(function(w){if(!_.has(visited,w)){dfs(w);entry.lowlink=Math.min(entry.lowlink,visited[w].lowlink)}else if(visited[w].onStack){entry.lowlink=Math.min(entry.lowlink,visited[w].index)}});if(entry.lowlink===entry.index){var cmpt=[],w;do{w=stack.pop();visited[w].onStack=false;cmpt.push(w)}while(v!==w);results.push(cmpt)}}g.nodes().forEach(function(v){if(!_.has(visited,v)){dfs(v)}});return results}},{"../lodash":20}],15:[function(require,module,exports){var _=require("../lodash");module.exports=topsort;topsort.CycleException=CycleException;function topsort(g){var visited={},stack={},results=[];function visit(node){if(_.has(stack,node)){throw new CycleException}if(!_.has(visited,node)){stack[node]=true;visited[node]=true;_.each(g.predecessors(node),visit);delete stack[node];results.push(node)}}_.each(g.sinks(),visit);if(_.size(visited)!==g.nodeCount()){throw new CycleException}return results}function CycleException(){}},{"../lodash":20}],16:[function(require,module,exports){var _=require("../lodash");module.exports=PriorityQueue;function PriorityQueue(){this._arr=[];this._keyIndices={}}PriorityQueue.prototype.size=function(){return this._arr.length};PriorityQueue.prototype.keys=function(){return this._arr.map(function(x){return x.key})};PriorityQueue.prototype.has=function(key){return _.has(this._keyIndices,key)};PriorityQueue.prototype.priority=function(key){var index=this._keyIndices[key];if(index!==undefined){return this._arr[index].priority}};PriorityQueue.prototype.min=function(){if(this.size()===0){throw new Error("Queue underflow")}return this._arr[0].key};PriorityQueue.prototype.add=function(key,priority){var keyIndices=this._keyIndices;key=String(key);if(!_.has(keyIndices,key)){var arr=this._arr;var index=arr.length;keyIndices[key]=index;arr.push({key:key,priority:priority});this._decrease(index);return true}return false};PriorityQueue.prototype.removeMin=function(){this._swap(0,this._arr.length-1);var min=this._arr.pop();delete this._keyIndices[min.key];this._heapify(0);return min.key};PriorityQueue.prototype.decrease=function(key,priority){var index=this._keyIndices[key];if(priority>this._arr[index].priority){throw new Error("New priority is greater than current priority. "+"Key: "+key+" Old: "+this._arr[index].priority+" New: "+priority)}this._arr[index].priority=priority;this._decrease(index)};PriorityQueue.prototype._heapify=function(i){var arr=this._arr;var l=2*i,r=l+1,largest=i;if(l>1;if(arr[parent].priority1){this.setNode(v,value)}else{this.setNode(v)}},this);return this};Graph.prototype.setNode=function(v,value){if(_.has(this._nodes,v)){if(arguments.length>1){this._nodes[v]=value}return this}this._nodes[v]=arguments.length>1?value:this._defaultNodeLabelFn(v);if(this._isCompound){this._parent[v]=GRAPH_NODE;this._children[v]={};this._children[GRAPH_NODE][v]=true}this._in[v]={};this._preds[v]={};this._out[v]={};this._sucs[v]={};++this._nodeCount;return this};Graph.prototype.node=function(v){return this._nodes[v]};Graph.prototype.hasNode=function(v){return _.has(this._nodes,v)};Graph.prototype.removeNode=function(v){var self=this;if(_.has(this._nodes,v)){var removeEdge=function(e){self.removeEdge(self._edgeObjs[e])};delete this._nodes[v];if(this._isCompound){this._removeFromParentsChildList(v);delete this._parent[v];_.each(this.children(v),function(child){this.setParent(child)},this);delete this._children[v]}_.each(_.keys(this._in[v]),removeEdge);delete this._in[v];delete this._preds[v];_.each(_.keys(this._out[v]),removeEdge);delete this._out[v];delete this._sucs[v];--this._nodeCount}return this};Graph.prototype.setParent=function(v,parent){if(!this._isCompound){throw new Error("Cannot set parent in a non-compound graph")}if(_.isUndefined(parent)){parent=GRAPH_NODE}else{parent+="";for(var ancestor=parent;!_.isUndefined(ancestor);ancestor=this.parent(ancestor)){if(ancestor===v){throw new Error("Setting "+parent+" as parent of "+v+" would create create a cycle")}}this.setNode(parent)}this.setNode(v);this._removeFromParentsChildList(v);this._parent[v]=parent;this._children[parent][v]=true;return this};Graph.prototype._removeFromParentsChildList=function(v){delete this._children[this._parent[v]][v]};Graph.prototype.parent=function(v){if(this._isCompound){var parent=this._parent[v];if(parent!==GRAPH_NODE){return parent}}};Graph.prototype.children=function(v){if(_.isUndefined(v)){v=GRAPH_NODE}if(this._isCompound){var children=this._children[v];if(children){return _.keys(children)}}else if(v===GRAPH_NODE){return this.nodes()}else if(this.hasNode(v)){return[]}};Graph.prototype.predecessors=function(v){var predsV=this._preds[v];if(predsV){return _.keys(predsV)}};Graph.prototype.successors=function(v){var sucsV=this._sucs[v];if(sucsV){return _.keys(sucsV)}};Graph.prototype.neighbors=function(v){var preds=this.predecessors(v);if(preds){return _.union(preds,this.successors(v))}};Graph.prototype.filterNodes=function(filter){var copy=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});copy.setGraph(this.graph());_.each(this._nodes,function(value,v){if(filter(v)){copy.setNode(v,value)}},this);_.each(this._edgeObjs,function(e){if(copy.hasNode(e.v)&©.hasNode(e.w)){copy.setEdge(e,this.edge(e))}},this);var self=this;var parents={};function findParent(v){var parent=self.parent(v);if(parent===undefined||copy.hasNode(parent)){parents[v]=parent;return parent}else if(parent in parents){return parents[parent]}else{return findParent(parent)}}if(this._isCompound){_.each(copy.nodes(),function(v){copy.setParent(v,findParent(v))})}return copy};Graph.prototype.setDefaultEdgeLabel=function(newDefault){if(!_.isFunction(newDefault)){newDefault=_.constant(newDefault)}this._defaultEdgeLabelFn=newDefault;return this};Graph.prototype.edgeCount=function(){return this._edgeCount};Graph.prototype.edges=function(){return _.values(this._edgeObjs)};Graph.prototype.setPath=function(vs,value){var self=this,args=arguments;_.reduce(vs,function(v,w){if(args.length>1){self.setEdge(v,w,value)}else{self.setEdge(v,w)}return w});return this};Graph.prototype.setEdge=function(){var v,w,name,value,valueSpecified=false,arg0=arguments[0];if(typeof arg0==="object"&&arg0!==null&&"v"in arg0){v=arg0.v;w=arg0.w;name=arg0.name;if(arguments.length===2){value=arguments[1];valueSpecified=true}}else{v=arg0;w=arguments[1];name=arguments[3];if(arguments.length>2){value=arguments[2];valueSpecified=true}}v=""+v;w=""+w;if(!_.isUndefined(name)){name=""+name}var e=edgeArgsToId(this._isDirected,v,w,name);if(_.has(this._edgeLabels,e)){if(valueSpecified){this._edgeLabels[e]=value}return this}if(!_.isUndefined(name)&&!this._isMultigraph){throw new Error("Cannot set a named edge when isMultigraph = false")}this.setNode(v);this.setNode(w);this._edgeLabels[e]=valueSpecified?value:this._defaultEdgeLabelFn(v,w,name);var edgeObj=edgeArgsToObj(this._isDirected,v,w,name);v=edgeObj.v;w=edgeObj.w;Object.freeze(edgeObj);this._edgeObjs[e]=edgeObj;incrementOrInitEntry(this._preds[w],v);incrementOrInitEntry(this._sucs[v],w);this._in[w][e]=edgeObj;this._out[v][e]=edgeObj;this._edgeCount++;return this};Graph.prototype.edge=function(v,w,name){var e=arguments.length===1?edgeObjToId(this._isDirected,arguments[0]):edgeArgsToId(this._isDirected,v,w,name);return this._edgeLabels[e]};Graph.prototype.hasEdge=function(v,w,name){var e=arguments.length===1?edgeObjToId(this._isDirected,arguments[0]):edgeArgsToId(this._isDirected,v,w,name);return _.has(this._edgeLabels,e)};Graph.prototype.removeEdge=function(v,w,name){var e=arguments.length===1?edgeObjToId(this._isDirected,arguments[0]):edgeArgsToId(this._isDirected,v,w,name),edge=this._edgeObjs[e];if(edge){v=edge.v;w=edge.w;delete this._edgeLabels[e];delete this._edgeObjs[e];decrementOrRemoveEntry(this._preds[w],v);decrementOrRemoveEntry(this._sucs[v],w);delete this._in[w][e];delete this._out[v][e];this._edgeCount--}return this};Graph.prototype.inEdges=function(v,u){var inV=this._in[v];if(inV){var edges=_.values(inV);if(!u){return edges}return _.filter(edges,function(edge){return edge.v===u})}};Graph.prototype.outEdges=function(v,w){var outV=this._out[v];if(outV){var edges=_.values(outV);if(!w){return edges}return _.filter(edges,function(edge){return edge.w===w})}};Graph.prototype.nodeEdges=function(v,w){var inEdges=this.inEdges(v,w);if(inEdges){return inEdges.concat(this.outEdges(v,w))}};function incrementOrInitEntry(map,k){if(map[k]){map[k]++}else{map[k]=1}}function decrementOrRemoveEntry(map,k){if(!--map[k]){delete map[k]}}function edgeArgsToId(isDirected,v_,w_,name){var v=""+v_;var w=""+w_;if(!isDirected&&v>w){var tmp=v;v=w;w=tmp}return v+EDGE_KEY_DELIM+w+EDGE_KEY_DELIM+(_.isUndefined(name)?DEFAULT_EDGE_NAME:name)}function edgeArgsToObj(isDirected,v_,w_,name){var v=""+v_;var w=""+w_;if(!isDirected&&v>w){var tmp=v;v=w;w=tmp}var edgeObj={v:v,w:w};if(name){edgeObj.name=name}return edgeObj}function edgeObjToId(isDirected,edgeObj){return edgeArgsToId(isDirected,edgeObj.v,edgeObj.w,edgeObj.name)}},{"./lodash":20}],18:[function(require,module,exports){module.exports={Graph:require("./graph"),version:require("./version")}},{"./graph":17,"./version":21}],19:[function(require,module,exports){var _=require("./lodash"),Graph=require("./graph");module.exports={write:write,read:read};function write(g){var json={options:{directed:g.isDirected(),multigraph:g.isMultigraph(),compound:g.isCompound()},nodes:writeNodes(g),edges:writeEdges(g)};if(!_.isUndefined(g.graph())){json.value=_.clone(g.graph())}return json}function writeNodes(g){return _.map(g.nodes(),function(v){var nodeValue=g.node(v),parent=g.parent(v),node={v:v};if(!_.isUndefined(nodeValue)){node.value=nodeValue}if(!_.isUndefined(parent)){node.parent=parent}return node})}function writeEdges(g){return _.map(g.edges(),function(e){var edgeValue=g.edge(e),edge={v:e.v,w:e.w};if(!_.isUndefined(e.name)){edge.name=e.name}if(!_.isUndefined(edgeValue)){edge.value=edgeValue}return edge})}function read(json){var g=new Graph(json.options).setGraph(json.value);_.each(json.nodes,function(entry){g.setNode(entry.v,entry.value);if(entry.parent){g.setParent(entry.v,entry.parent)}});_.each(json.edges,function(entry){g.setEdge({v:entry.v,w:entry.w,name:entry.name},entry.value)});return g}},{"./graph":17,"./lodash":20}],20:[function(require,module,exports){var lodash;if(typeof require==="function"){try{lodash=require("lodash")}catch(e){}}if(!lodash){lodash=window._}module.exports=lodash},{lodash:undefined}],21:[function(require,module,exports){module.exports="1.0.7"},{}]},{},[1]); 32 | -------------------------------------------------------------------------------- /bower_components/lodash/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lodash", 3 | "main": "lodash.js", 4 | "ignore": [ 5 | ".*", 6 | "*.custom.*", 7 | "*.log", 8 | "*.map", 9 | "*.md", 10 | "lodash.src.js", 11 | "component.json", 12 | "package.json", 13 | "doc", 14 | "node_modules", 15 | "perf", 16 | "test", 17 | "vendor" 18 | ], 19 | "homepage": "https://github.com/lodash/lodash", 20 | "version": "3.10.1", 21 | "_release": "3.10.1", 22 | "_resolution": { 23 | "type": "version", 24 | "tag": "3.10.1", 25 | "commit": "ef20b4290cc4fe7551c82a552ea7ffa76548eec8" 26 | }, 27 | "_source": "git://github.com/lodash/lodash.git", 28 | "_target": "^3.10.0", 29 | "_originalSource": "lodash" 30 | } -------------------------------------------------------------------------------- /bower_components/lodash/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012-2015 The Dojo Foundation 2 | Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas, 3 | DocumentCloud and Investigative Reporters & Editors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /bower_components/lodash/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lodash", 3 | "main": "lodash.js", 4 | "ignore": [ 5 | ".*", 6 | "*.custom.*", 7 | "*.log", 8 | "*.map", 9 | "*.md", 10 | "lodash.src.js", 11 | "component.json", 12 | "package.json", 13 | "doc", 14 | "node_modules", 15 | "perf", 16 | "test", 17 | "vendor" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /bulk.jsx: -------------------------------------------------------------------------------- 1 | /* global React,App,ReactModal,_*/ 2 | 3 | App.Bulk = class Bulk extends React.Component { 4 | state = { 5 | inputText: "", 6 | error: null 7 | } 8 | 9 | onOpen = () => { 10 | var inputText = _.map(this.props.inputs, function(input) { 11 | return input.recipe + " " + input.ipm; 12 | }).join("\n"); 13 | this.setState({inputText: inputText}); 14 | } 15 | 16 | onChangeText = (event) => { 17 | this.setState({inputText: event.target.value}); 18 | } 19 | 20 | onImport = () => { 21 | var inputText = this.state.inputText; 22 | var lines = inputText.split(/\n/); 23 | var errorAtLine = null; 24 | var recipes = _.filter(_.map(lines, function(line, index) { 25 | var trimmed = line.trim(); 26 | if (trimmed === "") { 27 | return null; // ignore blank lines 28 | } 29 | var parts = trimmed.split(" "); 30 | if (parts.length != 2) { 31 | errorAtLine = index + 1; 32 | return null; 33 | } 34 | return {recipe: parts[0], ipm: parts[1]}; 35 | })); 36 | if (errorAtLine) { 37 | this.setState({error: "Line " + errorAtLine + ": Input not in valid format"}); 38 | } else { 39 | this.props.onImport(recipes); 40 | } 41 | } 42 | 43 | onRequestClose = (event) => { 44 | event.preventDefault(); 45 | this.props.onRequestClose(); 46 | } 47 | 48 | render() { 49 | 50 | var style = { 51 | content: { 52 | top: "100px", 53 | left: "50%", 54 | right: "auto", 55 | width: "800px", 56 | marginLeft: "-400px" 57 | } 58 | }; 59 | 60 | var error; 61 | if (this.state.error) { 62 | error = (
{this.state.error}
); 63 | } else { 64 | error = null; 65 | } 66 | 67 | var content = ( 68 |
69 |
Bulk import/export
70 |
Enter recipes, one per line, separating the recipe and items per minute with whitespace.
71 |