Ticket #1321: trac_1321-sagenb_graphed.patch
File trac_1321-sagenb_graphed.patch, 193.5 KB (added by , 12 years ago) |
---|
-
new file sagenb/data/graph_editor/graph_editor.html
# HG changeset patch # User Mitesh Patel <qed777@gmail.com> # Date 1259033161 28800 # Node ID 8b5d3cffe0b711a3008e548ec4823f9dd9c4af7d # Parent 96dc9920ce447ee8d235e0faa0301d0ad2349155 #1321/sagenb: A graph editor by Radoslav Kirov diff --git a/sagenb/data/graph_editor/graph_editor.html b/sagenb/data/graph_editor/graph_editor.html new file mode 100644
- + 1 <html> 2 <head> 3 <title>Graph Editor</title> 4 <style type="text/css"> 5 body { 6 font-size: 10pt; 7 } 8 canvas { 9 border: 1px solid; 10 height: 350px; 11 width: 350px; 12 margin: 20px; 13 float: left; 14 } 15 tr.live_slider { 16 height: 1.75em; 17 } 18 div.slider { 19 width : 150px; 20 } 21 #help { 22 display: hidden; 23 } 24 h3 { 25 color: #aa0; 26 margin: 10px; 27 } 28 </style> 29 <script type="text/javascript" src="/javascript/jquery/jquery-1.3.2.min.js"></script> 30 <link rel="stylesheet" href="/javascript/jqueryui/css/sage/jquery-ui-1.7.2.custom.css" /> 31 <script type="text/javascript" src="/javascript/jqueryui/js/jquery-ui-1.7.2.custom.min.js"></script> 32 <script type="text/javascript" src="/javascript/graph_editor/processing.editor.min.js"></script> 33 <script type="text/javascript" src="/javascript/graph_editor/graph_editor.js"></script> 34 </head> 35 <body> 36 <canvas id="canvas"></canvas> 37 <table> 38 <tbody> 39 <tr> 40 <td> 41 live: 42 </td> 43 <td> 44 <input type="checkbox" id="live" value="true" /> 45 </td> 46 </tr> 47 <tr> 48 <td> 49 variable name: 50 </td> 51 <td> 52 <input type="text" id="graph_name" size="20" /> 53 </td> 54 </tr> 55 <tr class="live_slider"> 56 <td> 57 strength: 58 </td> 59 <td> 60 <input type="hidden" id="val_edge" name="val_edge" value="50" /> 61 <div class="slider" id="slider_edge"></div> 62 </td> 63 </tr> 64 <tr class="live_slider"> 65 <td> 66 length: 67 </td> 68 <td> 69 <input type="hidden" id="val_fixed_length" name="val_fixed_length" value="100" /> 70 <div class="slider" id="slider_fixed_length"></div> 71 </td> 72 </tr> 73 </tbody> 74 </table> 75 <input type="button" id="help_button" value="help"> 76 <ul id="help"> 77 <li><h3>move vertex</h3>Vertices are draggable. 78 <li><h3>create vertex</h3>Click on empty space not too close to existing vertices. 79 <li><h3>select a vertex</h3>Click on existing vertex. 80 <li><h3>create/erase edge</h3>Select the first vertex. Click on another vertex (different than the selected one) to turn on/off (toggle) the edge between them. 81 <li><h3>keep the selected vertex</h3>Hold 'SHIFT' to perserve the selected vertex after creating/erasing an edge. 82 <li><h3>delete vertex</h3>Double click on vertex or drag to the edge for the frame (be careful, there is no UNDO yet!). 83 </ul> 84 </body> 85 </html> -
new file sagenb/data/graph_editor/graph_editor.js
diff --git a/sagenb/data/graph_editor/graph_editor.js b/sagenb/data/graph_editor/graph_editor.js new file mode 100644
- + 1 /*global $, document, p: true, Processing, top, window */ 2 /*jslint white: false, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, strict: true, newcap: true, immed: true */ 3 "use strict"; 4 var edge_list = [], nodes = [], NODES, EDGES, SIZE, NEW_RADIUS, 5 DOUBLECLICK, LIVE, SPRING, FIXED_LENGTH, 6 selected_node, dragged_node, dragging_flag, last_click_time, 7 initial_x, initial_y 8 9 var edges = [], num_vertices = null, pos = null; 10 11 NODES = 10; 12 EDGES = 20; 13 SIZE = 350; 14 NEW_RADIUS = 20; 15 DOUBLECLICK = 250; 16 LIVE = false; 17 SPRING = 0.999; 18 FIXED_LENGTH = 100.0; 19 20 function rand(a, b) { 21 return a + Math.floor(Math.random() * (b - a)); 22 } 23 24 function Node(x, y) { 25 this.x = x; 26 this.y = y; 27 this.size = 7; 28 } 29 30 Node.prototype.display = function () { 31 p.stroke(0); 32 if (this.selected) { 33 p.fill(255, 0, 0); 34 p.ellipse(this.x, this.y, this.size, this.size); 35 } else { 36 p.fill(0); 37 p.ellipse(this.x, this.y, this.size, this.size); 38 } 39 }; 40 41 Node.prototype.distance_to = function (x, y) { 42 return Math.sqrt(Math.pow((x - this.x), 2) + Math.pow((y - this.y), 2)); 43 }; 44 45 Node.prototype.is_hit = function (x, y) { 46 return Math.abs(x - this.x) < this.size && 47 Math.abs(y - this.y) < this.size; 48 }; 49 50 function Edge(node1, node2) { 51 this.node1 = node1; 52 this.node2 = node2; 53 } 54 55 Edge.prototype.shrink = function () { 56 var d, gx, gy, mx, my; 57 58 mx = (this.node1.x + this.node2.x) / 2; 59 my = (this.node1.y + this.node2.y) / 2; 60 61 if (this.node1 !== dragged_node) { 62 d = this.node1.distance_to(mx, my); 63 gx = mx + (this.node1.x - mx) / d * FIXED_LENGTH / 2; 64 gy = my + (this.node1.y - my) / d * FIXED_LENGTH / 2; 65 this.node1.x = gx + (this.node1.x - gx) * SPRING; 66 this.node1.y = gy + (this.node1.y - gy) * SPRING; 67 } 68 if (this.node2 !== dragged_node) { 69 d = this.node2.distance_to(mx, my); 70 gx = mx + (this.node2.x - mx) / d * FIXED_LENGTH / 2; 71 gy = my + (this.node2.y - my) / d * FIXED_LENGTH / 2; 72 this.node2.x = gx + (this.node2.x - gx) * SPRING; 73 this.node2.y = gy + (this.node2.y - gy) * SPRING; 74 } 75 }; 76 77 Edge.prototype.display = function () { 78 if (this.node1.x > SIZE || this.node1.y > SIZE || 79 this.node1.x < 0 || this.node1.y < 0 || 80 this.node2.x > SIZE || this.node2.y > SIZE || 81 this.node2.x < 0 || this.node2.y < 0) { 82 p.stroke(255, 0, 0); 83 } else { 84 if (this.node1.selected || this.node2.selected) { 85 p.stroke(0, 0, 200); 86 } else { 87 p.stroke(0); 88 } 89 } 90 p.line(this.node1.x, this.node1.y, this.node2.x, this.node2.y); 91 }; 92 93 function add_node(node) { 94 if (nodes.indexOf(node) === -1) { 95 nodes.push(node); 96 } 97 } 98 99 function remove_node(node) { 100 var edge, i, index; 101 for (i = edge_list.length - 1; i > -1; i -= 1) { 102 edge = edge_list[i]; 103 if (edge.node1 === node || edge.node2 === node) { 104 edge_list.splice(i, 1); 105 } 106 } 107 index = nodes.indexOf(node); 108 if (index !== -1) { 109 nodes.splice(index, 1); 110 } 111 } 112 113 function add_edge_between_nodes(node1, node2) { 114 if (node1 === node2) { 115 // Only simple graphs are implemented so far. 116 return; 117 } 118 edge_list.push(new Edge(node1, node2)); 119 if (nodes.indexOf(node1) === -1) { 120 nodes.add(node1); 121 } 122 if (nodes.indexOf(node2) === -1) { 123 nodes.add(node2); 124 } 125 } 126 127 function toggle_edge(node1, node2) { 128 var edge, existing = false, i, new_edge; 129 if (node1 === node2) { 130 // Only simple graphs are implemented so far. 131 return; 132 } 133 new_edge = new Edge(node1, node2); 134 for (i = edge_list.length - 1; i > -1; i -= 1) { 135 edge = edge_list[i]; 136 if ((edge.node1 === new_edge.node1 && edge.node2 === new_edge.node2) || 137 (edge.node1 === new_edge.node2 && edge.node2 === new_edge.node1)) { 138 existing = true; 139 break; 140 } 141 } 142 if (existing) { 143 edge_list.splice(i, 1); 144 } else { 145 edge_list.push(new_edge); 146 } 147 } 148 149 function set_graph() { 150 var i, n1, n2; 151 152 if (!pos) { 153 for (i = 0; i < NODES; i += 1) { 154 add_node(new Node(rand(0, SIZE), rand(0, SIZE))); 155 } 156 for (i = 0; i < EDGES; i += 1) { 157 n1 = rand(0, NODES); 158 n2 = rand(0, NODES); 159 add_edge_between_nodes(nodes[n1], nodes[n2]); 160 } 161 } 162 for (i = 0; i < num_vertices; i += 1) { 163 if (pos) { 164 add_node(new Node(pos[i][0] * 8 * SIZE / 10 + SIZE / 10, 165 pos[i][1] * 8 * SIZE / 10 + SIZE / 10)); 166 } else { 167 add_node(new Node(rand(0, SIZE), rand(0, SIZE))); 168 } 169 } 170 for (i = 0; i < edges.length; i += 1) { 171 add_edge_between_nodes(nodes[edges[i][0]], nodes[edges[i][1]]); 172 } 173 p.draw(); 174 } 175 176 function display_graph() { 177 var i; 178 for (i = 0; i < edge_list.length; i += 1) { 179 edge_list[i].display(); 180 if (LIVE) { 181 edge_list[i].shrink(); 182 } 183 } 184 for (i = 0; i < nodes.length; i += 1) { 185 nodes[i].display(); 186 } 187 } 188 189 function setup() { 190 p.size(SIZE, SIZE); 191 set_graph(); 192 p.rectMode(p.RADIUS); 193 p.ellipseMode(p.RADIUS); 194 p.noLoop(); 195 } 196 197 function update_sliders() { 198 SPRING = (1 - 1e-2) + 1e-4 * (100 - $('#val_edge').val()); 199 FIXED_LENGTH = $('#val_fixed_length').val(); 200 } 201 202 function draw() { 203 update_sliders(); 204 p.background(255); 205 display_graph(); 206 } 207 208 function toggle_live() { 209 if (LIVE) { 210 LIVE = false; 211 p.noLoop(); 212 } else { 213 LIVE = true; 214 p.loop(); 215 } 216 } 217 218 function mousePressed() { 219 var clicked_node, closest_distance, i, new_distance; 220 if (!LIVE) { 221 p.loop(); 222 } 223 for (i = 0; i < nodes.length; i += 1) { 224 if (nodes[i].is_hit(p.mouseX, p.mouseY)) { 225 clicked_node = nodes[i]; 226 break; 227 } 228 } 229 if (!clicked_node) { 230 closest_distance = SIZE; 231 for (i = 0; i < nodes.length; i += 1) { 232 new_distance = nodes[i].distance_to(p.mouseX, p.mouseY); 233 if (new_distance < closest_distance) { 234 closest_distance = new_distance; 235 } 236 } 237 if (closest_distance > NEW_RADIUS) { 238 add_node(new Node(p.mouseX, p.mouseY)); 239 } 240 return; 241 } else { 242 dragged_node = clicked_node; 243 initial_x = dragged_node.x; 244 initial_y = dragged_node.y; 245 } 246 } 247 248 function mouseDragged() { 249 if (dragged_node) { 250 dragging_flag = true; 251 dragged_node.x = p.mouseX; 252 dragged_node.y = p.mouseY; 253 } 254 } 255 256 function mouseReleased() { 257 if (dragged_node) { 258 if (dragging_flag) { 259 dragging_flag = false; 260 if (dragged_node.x > SIZE || dragged_node.y > SIZE || 261 dragged_node.x < 0 || dragged_node.y < 0) { 262 remove_node(dragged_node); 263 if (selected_node === dragged_node) { 264 selected_node = false; 265 } 266 dragged_node = false; 267 } 268 } else { 269 if (p.millis() - last_click_time < DOUBLECLICK) { 270 remove_node(dragged_node); 271 if (selected_node === dragged_node) { 272 selected_node = false; 273 } 274 } else if (selected_node) { 275 toggle_edge(selected_node, dragged_node); 276 if (!p.keyPressed) { 277 selected_node.selected = false; 278 selected_node = false; 279 } else { 280 if (selected_node === dragged_node) { 281 selected_node.selected = false; 282 selected_node = false; 283 } 284 } 285 } else { 286 selected_node = dragged_node; 287 selected_node.selected = true; 288 } 289 } 290 dragged_node = false; 291 last_click_time = p.millis(); 292 p.redraw(); 293 } 294 if (!LIVE) { 295 p.noLoop(); 296 } 297 } 298 299 function mouse_out() { 300 if (dragged_node) { 301 dragged_node.x = initial_x; 302 dragged_node.y = initial_y; 303 dragged_node = false; 304 } 305 } 306 307 function positions_dict() { 308 var i, out; 309 out = "{"; 310 for (i = 0; i < nodes.length; i += 1) { 311 out += i + ":[" + nodes[i].x + "," + (SIZE - nodes[i].y) + "],"; 312 } 313 return out.substring(0, out.length - 1) + "}"; 314 } 315 316 function adjacency_lists_dict() { 317 var edge, empty, i, j, node, out; 318 out = "{"; 319 for (i = 0; i < nodes.length; i += 1) { 320 out += i + ":["; 321 node = nodes[i]; 322 empty = true; 323 for (j = 0; j < edge_list.length; j += 1) { 324 edge = edge_list[j]; 325 if (edge.node1 === node) { 326 if (!empty) { 327 out += ","; 328 } 329 empty = false; 330 out += nodes.indexOf(edge.node2); 331 } 332 if (edge.node2 === node) { 333 if (!empty) { 334 out+=","; 335 } 336 empty = false; 337 out += nodes.indexOf(edge.node1); 338 } 339 } 340 out += "],"; 341 } 342 return out.substring(0, out.length - 1) + "}"; 343 } 344 345 function update_sage() { 346 return [adjacency_lists_dict(), positions_dict(), $('#graph_name').val()]; 347 } 348 349 350 $(document).ready(function () { 351 var cell_id, cell_outer, loc; 352 353 // Retrieve graph data and name from parent document. 354 loc = window.location.href; 355 cell_id = parseInt(loc.slice(loc.search('cell_id=') + 8), 10); 356 cell_outer = $('#cell_outer_' + cell_id, top.document); 357 eval($('#graph_data_' + cell_id, cell_outer).val()); 358 $('#graph_name').val($('#graph_name_' + cell_id, cell_outer).val()); 359 360 // Set up processing.js. 361 p = Processing($('#canvas')[0], ''); 362 p.setup = setup; 363 p.draw = draw; 364 p.mouseDragged = mouseDragged; 365 p.mousePressed = mousePressed; 366 p.mouseReleased = mouseReleased; 367 p.init(); 368 369 $('#help').hide(); 370 371 $('#help_button').click(function () { 372 $('#help').toggle(); 373 }); 374 375 $('#live').click(function() { 376 toggle_live(); 377 }); 378 379 $('#slider_edge').slider({ 380 min: 0, 381 max: 100, 382 value: 50, 383 slide: function(event, ui) { 384 $('#val_edge').val(ui.value); 385 } 386 }); 387 388 $('#slider_fixed_length').slider({ 389 min: 0, 390 max: 200, 391 value: 100, 392 slide: function(event, ui) { 393 $('#val_fixed_length').val(ui.value); 394 } 395 }); 396 }); -
new file sagenb/data/graph_editor/processing.editor.js
diff --git a/sagenb/data/graph_editor/processing.editor.js b/sagenb/data/graph_editor/processing.editor.js new file mode 100644
- + 1 (function() { 2 this.Processing = function Processing(aElement, aCode) { 3 if (typeof aElement == "string") aElement = document.getElementById(aElement); 4 var p = buildProcessing(aElement); 5 if (aCode) p.init(aCode); 6 return p; 7 }; 8 9 function log() { 10 try { 11 console.log.apply(console, arguments); 12 } catch(e) { 13 try { 14 opera.postError.apply(opera, arguments); 15 } catch(e) {} 16 } 17 } 18 var parse = Processing.parse = function parse(aCode, p) { 19 aCode = aCode.replace(/\/\/ .*\n/g, "\n"); 20 aCode = aCode.replace(/([^\s])%([^\s])/g, "$1 % $2"); 21 aCode = aCode.replace(/(?:static )?(\w+ )(\w+)\s*(\([^\)]*\)\s*{)/g, function(all, type, name, args) { 22 if (name == "if" || name == "for" || name == "while") { 23 return all; 24 } else { 25 return "Processing." + name + " = function " + name + args; 26 } 27 }); 28 aCode = aCode.replace(/\.length\(\)/g, ".length"); 29 aCode = aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4"); 30 aCode = aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4"); 31 aCode = aCode.replace(/new (\w+)((?:\[([^\]]*)\])+)/g, function(all, name, args) { 32 return "new ArrayList(" + args.slice(1, -1).split("][").join(", ") + ")"; 33 }); 34 aCode = aCode.replace(/(?:static )?\w+\[\]\s*(\w+)\[?\]?\s*=\s*{.*?};/g, function(all) { 35 return all.replace(/{/g, "[").replace(/}/g, "]"); 36 }); 37 var intFloat = /(\n\s*(?:int|float)(?:\[\])?(?:\s*|[^\(]*?,\s*))([a-z]\w*)(;|,)/i; 38 while (intFloat.test(aCode)) { 39 aCode = aCode.replace(new RegExp(intFloat), function(all, type, name, sep) { 40 return type + " " + name + " = 0" + sep; 41 }); 42 } 43 aCode = aCode.replace(/(?:static )?(\w+)((?:\[\])+| ) *(\w+)\[?\]?(\s*[=,;])/g, function(all, type, arr, name, sep) { 44 if (type == "return") return all; 45 else return "var " + name + sep; 46 }); 47 aCode = aCode.replace(/=\s*{((.|\s)*?)};/g, function(all, data) { 48 return "= [" + data.replace(/{/g, "[").replace(/}/g, "]") + "]"; 49 }); 50 aCode = aCode.replace(/static\s*{((.|\n)*?)}/g, function(all, init) { 51 return init; 52 }); 53 aCode = aCode.replace(/super\(/g, "superMethod("); 54 var classes = ["int", "float", "boolean", "string"]; 55 56 function ClassReplace(all, name, extend, vars, last) { 57 classes.push(name); 58 var static = ""; 59 vars = vars.replace(/final\s+var\s+(\w+\s*=\s*.*?;)/g, function(all, set) { 60 static += " " + name + "." + set; 61 return ""; 62 }); 63 return "function " + name + "() {with(this){\n " + (extend ? "var __self=this;function superMethod(){extendClass(__self,arguments," + extend + ");}\n" : "") + vars.replace(/,\s?/g, ";\n this.").replace(/\b(var |final |public )+\s*/g, "this.").replace(/this.(\w+);/g, "this.$1 = null;") + (extend ? "extendClass(this, " + extend + ");\n" : "") + "<CLASS " + name + " " + static + ">" + (typeof last == "string" ? last : name + "("); 64 } 65 var matchClasses = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)\b\1\s*\(/g; 66 var matchNoCon = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)(Processing)/g; 67 aCode = aCode.replace(matchClasses, ClassReplace); 68 aCode = aCode.replace(matchNoCon, ClassReplace); 69 var matchClass = /<CLASS (\w+) (.*?)>/, 70 m; 71 while ((m = aCode.match(matchClass))) { 72 var left = RegExp.leftContext, 73 allRest = RegExp.rightContext, 74 rest = nextBrace(allRest), 75 className = m[1], 76 staticVars = m[2] || ""; 77 allRest = allRest.slice(rest.length + 1); 78 rest = rest.replace(new RegExp("\\b" + className + "\\(([^\\)]*?)\\)\\s*{", "g"), function(all, args) { 79 args = args.split(/,\s*?/); 80 if (args[0].match(/^\s*$/)) args.shift(); 81 var fn = "if ( arguments.length == " + args.length + " ) {\n"; 82 for (var i = 0; i < args.length; i++) { 83 fn += " var " + args[i] + " = arguments[" + i + "];\n"; 84 } 85 return fn; 86 }); 87 rest = rest.replace(/(?:public )?Processing.\w+ = function (\w+)\((.*?)\)/g, function(all, name, args) { 88 return "ADDMETHOD(this, '" + name + "', function(" + args + ")"; 89 }); 90 var matchMethod = /ADDMETHOD([\s\S]*?{)/, 91 mc; 92 var methods = ""; 93 while ((mc = rest.match(matchMethod))) { 94 var prev = RegExp.leftContext, 95 allNext = RegExp.rightContext, 96 next = nextBrace(allNext); 97 methods += "addMethod" + mc[1] + next + "});" 98 rest = prev + allNext.slice(next.length + 1); 99 } 100 rest = methods + rest; 101 aCode = left + rest + "\n}}" + staticVars + allRest; 102 } 103 aCode = aCode.replace(/Processing.\w+ = function addMethod/g, "addMethod"); 104 105 function nextBrace(right) { 106 var rest = right; 107 var position = 0; 108 var leftCount = 1, 109 rightCount = 0; 110 while (leftCount != rightCount) { 111 var nextLeft = rest.indexOf("{"); 112 var nextRight = rest.indexOf("}"); 113 if (nextLeft < nextRight && nextLeft != -1) { 114 leftCount++; 115 rest = rest.slice(nextLeft + 1); 116 position += nextLeft + 1; 117 } else { 118 rightCount++; 119 rest = rest.slice(nextRight + 1); 120 position += nextRight + 1; 121 } 122 } 123 return right.slice(0, position - 1); 124 } 125 aCode = aCode.replace(/\(int\)/g, "0|"); 126 aCode = aCode.replace(new RegExp("\\((" + classes.join("|") + ")(\\[\\])?\\)", "g"), ""); 127 aCode = aCode.replace(/(\d+)f/g, "$1"); 128 aCode = aCode.replace(/('[a-zA-Z0-9]')/g, "$1.charCodeAt(0)"); 129 aCode = aCode.replace(/#([a-f0-9]{6})/ig, function(m, hex) { 130 var num = toNumbers(hex); 131 return "color(" + num[0] + "," + num[1] + "," + num[2] + ")"; 132 }); 133 134 function toNumbers(str) { 135 var ret = []; 136 str.replace(/(..)/g, function(str) { 137 ret.push(parseInt(str, 16)); 138 }); 139 return ret; 140 } 141 return aCode; 142 }; 143 144 function buildProcessing(curElement) { 145 var p = {}; 146 p.PI = Math.PI; 147 p.TWO_PI = 2 * p.PI; 148 p.HALF_PI = p.PI / 2; 149 p.P3D = 3; 150 p.CORNER = 0; 151 p.RADIUS = 1; 152 p.CENTER_RADIUS = 1; 153 p.CENTER = 2; 154 p.POLYGON = 2; 155 p.QUADS = 5; 156 p.TRIANGLES = 6; 157 p.POINTS = 7; 158 p.LINES = 8; 159 p.TRIANGLE_STRIP = 9; 160 p.TRIANGLE_FAN = 4; 161 p.QUAD_STRIP = 3; 162 p.CORNERS = 10; 163 p.CLOSE = true; 164 p.RGB = 1; 165 p.HSB = 2; 166 p.CENTER = 88888880; 167 p.CODED = 88888888; 168 p.UP = 88888870; 169 p.RIGHT = 88888871; 170 p.DOWN = 88888872; 171 p.LEFT = 88888869; 172 p.codedKeys = [69, 70, 71, 72]; 173 var curContext = curElement.getContext("2d"); 174 var doFill = true; 175 var doStroke = true; 176 var loopStarted = false; 177 var hasBackground = false; 178 var doLoop = true; 179 var looping = 0; 180 var curRectMode = p.CORNER; 181 var curEllipseMode = p.CENTER; 182 var inSetup = false; 183 var inDraw = false; 184 var curBackground = "rgba(204,204,204,1)"; 185 var curFrameRate = 1000; 186 var curShape = p.POLYGON; 187 var curShapeCount = 0; 188 var curvePoints = []; 189 var curTightness = 0; 190 var opacityRange = 255; 191 var redRange = 255; 192 var greenRange = 255; 193 var blueRange = 255; 194 var pathOpen = false; 195 var mousePressed = false; 196 var keyPressed = false; 197 var firstX, firstY, secondX, secondY, prevX, prevY; 198 var curColorMode = p.RGB; 199 var curTint = -1; 200 var curTextSize = 12; 201 var curTextFont = "Arial"; 202 var getLoaded = false; 203 var start = (new Date).getTime(); 204 p.pmouseX = 0; 205 p.pmouseY = 0; 206 p.mouseX = 0; 207 p.mouseY = 0; 208 p.mouseButton = 0; 209 p.mouseDragged = undefined; 210 p.mouseMoved = undefined; 211 p.mousePressed = undefined; 212 p.mouseReleased = undefined; 213 p.keyPressed = undefined; 214 p.keyReleased = undefined; 215 p.draw = undefined; 216 p.setup = undefined; 217 p.width = curElement.width - 0; 218 p.height = curElement.height - 0; 219 p.frameCount = 0; 220 p.ajax = function(url) { 221 if (window.XMLHttpRequest) { 222 AJAX = new XMLHttpRequest(); 223 } else { 224 AJAX = new ActiveXObject("Microsoft.XMLHTTP"); 225 } 226 if (AJAX) { 227 AJAX.open("GET", url, false); 228 AJAX.send(null); 229 return AJAX.responseText; 230 } else { 231 return false; 232 } 233 } 234 p.loadStrings = function loadStrings(url) { 235 return p.ajax(url).split("\n"); 236 }; 237 p.color = function color(aValue1, aValue2, aValue3, aValue4) { 238 var aColor = ""; 239 if (arguments.length == 3) { 240 aColor = p.color(aValue1, aValue2, aValue3, opacityRange); 241 } else if (arguments.length == 4) { 242 var a = aValue4 / opacityRange; 243 a = isNaN(a) ? 1 : a; 244 if (curColorMode == p.HSB) { 245 var rgb = HSBtoRGB(aValue1, aValue2, aValue3); 246 var r = rgb[0], 247 g = rgb[1], 248 b = rgb[2]; 249 } else { 250 var r = getColor(aValue1, redRange); 251 var g = getColor(aValue2, greenRange); 252 var b = getColor(aValue3, blueRange); 253 } 254 aColor = "rgba(" + r + "," + g + "," + b + "," + a + ")"; 255 } else if (typeof aValue1 == "string") { 256 aColor = aValue1; 257 if (arguments.length == 2) { 258 var c = aColor.split(","); 259 c[3] = (aValue2 / opacityRange) + ")"; 260 aColor = c.join(","); 261 } 262 } else if (arguments.length == 2) { 263 aColor = p.color(aValue1, aValue1, aValue1, aValue2); 264 } else if (typeof aValue1 == "number") { 265 aColor = p.color(aValue1, aValue1, aValue1, opacityRange); 266 } else { 267 aColor = p.color(redRange, greenRange, blueRange, opacityRange); 268 } 269 270 function HSBtoRGB(h, s, b) { 271 h = (h / redRange) * 100; 272 s = (s / greenRange) * 100; 273 b = (b / blueRange) * 100; 274 if (s == 0) { 275 return [b, b, b]; 276 } else { 277 var hue = h % 360; 278 var f = hue % 60; 279 var br = Math.round(b / 100 * 255); 280 var p = Math.round((b * (100 - s)) / 10000 * 255); 281 var q = Math.round((b * (6000 - s * f)) / 600000 * 255); 282 var t = Math.round((b * (6000 - s * (60 - f))) / 600000 * 255); 283 switch (Math.floor(hue / 60)) { 284 case 0: 285 return [br, t, p]; 286 case 1: 287 return [q, br, p]; 288 case 2: 289 return [p, br, t]; 290 case 3: 291 return [p, q, br]; 292 case 4: 293 return [t, p, br]; 294 case 5: 295 return [br, p, q]; 296 } 297 } 298 } 299 300 function getColor(aValue, range) { 301 return Math.round(255 * (aValue / range)); 302 } 303 return aColor; 304 } 305 p.red = function(aColor) { 306 return parseInt(verifyChannel(aColor).slice(5)); 307 }; 308 p.green = function(aColor) { 309 return parseInt(verifyChannel(aColor).split(",")[1]); 310 }; 311 p.blue = function(aColor) { 312 return parseInt(verifyChannel(aColor).split(",")[2]); 313 }; 314 p.alpha = function(aColor) { 315 return parseInt(parseFloat(verifyChannel(aColor).split(",")[3]) * 255); 316 }; 317 318 function verifyChannel(aColor) { 319 if (aColor.constructor == Array) { 320 return aColor; 321 } else { 322 return p.color(aColor); 323 } 324 } 325 p.lerpColor = function lerpColor(c1, c2, amt) { 326 var colors1 = p.color(c1).split(","); 327 var r1 = parseInt(colors1[0].split("(")[1]); 328 var g1 = parseInt(colors1[1]); 329 var b1 = parseInt(colors1[2]); 330 var a1 = parseFloat(colors1[3].split(")")[0]); 331 var colors2 = p.color(c2).split(","); 332 var r2 = parseInt(colors2[0].split("(")[1]); 333 var g2 = parseInt(colors2[1]); 334 var b2 = parseInt(colors2[2]); 335 var a2 = parseFloat(colors2[3].split(")")[0]); 336 var r = parseInt(p.lerp(r1, r2, amt)); 337 var g = parseInt(p.lerp(g1, g2, amt)); 338 var b = parseInt(p.lerp(b1, b2, amt)); 339 var a = parseFloat(p.lerp(a1, a2, amt)); 340 aColor = "rgba(" + r + "," + g + "," + b + "," + a + ")"; 341 return aColor; 342 } 343 p.nf = function(num, pad) { 344 var str = "" + num; 345 while (pad - str.length) str = "0" + str; 346 return str; 347 }; 348 p.AniSprite = function(prefix, frames) { 349 this.images = []; 350 this.pos = 0; 351 for (var i = 0; i < frames; i++) { 352 this.images.push(prefix + p.nf(i, ("" + frames).length) + ".gif"); 353 } 354 this.display = function(x, y) { 355 p.image(this.images[this.pos], x, y); 356 if (++this.pos >= frames) this.pos = 0; 357 }; 358 this.getWidth = function() { 359 return getImage(this.images[0]).width; 360 }; 361 this.getHeight = function() { 362 return getImage(this.images[0]).height; 363 }; 364 }; 365 366 function buildImageObject(obj) { 367 var pixels = obj.data; 368 var data = p.createImage(obj.width, obj.height); 369 if (data.__defineGetter__ && data.__lookupGetter__ && !data.__lookupGetter__("pixels")) { 370 var pixelsDone; 371 data.__defineGetter__("pixels", function() { 372 if (pixelsDone) return pixelsDone; 373 pixelsDone = []; 374 for (var i = 0; i < pixels.length; i += 4) { 375 pixelsDone.push(p.color(pixels[i], pixels[i + 1], pixels[i + 2], pixels[i + 3])); 376 } 377 return pixelsDone; 378 }); 379 } else { 380 data.pixels = []; 381 for (var i = 0; i < pixels.length; i += 4) { 382 data.pixels.push(p.color(pixels[i], pixels[i + 1], pixels[i + 2], pixels[i + 3])); 383 } 384 } 385 return data; 386 } 387 p.createImage = function createImage(w, h, mode) { 388 var data = {}; 389 data.width = w; 390 data.height = h; 391 data.data = []; 392 if (curContext.createImageData) { 393 data = curContext.createImageData(w, h); 394 } 395 data.pixels = new Array(w * h); 396 data.get = function(x, y) { 397 return this.pixels[w * y + x]; 398 }; 399 data._mask = null; 400 data.mask = function(img) { 401 this._mask = img; 402 }; 403 data.loadPixels = function() {}; 404 data.updatePixels = function() {}; 405 return data; 406 }; 407 p.createGraphics = function createGraphics(w, h) { 408 var canvas = document.createElement("canvas"); 409 var ret = buildProcessing(canvas); 410 ret.size(w, h); 411 ret.canvas = canvas; 412 return ret; 413 }; 414 p.beginDraw = function beginDraw() {}; 415 p.endDraw = function endDraw() {}; 416 p.tint = function tint(rgb, a) { 417 curTint = a; 418 }; 419 420 function getImage(img) { 421 if (typeof img == "string") { 422 return document.getElementById(img); 423 } 424 if (img.img || img.canvas) { 425 return img.img || img.canvas; 426 } 427 for (var i = 0, l = img.pixels.length; i < l; i++) { 428 var pos = i * 4; 429 var c = (img.pixels[i] || "rgba(0,0,0,1)").slice(5, -1).split(","); 430 img.data[pos] = parseInt(c[0]); 431 img.data[pos + 1] = parseInt(c[1]); 432 img.data[pos + 2] = parseInt(c[2]); 433 img.data[pos + 3] = parseFloat(c[3]) * 100; 434 } 435 var canvas = document.createElement("canvas") canvas.width = img.width; 436 canvas.height = img.height; 437 var context = canvas.getContext("2d"); 438 context.putImageData(img, 0, 0); 439 img.canvas = canvas; 440 return canvas; 441 } 442 p.image = function image(img, x, y, w, h) { 443 x = x || 0; 444 y = y || 0; 445 var obj = getImage(img); 446 if (curTint >= 0) { 447 var oldAlpha = curContext.globalAlpha; 448 curContext.globalAlpha = curTint / opacityRange; 449 } 450 if (arguments.length == 3) { 451 curContext.drawImage(obj, x, y); 452 } else { 453 curContext.drawImage(obj, x, y, w, h); 454 } 455 if (curTint >= 0) { 456 curContext.globalAlpha = oldAlpha; 457 } 458 if (img._mask) { 459 var oldComposite = curContext.globalCompositeOperation; 460 curContext.globalCompositeOperation = "darker"; 461 p.image(img._mask, x, y); 462 curContext.globalCompositeOperation = oldComposite; 463 } 464 }; 465 p.exit = function exit() { 466 clearInterval(looping); 467 }; 468 p.save = function save(file) {}; 469 p.loadImage = function loadImage(file) { 470 var img = document.getElementById(file); 471 if (!img) return; 472 var h = img.height, 473 w = img.width; 474 var canvas = document.createElement("canvas"); 475 canvas.width = w; 476 canvas.height = h; 477 var context = canvas.getContext("2d"); 478 context.drawImage(img, 0, 0); 479 var data = buildImageObject(context.getImageData(0, 0, w, h)); 480 data.img = img; 481 return data; 482 }; 483 p.loadFont = function loadFont(name) { 484 return { 485 name: name, 486 width: function(str) { 487 if (curContext.mozMeasureText) return curContext.mozMeasureText(typeof str == "number" ? String.fromCharCode(str) : str) / curTextSize; 488 else return 0; 489 } 490 }; 491 }; 492 p.textFont = function textFont(name, size) { 493 curTextFont = name; 494 p.textSize(size); 495 }; 496 p.textSize = function textSize(size) { 497 if (size) { 498 curTextSize = size; 499 } 500 }; 501 p.textAlign = function textAlign() {}; 502 p.text = function text(str, x, y) { 503 if (str && curContext.mozDrawText) { 504 curContext.save(); 505 curContext.mozTextStyle = curTextSize + "px " + curTextFont.name; 506 curContext.translate(x, y); 507 curContext.mozDrawText(typeof str == "number" ? String.fromCharCode(str) : str); 508 curContext.restore(); 509 } 510 }; 511 p.print = function print(output) { 512 alert(output); 513 } 514 p.println = p.print; 515 p.char = function char(key) { 516 return key; 517 }; 518 p.map = function map(value, istart, istop, ostart, ostop) { 519 return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)); 520 }; 521 String.prototype.replaceAll = function(re, replace) { 522 return this.replace(new RegExp(re, "g"), replace); 523 }; 524 p.Point = function Point(x, y) { 525 this.x = x; 526 this.y = y; 527 this.copy = function() { 528 return new Point(x, y); 529 } 530 }; 531 p.Random = function() { 532 var haveNextNextGaussian = false; 533 var nextNextGaussian; 534 this.nextGaussian = function() { 535 if (haveNextNextGaussian) { 536 haveNextNextGaussian = false; 537 return nextNextGaussian; 538 } else { 539 var v1, v2, s; 540 do { 541 v1 = 2 * p.random(1) - 1; 542 v2 = 2 * p.random(1) - 1; 543 s = v1 * v1 + v2 * v2; 544 } while (s >= 1 || s == 0); 545 var multiplier = Math.sqrt(-2 * Math.log(s) / s); 546 nextNextGaussian = v2 * multiplier; 547 haveNextNextGaussian = true; 548 return v1 * multiplier; 549 } 550 }; 551 }; 552 p.ArrayList = function ArrayList(size, size2, size3) { 553 var array = new Array(0 | size); 554 if (size2) { 555 for (var i = 0; i < size; i++) { 556 array[i] = []; 557 for (var j = 0; j < size2; j++) { 558 var a = array[i][j] = size3 ? new Array(size3) : 0; 559 for (var k = 0; k < size3; k++) { 560 a[k] = 0; 561 } 562 } 563 } 564 } else { 565 for (var i = 0; i < size; i++) { 566 array[i] = 0; 567 } 568 } 569 array.size = function() { 570 return this.length; 571 }; 572 array.get = function(i) { 573 return this[i]; 574 }; 575 array.remove = function(i) { 576 return this.splice(i, 1); 577 }; 578 array.add = function(item) { 579 return this.push(item); 580 }; 581 array.clone = function() { 582 var a = new ArrayList(size); 583 for (var i = 0; i < size; i++) { 584 a[i] = this[i]; 585 } 586 return a; 587 }; 588 array.isEmpty = function() { 589 return !this.length; 590 }; 591 array.clear = function() { 592 this.length = 0; 593 }; 594 return array; 595 }; 596 p.colorMode = function colorMode(mode, range1, range2, range3, range4) { 597 curColorMode = mode; 598 if (arguments.length >= 4) { 599 redRange = range1; 600 greenRange = range2; 601 blueRange = range3; 602 } 603 if (arguments.length == 5) { 604 opacityRange = range4; 605 } 606 if (arguments.length == 2) { 607 p.colorMode(mode, range1, range1, range1, range1); 608 } 609 }; 610 p.beginShape = function beginShape(type) { 611 curShape = type; 612 curShapeCount = 0; 613 curvePoints = []; 614 }; 615 p.endShape = function endShape(close) { 616 if (curShapeCount != 0) { 617 if (close || doFill) curContext.lineTo(firstX, firstY); 618 if (doFill) curContext.fill(); 619 if (doStroke) curContext.stroke(); 620 curContext.closePath(); 621 curShapeCount = 0; 622 pathOpen = false; 623 } 624 if (pathOpen) { 625 if (doFill) curContext.fill(); 626 if (doStroke) curContext.stroke(); 627 curContext.closePath(); 628 curShapeCount = 0; 629 pathOpen = false; 630 } 631 }; 632 p.vertex = function vertex(x, y, x2, y2, x3, y3) { 633 if (curShapeCount == 0 && curShape != p.POINTS) { 634 pathOpen = true; 635 curContext.beginPath(); 636 curContext.moveTo(x, y); 637 firstX = x; 638 firstY = y; 639 } else { 640 if (curShape == p.POINTS) { 641 p.point(x, y); 642 } else if (arguments.length == 2) { 643 if (curShape != p.QUAD_STRIP || curShapeCount != 2) curContext.lineTo(x, y); 644 if (curShape == p.TRIANGLE_STRIP) { 645 if (curShapeCount == 2) { 646 p.endShape(p.CLOSE); 647 pathOpen = true; 648 curContext.beginPath(); 649 curContext.moveTo(prevX, prevY); 650 curContext.lineTo(x, y); 651 curShapeCount = 1; 652 } 653 firstX = prevX; 654 firstY = prevY; 655 } 656 if (curShape == p.TRIANGLE_FAN && curShapeCount == 2) { 657 p.endShape(p.CLOSE); 658 pathOpen = true; 659 curContext.beginPath(); 660 curContext.moveTo(firstX, firstY); 661 curContext.lineTo(x, y); 662 curShapeCount = 1; 663 } 664 if (curShape == p.QUAD_STRIP && curShapeCount == 3) { 665 curContext.lineTo(prevX, prevY); 666 p.endShape(p.CLOSE); 667 pathOpen = true; 668 curContext.beginPath(); 669 curContext.moveTo(prevX, prevY); 670 curContext.lineTo(x, y); 671 curShapeCount = 1; 672 } 673 if (curShape == p.QUAD_STRIP) { 674 firstX = secondX; 675 firstY = secondY; 676 secondX = prevX; 677 secondY = prevY; 678 } 679 } else if (arguments.length == 4) { 680 if (curShapeCount > 1) { 681 curContext.moveTo(prevX, prevY); 682 curContext.quadraticCurveTo(firstX, firstY, x, y); 683 curShapeCount = 1; 684 } 685 } else if (arguments.length == 6) { 686 curContext.bezierCurveTo(x, y, x2, y2, x3, y3); 687 } 688 } 689 prevX = x; 690 prevY = y; 691 curShapeCount++; 692 if (curShape == p.LINES && curShapeCount == 2 || (curShape == p.TRIANGLES) && curShapeCount == 3 || (curShape == p.QUADS) && curShapeCount == 4) { 693 p.endShape(p.CLOSE); 694 } 695 }; 696 p.curveVertex = function(x, y, x2, y2) { 697 if (curvePoints.length < 3) { 698 curvePoints.push([x, y]); 699 } else { 700 var b = [], 701 s = 1 - curTightness; 702 curvePoints.push([x, y]); 703 b[0] = [curvePoints[1][0], curvePoints[1][1]]; 704 b[1] = [curvePoints[1][0] + (s * curvePoints[2][0] - s * curvePoints[0][0]) / 6, curvePoints[1][1] + (s * curvePoints[2][1] - s * curvePoints[0][1]) / 6]; 705 b[2] = [curvePoints[2][0] + (s * curvePoints[1][0] - s * curvePoints[3][0]) / 6, curvePoints[2][1] + (s * curvePoints[1][1] - s * curvePoints[3][1]) / 6]; 706 b[3] = [curvePoints[2][0], curvePoints[2][1]]; 707 if (!pathOpen) { 708 p.vertex(b[0][0], b[0][1]); 709 } else { 710 curShapeCount = 1; 711 } 712 p.vertex(b[1][0], b[1][1], b[2][0], b[2][1], b[3][0], b[3][1]); 713 curvePoints.shift(); 714 } 715 }; 716 p.curveTightness = function(tightness) { 717 curTightness = tightness; 718 }; 719 p.bezierVertex = p.vertex; 720 p.rectMode = function rectMode(aRectMode) { 721 curRectMode = aRectMode; 722 }; 723 p.imageMode = function() {}; 724 p.ellipseMode = function ellipseMode(aEllipseMode) { 725 curEllipseMode = aEllipseMode; 726 }; 727 p.dist = function dist(x1, y1, x2, y2) { 728 return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); 729 }; 730 p.year = function year() { 731 return (new Date).getYear() + 1900; 732 }; 733 p.month = function month() { 734 return (new Date).getMonth(); 735 }; 736 p.day = function day() { 737 return (new Date).getDay(); 738 }; 739 p.hour = function hour() { 740 return (new Date).getHours(); 741 }; 742 p.minute = function minute() { 743 return (new Date).getMinutes(); 744 }; 745 p.second = function second() { 746 return (new Date).getSeconds(); 747 }; 748 p.millis = function millis() { 749 return (new Date).getTime() - start; 750 }; 751 p.ortho = function ortho() {}; 752 p.translate = function translate(x, y) { 753 curContext.translate(x, y); 754 }; 755 p.scale = function scale(x, y) { 756 curContext.scale(x, y || x); 757 }; 758 p.rotate = function rotate(aAngle) { 759 curContext.rotate(aAngle); 760 }; 761 p.pushMatrix = function pushMatrix() { 762 curContext.save(); 763 }; 764 p.popMatrix = function popMatrix() { 765 curContext.restore(); 766 }; 767 p.redraw = function redraw() { 768 if (hasBackground) { 769 p.background(); 770 } 771 p.frameCount++; 772 inDraw = true; 773 p.pushMatrix(); 774 p.draw(); 775 p.popMatrix(); 776 inDraw = false; 777 }; 778 p.loop = function loop() { 779 if (loopStarted) return; 780 looping = setInterval(function() { 781 try { 782 if (!p.paused) { 783 p.redraw(); 784 } 785 } catch(e) { 786 clearInterval(looping); 787 throw e; 788 } 789 }, 790 1000 / curFrameRate); 791 loopStarted = true; 792 }; 793 p.frameRate = function frameRate(aRate) { 794 curFrameRate = aRate; 795 }; 796 p.background = function background(img) { 797 if (arguments.length) { 798 if (img && img.img) { 799 curBackground = img; 800 } else { 801 curBackground = p.color.apply(this, arguments); 802 } 803 } 804 if (curBackground.img) { 805 p.image(curBackground, 0, 0); 806 } else { 807 var oldFill = curContext.fillStyle; 808 curContext.fillStyle = curBackground + ""; 809 curContext.fillRect(0, 0, p.width, p.height); 810 curContext.fillStyle = oldFill; 811 } 812 }; 813 p.clear = function clear(x, y, width, height) { 814 arguments.length == 0 ? curContext.clearRect(0, 0, p.width, p.height) : curContext.clearRect(x, y, width, height); 815 } 816 p.str = function str(aNumber) { 817 return aNumber + ''; 818 } 819 p.sq = function sq(aNumber) { 820 return aNumber * aNumber; 821 }; 822 p.sqrt = function sqrt(aNumber) { 823 return Math.sqrt(aNumber); 824 }; 825 p.ngsqrt = function ngsqrt(aNumber) { 826 if (aNumber <= 0) { 827 return Math.sqrt(-aNumber); 828 } else { 829 return Math.sqrt(aNumber); 830 } 831 }; 832 p.int = function int(aNumber) { 833 return Math.floor(aNumber); 834 }; 835 p.min = function min(aNumber, aNumber2) { 836 return Math.min(aNumber, aNumber2); 837 }; 838 p.max = function max(aNumber, aNumber2) { 839 return Math.max(aNumber, aNumber2); 840 }; 841 p.ceil = function ceil(aNumber) { 842 return Math.ceil(aNumber); 843 }; 844 p.round = function round(aNumber) { 845 return Math.round(aNumber); 846 }; 847 p.norm = function norm(aNumber, low, high) { 848 var range = high - low; 849 return ((1 / range) * aNumber) - ((1 / range) * low); 850 }; 851 p.lerp = function lerp(value1, value2, amt) { 852 var range = value2 - value1; 853 return (range * amt) + value1; 854 } 855 p.floor = function floor(aNumber) { 856 return Math.floor(aNumber); 857 }; 858 p.float = function float(aNumber) { 859 return parseFloat(aNumber); 860 }; 861 p.byte = function byte(aNumber) { 862 return aNumber || 0; 863 }; 864 p.random = function random(aMin, aMax) { 865 return arguments.length == 2 ? aMin + (Math.random() * (aMax - aMin)) : Math.random() * aMin; 866 }; 867 p.noise = function(x, y, z) { 868 return arguments.length >= 2 ? PerlinNoise_2D(x, y) : PerlinNoise_2D(x, x); 869 }; 870 871 function Noise(x, y) { 872 var n = x + y * 57; 873 n = (n << 13) ^ n; 874 return Math.abs(1.0 - (((n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0)); 875 }; 876 877 function SmoothedNoise(x, y) { 878 var corners = (Noise(x - 1, y - 1) + Noise(x + 1, y - 1) + Noise(x - 1, y + 1) + Noise(x + 1, y + 1)) / 16; 879 var sides = (Noise(x - 1, y) + Noise(x + 1, y) + Noise(x, y - 1) + Noise(x, y + 1)) / 8; 880 var center = Noise(x, y) / 4; 881 return corners + sides + center; 882 }; 883 884 function InterpolatedNoise(x, y) { 885 var integer_X = Math.floor(x); 886 var fractional_X = x - integer_X; 887 var integer_Y = Math.floor(y); 888 var fractional_Y = y - integer_Y; 889 var v1 = SmoothedNoise(integer_X, integer_Y); 890 var v2 = SmoothedNoise(integer_X + 1, integer_Y); 891 var v3 = SmoothedNoise(integer_X, integer_Y + 1); 892 var v4 = SmoothedNoise(integer_X + 1, integer_Y + 1); 893 var i1 = Interpolate(v1, v2, fractional_X); 894 var i2 = Interpolate(v3, v4, fractional_X); 895 return Interpolate(i1, i2, fractional_Y); 896 } 897 898 function PerlinNoise_2D(x, y) { 899 var total = 0; 900 var p = 0.25; 901 var n = 3; 902 for (var i = 0; i <= n; i++) { 903 var frequency = Math.pow(2, i); 904 var amplitude = Math.pow(p, i); 905 total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude; 906 } 907 return total; 908 } 909 910 function Interpolate(a, b, x) { 911 var ft = x * p.PI; 912 var f = (1 - p.cos(ft)) * .5; 913 return a * (1 - f) + b * f; 914 } 915 p.abs = function abs(aNumber) { 916 return Math.abs(aNumber); 917 }; 918 p.cos = function cos(aNumber) { 919 return Math.cos(aNumber); 920 }; 921 p.sin = function sin(aNumber) { 922 return Math.sin(aNumber); 923 }; 924 p.pow = function pow(aNumber, aExponent) { 925 return Math.pow(aNumber, aExponent); 926 }; 927 p.constrain = function constrain(aNumber, aMin, aMax) { 928 return Math.min(Math.max(aNumber, aMin), aMax); 929 }; 930 p.sqrt = function sqrt(aNumber) { 931 return Math.sqrt(aNumber); 932 }; 933 p.atan2 = function atan2(aNumber, aNumber2) { 934 return Math.atan2(aNumber, aNumber2); 935 }; 936 p.radians = function radians(aAngle) { 937 return (aAngle / 180) * p.PI; 938 }; 939 p.degrees = function degrees(aAngle) { 940 aAngle = (aAngle * 180) / p.PI; 941 if (aAngle < 0) { 942 aAngle = 360 + aAngle 943 } 944 return aAngle; 945 }; 946 p.size = function size(aWidth, aHeight) { 947 var fillStyle = curContext.fillStyle; 948 var strokeStyle = curContext.strokeStyle; 949 curElement.width = p.width = aWidth; 950 curElement.height = p.height = aHeight; 951 curContext.fillStyle = fillStyle; 952 curContext.strokeStyle = strokeStyle; 953 }; 954 p.noStroke = function noStroke() { 955 doStroke = false; 956 }; 957 p.noFill = function noFill() { 958 doFill = false; 959 }; 960 p.smooth = function smooth() {}; 961 p.noSmooth = function noSmooth() {}; 962 p.noLoop = function noLoop() { 963 clearInterval(looping); 964 loopStarted = false; 965 doLoop = false; 966 }; 967 p.fill = function fill() { 968 doFill = true; 969 curContext.fillStyle = p.color.apply(this, arguments); 970 }; 971 p.stroke = function stroke() { 972 doStroke = true; 973 curContext.strokeStyle = p.color.apply(this, arguments); 974 }; 975 p.strokeWeight = function strokeWeight(w) { 976 curContext.lineWidth = w; 977 }; 978 p.point = function point(x, y) { 979 var oldFill = curContext.fillStyle; 980 curContext.fillStyle = curContext.strokeStyle; 981 curContext.fillRect(Math.round(x), Math.round(y), 1, 1); 982 curContext.fillStyle = oldFill; 983 }; 984 p.get = function get(x, y) { 985 if (arguments.length == 0) { 986 var c = p.createGraphics(p.width, p.height); 987 c.image(curContext, 0, 0); 988 return c; 989 } 990 if (!getLoaded) { 991 getLoaded = buildImageObject(curContext.getImageData(0, 0, p.width, p.height)); 992 } 993 return getLoaded.get(x, y); 994 }; 995 p.set = function set(x, y, obj) { 996 if (obj && obj.img) { 997 p.image(obj, x, y); 998 } else { 999 var oldFill = curContext.fillStyle; 1000 var color = obj; 1001 curContext.fillStyle = color; 1002 curContext.fillRect(Math.round(x), Math.round(y), 1, 1); 1003 curContext.fillStyle = oldFill; 1004 } 1005 }; 1006 p.arc = function arc(x, y, width, height, start, stop) { 1007 if (width <= 0) return; 1008 if (curEllipseMode == p.CORNER) { 1009 x += width / 2; 1010 y += height / 2; 1011 } 1012 curContext.moveTo(x, y); 1013 curContext.beginPath(); 1014 curContext.arc(x, y, curEllipseMode == p.CENTER_RADIUS ? width : width / 2, start, stop, false); 1015 if (doStroke) curContext.stroke(); 1016 curContext.lineTo(x, y); 1017 if (doFill) curContext.fill(); 1018 curContext.closePath(); 1019 }; 1020 p.line = function line(x1, y1, x2, y2) { 1021 curContext.lineCap = "round"; 1022 curContext.beginPath(); 1023 curContext.moveTo(x1 || 0, y1 || 0); 1024 curContext.lineTo(x2 || 0, y2 || 0); 1025 curContext.stroke(); 1026 curContext.closePath(); 1027 }; 1028 p.bezier = function bezier(x1, y1, x2, y2, x3, y3, x4, y4) { 1029 curContext.lineCap = "butt"; 1030 curContext.beginPath(); 1031 curContext.moveTo(x1, y1); 1032 curContext.bezierCurveTo(x2, y2, x3, y3, x4, y4); 1033 curContext.stroke(); 1034 curContext.closePath(); 1035 }; 1036 p.triangle = function triangle(x1, y1, x2, y2, x3, y3) { 1037 p.beginShape(); 1038 p.vertex(x1, y1); 1039 p.vertex(x2, y2); 1040 p.vertex(x3, y3); 1041 p.endShape(); 1042 }; 1043 p.quad = function quad(x1, y1, x2, y2, x3, y3, x4, y4) { 1044 curContext.lineCap = "square"; 1045 p.beginShape(); 1046 p.vertex(x1, y1); 1047 p.vertex(x2, y2); 1048 p.vertex(x3, y3); 1049 p.vertex(x4, y4); 1050 p.endShape(); 1051 }; 1052 p.rect = function rect(x, y, width, height) { 1053 if (width == 0 && height == 0) return; 1054 curContext.beginPath(); 1055 var offsetStart = 0; 1056 var offsetEnd = 0; 1057 if (curRectMode == p.CORNERS) { 1058 width -= x; 1059 height -= y; 1060 } 1061 if (curRectMode == p.RADIUS) { 1062 width *= 2; 1063 height *= 2; 1064 } 1065 if (curRectMode == p.CENTER || curRectMode == p.RADIUS) { 1066 x -= width / 2; 1067 y -= height / 2; 1068 } 1069 curContext.rect(Math.round(x) - offsetStart, Math.round(y) - offsetStart, Math.round(width) + offsetEnd, Math.round(height) + offsetEnd); 1070 if (doFill) curContext.fill(); 1071 if (doStroke) curContext.stroke(); 1072 curContext.closePath(); 1073 }; 1074 p.ellipse = function ellipse(x, y, width, height) { 1075 x = x || 0; 1076 y = y || 0; 1077 if (width <= 0 && height <= 0) return; 1078 curContext.beginPath(); 1079 if (curEllipseMode == p.RADIUS) { 1080 width *= 2; 1081 height *= 2; 1082 } 1083 var offsetStart = 0; 1084 if (width == height) { 1085 curContext.arc(x - offsetStart, y - offsetStart, width / 2, 0, Math.PI * 2, false); 1086 } else { 1087 var w = width / 2; 1088 var h = height / 2; 1089 var C = 0.5522847498307933; 1090 var c_x = C * w; 1091 var c_y = C * h; 1092 curContext.moveTo(x + w, y); 1093 curContext.bezierCurveTo(x + w, y - c_y, x + c_x, y - h, x, y - h); 1094 curContext.bezierCurveTo(x - c_x, y - h, x - w, y - c_y, x - w, y); 1095 curContext.bezierCurveTo(x - w, y + c_y, x - c_x, y + h, x, y + h); 1096 curContext.bezierCurveTo(x + c_x, y + h, x + w, y + c_y, x + w, y); 1097 } 1098 if (doFill) curContext.fill(); 1099 if (doStroke) curContext.stroke(); 1100 curContext.closePath(); 1101 }; 1102 p.link = function(href, target) { 1103 window.location = href; 1104 }; 1105 p.loadPixels = function() { 1106 p.pixels = buildImageObject(curContext.getImageData(0, 0, p.width, p.height)).pixels; 1107 }; 1108 p.updatePixels = function() { 1109 var colors = /(\d+),(\d+),(\d+),(\d+)/; 1110 var pixels = {}; 1111 pixels.width = p.width; 1112 pixels.height = p.height; 1113 pixels.data = []; 1114 if (curContext.createImageData) { 1115 pixels = curContext.createImageData(p.width, p.height); 1116 } 1117 var data = pixels.data; 1118 var pos = 0; 1119 for (var i = 0, l = p.pixels.length; i < l; i++) { 1120 var c = (p.pixels[i] || "rgba(0,0,0,1)").match(colors); 1121 data[pos] = parseInt(c[1]); 1122 data[pos + 1] = parseInt(c[2]); 1123 data[pos + 2] = parseInt(c[3]); 1124 data[pos + 3] = parseFloat(c[4]) * 255; 1125 pos += 4; 1126 } 1127 curContext.putImageData(pixels, 0, 0); 1128 }; 1129 p.extendClass = function extendClass(obj, args, fn) { 1130 if (arguments.length == 3) { 1131 fn.apply(obj, args); 1132 } else { 1133 args.call(obj); 1134 } 1135 }; 1136 p.addMethod = function addMethod(object, name, fn) { 1137 if (object[name]) { 1138 var args = fn.length; 1139 var oldfn = object[name]; 1140 object[name] = function() { 1141 if (arguments.length == args) return fn.apply(this, arguments); 1142 else return oldfn.apply(this, arguments); 1143 }; 1144 } else { 1145 object[name] = fn; 1146 } 1147 }; 1148 p.init = function init(code) { 1149 p.stroke(0); 1150 p.fill(255); 1151 curContext.translate(0.5, 0.5); 1152 if (code) { 1153 (function(Processing) { 1154 with(p) { 1155 eval(parse(code, p)); 1156 } 1157 })(p); 1158 } 1159 if (p.setup) { 1160 inSetup = true; 1161 p.setup(); 1162 } 1163 inSetup = false; 1164 if (p.draw) { 1165 if (!doLoop) { 1166 p.redraw(); 1167 } else { 1168 p.loop(); 1169 } 1170 } 1171 attach(document, "mousemove", function(e) { 1172 var scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset; 1173 var scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset; 1174 p.pmouseX = p.mouseX; 1175 p.pmouseY = p.mouseY; 1176 p.mouseX = e.clientX - curElement.offsetLeft + scrollX; 1177 p.mouseY = e.clientY - curElement.offsetTop + scrollY; 1178 if (p.mouseMoved) { 1179 p.mouseMoved(); 1180 } 1181 if (mousePressed && p.mouseDragged) { 1182 p.mouseDragged(); 1183 } 1184 }); 1185 attach(curElement, "mousedown", function(e) { 1186 mousePressed = true; 1187 switch (e.which) { 1188 case 1: 1189 p.mouseButton = p.LEFT; 1190 break; 1191 case 2: 1192 p.mouseButton = p.CENTER; 1193 break; 1194 case 3: 1195 p.mouseButton = p.RIGHT; 1196 break; 1197 } 1198 if (typeof p.mousePressed == "function") { 1199 p.mousePressed(); 1200 } else { 1201 p.mousePressed = true; 1202 } 1203 }); 1204 attach(curElement, "contextmenu", function(e) { 1205 e.preventDefault(); 1206 e.stopPropagation(); 1207 }); 1208 attach(document, "mouseup", function(e) { 1209 mousePressed = false; 1210 if (typeof p.mousePressed != "function") { 1211 p.mousePressed = false; 1212 } 1213 if (p.mouseReleased) { 1214 p.mouseReleased(); 1215 } 1216 }); 1217 attach(document, "keydown", function(e) { 1218 keyPressed = true; 1219 p.key = e.keyCode + 32; 1220 var i; 1221 for (i = 0; i < p.codedKeys.length; i++) { 1222 if (p.key == p.codedKeys[i]) { 1223 switch (p.key) { 1224 case 70: 1225 p.keyCode = p.UP; 1226 break; 1227 case 71: 1228 p.keyCode = p.RIGHT; 1229 break; 1230 case 72: 1231 p.keyCode = p.DOWN; 1232 break; 1233 case 69: 1234 p.keyCode = p.LEFT; 1235 break; 1236 } 1237 p.key = p.CODED; 1238 } 1239 } 1240 if (e.shiftKey) { 1241 p.key = String.fromCharCode(p.key).toUpperCase().charCodeAt(0); 1242 } 1243 if (typeof p.keyPressed == "function") { 1244 p.keyPressed(); 1245 } else { 1246 p.keyPressed = true; 1247 } 1248 }); 1249 attach(document, "keyup", function(e) { 1250 keyPressed = false; 1251 if (typeof p.keyPressed != "function") { 1252 p.keyPressed = false; 1253 } 1254 if (p.keyReleased) { 1255 p.keyReleased(); 1256 } 1257 }); 1258 1259 function attach(elem, type, fn) { 1260 if (elem.addEventListener) elem.addEventListener(type, fn, false); 1261 else elem.attachEvent("on" + type, fn); 1262 } 1263 }; 1264 return p; 1265 } 1266 })(); -
new file sagenb/data/graph_editor/processing.editor.min.js
diff --git a/sagenb/data/graph_editor/processing.editor.min.js b/sagenb/data/graph_editor/processing.editor.min.js new file mode 100644
- + 1 (function(){this.Processing=function Processing(aElement,aCode){if(typeof aElement=="string") 2 aElement=document.getElementById(aElement);var p=buildProcessing(aElement);if(aCode) 3 p.init(aCode);return p;};function log(){try{console.log.apply(console,arguments);}catch(e){try{opera.postError.apply(opera,arguments);}catch(e){}}} 4 var parse=Processing.parse=function parse(aCode,p){aCode=aCode.replace(/\/\/ .*\n/g,"\n");aCode=aCode.replace(/([^\s])%([^\s])/g,"$1 % $2");aCode=aCode.replace(/(?:static )?(\w+ )(\w+)\s*(\([^\)]*\)\s*{)/g,function(all,type,name,args){if(name=="if"||name=="for"||name=="while"){return all;}else{return"Processing."+name+" = function "+name+args;}});aCode=aCode.replace(/\.length\(\)/g,".length");aCode=aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g,"$1$4");aCode=aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g,"$1$4");aCode=aCode.replace(/new (\w+)((?:\[([^\]]*)\])+)/g,function(all,name,args){return"new ArrayList("+args.slice(1,-1).split("][").join(", ")+")";});aCode=aCode.replace(/(?:static )?\w+\[\]\s*(\w+)\[?\]?\s*=\s*{.*?};/g,function(all){return all.replace(/{/g,"[").replace(/}/g,"]");});var intFloat=/(\n\s*(?:int|float)(?:\[\])?(?:\s*|[^\(]*?,\s*))([a-z]\w*)(;|,)/i;while(intFloat.test(aCode)){aCode=aCode.replace(new RegExp(intFloat),function(all,type,name,sep){return type+" "+name+" = 0"+sep;});} 5 aCode=aCode.replace(/(?:static )?(\w+)((?:\[\])+| ) *(\w+)\[?\]?(\s*[=,;])/g,function(all,type,arr,name,sep){if(type=="return") 6 return all;else 7 return"var "+name+sep;});aCode=aCode.replace(/=\s*{((.|\s)*?)};/g,function(all,data){return"= ["+data.replace(/{/g,"[").replace(/}/g,"]")+"]";});aCode=aCode.replace(/static\s*{((.|\n)*?)}/g,function(all,init){return init;});aCode=aCode.replace(/super\(/g,"superMethod(");var classes=["int","float","boolean","string"];function ClassReplace(all,name,extend,vars,last){classes.push(name);var static="";vars=vars.replace(/final\s+var\s+(\w+\s*=\s*.*?;)/g,function(all,set){static+=" "+name+"."+set;return"";});return"function "+name+"() {with(this){\n "+ 8 (extend?"var __self=this;function superMethod(){extendClass(__self,arguments,"+extend+");}\n":"")+ 9 vars.replace(/,\s?/g,";\n this.").replace(/\b(var |final |public )+\s*/g,"this.").replace(/this.(\w+);/g,"this.$1 = null;")+ 10 (extend?"extendClass(this, "+extend+");\n":"")+"<CLASS "+name+" "+static+">"+(typeof last=="string"?last:name+"(");} 11 var matchClasses=/(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)\b\1\s*\(/g;var matchNoCon=/(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)(Processing)/g;aCode=aCode.replace(matchClasses,ClassReplace);aCode=aCode.replace(matchNoCon,ClassReplace);var matchClass=/<CLASS (\w+) (.*?)>/,m;while((m=aCode.match(matchClass))){var left=RegExp.leftContext,allRest=RegExp.rightContext,rest=nextBrace(allRest),className=m[1],staticVars=m[2]||"";allRest=allRest.slice(rest.length+1);rest=rest.replace(new RegExp("\\b"+className+"\\(([^\\)]*?)\\)\\s*{","g"),function(all,args){args=args.split(/,\s*?/);if(args[0].match(/^\s*$/)) 12 args.shift();var fn="if ( arguments.length == "+args.length+" ) {\n";for(var i=0;i<args.length;i++){fn+=" var "+args[i]+" = arguments["+i+"];\n";} 13 return fn;});rest=rest.replace(/(?:public )?Processing.\w+ = function (\w+)\((.*?)\)/g,function(all,name,args){return"ADDMETHOD(this, '"+name+"', function("+args+")";});var matchMethod=/ADDMETHOD([\s\S]*?{)/,mc;var methods="";while((mc=rest.match(matchMethod))){var prev=RegExp.leftContext,allNext=RegExp.rightContext,next=nextBrace(allNext);methods+="addMethod"+mc[1]+next+"});" 14 rest=prev+allNext.slice(next.length+1);} 15 rest=methods+rest;aCode=left+rest+"\n}}"+staticVars+allRest;} 16 aCode=aCode.replace(/Processing.\w+ = function addMethod/g,"addMethod");function nextBrace(right){var rest=right;var position=0;var leftCount=1,rightCount=0;while(leftCount!=rightCount){var nextLeft=rest.indexOf("{");var nextRight=rest.indexOf("}");if(nextLeft<nextRight&&nextLeft!=-1){leftCount++;rest=rest.slice(nextLeft+1);position+=nextLeft+1;}else{rightCount++;rest=rest.slice(nextRight+1);position+=nextRight+1;}} 17 return right.slice(0,position-1);} 18 aCode=aCode.replace(/\(int\)/g,"0|");aCode=aCode.replace(new RegExp("\\(("+classes.join("|")+")(\\[\\])?\\)","g"),"");aCode=aCode.replace(/(\d+)f/g,"$1");aCode=aCode.replace(/('[a-zA-Z0-9]')/g,"$1.charCodeAt(0)");aCode=aCode.replace(/#([a-f0-9]{6})/ig,function(m,hex){var num=toNumbers(hex);return"color("+num[0]+","+num[1]+","+num[2]+")";});function toNumbers(str){var ret=[];str.replace(/(..)/g,function(str){ret.push(parseInt(str,16));});return ret;} 19 return aCode;};function buildProcessing(curElement){var p={};p.PI=Math.PI;p.TWO_PI=2*p.PI;p.HALF_PI=p.PI/2;p.P3D=3;p.CORNER=0;p.RADIUS=1;p.CENTER_RADIUS=1;p.CENTER=2;p.POLYGON=2;p.QUADS=5;p.TRIANGLES=6;p.POINTS=7;p.LINES=8;p.TRIANGLE_STRIP=9;p.TRIANGLE_FAN=4;p.QUAD_STRIP=3;p.CORNERS=10;p.CLOSE=true;p.RGB=1;p.HSB=2;p.CENTER=88888880;p.CODED=88888888;p.UP=88888870;p.RIGHT=88888871;p.DOWN=88888872;p.LEFT=88888869;p.codedKeys=[69,70,71,72];var curContext=curElement.getContext("2d");var doFill=true;var doStroke=true;var loopStarted=false;var hasBackground=false;var doLoop=true;var looping=0;var curRectMode=p.CORNER;var curEllipseMode=p.CENTER;var inSetup=false;var inDraw=false;var curBackground="rgba(204,204,204,1)";var curFrameRate=1000;var curShape=p.POLYGON;var curShapeCount=0;var curvePoints=[];var curTightness=0;var opacityRange=255;var redRange=255;var greenRange=255;var blueRange=255;var pathOpen=false;var mousePressed=false;var keyPressed=false;var firstX,firstY,secondX,secondY,prevX,prevY;var curColorMode=p.RGB;var curTint=-1;var curTextSize=12;var curTextFont="Arial";var getLoaded=false;var start=(new Date).getTime();p.pmouseX=0;p.pmouseY=0;p.mouseX=0;p.mouseY=0;p.mouseButton=0;p.mouseDragged=undefined;p.mouseMoved=undefined;p.mousePressed=undefined;p.mouseReleased=undefined;p.keyPressed=undefined;p.keyReleased=undefined;p.draw=undefined;p.setup=undefined;p.width=curElement.width-0;p.height=curElement.height-0;p.frameCount=0;p.ajax=function(url){if(window.XMLHttpRequest){AJAX=new XMLHttpRequest();} 20 else{AJAX=new ActiveXObject("Microsoft.XMLHTTP");} 21 if(AJAX){AJAX.open("GET",url,false);AJAX.send(null);return AJAX.responseText;}else{return false;}} 22 p.loadStrings=function loadStrings(url){return p.ajax(url).split("\n");};p.color=function color(aValue1,aValue2,aValue3,aValue4){var aColor="";if(arguments.length==3){aColor=p.color(aValue1,aValue2,aValue3,opacityRange);}else if(arguments.length==4){var a=aValue4/opacityRange;a=isNaN(a)?1:a;if(curColorMode==p.HSB){var rgb=HSBtoRGB(aValue1,aValue2,aValue3);var r=rgb[0],g=rgb[1],b=rgb[2];}else{var r=getColor(aValue1,redRange);var g=getColor(aValue2,greenRange);var b=getColor(aValue3,blueRange);} 23 aColor="rgba("+r+","+g+","+b+","+a+")";}else if(typeof aValue1=="string"){aColor=aValue1;if(arguments.length==2){var c=aColor.split(",");c[3]=(aValue2/opacityRange)+")";aColor=c.join(",");}}else if(arguments.length==2){aColor=p.color(aValue1,aValue1,aValue1,aValue2);}else if(typeof aValue1=="number"){aColor=p.color(aValue1,aValue1,aValue1,opacityRange);}else{aColor=p.color(redRange,greenRange,blueRange,opacityRange);} 24 function HSBtoRGB(h,s,b){h=(h/redRange)*100;s=(s/greenRange)*100;b=(b/blueRange)*100;if(s==0){return[b,b,b];}else{var hue=h%360;var f=hue%60;var br=Math.round(b/100*255);var p=Math.round((b*(100-s))/10000*255);var q=Math.round((b*(6000-s*f))/600000*255);var t=Math.round((b*(6000-s*(60-f)))/600000*255);switch(Math.floor(hue/60)){case 0:return[br,t,p];case 1:return[q,br,p];case 2:return[p,br,t];case 3:return[p,q,br];case 4:return[t,p,br];case 5:return[br,p,q];}}} 25 function getColor(aValue,range){return Math.round(255*(aValue/range));} 26 return aColor;} 27 p.red=function(aColor){return parseInt(verifyChannel(aColor).slice(5));};p.green=function(aColor){return parseInt(verifyChannel(aColor).split(",")[1]);};p.blue=function(aColor){return parseInt(verifyChannel(aColor).split(",")[2]);};p.alpha=function(aColor){return parseInt(parseFloat(verifyChannel(aColor).split(",")[3])*255);};function verifyChannel(aColor){if(aColor.constructor==Array){return aColor;}else{return p.color(aColor);}} 28 p.lerpColor=function lerpColor(c1,c2,amt){var colors1=p.color(c1).split(",");var r1=parseInt(colors1[0].split("(")[1]);var g1=parseInt(colors1[1]);var b1=parseInt(colors1[2]);var a1=parseFloat(colors1[3].split(")")[0]);var colors2=p.color(c2).split(",");var r2=parseInt(colors2[0].split("(")[1]);var g2=parseInt(colors2[1]);var b2=parseInt(colors2[2]);var a2=parseFloat(colors2[3].split(")")[0]);var r=parseInt(p.lerp(r1,r2,amt));var g=parseInt(p.lerp(g1,g2,amt));var b=parseInt(p.lerp(b1,b2,amt));var a=parseFloat(p.lerp(a1,a2,amt));aColor="rgba("+r+","+g+","+b+","+a+")";return aColor;} 29 p.nf=function(num,pad){var str=""+num;while(pad-str.length) 30 str="0"+str;return str;};p.AniSprite=function(prefix,frames){this.images=[];this.pos=0;for(var i=0;i<frames;i++){this.images.push(prefix+p.nf(i,(""+frames).length)+".gif");} 31 this.display=function(x,y){p.image(this.images[this.pos],x,y);if(++this.pos>=frames) 32 this.pos=0;};this.getWidth=function(){return getImage(this.images[0]).width;};this.getHeight=function(){return getImage(this.images[0]).height;};};function buildImageObject(obj){var pixels=obj.data;var data=p.createImage(obj.width,obj.height);if(data.__defineGetter__&&data.__lookupGetter__&&!data.__lookupGetter__("pixels")){var pixelsDone;data.__defineGetter__("pixels",function(){if(pixelsDone) 33 return pixelsDone;pixelsDone=[];for(var i=0;i<pixels.length;i+=4){pixelsDone.push(p.color(pixels[i],pixels[i+1],pixels[i+2],pixels[i+3]));} 34 return pixelsDone;});}else{data.pixels=[];for(var i=0;i<pixels.length;i+=4){data.pixels.push(p.color(pixels[i],pixels[i+1],pixels[i+2],pixels[i+3]));}} 35 return data;} 36 p.createImage=function createImage(w,h,mode){var data={};data.width=w;data.height=h;data.data=[];if(curContext.createImageData){data=curContext.createImageData(w,h);} 37 data.pixels=new Array(w*h);data.get=function(x,y){return this.pixels[w*y+x];};data._mask=null;data.mask=function(img){this._mask=img;};data.loadPixels=function(){};data.updatePixels=function(){};return data;};p.createGraphics=function createGraphics(w,h){var canvas=document.createElement("canvas");var ret=buildProcessing(canvas);ret.size(w,h);ret.canvas=canvas;return ret;};p.beginDraw=function beginDraw(){};p.endDraw=function endDraw(){};p.tint=function tint(rgb,a){curTint=a;};function getImage(img){if(typeof img=="string"){return document.getElementById(img);} 38 if(img.img||img.canvas){return img.img||img.canvas;} 39 for(var i=0,l=img.pixels.length;i<l;i++){var pos=i*4;var c=(img.pixels[i]||"rgba(0,0,0,1)").slice(5,-1).split(",");img.data[pos]=parseInt(c[0]);img.data[pos+1]=parseInt(c[1]);img.data[pos+2]=parseInt(c[2]);img.data[pos+3]=parseFloat(c[3])*100;} 40 var canvas=document.createElement("canvas") 41 canvas.width=img.width;canvas.height=img.height;var context=canvas.getContext("2d");context.putImageData(img,0,0);img.canvas=canvas;return canvas;} 42 p.image=function image(img,x,y,w,h){x=x||0;y=y||0;var obj=getImage(img);if(curTint>=0){var oldAlpha=curContext.globalAlpha;curContext.globalAlpha=curTint/opacityRange;} 43 if(arguments.length==3){curContext.drawImage(obj,x,y);}else{curContext.drawImage(obj,x,y,w,h);} 44 if(curTint>=0){curContext.globalAlpha=oldAlpha;} 45 if(img._mask){var oldComposite=curContext.globalCompositeOperation;curContext.globalCompositeOperation="darker";p.image(img._mask,x,y);curContext.globalCompositeOperation=oldComposite;}};p.exit=function exit(){clearInterval(looping);};p.save=function save(file){};p.loadImage=function loadImage(file){var img=document.getElementById(file);if(!img) 46 return;var h=img.height,w=img.width;var canvas=document.createElement("canvas");canvas.width=w;canvas.height=h;var context=canvas.getContext("2d");context.drawImage(img,0,0);var data=buildImageObject(context.getImageData(0,0,w,h));data.img=img;return data;};p.loadFont=function loadFont(name){return{name:name,width:function(str){if(curContext.mozMeasureText) 47 return curContext.mozMeasureText(typeof str=="number"?String.fromCharCode(str):str)/curTextSize;else 48 return 0;}};};p.textFont=function textFont(name,size){curTextFont=name;p.textSize(size);};p.textSize=function textSize(size){if(size){curTextSize=size;}};p.textAlign=function textAlign(){};p.text=function text(str,x,y){if(str&&curContext.mozDrawText){curContext.save();curContext.mozTextStyle=curTextSize+"px "+curTextFont.name;curContext.translate(x,y);curContext.mozDrawText(typeof str=="number"?String.fromCharCode(str):str);curContext.restore();}};p.print=function print(output){alert(output);} 49 p.println=p.print;p.char=function char(key){return key;};p.map=function map(value,istart,istop,ostart,ostop){return ostart+(ostop-ostart)*((value-istart)/(istop-istart));};String.prototype.replaceAll=function(re,replace){return this.replace(new RegExp(re,"g"),replace);};p.Point=function Point(x,y){this.x=x;this.y=y;this.copy=function(){return new Point(x,y);}};p.Random=function(){var haveNextNextGaussian=false;var nextNextGaussian;this.nextGaussian=function(){if(haveNextNextGaussian){haveNextNextGaussian=false;return nextNextGaussian;}else{var v1,v2,s;do{v1=2*p.random(1)-1;v2=2*p.random(1)-1;s=v1*v1+v2*v2;}while(s>=1||s==0);var multiplier=Math.sqrt(-2*Math.log(s)/s);nextNextGaussian=v2*multiplier;haveNextNextGaussian=true;return v1*multiplier;}};};p.ArrayList=function ArrayList(size,size2,size3){var array=new Array(0|size);if(size2){for(var i=0;i<size;i++){array[i]=[];for(var j=0;j<size2;j++){var a=array[i][j]=size3?new Array(size3):0;for(var k=0;k<size3;k++){a[k]=0;}}}}else{for(var i=0;i<size;i++){array[i]=0;}} 50 array.size=function(){return this.length;};array.get=function(i){return this[i];};array.remove=function(i){return this.splice(i,1);};array.add=function(item){return this.push(item);};array.clone=function(){var a=new ArrayList(size);for(var i=0;i<size;i++){a[i]=this[i];} 51 return a;};array.isEmpty=function(){return!this.length;};array.clear=function(){this.length=0;};return array;};p.colorMode=function colorMode(mode,range1,range2,range3,range4){curColorMode=mode;if(arguments.length>=4){redRange=range1;greenRange=range2;blueRange=range3;} 52 if(arguments.length==5){opacityRange=range4;} 53 if(arguments.length==2){p.colorMode(mode,range1,range1,range1,range1);}};p.beginShape=function beginShape(type){curShape=type;curShapeCount=0;curvePoints=[];};p.endShape=function endShape(close){if(curShapeCount!=0){if(close||doFill) 54 curContext.lineTo(firstX,firstY);if(doFill) 55 curContext.fill();if(doStroke) 56 curContext.stroke();curContext.closePath();curShapeCount=0;pathOpen=false;} 57 if(pathOpen){if(doFill) 58 curContext.fill();if(doStroke) 59 curContext.stroke();curContext.closePath();curShapeCount=0;pathOpen=false;}};p.vertex=function vertex(x,y,x2,y2,x3,y3){if(curShapeCount==0&&curShape!=p.POINTS){pathOpen=true;curContext.beginPath();curContext.moveTo(x,y);firstX=x;firstY=y;}else{if(curShape==p.POINTS){p.point(x,y);}else if(arguments.length==2){if(curShape!=p.QUAD_STRIP||curShapeCount!=2) 60 curContext.lineTo(x,y);if(curShape==p.TRIANGLE_STRIP){if(curShapeCount==2){p.endShape(p.CLOSE);pathOpen=true;curContext.beginPath();curContext.moveTo(prevX,prevY);curContext.lineTo(x,y);curShapeCount=1;} 61 firstX=prevX;firstY=prevY;} 62 if(curShape==p.TRIANGLE_FAN&&curShapeCount==2){p.endShape(p.CLOSE);pathOpen=true;curContext.beginPath();curContext.moveTo(firstX,firstY);curContext.lineTo(x,y);curShapeCount=1;} 63 if(curShape==p.QUAD_STRIP&&curShapeCount==3){curContext.lineTo(prevX,prevY);p.endShape(p.CLOSE);pathOpen=true;curContext.beginPath();curContext.moveTo(prevX,prevY);curContext.lineTo(x,y);curShapeCount=1;} 64 if(curShape==p.QUAD_STRIP){firstX=secondX;firstY=secondY;secondX=prevX;secondY=prevY;}}else if(arguments.length==4){if(curShapeCount>1){curContext.moveTo(prevX,prevY);curContext.quadraticCurveTo(firstX,firstY,x,y);curShapeCount=1;}}else if(arguments.length==6){curContext.bezierCurveTo(x,y,x2,y2,x3,y3);}} 65 prevX=x;prevY=y;curShapeCount++;if(curShape==p.LINES&&curShapeCount==2||(curShape==p.TRIANGLES)&&curShapeCount==3||(curShape==p.QUADS)&&curShapeCount==4){p.endShape(p.CLOSE);}};p.curveVertex=function(x,y,x2,y2){if(curvePoints.length<3){curvePoints.push([x,y]);}else{var b=[],s=1-curTightness;curvePoints.push([x,y]);b[0]=[curvePoints[1][0],curvePoints[1][1]];b[1]=[curvePoints[1][0]+(s*curvePoints[2][0]-s*curvePoints[0][0])/6,curvePoints[1][1]+(s*curvePoints[2][1]-s*curvePoints[0][1])/6];b[2]=[curvePoints[2][0]+(s*curvePoints[1][0]-s*curvePoints[3][0])/6,curvePoints[2][1]+(s*curvePoints[1][1]-s*curvePoints[3][1])/6];b[3]=[curvePoints[2][0],curvePoints[2][1]];if(!pathOpen){p.vertex(b[0][0],b[0][1]);}else{curShapeCount=1;} 66 p.vertex(b[1][0],b[1][1],b[2][0],b[2][1],b[3][0],b[3][1]);curvePoints.shift();}};p.curveTightness=function(tightness){curTightness=tightness;};p.bezierVertex=p.vertex;p.rectMode=function rectMode(aRectMode){curRectMode=aRectMode;};p.imageMode=function(){};p.ellipseMode=function ellipseMode(aEllipseMode){curEllipseMode=aEllipseMode;};p.dist=function dist(x1,y1,x2,y2){return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));};p.year=function year(){return(new Date).getYear()+1900;};p.month=function month(){return(new Date).getMonth();};p.day=function day(){return(new Date).getDay();};p.hour=function hour(){return(new Date).getHours();};p.minute=function minute(){return(new Date).getMinutes();};p.second=function second(){return(new Date).getSeconds();};p.millis=function millis(){return(new Date).getTime()-start;};p.ortho=function ortho(){};p.translate=function translate(x,y){curContext.translate(x,y);};p.scale=function scale(x,y){curContext.scale(x,y||x);};p.rotate=function rotate(aAngle){curContext.rotate(aAngle);};p.pushMatrix=function pushMatrix(){curContext.save();};p.popMatrix=function popMatrix(){curContext.restore();};p.redraw=function redraw(){if(hasBackground){p.background();} 67 p.frameCount++;inDraw=true;p.pushMatrix();p.draw();p.popMatrix();inDraw=false;};p.loop=function loop(){if(loopStarted) 68 return;looping=setInterval(function(){try{if(!p.paused){p.redraw();}} 69 catch(e){clearInterval(looping);throw e;}},1000/curFrameRate);loopStarted=true;};p.frameRate=function frameRate(aRate){curFrameRate=aRate;};p.background=function background(img){if(arguments.length){if(img&&img.img){curBackground=img;}else{curBackground=p.color.apply(this,arguments);}} 70 if(curBackground.img){p.image(curBackground,0,0);}else{var oldFill=curContext.fillStyle;curContext.fillStyle=curBackground+"";curContext.fillRect(0,0,p.width,p.height);curContext.fillStyle=oldFill;}};p.clear=function clear(x,y,width,height){arguments.length==0?curContext.clearRect(0,0,p.width,p.height):curContext.clearRect(x,y,width,height);} 71 p.str=function str(aNumber){return aNumber+'';} 72 p.sq=function sq(aNumber){return aNumber*aNumber;};p.sqrt=function sqrt(aNumber){return Math.sqrt(aNumber);};p.ngsqrt=function ngsqrt(aNumber){if(aNumber<=0){return Math.sqrt(-aNumber);}else{return Math.sqrt(aNumber);}};p.int=function int(aNumber){return Math.floor(aNumber);};p.min=function min(aNumber,aNumber2){return Math.min(aNumber,aNumber2);};p.max=function max(aNumber,aNumber2){return Math.max(aNumber,aNumber2);};p.ceil=function ceil(aNumber){return Math.ceil(aNumber);};p.round=function round(aNumber){return Math.round(aNumber);};p.norm=function norm(aNumber,low,high){var range=high-low;return((1/range)*aNumber)-((1/range)*low);};p.lerp=function lerp(value1,value2,amt){var range=value2-value1;return(range*amt)+value1;} 73 p.floor=function floor(aNumber){return Math.floor(aNumber);};p.float=function float(aNumber){return parseFloat(aNumber);};p.byte=function byte(aNumber){return aNumber||0;};p.random=function random(aMin,aMax){return arguments.length==2?aMin+(Math.random()*(aMax-aMin)):Math.random()*aMin;};p.noise=function(x,y,z){return arguments.length>=2?PerlinNoise_2D(x,y):PerlinNoise_2D(x,x);};function Noise(x,y){var n=x+y*57;n=(n<<13)^n;return Math.abs(1.0-(((n*((n*n*15731)+789221)+1376312589)&0x7fffffff)/1073741824.0));};function SmoothedNoise(x,y){var corners=(Noise(x-1,y-1)+Noise(x+1,y-1)+Noise(x-1,y+1)+Noise(x+1,y+1))/16;var sides=(Noise(x-1,y)+Noise(x+1,y)+Noise(x,y-1)+Noise(x,y+1))/8;var center=Noise(x,y)/4;return corners+sides+center;};function InterpolatedNoise(x,y){var integer_X=Math.floor(x);var fractional_X=x-integer_X;var integer_Y=Math.floor(y);var fractional_Y=y-integer_Y;var v1=SmoothedNoise(integer_X,integer_Y);var v2=SmoothedNoise(integer_X+1,integer_Y);var v3=SmoothedNoise(integer_X,integer_Y+1);var v4=SmoothedNoise(integer_X+1,integer_Y+1);var i1=Interpolate(v1,v2,fractional_X);var i2=Interpolate(v3,v4,fractional_X);return Interpolate(i1,i2,fractional_Y);} 74 function PerlinNoise_2D(x,y){var total=0;var p=0.25;var n=3;for(var i=0;i<=n;i++){var frequency=Math.pow(2,i);var amplitude=Math.pow(p,i);total=total+InterpolatedNoise(x*frequency,y*frequency)*amplitude;} 75 return total;} 76 function Interpolate(a,b,x){var ft=x*p.PI;var f=(1-p.cos(ft))*.5;return a*(1-f)+b*f;} 77 p.abs=function abs(aNumber){return Math.abs(aNumber);};p.cos=function cos(aNumber){return Math.cos(aNumber);};p.sin=function sin(aNumber){return Math.sin(aNumber);};p.pow=function pow(aNumber,aExponent){return Math.pow(aNumber,aExponent);};p.constrain=function constrain(aNumber,aMin,aMax){return Math.min(Math.max(aNumber,aMin),aMax);};p.sqrt=function sqrt(aNumber){return Math.sqrt(aNumber);};p.atan2=function atan2(aNumber,aNumber2){return Math.atan2(aNumber,aNumber2);};p.radians=function radians(aAngle){return(aAngle/180)*p.PI;};p.degrees=function degrees(aAngle){aAngle=(aAngle*180)/p.PI;if(aAngle<0){aAngle=360+aAngle} 78 return aAngle;};p.size=function size(aWidth,aHeight){var fillStyle=curContext.fillStyle;var strokeStyle=curContext.strokeStyle;curElement.width=p.width=aWidth;curElement.height=p.height=aHeight;curContext.fillStyle=fillStyle;curContext.strokeStyle=strokeStyle;};p.noStroke=function noStroke(){doStroke=false;};p.noFill=function noFill(){doFill=false;};p.smooth=function smooth(){};p.noSmooth=function noSmooth(){};p.noLoop=function noLoop(){clearInterval(looping);loopStarted=false;doLoop=false;};p.fill=function fill(){doFill=true;curContext.fillStyle=p.color.apply(this,arguments);};p.stroke=function stroke(){doStroke=true;curContext.strokeStyle=p.color.apply(this,arguments);};p.strokeWeight=function strokeWeight(w){curContext.lineWidth=w;};p.point=function point(x,y){var oldFill=curContext.fillStyle;curContext.fillStyle=curContext.strokeStyle;curContext.fillRect(Math.round(x),Math.round(y),1,1);curContext.fillStyle=oldFill;};p.get=function get(x,y){if(arguments.length==0){var c=p.createGraphics(p.width,p.height);c.image(curContext,0,0);return c;} 79 if(!getLoaded){getLoaded=buildImageObject(curContext.getImageData(0,0,p.width,p.height));} 80 return getLoaded.get(x,y);};p.set=function set(x,y,obj){if(obj&&obj.img){p.image(obj,x,y);}else{var oldFill=curContext.fillStyle;var color=obj;curContext.fillStyle=color;curContext.fillRect(Math.round(x),Math.round(y),1,1);curContext.fillStyle=oldFill;}};p.arc=function arc(x,y,width,height,start,stop){if(width<=0) 81 return;if(curEllipseMode==p.CORNER){x+=width/2;y+=height/2;} 82 curContext.moveTo(x,y);curContext.beginPath();curContext.arc(x,y,curEllipseMode==p.CENTER_RADIUS?width:width/2,start,stop,false);if(doStroke) 83 curContext.stroke();curContext.lineTo(x,y);if(doFill) 84 curContext.fill();curContext.closePath();};p.line=function line(x1,y1,x2,y2){curContext.lineCap="round";curContext.beginPath();curContext.moveTo(x1||0,y1||0);curContext.lineTo(x2||0,y2||0);curContext.stroke();curContext.closePath();};p.bezier=function bezier(x1,y1,x2,y2,x3,y3,x4,y4){curContext.lineCap="butt";curContext.beginPath();curContext.moveTo(x1,y1);curContext.bezierCurveTo(x2,y2,x3,y3,x4,y4);curContext.stroke();curContext.closePath();};p.triangle=function triangle(x1,y1,x2,y2,x3,y3){p.beginShape();p.vertex(x1,y1);p.vertex(x2,y2);p.vertex(x3,y3);p.endShape();};p.quad=function quad(x1,y1,x2,y2,x3,y3,x4,y4){curContext.lineCap="square";p.beginShape();p.vertex(x1,y1);p.vertex(x2,y2);p.vertex(x3,y3);p.vertex(x4,y4);p.endShape();};p.rect=function rect(x,y,width,height){if(width==0&&height==0) 85 return;curContext.beginPath();var offsetStart=0;var offsetEnd=0;if(curRectMode==p.CORNERS){width-=x;height-=y;} 86 if(curRectMode==p.RADIUS){width*=2;height*=2;} 87 if(curRectMode==p.CENTER||curRectMode==p.RADIUS){x-=width/2;y-=height/2;} 88 curContext.rect(Math.round(x)-offsetStart,Math.round(y)-offsetStart,Math.round(width)+offsetEnd,Math.round(height)+offsetEnd);if(doFill) 89 curContext.fill();if(doStroke) 90 curContext.stroke();curContext.closePath();};p.ellipse=function ellipse(x,y,width,height){x=x||0;y=y||0;if(width<=0&&height<=0) 91 return;curContext.beginPath();if(curEllipseMode==p.RADIUS){width*=2;height*=2;} 92 var offsetStart=0;if(width==height){curContext.arc(x-offsetStart,y-offsetStart,width/2,0,Math.PI*2,false);}else{var w=width/2;var h=height/2;var C=0.5522847498307933;var c_x=C*w;var c_y=C*h;curContext.moveTo(x+w,y);curContext.bezierCurveTo(x+w,y-c_y,x+c_x,y-h,x,y-h);curContext.bezierCurveTo(x-c_x,y-h,x-w,y-c_y,x-w,y);curContext.bezierCurveTo(x-w,y+c_y,x-c_x,y+h,x,y+h);curContext.bezierCurveTo(x+c_x,y+h,x+w,y+c_y,x+w,y);} 93 if(doFill) 94 curContext.fill();if(doStroke) 95 curContext.stroke();curContext.closePath();};p.link=function(href,target){window.location=href;};p.loadPixels=function(){p.pixels=buildImageObject(curContext.getImageData(0,0,p.width,p.height)).pixels;};p.updatePixels=function(){var colors=/(\d+),(\d+),(\d+),(\d+)/;var pixels={};pixels.width=p.width;pixels.height=p.height;pixels.data=[];if(curContext.createImageData){pixels=curContext.createImageData(p.width,p.height);} 96 var data=pixels.data;var pos=0;for(var i=0,l=p.pixels.length;i<l;i++){var c=(p.pixels[i]||"rgba(0,0,0,1)").match(colors);data[pos]=parseInt(c[1]);data[pos+1]=parseInt(c[2]);data[pos+2]=parseInt(c[3]);data[pos+3]=parseFloat(c[4])*255;pos+=4;} 97 curContext.putImageData(pixels,0,0);};p.extendClass=function extendClass(obj,args,fn){if(arguments.length==3){fn.apply(obj,args);}else{args.call(obj);}};p.addMethod=function addMethod(object,name,fn){if(object[name]){var args=fn.length;var oldfn=object[name];object[name]=function(){if(arguments.length==args) 98 return fn.apply(this,arguments);else 99 return oldfn.apply(this,arguments);};}else{object[name]=fn;}};p.init=function init(code){p.stroke(0);p.fill(255);curContext.translate(0.5,0.5);if(code){(function(Processing){with(p){eval(parse(code,p));}})(p);} 100 if(p.setup){inSetup=true;p.setup();} 101 inSetup=false;if(p.draw){if(!doLoop){p.redraw();}else{p.loop();}} 102 attach(document,"mousemove",function(e){var scrollX=window.scrollX!=null?window.scrollX:window.pageXOffset;var scrollY=window.scrollY!=null?window.scrollY:window.pageYOffset;p.pmouseX=p.mouseX;p.pmouseY=p.mouseY;p.mouseX=e.clientX-curElement.offsetLeft+scrollX;p.mouseY=e.clientY-curElement.offsetTop+scrollY;if(p.mouseMoved){p.mouseMoved();} 103 if(mousePressed&&p.mouseDragged){p.mouseDragged();}});attach(curElement,"mousedown",function(e){mousePressed=true;switch(e.which){case 1:p.mouseButton=p.LEFT;break;case 2:p.mouseButton=p.CENTER;break;case 3:p.mouseButton=p.RIGHT;break;} 104 if(typeof p.mousePressed=="function"){p.mousePressed();}else{p.mousePressed=true;}});attach(curElement,"contextmenu",function(e){e.preventDefault();e.stopPropagation();});attach(document,"mouseup",function(e){mousePressed=false;if(typeof p.mousePressed!="function"){p.mousePressed=false;} 105 if(p.mouseReleased){p.mouseReleased();}});attach(document,"keydown",function(e){keyPressed=true;p.key=e.keyCode+32;var i;for(i=0;i<p.codedKeys.length;i++){if(p.key==p.codedKeys[i]){switch(p.key){case 70:p.keyCode=p.UP;break;case 71:p.keyCode=p.RIGHT;break;case 72:p.keyCode=p.DOWN;break;case 69:p.keyCode=p.LEFT;break;} 106 p.key=p.CODED;}} 107 if(e.shiftKey){p.key=String.fromCharCode(p.key).toUpperCase().charCodeAt(0);} 108 if(typeof p.keyPressed=="function"){p.keyPressed();}else{p.keyPressed=true;}});attach(document,"keyup",function(e){keyPressed=false;if(typeof p.keyPressed!="function"){p.keyPressed=false;} 109 if(p.keyReleased){p.keyReleased();}});function attach(elem,type,fn){if(elem.addEventListener) 110 elem.addEventListener(type,fn,false);else 111 elem.attachEvent("on"+type,fn);}};return p;}})(); -
new file sagenb/data/graph_editor/processing.js
diff --git a/sagenb/data/graph_editor/processing.js b/sagenb/data/graph_editor/processing.js new file mode 100644
- + 1 /* 2 3 P R O C E S S I N G - 0 . 0 . J S 4 a port of the Processing visualization language 5 6 License : MIT 7 Developer : John Resig: http://ejohn.org 8 Web Site : http://processingjs.org 9 Java Version : http://processing.org 10 Github Repo. : http://github.com/jeresig/processing-js 11 Bug Tracking : http://processing-js.lighthouseapp.com 12 Mozilla POW! : http://wiki.Mozilla.org/Education/Projects/ProcessingForTheWeb 13 Maintained by : Seneca: http://zenit.senecac.on.ca/wiki/index.php/Processing.js 14 Hyper-Metrix: http://hyper-metrix.com/#Processing 15 16 */ 17 18 19 (function(){ 20 21 22 // Attach Processing to the window 23 this.Processing = function Processing( aElement, aCode ){ 24 25 // Get the DOM element if string was passed 26 if( typeof aElement == "string" ){ 27 aElement = document.getElementById( aElement ); 28 } 29 30 // Build an Processing functions and env. vars into 'p' 31 var p = buildProcessing( aElement ); 32 33 // Send aCode Processing syntax to be converted to JavaScript 34 if( aCode ){ p.init( aCode ); } 35 36 return p; 37 38 }; 39 40 // IE Unfriendly AJAX Method 41 var ajax=function( url ){ 42 var AJAX; 43 if( AJAX = new XMLHttpRequest() ){ 44 AJAX.open( "GET", url, false ); 45 AJAX.send( null ); 46 return AJAX.responseText; 47 }else{ 48 return false; 49 } 50 }; 51 52 // Automatic Initialization Method 53 var init = function(){ 54 55 var canvas = document.getElementsByTagName( 'canvas' ), 56 datasrc = undefined; 57 58 for( var i = 0; l = i < canvas.length; i++ ){ 59 if( datasrc = canvas[ i ].getAttribute( 'datasrc' ) ){ 60 Processing( canvas[ i ], ajax( datasrc ) ); 61 } 62 } 63 64 }; 65 66 addEventListener( 'DOMContentLoaded', function(){ init(); }, false ); 67 68 // Parse Processing (Java-like) syntax to JavaScript syntax with Regex 69 var parse = Processing.parse = function parse( aCode, p ){ 70 71 // Remove end-of-line comments 72 aCode = aCode.replace( /\/\/ .*\n/g, "\n" ); 73 74 // Weird parsing errors with % 75 aCode = aCode.replace( /([^\s])%([^\s])/g, "$1 % $2" ); 76 77 // Simple convert a function-like thing to function 78 aCode = aCode.replace( /(?:static )?(\w+ )(\w+)\s*(\([^\)]*\)\s*{)/g, function( all, type, name, args ){ 79 if ( name == "if" || name == "for" || name == "while" ) { 80 return all; 81 } else { 82 return "Processing." + name + " = function " + name + args; 83 } 84 }); 85 86 // Attach import() to p{} bypassing JS command, allowing for extrernal library loading 87 aCode = aCode.replace( /import \(|import\(/g, "p.Import(" ); 88 89 // Force .length() to be .length 90 aCode = aCode.replace( /\.length\(\)/g, ".length" ); 91 92 // foo( int foo, float bar ) 93 aCode = aCode.replace( /([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4" ); 94 aCode = aCode.replace( /([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g, "$1$4" ); 95 96 // float[] foo = new float[5]; 97 aCode = aCode.replace( /new (\w+)((?:\[([^\]]*)\])+)/g, function( all, name, args ){ 98 return "new ArrayList(" + args.slice(1,-1).split("][").join(", ") + ")"; 99 }); 100 101 // What does this do? 102 aCode = aCode.replace( /(?:static )?\w+\[\]\s*(\w+)\[?\]?\s*=\s*{.*?};/g, function( all ){ 103 return all.replace( /{/g, "[").replace(/}/g, "]" ); 104 }); 105 106 // int|float foo; 107 var intFloat = /(\n\s*(?:int|float)(?:\[\])?(?:\s*|[^\(]*?,\s*))([a-z]\w*)(;|,)/i; 108 while( intFloat.test(aCode) ){ 109 aCode = aCode.replace( new RegExp( intFloat ), function( all, type, name, sep ){ 110 return type + " " + name + " = 0" + sep; 111 }); 112 } 113 114 // float foo = 5; 115 aCode = aCode.replace( /(?:static )?(\w+)((?:\[\])+| ) *(\w+)\[?\]?(\s*[=,;])/g, function( all, type, arr, name, sep ){ 116 if ( type == "return" ) 117 return all; 118 else 119 return "var " + name + sep; 120 }); 121 122 // Fix Array[] foo = {...} to [...] 123 aCode = aCode.replace( /=\s*{((.|\s)*?)};/g, function(all,data){ 124 return "= [" + data.replace(/{/g, "[").replace(/}/g, "]") + "]"; 125 }); 126 127 // super() is a reserved word 128 aCode = aCode.replace( /super\(/g, "superMethod(" ); 129 130 var classes = [ "int", "float", "boolean", "string" ]; 131 132 function ClassReplace( all, name, extend, vars, last ){ 133 134 classes.push( name ); 135 136 var static = ""; 137 138 vars = vars.replace( /final\s+var\s+(\w+\s*=\s*.*?;)/g, function( all, set ){ 139 static += " " + name + "." + set; 140 return ""; 141 }); 142 143 // Move arguments up from constructor and wrap contents with 144 // a with(this), and unwrap constructor 145 return "function " + name + "() {with(this){\n " + 146 ( extend ? "var __self=this;function superMethod(){extendClass(__self,arguments," + extend + ");}\n" : "" ) + 147 // Replace var foo = 0; with this.foo = 0; 148 // and force var foo; to become this.foo = null; 149 vars 150 .replace( /,\s?/g, ";\n this." ) 151 .replace( /\b(var |final |public )+\s*/g, "this." ) 152 .replace( /\b(var |final |public )+\s*/g, "this." ) 153 .replace( /this.(\w+);/g, "this.$1 = null;" ) + 154 ( extend ? "extendClass(this, " + extend + ");\n" : "" ) + 155 "<CLASS " + name + " " + static + ">" + ( typeof last == "string" ? last : name + "(" ); 156 } 157 158 var matchClasses = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)\b\1\s*\(/g; 159 var matchNoCon = /(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)(Processing)/g; 160 161 aCode = aCode.replace( matchClasses, ClassReplace ); 162 aCode = aCode.replace( matchNoCon, ClassReplace ); 163 164 var matchClass = /<CLASS (\w+) (.*?)>/, m; 165 166 while ( ( m = aCode.match( matchClass ) ) ){ 167 168 var left = RegExp.leftContext, 169 allRest = RegExp.rightContext, 170 rest = nextBrace( allRest ), 171 className = m[ 1 ], 172 staticVars = m[ 2 ] || ""; 173 174 allRest = allRest.slice( rest.length + 1 ); 175 176 rest = rest.replace( new RegExp("\\b" + className + "\\(([^\\)]*?)\\)\\s*{", "g"), function( all, args ){ 177 args = args.split( /,\s*?/ ); 178 179 if( args[ 0 ].match( /^\s*$/ ) ){ 180 args.shift(); 181 } 182 183 var fn = "if ( arguments.length == " + args.length + " ) {\n"; 184 185 for ( var i = 0; i < args.length; i++ ) { 186 fn += " var " + args[ i ] + " = arguments["+ i +"];\n"; 187 } 188 189 return fn; 190 }); 191 192 // Fix class method names 193 // this.collide = function() { ... } 194 // and add closing } for with(this) ... 195 rest = rest.replace( /(?:public )?Processing.\w+ = function (\w+)\((.*?)\)/g, function( all, name, args ){ 196 return "ADDMETHOD(this, '" + name + "', function(" + args + ")"; 197 }); 198 199 var matchMethod = /ADDMETHOD([\s\S]*?{)/, mc; 200 var methods = ""; 201 202 while ( ( mc = rest.match( matchMethod ) ) ){ 203 var prev = RegExp.leftContext, 204 allNext = RegExp.rightContext, 205 next = nextBrace(allNext); 206 207 methods += "addMethod" + mc[ 1 ] + next + "});"; 208 209 rest = prev + allNext.slice( next.length + 1 ); 210 } 211 212 rest = methods + rest; 213 214 aCode = left + rest + "\n}}" + staticVars + allRest; 215 } 216 217 // Do some tidying up, where necessary 218 aCode = aCode.replace( /Processing.\w+ = function addMethod/g, "addMethod" ); 219 220 function nextBrace( right ) { 221 222 var rest = right, 223 position = 0, 224 leftCount = 1, 225 rightCount = 0; 226 227 while( leftCount != rightCount ) { 228 229 var nextLeft = rest.indexOf( "{" ), 230 nextRight = rest.indexOf( "}" ); 231 232 if( nextLeft < nextRight && nextLeft != - 1 ) { 233 234 leftCount++; 235 rest = rest.slice( nextLeft + 1 ); 236 position += nextLeft + 1; 237 238 }else{ 239 240 rightCount++; 241 rest = rest.slice( nextRight + 1 ); 242 position += nextRight + 1; 243 244 } 245 246 } 247 248 return right.slice( 0, position - 1 ); 249 } 250 251 // Handle (int) Casting 252 aCode = aCode.replace( /\(int\)/g, "0|" ); 253 254 // Remove Casting 255 aCode = aCode.replace( new RegExp("\\((" + classes.join("|") + ")(\\[\\])?\\)", "g"), "" ); 256 257 // Convert 3.0f to just 3.0 258 aCode = aCode.replace( /(\d+)f[^a-zA-Z0-9]/g, "$1" ); 259 260 // Force numbers to exist // 261 //aCode = aCode.replace(/([^.])(\w+)\s*\+=/g, "$1$2 = ($2||0) +"); 262 263 //! // Force characters-as-bytes to work --> Ping: Andor 264 aCode = aCode.replace(/('[a-zA-Z0-9]')/g, "$1.charCodeAt(0)"); 265 266 // Convert #aaaaaa into color 267 aCode = aCode.replace(/#([a-f0-9]{6})/ig, function(m, hex){ 268 var num = toNumbers(hex); 269 return "DefaultColor(" + num[0] + "," + num[1] + "," + num[2] + ")"; 270 }); 271 272 function toNumbers( str ){ 273 var ret = []; 274 275 str.replace( /(..)/g, function( str ){ 276 ret.push( parseInt( str, 16 ) ); 277 }); 278 279 return ret; 280 } 281 282 return aCode; 283 284 }; 285 286 287 // Attach Processing functions to 'p' 288 function buildProcessing( curElement ){ 289 290 // Create the 'p' object 291 var p = {}; 292 293 // Set Processing defaults / environment variables 294 p.name = 'Processing.js Instance'; 295 p.PI = Math.PI; 296 p.TWO_PI = 2 * p.PI; 297 p.HALF_PI = p.PI / 2; 298 p.P3D = 3; 299 p.CORNER = 0; 300 p.RADIUS = 1; 301 p.CENTER_RADIUS = 1; 302 p.CENTER = 2; 303 p.POLYGON = 2; 304 p.QUADS = 5; 305 p.TRIANGLES = 6; 306 p.POINTS = 7; 307 p.LINES = 8; 308 p.TRIANGLE_STRIP = 9; 309 p.TRIANGLE_FAN = 4; 310 p.QUAD_STRIP = 3; 311 p.CORNERS = 10; 312 p.CLOSE = true; 313 p.RGB = 1; 314 p.HSB = 2; 315 316 // KeyCode table 317 p.CENTER = 88888880; 318 p.CODED = 88888888; 319 p.UP = 88888870; 320 p.RIGHT = 88888871; 321 p.DOWN = 88888872; 322 p.LEFT = 88888869; 323 324 //! // Description required... 325 p.codedKeys = [ 69, 70, 71, 72 ]; 326 327 // "Private" variables used to maintain state 328 var curContext = curElement.getContext( "2d" ), 329 doFill = true, 330 doStroke = true, 331 loopStarted = false, 332 hasBackground = false, 333 doLoop = true, 334 looping = 0, 335 curRectMode = p.CORNER, 336 curEllipseMode = p.CENTER, 337 inSetup = false, 338 inDraw = false, 339 curBackground = "rgba( 204, 204, 204, 1 )", 340 curFrameRate = 1000, 341 curMsPerFrame = 1, 342 curShape = p.POLYGON, 343 curShapeCount = 0, 344 curvePoints = [], 345 curTightness = 0, 346 opacityRange = 255, 347 redRange = 255, 348 greenRange = 255, 349 blueRange = 255, 350 pathOpen = false, 351 mousePressed = false, 352 keyPressed = false, 353 curColorMode = p.RGB; 354 curTint = - 1, 355 curTextSize = 12, 356 curTextFont = "Arial", 357 getLoaded = false, 358 start = ( new Date ).getTime(); 359 360 var firstX, 361 firstY, 362 secondX, 363 secondY, 364 prevX, 365 prevY; 366 367 // Store a line for println(), print() handline 368 p.ln = ""; 369 370 // Glyph path storage for textFonts 371 p.glyphTable = {}; 372 373 // Global vars for tracking mouse position 374 p.pmouseX = 0; 375 p.pmouseY = 0; 376 p.mouseX = 0; 377 p.mouseY = 0; 378 p.mouseButton = 0; 379 p.mouseDown = false; 380 381 // Undefined event handlers to be replaced by user when needed 382 p.mouseClicked = undefined; 383 p.mouseDragged = undefined; 384 p.mouseMoved = undefined; 385 p.mousePressed = undefined; 386 p.mouseReleased = undefined; 387 p.keyPressed = undefined; 388 p.keyReleased = undefined; 389 p.draw = undefined; 390 p.setup = undefined; 391 392 // The height/width of the canvas 393 p.width = curElement.width - 0; 394 p.height = curElement.height - 0; 395 396 // The current animation frame 397 p.frameCount = 0; 398 399 400 401 //////////////////////////////////////////////////////////////////////////// 402 // Array handling 403 //////////////////////////////////////////////////////////////////////////// 404 405 p.shorten = function( ary ){ 406 407 var newary = new Array(); 408 409 // copy array into new array 410 var len = ary.length; 411 for( var i = 0; i < len; i++ ){ 412 newary[ i ] = ary[ i ]; 413 } 414 415 newary.pop(); 416 417 return newary; 418 } 419 420 421 p.expand = function( ary, newSize ){ 422 423 var newary = new Array(); 424 425 var len = ary.length 426 for( var i = 0; i < len; i++ ){ 427 newary[ i ] = ary[ i ]; 428 } 429 430 if( arguments.length == 1 ){ 431 432 // double size of array 433 newary.length *= 2; 434 435 }else if( arguments.length == 2 ){ 436 437 // size is newSize 438 newary.length = newSize; 439 440 } 441 442 return newary; 443 } 444 445 446 447 p.ArrayList = function ArrayList( size, size2, size3 ){ 448 449 var array = new Array( 0 | size ); 450 451 if( size2 ){ 452 453 for( var i = 0; i < size; i++ ){ 454 455 array[ i ] = []; 456 457 for( var j = 0; j < size2; j++ ){ 458 var a = array[ i ][ j ] = size3 ? new Array( size3 ) : 0 ; 459 for( var k = 0; k < size3; k++ ){ a[ k ] = 0; } 460 } 461 462 } 463 464 }else{ 465 466 for( var i = 0; i < size; i++ ){ array[ i ] = 0; } 467 } 468 469 array.get = function( i ){ return this[ i ]; }; 470 array.add = function( item ){ return this.push( item ); }; 471 array.size = function( ){ return this.length; }; 472 array.clear = function( ){ this.length = 0; }; 473 array.remove = function( i ){ return this.splice( i, 1 ); }; 474 array.isEmpty = function( ){ return !this.length; }; 475 array.clone = function( ){ 476 var a = new ArrayList( size ); 477 for( var i = 0; i < size; i++ ){ 478 a[ i ] = this[ i ]; 479 } 480 return a; 481 }; 482 483 return array; 484 }; 485 486 487 488 //////////////////////////////////////////////////////////////////////////// 489 // Color functions 490 //////////////////////////////////////////////////////////////////////////// 491 492 // In case I ever need to do HSV conversion: 493 // http://srufaculty.sru.edu/david.dailey/javascript/js/5rml.js 494 p.color = function color( aValue1, aValue2, aValue3, aValue4 ) { 495 var aColor = ""; 496 497 if ( arguments.length == 3 ) { 498 499 aColor = p.color( aValue1, aValue2, aValue3, opacityRange ); 500 } else if ( arguments.length == 4 ) { 501 var a = aValue4 / opacityRange; 502 a = isNaN(a) ? 1 : a; 503 504 if ( curColorMode == p.HSB ) { 505 var rgb = HSBtoRGB(aValue1, aValue2, aValue3); 506 var r = rgb[0], g = rgb[1], b = rgb[2]; 507 } else { 508 var r = getColor(aValue1, redRange); 509 var g = getColor(aValue2, greenRange); 510 var b = getColor(aValue3, blueRange); 511 } 512 513 aColor = "rgba(" + r + "," + g + "," + b + "," + a + ")"; 514 } else if ( typeof aValue1 == "string" ) { 515 aColor = aValue1; 516 517 if ( arguments.length == 2 ) { 518 var c = aColor.split(","); 519 c[3] = (aValue2 / opacityRange) + ")"; 520 aColor = c.join(","); 521 } 522 } else if ( arguments.length == 2 ) { 523 aColor = p.color( aValue1, aValue1, aValue1, aValue2 ); 524 } else if ( typeof aValue1 == "number" && aValue1 < 256 && aValue1 >= 0) { 525 aColor = p.color( aValue1, aValue1, aValue1, opacityRange ); 526 } else if ( typeof aValue1 == "number" ) { 527 var intcolor = 0; 528 if( aValue1 < 0 ){ 529 intcolor = 4294967296 - ( aValue1 * -1 ); 530 }else{ 531 intcolor = aValue1; 532 } 533 var ac = Math.floor((intcolor % 4294967296) / 16777216); 534 var rc = Math.floor((intcolor % 16777216) / 65536); 535 var gc = Math.floor((intcolor % 65536) / 256); 536 var bc = intcolor % 256; 537 538 aColor = p.color( rc, gc, bc, ac ); 539 } else { 540 aColor = p.color( redRange, greenRange, blueRange, opacityRange ); 541 } 542 543 // HSB conversion function from Mootools, MIT Licensed 544 function HSBtoRGB(h, s, b) { 545 h = (h / redRange) * 360; 546 s = (s / greenRange) * 100; 547 b = (b / blueRange) * 100; 548 var br = Math.round(b / 100 * 255); 549 if (s == 0){ 550 return [br, br, br]; 551 } else { 552 var hue = h % 360; 553 var f = hue % 60; 554 var p = Math.round((b * (100 - s)) / 10000 * 255); 555 var q = Math.round((b * (6000 - s * f)) / 600000 * 255); 556 var t = Math.round((b * (6000 - s * (60 - f))) / 600000 * 255); 557 switch (Math.floor(hue / 60)){ 558 case 0: return [br, t, p]; 559 case 1: return [q, br, p]; 560 case 2: return [p, br, t]; 561 case 3: return [p, q, br]; 562 case 4: return [t, p, br]; 563 case 5: return [br, p, q]; 564 } 565 } 566 } 567 568 function getColor( aValue, range ) { 569 return Math.round(255 * (aValue / range)); 570 } 571 572 return aColor; 573 } 574 575 p.red = function( aColor ){ return parseInt( verifyChannel( aColor ).slice( 5 ) ); }; 576 p.green = function( aColor ){ return parseInt( verifyChannel( aColor ).split( "," )[ 1 ] ); }; 577 p.blue = function( aColor ){ return parseInt( verifyChannel( aColor ).split( "," )[ 2 ] ); }; 578 p.alpha = function( aColor ){ return parseInt( parseFloat( verifyChannel( aColor ).split( "," )[ 3 ] ) * 255 ); }; 579 580 function verifyChannel( aColor ){ 581 if( aColor.constructor == Array ){ 582 return aColor; 583 } else { 584 return p.color( aColor ); 585 } 586 } 587 588 p.lerpColor = function lerpColor( c1, c2, amt ){ 589 590 // Get RGBA values for Color 1 to floats 591 var colors1 = p.color( c1 ).split( "," ); 592 var r1 = parseInt( colors1[ 0 ].split( "(" )[ 1 ] ); 593 var g1 = parseInt( colors1[ 1 ] ); 594 var b1 = parseInt( colors1[ 2 ] ); 595 var a1 = parseFloat( colors1[ 3 ].split( ")" )[ 0 ] ); 596 597 // Get RGBA values for Color 2 to floats 598 var colors2 = p.color( c2 ).split( "," ); 599 var r2 = parseInt( colors2[ 0 ].split( "(" )[ 1 ] ); 600 var g2 = parseInt( colors2[ 1 ] ); 601 var b2 = parseInt( colors2[ 2 ] ); 602 var a2 = parseFloat( colors2[ 3 ].split( ")" )[ 0 ] ); 603 604 // Return lerp value for each channel, INT for color, Float for Alpha-range 605 var r = parseInt( p.lerp( r1, r2, amt ) ); 606 var g = parseInt( p.lerp( g1, g2, amt ) ); 607 var b = parseInt( p.lerp( b1, b2, amt ) ); 608 var a = parseFloat( p.lerp( a1, a2, amt ) ); 609 610 return aColor = "rgba("+ r +","+ g +","+ b +","+ a +")"; 611 612 } 613 614 // Forced default color mode for #aaaaaa style 615 p.DefaultColor = function( aValue1, aValue2, aValue3 ){ 616 var tmpColorMode = curColorMode; 617 curColorMode = p.RGB; 618 var c = p.color(aValue1 / 255 * redRange, aValue2 / 255 * greenRange, aValue3 / 255 * blueRange ); 619 curColorMode = tmpColorMode; 620 return c; 621 } 622 623 p.colorMode = function colorMode( mode, range1, range2, range3, range4 ){ 624 curColorMode = mode; 625 if( arguments.length >= 4 ){ redRange = range1; greenRange = range2; blueRange = range3; } 626 if( arguments.length == 5 ){ opacityRange = range4; } 627 if( arguments.length == 2 ){ p.colorMode( mode, range1, range1, range1, range1 ); } 628 }; 629 630 631 //////////////////////////////////////////////////////////////////////////// 632 // Canvas-Matrix manipulation 633 //////////////////////////////////////////////////////////////////////////// 634 635 p.translate = function translate( x, y ){ curContext.translate( x, y ); }; 636 p.scale = function scale( x, y ) { curContext.scale( x, y || x ); }; 637 p.rotate = function rotate( aAngle ) { curContext.rotate( aAngle ); }; 638 p.pushMatrix = function pushMatrix() { curContext.save(); }; 639 p.popMatrix = function popMatrix() { curContext.restore(); }; 640 p.ortho = function ortho(){}; 641 642 643 644 //////////////////////////////////////////////////////////////////////////// 645 //Time based functions 646 //////////////////////////////////////////////////////////////////////////// 647 648 p.year = function year() { return ( new Date ).getYear() + 1900; }; 649 p.month = function month() { return ( new Date ).getMonth(); }; 650 p.day = function day() { return ( new Date ).getDay(); }; 651 p.hour = function hour() { return ( new Date ).getHours(); }; 652 p.minute = function minute(){ return ( new Date ).getMinutes(); }; 653 p.second = function second(){ return ( new Date ).getSeconds(); }; 654 p.millis = function millis(){ return ( new Date ) .getTime() - start; }; 655 656 p.noLoop = function noLoop(){ doLoop = false; }; 657 658 p.redraw = function redraw(){ 659 if( hasBackground ){ p.background(); } 660 p.frameCount++; 661 inDraw = true; 662 p.pushMatrix(); 663 p.draw(); 664 p.popMatrix(); 665 inDraw = false; 666 }; 667 668 p.loop = function loop(){ 669 670 if( loopStarted ){ return; } 671 672 looping = setInterval( function(){ 673 674 try { 675 p.redraw(); 676 } 677 catch( e ){ 678 clearInterval( looping ); 679 throw e; 680 } 681 }, curMsPerFrame ); 682 683 loopStarted = true; 684 685 }; 686 687 p.frameRate = function frameRate( aRate ){ 688 curFrameRate = aRate; 689 curMsPerFrame = 1000 / curFrameRate; 690 }; 691 692 p.exit = function exit(){ 693 clearInterval( looping ); 694 }; 695 696 697 698 //////////////////////////////////////////////////////////////////////////// 699 // MISC functions 700 //////////////////////////////////////////////////////////////////////////// 701 p.cursor = function(mode){ document.body.style.cursor=mode; } 702 p.link = function( href, target ) { window.location = href; }; 703 p.beginDraw = function beginDraw(){}; 704 p.endDraw = function endDraw(){}; 705 706 p.ajax = ajax; 707 708 // Imports an external Processing.js library 709 p.Import = function Import( lib ){ 710 eval( p.ajax( lib ) ); 711 } 712 713 714 715 //////////////////////////////////////////////////////////////////////////// 716 // String functions 717 //////////////////////////////////////////////////////////////////////////// 718 719 p.nfs = function( num, left, right){ 720 var str; 721 // array handling 722 if (typeof num == "object"){ 723 str = new Array(); 724 len = num.length; 725 for(var i=0; i < len; i++){ 726 str[i] = p.nfs(num[i], left, right); 727 } 728 } 729 else if (arguments.length == 3){ 730 var negative = false; 731 if (num < 0) 732 negative = true; 733 734 str = "" + Math.abs(num); 735 var digits = ("" + Math.floor(Math.abs(num))).length; 736 var count = left - digits; 737 while (count > 0){ 738 str = "0" + str; 739 count--; 740 } 741 // get the number of decimal places, if none will be -1 742 var decimals = ("" + Math.abs(num)).length - digits - 1; 743 if (decimals == -1 && right > 0) 744 str = str + "."; 745 if (decimals != -1) 746 count = right - decimals; 747 else if (decimals == -1 && right > 0){ 748 count = right; 749 } 750 else 751 count = 0; 752 while (count > 0){ 753 str = str + "0"; 754 count--; 755 } 756 str = (negative ? "-" : " ") + str; 757 } 758 else if (arguments.length == 2){ 759 str = p.nfs(num, left, 0); 760 } 761 return str; 762 } 763 764 765 p.unhex = function( str ){ 766 var value = 0, 767 multiplier = 1, 768 num = 0; 769 770 var len = str.length - 1; 771 for (var i = len ; i >= 0; i--){ 772 try{ 773 switch(str[i]){ 774 case "0": num = 0; break; 775 case "1": num = 1; break; 776 case "2": num = 2; break; 777 case "3": num = 3; break; 778 case "4": num = 4; break; 779 case "5": num = 5; break; 780 case "6": num = 6; break; 781 case "7": num = 7; break; 782 case "8": num = 8; break; 783 case "9": num = 9; break; 784 case "A": 785 case "a": num = 10; break; 786 case "B": 787 case "b": num = 11; break; 788 case "C": 789 case "c": num = 12; break; 790 case "D": 791 case "d": num = 13; break; 792 case "E": 793 case "e": num = 14; break; 794 case "F": 795 case "f": num = 15; break; 796 default:return 0; break; 797 } 798 value += num * multiplier; 799 multiplier *= 16; 800 }catch(e){;} 801 // correct for int overflow java expectation 802 if (value > 2147483647) 803 { 804 value -= 4294967296; 805 } 806 } 807 return value; 808 } 809 810 811 // Load a file or URL into strings 812 p.loadStrings = function loadStrings( url ){ 813 return p.ajax( url ).split( "\n" ); 814 }; 815 816 p.nf = function( num, pad ){ 817 var str = "" + num; 818 while ( pad - str.length ){ 819 str = "0" + str; 820 } 821 return str; 822 }; 823 824 String.prototype.replaceAll = function( re, replace ){ 825 return this.replace( new RegExp( re, "g" ), replace ); 826 }; 827 828 // Returns a line to lnPrinted() for user handling 829 p.lnPrinted = function lnPrinted(){}; 830 p.printed = function printed() {}; 831 832 // Event to send output to user control function print()/println() 833 p.println = function println(){ 834 835 // Not working on Safari :( find work around! 836 if( arguments.callee.caller ){ 837 838 var Caller = arguments.callee.caller.name.toString(); 839 840 if( arguments.length > 1 ){ 841 842 Caller != "print" ? 843 p.ln = arguments : 844 p.ln = arguments[ 0 ] ; 845 846 }else{ 847 848 p.ln = arguments[ 0 ] ; 849 } 850 851 //Returns a line to lnPrinted() for user error handling/debugging 852 Caller == "print" ? 853 p.printed( arguments ) : 854 p.lnPrinted() ; 855 856 } 857 858 }; 859 860 // Converts a number to a string 861 p.str = function str( aNumber ){ return aNumber+''; } 862 863 p.print = function print(){ p.println(arguments[ 0 ] ) }; 864 865 p.char = function char( key ){ return key; }; 866 867 868 869 //////////////////////////////////////////////////////////////////////////// 870 // Math functions 871 //////////////////////////////////////////////////////////////////////////// 872 873 p.sq = function sq ( aNumber ){ return aNumber * aNumber; }; 874 p.sqrt = function sqrt ( aNumber ){ return Math.sqrt( aNumber ); }; 875 p.int = function int ( aNumber ){ return Math.floor( aNumber ); }; 876 p.min = function min ( aNumber, aNumber2 ){ return Math.min( aNumber, aNumber2 ); }; 877 p.max = function max ( aNumber, aNumber2 ){ return Math.max( aNumber, aNumber2 ); }; 878 p.floor = function floor ( aNumber ){ return Math.floor( aNumber ); }; 879 p.float = function float ( aNumber ){ return parseFloat( aNumber ); }; 880 p.ceil = function ceil ( aNumber ){ return Math.ceil( aNumber ); }; 881 p.round = function round ( aNumber ){ return Math.round( aNumber ); }; 882 p.lerp = function lerp ( value1, value2, amt ){ return ( ( value2 - value1 ) * amt ) + value1; }; 883 p.abs = function abs ( aNumber ){ return Math.abs( aNumber ); }; 884 p.cos = function cos ( aNumber ){ return Math.cos( aNumber ); }; 885 p.sin = function sin ( aNumber ){ return Math.sin( aNumber ); }; 886 p.pow = function pow ( aNumber, aExponent ){ return Math.pow( aNumber, aExponent ); }; 887 p.sqrt = function sqrt ( aNumber ){ return Math.sqrt( aNumber ); }; 888 p.atan2 = function atan2 ( aNumber, aNumber2 ){ return Math.atan2( aNumber, aNumber2 ); }; 889 p.radians = function radians( aAngle ){ return ( aAngle / 180 ) * p.PI; }; 890 891 p.dist = function dist( x1, y1, x2, y2 ){ 892 return Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) ); 893 }; 894 895 p.map = function map( value, istart, istop, ostart, ostop ){ 896 return ostart + ( ostop - ostart ) * ( ( value - istart ) / ( istop - istart ) ); 897 }; 898 899 p.Random = function(){ 900 901 var haveNextNextGaussian = false, 902 nextNextGaussian; 903 904 this.nextGaussian = function(){ 905 906 if( haveNextNextGaussian ){ 907 908 haveNextNextGaussian = false; 909 return nextNextGaussian; 910 911 }else{ 912 913 var v1, v2, s; 914 do{ 915 v1 = 2 * p.random( 1 ) - 1; // between -1.0 and 1.0 916 v2 = 2 * p.random( 1 ) - 1; // between -1.0 and 1.0 917 s = v1 * v1 + v2 * v2; 918 } 919 while( s >= 1 || s == 0 ); 920 921 var multiplier = Math.sqrt( - 2 * Math.log( s ) / s ); 922 nextNextGaussian = v2 * multiplier; 923 haveNextNextGaussian = true; 924 925 return v1 * multiplier; 926 927 } 928 929 }; 930 931 }; 932 933 //! This can't be right... right? 934 p.byte = function byte( aNumber ){ return aNumber || 0; }; 935 936 p.norm = function norm( aNumber, low, high ){ 937 var range = high-low; 938 return ( ( 1 / range ) * aNumber ) - ( ( 1 / range ) * low ); 939 }; 940 941 p.random = function random( aMin, aMax ) { 942 return arguments.length == 2 ? 943 aMin + ( Math.random() * ( aMax - aMin ) ) : 944 Math.random() * aMin ; 945 }; 946 947 // From: http://freespace.virgin.net/hugo.elias/models/m_perlin.htm 948 p.noise = function( x, y, z ){ 949 return arguments.length >= 2 ? 950 PerlinNoise_2D( x, y, z ) : 951 PerlinNoise_3D( x, x, z ) ; 952 }; 953 954 function Noise( x, y ){ 955 var n = x + y * 57; 956 n = ( n << 13 ) ^ n; 957 return Math.abs( 1.0 - ( ( ( n * ( ( n * n * 15731 ) + 789221 ) + 1376312589 ) & 0x7fffffff ) / 1073741824.0 ) ); 958 }; 959 960 function SmoothedNoise( x, y ){ 961 var corners = ( Noise( x - 1, y - 1 ) + Noise( x + 1, y - 1 ) + Noise( x - 1, y + 1 ) + Noise( x + 1, y + 1 ) ) / 16, 962 sides = ( Noise( x - 1, y ) + Noise( x + 1, y ) + Noise( x, y - 1 ) + Noise( x, y + 1 ) ) / 8, 963 center = Noise( x, y ) / 4; 964 return corners + sides + center; 965 }; 966 967 function InterpolatedNoise( x, y ){ 968 969 var integer_X = Math.floor( x ); 970 var fractional_X = x - integer_X; 971 972 var integer_Y = Math.floor( y ); 973 var fractional_Y = y - integer_Y; 974 975 var v1 = SmoothedNoise( integer_X, integer_Y ), 976 v2 = SmoothedNoise( integer_X + 1, integer_Y ), 977 v3 = SmoothedNoise( integer_X, integer_Y + 1 ), 978 v4 = SmoothedNoise( integer_X + 1, integer_Y + 1 ); 979 980 var i1 = Interpolate( v1, v2, fractional_X ), 981 i2 = Interpolate( v3, v4, fractional_X ); 982 983 return Interpolate( i1, i2, fractional_Y ); 984 985 } 986 987 988 function PerlinNoise_2D( x, y ){ 989 990 var total = 0, 991 p = 0.25, 992 n = 3; 993 994 for( var i = 0; i <= n; i++ ){ 995 var frequency = Math.pow( 2, i ); 996 var amplitude = Math.pow( p, i ); 997 total += InterpolatedNoise( x * frequency, y * frequency ) * amplitude; 998 } 999 1000 return total; 1001 } 1002 1003 function Interpolate( a, b, x ){ 1004 var ft = x * p.PI; 1005 var f = (1 - Math.cos( ft ) ) * .5; 1006 return a * ( 1 - f ) + b * f; 1007 } 1008 1009 p.constrain = function constrain( aNumber, aMin, aMax ){ 1010 return Math.min( Math.max( aNumber, aMin ), aMax ); 1011 }; 1012 1013 p.degrees = function degrees( aAngle ){ 1014 aAngle = ( aAngle * 180 ) / p.PI; 1015 if (aAngle < 0) {aAngle = 360 + aAngle} 1016 return aAngle; 1017 }; 1018 1019 p.size = function size( aWidth, aHeight ){ 1020 var fillStyle = curContext.fillStyle, 1021 strokeStyle = curContext.strokeStyle; 1022 1023 curElement.width = p.width = aWidth; 1024 curElement.height = p.height = aHeight; 1025 1026 curContext.fillStyle = fillStyle; 1027 curContext.strokeStyle = strokeStyle; 1028 }; 1029 1030 1031 1032 //////////////////////////////////////////////////////////////////////////// 1033 // Style functions 1034 //////////////////////////////////////////////////////////////////////////// 1035 1036 p.noStroke = function noStroke() { doStroke = false; }; 1037 p.noFill = function noFill() { doFill = false; }; 1038 p.smooth = function smooth() {}; 1039 p.noSmooth = function noSmooth() {}; 1040 1041 p.fill = function fill(){ 1042 doFill = true; 1043 curContext.fillStyle = p.color.apply( this, arguments ); 1044 }; 1045 1046 p.stroke = function stroke(){ 1047 doStroke = true; 1048 curContext.strokeStyle = p.color.apply( this, arguments ); 1049 }; 1050 1051 p.strokeWeight = function strokeWeight( w ){ 1052 curContext.lineWidth = w; 1053 }; 1054 1055 1056 1057 //////////////////////////////////////////////////////////////////////////// 1058 // Vector drawing functions 1059 //////////////////////////////////////////////////////////////////////////// 1060 1061 p.Point = function Point( x, y ){ 1062 this.x = x; 1063 this.y = y; 1064 this.copy = function(){ 1065 return new Point( x, y ); 1066 } 1067 }; 1068 1069 p.point = function point( x, y ){ 1070 var oldFill = curContext.fillStyle; 1071 curContext.fillStyle = curContext.strokeStyle; 1072 curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 ); 1073 curContext.fillStyle = oldFill; 1074 }; 1075 1076 p.beginShape = function beginShape( type ){ 1077 curShape = type; 1078 curShapeCount = 0; 1079 curvePoints = []; 1080 }; 1081 1082 p.endShape = function endShape( close ){ 1083 1084 if( curShapeCount != 0 ){ 1085 1086 if( close || doFill ){ curContext.lineTo( firstX, firstY ); } 1087 if( doFill ){ curContext.fill(); } 1088 if( doStroke ){ curContext.stroke(); } 1089 1090 curContext.closePath(); 1091 curShapeCount = 0; 1092 pathOpen = false; 1093 1094 } 1095 1096 if( pathOpen ){ 1097 1098 if ( doFill ){ curContext.fill(); } 1099 if ( doStroke ){ curContext.stroke(); } 1100 1101 curContext.closePath(); 1102 curShapeCount = 0; 1103 pathOpen = false; 1104 1105 } 1106 1107 }; 1108 1109 p.vertex = function vertex( x, y, x2, y2, x3, y3 ){ 1110 1111 if( curShapeCount == 0 && curShape != p.POINTS ){ 1112 1113 pathOpen = true; 1114 curContext.beginPath(); 1115 curContext.moveTo( x, y ); 1116 firstX = x; 1117 firstY = y; 1118 1119 }else{ 1120 1121 if( curShape == p.POINTS ){ 1122 1123 p.point( x, y ); 1124 1125 }else if( arguments.length == 2 ){ 1126 1127 if( curShape != p.QUAD_STRIP || curShapeCount != 2 ){ 1128 1129 curContext.lineTo( x, y ); 1130 1131 } 1132 1133 if( curShape == p.TRIANGLE_STRIP ){ 1134 1135 if( curShapeCount == 2 ){ 1136 1137 // finish shape 1138 p.endShape( p.CLOSE ); 1139 pathOpen = true; 1140 curContext.beginPath(); 1141 1142 // redraw last line to start next shape 1143 curContext.moveTo( prevX, prevY ); 1144 curContext.lineTo( x, y ); 1145 curShapeCount = 1; 1146 1147 } 1148 1149 firstX = prevX; 1150 firstY = prevY; 1151 1152 } 1153 1154 if( curShape == p.TRIANGLE_FAN && curShapeCount == 2 ){ 1155 1156 // finish shape 1157 p.endShape( p.CLOSE) ; 1158 pathOpen = true; 1159 curContext.beginPath(); 1160 1161 // redraw last line to start next shape 1162 curContext.moveTo( firstX, firstY ); 1163 curContext.lineTo( x, y ); 1164 curShapeCount = 1; 1165 1166 } 1167 1168 if( curShape == p.QUAD_STRIP && curShapeCount == 3 ){ 1169 1170 // finish shape 1171 curContext.lineTo( prevX, prevY ); 1172 p.endShape(p.CLOSE); 1173 pathOpen = true; 1174 curContext.beginPath(); 1175 1176 // redraw lines to start next shape 1177 curContext.moveTo( prevX, prevY ); 1178 curContext.lineTo( x, y ); 1179 curShapeCount = 1; 1180 1181 } 1182 1183 if( curShape == p.QUAD_STRIP ){ 1184 1185 firstX = secondX; 1186 firstY = secondY; 1187 secondX = prevX; 1188 secondY = prevY; 1189 1190 } 1191 1192 }else if( arguments.length == 4 ){ 1193 1194 if( curShapeCount > 1 ){ 1195 1196 curContext.moveTo( prevX, prevY ); 1197 curContext.quadraticCurveTo( firstX, firstY, x, y ); 1198 curShapeCount = 1; 1199 1200 } 1201 1202 }else if( arguments.length == 6 ){ 1203 1204 curContext.bezierCurveTo( x, y, x2, y2, x3, y3 ); 1205 1206 } 1207 } 1208 1209 prevX = x; 1210 prevY = y; 1211 curShapeCount ++; 1212 1213 if( curShape == p.LINES && curShapeCount == 2 || 1214 ( curShape == p.TRIANGLES ) && curShapeCount == 3 || 1215 ( curShape == p.QUADS ) && curShapeCount == 4 1216 ){ 1217 p.endShape( p.CLOSE ); 1218 } 1219 1220 }; 1221 1222 p.curveVertex = function( x, y, x2, y2 ){ 1223 1224 if( curvePoints.length < 3 ){ 1225 1226 curvePoints.push( [ x, y ] ); 1227 1228 }else{ 1229 1230 var b = [], s = 1 - curTightness; 1231 1232 /* 1233 * Matrix to convert from Catmull-Rom to cubic Bezier 1234 * where t = curTightness 1235 * |0 1 0 0 | 1236 * |(t-1)/6 1 (1-t)/6 0 | 1237 * |0 (1-t)/6 1 (t-1)/6 | 1238 * |0 0 0 0 | 1239 */ 1240 1241 curvePoints.push( [ x, y ] ); 1242 1243 b[ 0 ] = [ curvePoints[ 1 ][ 0 ], curvePoints[ 1 ][ 1 ] ]; 1244 b[ 1 ] = [ curvePoints[ 1 ][ 0 ] + ( s * curvePoints[ 2 ][ 0 ] - s * curvePoints[ 0 ][ 0 ] ) / 6, curvePoints[ 1 ][ 1 ] + ( s * curvePoints[ 2 ][ 1 ] - s * curvePoints[ 0 ][ 1 ] ) / 6 ]; 1245 b[ 2 ] = [ curvePoints[ 2 ][ 0 ] + ( s * curvePoints[ 1 ][ 0 ] - s * curvePoints[ 3 ][ 0 ] ) / 6, curvePoints[ 2 ][ 1 ] + ( s * curvePoints[ 1 ][ 1 ] - s * curvePoints[ 3 ][ 1 ] ) / 6 ]; 1246 b[ 3 ] = [ curvePoints[ 2 ][ 0 ], curvePoints[ 2 ][ 1 ] ]; 1247 1248 if( !pathOpen ){ 1249 p.vertex( b[ 0 ][ 0 ], b[ 0 ][ 1 ] ); 1250 }else{ 1251 curShapeCount = 1; 1252 } 1253 1254 p.vertex( 1255 b[ 1 ][ 0 ], 1256 b[ 1 ][ 1 ], 1257 b[ 2 ][ 0 ], 1258 b[ 2 ][ 1 ], 1259 b[ 3 ][ 0 ], 1260 b[ 3 ][ 1 ] 1261 ); 1262 1263 curvePoints.shift(); 1264 } 1265 1266 }; 1267 1268 p.curveTightness = function( tightness ){ curTightness = tightness; }; 1269 1270 p.bezierVertex = p.vertex; 1271 1272 p.rectMode = function rectMode( aRectMode ){ curRectMode = aRectMode; }; 1273 p.imageMode = function (){}; 1274 p.ellipseMode = function ellipseMode( aEllipseMode ) { curEllipseMode = aEllipseMode; }; 1275 1276 p.arc = function arc( x, y, width, height, start, stop ){ 1277 1278 if( width <= 0 ){ return; } 1279 1280 if( curEllipseMode == p.CORNER ){ 1281 x += width / 2; 1282 y += height / 2; 1283 } 1284 1285 curContext.moveTo( x, y ); 1286 curContext.beginPath(); 1287 curContext.arc( x, y, curEllipseMode == p.CENTER_RADIUS ? width : width/2, start, stop, false ); 1288 1289 if( doStroke ){ curContext.stroke(); } 1290 curContext.lineTo( x, y ); 1291 1292 if( doFill ){ curContext.fill(); } 1293 curContext.closePath(); 1294 1295 }; 1296 1297 p.line = function line( x1, y1, x2, y2 ){ 1298 curContext.lineCap = "round"; 1299 curContext.beginPath(); 1300 curContext.moveTo( x1 || 0, y1 || 0 ); 1301 curContext.lineTo( x2 || 0, y2 || 0 ); 1302 curContext.stroke(); 1303 curContext.closePath(); 1304 }; 1305 1306 p.bezier = function bezier( x1, y1, x2, y2, x3, y3, x4, y4 ){ 1307 curContext.lineCap = "butt"; 1308 curContext.beginPath(); 1309 curContext.moveTo( x1, y1 ); 1310 curContext.bezierCurveTo( x2, y2, x3, y3, x4, y4 ); 1311 curContext.stroke(); 1312 curContext.closePath(); 1313 }; 1314 1315 p.triangle = function triangle( x1, y1, x2, y2, x3, y3 ){ 1316 p.beginShape(); 1317 p.vertex( x1, y1 ); 1318 p.vertex( x2, y2 ); 1319 p.vertex( x3, y3 ); 1320 p.endShape(); 1321 }; 1322 1323 p.quad = function quad( x1, y1, x2, y2, x3, y3, x4, y4 ){ 1324 curContext.lineCap = "square"; 1325 p.beginShape(); 1326 p.vertex( x1, y1 ); 1327 p.vertex( x2, y2 ); 1328 p.vertex( x3, y3 ); 1329 p.vertex( x4, y4 ); 1330 p.endShape(); 1331 }; 1332 1333 p.rect = function rect( x, y, width, height ){ 1334 1335 if( !( width + height ) ){ return; } 1336 1337 curContext.beginPath(); 1338 1339 var offsetStart = 0; 1340 var offsetEnd = 0; 1341 1342 if( curRectMode == p.CORNERS ){ 1343 width -= x; 1344 height -= y; 1345 } 1346 1347 if( curRectMode == p.RADIUS ){ 1348 width *= 2; 1349 height *= 2; 1350 } 1351 1352 if( curRectMode == p.CENTER || curRectMode == p.RADIUS ){ 1353 x -= width / 2; 1354 y -= height / 2; 1355 } 1356 1357 curContext.rect( 1358 Math.round( x ) - offsetStart, 1359 Math.round( y ) - offsetStart, 1360 Math.round( width ) + offsetEnd, 1361 Math.round( height ) + offsetEnd 1362 ); 1363 1364 if( doFill ){ curContext.fill(); } 1365 if( doStroke ){ curContext.stroke() }; 1366 1367 curContext.closePath(); 1368 1369 }; 1370 1371 p.ellipse = function ellipse( x, y, width, height ){ 1372 1373 x = x || 0; 1374 y = y || 0; 1375 1376 if( width <= 0 && height <= 0 ){ return; } 1377 1378 curContext.beginPath(); 1379 1380 if( curEllipseMode == p.RADIUS ){ 1381 width *= 2; 1382 height *= 2; 1383 } 1384 1385 var offsetStart = 0; 1386 1387 // Shortcut for drawing a circle 1388 if( width == height ){ 1389 1390 curContext.arc( x - offsetStart, y - offsetStart, width / 2, 0, p.TWO_PI, false ); 1391 1392 }else{ 1393 1394 var w = width/2, 1395 h = height/2, 1396 C = 0.5522847498307933; 1397 var c_x = C * w, 1398 c_y = C * h; 1399 1400 //! Do we still need this? I hope the Canvas arc() more capable by now? 1401 curContext.moveTo( x + w, y ); 1402 curContext.bezierCurveTo( x+w , y-c_y , x+c_x , y-h , x , y-h ); 1403 curContext.bezierCurveTo( x-c_x , y-h , x-w , y-c_y , x-w , y ); 1404 curContext.bezierCurveTo( x-w , y+c_y , x-c_x , y+h, x, y+h ); 1405 curContext.bezierCurveTo( x+c_x , y+h , x+w , y+c_y , x+w , y ); 1406 1407 } 1408 1409 if( doFill ){ curContext.fill(); } 1410 if( doStroke ){ curContext.stroke(); } 1411 1412 curContext.closePath(); 1413 1414 }; 1415 1416 1417 1418 //////////////////////////////////////////////////////////////////////////// 1419 // Raster drawing functions 1420 //////////////////////////////////////////////////////////////////////////// 1421 1422 p.save = function save( file ){}; 1423 1424 // Loads an image for display. Type is unused. Callback is fired on load. 1425 p.loadImage = function loadImage( file, type, callback ){ 1426 1427 var img = document.createElement( 'img' ); 1428 img.src = file; 1429 1430 img.onload = function(){ 1431 1432 var h = this.height, 1433 w = this.width; 1434 1435 var canvas = document.createElement( "canvas" ); 1436 canvas.width = w; 1437 canvas.height = h; 1438 var context = canvas.getContext( "2d" ); 1439 1440 context.drawImage( this, 0, 0 ); 1441 this.data = buildImageObject( context.getImageData( 0, 0, w, h ) ); 1442 this.data.img = img; 1443 1444 callback?callback():0; 1445 1446 } 1447 1448 return img; 1449 1450 }; 1451 1452 // Gets a single pixel or block of pixels from the current Canvas Context 1453 p.get = function get( x, y ){ 1454 1455 if( !arguments.length ){ 1456 var c = p.createGraphics( p.width, p.height ); 1457 c.image( curContext, 0, 0 ); 1458 return c; 1459 } 1460 1461 if( !getLoaded ){ 1462 getLoaded = buildImageObject( curContext.getImageData( 0, 0, p.width, p.height ) ); 1463 } 1464 1465 return getLoaded.get( x, y ); 1466 1467 }; 1468 1469 // Creates a new Processing instance and passes it back for... processing 1470 p.createGraphics = function createGraphics( w, h ){ 1471 1472 var canvas = document.createElement( "canvas" ); 1473 var ret = buildProcessing( canvas ); 1474 ret.size( w, h ); 1475 ret.canvas = canvas; 1476 return ret; 1477 1478 }; 1479 1480 // Paints a pixel array into the canvas 1481 p.set = function set( x, y, obj ){ 1482 1483 if( obj && obj.img ){ 1484 1485 p.image( obj, x, y ); 1486 1487 }else{ 1488 1489 var oldFill = curContext.fillStyle, 1490 color = obj; 1491 1492 curContext.fillStyle = color; 1493 curContext.fillRect( Math.round( x ), Math.round( y ), 1, 1 ); 1494 curContext.fillStyle = oldFill; 1495 1496 } 1497 1498 }; 1499 1500 // Gets a 1-Dimensional pixel array from Canvas 1501 p.loadPixels = function(){ 1502 p.pixels = buildImageObject( curContext.getImageData(0, 0, p.width, p.height) ).pixels; 1503 }; 1504 1505 // Draws a 1-Dimensional pixel array to Canvas 1506 p.updatePixels = function() { 1507 1508 var colors = /(\d+),(\d+),(\d+),(\d+)/, 1509 pixels = {}; 1510 1511 pixels.width = p.width; 1512 pixels.height = p.height; 1513 pixels.data = []; 1514 1515 if( curContext.createImageData ){ 1516 pixels = curContext.createImageData( p.width, p.height ); 1517 } 1518 1519 var data = pixels.data, 1520 pos = 0; 1521 1522 for( var i = 0, l = p.pixels.length; i < l; i++ ){ 1523 1524 var c = ( p.pixels[i] || "rgba(0,0,0,1)" ).match( colors ); 1525 1526 data[ pos + 0 ] = parseInt( c[ 1 ] ); 1527 data[ pos + 1 ] = parseInt( c[ 2 ] ); 1528 data[ pos + 2 ] = parseInt( c[ 3 ] ); 1529 data[ pos + 3 ] = parseFloat( c[ 4 ] ) * 255; 1530 1531 pos += 4; 1532 1533 } 1534 1535 curContext.putImageData( pixels, 0, 0 ); 1536 1537 }; 1538 1539 // Draw an image or a color to the background 1540 p.background = function background( img ) { 1541 1542 if( arguments.length ){ 1543 1544 if( img.data && img.data.img ){ 1545 curBackground = img.data; 1546 }else{ 1547 curBackground = p.color.apply( this, arguments ); 1548 } 1549 1550 } 1551 1552 if( curBackground.img ){ 1553 1554 p.image( img, 0, 0 ); 1555 1556 }else{ 1557 1558 var oldFill = curContext.fillStyle; 1559 curContext.fillStyle = curBackground + ""; 1560 curContext.fillRect( 0, 0, p.width, p.height ); 1561 curContext.fillStyle = oldFill; 1562 1563 } 1564 1565 }; 1566 1567 p.AniSprite = function( prefix, frames ){ 1568 this.images = []; 1569 this.pos = 0; 1570 1571 for( var i = 0; i < frames; i++ ){ 1572 this.images.push( prefix + p.nf( i, ( "" + frames ).length ) + ".gif" ); 1573 } 1574 1575 this.display = function( x, y ){ 1576 p.image_old( this.images[ this.pos ], x, y ); 1577 1578 if( ++this.pos >= frames ){ 1579 this.pos = 0; 1580 } 1581 }; 1582 1583 this.getWidth = function(){ return getImage_old( this.images[ 0 ] ).width; }; 1584 this.getHeight = function(){ return getImage_old( this.images[ 0 ] ).height; }; 1585 }; 1586 1587 function buildImageObject( obj ){ 1588 1589 var pixels = obj.data; 1590 var data = p.createImage( obj.width, obj.height ); 1591 1592 if( data.__defineGetter__ && data.__lookupGetter__ && !data.__lookupGetter__( "pixels" ) ){ 1593 1594 var pixelsDone; 1595 1596 data.__defineGetter__( "pixels", function(){ 1597 1598 if( pixelsDone ){ 1599 return pixelsDone; 1600 } 1601 pixelsDone = []; 1602 1603 for( var i = 0; i < pixels.length; i += 4 ){ 1604 pixelsDone.push( 1605 p.color( 1606 pixels[ i ], 1607 pixels[ i + 1 ], 1608 pixels[ i + 2 ], 1609 pixels[ i + 3 ]) 1610 ); 1611 } 1612 1613 return pixelsDone; 1614 1615 }); 1616 1617 }else{ 1618 1619 data.pixels = []; 1620 1621 for ( var i = 0; i < pixels.length; i += 4 ){ 1622 data.pixels.push( p.color( 1623 pixels[ i ], 1624 pixels[ i + 1 ], 1625 pixels[ i + 2 ], 1626 pixels[ i + 3 ] 1627 )); 1628 } 1629 1630 } 1631 1632 return data; 1633 } 1634 1635 p.createImage = function createImage( w, h, mode ){ 1636 1637 var data = {}; 1638 data.width = w; 1639 data.height = h; 1640 data.data = []; 1641 1642 if( curContext.createImageData ) { 1643 data = curContext.createImageData( w, h ); 1644 } 1645 1646 data.pixels = new Array( w * h ); 1647 1648 data.get = function( x, y ){ 1649 return this.pixels[ w * y + x ]; 1650 }; 1651 1652 data._mask = null; 1653 1654 data.mask = function( img ){ 1655 this._mask = img; 1656 }; 1657 1658 data.loadPixels = function(){}; 1659 data.updatePixels = function(){}; 1660 1661 return data; 1662 1663 }; 1664 1665 function getImage( img ){ 1666 1667 if( typeof img == "string" ){ 1668 return document.getElementById( img ); 1669 } 1670 1671 if( img.img ){ 1672 1673 return img.img; 1674 1675 }else if( img.getContext || img.canvas ){ 1676 1677 img.pixels = img.getContext( '2d' ).createImageData( img.width, img.height ); 1678 } 1679 1680 for( var i = 0, l = img.pixels.length; i < l; i++ ){ 1681 1682 var pos = i * 4; 1683 var c = ( img.pixels[ i ] || "rgba(0,0,0,1)" ).slice( 5, - 1 ).split( "," ); 1684 1685 img.data[ pos + 0 ] = parseInt( c[ 0 ] ); 1686 img.data[ pos + 1 ] = parseInt( c[ 1 ] ); 1687 img.data[ pos + 2 ] = parseInt( c[ 2 ] ); 1688 img.data[ pos + 3 ] = parseFloat( c[ 3 ] ) * 100; 1689 1690 } 1691 1692 var canvas = document.createElement( "canvas" ); 1693 canvas.width = img.width; 1694 canvas.height = img.height; 1695 1696 var context = canvas.getContext( "2d" ); 1697 context.putImageData( img.pixels, 0, 0 ); 1698 1699 img.canvas = canvas; 1700 1701 return img; 1702 } 1703 1704 // Depreciating "getImage_old" from PJS - currently here to support AniSprite 1705 function getImage_old( img ){ 1706 if( typeof img == "string" ){ 1707 return document.getElementById( img ); 1708 } 1709 if( img.img || img.canvas ){ 1710 return img.img || img.canvas; 1711 } 1712 for( var i = 0, l = img.pixels.length; i < l; i++ ){ 1713 var pos = i * 4; 1714 var c = ( img.pixels[ i ] || "rgba(0,0,0,1)" ).slice( 5, - 1 ).split( "," ); 1715 img.data[ pos + 0 ] = parseInt( c[ 0 ] ); 1716 img.data[ pos + 1 ] = parseInt( c[ 1 ] ); 1717 img.data[ pos + 2 ] = parseInt( c[ 2 ] ); 1718 img.data[ pos + 3 ] = parseFloat( c[ 3 ] ) * 100; 1719 } 1720 var canvas = document.createElement( "canvas" ); 1721 canvas.width = img.width; 1722 canvas.height = img.height; 1723 var context = canvas.getContext( "2d" ); 1724 context.putImageData( img, 0, 0 ); 1725 img.canvas = canvas; 1726 return canvas; 1727 } 1728 // Depreciating "getImage_old" from PJS - currently here to support AniSprite 1729 p.image_old=function image_old(img,x,y,w,h){ 1730 x = x || 0; 1731 y = y || 0; 1732 var obj = getImage( img ); 1733 if( curTint >= 0 ){ 1734 var oldAlpha = curContext.globalAlpha; 1735 curContext.globalAlpha = curTint / opacityRange; 1736 } 1737 if( arguments.length == 3 ){ 1738 curContext.drawImage( obj, x, y ); 1739 }else{ 1740 curContext.drawImage( obj, x, y, w, h ); 1741 } 1742 if( curTint >= 0 ){ 1743 curContext.globalAlpha = oldAlpha; 1744 } 1745 if( img._mask ){ 1746 var oldComposite = curContext.globalCompositeOperation; 1747 curContext.globalCompositeOperation = "darker"; 1748 p.image( img._mask, x, y ); 1749 curContext.globalCompositeOperation = oldComposite; 1750 } 1751 }; 1752 1753 // Draws an image to the Canvas 1754 p.image = function image( img, x, y, w, h ){ 1755 1756 if( img.data || img.canvas ){ 1757 1758 x = x || 0; 1759 y = y || 0; 1760 1761 var obj = getImage( img.data || img.canvas ); 1762 1763 if( curTint >= 0 ){ 1764 var oldAlpha = curContext.globalAlpha; 1765 curContext.globalAlpha = curTint / opacityRange; 1766 } 1767 1768 if( arguments.length == 3 ){ 1769 curContext.drawImage( obj, x, y ); 1770 }else{ 1771 curContext.drawImage( obj, x, y, w, h ); 1772 } 1773 1774 if( curTint >= 0 ){ 1775 curContext.globalAlpha = oldAlpha; 1776 } 1777 1778 if( img._mask ){ 1779 var oldComposite = curContext.globalCompositeOperation; 1780 curContext.globalCompositeOperation = "darker"; 1781 p.image( img._mask, x, y ); 1782 curContext.globalCompositeOperation = oldComposite; 1783 } 1784 1785 } 1786 1787 if( typeof img == 'string' ){ 1788 1789 } 1790 1791 }; 1792 1793 // Clears hole in the Canvas or the whole Canvas 1794 p.clear = function clear ( x, y, width, height ) { 1795 if( arguments.length == 0 ){ 1796 curContext.clearRect( x, y, width, height ); 1797 }else{ 1798 curContext.clearRect( 0, 0, p.width, p.height ); 1799 } 1800 } 1801 1802 p.tint = function tint( rgb, a ){ 1803 curTint = a; 1804 }; 1805 1806 1807 1808 //////////////////////////////////////////////////////////////////////////// 1809 // Font handling 1810 //////////////////////////////////////////////////////////////////////////// 1811 1812 // Loads a font from an SVG or Canvas API 1813 p.loadFont = function loadFont( name ){ 1814 1815 if( name.indexOf( ".svg" ) == - 1 ){ 1816 1817 return { 1818 name: name, 1819 width: function( str ){ 1820 if( curContext.mozMeasureText ){ 1821 return curContext.mozMeasureText( 1822 typeof str == "number" ? 1823 String.fromCharCode( str ) : 1824 str 1825 ) / curTextSize; 1826 }else{ 1827 return 0; 1828 } 1829 } 1830 }; 1831 1832 }else{ 1833 1834 // If the font is a glyph, calculate by SVG table 1835 var font = p.loadGlyphs( name ); 1836 1837 return { 1838 name : name, 1839 glyph : true, 1840 units_per_em : font.units_per_em, 1841 horiz_adv_x : 1 / font.units_per_em * font.horiz_adv_x, 1842 ascent : font.ascent, 1843 descent : font.descent, 1844 width : 1845 function( str ){ 1846 var width = 0; 1847 var len = str.length; 1848 for( var i = 0; i < len; i++ ){ 1849 try{ width += parseFloat( p.glyphLook( p.glyphTable[ name ], str[ i ] ).horiz_adv_x ); } 1850 catch( e ){ ; } 1851 } 1852 return width / p.glyphTable[ name ].units_per_em; 1853 } 1854 } 1855 1856 } 1857 1858 }; 1859 1860 // Sets a 'current font' for use 1861 p.textFont = function textFont( name, size ){ 1862 curTextFont = name; 1863 p.textSize( size ); 1864 }; 1865 1866 // Sets the font size 1867 p.textSize = function textSize( size ){ 1868 //! Was this meant to return textSize value if no arguments were passed? 1869 if( size ){ 1870 curTextSize = size; 1871 } 1872 }; 1873 1874 p.textAlign = function textAlign(){}; 1875 1876 // A lookup table for characters that can not be referenced by Object 1877 p.glyphLook = function glyphLook( font, chr ){ 1878 1879 try{ 1880 switch( chr ){ 1881 case "1" : return font[ "one" ]; break; 1882 case "2" : return font[ "two" ]; break; 1883 case "3" : return font[ "three" ]; break; 1884 case "4" : return font[ "four" ]; break; 1885 case "5" : return font[ "five" ]; break; 1886 case "6" : return font[ "six" ]; break; 1887 case "7" : return font[ "seven" ]; break; 1888 case "8" : return font[ "eight" ]; break; 1889 case "9" : return font[ "nine" ]; break; 1890 case "0" : return font[ "zero" ]; break; 1891 case " " : return font[ "space" ]; break; 1892 case "$" : return font[ "dollar" ]; break; 1893 case "!" : return font[ "exclam" ]; break; 1894 case '"' : return font[ "quotedbl" ]; break; 1895 case "#" : return font[ "numbersign" ]; break; 1896 case "%" : return font[ "percent" ]; break; 1897 case "&" : return font[ "ampersand" ]; break; 1898 case "'" : return font[ "quotesingle" ]; break; 1899 case "(" : return font[ "parenleft" ]; break; 1900 case ")" : return font[ "parenright" ]; break; 1901 case "*" : return font[ "asterisk" ]; break; 1902 case "+" : return font[ "plus" ]; break; 1903 case "," : return font[ "comma" ]; break; 1904 case "-" : return font[ "hyphen" ]; break; 1905 case "." : return font[ "period" ]; break; 1906 case "/" : return font[ "slash" ]; break; 1907 case "_" : return font[ "underscore" ]; break; 1908 case ":" : return font[ "colon" ]; break; 1909 case ";" : return font[ "semicolon" ]; break; 1910 case "<" : return font[ "less" ]; break; 1911 case "=" : return font[ "equal" ]; break; 1912 case ">" : return font[ "greater" ]; break; 1913 case "?" : return font[ "question" ]; break; 1914 case "@" : return font[ "at" ]; break; 1915 case "[" : return font[ "bracketleft" ]; break; 1916 case "\\" : return font[ "backslash" ]; break; 1917 case "]" : return font[ "bracketright" ]; break; 1918 case "^" : return font[ "asciicircum" ]; break; 1919 case "`" : return font[ "grave" ]; break; 1920 case "{" : return font[ "braceleft" ]; break; 1921 case "|" : return font[ "bar" ]; break; 1922 case "}" : return font[ "braceright" ]; break; 1923 case "~" : return font[ "asciitilde" ]; break; 1924 // If the character is not 'special', access it by object reference 1925 default : return font[ chr ]; break; 1926 } 1927 }catch( e ){ ; } 1928 1929 } 1930 1931 // Print some text to the Canvas 1932 p.text = function text( str, x, y ){ 1933 1934 // If the font is a standard Canvas font... 1935 if( !curTextFont.glyph ){ 1936 1937 if( str && curContext.mozDrawText ){ 1938 1939 curContext.save(); 1940 curContext.mozTextStyle = curTextSize + "px " + curTextFont.name; 1941 curContext.translate( x, y ); 1942 curContext.mozDrawText( 1943 typeof str == "number" ? 1944 String.fromCharCode( str ) : 1945 str ) ; 1946 curContext.restore(); 1947 1948 } 1949 1950 }else{ 1951 1952 // If the font is a Batik SVG font... 1953 var font = p.glyphTable[ curTextFont.name ]; 1954 curContext.save(); 1955 curContext.translate( x, y + curTextSize ); 1956 1957 var upem = font[ "units_per_em" ], 1958 newScale = 1 / upem * curTextSize; 1959 1960 curContext.scale( newScale, newScale ); 1961 1962 var len = str.length; 1963 1964 for(var i = 0; i < len; i++ ){ 1965 // Test character against glyph table 1966 try{ p.glyphLook( font, str[ i ] ).draw(); } 1967 catch( e ){ ; } 1968 } 1969 1970 curContext.restore(); 1971 } 1972 1973 }; 1974 1975 // Load Batik SVG Fonts and parse to pre-def objects for quick rendering 1976 p.loadGlyphs = function loadGlyph( url ){ 1977 1978 // Load and parse Batik SVG font as XML into a Processing Glyph object 1979 var loadXML = function loadXML(){ 1980 1981 try{ 1982 var xmlDoc = new ActiveXObject( "Microsoft.XMLDOM" ); 1983 } 1984 catch( e ){ 1985 try{ 1986 xmlDoc=document.implementation.createDocument( "", "", null ); 1987 } 1988 catch( e ){ 1989 p.println( e.message ); 1990 return; 1991 } 1992 }; 1993 1994 try{ 1995 xmlDoc.async = false; 1996 xmlDoc.load( url ); 1997 parse( xmlDoc.getElementsByTagName( "svg" )[ 0 ] ); 1998 } 1999 catch( e ){ 2000 // Google Chrome, Safari etc. 2001 try{ 2002 p.println( e.message ); 2003 var xmlhttp = new window.XMLHttpRequest(); 2004 xmlhttp.open( "GET", url, false ); 2005 xmlhttp.send( null ); 2006 parse( xmlhttp.responseXML.documentElement ); 2007 } 2008 catch( e ){ ; } 2009 } 2010 }; 2011 2012 // Return arrays of SVG commands and coords 2013 var regex = function regex( needle, hay ){ 2014 2015 var regexp = new RegExp( needle, "g" ), 2016 results = [], 2017 i = 0; 2018 2019 while( results[ i ] = regexp.exec( hay ) ){ i++; } 2020 return results; 2021 2022 } 2023 2024 // Parse SVG font-file into block of Canvas commands 2025 var parse = function parse( svg ){ 2026 2027 // Store font attributes 2028 var font = svg.getElementsByTagName( "font" ); 2029 p.glyphTable[ url ][ "horiz_adv_x" ] = font[ 0 ].getAttribute( "horiz-adv-x" ); 2030 2031 var font_face = svg.getElementsByTagName( "font-face" )[ 0 ]; 2032 p.glyphTable[ url ][ "units_per_em" ] = parseFloat( font_face.getAttribute( "units-per-em") ); 2033 p.glyphTable[ url ][ "ascent" ] = parseFloat( font_face.getAttribute( "ascent" ) ); 2034 p.glyphTable[ url ][ "descent" ] = parseFloat( font_face.getAttribute( "descent" ) ); 2035 2036 var getXY = "[0-9\-]+", 2037 glyph = svg.getElementsByTagName( "glyph" ), 2038 len = glyph.length; 2039 2040 // Loop through each glyph in the SVG 2041 for( var i = 0; i < len; i++ ){ 2042 2043 // Store attributes for this glyph 2044 var unicode = glyph[ i ].getAttribute( "unicode" ); 2045 var name = glyph[ i ].getAttribute( "glyph-name" ); 2046 var horiz_adv_x = glyph[ i ].getAttribute( "horiz-adv-x" ); 2047 if( horiz_adv_x == null ){ var horiz_adv_x = p.glyphTable[ url ][ 'horiz_adv_x' ]; } 2048 2049 var buildPath = function buildPath( d ){ 2050 2051 var c = regex( "[A-Za-z][0-9\- ]+|Z", d ); 2052 2053 // Begin storing path object 2054 var path = "var path={draw:function(){curContext.beginPath();curContext.save();"; 2055 2056 var x = 0, 2057 y = 0, 2058 cx = 0, 2059 cy = 0, 2060 nx = 0, 2061 ny = 0, 2062 d = 0, 2063 a = 0, 2064 lastCom = "", 2065 lenC = c.length - 1; 2066 2067 // Loop through SVG commands translating to canvas eqivs functions in path object 2068 for( var j = 0; j < lenC; j++ ){ 2069 2070 var com = c[ j ][ 0 ], 2071 xy = regex( getXY, com ); 2072 2073 switch( com[ 0 ] ){ 2074 2075 case "M": //curContext.moveTo(x,-y); 2076 x = parseFloat( xy[ 0 ][ 0 ] ); 2077 y = parseFloat( xy[ 1 ][ 0 ] ); 2078 //! Brackets needed on (-y)? 2079 path += "curContext.moveTo("+ x +","+ (-y) +");"; 2080 break; 2081 2082 case "L": //curContext.lineTo(x,-y); 2083 x = parseFloat( xy[ 0 ][ 0 ] ); 2084 y = parseFloat( xy[ 1 ][ 0 ] ); 2085 path += "curContext.lineTo("+ x +","+ (-y) +");"; 2086 break; 2087 2088 case "H"://curContext.lineTo(x,-y) 2089 x = parseFloat( xy[ 0 ][ 0 ] ); 2090 path += "curContext.lineTo("+ x +","+ (-y) +");"; 2091 break; 2092 2093 case "V"://curContext.lineTo(x,-y); 2094 y = parseFloat( xy[ 0 ][ 0 ] ); 2095 path += "curContext.lineTo("+ x +","+ (-y) +");"; 2096 break; 2097 2098 case "T"://curContext.quadraticCurveTo(cx,-cy,nx,-ny); 2099 nx = parseFloat( xy[ 0 ][ 0 ] ); 2100 ny = parseFloat( xy[ 1 ][ 0 ] ); 2101 2102 if( lastCom == "Q" || lastCom == "T" ){ 2103 2104 d = Math.sqrt( Math.pow( x - cx, 2 ) + Math.pow( cy - y, 2 ) ); 2105 a = Math.PI+Math.atan2( cx - x, cy - y ); 2106 cx = x + ( Math.sin( a ) * ( d ) ); 2107 cy = y + ( Math.cos( a ) * ( d ) ); 2108 2109 }else{ 2110 cx = x; 2111 cy = y; 2112 } 2113 2114 path += "curContext.quadraticCurveTo("+ cx +","+ (-cy) +","+ nx +","+ (-ny) +");"; 2115 x = nx; 2116 y = ny; 2117 break; 2118 2119 case "Q"://curContext.quadraticCurveTo(cx,-cy,nx,-ny); 2120 cx = parseFloat( xy[ 0 ][ 0 ] ); 2121 cy = parseFloat( xy[ 1 ][ 0 ] ); 2122 nx = parseFloat( xy[ 2 ][ 0 ] ); 2123 ny = parseFloat( xy[ 3 ][ 0 ] ); 2124 path += "curContext.quadraticCurveTo("+ cx +","+ (-cy) +","+ nx +","+ (-ny) +");"; 2125 x = nx; 2126 y = ny; 2127 break; 2128 2129 case "Z"://curContext.closePath(); 2130 path += "curContext.closePath();"; 2131 break; 2132 2133 } 2134 2135 lastCom = com[ 0 ]; 2136 2137 } 2138 2139 path += "doStroke?curContext.stroke():0;"; 2140 path += "doFill?curContext.fill():0;"; 2141 path += "curContext.restore();"; 2142 path += "curContext.translate("+ horiz_adv_x +",0);"; 2143 path += "}}"; 2144 2145 return path; 2146 2147 } 2148 2149 var d = glyph[ i ].getAttribute( "d" ); 2150 2151 // Split path commands in glpyh 2152 if( d !== undefined ){ 2153 2154 var path = buildPath( d ); 2155 eval( path ); 2156 2157 // Store glyph data to table object 2158 p.glyphTable[ url ][ name ] = { 2159 name : name, 2160 unicode : unicode, 2161 horiz_adv_x : horiz_adv_x, 2162 draw : path.draw 2163 } 2164 2165 } 2166 2167 } // finished adding glyphs to table 2168 2169 } 2170 2171 // Create a new object in glyphTable to store this font 2172 p.glyphTable[ url ] = {}; 2173 2174 // Begin loading the Batik SVG font... 2175 loadXML( url ); 2176 2177 // Return the loaded font for attribute grabbing 2178 return p.glyphTable[ url ]; 2179 } 2180 2181 2182 2183 //////////////////////////////////////////////////////////////////////////// 2184 // Class methods 2185 //////////////////////////////////////////////////////////////////////////// 2186 2187 p.extendClass = function extendClass( obj, args, fn ){ 2188 if( arguments.length == 3 ){ 2189 fn.apply( obj, args ); 2190 }else{ 2191 args.call( obj ); 2192 } 2193 }; 2194 2195 p.addMethod = function addMethod( object, name, fn ){ 2196 2197 if( object[ name ] ){ 2198 2199 var args = fn.length, 2200 oldfn = object[ name ]; 2201 2202 object[ name ] = function(){ 2203 2204 if( arguments.length == args ){ 2205 2206 return fn.apply( this, arguments ); 2207 2208 }else{ 2209 2210 return oldfn.apply( this, arguments ); 2211 2212 } 2213 2214 }; 2215 2216 }else{ 2217 2218 object[ name ] = fn; 2219 2220 } 2221 2222 }; 2223 2224 2225 2226 //////////////////////////////////////////////////////////////////////////// 2227 // Set up environment 2228 //////////////////////////////////////////////////////////////////////////// 2229 2230 p.init = function init(code){ 2231 2232 p.stroke( 0 ); 2233 p.fill( 255 ); 2234 2235 // Canvas has trouble rendering single pixel stuff on whole-pixel 2236 // counts, so we slightly offset it (this is super lame). 2237 2238 curContext.translate( 0.5, 0.5 ); 2239 2240 // The fun bit! 2241 if( code ){ 2242 (function( Processing ){ 2243 with ( p ){ 2244 eval(parse(code, p)); 2245 } 2246 })( p ); 2247 } 2248 2249 if( p.setup ){ 2250 inSetup = true; 2251 p.setup(); 2252 } 2253 2254 inSetup = false; 2255 2256 if( p.draw ){ 2257 if( !doLoop ){ 2258 p.redraw(); 2259 } else { 2260 p.loop(); 2261 } 2262 } 2263 2264 2265 ////////////////////////////////////////////////////////////////////////// 2266 // Event handling 2267 ////////////////////////////////////////////////////////////////////////// 2268 2269 attach( curElement, "mousemove" , function(e){ 2270 2271 var scrollX = window.scrollX != null ? window.scrollX : window.pageXOffset; 2272 var scrollY = window.scrollY != null ? window.scrollY : window.pageYOffset; 2273 2274 p.pmouseX = p.mouseX; 2275 p.pmouseY = p.mouseY; 2276 p.mouseX = e.clientX - curElement.offsetLeft + scrollX; 2277 p.mouseY = e.clientY - curElement.offsetTop + scrollY; 2278 2279 if( p.mouseMoved ){ p.mouseMoved(); } 2280 if( mousePressed && p.mouseDragged ){ p.mouseDragged(); } 2281 2282 }); 2283 2284 attach( curElement, "mouseout" , function( e ){ p.cursor("auto"); }); 2285 2286 attach( curElement, "mousedown", function( e ){ 2287 mousePressed = true; 2288 switch(e.which){ 2289 case 1: p.mouseButton = p.LEFT; break; 2290 case 2: p.mouseButton = p.CENTER; break; 2291 case 3: p.mouseButton = p.RIGHT; break; 2292 } 2293 p.mouseDown = true; 2294 if( typeof p.mousePressed == "function" ){ p.mousePressed(); } 2295 else{ p.mousePressed = true; } 2296 }); 2297 2298 attach( curElement, "contextmenu", function( e ){ 2299 e.preventDefault(); 2300 e.stopPropagation(); 2301 }); 2302 2303 attach( curElement, "mouseup", function( e ){ 2304 mousePressed = false; 2305 if( p.mouseClicked ){ p.mouseClicked(); } 2306 if( typeof p.mousePressed != "function" ){ p.mousePressed = false; } 2307 if( p.mouseReleased ){ p.mouseReleased(); } 2308 }); 2309 2310 attach( document, "keydown", function( e ){ 2311 keyPressed = true; 2312 p.key = e.keyCode + 32; 2313 var i, len = p.codedKeys.length; 2314 for( i=0; i < len; i++ ){ 2315 if( p.key == p.codedKeys[ i ] ){ 2316 switch(p.key){ 2317 case 70: p.keyCode = p.UP ; break; 2318 case 71: p.keyCode = p.RIGHT ; break; 2319 case 72: p.keyCode = p.DOWN ; break; 2320 case 69: p.keyCode = p.LEFT ; break; 2321 } 2322 p.key=p.CODED; 2323 } 2324 } 2325 if( e.shiftKey ){ p.key = String.fromCharCode(p.key).toUpperCase().charCodeAt( 0 ); } 2326 if( typeof p.keyPressed == "function" ){ p.keyPressed(); } 2327 else{ p.keyPressed = true; } 2328 }); 2329 2330 attach( document, "keyup", function( e ){ 2331 keyPressed = false; 2332 if( typeof p.keyPressed != "function" ){ p.keyPressed = false; } 2333 if( p.keyReleased ){ p.keyReleased(); } 2334 }); 2335 2336 function attach(elem, type, fn) { 2337 if( elem.addEventListener ){ elem.addEventListener( type, fn, false ); } 2338 else{ elem.attachEvent( "on" + type, fn ); } 2339 } 2340 2341 }; 2342 2343 return p; 2344 2345 } 2346 2347 })(); -
new file sagenb/data/graph_editor/processing.min.js
diff --git a/sagenb/data/graph_editor/processing.min.js b/sagenb/data/graph_editor/processing.min.js new file mode 100644
- + 1 (function(){this.Processing=function Processing(aElement,aCode){if(typeof aElement=="string"){aElement=document.getElementById(aElement);} 2 var p=buildProcessing(aElement);if(aCode){p.init(aCode);} 3 return p;};var ajax=function(url){var AJAX;if(AJAX=new XMLHttpRequest()){AJAX.open("GET",url,false);AJAX.send(null);return AJAX.responseText;}else{return false;}};var init=function(){var canvas=document.getElementsByTagName('canvas'),datasrc=undefined;for(var i=0;l=i<canvas.length;i++){if(datasrc=canvas[i].getAttribute('datasrc')){Processing(canvas[i],ajax(datasrc));}}};addEventListener('DOMContentLoaded',function(){init();},false);var parse=Processing.parse=function parse(aCode,p){aCode=aCode.replace(/\/\/ .*\n/g,"\n");aCode=aCode.replace(/([^\s])%([^\s])/g,"$1 % $2");aCode=aCode.replace(/(?:static )?(\w+ )(\w+)\s*(\([^\)]*\)\s*{)/g,function(all,type,name,args){if(name=="if"||name=="for"||name=="while"){return all;}else{return"Processing."+name+" = function "+name+args;}});aCode=aCode.replace(/import \(|import\(/g,"p.Import(");aCode=aCode.replace(/\.length\(\)/g,".length");aCode=aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g,"$1$4");aCode=aCode.replace(/([\(,]\s*)(\w+)((?:\[\])+| )\s*(\w+\s*[\),])/g,"$1$4");aCode=aCode.replace(/new (\w+)((?:\[([^\]]*)\])+)/g,function(all,name,args){return"new ArrayList("+args.slice(1,-1).split("][").join(", ")+")";});aCode=aCode.replace(/(?:static )?\w+\[\]\s*(\w+)\[?\]?\s*=\s*{.*?};/g,function(all){return all.replace(/{/g,"[").replace(/}/g,"]");});var intFloat=/(\n\s*(?:int|float)(?:\[\])?(?:\s*|[^\(]*?,\s*))([a-z]\w*)(;|,)/i;while(intFloat.test(aCode)){aCode=aCode.replace(new RegExp(intFloat),function(all,type,name,sep){return type+" "+name+" = 0"+sep;});} 4 aCode=aCode.replace(/(?:static )?(\w+)((?:\[\])+| ) *(\w+)\[?\]?(\s*[=,;])/g,function(all,type,arr,name,sep){if(type=="return") 5 return all;else 6 return"var "+name+sep;});aCode=aCode.replace(/=\s*{((.|\s)*?)};/g,function(all,data){return"= ["+data.replace(/{/g,"[").replace(/}/g,"]")+"]";});aCode=aCode.replace(/super\(/g,"superMethod(");var classes=["int","float","boolean","string"];function ClassReplace(all,name,extend,vars,last){classes.push(name);var static="";vars=vars.replace(/final\s+var\s+(\w+\s*=\s*.*?;)/g,function(all,set){static+=" "+name+"."+set;return"";});return"function "+name+"() {with(this){\n "+ 7 (extend?"var __self=this;function superMethod(){extendClass(__self,arguments,"+extend+");}\n":"")+ 8 vars.replace(/,\s?/g,";\n this.").replace(/\b(var |final |public )+\s*/g,"this.").replace(/\b(var |final |public )+\s*/g,"this.").replace(/this.(\w+);/g,"this.$1 = null;")+ 9 (extend?"extendClass(this, "+extend+");\n":"")+"<CLASS "+name+" "+static+">"+(typeof last=="string"?last:name+"(");} 10 var matchClasses=/(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)\b\1\s*\(/g;var matchNoCon=/(?:public |abstract |static )*class (\w+)\s*(?:extends\s*(\w+)\s*)?{\s*((?:.|\n)*?)(Processing)/g;aCode=aCode.replace(matchClasses,ClassReplace);aCode=aCode.replace(matchNoCon,ClassReplace);var matchClass=/<CLASS (\w+) (.*?)>/,m;while((m=aCode.match(matchClass))){var left=RegExp.leftContext,allRest=RegExp.rightContext,rest=nextBrace(allRest),className=m[1],staticVars=m[2]||"";allRest=allRest.slice(rest.length+1);rest=rest.replace(new RegExp("\\b"+className+"\\(([^\\)]*?)\\)\\s*{","g"),function(all,args){args=args.split(/,\s*?/);if(args[0].match(/^\s*$/)){args.shift();} 11 var fn="if ( arguments.length == "+args.length+" ) {\n";for(var i=0;i<args.length;i++){fn+=" var "+args[i]+" = arguments["+i+"];\n";} 12 return fn;});rest=rest.replace(/(?:public )?Processing.\w+ = function (\w+)\((.*?)\)/g,function(all,name,args){return"ADDMETHOD(this, '"+name+"', function("+args+")";});var matchMethod=/ADDMETHOD([\s\S]*?{)/,mc;var methods="";while((mc=rest.match(matchMethod))){var prev=RegExp.leftContext,allNext=RegExp.rightContext,next=nextBrace(allNext);methods+="addMethod"+mc[1]+next+"});";rest=prev+allNext.slice(next.length+1);} 13 rest=methods+rest;aCode=left+rest+"\n}}"+staticVars+allRest;} 14 aCode=aCode.replace(/Processing.\w+ = function addMethod/g,"addMethod");function nextBrace(right){var rest=right,position=0,leftCount=1,rightCount=0;while(leftCount!=rightCount){var nextLeft=rest.indexOf("{"),nextRight=rest.indexOf("}");if(nextLeft<nextRight&&nextLeft!=-1){leftCount++;rest=rest.slice(nextLeft+1);position+=nextLeft+1;}else{rightCount++;rest=rest.slice(nextRight+1);position+=nextRight+1;}} 15 return right.slice(0,position-1);} 16 aCode=aCode.replace(/\(int\)/g,"0|");aCode=aCode.replace(new RegExp("\\(("+classes.join("|")+")(\\[\\])?\\)","g"),"");aCode=aCode.replace(/(\d+)f[^a-zA-Z0-9]/g,"$1");aCode=aCode.replace(/('[a-zA-Z0-9]')/g,"$1.charCodeAt(0)");aCode=aCode.replace(/#([a-f0-9]{6})/ig,function(m,hex){var num=toNumbers(hex);return"DefaultColor("+num[0]+","+num[1]+","+num[2]+")";});function toNumbers(str){var ret=[];str.replace(/(..)/g,function(str){ret.push(parseInt(str,16));});return ret;} 17 return aCode;};function buildProcessing(curElement){var p={};p.name='Processing.js Instance';p.PI=Math.PI;p.TWO_PI=2*p.PI;p.HALF_PI=p.PI/2;p.P3D=3;p.CORNER=0;p.RADIUS=1;p.CENTER_RADIUS=1;p.CENTER=2;p.POLYGON=2;p.QUADS=5;p.TRIANGLES=6;p.POINTS=7;p.LINES=8;p.TRIANGLE_STRIP=9;p.TRIANGLE_FAN=4;p.QUAD_STRIP=3;p.CORNERS=10;p.CLOSE=true;p.RGB=1;p.HSB=2;p.CENTER=88888880;p.CODED=88888888;p.UP=88888870;p.RIGHT=88888871;p.DOWN=88888872;p.LEFT=88888869;p.codedKeys=[69,70,71,72];var curContext=curElement.getContext("2d"),doFill=true,doStroke=true,loopStarted=false,hasBackground=false,doLoop=true,looping=0,curRectMode=p.CORNER,curEllipseMode=p.CENTER,inSetup=false,inDraw=false,curBackground="rgba( 204, 204, 204, 1 )",curFrameRate=1000,curMsPerFrame=1,curShape=p.POLYGON,curShapeCount=0,curvePoints=[],curTightness=0,opacityRange=255,redRange=255,greenRange=255,blueRange=255,pathOpen=false,mousePressed=false,keyPressed=false,curColorMode=p.RGB;curTint=-1,curTextSize=12,curTextFont="Arial",getLoaded=false,start=(new Date).getTime();var firstX,firstY,secondX,secondY,prevX,prevY;p.ln="";p.glyphTable={};p.pmouseX=0;p.pmouseY=0;p.mouseX=0;p.mouseY=0;p.mouseButton=0;p.mouseDown=false;p.mouseClicked=undefined;p.mouseDragged=undefined;p.mouseMoved=undefined;p.mousePressed=undefined;p.mouseReleased=undefined;p.keyPressed=undefined;p.keyReleased=undefined;p.draw=undefined;p.setup=undefined;p.width=curElement.width-0;p.height=curElement.height-0;p.frameCount=0;p.ArrayList=function ArrayList(size,size2,size3){var array=new Array(0|size);if(size2){for(var i=0;i<size;i++){array[i]=[];for(var j=0;j<size2;j++){var a=array[i][j]=size3?new Array(size3):0;for(var k=0;k<size3;k++){a[k]=0;}}}}else{for(var i=0;i<size;i++){array[i]=0;}} 18 array.get=function(i){return this[i];};array.add=function(item){return this.push(item);};array.size=function(){return this.length;};array.clear=function(){this.length=0;};array.remove=function(i){return this.splice(i,1);};array.isEmpty=function(){return!this.length;};array.clone=function(){var a=new ArrayList(size);for(var i=0;i<size;i++){a[i]=this[i];} 19 return a;};return array;};p.color=function color(aValue1,aValue2,aValue3,aValue4){var aColor="";if(arguments.length==3){aColor=p.color(aValue1,aValue2,aValue3,opacityRange);}else if(arguments.length==4){var a=aValue4/opacityRange;a=isNaN(a)?1:a;if(curColorMode==p.HSB){var rgb=HSBtoRGB(aValue1,aValue2,aValue3) 20 r=rgb[0],g=rgb[1],b=rgb[2];}else{var r=getColor(aValue1,redRange);var g=getColor(aValue2,greenRange);var b=getColor(aValue3,blueRange);} 21 aColor="rgba("+r+","+g+","+b+","+a+")";}else if(typeof aValue1=="string"){aColor=aValue1;if(arguments.length==2){var c=aColor.split(",");c[3]=(aValue2/opacityRange)+")";aColor=c.join(",");}}else if(arguments.length==2){aColor=p.color(aValue1,aValue1,aValue1,aValue2);}else if(typeof aValue1=="number"){aColor=p.color(aValue1,aValue1,aValue1,opacityRange);}else{aColor=p.color(redRange,greenRange,blueRange,opacityRange);} 22 function HSBtoRGB(h,s,b){h=(h/redRange)*360;s=(s/greenRange)*100;b=(b/blueRange)*100;var br=Math.round(b/100*255);if(s==0){return[br,br,br];}else{var hue=h%360;var f=hue%60;var p=Math.round((b*(100-s))/10000*255);var q=Math.round((b*(6000-s*f))/600000*255);var t=Math.round((b*(6000-s*(60-f)))/600000*255);switch(Math.floor(hue/60)){case 0:return[br,t,p];case 1:return[q,br,p];case 2:return[p,br,t];case 3:return[p,q,br];case 4:return[t,p,br];case 5:return[br,p,q];}}} 23 function getColor(aValue,range){return Math.round(255*(aValue/range));} 24 return aColor;} 25 p.red=function(aColor){return parseInt(verifyChannel(aColor).slice(5));};p.green=function(aColor){return parseInt(verifyChannel(aColor).split(",")[1]);};p.blue=function(aColor){return parseInt(verifyChannel(aColor).split(",")[2]);};p.alpha=function(aColor){return parseInt(parseFloat(verifyChannel(aColor).split(",")[3])*255);};function verifyChannel(aColor){if(aColor.constructor==Array){return aColor;}else{return p.color(aColor);}} 26 p.lerpColor=function lerpColor(c1,c2,amt){var colors1=p.color(c1).split(",");var r1=parseInt(colors1[0].split("(")[1]);var g1=parseInt(colors1[1]);var b1=parseInt(colors1[2]);var a1=parseFloat(colors1[3].split(")")[0]);var colors2=p.color(c2).split(",");var r2=parseInt(colors2[0].split("(")[1]);var g2=parseInt(colors2[1]);var b2=parseInt(colors2[2]);var a2=parseFloat(colors2[3].split(")")[0]);var r=parseInt(p.lerp(r1,r2,amt));var g=parseInt(p.lerp(g1,g2,amt));var b=parseInt(p.lerp(b1,b2,amt));var a=parseFloat(p.lerp(a1,a2,amt));return aColor="rgba("+r+","+g+","+b+","+a+")";} 27 p.DefaultColor=function(aValue1,aValue2,aValue3){var tmpColorMode=curColorMode;curColorMode=p.RGB;var c=p.color(aValue1/255*redRange,aValue2/255*greenRange,aValue3/255*blueRange);curColorMode=tmpColorMode;return c;} 28 p.colorMode=function colorMode(mode,range1,range2,range3,range4){curColorMode=mode;if(arguments.length>=4){redRange=range1;greenRange=range2;blueRange=range3;} 29 if(arguments.length==5){opacityRange=range4;} 30 if(arguments.length==2){p.colorMode(mode,range1,range1,range1,range1);}};p.translate=function translate(x,y){curContext.translate(x,y);};p.scale=function scale(x,y){curContext.scale(x,y||x);};p.rotate=function rotate(aAngle){curContext.rotate(aAngle);};p.pushMatrix=function pushMatrix(){curContext.save();};p.popMatrix=function popMatrix(){curContext.restore();};p.ortho=function ortho(){};p.year=function year(){return(new Date).getYear()+1900;};p.month=function month(){return(new Date).getMonth();};p.day=function day(){return(new Date).getDay();};p.hour=function hour(){return(new Date).getHours();};p.minute=function minute(){return(new Date).getMinutes();};p.second=function second(){return(new Date).getSeconds();};p.millis=function millis(){return(new Date).getTime()-start;};p.noLoop=function noLoop(){doLoop=false;};p.redraw=function redraw(){if(hasBackground){p.background();} 31 p.frameCount++;inDraw=true;p.pushMatrix();p.draw();p.popMatrix();inDraw=false;};p.loop=function loop(){if(loopStarted){return;} 32 looping=setInterval(function(){try{p.redraw();} 33 catch(e){clearInterval(looping);throw e;}},curMsPerFrame);loopStarted=true;};p.frameRate=function frameRate(aRate){curFrameRate=aRate;curMsPerFrame=1000/curFrameRate;};p.exit=function exit(){clearInterval(looping);};p.cursor=function(mode){document.body.style.cursor=mode;} 34 p.link=function(href,target){window.location=href;};p.beginDraw=function beginDraw(){};p.endDraw=function endDraw(){};p.ajax=ajax;p.Import=function Import(lib){eval(p.ajax(lib));} 35 p.loadStrings=function loadStrings(url){return p.ajax(url).split("\n");};p.nf=function(num,pad){var str=""+num;while(pad-str.length){str="0"+str;} 36 return str;};String.prototype.replaceAll=function(re,replace){return this.replace(new RegExp(re,"g"),replace);};p.lnPrinted=function lnPrinted(){};p.printed=function printed(){};p.println=function println(){if(arguments.callee.caller){var Caller=arguments.callee.caller.name.toString();if(arguments.length>1){Caller!="print"?p.ln=arguments:p.ln=arguments[0];}else{p.ln=arguments[0];} 37 Caller=="print"?p.printed(arguments):p.lnPrinted();}};p.str=function str(aNumber){return aNumber+'';} 38 p.print=function print(){p.println(arguments[0])};p.char=function char(key){return key;};p.sq=function sq(aNumber){return aNumber*aNumber;};p.sqrt=function sqrt(aNumber){return Math.sqrt(aNumber);};p.int=function int(aNumber){return Math.floor(aNumber);};p.min=function min(aNumber,aNumber2){return Math.min(aNumber,aNumber2);};p.max=function max(aNumber,aNumber2){return Math.max(aNumber,aNumber2);};p.floor=function floor(aNumber){return Math.floor(aNumber);};p.float=function float(aNumber){return parseFloat(aNumber);};p.ceil=function ceil(aNumber){return Math.ceil(aNumber);};p.round=function round(aNumber){return Math.round(aNumber);};p.lerp=function lerp(value1,value2,amt){return((value2-value1)*amt)+value1;};p.abs=function abs(aNumber){return Math.abs(aNumber);};p.cos=function cos(aNumber){return Math.cos(aNumber);};p.sin=function sin(aNumber){return Math.sin(aNumber);};p.pow=function pow(aNumber,aExponent){return Math.pow(aNumber,aExponent);};p.sqrt=function sqrt(aNumber){return Math.sqrt(aNumber);};p.atan2=function atan2(aNumber,aNumber2){return Math.atan2(aNumber,aNumber2);};p.radians=function radians(aAngle){return(aAngle/180)*p.PI;};p.dist=function dist(x1,y1,x2,y2){return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));};p.map=function map(value,istart,istop,ostart,ostop){return ostart+(ostop-ostart)*((value-istart)/(istop-istart));};p.Random=function(){var haveNextNextGaussian=false,nextNextGaussian;this.nextGaussian=function(){if(haveNextNextGaussian){haveNextNextGaussian=false;return nextNextGaussian;}else{var v1,v2,s;do{v1=2*p.random(1)-1;v2=2*p.random(1)-1;s=v1*v1+v2*v2;} 39 while(s>=1||s==0);var multiplier=Math.sqrt(-2*Math.log(s)/s);nextNextGaussian=v2*multiplier;haveNextNextGaussian=true;return v1*multiplier;}};};p.byte=function byte(aNumber){return aNumber||0;};p.norm=function norm(aNumber,low,high){var range=high-low;return((1/range)*aNumber)-((1/range)*low);};p.random=function random(aMin,aMax){return arguments.length==2?aMin+(Math.random()*(aMax-aMin)):Math.random()*aMin;};p.noise=function(x,y,z){return arguments.length>=2?PerlinNoise_2D(x,y,z):PerlinNoise_3D(x,x,z);};function Noise(x,y){var n=x+y*57;n=(n<<13)^n;return Math.abs(1.0-(((n*((n*n*15731)+789221)+1376312589)&0x7fffffff)/1073741824.0));};function SmoothedNoise(x,y){var corners=(Noise(x-1,y-1)+Noise(x+1,y-1)+Noise(x-1,y+1)+Noise(x+1,y+1))/16,sides=(Noise(x-1,y)+Noise(x+1,y)+Noise(x,y-1)+Noise(x,y+1))/8,center=Noise(x,y)/4;return corners+sides+center;};function InterpolatedNoise(x,y){var integer_X=Math.floor(x);var fractional_X=x-integer_X;var integer_Y=Math.floor(y);var fractional_Y=y-integer_Y;var v1=SmoothedNoise(integer_X,integer_Y),v2=SmoothedNoise(integer_X+1,integer_Y),v3=SmoothedNoise(integer_X,integer_Y+1),v4=SmoothedNoise(integer_X+1,integer_Y+1);var i1=Interpolate(v1,v2,fractional_X),i2=Interpolate(v3,v4,fractional_X);return Interpolate(i1,i2,fractional_Y);} 40 function PerlinNoise_2D(x,y){var total=0,p=0.25,n=3;for(var i=0;i<=n;i++){var frequency=Math.pow(2,i);var amplitude=Math.pow(p,i);total+=InterpolatedNoise(x*frequency,y*frequency)*amplitude;} 41 return total;} 42 function Interpolate(a,b,x){var ft=x*p.PI;var f=(1-Math.cos(ft))*.5;return a*(1-f)+b*f;} 43 p.constrain=function constrain(aNumber,aMin,aMax){return Math.min(Math.max(aNumber,aMin),aMax);};p.degrees=function degrees(aAngle){aAngle=(aAngle*180)/p.PI;if(aAngle<0){aAngle=360+aAngle} 44 return aAngle;};p.size=function size(aWidth,aHeight){var fillStyle=curContext.fillStyle,strokeStyle=curContext.strokeStyle;curElement.width=p.width=aWidth;curElement.height=p.height=aHeight;curContext.fillStyle=fillStyle;curContext.strokeStyle=strokeStyle;};p.noStroke=function noStroke(){doStroke=false;};p.noFill=function noFill(){doFill=false;};p.smooth=function smooth(){};p.noSmooth=function noSmooth(){};p.fill=function fill(){doFill=true;curContext.fillStyle=p.color.apply(this,arguments);};p.stroke=function stroke(){doStroke=true;curContext.strokeStyle=p.color.apply(this,arguments);};p.strokeWeight=function strokeWeight(w){curContext.lineWidth=w;};p.Point=function Point(x,y){this.x=x;this.y=y;this.copy=function(){return new Point(x,y);}};p.point=function point(x,y){var oldFill=curContext.fillStyle;curContext.fillStyle=curContext.strokeStyle;curContext.fillRect(Math.round(x),Math.round(y),1,1);curContext.fillStyle=oldFill;};p.beginShape=function beginShape(type){curShape=type;curShapeCount=0;curvePoints=[];};p.endShape=function endShape(close){if(curShapeCount!=0){if(close||doFill){curContext.lineTo(firstX,firstY);} 45 if(doFill){curContext.fill();} 46 if(doStroke){curContext.stroke();} 47 curContext.closePath();curShapeCount=0;pathOpen=false;} 48 if(pathOpen){if(doFill){curContext.fill();} 49 if(doStroke){curContext.stroke();} 50 curContext.closePath();curShapeCount=0;pathOpen=false;}};p.vertex=function vertex(x,y,x2,y2,x3,y3){if(curShapeCount==0&&curShape!=p.POINTS){pathOpen=true;curContext.beginPath();curContext.moveTo(x,y);firstX=x;firstY=y;}else{if(curShape==p.POINTS){p.point(x,y);}else if(arguments.length==2){if(curShape!=p.QUAD_STRIP||curShapeCount!=2){curContext.lineTo(x,y);} 51 if(curShape==p.TRIANGLE_STRIP){if(curShapeCount==2){p.endShape(p.CLOSE);pathOpen=true;curContext.beginPath();curContext.moveTo(prevX,prevY);curContext.lineTo(x,y);curShapeCount=1;} 52 firstX=prevX;firstY=prevY;} 53 if(curShape==p.TRIANGLE_FAN&&curShapeCount==2){p.endShape(p.CLOSE);pathOpen=true;curContext.beginPath();curContext.moveTo(firstX,firstY);curContext.lineTo(x,y);curShapeCount=1;} 54 if(curShape==p.QUAD_STRIP&&curShapeCount==3){curContext.lineTo(prevX,prevY);p.endShape(p.CLOSE);pathOpen=true;curContext.beginPath();curContext.moveTo(prevX,prevY);curContext.lineTo(x,y);curShapeCount=1;} 55 if(curShape==p.QUAD_STRIP){firstX=secondX;firstY=secondY;secondX=prevX;secondY=prevY;}}else if(arguments.length==4){if(curShapeCount>1){curContext.moveTo(prevX,prevY);curContext.quadraticCurveTo(firstX,firstY,x,y);curShapeCount=1;}}else if(arguments.length==6){curContext.bezierCurveTo(x,y,x2,y2,x3,y3);}} 56 prevX=x;prevY=y;curShapeCount++;if(curShape==p.LINES&&curShapeCount==2||(curShape==p.TRIANGLES)&&curShapeCount==3||(curShape==p.QUADS)&&curShapeCount==4){p.endShape(p.CLOSE);}};p.curveVertex=function(x,y,x2,y2){if(curvePoints.length<3){curvePoints.push([x,y]);}else{var b=[],s=1-curTightness;curvePoints.push([x,y]);b[0]=[curvePoints[1][0],curvePoints[1][1]];b[1]=[curvePoints[1][0]+(s*curvePoints[2][0]-s*curvePoints[0][0])/6,curvePoints[1][1]+(s*curvePoints[2][1]-s*curvePoints[0][1])/6];b[2]=[curvePoints[2][0]+(s*curvePoints[1][0]-s*curvePoints[3][0])/6,curvePoints[2][1]+(s*curvePoints[1][1]-s*curvePoints[3][1])/6];b[3]=[curvePoints[2][0],curvePoints[2][1]];if(!pathOpen){p.vertex(b[0][0],b[0][1]);}else{curShapeCount=1;} 57 p.vertex(b[1][0],b[1][1],b[2][0],b[2][1],b[3][0],b[3][1]);curvePoints.shift();}};p.curveTightness=function(tightness){curTightness=tightness;};p.bezierVertex=p.vertex;p.rectMode=function rectMode(aRectMode){curRectMode=aRectMode;};p.imageMode=function(){};p.ellipseMode=function ellipseMode(aEllipseMode){curEllipseMode=aEllipseMode;};p.arc=function arc(x,y,width,height,start,stop){if(width<=0){return;} 58 if(curEllipseMode==p.CORNER){x+=width/2;y+=height/2;} 59 curContext.moveTo(x,y);curContext.beginPath();curContext.arc(x,y,curEllipseMode==p.CENTER_RADIUS?width:width/2,start,stop,false);if(doStroke){curContext.stroke();} 60 curContext.lineTo(x,y);if(doFill){curContext.fill();} 61 curContext.closePath();};p.line=function line(x1,y1,x2,y2){curContext.lineCap="round";curContext.beginPath();curContext.moveTo(x1||0,y1||0);curContext.lineTo(x2||0,y2||0);curContext.stroke();curContext.closePath();};p.bezier=function bezier(x1,y1,x2,y2,x3,y3,x4,y4){curContext.lineCap="butt";curContext.beginPath();curContext.moveTo(x1,y1);curContext.bezierCurveTo(x2,y2,x3,y3,x4,y4);curContext.stroke();curContext.closePath();};p.triangle=function triangle(x1,y1,x2,y2,x3,y3){p.beginShape();p.vertex(x1,y1);p.vertex(x2,y2);p.vertex(x3,y3);p.endShape();};p.quad=function quad(x1,y1,x2,y2,x3,y3,x4,y4){curContext.lineCap="square";p.beginShape();p.vertex(x1,y1);p.vertex(x2,y2);p.vertex(x3,y3);p.vertex(x4,y4);p.endShape();};p.rect=function rect(x,y,width,height){if(!(width+height)){return;} 62 curContext.beginPath();var offsetStart=0;var offsetEnd=0;if(curRectMode==p.CORNERS){width-=x;height-=y;} 63 if(curRectMode==p.RADIUS){width*=2;height*=2;} 64 if(curRectMode==p.CENTER||curRectMode==p.RADIUS){x-=width/2;y-=height/2;} 65 curContext.rect(Math.round(x)-offsetStart,Math.round(y)-offsetStart,Math.round(width)+offsetEnd,Math.round(height)+offsetEnd);if(doFill){curContext.fill();} 66 if(doStroke){curContext.stroke()};curContext.closePath();};p.ellipse=function ellipse(x,y,width,height){x=x||0;y=y||0;if(width<=0&&height<=0){return;} 67 curContext.beginPath();if(curEllipseMode==p.RADIUS){width*=2;height*=2;} 68 var offsetStart=0;if(width==height){curContext.arc(x-offsetStart,y-offsetStart,width/2,0,p.TWO_PI,false);}else{var w=width/2,h=height/2,C=0.5522847498307933;var c_x=C*w,c_y=C*h;curContext.moveTo(x+w,y);curContext.bezierCurveTo(x+w,y-c_y,x+c_x,y-h,x,y-h);curContext.bezierCurveTo(x-c_x,y-h,x-w,y-c_y,x-w,y);curContext.bezierCurveTo(x-w,y+c_y,x-c_x,y+h,x,y+h);curContext.bezierCurveTo(x+c_x,y+h,x+w,y+c_y,x+w,y);} 69 if(doFill){curContext.fill();} 70 if(doStroke){curContext.stroke();} 71 curContext.closePath();};p.save=function save(file){};p.loadImage=function loadImage(file,type,callback){var img=document.createElement('img');img.src=file;img.onload=function(){var h=this.height,w=this.width;var canvas=document.createElement("canvas");canvas.width=w;canvas.height=h;var context=canvas.getContext("2d");context.drawImage(this,0,0);this.data=buildImageObject(context.getImageData(0,0,w,h));this.data.img=img;callback?callback():0;} 72 return img;};p.get=function get(x,y){if(!arguments.length){var c=p.createGraphics(p.width,p.height);c.image(curContext,0,0);return c;} 73 if(!getLoaded){getLoaded=buildImageObject(curContext.getImageData(0,0,p.width,p.height));} 74 return getLoaded.get(x,y);};p.createGraphics=function createGraphics(w,h){var canvas=document.createElement("canvas");var ret=buildProcessing(canvas);ret.size(w,h);ret.canvas=canvas;return ret;};p.set=function set(x,y,obj){if(obj&&obj.img){p.image(obj,x,y);}else{var oldFill=curContext.fillStyle,color=obj;curContext.fillStyle=color;curContext.fillRect(Math.round(x),Math.round(y),1,1);curContext.fillStyle=oldFill;}};p.loadPixels=function(){p.pixels=buildImageObject(curContext.getImageData(0,0,p.width,p.height)).pixels;};p.updatePixels=function(){var colors=/(\d+),(\d+),(\d+),(\d+)/,pixels={};pixels.width=p.width;pixels.height=p.height;pixels.data=[];if(curContext.createImageData){pixels=curContext.createImageData(p.width,p.height);} 75 var data=pixels.data,pos=0;for(var i=0,l=p.pixels.length;i<l;i++){var c=(p.pixels[i]||"rgba(0,0,0,1)").match(colors);data[pos+0]=parseInt(c[1]);data[pos+1]=parseInt(c[2]);data[pos+2]=parseInt(c[3]);data[pos+3]=parseFloat(c[4])*255;pos+=4;} 76 curContext.putImageData(pixels,0,0);};p.background=function background(img){if(arguments.length){if(img.data&&img.data.img){curBackground=img.data;}else{curBackground=p.color.apply(this,arguments);}} 77 if(curBackground.img){p.image(img,0,0);}else{var oldFill=curContext.fillStyle;curContext.fillStyle=curBackground+"";curContext.fillRect(0,0,p.width,p.height);curContext.fillStyle=oldFill;}};p.AniSprite=function(prefix,frames){this.images=[];this.pos=0;for(var i=0;i<frames;i++){this.images.push(prefix+p.nf(i,(""+frames).length)+".gif");} 78 this.display=function(x,y){p.image_old(this.images[this.pos],x,y);if(++this.pos>=frames){this.pos=0;}};this.getWidth=function(){return getImage_old(this.images[0]).width;};this.getHeight=function(){return getImage_old(this.images[0]).height;};};function buildImageObject(obj){var pixels=obj.data;var data=p.createImage(obj.width,obj.height);if(data.__defineGetter__&&data.__lookupGetter__&&!data.__lookupGetter__("pixels")){var pixelsDone;data.__defineGetter__("pixels",function(){if(pixelsDone){return pixelsDone;} 79 pixelsDone=[];for(var i=0;i<pixels.length;i+=4){pixelsDone.push(p.color(pixels[i],pixels[i+1],pixels[i+2],pixels[i+3]));} 80 return pixelsDone;});}else{data.pixels=[];for(var i=0;i<pixels.length;i+=4){data.pixels.push(p.color(pixels[i],pixels[i+1],pixels[i+2],pixels[i+3]));}} 81 return data;} 82 p.createImage=function createImage(w,h,mode){var data={};data.width=w;data.height=h;data.data=[];if(curContext.createImageData){data=curContext.createImageData(w,h);} 83 data.pixels=new Array(w*h);data.get=function(x,y){return this.pixels[w*y+x];};data._mask=null;data.mask=function(img){this._mask=img;};data.loadPixels=function(){};data.updatePixels=function(){};return data;};function getImage(img){if(typeof img=="string"){return document.getElementById(img);} 84 if(img.img){return img.img;}else if(img.getContext||img.canvas){img.pixels=img.getContext('2d').createImageData(img.width,img.height);} 85 for(var i=0,l=img.pixels.length;i<l;i++){var pos=i*4;var c=(img.pixels[i]||"rgba(0,0,0,1)").slice(5,-1).split(",");img.data[pos+0]=parseInt(c[0]);img.data[pos+1]=parseInt(c[1]);img.data[pos+2]=parseInt(c[2]);img.data[pos+3]=parseFloat(c[3])*100;} 86 var canvas=document.createElement("canvas");canvas.width=img.width;canvas.height=img.height;var context=canvas.getContext("2d");context.putImageData(img.pixels,0,0);img.canvas=canvas;return img;} 87 function getImage_old(img){if(typeof img=="string"){return document.getElementById(img);} 88 if(img.img||img.canvas){return img.img||img.canvas;} 89 for(var i=0,l=img.pixels.length;i<l;i++){var pos=i*4;var c=(img.pixels[i]||"rgba(0,0,0,1)").slice(5,-1).split(",");img.data[pos+0]=parseInt(c[0]);img.data[pos+1]=parseInt(c[1]);img.data[pos+2]=parseInt(c[2]);img.data[pos+3]=parseFloat(c[3])*100;} 90 var canvas=document.createElement("canvas");canvas.width=img.width;canvas.height=img.height;var context=canvas.getContext("2d");context.putImageData(img,0,0);img.canvas=canvas;return canvas;} 91 p.image_old=function image_old(img,x,y,w,h){x=x||0;y=y||0;var obj=getImage(img);if(curTint>=0){var oldAlpha=curContext.globalAlpha;curContext.globalAlpha=curTint/opacityRange;} 92 if(arguments.length==3){curContext.drawImage(obj,x,y);}else{curContext.drawImage(obj,x,y,w,h);} 93 if(curTint>=0){curContext.globalAlpha=oldAlpha;} 94 if(img._mask){var oldComposite=curContext.globalCompositeOperation;curContext.globalCompositeOperation="darker";p.image(img._mask,x,y);curContext.globalCompositeOperation=oldComposite;}};p.image=function image(img,x,y,w,h){if(img.data||img.canvas){x=x||0;y=y||0;var obj=getImage(img.data||img.canvas);if(curTint>=0){var oldAlpha=curContext.globalAlpha;curContext.globalAlpha=curTint/opacityRange;} 95 if(arguments.length==3){curContext.drawImage(obj,x,y);}else{curContext.drawImage(obj,x,y,w,h);} 96 if(curTint>=0){curContext.globalAlpha=oldAlpha;} 97 if(img._mask){var oldComposite=curContext.globalCompositeOperation;curContext.globalCompositeOperation="darker";p.image(img._mask,x,y);curContext.globalCompositeOperation=oldComposite;}} 98 if(typeof img=='string'){}};p.clear=function clear(x,y,width,height){if(arguments.length==0){curContext.clearRect(x,y,width,height);}else{curContext.clearRect(0,0,p.width,p.height);}} 99 p.tint=function tint(rgb,a){curTint=a;};p.loadFont=function loadFont(name){if(name.indexOf(".svg")==-1){return{name:name,width:function(str){if(curContext.mozMeasureText){return curContext.mozMeasureText(typeof str=="number"?String.fromCharCode(str):str)/curTextSize;}else{return 0;}}};}else{var font=p.loadGlyphs(name);return{name:name,glyph:true,units_per_em:font.units_per_em,horiz_adv_x:1/font.units_per_em*font.horiz_adv_x,ascent:font.ascent,descent:font.descent,width:function(str){var width=0;var len=str.length;for(var i=0;i<len;i++){try{width+=parseFloat(p.glyphLook(p.glyphTable[name],str[i]).horiz_adv_x);} 100 catch(e){;}} 101 return width/p.glyphTable[name].units_per_em;}}}};p.textFont=function textFont(name,size){curTextFont=name;p.textSize(size);};p.textSize=function textSize(size){if(size){curTextSize=size;}};p.textAlign=function textAlign(){};p.glyphLook=function glyphLook(font,chr){try{switch(chr){case"1":return font["one"];break;case"2":return font["two"];break;case"3":return font["three"];break;case"4":return font["four"];break;case"5":return font["five"];break;case"6":return font["six"];break;case"7":return font["seven"];break;case"8":return font["eight"];break;case"9":return font["nine"];break;case"0":return font["zero"];break;case" ":return font["space"];break;case"$":return font["dollar"];break;case"!":return font["exclam"];break;case'"':return font["quotedbl"];break;case"#":return font["numbersign"];break;case"%":return font["percent"];break;case"&":return font["ampersand"];break;case"'":return font["quotesingle"];break;case"(":return font["parenleft"];break;case")":return font["parenright"];break;case"*":return font["asterisk"];break;case"+":return font["plus"];break;case",":return font["comma"];break;case"-":return font["hyphen"];break;case".":return font["period"];break;case"/":return font["slash"];break;case"_":return font["underscore"];break;case":":return font["colon"];break;case";":return font["semicolon"];break;case"<":return font["less"];break;case"=":return font["equal"];break;case">":return font["greater"];break;case"?":return font["question"];break;case"@":return font["at"];break;case"[":return font["bracketleft"];break;case"\\":return font["backslash"];break;case"]":return font["bracketright"];break;case"^":return font["asciicircum"];break;case"`":return font["grave"];break;case"{":return font["braceleft"];break;case"|":return font["bar"];break;case"}":return font["braceright"];break;case"~":return font["asciitilde"];break;default:return font[chr];break;}}catch(e){;}} 102 p.text=function text(str,x,y){if(!curTextFont.glyph){if(str&&curContext.mozDrawText){curContext.save();curContext.mozTextStyle=curTextSize+"px "+curTextFont.name;curContext.translate(x,y);curContext.mozDrawText(typeof str=="number"?String.fromCharCode(str):str);curContext.restore();}}else{var font=p.glyphTable[curTextFont.name];curContext.save();curContext.translate(x,y+curTextSize);var upem=font["units_per_em"],newScale=1/upem*curTextSize;curContext.scale(newScale,newScale);var len=str.length;for(var i=0;i<len;i++){try{p.glyphLook(font,str[i]).draw();} 103 catch(e){;}} 104 curContext.restore();}};p.loadGlyphs=function loadGlyph(url){var loadXML=function loadXML(){try{var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");} 105 catch(e){try{xmlDoc=document.implementation.createDocument("","",null);} 106 catch(e){p.println(e.message);return;}};try{xmlDoc.async=false;xmlDoc.load(url);parse(xmlDoc.getElementsByTagName("svg")[0]);} 107 catch(e){try{p.println(e.message);var xmlhttp=new window.XMLHttpRequest();xmlhttp.open("GET",url,false);xmlhttp.send(null);parse(xmlhttp.responseXML.documentElement);} 108 catch(e){;}}};var regex=function regex(needle,hay){var regexp=new RegExp(needle,"g"),results=[],i=0;while(results[i]=regexp.exec(hay)){i++;} 109 return results;} 110 var parse=function parse(svg){var font=svg.getElementsByTagName("font");p.glyphTable[url]["horiz_adv_x"]=font[0].getAttribute("horiz-adv-x");var font_face=svg.getElementsByTagName("font-face")[0];p.glyphTable[url]["units_per_em"]=parseFloat(font_face.getAttribute("units-per-em"));p.glyphTable[url]["ascent"]=parseFloat(font_face.getAttribute("ascent"));p.glyphTable[url]["descent"]=parseFloat(font_face.getAttribute("descent"));var getXY="[0-9\-]+",glyph=svg.getElementsByTagName("glyph"),len=glyph.length;for(var i=0;i<len;i++){var unicode=glyph[i].getAttribute("unicode");var name=glyph[i].getAttribute("glyph-name");var horiz_adv_x=glyph[i].getAttribute("horiz-adv-x");if(horiz_adv_x==null){var horiz_adv_x=p.glyphTable[url]['horiz_adv_x'];} 111 var buildPath=function buildPath(d){var c=regex("[A-Za-z][0-9\- ]+|Z",d);var path="var path={draw:function(){curContext.beginPath();curContext.save();";var x=0,y=0,cx=0,cy=0,nx=0,ny=0,d=0,a=0,lastCom="",lenC=c.length-1;for(var j=0;j<lenC;j++){var com=c[j][0],xy=regex(getXY,com);switch(com[0]){case"M":x=parseFloat(xy[0][0]);y=parseFloat(xy[1][0]);path+="curContext.moveTo("+x+","+(-y)+");";break;case"L":x=parseFloat(xy[0][0]);y=parseFloat(xy[1][0]);path+="curContext.lineTo("+x+","+(-y)+");";break;case"H":x=parseFloat(xy[0][0]);path+="curContext.lineTo("+x+","+(-y)+");";break;case"V":y=parseFloat(xy[0][0]);path+="curContext.lineTo("+x+","+(-y)+");";break;case"T":nx=parseFloat(xy[0][0]);ny=parseFloat(xy[1][0]);if(lastCom=="Q"||lastCom=="T"){d=Math.sqrt(Math.pow(x-cx,2)+Math.pow(cy-y,2));a=Math.PI+Math.atan2(cx-x,cy-y);cx=x+(Math.sin(a)*(d));cy=y+(Math.cos(a)*(d));}else{cx=x;cy=y;} 112 path+="curContext.quadraticCurveTo("+cx+","+(-cy)+","+nx+","+(-ny)+");";x=nx;y=ny;break;case"Q":cx=parseFloat(xy[0][0]);cy=parseFloat(xy[1][0]);nx=parseFloat(xy[2][0]);ny=parseFloat(xy[3][0]);path+="curContext.quadraticCurveTo("+cx+","+(-cy)+","+nx+","+(-ny)+");";x=nx;y=ny;break;case"Z":path+="curContext.closePath();";break;} 113 lastCom=com[0];} 114 path+="doStroke?curContext.stroke():0;";path+="doFill?curContext.fill():0;";path+="curContext.restore();";path+="curContext.translate("+horiz_adv_x+",0);";path+="}}";return path;} 115 var d=glyph[i].getAttribute("d");if(d!==undefined){var path=buildPath(d);eval(path);p.glyphTable[url][name]={name:name,unicode:unicode,horiz_adv_x:horiz_adv_x,draw:path.draw}}}} 116 p.glyphTable[url]={};loadXML(url);return p.glyphTable[url];} 117 p.extendClass=function extendClass(obj,args,fn){if(arguments.length==3){fn.apply(obj,args);}else{args.call(obj);}};p.addMethod=function addMethod(object,name,fn){if(object[name]){var args=fn.length,oldfn=object[name];object[name]=function(){if(arguments.length==args){return fn.apply(this,arguments);}else{return oldfn.apply(this,arguments);}};}else{object[name]=fn;}};p.init=function init(code){p.stroke(0);p.fill(255);curContext.translate(0.5,0.5);if(code){(function(Processing){with(p){eval(parse(code,p));}})(p);} 118 if(p.setup){inSetup=true;p.setup();} 119 inSetup=false;if(p.draw){if(!doLoop){p.redraw();}else{p.loop();}} 120 attach(curElement,"mousemove",function(e){var scrollX=window.scrollX!=null?window.scrollX:window.pageXOffset;var scrollY=window.scrollY!=null?window.scrollY:window.pageYOffset;p.pmouseX=p.mouseX;p.pmouseY=p.mouseY;p.mouseX=e.clientX-curElement.offsetLeft+scrollX;p.mouseY=e.clientY-curElement.offsetTop+scrollY;if(p.mouseMoved){p.mouseMoved();} 121 if(mousePressed&&p.mouseDragged){p.mouseDragged();}});attach(curElement,"mouseout",function(e){p.cursor("auto");});attach(curElement,"mousedown",function(e){mousePressed=true;switch(e.which){case 1:p.mouseButton=p.LEFT;break;case 2:p.mouseButton=p.CENTER;break;case 3:p.mouseButton=p.RIGHT;break;} 122 p.mouseDown=true;if(typeof p.mousePressed=="function"){p.mousePressed();} 123 else{p.mousePressed=true;}});attach(curElement,"contextmenu",function(e){e.preventDefault();e.stopPropagation();});attach(curElement,"mouseup",function(e){mousePressed=false;if(p.mouseClicked){p.mouseClicked();} 124 if(typeof p.mousePressed!="function"){p.mousePressed=false;} 125 if(p.mouseReleased){p.mouseReleased();}});attach(document,"keydown",function(e){keyPressed=true;p.key=e.keyCode+32;var i,len=p.codedKeys.length;for(i=0;i<len;i++){if(p.key==p.codedKeys[i]){switch(p.key){case 70:p.keyCode=p.UP;break;case 71:p.keyCode=p.RIGHT;break;case 72:p.keyCode=p.DOWN;break;case 69:p.keyCode=p.LEFT;break;} 126 p.key=p.CODED;}} 127 if(e.shiftKey){p.key=String.fromCharCode(p.key).toUpperCase().charCodeAt(0);} 128 if(typeof p.keyPressed=="function"){p.keyPressed();} 129 else{p.keyPressed=true;}});attach(document,"keyup",function(e){keyPressed=false;if(typeof p.keyPressed!="function"){p.keyPressed=false;} 130 if(p.keyReleased){p.keyReleased();}});function attach(elem,type,fn){if(elem.addEventListener){elem.addEventListener(type,fn,false);} 131 else{elem.attachEvent("on"+type,fn);}}};return p;}})(); -
sagenb/data/sage/js/notebook_lib.js
diff --git a/sagenb/data/sage/js/notebook_lib.js b/sagenb/data/sage/js/notebook_lib.js
a b function cell_delete_callback(status, re 2171 2171 } 2172 2172 } 2173 2173 2174 function cell_delete_output(id) { 2175 /* 2176 Ask the server to delete the output of a cell. 2177 2178 INPUT: 2179 id -- an integer 2180 */ 2181 if (active_cell_list.indexOf(id) != -1) { 2182 // Deleting a running cell causes evaluation to be interrupted. 2183 // In most cases this avoids potentially tons of confusion. 2184 async_request(worksheet_command('interrupt')); 2185 } 2186 async_request(worksheet_command('delete_cell_output'), 2187 cell_delete_output_callback, {id: id}); 2188 } 2189 2190 function cell_delete_output_callback(status, response_text) { 2191 /* 2192 Callback for after the server deletes a cell's output. This 2193 function removes the cell's output from the DOM. 2194 2195 INPUT: 2196 status -- string ('success' or 'failure') 2197 response_text -- [command]SEP[id] 2198 command -- string ('delete_output') 2199 id -- id of cell whose output is deleted. 2200 */ 2201 var id; 2202 if (status !== 'success') { 2203 // Do not delete output, for some reason. 2204 return; 2205 } 2206 id = response_text.split(SEP)[1]; 2207 2208 // Delete the output. 2209 get_element('cell_output_' + id).innerHTML = ""; 2210 get_element('cell_output_nowrap_' + id).innerHTML = ""; 2211 get_element('cell_output_html_' + id).innerHTML = ""; 2212 2213 // Set the cell to not evaluated. 2214 cell_set_not_evaluated(id); 2215 } 2216 2217 2174 2218 function debug_input_key_event(e) { 2175 2219 /* 2176 2220 Handle an input key even when we're in debug mode. -
sagenb/notebook/twist.py
diff --git a/sagenb/notebook/twist.py b/sagenb/notebook/twist.py
a b class Worksheet_delete_cell(WorksheetRes 1124 1124 s = encode_list(['delete', id, prev_id, W.cell_id_list()]) 1125 1125 return HTMLResponse(stream = s) 1126 1126 1127 ############################################################################## 1128 # The delete cell output command: /home/worksheet/delete_cell_output?id=number 1129 ############################################################################## 1130 class Worksheet_delete_cell_output(WorksheetResource, resource.PostableResource): 1131 """ 1132 Deletes a cell's output. 1133 """ 1134 def render(self, ctx): 1135 id = self.id(ctx) 1136 self.worksheet.get_cell_with_id(id).delete_output() 1137 return HTMLResponse(stream = encode_list(['delete_output', id])) 1138 1127 1139 1128 1140 ############################ 1129 1141 # Get the latest update on output appearing