Skip to content
Browse files

Initial Commit

  • Loading branch information...
0 parents commit 7ef2802ef75d59f5464a8f863e43da4e423c6fd1 @imbcmdth committed
3 README
@@ -0,0 +1,3 @@
+R-Tree Library for Javascript
+
+TODO: Make More ReadMe
3 examples/20k_tree.js
3 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
480 examples/canvas_test_generate.html
@@ -0,0 +1,480 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>More Canvas Fun</title>
+<script type='text/javascript' src='../libs/firebug-lite-compressed.js'></script>
+<script type='text/javascript' src="../libs/jquery.min.js"></script>
+<script type='text/javascript' src="../src/rtree.js"></script>
+</head>
+<body>
+ This test generate 20k squares over a an area several times larger than the canvas window. Once insertion has completely, the canvas begins scrolling diagonally. This test shows canvas rendering and event handling of a small subset (<300 objects) of a much larger dataset (20k objects) at interactive rates.<br/>
+ <canvas id="game" width="650px" height="500px">
+ </canvas>
+ <script type="text/javascript">
+
+ /* I want to be able to do:
+ * cQuery:
+ * addObject(object_interface)
+ *
+ *
+ * cQuery(Rectangle | CanvasObject) [decorated array]
+ *
+ * object interface:
+ * attachEvent(event_name,function())
+ * removeEvent(event_name)
+ * doAreaEvent(event_name)
+ *
+ */
+/********************************************
+ * Full Canvas Library *
+ ********************************************/
+
+var canvwrap=(function(){
+
+ var canv=null,
+ canvctx=null,
+ rt=new RTree(),
+ layers={'main':0},
+ mouse={track:false,x:0,y:0},
+ mouseouts=[],
+ mouseoutids=0;
+
+ var canvasElement=function(x,y,w,h){
+ this.x=x;
+ this.y=y;
+ this.w=w;
+ this.h=h;
+ }
+
+ canvasElement.prototype.attachEvent=function(action,func,layer){
+ canvwrap.attachEvent({x:this.x,y:this.y,w:this.w,h:this.h},action,func,layer);
+ }
+
+ canvasElement.prototype.toString=function(){ return '[CanvasElement]'; };
+
+ function addIndex(bounds,id,action,func,layer, opts)
+ {
+ if(!func) return;
+ if(!layer) layer='main';
+
+ // Get all overlapping objects from the tree
+ var local_objs = treeSearch(bounds.x,bounds.y,bounds.w,bounds.h);
+ var new_obj = true;
+
+ // Look for an existing object with our same ID
+ while(local_objs.length > 0)
+ {
+ obj = local_objs.pop();
+ if(obj.id == id)
+ {
+ new_obj = false;
+ break;
+ }
+ }
+ // If no object was found, make a new one...
+ if(new_obj) obj = {"func":{}, "action":{}, "id":id};
+
+ // If no events have been attached to the canvas, attach them..
+ if((action=='mouseover' || action=='mouseout' || action=='mousemove') && !mouse.track)
+ {
+ mouse.track=true;
+ canv.addEvent('mousemove',__mouseMove);
+ }
+
+ for (var k in opts)
+ obj[k] = opts[k];
+
+
+ // Update our obj's properties
+ obj.func[action] = func;
+ obj.action[action] = true;
+ obj.layer = layers[layer];
+ if(new_obj) rt.insert(bounds,obj);
+ }
+
+ function treeSearch(x,y,w,h)
+ {
+ var results=rt.search({x:x,y:y,w:w,h:h});
+ if(results.length==0)
+ return [];
+ results.sort(sortRes);
+ return results;
+ }
+
+ function sortRes(a,b){ return b.layer-a.layer; }
+
+ function __mouseDown(e){
+ var xy=getXY(e);
+ xy.x = canv_off_x+xy.x/zoom;
+ xy.y = canv_off_y+xy.y/zoom;
+
+ var results=treeSearch(xy.x,xy.y,1,1);
+ for(var i=0;i<results.length;i++)
+ if(results[i].action[e.type])
+ results[i].func[e.type].apply(results[i], [{x:xy.x,y:xy.y}]);
+ }
+
+
+ function __drawImage(image, dx, dy)
+ {
+ if(arguments[8])
+ {
+ sx=dx;
+ sy=dy;
+ sw=arguments[3];
+ sh=arguments[4];
+ dx=arguments[5];
+ dy=arguments[6];
+ dw=arguments[7];
+ dh=arguments[8];
+ canvctx.drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh);
+ return new canvasElement(dx,dy,dw,dh);
+ }
+
+ if(arguments[3] && arguments[4])
+ {
+ dw=arguments[3];
+ dh=arguments[4];
+ }
+ else
+ {
+ dw=image.width;
+ dh=image.height;
+ }
+ canvctx.drawImage(image,dx,dy,dw,dh);
+ return new canvasElement(dx,dy,dw,dh);
+ }
+
+ function getXY(e)
+ {
+ var posx = 0;
+ var posy = 0;
+ if (!e) var e = window.event;
+ if (e.pageX || e.pageY) {
+ posx = e.pageX;
+ posy = e.pageY;
+ }
+ else if (e.clientX || e.clientY) {
+ posx = e.clientX + document.body.scrollLeft
+ + document.documentElement.scrollLeft;
+ posy = e.clientY + document.body.scrollTop
+ + document.documentElement.scrollTop;
+ }
+ posx=posx-canv.offsetLeft;
+ posy=posy-canv.offsetTop;
+ return {x:posx,y:posy};
+ }
+
+ function __mouseMove(e){
+ var xy=getXY(e);
+ xy.x = canv_off_x+xy.x/zoom;
+ xy.y = canv_off_y+xy.y/zoom;
+
+ var results=treeSearch(xy.x,xy.y,1,1),
+ thrown=null,
+ entryfound=false;
+ var results_copy = results.slice(0, results.length);
+ var l_mouse_ins = []; // Holds new (mousein) elements
+ var l_mouse_moves = []; // holds all repeated elements
+ // mouseouts will hold mouseouts
+ mouse.x=xy.x;
+ mouse.y=xy.y;
+
+ // Seperate the elements from mouseouts + results into three arrays (in, out, move)
+ while(results.length > 0)
+ {
+ var current_results = results.pop();
+
+ var m=0;
+ while(m<mouseouts.length)
+ {
+ if(mouseouts[m].id === current_results) //IF it was found in "results" then it is a move
+ {
+ l_mouse_moves.push(mouseouts.splice(m));
+ m-=1;
+ current_results = null;
+ }
+ m+=1;
+ }
+ if(current_results) //IF it wasn't found in "results" then it is new
+ l_mouse_ins.push(current_results);
+ }
+
+ // now the three arrays contain the elements they should..
+ while(mouseouts.length>0)
+ {
+ var thrown=mouseouts.pop();
+ if(thrown.action['mouseout'])
+ thrown.func['mouseout']({x:xy.x,y:xy.y});
+ }
+ while(l_mouse_ins.length>0)
+ {
+ var thrown=l_mouse_ins.pop();
+ if(thrown.action['mouseover'])
+ thrown.func['mouseover']({x:xy.x,y:xy.y});
+ }
+ while(l_mouse_moves.length>0)
+ {
+ var thrown=l_mouse_moves.pop();
+ if(thrown.action['mousemove'])
+ thrown.func['mousemove']({x:xy.x,y:xy.y});
+ }
+ mouseouts = results_copy;
+ }
+
+ function init(canvid, width, height)
+ {
+ canv=document.getElementById(canvid);
+ canv.addEvent=function(type,func){
+ if(canv.addEventListener)
+ canv.addEventListener(type,func,false);
+ else if(canv.attachEvent)
+ canv.attachEvent(type,func);
+ };
+
+ canv.addEvent('mousedown',__mouseDown);
+ canv.addEvent('mouseup',__mouseDown);
+ canv.addEvent('click',__mouseDown);
+ canv.addEvent('dblclick',__mouseDown);
+
+ if(canv.getContext)
+ canvctx=canv.getContext('2d');
+ }
+
+ return {
+ init: init,
+ attachEvent: addIndex,
+ drawImage: __drawImage,
+ getTree: function(){return(rt);}
+ }
+
+})();
+
+canvwrap.init("game", 650, 475);
+
+var ctx=document.getElementById('game');
+ctx = ctx.getContext('2d');
+
+function test(dir){
+ //alert(dir);
+ var dirarr=['top_left', 'top', 'top_right', 'right', 'bottom_right', 'bottom', 'bottom_left', 'left'];
+ document.getElementById('status').innerHTML=dirarr[dir] + " was clicked!";
+}
+
+var canv_off_x = 1237;
+var canv_del_x = 0;
+var canv_off_y = 931;
+var canv_del_y = 0;
+var zoom = 1;
+var zdel = 0.99; // speed of zoom
+zdel = 1.0;
+
+var border_width = 4.0;
+
+var fps_timer = false;
+
+function draw_nodes(context)
+{
+ var hit_stack = []; // Contains the local elements (at current tree depth) that overlap
+ var temp_tree = canvwrap.getTree().get_tree();
+
+ context.strokeStyle = "rgb(0,0,0)";
+ context.lineWidth = border_width*zoom;
+
+// hit_stack.push(temp_tree.nodes);
+// context.strokeRect(temp_tree.x, temp_tree.y, temp_tree.w, temp_tree.h);
+
+ var elements = canvwrap.getTree().search({x:canv_off_x,y:canv_off_y,w:context.canvas.width/zoom,h:context.canvas.height/zoom}, true);
+ var to_draw = elements.length;
+if(window["console"] && console.time && fps_timer)
+ console.time("Draw Frame...");
+ while(elements.length >0)
+ {
+ var el = elements.pop();
+ context.strokeRect((el.x-canv_off_x)*zoom, (el.y-canv_off_y)*zoom, el.w*zoom, el.h*zoom);
+ context.fillStyle=el.leaf.color;
+ context.fillRect((el.x-canv_off_x)*zoom, (el.y-canv_off_y)*zoom, el.w*zoom, el.h*zoom);
+ //context.fillText(el.node.id+"", (el.x-canv_off_x+1)*zoom, (el.y-canv_off_y)*zoom);
+ }
+ if(window["console"] && console.timeEnd && fps_timer && !(fps_timer = false))
+ console.timeEnd("Draw Frame...");
+ return(to_draw);
+}
+
+function draw(){
+ var tcanvas = document.getElementById("game");
+ var ctx = tcanvas.getContext("2d");
+
+// ctx.fillStyle="rgba(255,255,255,0.3)";
+// ctx.fillRect(0, 0, tcanvas.width, tcanvas.height);
+ ctx.clearRect(0, 0, tcanvas.width, tcanvas.height)
+
+ var drawn = draw_nodes(ctx);
+ ctx.clearRect(0, 0, 160, 40);
+ ctx.fillStyle="rgb(0,0,0)";
+ ctx.fillText("# of Elements on Screen: " + drawn, 10, 10);
+ ctx.fillText("# of Elements in Tree: " + test_damnit, 10, 20);
+ ctx.fillText("-= " + col_name +" =-", 10, 30);
+}
+
+q=0;
+var test_damnit = 0;
+
+switch(parseInt((Math.random()*7.99)))
+{
+ case 0:
+ col_name="Primarily Mellow";
+ cols =['#B01E1E','#174385','#15592F','#FCDC0A','#000000'];border_width = 3.0;
+ break;
+ case 1:
+ col_name="A Sad Memory";
+ cols =['#1C465C','#597B6B','#D5C263','#E8DF97','#2D88A5'];border_width = 5.0;
+ break;
+ case 2:
+ col_name="Patriot Games";
+ cols =['#ffffff','#353842','#5E6669','#BED1AE','#5E6669','#DEEFBB','#5E6669','#BED1AE','#5E6669','#DEEFBB','#C7493B'];border_width = 3.0;
+ break;
+ case 3:
+ col_name="Weakerthans";
+ cols =['#ffffff', '#292929','#292929','#E2E2E2','#E2E2E2','#E2E2E2','#1A4685','#E80101','#FFBF15'];border_width = 1.0;
+ break;
+ case 4:
+ col_name="Stoicism";
+ cols =['#303030','#303030','#303030','#303030','#303030','#303030','#303030','#303030','#F5EDDF','#F5EDDF','#F5EDDF','#F5EDDF','#F5EDDF','#EDE592','#EDE592','#BFC7C7','#BFC7C7','#D84818']; border_width = 1.0;
+ break;
+ case 5:
+ col_name="Fish bowl";
+ cols =['#BDCCDF', '#BDD1DE', '#BDDEDE', '#BDDED7', '#FC8B4A'];border_width = 1.0;
+ break;
+ case 6:
+ col_name="Bull in a China Shop";
+ cols =['#FDECB1','#F7E5B5','#3A271F','#C51616','#EDDBB4'];border_width = 3.0;
+ break;
+ case 7:
+ col_name="A Funk Odyssey";
+ cols =['#7A6C5D','#7A6C5D','#7A6C5D','#7A6C5D','#7A6C5D','#7A6C5D','#F0B603','#F0B603','#F0B603','#F0B603','#F0B603','#98AAAC','#98AAAC','#98AAAC','#A3033D','#A3033D','#E9FABE'];border_width = 3.0;
+ break;
+}
+
+// LOAD PRE-BUILT TREE
+// canvwrap.getTree().set_tree(OBJ_TREE_20K);
+
+if( canvwrap.getTree().get_tree().nodes.length == 0 )
+{
+ var scale_fact = 1.0;
+
+ var new_func = function(e){alert("You hit object number '" + this.id + "' and the fill color is '"+ this.color);};
+ var do_some_then_yield = function(){
+ var loops = 0;
+ var made = 0;
+ var bounds = {x:(Math.random()*6000+20), y:(Math.random()*4000+7), w:(Math.random()*(100/scale_fact)+1), h:(Math.random()*(100/scale_fact)+1)};
+ var opts = {color:cols[(Math.random()*100).toFixed()%5]};
+ while(test_damnit < 20000)
+ {
+ if(canvwrap.getTree().count({x:bounds.x-border_width-(25/scale_fact), y:bounds.y-border_width-(25/scale_fact), w:bounds.w+border_width*2+(50/scale_fact), h:bounds.h+border_width*2+(50/scale_fact)}) == 0)
+ {
+ canvwrap.attachEvent(bounds,test_damnit,'mousedown', new_func, null, opts);
+ test_damnit++;
+ bounds = {x:(Math.random()*6000+20), y:(Math.random()*4000+7), w:(Math.random()*(100/scale_fact)+1), h:(Math.random()*(100/scale_fact)+1)};
+ var opts = {color:cols[(Math.random()*123).toFixed()%cols.length]};
+ made++;
+ }
+ else
+ {
+ bounds.x=(Math.random()*6000+20); bounds.y=(Math.random()*4000+7); bounds.w=(Math.random()*(100/scale_fact)+1); bounds.h=(Math.random()*(100/scale_fact)+1);
+ }
+ loops++;
+ if(loops >= 500)
+ {
+ if(loops/made > 5)
+ scale_fact *= 2;
+ setTimeout(do_some_then_yield, 0);
+ return;
+ }
+ }
+ canv_del_x = canv_del_y = -2;
+ };
+ do_some_then_yield();
+}
+//canv_del_x = canv_del_y = -2;
+setInterval(function(){ if(zoom > 2 || zoom < 0.4) zdel = 1.0 / zdel; if(canv_off_x > 5400 || canv_off_x < 0) canv_del_x*=-1; if(canv_off_y > 3600 || canv_off_y < 0) canv_del_y*=-1; zoom *= zdel; canv_off_x += (canv_del_x/zoom); canv_off_y += (canv_del_y/zoom); draw();}, 30); // Yield to browser temporarily to suppress "script is taking too damn long!" alert
+
+//ctx.drawImage(document.getElementById('test'), 0, 0, 50, 50, 200, 200, 50, 50); // not possible without an intermediary
+
+
+
+var UI=(function(){
+
+ var arrows=[
+ [img=new Image(10,10),'top_left',2,2,10,10,0],
+ [img=new Image(10,10),'top',14,2,10,10,1],
+ [img=new Image(10,10),'top_right',26,2,10,10,2],
+ [img=new Image(10,10),'right',26,14,10,10,3],
+ [img=new Image(10,10),'bottom_right',26,26,10,10,4],
+ [img=new Image(10,10),'bottom',14,26,10,10,5],
+ [img=new Image(10,10),'bottom_left',2,26,10,10,6],
+ [img=new Image(10,10),'left',2,14,10,10,7]];
+
+ function loadUI(){
+ // arrows for the top are so far implemented
+ var imagessrc="/files/images/game_ui/arrows_new/",
+ imgext="gif";
+
+ for(var i=0;i<arrows.length;i++)
+ {
+ arrows[i][0].src=imagessrc+arrows[i][1]+"."+imgext;
+ arrows[i][0].onload=function(im){return function(){im.loaded=true; loadProgress();}}(arrows[i]);
+ }
+ }
+
+ function loadProgress(){
+ if(!this.loaded)
+ this.loaded=0;
+ this.loaded++;
+
+ if(this.loaded==7)
+ drawArrows();
+ }
+
+ function drawArrows(){
+ /*index=index||-1;
+ if(index>=0)
+ if(arrows[index].loaded){
+ ctx.drawImage(arrows[index][0], arrows[index][2], arrows[index][3]);
+ attEvent.add(function(i){return function(){test(arrows[i][6]);}}(index),arrows[index][2],arrows[index][3],arrows[index][4],arrows[index][5],'ui');
+ }
+ else
+ setTimeout(function(){ drawArrows(arrows,i); }, 45);
+ else
+ */for(var i=0;i<arrows.length;i++)
+ {
+ //if(arrows[i].loaded){
+ x=arrows[i][2];
+ y=arrows[i][3];
+ w=arrows[i][4];
+ h=arrows[i][5];
+ canvwrap.drawImage(arrows[i][0], x, y, w, h).attachEvent('mousedown',function(i){
+ return function(){
+ test(arrows[i][6]);
+ }
+ }(i));
+
+ /*}
+ //else
+ //{
+ setTimeout(function(i){return function(){drawArrows(arrows,i);}}(i), 45);
+ break;
+ */}
+ }
+
+ return {
+ load: loadUI
+ };
+
+})();
+
+//UI.load();
+
+</script>
+</body>
+</html>
26 examples/index.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+ <title>R-Tree Madness</title>
+ <script type='text/javascript' src="../libs/jquery.min.js"></script>
+</head>
+<body>
+<h1>R-Tree for Javascript</h1>
+<form style="float:right;"action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_s-xclick"><input type="hidden" name="hosted_button_id" value="10326004"><input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"><img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1"></form>
+<p>This page contains examples of my R-Tree Library (<a href="rtree.js">rtree.js</a>) for Javascript. Check the results of some <a href="unit.html">unit tests</a>.
+</p>
+<h3>Tests:</h3>
+<h4><a href="simple_test.html">Simple Playground</a></h4>
+<p>A simple interactive example of the R-Tree. Great for understanding R-Tree principles.
+</p>
+<h4><a href="rtree.html">Area Effect</a></h4>
+<p>Generates a group of 6500 random small non-overlapping rectangles and shows the resultant tree-structure using a &quot;heat-map&quot;.
+</p>
+<h4><a href="numbers.html">Benchmark</a></h4>
+<p>Inserts 10k objects. Performs some searches. Inserts another 10k objects. Performs some searches. Deletes and reinserts some objects. Performs some final searches.
+<a href="rtree_benchmark.png">Screenshot of various benchmark results</a></p>
+<h4><a href="canvas_test_generate.html">Super-Harcore Example</a></h4>
+<p><b>ONLY run on Opera, Chrome, Safari, or Firefox 3.6 nightlies!</b><br/>
+This test generates 20k dense non-overlapping rectangles of various size and color.
+</p>
+</body>
+</html>
121 examples/numbers.html
@@ -0,0 +1,121 @@
+<html>
+<head>
+ <title>R-Tree for Javascript - Just the numbers</title>
+ <script src="../libs/jquery.min.js"></script>
+ <script src="../src/rtree.js"></script>
+ <script>
+ $(document).ready(function() {
+ var rt = new RTree(32);
+ var deleted_set = new Array();
+ var test_name = ['Inserting 10k elements..','Performing 1k window queries..','Inserting 10k more elements..','Performing 1k window queries..','Deleting 1k elements..','Reinserting the deleted 1k elements..','Performing 1k window queries..'];
+ var test_func = new Array(7);
+ test_func[0] = function(i) {
+ var bounds;
+ while(i > 0) {
+ bounds = {x:(Math.random()*100000), y:(Math.random()*100000), w:(Math.random()*500), h:(Math.random()*500)};
+ rt.insert(bounds, "JUST A TEST OBJECT!_"+i);
+ i--;
+ }
+ };
+ test_func[1] = function(i) {
+ var bounds;
+ i/=10;
+ while(i > 0) {
+ bounds = {x:(Math.random()*95000), y:(Math.random()*95000), w:(Math.random()*1000), h:(Math.random()*1000)};
+ rt.search(bounds);
+ i--;
+ }
+ };
+ test_func[2] = function(i) {
+ var bounds;
+ while(i > 0) {
+ bounds = {x:(Math.random()*100000), y:(Math.random()*100000), w:(Math.random()*500), h:(Math.random()*500)};
+ rt.insert(bounds, "JUST ANOTHER TEST OBJECT!_"+i);
+ i--;
+ }
+ };
+ test_func[3] = function(i) {
+ var bounds;
+ i/=10;
+ while(i > 0) {
+ bounds = {x:(Math.random()*95000), y:(Math.random()*95000), w:(Math.random()*1000), h:(Math.random()*1000)};
+ rt.search(bounds);
+ i--;
+ }
+ };
+ test_func[4] = function(i) {
+ var bounds;
+ var output;
+ i/=10;
+ var original_i = i;
+ while(i > 0) {
+ bounds = {x:(Math.random()*95000), y:(Math.random()*95000), w:(Math.random()*1000), h:(Math.random()*1000)};
+ output = rt.remove(bounds);
+ if(output.length > 0) {
+ i-=output.length;
+ while(i < 0) {
+ t=output.pop();
+ rt.insert(t, t.leaf);
+ i++;
+ }
+ deleted_set = deleted_set.concat(output);
+ }
+ }
+ };
+ test_func[5] = function(i) {
+ var output;
+ i = 0;
+ while(deleted_set.length > 0) {
+ output = deleted_set.pop();
+ rt.insert(output, output.leaf);
+ i++;
+ }
+ };
+ test_func[6] = function(i) {
+ var bounds;
+ i/=10;
+ while(i > 0) {
+ bounds = {x:(Math.random()*95000), y:(Math.random()*95000), w:(Math.random()*1000), h:(Math.random()*1000)};
+ rt.search(bounds);
+ i--;
+ }
+ };
+ var ti = 0;
+ var yield_some = function() {
+ var results_name = "results_"+ti;
+ if(ti % 2 == 0)
+ var test_output = $('<div class="even_row" id="'+results_name+'"><div>'+test_name[ti]+'</div></div>');
+ else
+ var test_output = $('<div class="odd_row" id="'+results_name+'"><div>'+test_name[ti]+'</div></div>');
+ $("#results").append(test_output);
+ var start = (new Date).getTime();
+ test_func[ti](10000);
+ var diff = (new Date).getTime() - start;
+ $('<div>Time To Run: '+diff+'ms</div>').appendTo($("#"+results_name));
+ $('<div>Number of Elements in Tree: '+rt.count({x:-1, y:-1, w:100600, h:100600})+'</div>').appendTo($("#"+results_name));
+ ti+=1;
+ if(ti < 7) {
+ setTimeout(yield_some, 1000);
+ return;
+ }
+ delete rt;
+ }
+ yield_some();
+ });
+ </script>
+ <style>
+ .even_row { padding:10px;
+ background-color:#fefefe;
+ }
+ .odd_row { padding:10px;
+ background-color:#efefff;
+ }
+ </style>
+</head>
+<body>
+<h1>Raw freaking R-Tree numbers!</h1>
+<p>Note the faster searches after re-insertion of the same elements that were deleted.</p>
+<div id="results">
+</div>
+</body>
+</html>
146 examples/rtree.html
@@ -0,0 +1,146 @@
+<html>
+
+<script type='text/javascript' src='../libs/firebug-lite-compressed.js'></script>
+<script type='text/javascript' src="../libs/excanvas.compiled.js"></script>
+<script type='text/javascript' src="../src/rtree.js"></script>
+<script type='text/javascript'>
+var temp_tree = new RTree();
+function getMousePos(e)
+{
+ var posx = 0;
+ var posy = 0;
+ if (!e) var e = window.event;
+ if (e.pageX || e.pageY) {
+ posx = e.pageX;
+ posy = e.pageY;
+ }
+ else if (e.clientX || e.clientY) {
+ posx = e.clientX + document.body.scrollLeft
+ + document.documentElement.scrollLeft;
+ posy = e.clientY + document.body.scrollTop
+ + document.documentElement.scrollTop;
+ }
+ // posx and posy contain the mouse position relative to the document
+ // Do something with this information
+ var tcanvas = document.getElementById("tree_canvas");
+ posx = posx - tcanvas.offsetLeft; posy = posy - tcanvas.offsetTop;
+ return([posx*10,posy*10]);
+
+}
+function dodown(e)
+{
+
+}
+
+function doclick(e)
+{
+ pos = getMousePos(e);
+ console.time("Deleting a portion of "+yy+" objects within a 100x100 pixel window");
+ var t = temp_tree.remove({x:pos[0]-500,y:pos[1]-500,w:1000,h:1000});
+ console.timeEnd("Deleting a portion of "+yy+" objects within a 100x100 pixel window");
+ console.log("Deleted "+t.length+" objects!");
+ draw();
+}
+
+var redraw_timer = null;
+var yy=0;
+var yy_target=6500;
+
+/**
+ * A doload.
+ * @constructor
+ */
+doload = function()
+{
+ var tcanvas = document.getElementById("tree_canvas");
+ if(tcanvas.addEventListener)
+ tcanvas.addEventListener("click", doclick, false);
+
+ console.time("Adding "+yy_target+" non-overlapping objects to the R-Tree");
+ build();
+}
+var tries = 0;
+
+build = function(){
+ tries = 0;
+ while(yy<yy_target)
+ {
+ build_step();
+ if(tries >= 500)
+ {
+ // console.time("Drawing 20k objects from the R-Tree");
+ // draw();
+ // console.timeEnd("Drawing 20k objects from the R-Tree");
+ setTimeout(build, 1); // For no script timeout
+ return;
+ }
+ }
+ console.timeEnd("Adding "+yy_target+" non-overlapping objects to the R-Tree");
+ draw();
+}
+
+build_step = function()
+{
+ var bounds = {x:(Math.random()*12000+200), y:(Math.random()*8800+100), w:(Math.random()*50+1), h:(Math.random()*50+1)};
+ if(/*temp_tree.count(bounds)*/0 == 0)
+ {
+ temp_tree.insert(bounds, {id:"test_object_"+yy, color:"white"});
+ yy+=1;
+ }
+ tries += 1;
+}
+
+function draw_nodes(context)
+{
+ var hit_stack = []; // Contains the local elements (at current tree depth) that overlap
+ var drawn = 0;
+ var leaf_stack = [];
+ hit_stack.push(temp_tree.get_tree().nodes);
+ context.strokeRect(temp_tree.get_tree().x/10, temp_tree.get_tree().y/10, temp_tree.get_tree().w/10, temp_tree.get_tree().h/10);
+ context.strokeStyle = "rgba(155,50,50,0.1)";
+ context.fillStyle = "rgba(225,155,155,0.01)";
+ do
+ {
+ var nodes = hit_stack.pop();
+
+ for(var i = nodes.length-1; i >= 0; i--)
+ {
+ var ltree = nodes[i];
+ if("nodes" in ltree) // Not a Leaf
+ {
+ context.strokeRect(ltree.x/10, ltree.y/10, ltree.w/10, ltree.h/10);
+ context.fillRect(ltree.x/10, ltree.y/10, ltree.w/10, ltree.h/10);
+ hit_stack.push(ltree.nodes);
+ }else
+ leaf_stack.push(ltree);
+ }
+ }while(hit_stack.length > 0);
+ context.fillStyle = "rgba(20,20,20,0.8)";
+ do
+ {
+ var leaf = leaf_stack.pop();
+ drawn++;
+ context.fillRect(leaf.x/10, leaf.y/10, leaf.w/10, leaf.h/10);
+ }while(leaf_stack.length > 0);
+ return drawn;
+}
+
+function draw(){
+ var tcanvas = document.getElementById("tree_canvas");
+ var ctx = tcanvas.getContext("2d");
+ ctx.clearRect(0, 0, tcanvas.width, tcanvas.height)
+ ctx.fillStyle = "rgb(0,0,0)";
+
+
+ ctx.strokeStyle = "rgb(0,150,0)";
+ var drawn = draw_nodes(ctx);
+
+ ctx.clearRect(0, 0, 160, 15);
+ if("fillText" in ctx) ctx.fillText("Current # of Elements: " + drawn, 10, 10);
+}
+</script>
+<body onload="doload()">
+ This test generates 6500 small and non-overlapping rectangles. Each left mouse click searches a 100x100 pixel window deleting any elements it funds. The time taken is reported in the firebug-lite console.<br/>
+ <canvas id="tree_canvas" width="1250" height="900" style="border:1px solid #000;">
+ </canvas>
+</body>
469 examples/simple_test.html
@@ -0,0 +1,469 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>More Canvas Fun</title>
+<script type='text/javascript' src="../src/rtree.js"></script>
+</head>
+<body>
+ The black outline is the tree's root node. Each pink outline is a sub-node.<br/>
+ Click on a rectangle to delete it and see the result in the R-Tree. <br/>
+ Click on any blank area to create a new rectangle and add it to the R-Tree.<br/>
+ <canvas id="game" width="1000px" height="500px" style="border:1px solid blue;">
+ </canvas>
+<script>
+var new_funcs = function(e){canvwrap.getTree().remove({x:e.x,y:e.y,w:1,h:1});};
+var dirty_frame = false;
+var border_width = 4.0; // default?
+
+switch(parseInt((Math.random()*7.99)))
+{
+ case 0:
+ col_name="Primarily Mellow";
+ cols =['#B01E1E','#174385','#15592F','#FCDC0A','#000000'];border_width = 3.0;
+ break;
+ case 1:
+ col_name="A Sad Memory";
+ cols =['#1C465C','#597B6B','#D5C263','#E8DF97','#2D88A5'];border_width = 5.0;
+ break;
+ case 2:
+ col_name="Patriot Games";
+ cols =['#ffffff','#353842','#5E6669','#BED1AE','#5E6669','#DEEFBB','#5E6669','#BED1AE','#5E6669','#DEEFBB','#C7493B'];border_width = 3.0;
+ break;
+ case 3:
+ col_name="Weakerthans";
+ cols =['#ffffff', '#292929','#292929','#E2E2E2','#E2E2E2','#E2E2E2','#1A4685','#E80101','#FFBF15'];border_width = 1.0;
+ break;
+ case 4:
+ col_name="Stoicism";
+ cols =['#303030','#303030','#303030','#303030','#303030','#303030','#303030','#303030','#F5EDDF','#F5EDDF','#F5EDDF','#F5EDDF','#F5EDDF','#EDE592','#EDE592','#BFC7C7','#BFC7C7','#D84818']; border_width = 1.0;
+ break;
+ case 5:
+ col_name="Fish bowl";
+ cols =['#BDCCDF', '#BDD1DE', '#BDDEDE', '#BDDED7', '#FC8B4A'];border_width = 1.0;
+ break;
+ case 6:
+ col_name="Bull in a China Shop";
+ cols =['#FDECB1','#F7E5B5','#3A271F','#C51616','#EDDBB4'];border_width = 3.0;
+ break;
+ case 7:
+ col_name="A Funk Odyssey";
+ cols =['#7A6C5D','#7A6C5D','#7A6C5D','#7A6C5D','#7A6C5D','#7A6C5D','#F0B603','#F0B603','#F0B603','#F0B603','#F0B603','#98AAAC','#98AAAC','#98AAAC','#A3033D','#A3033D','#E9FABE'];border_width = 3.0;
+ break;
+}
+</script>
+<script src="20k_tree.js"></script>
+ <script type="text/javascript">
+
+ /* I want to be able to do: (one day)
+ * cQuery:
+ * addObject(object_interface)
+ *
+ *
+ * cQuery(Rectangle | CanvasObject) [decorated array]
+ *
+ * object interface:
+ * attachEvent(event_name,function())
+ * removeEvent(event_name)
+ * doAreaEvent(event_name)
+ *
+ */
+/********************************************
+ * Full Canvas Library *
+ ********************************************/
+
+var canvwrap=(function(){
+
+ var canv=null,
+ canvctx=null,
+ rt=new RTree(),
+ layers={'main':0},
+ mouse={track:false,x:0,y:0},
+ mouseouts=[],
+ mouseoutids=0;
+
+ var canvasElement=function(x,y,w,h){
+ this.x=x;
+ this.y=y;
+ this.w=w;
+ this.h=h;
+ }
+
+ canvasElement.prototype.attachEvent=function(action,func,layer){
+ canvwrap.attachEvent({x:this.x,y:this.y,w:this.w,h:this.h},action,func,layer);
+ }
+
+ canvasElement.prototype.toString=function(){ return '[CanvasElement]'; };
+
+ function addIndex(bounds,id,action,func,layer, opts)
+ {
+ if(!func) return;
+ if(!layer) layer='main';
+
+ // Get all overlapping objects from the tree
+ var local_objs = rt.search({x:bounds.x,y:bounds.y,w:bounds.w,h:bounds.h});
+ var new_obj = true;
+
+ // Look for an existing object with our same ID
+ while(local_objs.length > 0)
+ {
+ obj = local_objs.pop();
+ if(obj.id == id)
+ {
+ new_obj = false;
+ break;
+ }
+ }
+ // If no object was found, make a new one...
+ if(new_obj) obj = {"func":{}, "action":{}, "id":id};
+
+ // If no events have been attached to the canvas, attach them..
+ if((action=='mouseover' || action=='mouseout' || action=='mousemove') && !mouse.track)
+ {
+ mouse.track=true;
+ canv.addEvent('mousemove',__mouseMove);
+ }
+
+ for (var k in opts)
+ obj[k] = opts[k];
+
+
+ // Update our obj's properties
+ obj.func[action] = func;
+ obj.action[action] = true;
+ obj.layer = layers[layer];
+ if(new_obj) rt.insert(bounds,obj);
+ }
+
+ function treeSearch(x,y,w,h)
+ {
+/* if(window["console"] && console.time)
+ console.time("Searching Tree...");*/
+ var results=rt.search({x:x,y:y,w:w,h:h});
+/* if(window["console"] && console.timeEnd)
+ console.timeEnd("Searching Tree...");*/
+
+ if(results.length==0)
+ return [];
+ results.sort(sortRes);
+ return results;
+ }
+
+ function sortRes(a,b){ return b.layer-a.layer; }
+
+ function __mouseDown(e){
+ var xy=getXY(e);
+ xy.x = canv_off_x+xy.x/zoom;
+ xy.y = canv_off_y+xy.y/zoom;
+ var results=treeSearch(xy.x,xy.y,1,1);
+ var result_count = results.length;
+ if(result_count > 0) {
+ for(var i=0;i<results.length;i++) {
+ if(results[i].action[e.type])
+ results[i].func[e.type].apply(results[i], [{x:xy.x,y:xy.y}]);
+ }
+ } else {
+ var bounds = {x:xy.x, y:xy.y, w:(Math.random()*10), h:(Math.random()*10)};
+ var opts = {color:cols[(Math.random()*100).toFixed()%cols.length]};
+ if(rt.count(bounds) == 0)
+ {
+ canvwrap.attachEvent(bounds,test_damnit,'mousedown', new_funcs, null, opts);
+ test_damnit++;
+ }
+ }
+ dirty_frame = true;
+ }
+
+ function __drawImage(image, dx, dy)
+ {
+ if(arguments[8])
+ {
+ sx=dx;
+ sy=dy;
+ sw=arguments[3];
+ sh=arguments[4];
+ dx=arguments[5];
+ dy=arguments[6];
+ dw=arguments[7];
+ dh=arguments[8];
+ canvctx.drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh);
+ return new canvasElement(dx,dy,dw,dh);
+ }
+
+ if(arguments[3] && arguments[4])
+ {
+ dw=arguments[3];
+ dh=arguments[4];
+ }
+ else
+ {
+ dw=image.width;
+ dh=image.height;
+ }
+ canvctx.drawImage(image,dx,dy,dw,dh);
+ return new canvasElement(dx,dy,dw,dh);
+ }
+
+ function getXY(e)
+ {
+ var posx = 0;
+ var posy = 0;
+ if (!e) var e = window.event;
+ if (e.pageX || e.pageY) {
+ posx = e.pageX;
+ posy = e.pageY;
+ }
+ else if (e.clientX || e.clientY) {
+ posx = e.clientX + document.body.scrollLeft
+ + document.documentElement.scrollLeft;
+ posy = e.clientY + document.body.scrollTop
+ + document.documentElement.scrollTop;
+ }
+ posx=posx-canv.offsetLeft;
+ posy=posy-canv.offsetTop;
+ return {x:posx,y:posy};
+ }
+
+ function __mouseMove(e){
+ var xy=getXY(e);
+ xy.x = canv_off_x+xy.x/zoom;
+ xy.y = canv_off_y+xy.y/zoom;
+
+ var results=treeSearch(xy.x,xy.y,1,1),
+ thrown=null,
+ entryfound=false;
+ var results_copy = results.slice(0, results.length);
+ var l_mouse_ins = []; // Holds new (mousein) elements
+ var l_mouse_moves = []; // holds all repeated elements
+ // mouseouts will hold mouseouts
+ mouse.x=xy.x;
+ mouse.y=xy.y;
+
+ // Seperate the elements from mouseouts + results into three arrays (in, out, move)
+ while(results.length > 0)
+ {
+ var current_results = results.pop();
+
+ var m=0;
+ while(m<mouseouts.length)
+ {
+ if(mouseouts[m].id === current_results) //IF it was found in "results" then it is a move
+ {
+ l_mouse_moves.push(mouseouts.splice(m));
+ m-=1;
+ current_results = null;
+ }
+ m+=1;
+ }
+ if(current_results) //IF it wasn't found in "results" then it is new
+ l_mouse_ins.push(current_results);
+ }
+
+ // now the three arrays contain the elements they should..
+ while(mouseouts.length>0)
+ {
+ var thrown=mouseouts.pop();
+ if(thrown.action['mouseout'])
+ thrown.func['mouseout']({x:xy.x,y:xy.y});
+ }
+ while(l_mouse_ins.length>0)
+ {
+ var thrown=l_mouse_ins.pop();
+ if(thrown.action['mouseover'])
+ thrown.func['mouseover']({x:xy.x,y:xy.y});
+ }
+ while(l_mouse_moves.length>0)
+ {
+ var thrown=l_mouse_moves.pop();
+ if(thrown.action['mousemove'])
+ thrown.func['mousemove']({x:xy.x,y:xy.y});
+ }
+ mouseouts = results_copy;
+ }
+
+ function init(canvid, width, height)
+ {
+ canv=document.getElementById(canvid);
+ canv.addEvent=function(type,func){
+ if(canv.addEventListener)
+ canv.addEventListener(type,func,false);
+ else if(canv.attachEvent)
+ canv.attachEvent(type,func);
+ };
+
+ canv.addEvent('mousedown',__mouseDown);
+ // canv.addEvent('mouseup',__mouseDown);
+ // canv.addEvent('click',__mouseDown);
+ // canv.addEvent('dblclick',__mouseDown);
+
+ if(canv.getContext)
+ canvctx=canv.getContext('2d');
+ }
+
+ return {
+ init: init,
+ attachEvent: addIndex,
+ drawImage: __drawImage,
+ getTree: function(){return(rt);}
+ }
+
+})();
+
+canvwrap.init("game", 650, 475);
+
+var ctx=document.getElementById('game');
+ctx = ctx.getContext('2d');
+
+function test(dir){
+ //alert(dir);
+ var dirarr=['top_left', 'top', 'top_right', 'right', 'bottom_right', 'bottom', 'bottom_left', 'left'];
+ document.getElementById('status').innerHTML=dirarr[dir] + " was clicked!";
+}
+
+var canv_off_x = 0;
+var canv_del_x = 0;
+var canv_off_y = 0;
+var canv_del_y = 0;
+var zoom = 1;
+var zdel = 0.99; // speed of zoom
+zdel = 1.0;
+
+var fps_timer = false;
+var draw_tree = true;
+
+function draw_nodes(context)
+{
+ var hit_stack = []; // Contains the local elements (at current tree depth) that overlap
+
+ var to_draw = 0;
+ var hit_stack = []; // Contains the elements that overlap
+ var T = canvwrap.getTree().get_tree();
+ var rect = {x:canv_off_x, y:canv_off_y, w:document.getElementById("game").width*zoom, h:document.getElementById("game").height*zoom };
+ context.strokeStyle = "rgb(0,0,0)";
+ context.lineWidth = 0.5;
+ context.strokeRect((T.x-canv_off_x)*zoom, (T.y-canv_off_y)*zoom, T.w*zoom, T.h*zoom);
+ context.strokeStyle = "rgb(0,0,0)";
+ context.lineWidth = border_width*zoom;
+
+ if(!RTree.Rectangle.overlap_rectangle(rect, T))
+ return(0);
+
+ hit_stack.push(T.nodes);
+
+/* if(window["console"] && console.time && fps_timer)
+ console.time("Draw Frame...");
+*/
+ do
+ {
+ var nodes = hit_stack.pop();
+ for(var i = nodes.length-1; i >= 0; i--)
+ {
+ var el = nodes[i];
+ if(RTree.Rectangle.overlap_rectangle(rect, el))
+ {
+ if(el.nodes) // Not a Leaf
+ {
+ hit_stack.push(el.nodes);
+ if(draw_tree)
+ {
+ context.strokeStyle = "rgb(200,100,100)";
+ context.lineWidth = 0.33;
+ context.strokeRect((el.x-canv_off_x)*zoom, (el.y-canv_off_y)*zoom, el.w*zoom, el.h*zoom);
+
+ //return to old style
+ context.strokeStyle = "rgb(0,0,0)";
+ context.lineWidth = border_width*zoom;
+ to_draw++;
+ }
+ }
+ else // A Leaf !!
+ {
+// if(!draw_tree)
+// {
+ to_draw++;
+ context.strokeRect((el.x-canv_off_x)*zoom, (el.y-canv_off_y)*zoom, el.w*zoom, el.h*zoom);
+ context.fillStyle=el.leaf.color;
+ context.fillRect((el.x-canv_off_x)*zoom, (el.y-canv_off_y)*zoom, el.w*zoom, el.h*zoom);
+// }
+ }
+ }
+ }
+ }while(hit_stack.length > 0);
+
+/* if(window["console"] && console.timeEnd && fps_timer && !(fps_timer = false))
+ console.timeEnd("Draw Frame...");
+*/
+ return(to_draw);
+}
+
+
+
+
+function draw(){
+ if(dirty_frame) {
+ dirty_frame = false;
+ var tcanvas = document.getElementById("game");
+ var ctx = tcanvas.getContext("2d");
+ ctx.clearRect(0, 0, tcanvas.width, tcanvas.height)
+ //ctx.fillStyle = "rgb(0,0,0)";
+
+ //ctx.strokeStyle = "rgb(0,150,0)";
+ ctx.fillStyle="rgb(200,200,200)";
+
+ var drawn = draw_nodes(ctx);
+
+ ctx.clearRect(0, 0, 160, 40);
+ ctx.fillStyle="rgb(0,0,0)";
+ ctx.fillText("# of Elements on Screen: " + drawn, 10, 10);
+ ctx.fillText("# of Elements in Tree: " + test_damnit, 10, 20);
+ ctx.fillText("-= " + col_name +" =-", 10, 30);
+ }
+}
+
+q=0;
+var test_damnit = 0;
+
+
+// LOAD PRE-BUILT TREE
+
+//console.log(canvwrap.getTree().set_tree(OBJ_TREE_20K)); test_damnit = 20000; canv_del_x = canv_del_y = -2;
+
+if( canvwrap.getTree().get_tree().nodes.length == 0 )
+{
+ var do_some_then_yield = function(){
+ var loops = 0; var yy= (Math.random()*10);
+ var bounds = {x:(Math.random()*969), y:yy*30+50, w:(Math.random()*25+5), h:(Math.random()*25+5)};
+ var opts = {color:cols[(Math.random()*100).toFixed()%cols.length]};
+ while(test_damnit < 10)
+ {
+ if(canvwrap.getTree().count({x:bounds.x, y:bounds.y, w:bounds.w, h:bounds.h}) == 0)
+ {
+ canvwrap.attachEvent(bounds,test_damnit,'mousedown', new_funcs, null, opts);
+ test_damnit++;
+ yy= (Math.random()*20);
+ bounds = {x:(Math.random()*969), y:yy*30+50, w:(Math.random()*25+5), h:(Math.random()*25+5)};
+ var opts = {color:cols[(Math.random()*123).toFixed()%cols.length]};
+ }
+ else
+ {
+ yy= (Math.random()*20);
+ bounds.x=(Math.random()*969); bounds.y=yy*30+50; bounds.w=(Math.random()*25+5); bounds.h=(Math.random()*25+5);
+ }
+ loops++;
+ if(loops >= 1)
+ {
+ dirty_frame = true;
+ setTimeout(do_some_then_yield, 250);
+ return;
+ }
+ }
+ //clearInterval(draw_timer);
+ //canv_del_x = canv_del_y = -2;
+ };
+ do_some_then_yield();
+}
+//canv_del_x = canv_del_y = -2;
+draw_timer = setInterval(function(){ if(!dirty_frame) return; if(zoom > 2 || zoom < 0.4) zdel = 1.0 / zdel; if(canv_off_x > 220 || canv_off_x < 10) canv_del_x*=-1; if(canv_off_y > 160 || canv_off_y < 10) canv_del_y*=-1; zoom *= zdel; canv_off_x += (canv_del_x/zoom); canv_off_y += (canv_del_y/zoom); draw();}, 33); // Yield to browser temporarily to suppress "script is taking too damn long!" alert
+
+</script>
+</body>
+</html>
197 examples/test.html
@@ -0,0 +1,197 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Slowdowns.. bleh</title>
+</head>
+<body>
+ <canvas style="margin-top: 100px;" id="game" width="650px" height="475px">
+ </canvas>
+ <script type="text/javascript" src="../src/rtree.js"></script>
+ <script type="text/javascript">
+CanvasWrapper=function(canvasid,width,height){
+
+ var canv=null,
+ canvctx=null,
+ rt=new RTree(),
+ layers={'main':0},
+ mouse={track:false,x:0,y:0},
+ old_results = []; // Holds old mousing elements (for _mouseMove)
+
+ canv=document.getElementById(canvasid);
+ canv["x"] = 0; canv["y"] = 0;
+ canv["w"] = canv.width; canv["h"] = canv.height;
+
+ canv.addEvent=function(type,func){
+ if(window.addEventListener)
+ window.addEventListener(type,func,false);
+ else if(window.attachEvent)
+ window.attachEvent(type,func);
+ };
+
+ canv.addEvent('mousedown',__mouseDown);
+ canv.addEvent('mouseup',__mouseDown);
+ canv.addEvent('click',__mouseDown);
+ canv.addEvent('dblclick',__mouseDown);
+
+ if(canv.getContext)
+ canvctx=canv.getContext('2d');
+
+ // This needs to be created into a public function for AddObject, not events
+ this.insertIndex=function(bounds,id,action,func,layer)
+ {
+ if(!func) return;
+ if(!layer) layer='main';
+
+ // Get all overlapping objects from the tree
+ var local_objs = treeSearch(bounds);
+ var new_obj = true;
+
+ // Look for an existing object with our same ID
+ while(local_objs.length > 0)
+ {
+ obj = local_objs.pop();
+ if(obj.id == id)
+ {
+ new_obj = false;
+ break;
+ }
+ }
+ // If no object was found, make a new one...
+ if(new_obj) obj = {"func":{}, "action":{}, "bounds":{}, "id":id};
+
+ // If no events have been attached to the canvas, attach them..
+ if((action=='mouseover' || action=='mouseout' || action=='mousemove') && !mouse.track)
+ {
+ mouse.track=true;
+ canv.addEvent('mousemove',__mouseMove);
+ }
+
+ // Update our obj's properties
+ obj.func[action] = func;
+ obj.bounds[action] = bounds;
+ obj.action[action] = true;
+ obj.layer = layers[layer];
+ if(new_obj) rt.insert(bounds,obj);
+ }
+
+ function treeSearch(rect)
+ {
+ var results=rt.search(rect);
+ if(results.length==0)
+ return [];
+ results.sort(sortRes);
+ return results;
+ }
+
+ function sortRes(a,b){ return b.layer-a.layer; }
+
+ function __mouseDown(e){
+ var xy=getXY(e),
+ results=treeSearch(xy);
+ for(var i=0;i<results.length;i++)
+ if(results[i].action[e.type])
+ results[i].func[e.type].apply(results[i], [xy.x,xy.y]);
+ }
+
+ // SET_NOT returns an array containing all elements in A that are NOT IN B
+ function SET_NOT(A, B) {
+ var a_len = A.length, b_len = B.length;
+ var ret_array = [], a_found_in_b = false;
+ for(var ai = 0; ai < a_len; ai++) {
+ for(var bi = 0; bi < b_len; bi++) {
+ if(A[ai] === B[bi])
+ a_found_in_b = true;
+ }
+ if(!a_found_in_b)
+ ret_array.push(A[ai]);
+ a_found_in_b = false;
+ }
+ return(ret_array);
+ }
+
+ function __mouseMove(e) {
+ var xy=getXY(e);
+
+ // everything in l_results is a mouseMOVE
+ var l_results=RTree.Rectangle.overlap_rectangle(xy, canv)?treeSearch(xy):[];
+
+ // whatever is in l_results but NOT in old_results is a mouseOVER
+ var l_mouse_ins = SET_NOT(l_results, old_results);
+
+ // whatever is in old_results but NOT in l_results is a mouseOUT
+ var l_mouse_outs = SET_NOT(old_results, l_results);
+
+ while(l_mouse_outs.length>0) {
+ var thrown=l_mouse_outs.pop();
+ if(thrown.action['mouseout'])
+ thrown.func['mouseout'].apply(thrown, [thrown.bounds['mouseout'].x,thrown.bounds['mouseout'].y]);
+ }
+ while(l_mouse_ins.length>0) {
+ var thrown=l_mouse_ins.pop();
+ if(thrown.action['mouseover'])
+ thrown.func['mouseover'].apply(thrown, [thrown.bounds['mouseover'].x,thrown.bounds['mouseover'].y]);
+ }
+ old_results = l_results.splice(0, l_results.length);
+ while(l_results.length>0) {
+ var thrown=results.pop();
+ if(thrown.action['mousemove'])
+ thrown.func['mousemove'].apply(thrown, [thrown.bounds['mousemove'].x,thrown.bounds['mousemove'].y]);
+ }
+ }
+
+ function getXY(e) {
+ var posx = 0;
+ var posy = 0;
+ if (!e) var e = window.event;
+ if (e.pageX || e.pageY) {
+ posx = e.pageX;
+ posy = e.pageY;
+ }
+ else if (e.clientX || e.clientY) {
+ posx = e.clientX + document.body.scrollLeft
+ + document.documentElement.scrollLeft;
+ posy = e.clientY + document.body.scrollTop
+ + document.documentElement.scrollTop;
+ }
+ posx=posx-canv.offsetLeft;
+ posy=posy-canv.offsetTop;
+ return {x:posx,y:posy, w:1, h:1};
+ }
+}
+
+
+var ctx=document.getElementById('game').getContext('2d');
+
+var test=new CanvasWrapper("game",650,475);
+
+var cols=['red','blue','green','orange','yellow','silver'];
+var x=0,y=0,w=10,h=10;
+for(var i=0;i<8000;i++)
+{
+ x=rnd(5,600);
+ y=rnd(5,450);
+ test.insertIndex({x:x,y:y,w:w,h:h},"box"+i,'mouseover',highlight);
+ test.insertIndex({x:x,y:y,w:w,h:h},"box"+i,'mouseout',function(b,c){setTimeout(function(){ctx.fillStyle="grey";ctx.fillRect(b,c,w,h);},500)});
+ ctx.fillStyle="grey";
+ ctx.fillRect(x,y,w,h);
+}
+var m=0;
+function highlight(x,y)
+{
+ ctx.fillStyle=cols[m++>4?m=0:m];
+ ctx.fillRect(x,y,w,h);
+}
+/*
+w=100;
+h=100;
+
+ctx.fillStyle="white";
+ctx.fillRect(100,100,100,100);
+test.insertIndex({x:100,y:100,w:100,h:100},'id','mouseout',function(){setTimeout(function(){ctx.fillStyle="white";ctx.fillRect(100,100,100,100);},60)});
+test.insertIndex({x:100,y:100,w:100,h:100},'id','mouseover',function(){highlight(100,100);});
+*/
+
+function rnd(min,max){ return Math.floor(Math.random()*max+min); }
+ </script>
+</body>
+</html>
224 jsspec/JSSpec.css
@@ -0,0 +1,224 @@
+@CHARSET "UTF-8";
+
+/* --------------------
+ * @Layout
+ */
+
+html {
+ overflow: hidden;
+}
+
+body, #jsspec_container {
+ overflow: hidden;
+ padding: 0;
+ margin: 0;
+ width: 100%;
+ height: 100%;
+ background-color: white;
+}
+
+#title {
+ padding: 0;
+ margin: 0;
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 40px;
+ overflow: hidden;
+}
+
+#list {
+ padding: 0;
+ margin: 0;
+ position: absolute;
+ top: 40px;
+ left: 0px;
+ bottom: 0px;
+ overflow: auto;
+ width: 250px;
+ _height:expression(document.body.clientHeight-40);
+}
+
+#log {
+ padding: 0;
+ margin: 0;
+ position: absolute;
+ top: 40px;
+ left: 250px;
+ right: 0px;
+ bottom: 0px;
+ overflow: auto;
+ _height:expression(document.body.clientHeight-40);
+ _width:expression(document.body.clientWidth-250);
+}
+
+
+
+/* --------------------
+ * @Decorations and colors
+ */
+* {
+ padding: 0;
+ margin: 0;
+ font-family: "Lucida Grande", Helvetica, sans-serif;
+}
+
+li {
+ list-style: none;
+}
+
+/* hiding subtitles */
+h2 {
+ display: none;
+}
+
+/* title section */
+div#title {
+ padding: 0em 0.5em;
+}
+
+div#title h1 {
+ font-size: 1.5em;
+ float: left;
+}
+
+div#title ul li {
+ float: left;
+ padding: 0.5em 0em 0.5em 0.75em;
+}
+
+div#title p {
+ float:right;
+ margin-right:1em;
+ font-size: 0.75em;
+}
+
+/* spec container */
+ul.specs {
+ margin: 0.5em;
+}
+ul.specs li {
+ margin-bottom: 0.1em;
+}
+
+/* spec title */
+ul.specs li h3 {
+ font-weight: bold;
+ font-size: 0.75em;
+ padding: 0.2em 1em;
+ cursor: pointer;
+ _cursor: hand;
+}
+
+/* example container */
+ul.examples li {
+ border-style: solid;
+ border-width: 0px 0px 1px 5px;
+ margin: 0.2em 0em 0.2em 1em;
+}
+
+/* example title */
+ul.examples li h4 {
+ font-weight: normal;
+ font-size: 0.75em;
+ margin-left: 1em;
+}
+
+pre.examples-code {
+ margin: 0.5em 2em;
+ padding: 0.5em;
+ background: white;
+ border: solid 1px #CCC;
+}
+
+/* example explaination */
+ul.examples li div {
+ padding: 1em 2em;
+ font-size: 0.75em;
+}
+
+/* styles for ongoing, success, failure, error */
+div.success, div.success a {
+ color: #FFFFFF;
+ background-color: #65C400;
+}
+
+ul.specs li.success h3, ul.specs li.success h3 a {
+ color: #FFFFFF;
+ background-color: #65C400;
+}
+
+ul.examples li.success, ul.examples li.success a {
+ color: #3D7700;
+ background-color: #DBFFB4;
+ border-color: #65C400;
+}
+
+div.exception, div.exception a {
+ color: #FFFFFF;
+ background-color: #C20000;
+}
+
+ul.specs li.exception h3, ul.specs li.exception h3 a {
+ color: #FFFFFF;
+ background-color: #C20000;
+}
+
+ul.examples li.exception, ul.examples li.exception a {
+ color: #C20000;
+ background-color: #FFFBD3;
+ border-color: #C20000;
+}
+
+div.ongoing, div.ongoing a {
+ color: #000000;
+ background-color: #FFFF80;
+}
+
+ul.specs li.ongoing h3, ul.specs li.ongoing h3 a {
+ color: #000000;
+ background-color: #FFFF80;
+}
+
+ul.examples li.ongoing, ul.examples li.ongoing a {
+ color: #000000;
+ background-color: #FFFF80;
+ border-color: #DDDD00;
+}
+
+
+
+/* --------------------
+ * values
+ */
+.number_value, .string_value, .regexp_value, .boolean_value, .dom_value {
+ font-family: monospace;
+ color: blue;
+}
+.object_value, .array_value {
+ line-height: 2em;
+ padding: 0.1em 0.2em;
+ margin: 0.1em 0;
+}
+.date_value {
+ font-family: monospace;
+ color: olive;
+}
+.undefined_value, .null_value {
+ font-style: italic;
+ color: blue;
+}
+.dom_attr_name {
+}
+.dom_attr_value {
+ color: red;
+}
+.dom_path {
+ font-size: 0.75em;
+ color: gray;
+}
+strong {
+ font-weight: normal;
+ background-color: #FFC6C6;
+}
1,548 jsspec/JSSpec.js
1,548 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
1 jsspec/diff_match_patch.js
@@ -0,0 +1 @@
+function diff_match_patch(){this.Diff_Timeout=1.0;this.Diff_EditCost=4;this.Diff_DualThreshold=32;this.Match_Balance=0.5;this.Match_Threshold=0.5;this.Match_MinLength=100;this.Match_MaxLength=1000;this.Patch_Margin=4;function getMaxBits(){var maxbits=0;var oldi=1;var newi=2;while(oldi!=newi){maxbits++;oldi=newi;newi=newi<<1}return maxbits}this.Match_MaxBits=getMaxBits()}var DIFF_DELETE=-1;var DIFF_INSERT=1;var DIFF_EQUAL=0;diff_match_patch.prototype.diff_main=function(text1,text2,opt_checklines){if(text1==text2){return[[DIFF_EQUAL,text1]]}if(typeof opt_checklines=='undefined'){opt_checklines=true}var checklines=opt_checklines;var commonlength=this.diff_commonPrefix(text1,text2);var commonprefix=text1.substring(0,commonlength);text1=text1.substring(commonlength);text2=text2.substring(commonlength);commonlength=this.diff_commonSuffix(text1,text2);var commonsuffix=text1.substring(text1.length-commonlength);text1=text1.substring(0,text1.length-commonlength);text2=text2.substring(0,text2.length-commonlength);var diffs=this.diff_compute(text1,text2,checklines);if(commonprefix){diffs.unshift([DIFF_EQUAL,commonprefix])}if(commonsuffix){diffs.push([DIFF_EQUAL,commonsuffix])}this.diff_cleanupMerge(diffs);return diffs};diff_match_patch.prototype.diff_compute=function(text1,text2,checklines){var diffs;if(!text1){return[[DIFF_INSERT,text2]]}if(!text2){return[[DIFF_DELETE,text1]]}var longtext=text1.length>text2.length?text1:text2;var shorttext=text1.length>text2.length?text2:text1;var i=longtext.indexOf(shorttext);if(i!=-1){diffs=[[DIFF_INSERT,longtext.substring(0,i)],[DIFF_EQUAL,shorttext],[DIFF_INSERT,longtext.substring(i+shorttext.length)]];if(text1.length>text2.length){diffs[0][0]=diffs[2][0]=DIFF_DELETE}return diffs}longtext=shorttext=null;var hm=this.diff_halfMatch(text1,text2);if(hm){var text1_a=hm[0];var text1_b=hm[1];var text2_a=hm[2];var text2_b=hm[3];var mid_common=hm[4];var diffs_a=this.diff_main(text1_a,text2_a,checklines);var diffs_b=this.diff_main(text1_b,text2_b,checklines);return diffs_a.concat([[DIFF_EQUAL,mid_common]],diffs_b)}if(checklines&&text1.length+text2.length<250){checklines=false}var linearray;if(checklines){var a=this.diff_linesToChars(text1,text2);text1=a[0];text2=a[1];linearray=a[2]}diffs=this.diff_map(text1,text2);if(!diffs){diffs=[[DIFF_DELETE,text1],[DIFF_INSERT,text2]]}if(checklines){this.diff_charsToLines(diffs,linearray);this.diff_cleanupSemantic(diffs);diffs.push([DIFF_EQUAL,'']);var pointer=0;var count_delete=0;var count_insert=0;var text_delete='';var text_insert='';while(pointer<diffs.length){if(diffs[pointer][0]==DIFF_INSERT){count_insert++;text_insert+=diffs[pointer][1]}else if(diffs[pointer][0]==DIFF_DELETE){count_delete++;text_delete+=diffs[pointer][1]}else{if(count_delete>=1&&count_insert>=1){var a=this.diff_main(text_delete,text_insert,false);diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert);pointer=pointer-count_delete-count_insert;for(var j=a.length-1;j>=0;j--){diffs.splice(pointer,0,a[j])}pointer=pointer+a.length}count_insert=0;count_delete=0;text_delete='';text_insert=''}pointer++}diffs.pop()}return diffs};diff_match_patch.prototype.diff_linesToChars=function(text1,text2){var linearray=[];var linehash={};linearray.push('');function diff_linesToCharsMunge(text){var chars='';while(text){var i=text.indexOf('\n');if(i==-1){i=text.length}var line=text.substring(0,i+1);text=text.substring(i+1);if(linehash.hasOwnProperty?linehash.hasOwnProperty(line):(linehash[line]!==undefined)){chars+=String.fromCharCode(linehash[line])}else{linearray.push(line);linehash[line]=linearray.length-1;chars+=String.fromCharCode(linearray.length-1)}}return chars}var chars1=diff_linesToCharsMunge(text1);var chars2=diff_linesToCharsMunge(text2);return[chars1,chars2,linearray]};diff_match_patch.prototype.diff_charsToLines=function(diffs,linearray){for(var x=0;x<diffs.length;x++){var chars=diffs[x][1];var text=[];for(var y=0;y<chars.length;y++){text.push(linearray[chars.charCodeAt(y)])}diffs[x][1]=text.join('')}};diff_match_patch.prototype.diff_map=function(text1,text2){var ms_end=(new Date()).getTime()+this.Diff_Timeout*1000;var max_d=text1.length+text2.length-1;var doubleEnd=this.Diff_DualThreshold*2<max_d;var v_map1=[];var v_map2=[];var v1={};var v2={};v1[1]=0;v2[1]=0;var x,y;var footstep;var footsteps={};var done=false;var hasOwnProperty=!!(footsteps.hasOwnProperty);var front=(text1.length+text2.length)%2;for(var d=0;d<max_d;d++){if(this.Diff_Timeout>0&&(new Date()).getTime()>ms_end){return null}v_map1[d]={};for(var k=-d;k<=d;k+=2){if(k==-d||k!=d&&v1[k-1]<v1[k+1]){x=v1[k+1]}else{x=v1[k-1]+1}y=x-k;if(doubleEnd){footstep=x+','+y;if(front&&(hasOwnProperty?footsteps.hasOwnProperty(footstep):(footsteps[footstep]!==undefined))){done=true}if(!front){footsteps[footstep]=d}}while(!done&&x<text1.length&&y<text2.length&&text1.charAt(x)==text2.charAt(y)){x++;y++;if(doubleEnd){footstep=x+','+y;if(front&&(hasOwnProperty?footsteps.hasOwnProperty(footstep):(footsteps[footstep]!==undefined))){done=true}if(!front){footsteps[footstep]=d}}}v1[k]=x;v_map1[d][x+','+y]=true;if(x==text1.length&&y==text2.length){return this.diff_path1(v_map1,text1,text2)}else if(done){v_map2=v_map2.slice(0,footsteps[footstep]+1);var a=this.diff_path1(v_map1,text1.substring(0,x),text2.substring(0,y));return a.concat(this.diff_path2(v_map2,text1.substring(x),text2.substring(y)))}}if(doubleEnd){v_map2[d]={};for(var k=-d;k<=d;k+=2){if(k==-d||k!=d&&v2[k-1]<v2[k+1]){x=v2[k+1]}else{x=v2[k-1]+1}y=x-k;footstep=(text1.length-x)+','+(text2.length-y);if(!front&&(hasOwnProperty?footsteps.hasOwnProperty(footstep):(footsteps[footstep]!==undefined))){done=true}if(front){footsteps[footstep]=d}while(!done&&x<text1.length&&y<text2.length&&text1.charAt(text1.length-x-1)==text2.charAt(text2.length-y-1)){x++;y++;footstep=(text1.length-x)+','+(text2.length-y);if(!front&&(hasOwnProperty?footsteps.hasOwnProperty(footstep):(footsteps[footstep]!==undefined))){done=true}if(front){footsteps[footstep]=d}}v2[k]=x;v_map2[d][x+','+y]=true;if(done){v_map1=v_map1.slice(0,footsteps[footstep]+1);var a=this.diff_path1(v_map1,text1.substring(0,text1.length-x),text2.substring(0,text2.length-y));return a.concat(this.diff_path2(v_map2,text1.substring(text1.length-x),text2.substring(text2.length-y)))}}}}return null};diff_match_patch.prototype.diff_path1=function(v_map,text1,text2){var path=[];var x=text1.length;var y=text2.length;var last_op=null;for(var d=v_map.length-2;d>=0;d--){while(1){if(v_map[d].hasOwnProperty?v_map[d].hasOwnProperty((x-1)+','+y):(v_map[d][(x-1)+','+y]!==undefined)){x--;if(last_op===DIFF_DELETE){path[0][1]=text1.charAt(x)+path[0][1]}else{path.unshift([DIFF_DELETE,text1.charAt(x)])}last_op=DIFF_DELETE;break}else if(v_map[d].hasOwnProperty?v_map[d].hasOwnProperty(x+','+(y-1)):(v_map[d][x+','+(y-1)]!==undefined)){y--;if(last_op===DIFF_INSERT){path[0][1]=text2.charAt(y)+path[0][1]}else{path.unshift([DIFF_INSERT,text2.charAt(y)])}last_op=DIFF_INSERT;break}else{x--;y--;if(last_op===DIFF_EQUAL){path[0][1]=text1.charAt(x)+path[0][1]}else{path.unshift([DIFF_EQUAL,text1.charAt(x)])}last_op=DIFF_EQUAL}}}return path};diff_match_patch.prototype.diff_path2=function(v_map,text1,text2){var path=[];var x=text1.length;var y=text2.length;var last_op=null;for(var d=v_map.length-2;d>=0;d--){while(1){if(v_map[d].hasOwnProperty?v_map[d].hasOwnProperty((x-1)+','+y):(v_map[d][(x-1)+','+y]!==undefined)){x--;if(last_op===DIFF_DELETE){path[path.length-1][1]+=text1.charAt(text1.length-x-1)}else{path.push([DIFF_DELETE,text1.charAt(text1.length-x-1)])}last_op=DIFF_DELETE;break}else if(v_map[d].hasOwnProperty?v_map[d].hasOwnProperty(x+','+(y-1)):(v_map[d][x+','+(y-1)]!==undefined)){y--;if(last_op===DIFF_INSERT){path[path.length-1][1]+=text2.charAt(text2.length-y-1)}else{path.push([DIFF_INSERT,text2.charAt(text2.length-y-1)])}last_op=DIFF_INSERT;break}else{x--;y--;if(last_op===DIFF_EQUAL){path[path.length-1][1]+=text1.charAt(text1.length-x-1)}else{path.push([DIFF_EQUAL,text1.charAt(text1.length-x-1)])}last_op=DIFF_EQUAL}}}return path};diff_match_patch.prototype.diff_commonPrefix=function(text1,text2){if(!text1||!text2||text1.charCodeAt(0)!==text2.charCodeAt(0)){return 0}var pointermin=0;var pointermax=Math.min(text1.length,text2.length);var pointermid=pointermax;var pointerstart=0;while(pointermin<pointermid){if(text1.substring(pointerstart,pointermid)==text2.substring(pointerstart,pointermid)){pointermin=pointermid;pointerstart=pointermin}else{pointermax=pointermid}pointermid=Math.floor((pointermax-pointermin)/2+pointermin)}return pointermid};diff_match_patch.prototype.diff_commonSuffix=function(text1,text2){if(!text1||!text2||text1.charCodeAt(text1.length-1)!==text2.charCodeAt(text2.length-1)){return 0}var pointermin=0;var pointermax=Math.min(text1.length,text2.length);var pointermid=pointermax;var pointerend=0;while(pointermin<pointermid){if(text1.substring(text1.length-pointermid,text1.length-pointerend)==text2.substring(text2.length-pointermid,text2.length-pointerend)){pointermin=pointermid;pointerend=pointermin}else{pointermax=pointermid}pointermid=Math.floor((pointermax-pointermin)/2+pointermin)}return pointermid};diff_match_patch.prototype.diff_halfMatch=function(text1,text2){var longtext=text1.length>text2.length?text1:text2;var shorttext=text1.length>text2.length?text2:text1;if(longtext.length<10||shorttext.length<1){return null}var dmp=this;function diff_halfMatchI(longtext,shorttext,i){var seed=longtext.substring(i,i+Math.floor(longtext.length/4));var j=-1;var best_common='';var best_longtext_a,best_longtext_b,best_shorttext_a,best_shorttext_b;while((j=shorttext.indexOf(seed,j+1))!=-1){var prefixLength=dmp.diff_commonPrefix(longtext.substring(i),shorttext.substring(j));var suffixLength=dmp.diff_commonSuffix(longtext.substring(0,i),shorttext.substring(0,j));if(best_common.length<suffixLength+prefixLength){best_common=shorttext.substring(j-suffixLength,j)+shorttext.substring(j,j+prefixLength);best_longtext_a=longtext.substring(0,i-suffixLength);best_longtext_b=longtext.substring(i+prefixLength);best_shorttext_a=shorttext.substring(0,j-suffixLength);best_shorttext_b=shorttext.substring(j+prefixLength)}}if(best_common.length>=longtext.length/2){return[best_longtext_a,best_longtext_b,best_shorttext_a,best_shorttext_b,best_common]}else{return null}}var hm1=diff_halfMatchI(longtext,shorttext,Math.ceil(longtext.length/4));var hm2=diff_halfMatchI(longtext,shorttext,Math.ceil(longtext.length/2));var hm;if(!hm1&&!hm2){return null}else if(!hm2){hm=hm1}else if(!hm1){hm=hm2}else{hm=hm1[4].length>hm2[4].length?hm1:hm2}var text1_a,text1_b,text2_a,text2_b;if(text1.length>text2.length){text1_a=hm[0];text1_b=hm[1];text2_a=hm[2];text2_b=hm[3]}else{text2_a=hm[0];text2_b=hm[1];text1_a=hm[2];text1_b=hm[3]}var mid_common=hm[4];return[text1_a,text1_b,text2_a,text2_b,mid_common]};diff_match_patch.prototype.diff_cleanupSemantic=function(diffs){var changes=false;var equalities=[];var lastequality=null;var pointer=0;var length_changes1=0;var length_changes2=0;while(pointer<diffs.length){if(diffs[pointer][0]==DIFF_EQUAL){equalities.push(pointer);length_changes1=length_changes2;length_changes2=0;lastequality=diffs[pointer][1]}else{length_changes2+=diffs[pointer][1].length;if(lastequality!==null&&(lastequality.length<=length_changes1)&&(lastequality.length<=length_changes2)){diffs.splice(equalities[equalities.length-1],0,[DIFF_DELETE,lastequality]);diffs[equalities[equalities.length-1]+1][0]=DIFF_INSERT;equalities.pop();equalities.pop();pointer=equalities.length?equalities[equalities.length-1]:-1;length_changes1=0;length_changes2=0;lastequality=null;changes=true}}pointer++}if(changes){this.diff_cleanupMerge(diffs)}this.diff_cleanupSemanticLossless(diffs)};diff_match_patch.prototype.diff_cleanupSemanticLossless=function(diffs){function diff_cleanupSemanticScore(one,two,three){var whitespace=/\s/;var score=0;if(one.charAt(one.length-1).match(whitespace)||two.charAt(0).match(whitespace)){score++}if(two.charAt(two.length-1).match(whitespace)||three.charAt(0).match(whitespace)){score++}return score}var pointer=1;while(pointer<diffs.length-1){if(diffs[pointer-1][0]==DIFF_EQUAL&&diffs[pointer+1][0]==DIFF_EQUAL){var equality1=diffs[pointer-1][1];var edit=diffs[pointer][1];var equality2=diffs[pointer+1][1];var commonOffset=this.diff_commonSuffix(equality1,edit);if(commonOffset){var commonString=edit.substring(edit.length-commonOffset);equality1=equality1.substring(0,equality1.length-commonOffset);edit=commonString+edit.substring(0,edit.length-commonOffset);equality2=commonString+equality2}var bestEquality1=equality1;var bestEdit=edit;var bestEquality2=equality2;var bestScore=diff_cleanupSemanticScore(equality1,edit,equality2);while(edit.charAt(0)===equality2.charAt(0)){equality1+=edit.charAt(0);edit=edit.substring(1)+equality2.charAt(0);equality2=equality2.substring(1);var score=diff_cleanupSemanticScore(equality1,edit,equality2);if(score>=bestScore){bestScore=score;bestEquality1=equality1;bestEdit=edit;bestEquality2=equality2}}if(diffs[pointer-1][1]!=bestEquality1){diffs[pointer-1][1]=bestEquality1;diffs[pointer][1]=bestEdit;diffs[pointer+1][1]=bestEquality2}}pointer++}};diff_match_patch.prototype.diff_cleanupEfficiency=function(diffs){var changes=false;var equalities=[];var lastequality='';var pointer=0;var pre_ins=false;var pre_del=false;var post_ins=false;var post_del=false;while(pointer<diffs.length){if(diffs[pointer][0]==DIFF_EQUAL){if(diffs[pointer][1].length<this.Diff_EditCost&&(post_ins||post_del)){equalities.push(pointer);pre_ins=post_ins;pre_del=post_del;lastequality=diffs[pointer][1]}else{equalities=[];lastequality=''}post_ins=post_del=false}else{if(diffs[pointer][0]==DIFF_DELETE){post_del=true}else{post_ins=true}if(lastequality&&((pre_ins&&pre_del&&post_ins&&post_del)||((lastequality.length<this.Diff_EditCost/2)&&(pre_ins+pre_del+post_ins+post_del)==3))){diffs.splice(equalities[equalities.length-1],0,[DIFF_DELETE,lastequality]);diffs[equalities[equalities.length-1]+1][0]=DIFF_INSERT;equalities.pop();lastequality='';if(pre_ins&&pre_del){post_ins=post_del=true;equalities=[]}else{equalities.pop();pointer=equalities.length?equalities[equalities.length-1]:-1;post_ins=post_del=false}changes=true}}pointer++}if(changes){this.diff_cleanupMerge(diffs)}};diff_match_patch.prototype.diff_cleanupMerge=function(diffs){diffs.push([DIFF_EQUAL,'']);var pointer=0;var count_delete=0;var count_insert=0;var text_delete='';var text_insert='';var commonlength;while(pointer<diffs.length){if(diffs[pointer][0]==DIFF_INSERT){count_insert++;text_insert+=diffs[pointer][1];pointer++}else if(diffs[pointer][0]==DIFF_DELETE){count_delete++;text_delete+=diffs[pointer][1];pointer++}else{if(count_delete!==0||count_insert!==0){if(count_delete!==0&&count_insert!==0){commonlength=this.diff_commonPrefix(text_insert,text_delete);if(commonlength!==0){if((pointer-count_delete-count_insert)>0&&diffs[pointer-count_delete-count_insert-1][0]==DIFF_EQUAL){diffs[pointer-count_delete-count_insert-1][1]+=text_insert.substring(0,commonlength)}else{diffs.splice(0,0,[DIFF_EQUAL,text_insert.substring(0,commonlength)]);pointer++}text_insert=text_insert.substring(commonlength);text_delete=text_delete.substring(commonlength)}commonlength=this.diff_commonSuffix(text_insert,text_delete);if(commonlength!==0){diffs[pointer][1]=text_insert.substring(text_insert.length-commonlength)+diffs[pointer][1];text_insert=text_insert.substring(0,text_insert.length-commonlength);text_delete=text_delete.substring(0,text_delete.length-commonlength)}}if(count_delete===0){diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert,[DIFF_INSERT,text_insert])}else if(count_insert===0){diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert,[DIFF_DELETE,text_delete])}else{diffs.splice(pointer-count_delete-count_insert,count_delete+count_insert,[DIFF_DELETE,text_delete],[DIFF_INSERT,text_insert])}pointer=pointer-count_delete-count_insert+(count_delete?1:0)+(count_insert?1:0)+1}else if(pointer!==0&&diffs[pointer-1][0]==DIFF_EQUAL){diffs[pointer-1][1]+=diffs[pointer][1];diffs.splice(pointer,1)}else{pointer++}count_insert=0;count_delete=0;text_delete='';text_insert=''}}if(diffs[diffs.length-1][1]===''){diffs.pop()}var changes=false;pointer=1;while(pointer<diffs.length-1){if(diffs[pointer-1][0]==DIFF_EQUAL&&diffs[pointer+1][0]==DIFF_EQUAL){if(diffs[pointer][1].substring(diffs[pointer][1].length-diffs[pointer-1][1].length)==diffs[pointer-1][1]){diffs[pointer][1]=diffs[pointer-1][1]+diffs[pointer][1].substring(0,diffs[pointer][1].length-diffs[pointer-1][1].length);diffs[pointer+1][1]=diffs[pointer-1][1]+diffs[pointer+1][1];diffs.splice(pointer-1,1);changes=true}else if(diffs[pointer][1].substring(0,diffs[pointer+1][1].length)==diffs[pointer+1][1]){diffs[pointer-1][1]+=diffs[pointer+1][1];diffs[pointer][1]=diffs[pointer][1].substring(diffs[pointer+1][1].length)+diffs[pointer+1][1];diffs.splice(pointer+1,1);changes=true}}pointer++}if(changes){this.diff_cleanupMerge(diffs)}};diff_match_patch.prototype.diff_addIndex=function(diffs){var i=0;for(var x=0;x<diffs.length;x++){diffs[x].push(i);if(diffs[x][0]!==DIFF_DELETE){i+=diffs[x][1].length}}};diff_match_patch.prototype.diff_xIndex=function(diffs,loc){var chars1=0;var chars2=0;var last_chars1=0;var last_chars2=0;var x;for(x=0;x<diffs.length;x++){if(diffs[x][0]!==DIFF_INSERT){chars1+=diffs[x][1].length}if(diffs[x][0]!==DIFF_DELETE){chars2+=diffs[x][1].length}if(chars1>loc){break}last_chars1=chars1;last_chars2=chars2}if(diffs.length!=x&&diffs[x][0]===DIFF_DELETE){return last_chars2}return last_chars2+(loc-last_chars1)};diff_match_patch.prototype.diff_prettyHtml=function(diffs){this.diff_addIndex(diffs);var html=[];for(var x=0;x<diffs.length;x++){var m=diffs[x][0];var t=diffs[x][1];var i=diffs[x][2];t=t.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');t=t.replace(/\n/g,'&para;<BR>');if(m===DIFF_DELETE){html.push('<DEL STYLE="background:#FFE6E6;" TITLE="i=',i,'">',t,'</DEL>')}else if(m===DIFF_INSERT){html.push('<INS STYLE="background:#E6FFE6;" TITLE="i=',i,'">',t,'</INS>')}else{html.push('<SPAN TITLE="i=',i,'">',t,'</SPAN>')}}return html.join('')};diff_match_patch.prototype.diff_text1=function(diffs){var txt=[];for(var x=0;x<diffs.length;x++){if(diffs[x][0]!==DIFF_INSERT){txt.push(diffs[x][1])}}return txt.join('')};diff_match_patch.prototype.diff_text2=function(diffs){var txt=[];for(var x=0;x<diffs.length;x++){if(diffs[x][0]!==DIFF_DELETE){txt.push(diffs[x][1])}}return txt.join('')};diff_match_patch.prototype.diff_toDelta=function(diffs){var txt=[];for(var x=0;x<diffs.length;x++){switch(diffs[x][0]){case DIFF_DELETE:txt.push('-',diffs[x][1].length,'\t');break;case DIFF_EQUAL:txt.push('=',diffs[x][1].length,'\t');break;case DIFF_INSERT:txt.push('+',encodeURI(diffs[x][1]),'\t');break;default:alert('Invalid diff operation in diff_toDelta()')}}return txt.join('').replace(/%20/g,' ')};diff_match_patch.prototype.diff_fromDelta=function(text1,delta){var diffs=[];var pointer=0;var tokens=delta.split(/\t/g);for(var x=0;x<tokens.length;x++){var param=tokens[x].substring(1);switch(tokens[x].charAt(0)){case'-':case'=':var n=parseInt(param,10);if(isNaN(n)||n<0){alert('Invalid number in diff_fromDelta()')}else{var text=text1.substring(pointer,pointer+=n);if(tokens[x].charAt(0)=='='){diffs.push([DIFF_EQUAL,text])}else{diffs.push([DIFF_DELETE,text])}}break;case'+':diffs.push([DIFF_INSERT,decodeURI(param)]);break;default:if(tokens[x]){alert('Invalid diff operation in diff_fromDelta()')}}}if(pointer!=text1.length){alert('Text length mismatch in diff_fromDelta()')}return diffs};diff_match_patch.prototype.match_main=function(text,pattern,loc){loc=Math.max(0,Math.min(loc,text.length-pattern.length));if(text==pattern){return 0}else if(text.length===0){return null}else if(text.substring(loc,loc+pattern.length)==pattern){return loc}else{return this.match_bitap(text,pattern,loc)}};diff_match_patch.prototype.match_bitap=function(text,pattern,loc){if(pattern.length>this.Match_MaxBits){return alert('Pattern too long for this browser.')}var s=this.match_alphabet(pattern);var score_text_length=text.length;score_text_length=Math.max(score_text_length,this.Match_MinLength);score_text_length=Math.min(score_text_length,this.Match_MaxLength);var dmp=this;function match_bitapScore(e,x){var d=Math.abs(loc-x);return(e/pattern.length/dmp.Match_Balance)+(d/score_text_length/(1.0-dmp.Match_Balance))}var score_threshold=this.Match_Threshold;var best_loc=text.indexOf(pattern,loc);if(best_loc!=-1){score_threshold=Math.min(match_bitapScore(0,best_loc),score_threshold)}best_loc=text.lastIndexOf(pattern,loc+pattern.length);if(best_loc!=-1){score_threshold=Math.min(match_bitapScore(0,best_loc),score_threshold)}var matchmask=1<<(pattern.length-1);best_loc=null;var bin_min,bin_mid;var bin_max=Math.max(loc+loc,text.length);var last_rd;for(var d=0;d<pattern.length;d++){var rd=Array(text.length);bin_min=loc;bin_mid=bin_max;while(bin_min<bin_mid){if(match_bitapScore(d,bin_mid)<score_threshold){bin_min=bin_mid}else{bin_max=bin_mid}bin_mid=Math.floor((bin_max-bin_min)/2+bin_min)}bin_max=bin_mid;var start=Math.max(0,loc-(bin_mid-loc)-1);var finish=Math.min(text.length-1,pattern.length+bin_mid);if(text.charAt(finish)==pattern.charAt(pattern.length-1)){rd[finish]=(1<<(d+1))-1}else{rd[finish]=(1<<d)-1}for(var j=finish-1;j>=start;j--){if(d===0){rd[j]=((rd[j+1]<<1)|1)&s[text.charAt(j)]}else{rd[j]=((rd[j+1]<<1)|1)&s[text.charAt(j)]|((last_rd[j+1]<<1)|1)|((last_rd[j]<<1)|1)|last_rd[j+1]}if(rd[j]&matchmask){var score=match_bitapScore(d,j);if(score<=score_threshold){score_threshold=score;best_loc=j;if(j>loc){start=Math.max(0,loc-(j-loc))}else{break}}}}if(match_bitapScore(d+1,loc)>score_threshold){break}last_rd=rd}return best_loc};diff_match_patch.prototype.match_alphabet=function(pattern){var s=Object();for(var i=0;i<pattern.length;i++){s[pattern.charAt(i)]=0}for(var i=0;i<pattern.length;i++){s[pattern.charAt(i)]|=1<<(pattern.length-i-1)}return s};diff_match_patch.prototype.patch_addContext=function(patch,text){var pattern=text.substring(patch.start2,patch.start2+patch.length1);var padding=0;while(text.indexOf(pattern)!=text.lastIndexOf(pattern)&&pattern.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin){padding+=this.Patch_Margin;pattern=text.substring(patch.start2-padding,patch.start2+patch.length1+padding)}padding+=this.Patch_Margin;var prefix=text.substring(patch.start2-padding,patch.start2);if(prefix!==''){patch.diffs.unshift([DIFF_EQUAL,prefix])}var suffix=text.substring(patch.start2+patch.length1,patch.start2+patch.length1+padding);if(suffix!==''){patch.diffs.push([DIFF_EQUAL,suffix])}patch.start1-=prefix.length;patch.start2-=prefix.length;patch.length1+=prefix.length+suffix.length;patch.length2+=prefix.length+suffix.length};diff_match_patch.prototype.patch_make=function(text1,text2,opt_diffs){var diffs;if(typeof opt_diffs!='undefined'){diffs=opt_diffs}else{diffs=this.diff_main(text1,text2,true);if(diffs.length>2){this.diff_cleanupSemantic(diffs);this.diff_cleanupEfficiency(diffs)}}if(diffs.length===0){return[]}var patches=[];var patch=new patch_obj();var char_count1=0;var char_count2=0;var prepatch_text=text1;var postpatch_text=text1;for(var x=0;x<diffs.length;x++){var diff_type=diffs[x][0];var diff_text=diffs[x][1];if(patch.diffs.length===0&&diff_type!==DIFF_EQUAL){patch.start1=char_count1;patch.start2=char_count2}if(diff_type===DIFF_INSERT){patch.diffs.push(diffs[x]);patch.length2+=diff_text.length;postpatch_text=postpatch_text.substring(0,char_count2)+diff_text+postpatch_text.substring(char_count2)}else if(diff_type===DIFF_DELETE){patch.length1+=diff_text.length;patch.diffs.push(diffs[x]);postpatch_text=postpatch_text.substring(0,char_count2)+postpatch_text.substring(char_count2+diff_text.length)}else if(diff_type===DIFF_EQUAL&&diff_text.length<=2*this.Patch_Margin&&patch.diffs.length!==0&&diffs.length!=x+1){patch.diffs.push(diffs[x]);patch.length1+=diff_text.length;patch.length2+=diff_text.length}if(diff_type===DIFF_EQUAL&&diff_text.length>=2*this.Patch_Margin){if(patch.diffs.length!==0){this.patch_addContext(patch,prepatch_text);patches.push(patch);patch=new patch_obj();prepatch_text=postpatch_text}}if(diff_type!==DIFF_INSERT){char_count1+=diff_text.length}if(diff_type!==DIFF_DELETE){char_count2+=diff_text.length}}if(patch.diffs.length!==0){this.patch_addContext(patch,prepatch_text);patches.push(patch)}return patches};diff_match_patch.prototype.patch_apply=function(patches,text){this.patch_splitMax(patches);var results=[];var delta=0;for(var x=0;x<patches.length;x++){var expected_loc=patches[x].start2+delta;var text1=this.diff_text1(patches[x].diffs);var start_loc=this.match_main(text,text1,expected_loc);if(start_loc===null){results.push(false)}else{results.push(true);delta=start_loc-expected_loc;var text2=text.substring(start_loc,start_loc+text1.length);if(text1==text2){text=text.substring(0,start_loc)+this.diff_text2(patches[x].diffs)+text.substring(start_loc+text1.length)}else{var diffs=this.diff_main(text1,text2,false);this.diff_cleanupSemanticLossless(diffs);var index1=0;var index2;for(var y=0;y<patches[x].diffs.length;y++){var mod=patches[x].diffs[y];if(mod[0]!==DIFF_EQUAL){index2=this.diff_xIndex(diffs,index1)}if(mod[0]===DIFF_INSERT){text=text.substring(0,start_loc+index2)+mod[1]+text.substring(start_loc+index2)}else if(mod[0]===DIFF_DELETE){text=text.substring(0,start_loc+index2)+text.substring(start_loc+this.diff_xIndex(diffs,index1+mod[1].length))}if(mod[0]!==DIFF_DELETE){index1+=mod[1].length}}}}}return[text,results]};diff_match_patch.prototype.patch_splitMax=function(patches){for(var x=0;x<patches.length;x++){if(patches[x].length1>this.Match_MaxBits){var bigpatch=patches[x];patches.splice(x,1);var patch_size=this.Match_MaxBits;var start1=bigpatch.start1;var start2=bigpatch.start2;var precontext='';while(bigpatch.diffs.length!==0){var patch=new patch_obj();var empty=true;patch.start1=start1-precontext.length;patch.start2=start2-precontext.length;if(precontext!==''){patch.length1=patch.length2=precontext.length;patch.diffs.push([DIFF_EQUAL,precontext])}while(bigpatch.diffs.length!==0&&patch.length1<patch_size-this.Patch_Margin){var diff_type=bigpatch.diffs[0][0];var diff_text=bigpatch.diffs[0][1];if(diff_type===DIFF_INSERT){patch.length2+=diff_text.length;start2+=diff_text.length;patch.diffs.push(bigpatch.diffs.shift());empty=false}else{diff_text=diff_text.substring(0,patch_size-patch.length1-this.Patch_Margin);patch.length1+=diff_text.length;start1+=diff_text.length;if(diff_type===DIFF_EQUAL){patch.length2+=diff_text.length;start2+=diff_text.length}else{empty=false}patch.diffs.push([diff_type,diff_text]);if(diff_text==bigpatch.diffs[0][1]){bigpatch.diffs.shift()}else{bigpatch.diffs[0][1]=bigpatch.diffs[0][1].substring(diff_text.length)}}}precontext=this.diff_text2(patch.diffs);precontext=precontext.substring(precontext.length-this.Patch_Margin);var postcontext=this.diff_text1(bigpatch.diffs).substring(0,this.Patch_Margin);if(postcontext!==''){patch.length1+=postcontext.length;patch.length2+=postcontext.length;if(patch.diffs.length!==0&&patch.diffs[patch.diffs.length-1][0]===DIFF_EQUAL){patch.diffs[patch.diffs.length-1][1]+=postcontext}else{patch.diffs.push([DIFF_EQUAL,postcontext])}}if(!empty){patches.splice(x++,0,patch)}}}}};diff_match_patch.prototype.patch_toText=function(patches){var text=[];for(var x=0;x<patches.length;x++){text.push(patches[x])}return text.join('')};diff_match_patch.prototype.patch_fromText=function(textline){var patches=[];var text=textline.split('\n');while(text.length!==0){var m=text[0].match(/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/);if(!m){return alert('Invalid patch string:\n'+text[0])}var patch=new patch_obj();patches.push(patch);patch.start1=parseInt(m[1],10);if(m[2]===''){patch.start1--;patch.length1=1}else if(m[2]=='0'){patch.length1=0}else{patch.start1--;patch.length1=parseInt(m[2],10)}patch.start2=parseInt(m[3],10);if(m[4]===''){patch.start2--;patch.length2=1}else if(m[4]=='0'){patch.length2=0}else{patch.start2--;patch.length2=parseInt(m[4],10)}text.shift();while(text.length!==0){var sign=text[0].charAt(0);var line=decodeURIComponent(text[0].substring(1));if(sign=='-'){patch.diffs.push([DIFF_DELETE,line])}else if(sign=='+'){patch.diffs.push([DIFF_INSERT,line])}else if(sign==' '){patch.diffs.push([DIFF_EQUAL,line])}else if(sign=='@'){break}else if(sign===''){}else{return alert('Invalid patch mode: "'+sign+'"\n'+line)}text.shift()}}return patches};function patch_obj(){this.diffs=[];this.start1=null;this.start2=null;this.length1=0;this.length2=0}patch_obj.prototype.toString=function(){var coords1,coords2;if(this.length1===0){coords1=this.start1+',0'}else if(this.length1==1){coords1=this.start1+1}else{coords1=(this.start1+1)+','+this.length1}if(this.length2===0){coords2=this.start2+',0'}else if(this.length2==1){coords2=this.start2+1}else{coords2=(this.start2+1)+','+this.length2}var txt=['@@ -',coords1,' +',coords2,' @@\n'];for(var x=0;x<this.diffs.length;x++){switch(this.diffs[x][0]){case DIFF_DELETE:txt.push('-');break;case DIFF_EQUAL:txt.push(' ');break;case DIFF_INSERT:txt.push('+');break;default:alert('Invalid diff operation in patch_obj.toString()')}txt.push(encodeURI(this.diffs[x][1]),'\n')}return txt.join('').replace(/%20/g,' ')};
124 libs/firebug-lite-compressed.js
@@ -0,0 +1,124 @@
+var firebug={version:[1.23,20090506],el:{},env:{"css":"http://getfirebug.com/releases/lite/1.2/firebug-lite.css","debug":true,"detectFirebug":true,"dIndex":"console","height":295,"hideDOMFunctions":false,"openInPopup":false,"override":false,"ml":false,"showIconWhenHidden":true,"popupTop":1,"popupLeft":1,"popupWidth":undefined,"popupHeight":undefined,"textNodeChars":0},internal:{"cache":{},"extConsole":null,"init":false,"isPopup":false,"liteFilename":null,"minimized":false,"popupWin":null,"targetWindow":undefined},initConsole:function(){var command;try{if((!window.console||(window.console&&!window.console.firebug))||(firebug.env.override&&!(/Firefox\/3/i.test(navigator.userAgent)))){window.console={"provider":"Firebug Lite"};for(command in firebug.d.console.cmd){window.console[command]=firebug.lib.util.Curry(firebug.d.console.run,window,command);};}
+window.onerror=function(_message,_file,_line){firebug.d.console.run('error',firebug.lib.util.String.format('{0} ({1},{2})',_message,firebug.getFileName(_file),_line));};}catch(e){}},overrideConsole:function(){with(firebug){env.override=true;try{internal.extConsole=window.console;}catch(e){}
+initConsole();}},restoreConsole:function(){with(firebug){if(internal.extConsole){env.override=false;try{window.console=internal.extConsole;}catch(e){}
+internal.extConsole=null;}}},init:function(_css){var i,cssLoaded=false,iconTitle="Click here or press F12, (CTRL|CMD)+SHIFT+L or SHIFT+ENTER to show Firebug Lite. CTRL|CMD click this icon to hide it.";with(firebug){if(document.getElementsByTagName('html')[0].attributes.getNamedItem('debug')){env.debug=document.getElementsByTagName('html')[0].attributes.getNamedItem('debug').nodeValue!=="false";}
+if(internal.isPopup){env.openInPopup=false;internal.targetWindow=window.opener;env.popupWidth=window.opener.firebug.env.popupWidth||window.opener.firebug.lib.util.GetViewport().width;env.popupHeight=window.opener.firebug.env.popupHeight||window.opener.firebug.lib.util.GetViewport().height;}else{internal.targetWindow=window;env.popupWidth=env.popupWidth||lib.util.GetViewport().width;env.popupHeight=env.popupHeight||lib.util.GetViewport().height;}
+settings.readCookie();if(internal.init||(env.detectFirebug&&window.console&&window.console.firebug)){return;}
+for(i=0;i<document.styleSheets.length;i++){if(/firebug-lite\.css/i.test(document.styleSheets[i].href)){cssLoaded=true;break;}}
+if(!cssLoaded){document.getElementsByTagName("head")[0].appendChild(new lib.element("link").attribute.set("rel","stylesheet").attribute.set("type","text/css").attribute.set("href",env.css).element);}
+if(env.override){overrideConsole();}
+el.firebugIcon=new lib.element("div").attribute.set('firebugIgnore',true).attribute.set("id","firebugIconDiv").attribute.set("title",iconTitle).attribute.set("alt",iconTitle).event.addListener("mousedown",win.iconClicked).insert(document.body);el.content={};el.mainiframe=new lib.element("IFRAME").attribute.set("id","FirebugIFrame").attribute.set('firebugIgnore',true).environment.addStyle({"display":"none","width":lib.util.GetViewport().width+"px"}).insert(document.body);el.main=new lib.element("DIV").attribute.set("id","Firebug").attribute.set('firebugIgnore',true).environment.addStyle({"display":"none","width":lib.util.GetViewport().width+"px"}).insert(document.body);if(!internal.isPopup){el.resizer=new lib.element("DIV").attribute.addClass("Resizer").event.addListener("mousedown",win.resizer.start).insert(el.main);}
+el.header=new lib.element("DIV").attribute.addClass("Header").insert(el.main);el.left={};el.left.container=new lib.element("DIV").attribute.addClass("Left").insert(el.main);el.right={};el.right.container=new lib.element("DIV").attribute.addClass("Right").insert(el.main);el.main.child.add(new lib.element("DIV").attribute.addClass('Clear'));el.button={};el.button.container=new lib.element("DIV").attribute.addClass("ButtonContainer").insert(el.header);el.button.logo=new lib.element("A").attribute.set("title","Firebug Lite").attribute.set("target","_blank").attribute.set("href","http://getfirebug.com/lite.html").update("&nbsp;").attribute.addClass("Button Logo").insert(el.button.container);el.button.inspect=new lib.element("A").attribute.addClass("Button").event.addListener("click",internal.targetWindow.firebug.d.inspector.toggle).update("Inspect").insert(el.button.container);el.button.dock=new lib.element("A").attribute.addClass("Button Dock").event.addListener("click",win.dock).insert(el.button.container);el.button.newWindow=new lib.element("A").attribute.addClass("Button NewWindow").event.addListener("click",win.newWindow).insert(el.button.container);if(!internal.isPopup){el.button.maximize=new lib.element("A").attribute.addClass("Button Maximize").event.addListener("click",win.maximize).insert(el.button.container);el.button.minimize=new lib.element("A").attribute.addClass("Button Minimize").event.addListener("click",win.minimize).insert(el.button.container);el.button.close=new lib.element("A").attribute.addClass("Button Close").event.addListener("click",win.hide).insert(el.button.container);}
+if(lib.env.ie||lib.env.webkit){el.button.container.environment.addStyle({"paddingTop":"12px"});}
+el.nav={};el.nav.container=new lib.element("DIV").attribute.addClass("Nav").insert(el.left.container);el.nav.console=new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.navigate,window,"console")).update("Console").insert(el.nav.container);el.nav.html=new lib.element("A").attribute.addClass("Tab").update("HTML").event.addListener("click",lib.util.Curry(d.navigate,window,"html")).insert(el.nav.container);el.nav.css=new lib.element("A").attribute.addClass("Tab").update("CSS").event.addListener("click",lib.util.Curry(d.navigate,window,"css")).insert(el.nav.container);if(!internal.isPopup){el.nav.scripts=new lib.element("A").attribute.addClass("Tab").update("Script").event.addListener("click",lib.util.Curry(d.navigate,window,"scripts")).insert(el.nav.container);}
+el.nav.dom=new lib.element("A").attribute.addClass("Tab").update("DOM").event.addListener("click",lib.util.Curry(d.navigate,internal.targetWindow,"dom")).insert(el.nav.container);el.nav.xhr=new lib.element("A").attribute.addClass("Tab").update("XHR").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).insert(el.nav.container);el.nav.optionsdiv=new lib.element("DIV").attribute.addClass("Settings").insert(el.nav.container);el.nav.options=new lib.element("A").attribute.addClass("Tab Button Options").update("Options&nbsp;&nbsp;&nbsp;&nbsp;").event.addListener("click",settings.toggle).insert(el.nav.optionsdiv);el.borderInspector=new lib.element("DIV").attribute.set("id","FirebugBorderInspector").attribute.set('firebugIgnore',true).event.addListener("click",listen.inspector).insert(document.body);el.bgInspector=new lib.element("DIV").attribute.set("id","FirebugBGInspector").attribute.set('firebugIgnore',true).insert(document.body);el.left.console={};el.left.console.container=new lib.element("DIV").attribute.addClass("Console").insert(el.left.container);el.left.console.mlButton=new lib.element("A").attribute.addClass("MLButton").event.addListener("click",d.console.toggleML).insert(el.left.console.container);el.left.console.monitor=new lib.element("DIV").insert(new lib.element("DIV").attribute.addClass("Monitor").insert(el.left.console.container));el.left.console.container.child.add(new lib.element("DIV").attribute.addClass("InputArrow").update(">>>"));el.left.console.input=new lib.element("INPUT").attribute.set("type","text").attribute.addClass("Input").event.addListener("keydown",listen.consoleTextbox).insert(new lib.element("DIV").attribute.addClass("InputContainer").insert(el.left.console.container));el.right.console={};el.right.console.container=new lib.element("DIV").attribute.addClass("Console Container").insert(el.right.container);el.right.console.mlButton=new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.console.container);el.right.console.input=new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.console.container);el.right.console.input.event.addListener("keydown",lib.util.Curry(tab,window,el.right.console.input.element));el.right.console.run=new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runMultiline).update("Run").insert(el.right.console.container);el.right.console.clear=new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.console.input)).update("Clear").insert(el.right.console.container);el.button.console={};el.button.console.container=new lib.element("DIV").attribute.addClass("ButtonSet").insert(el.button.container);el.button.console.clear=new lib.element("A").attribute.addClass("Button").event.addListener("click",d.console.clear).update("Clear").insert(el.button.console.container);el.left.html={};el.left.html.container=new lib.element("DIV").attribute.addClass("HTML").insert(el.left.container);el.right.html={};el.right.html.container=new lib.element("DIV").attribute.addClass("HTML Container").insert(el.right.container);el.right.html.nav={};el.right.html.nav.container=new lib.element("DIV").attribute.addClass("Nav").insert(el.right.html.container);el.right.html.nav.computedStyle=new lib.element("A").attribute.addClass("Tab Selected").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"computedStyle")).update("Computed Style").insert(el.right.html.nav.container);el.right.html.nav.dom=new lib.element("A").attribute.addClass("Tab").event.addListener("click",lib.util.Curry(d.html.navigate,firebug,"dom")).update("DOM").insert(el.right.html.nav.container);el.right.html.content=new lib.element("DIV").attribute.addClass("Content").insert(el.right.html.container);el.button.html={};el.button.html.container=new lib.element("DIV").attribute.addClass("ButtonSet HTML").insert(el.button.container);el.left.css={};el.left.css.container=new lib.element("DIV").attribute.addClass("CSS").insert(el.left.container);el.right.css={};el.right.css.container=new lib.element("DIV").attribute.addClass("CSS Container").insert(el.right.container);el.right.css.nav={};el.right.css.nav.container=new lib.element("DIV").attribute.addClass("Nav").insert(el.right.css.container);el.right.css.nav.runCSS=new lib.element("A").attribute.addClass("Tab Selected").update("Run CSS").insert(el.right.css.nav.container);el.right.css.mlButton=new lib.element("A").attribute.addClass("MLButton CloseML").event.addListener("click",d.console.toggleML).insert(el.right.css.container);el.right.css.input=new lib.element("TEXTAREA").attribute.addClass("Input").insert(el.right.css.container);el.right.css.input.event.addListener("keydown",lib.util.Curry(firebug.tab,window,el.right.css.input.element));el.right.css.run=new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.runCSS).update("Run").insert(el.right.css.container);el.right.css.clear=new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.clean,window,el.right.css.input)).update("Clear").insert(el.right.css.container);el.button.css={};el.button.css.container=new lib.element("DIV").attribute.addClass("ButtonSet CSS").insert(el.button.container);el.button.css.selectbox=new lib.element("SELECT").event.addListener("change",listen.cssSelectbox).insert(el.button.css.container);el.left.scripts={};el.left.scripts.container=new lib.element("DIV").attribute.addClass("Scripts").insert(el.left.container);el.right.scripts={};el.right.scripts.container=new lib.element("DIV").attribute.addClass("Scripts Container").insert(el.right.container);el.button.scripts={};el.button.scripts.container=new lib.element("DIV").attribute.addClass("ButtonSet Scripts").insert(el.button.container);el.button.scripts.selectbox=new lib.element("SELECT").event.addListener("change",listen.scriptsSelectbox).insert(el.button.scripts.container);el.button.scripts.lineNumbers=new lib.element("A").attribute.addClass("Button").event.addListener("click",d.scripts.toggleLineNumbers).update("Show Line Numbers").insert(el.button.scripts.container);el.left.dom={};el.left.dom.container=new lib.element("DIV").attribute.addClass("DOM").insert(el.left.container);el.right.dom={};el.right.dom.container=new lib.element("DIV").attribute.addClass("DOM Container").insert(el.right.container);el.button.dom={};el.button.dom.container=new lib.element("DIV").attribute.addClass("ButtonSet DOM").insert(el.button.container);el.button.dom.label=new lib.element("LABEL").update("Object Path:").insert(el.button.dom.container);el.button.dom.textbox=new lib.element("INPUT").event.addListener("keydown",listen.domTextbox).update(internal.isPopup?"window.opener":"window").insert(el.button.dom.container);el.left.str={};el.left.str.container=new lib.element("DIV").attribute.addClass("STR").insert(el.left.container);el.right.str={};el.right.str.container=new lib.element("DIV").attribute.addClass("STR").insert(el.left.container);el.button.str={};el.button.str.container=new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container);el.button.str.watch=new lib.element("A").attribute.addClass("Button").event.addListener("click",lib.util.Curry(d.navigate,window,"xhr")).update("Back").insert(el.button.str.container);el.left.xhr={};el.left.xhr.container=new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container);el.right.xhr={};el.right.xhr.container=new lib.element("DIV").attribute.addClass("XHR").insert(el.left.container);el.button.xhr={};el.button.xhr.container=new lib.element("DIV").attribute.addClass("ButtonSet XHR").insert(el.button.container);el.button.xhr.label=new lib.element("LABEL").update("XHR Path:").insert(el.button.xhr.container);el.button.xhr.textbox=new lib.element("INPUT").event.addListener("keydown",listen.xhrTextbox).insert(el.button.xhr.container);el.button.xhr.watch=new lib.element("A").attribute.addClass("Button").event.addListener("click",listen.addXhrObject).update("Watch").insert(el.button.xhr.container);el.settings={};el.settings.container=new lib.element("DIV").child.add(new lib.element("DIV").attribute.addClass("Header").child.add(new lib.element().attribute.addClass("Title").update('Firebug Lite Settings'))).attribute.addClass("SettingsDiv").insert(el.main);el.settings.content=new lib.element("DIV").attribute.addClass("Content").insert(el.settings.container);el.settings.progressDiv=new lib.element("DIV").attribute.addClass("ProgressDiv").insert(el.settings.content);el.settings.progress=new lib.element("DIV").attribute.addClass("Progress").insert(el.settings.progressDiv);el.settings.cbxDebug=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Start visible"));new lib.element("BR").insert(el.settings.content);el.settings.cbxDetectFirebug=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Hide when Firebug active"));new lib.element("BR").insert(el.settings.content);el.settings.cbxHideDOMFunctions=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Hide DOM functions"));new lib.element("BR").insert(el.settings.content);el.settings.cbxOverride=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Override window.console"));new lib.element("BR").insert(el.settings.content);el.settings.cbxShowIcon=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Show icon when hidden"));new lib.element("BR").insert(el.settings.content);el.settings.cbxOpenInPopup=new lib.element("INPUT").attribute.set("type","checkbox").attribute.addClass("SettingsCBX").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Open in popup"));new lib.element("BR").insert(el.settings.content);el.settings.content.child.add(document.createTextNode("Trim textnode to "));el.settings.textNodeChars=new lib.element("INPUT").attribute.set("type","text").attribute.addClass("SettingsTextbox").insert(el.settings.content);el.settings.content.child.add(document.createTextNode(" chars"));el.settings.buttonDiv=new lib.element("DIV").insert(el.settings.content);el.settings.buttonLeftDiv=new lib.element("DIV").attribute.addClass("ButtonsLeft").insert(el.settings.buttonDiv);el.settings.resetButton=new lib.element("INPUT").attribute.set("type","button").update("Reset").event.addListener("click",settings.reset).insert(el.settings.buttonLeftDiv);el.settings.buttonRightDiv=new lib.element("DIV").attribute.addClass("ButtonsRight").insert(el.settings.buttonDiv);el.settings.cancelButton=new lib.element("INPUT").attribute.set("type","button").update("Cancel").event.addListener("click",settings.hide).insert(el.settings.buttonRightDiv);el.settings.buttonRightDiv.child.add(document.createTextNode(" "));el.settings.saveButton=new lib.element("INPUT").attribute.set("type","button").update("Save").event.addListener("click",settings.saveClicked).insert(el.settings.buttonRightDiv);lib.util.AddEvent(document,"mousemove",listen.mouse)("mousemove",win.resizer.resize)("mouseup",win.resizer.stop)("keydown",listen.keyboard);internal.init=true;for(var i=0,len=d.console.cache.length;i<len;i++){var item=d.console.cache[i];d.console.cmd[item.command].apply(window,item.arg);};if(lib.env.ie6){window.onscroll=lib.util.Curry(win.setVerticalPosition,window,null);var buttons=[el.button.inspect,el.button.close,el.button.inspect,el.button.console.clear,el.right.console.run,el.right.console.clear,el.right.css.run,el.right.css.clear];for(var i=0,len=buttons.length;i<len;i++)
+buttons[i].attribute.set("href","#");win.refreshSize();}
+if(env.showIconWhenHidden){if(!internal.popupWin){el.firebugIcon.environment.addStyle({"display":env.debug&&'none'||'block'});}}
+lib.util.AddEvent(window,"unload",win.unload);if(internal.isPopup){env.height=lib.util.GetViewport().height;lib.util.AddEvent(window,"resize",win.fitToPopup);win.fitToPopup();}else{lib.util.AddEvent(window,"resize",win.refreshSize);}
+win.setHeight(env.height);if(env.openInPopup&&!internal.isPopup){win.newWindow();}else{el.main.environment.addStyle({"display":env.debug&&'block'||'none'});el.mainiframe.environment.addStyle({"display":env.debug&&'block'||'none'});}}},inspect:function(){return firebug.d.html.inspect.apply(window,arguments);},watchXHR:function(){with(firebug){d.xhr.addObject.apply(window,arguments);if(env.dIndex!="xhr"){d.navigate("xhr");}}},settings:{isVisible:false,show:function(){with(firebug){var posXY=lib.util.Element.getPosition(firebug.el.nav.options.element);settings.refreshForm();el.settings.container.environment.addStyle({"display":"block","left":(posXY.offsetLeft-107)+"px"});el.settings.progressDiv.environment.addStyle({"display":"none"});firebug.settings.isVisible=true;}},hide:function(){with(firebug){firebug.el.settings.container.environment.addStyle({"display":"none"});firebug.settings.isVisible=false;}},toggle:function(){with(firebug){settings[!settings.isVisible&&'show'||'hide']();}},saveClicked:function(){firebug.el.settings.progressDiv.environment.addStyle({"display":"block"});setTimeout(firebug.settings.formToSettings,0);},formToSettings:function(){var fe=firebug.env,ofe,elSet=firebug.el.settings,exdate;fe.debug=elSet.cbxDebug.element.checked;fe.detectFirebug=elSet.cbxDetectFirebug.element.checked;fe.hideDOMFunctions=elSet.cbxHideDOMFunctions.element.checked;fe.override=elSet.cbxOverride.element.checked;fe.showIconWhenHidden=elSet.cbxShowIcon.element.checked;fe.openInPopup=elSet.cbxOpenInPopup.element.checked;if(isFinite(elSet.textNodeChars.element.value)&&elSet.textNodeChars.element.value>0){fe.textNodeChars=elSet.textNodeChars.element.value;}else{fe.textNodeChars=0;}
+if(firebug.internal.isPopup){window.opener.firebug.env=firebug.lib.util.Hash.clone(fe);}
+with(firebug){settings.writeCookie();settings.hide();win.refreshDOM();d.html.openHtmlTree();if(internal.isPopup){with(opener.firebug){win.refreshDOM();d.html.openHtmlTree();}}}},reset:function(){var exdate=new Date();exdate.setTime(exdate.getTime()-1);document.cookie='FBLiteSettings=;expires='+exdate.toGMTString();location.reload(true);},readCookie:function(){var i,cookieArr,valueArr,item,value;with(firebug.env){if(firebug.internal.targetWindow.document.cookie.length>0){cookieArr=firebug.internal.targetWindow.document.cookie.split('; ');for(i=0;i<cookieArr.length;i++){if(cookieArr[i].split('=')[0]=='FBLiteSettings'){valueArr=cookieArr[i].split('=')[1].split(',');}}
+if(valueArr){for(i=0;i<valueArr.length;i++){item=valueArr[i].split(':')[0];value=valueArr[i].split(':')[1];switch(item){case'debug':debug=value=="true";break;case'detectFirebug':detectFirebug=value=="true";break;case'hideDOMFunctions':hideDOMFunctions=value=="true";break;case'override':override=value=="true";break;case'showIconWhenHidden':showIconWhenHidden=value=="true";break;case'openInPopup':openInPopup=value=="true";break;case'textNodeChars':textNodeChars=isFinite(value)?parseInt(value,10):0;break;case'popupTop':popupTop=parseInt(value,10);break;case'popupLeft':popupLeft=parseInt(value,10);break;case'popupWidth':popupWidth=parseInt(value,10);break;case'popupHeight':popupHeight=parseInt(value,10);break;case'height':height=parseInt(value,10);break;}}}}}},writeCookie:function(){var values;with(firebug.env){values='debug:'+debug+',';values+='detectFirebug:'+detectFirebug+',';values+='hideDOMFunctions:'+hideDOMFunctions+',';values+='override:'+override+',';values+='showIconWhenHidden:'+showIconWhenHidden+',';values+='openInPopup:'+openInPopup+',';values+='textNodeChars:'+textNodeChars+',';if(firebug.internal.isPopup){if(window.outerWidth===undefined){values+='popupTop:'+(window.screenTop-56)+',';values+='popupLeft:'+(window.screenLeft-8)+',';values+='popupWidth:'+document.body.clientWidth+',';values+='popupHeight:'+document.body.clientHeight+',';}else{values+='popupTop:'+window.screenY+',';values+='popupLeft:'+window.screenX+',';values+='popupWidth:'+window.outerWidth+',';values+='popupHeight:'+window.outerHeight+',';}}else{values+='popupTop:'+popupTop+',';values+='popupLeft:'+popupLeft+',';values+='popupWidth:'+popupWidth+',';values+='popupHeight:'+popupHeight+',';}
+values+='height:'+(parseInt(firebug.internal.targetWindow.firebug.el.main.element.style.height.replace(/px/,''),10)-38);exdate=new Date();exdate.setDate(exdate.getDate()+365);firebug.internal.targetWindow.document.cookie='FBLiteSettings='+values+';expires='+exdate.toGMTString();}},refreshForm:function(){var fe=firebug.env,elSet=firebug.el.settings;elSet.cbxDebug.element.checked=fe.debug;elSet.cbxDetectFirebug.element.checked=fe.detectFirebug;elSet.cbxHideDOMFunctions.element.checked=fe.hideDOMFunctions;elSet.cbxOverride.element.checked=fe.override;elSet.cbxShowIcon.element.checked=fe.showIconWhenHidden;elSet.cbxOpenInPopup.element.checked=fe.openInPopup;elSet.textNodeChars.element.value=fe.textNodeChars;}},win:{hide:function(){with(firebug){el.main.environment.addStyle({"display":"none"});el.mainiframe.environment.addStyle({"display":"none"});if(env.showIconWhenHidden){el.firebugIcon.environment.addStyle({"display":"block"});}}},show:function(){with(firebug){el.main.environment.addStyle({"display":"block"});el.mainiframe.environment.addStyle({"display":"block"});if(env.showIconWhenHidden){el.firebugIcon.environment.addStyle({"display":"none"});}}},iconClicked:function(_event){with(firebug){if(_event.ctrlKey==true||_event.metaKey==true){el.firebugIcon.environment.addStyle({"display":"none"});env.showIconWhenHidden=false;}else{win.show();}}},minimize:function(){with(firebug){internal.minimized=true;el.main.environment.addStyle({"height":"35px"});el.mainiframe.environment.addStyle({"height":"35px"});el.button.maximize.environment.addStyle({"display":"block"});el.button.minimize.environment.addStyle({"display":"none"});win.refreshSize();}},maximize:function(){with(firebug){internal.minimized=false;el.button.minimize.environment.addStyle({"display":"block"});el.button.maximize.environment.addStyle({"display":"none"});win.setHeight(env.height);}},newWindow:function(){var interval,scripts,script,scriptPath,fe=firebug.env,fi=firebug.internal;if(!fi.popupWin){scripts=document.getElementsByTagName('script');fi.popupWin=window.open("","_firebug","status=0,menubar=0,resizable=1,top="+fe.popupTop+",left="+fe.popupLeft+",width="+fe.popupWidth+",height="+fe.popupHeight+",scrollbars=0,addressbar=0,outerWidth="+fe.popupWidth+",outerHeight="+fe.popupHeight+"toolbar=0,location=0,directories=0,dialog=0");if(!fi.popupWin){alert("Firebug Lite could not open a pop-up window, most likely because of a popup blocker.\nPlease enable popups for this domain");}else{firebug.settings.hide();for(i=0,len=scripts.length;i<len;i++){if(scripts[i].src.indexOf(fi.liteFilename)>-1){scriptPath=scripts[i].src;break;}}
+if(scriptPath){done=false;script=fi.popupWin.document.createElement('script');script.type='text/javascript';script.src=scriptPath;script[firebug.lib.env.ie?"onreadystatechange":"onload"]=function(){if(!done&&(!firebug.lib.env.ie||this.readyState=="complete"||this.readyState=="loaded")){done=true;if(fi.popupWin.firebug){with(fi.popupWin.firebug){internal.isPopup=true;env.css=fe.css;init();el.button.dock.environment.addStyle({"display":"block"});el.button.newWindow.environment.addStyle({"display":"none"});}}}};if(!done&&firebug.lib.env.webkit){interval=setInterval(function(){if(firebug.internal.popupWin.firebug){clearInterval(interval);done=true;with(firebug.internal.popupWin.firebug){internal.isPopup=true;env.css=fe.css;init();el.button.dock.environment.addStyle({"display":"block"});el.button.newWindow.environment.addStyle({"display":"none"});}}},10);};if(!firebug.lib.env.ie){firebug.internal.popupWin.document.write('<html><head><title>Firebug Lite - '+document.location.href+'</title></head><body></body></html>');}
+if(!done){firebug.internal.popupWin.document.getElementsByTagName('head')[0].appendChild(script);firebug.el.main.environment.addStyle({"display":"none"});firebug.el.mainiframe.environment.addStyle({"display":"none"});}}else{alert("Unable to detect the following script \""+firebug.internal.liteFilename+"\" ... if the script has been renamed then please set the value of firebug.internal.liteFilename to reflect this change");firebug.internal.popupWin.close();firebug.internal.popupWin=null;}}}},dock:function(){with(opener.firebug){internal.popupWin=null;el.main.environment.addStyle({"display":"block"});el.mainiframe.environment.addStyle({"display":"block"});settings.readCookie();window.close();};},unload:function(){with(firebug){if(internal.isPopup){win.dock();}else if(internal.popupWin){internal.popupWin.close();}}},fitToPopup:function(){with(firebug){var viewport=lib.util.GetViewport(window);win.setHeight((window.innerHeight||viewport.height)-38);el.main.environment.addStyle({"width":(viewport.width)+"px"});el.mainiframe.environment.addStyle({"width":(viewport.width)+"px"});}},resizer:{y:[],enabled:false,start:function(_event){with(firebug){if(internal.minimized)return;win.resizer.y=[el.main.element.offsetHeight,_event.clientY];if(lib.env.ie6){win.resizer.y[3]=parseInt(el.main.environment.getPosition().top);}
+win.resizer.enabled=true;}},resize:function(_event){with(firebug){if(!win.resizer.enabled)return;win.resizer.y[2]=(win.resizer.y[0]+(win.resizer.y[1]-_event.clientY));el.main.environment.addStyle({"height":win.resizer.y[2]+"px"});el.mainiframe.environment.addStyle({"height":win.resizer.y[2]+"px"});if(lib.env.ie6){el.main.environment.addStyle({"top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px"});el.mainiframe.environment.addStyle({"top":win.resizer.y[3]-(win.resizer.y[1]-_event.clientY)+"px"});}}},stop:function(_event){with(firebug){if(win.resizer.enabled){win.resizer.enabled=false;win.setHeight(win.resizer.y[2]-35);}}}},setHeight:function(_height){with(firebug){env.height=_height;el.left.container.environment.addStyle({"height":_height+"px"});el.right.container.environment.addStyle({"height":_height+"px"});el.main.environment.addStyle({"height":_height+38+"px"});el.mainiframe.environment.addStyle({"height":_height+38+"px"});win.refreshSize();el.left.console.monitor.element.parentNode.style.height=_height-47+"px";el.left.console.mlButton.environment.addStyle({"top":_height+19+"px"});el.right.console.mlButton.environment.addStyle({"top":_height+19+"px"});el.right.console.input.environment.addStyle({"height":_height-29+"px"});el.left.html.container.environment.addStyle({"height":_height-23+"px"});el.right.html.content.environment.addStyle({"height":_height-23+"px"});el.left.css.container.environment.addStyle({"height":_height-33+"px"});el.right.css.input.environment.addStyle({"height":_height-55+"px"});el.left.scripts.container.environment.addStyle({"height":_height-23+"px"});el.left.dom.container.environment.addStyle({"height":_height-31+"px"});el.left.xhr.container.environment.addStyle({"height":_height-32+"px"});el.left.str.container.environment.addStyle({"height":_height-32+"px"});}},refreshDOM:function(){with(firebug){d.dom.open(eval(el.button.dom.textbox.environment.getElement().value),el.left.dom.container);if(d.html.nIndex=="dom"){firebug.d.html.navigate("dom")}}},refreshSize:function(){with(firebug){if(!internal.init)
+return;var dim=lib.util.GetViewport();el.main.environment.addStyle({"width":dim.width+"px"});el.mainiframe.environment.addStyle({"width":dim.width+"px"});if(lib.env.ie6)
+win.setVerticalPosition(dim);}},setVerticalPosition:function(_dim,_event){with(firebug){var dim=_dim||lib.util.GetViewport();el.main.environment.addStyle({"top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px"});el.mainiframe.environment.addStyle({"top":dim.height-el.main.environment.getSize().offsetHeight+Math.max(document.documentElement.scrollTop,document.body.scrollTop)+"px"});}}},d:{clean:function(_element){with(firebug){_element.update("");}},console:{addLine:function(){with(firebug){return new lib.element("DIV").attribute.addClass("Row").insert(el.left.console.monitor);}},cache:[],clear:function(){with(firebug){d.clean(el.left.console.monitor);d.console.cache=[];}},formatArgs:function(){with(firebug){var content=[];for(var i=0,len=arguments.length;i<len;i++){content.push(d.highlight(arguments[i],false,false,true));}
+return content.join(" ");}},history:[],historyIndex:0,openObject:function(_index){with(firebug){d.dom.open(d.console.cache[_index],el.left.dom.container,lib.env.ie);d.navigate("dom");}},print:function(_cmd,_text){with(firebug){d.console.addLine().attribute.addClass("Arrow").update(">>> "+_cmd);d.console.addLine().update(d.highlight(_text,false,false,true));d.console.scroll();}},printException:function(_exception){with(firebug){var message=_exception.description||_exception.message||_exception;if(_exception.fileName){message+=' ('+(_exception.name&&(_exception.name+', ')||'')+getFileName(_exception.fileName)+', '+_exception.lineNumber+')';}
+d.console.addLine().attribute.addClass("Error").update("<strong>Error: </strong>"+message,true);}},eval:function(_cmd){var result;with(firebug){if(_cmd.length==0)
+return;el.left.console.input.environment.getElement().value="";d.console.historyIndex=d.console.history.push(_cmd);try{if(_cmd==='console.firebug'){d.console.addLine().attribute.addClass("Arrow").update(firebug.version);}else{result=eval.call(window,_cmd);d.console.print(_cmd,result);}}catch(e){d.console.addLine().attribute.addClass("Arrow").update(">>> "+_cmd);d.console.printException(e);}
+d.console.scroll();}},scroll:function(){with(firebug){el.left.console.monitor.environment.getElement().parentNode.scrollTop=Math.abs(el.left.console.monitor.environment.getSize().offsetHeight-(el.left.console.monitor.element.parentNode.offsetHeight-11));}},run:function(_command){with(firebug){if(!internal.init){d.console.cache.push({"command":_command,"arg":Array.prototype.slice.call(arguments,1)});}else{d.console.cmd[_command].apply(window,Array.prototype.slice.call(arguments,1));}}},toggleML:function(){with(firebug){var open=!env.ml;env.ml=!env.ml;d.navigateRightColumn("console",open);el[open?"left":"right"].console.mlButton.environment.addStyle({display:"none"});el[!open?"left":"right"].console.mlButton.environment.addStyle({display:"block"});el.left.console.mlButton.attribute[(open?"add":"remove")+"Class"]("CloseML");}},countMap:{},timeMap:{},cmd:{log:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Log").update(args);d.console.scroll();}},warn:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Warn").update(args);d.console.scroll();}},info:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Info").update(args);d.console.scroll();}},debug:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Debug").update(args);d.console.scroll();}},error:function(_value){with(firebug){var args=d.console.formatArgs.apply(window,arguments);d.console.addLine().attribute.addClass("Error").update(args);d.console.scroll();}},trace:function(_value){with(firebug){var stackAmt=3,f=arguments.caller,isArray=lib.util.IsArray(f);if((!isArray&&f)||(isArray&&f.length>0)){d.console.addLine().attribute.addClass("Arrow").update(">>> console.trace(stack)");for(var i=0;i<stackAmt;i++){var func=f.toString(),args=f.arguments;d.dom.open({"function":func,"arguments":args},d.console.addLine());f=f.caller;}}}},dir:function(_value){with(firebug){d.console.addLine().attribute.addClass("Arrow").update(">>> console.dir("+_value+")");d.dom.open(_value,d.console.addLine());}},dirxml:function(){with(firebug){d.console.cmd.log.apply(this,arguments);}},time:function(_name){with(firebug){d.console.timeMap[_name]=new Date().getTime();}},timeEnd:function(_name){with(firebug){if(_name in d.console.timeMap){var delta=new Date().getTime()-d.console.timeMap[_name],args=d.console.formatArgs.apply(window,[_name+":",delta+"ms"]);d.console.addLine().attribute.addClass("log").update(args);delete d.console.timeMap[_name];}}},count:function(_name){with(firebug){if(!d.console.countMap[_name])
+d.console.countMap[_name]=0;d.console.countMap[_name]++;d.console.cmd.log.apply(window,[_name,d.console.countMap[_name]]);}},group:function(){with(firebug){d.console.cmd.log.apply(this,["console.group is not supported"]);}},groupEnd:function(){with(firebug){d.console.cmd.log.apply(this,["console.groupEnd is not supported"]);}},profile:function(){with(firebug){d.console.cmd.log.apply(this,["console.profile is not supported"]);}},profileEnd:function(){with(firebug){d.console.cmd.log.apply(this,["console.profileEnd is not supported"]);}}}},css:{index:-1,open:function(_index){with(firebug){var item=internal.targetWindow.document.styleSheets[_index],uri=item.href;try{var rules=item[lib.env.ie?"rules":"cssRules"],str="";for(var i=0;i<rules.length;i++){var item=rules[i];var selector=item.selectorText;var cssText=lib.env.ie?item.style.cssText:item.cssText.match(/\{(.*)\}/)[1];str+=d.css.printRule(selector,cssText.split(";"),el.left.css.container);}}catch(e){str="<em>Access to restricted URI denied</em>";}
+el.left.css.container.update(str);}},printRule:function(_selector,_css,_layer){with(firebug){var str="<div class='Selector'>"+_selector+" {</div>";for(var i=0,len=_css.length;i<len;i++){var item=_css[i];str+="<div class='CSSText'>"+item.replace(/(.+\:)(.+)/,"<span class='CSSProperty'>$1</span><span class='CSSValue'>$2;</span>")+"</div>";}
+str+="<div class='Selector'>}</div>";return str;}},refresh:function(){with(firebug){el.button.css.selectbox.update("");var collection=internal.targetWindow.document.styleSheets;for(var i=0,len=collection.length;i<len;i++){var uri=getFileName(collection[i].href);d.css.index=d.css.index<0?i:d.css.index;el.button.css.selectbox.child.add(new lib.element("OPTION").attribute.set("value",i).update(uri))};d.css.open(d.css.index);}}},dom:{open:function(_object,_layer){with(firebug){_layer.clean();var container=new lib.element("DIV").attribute.addClass("DOMContent").insert(_layer);d.dom.print(_object,container);}},print:function(_object,_parent,_inTree){with(firebug){var obj=_object||window,parentElement=_parent;parentElement.update("");if(parentElement.opened&&parentElement!=el.left.dom.container){parentElement.environment.getParent().lib.child.get()[0].lib.child.get()[0].lib.attribute.removeClass("Opened");parentElement.opened=false;parentElement.environment.addStyle({"display":"none"});return;}
+if(_inTree)
+parentElement.environment.getParent().lib.child.get()[0].lib.child.get()[0].lib.attribute.addClass("Opened");parentElement.opened=true;for(var key in obj){try{if(env.hideDOMFunctions&&typeof(obj[key])=="function")continue;var value=obj[key],property=key,container=new lib.element("DIV").attribute.addClass("DOMRow").insert(parentElement),left=new lib.element("DIV").attribute.addClass("DOMRowLeft").insert(container),right=new lib.element("DIV").attribute.addClass("DOMRowRight").insert(container);container.child.add(new lib.element("DIV").attribute.addClass('Clear'));var link=new lib.element("A").attribute.addClass(typeof value=="object"&&Boolean(value)?"Property Object":"Property").update(property).insert(left);right.update(d.highlight(value,false,true));var subContainer=new lib.element("DIV").attribute.addClass("DOMRowSubContainer").insert(container);if(typeof value!="object"||Boolean(value)==false)
+continue;link.event.addListener("click",lib.util.Curry(d.dom.print,window,value,subContainer,true));}catch(e){}}
+parentElement.environment.addStyle({"display":"block"});}}},highlight:function(_value,_inObject,_inArray,_link){with(firebug){var isArray=false,isHash,isElement=false,vtype=typeof _value,result=[];if(vtype=="object"){if(Object.prototype.toString.call(_value)==="[object Date]"){vtype="date";}else if(Object.prototype.toString.call(_value)==="[object String]"){vtype="string";}else if(Object.prototype.toString.call(_value)==="[object Boolean]"){vtype="boolean";}else if(Object.prototype.toString.call(_value)==="[object RegExp]"){vtype="regexp";}}
+try{isArray=lib.util.IsArray(_value);isHash=lib.util.IsHash(_value);isElement=_value!=undefined&&Boolean(_value.nodeName)&&Boolean(_value.nodeType);if(_value==null||vtype=="number"||vtype=="string"||vtype=="boolean"||(vtype=="function"&&_value.nodeName!="OBJECT")||vtype=="regexp"||vtype=="date"){if(_value==null){if(_value===undefined){result.push("<span class='Null'>undefined</span>");}else{result.push("<span class='Null'>null</span>");}}else if(vtype=="regexp"){result.push("<span class='Maroon'>"+_value+"</span>");}else if(vtype=="date"){result.push("<span class='DarkBlue'>'"+_value+"'</span>");}else if(vtype=="boolean"||vtype=="number"){result.push("<span class='DarkBlue'>"+_value+"</span>");}else if(vtype=="function"){result.push("<span class='"+(_inObject?"Italic Gray":"Green")+"'>function()</span>");}else{result.push("<span class='Red'>\""+(!_inObject&&!_inArray?_value:_value.substring(0,35)+(_value.length>35?" ...":"")).replace(/\n/g,"\\n").replace(/\s/g,"&nbsp;").replace(/>/g,"&#62;").replace(/</g,"&#60;")+"\"</span>");}}
+else if(isElement){if(_value.nodeType==3)
+result.push(d.highlight(_value.nodeValue));else if(_inObject){result.push("<span class='Gray Italic'>"+_value.nodeName.toLowerCase()+"</span>");}else{result.push("<span class='Blue"+(!_link?"'":" ObjectLink' onmouseover='this.className=this.className.replace(\"ObjectLink\",\"ObjectLinkHover\")' onmouseout='this.className=this.className.replace(\"ObjectLinkHover\",\"ObjectLink\")' onclick='firebug.d.html.inspect(firebug.d.console.cache["+(d.console.cache.push(_value)-1)+"])'")+"'>");if(_inArray){result.push(_value.nodeName.toLowerCase());if(_value.getAttribute){if(_value.getAttribute&&_value.getAttribute("id"))
+result.push("<span class='DarkBlue'>#"+_value.getAttribute("id")+"</span>");var elClass=_value.getAttribute(lib.env.ie&&!lib.env.ie8?"className":"class")||"";result.push(!elClass?"":"<span class='Red'>."+elClass.split(" ")[0]+"</span>");}
+result.push("</span>");}else{result.push("<span class='DarkBlue'>&#60;<span class='Blue TagName'>"+_value.nodeName.toLowerCase());if(_value.attributes){for(var i=0,len=_value.attributes.length;i<len;i++){var item=_value.attributes[i];if(!lib.env.ie||item.nodeValue)
+result.push(" <span class='DarkBlue'>"+item.nodeName+"=\"<span class='Red'>"+item.nodeValue+"</span>\"</span>");}}
+result.push("</span>&#62;</span>");}}}
+else if(isArray||isHash){if(isArray){if(_inObject){result.push("<span class='Gray Italic'>["+_value.length+"]</span>");}else{result.push("<span class='Strong'>[ ");for(var i=0,len=_value.length;i<len;i++){if((_inObject||_inArray)&&i>3){result.push(", <span class='Strong Gray'>"+(len-4)+" More...</span>");break;}
+result.push((i>0?", ":"")+d.highlight(_value[i],false,true,true));}
+result.push(" ]</span>");}}else if(_inObject){result.push("<span class='Gray Italic'>Object</span>");}else{result.push("<span class='Strong Green"+(!_link?"'":" ObjectLink' onmouseover='this.className=this.className.replace(\"ObjectLink\",\"ObjectLinkHover\")' onmouseout='this.className=this.className.replace(\"ObjectLinkHover\",\"ObjectLink\")' onclick='firebug.d.console.openObject("+(d.console.cache.push(_value)-1)+")'")+">Object");var i=0;for(var key in _value){var value=_value[key];if((_inObject||_inArray)&&i>3){result.push(" <span class='Strong Gray'>More...</span>");break;}
+result.push(" "+key+"="+d.highlight(value,true));i++;}
+result.push("</span>");}}else{result.push(["<span class'Gray Italic'>"+_value+"</span>"]);}}catch(e){result.push("..");}
+return result.join("");}},html:{nIndex:"computedStyle",current:null,highlight:function(_element,_clear,_event){with(firebug){if(_element.firebugElement){return;}
+if(_clear){internal.targetWindow.firebug.el.bgInspector.environment.addStyle({"display":"none"});return;}
+d.inspector.inspect(_element,true);}},inspect:function(_element){var map=[],parentLayer,t,link,tagName,searchEl,parent=_element;while(parent){map.push(parent);if(parent==firebug.internal.targetWindow.document.body)break;parent=parent.parentNode;}
+map=map.reverse();with(firebug){if(env.dIndex!="html"){internal.targetWindow.firebug.d.navigate("html");}
+internal.targetWindow.firebug.d.inspector.toggle(false);for(t=0;t<el.left.html.container.child.get().length;t++){searchEl=el.left.html.container.child.get()[t];if(/<body/i.test(searchEl.innerText||searchEl.textContent)){parentLayer=el.left.html.container.child.get()[t].childNodes[1].lib;break;}}
+if(!parentLayer){parentLayer=el.left.html.container.child.get()[3].childNodes[1].lib;}
+for(t=0,len=map.length;map[t];t++){if(t==len-1){link=parentLayer.environment.getElement().previousSibling.lib;link.attribute.addClass("Selected");if(link.element.scrollIntoView){link.element.scrollIntoView(false);}
+if(d.html.current){d.html.current[1].attribute.removeClass("Selected");}
+d.html.current=[_element,link];return;}
+parentLayer=d.html.openHtmlTree(map[t],parentLayer,map[t+1]);}}},navigate:function(_index,_element){with(firebug){el.right.html.nav[d.html.nIndex].attribute.removeClass("Selected");el.right.html.nav[_index].attribute.addClass("Selected");d.html.nIndex=_index;d.html.openProperties();}},openHtmlTree:function(_element,_parent,_returnParentElementByElement,_event){with(firebug){var element=_element||internal.targetWindow.document.documentElement,parent=_parent||el.left.html.container,returnParentEl=_returnParentElementByElement||null,returnParentVal=null,len=element.childNodes.length,nodeLink;if(!window.Node){window.Node={TEXT_NODE:3,COMMENT_NODE:8};}
+if(parent!=el.left.html.container){nodeLink=parent.environment.getParent().lib.child.get()[0].lib;if(d.html.current){d.html.current[1].attribute.removeClass("Selected");}
+nodeLink.attribute.addClass("Selected");d.html.current=[_element,nodeLink];d.html.openProperties();};if(element.childNodes&&(len==0||(len==1&&element.childNodes[0].nodeType==Node.TEXT_NODE)))return;parent.clean();if(parent.opened&&Boolean(_returnParentElementByElement)==false){parent.opened=false;parent.element.previousSibling.lib.attribute.removeClass("Open");parent.element.lib.attribute.removeClass("OpenSubContainer");return;};if(parent!=el.left.html.container){parent.element.previousSibling.lib.attribute.addClass("Open");parent.element.lib.attribute.addClass("OpenSubContainer");parent.opened=true;};if(element==document.documentElement){new lib.element("A").attribute.addClass("Block").update("<span class='DarkBlue'>&#60;<span class='Blue'>html</span>&#62;").insert(parent);};for(var i=0;i<=len;i++){if(i==len){new lib.element("A").attribute.addClass("Block").update("<span class='DarkBlue'>&#60;/<span class='Blue'>"+element.nodeName.toLowerCase()+"</span>&#62;").insert(container);break;}
+var item=element.childNodes[i];if(item.nodeType!=Node.TEXT_NODE&&!item.getAttribute('firebugIgnore')){var container=new lib.element().attribute.addClass("Block").insert(parent),link=new lib.element("A").attribute.addClass("Link").insert(container),spacer=new lib.element("SPAN").attribute.addClass("Spacer").update("&nbsp;").insert(link),html=new lib.element("SPAN").attribute.addClass("Content").update(d.highlight(item)).insert(link),subContainer=new lib.element("DIV").attribute.addClass("SubContainer").insert(container),view;if(item.nodeType==Node.COMMENT_NODE){continue;}
+view=lib.util.Element.getView(item);link.event.addListener("click",lib.util.Curry(d.html.openHtmlTree,window,item,subContainer,false));link.event.addListener("mouseover",lib.util.Curry(d.html.highlight,window,item,false));link.event.addListener("mouseout",lib.util.Curry(d.html.highlight,window,item,true));returnParentVal=returnParentEl==item?subContainer:returnParentVal;if(d.html.current==null&&item==document.body){link.attribute.addClass("Selected");link.attribute.addClass("Parent");d.html.current=[item,link];d.html.openHtmlTree(item,subContainer);}
+if(element.nodeName!="HEAD"&&element!=document.documentElement&&(view.visibility=="hidden"||view.display=="none")){container.attribute.addClass("Unvisible");};if(item.childNodes){var childLen=item.childNodes.length;if(childLen==1&&item.childNodes[0].nodeType==Node.TEXT_NODE){if(isFinite(env.textNodeChars)&&parseInt(env.textNodeChars)>0){html.child.add(document.createTextNode(item.childNodes[0].nodeValue.substring(0,env.textNodeChars)));}else{html.child.add(document.createTextNode(item.childNodes[0].nodeValue));}
+html.child.add(document.createTextNode("</"));html.child.add(new lib.element("span").attribute.addClass("Blue").update(item.nodeName.toLowerCase()).environment.getElement());html.child.add(document.createTextNode(">"));continue;}
+else if(childLen>0){link.attribute.addClass("Parent");}}}};return returnParentVal;}},openProperties:function(){with(firebug){var index=d.html.nIndex;var node=d.html.current[0];d.clean(el.right.html.content);var str="";switch(index){case"computedStyle":var property=["opacity","filter","azimuth","background","backgroundAttachment","backgroundColor","backgroundImage","backgroundPosition","backgroundRepeat","border","borderCollapse","borderColor","borderSpacing","borderStyle","borderTop","borderRight","borderBottom","borderLeft","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","borderTopStyle","borderRightStyle","borderBottomStyle","borderLeftStyle","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderWidth","bottom","captionSide","clear","clip","color","content","counterIncrement","counterReset","cue","cueAfter","cueBefore","cursor","direction","display","elevation","emptyCells","cssFloat","font","fontFamily","fontSize","fontSizeAdjust","fontStretch","fontStyle","fontVariant","fontWeight","height","left","letterSpacing","lineHeight","listStyle","listStyleImage","listStylePosition","listStyleType","margin","marginTop","marginRight","marginBottom","marginLeft","markerOffset","marks","maxHeight","maxWidth","minHeight","minWidth","orphans","outline","outlineColor","outlineStyle","outlineWidth","overflow","padding","paddingTop","paddingRight","paddingBottom","paddingLeft","page","pageBreakAfter","pageBreakBefore","pageBreakInside","pause","pauseAfter","pauseBefore","pitch","pitchRange","playDuring","position","quotes","richness","right","size","speak","speakHeader","speakNumeral","speakPunctuation","speechRate","stress","tableLayout","textAlign","textDecoration","textIndent","textShadow","textTransform","top","unicodeBidi","verticalAlign","visibility","voiceFamily","volume","whiteSpace","widows","width","wordSpacing","zIndex"].sort();var view=document.defaultView?document.defaultView.getComputedStyle(node,null):node.currentStyle;for(var i=0,len=property.length;i<len;i++){var item=property[i];if(!view[item])continue;str+="<div class='CSSItem'><div class='CSSProperty'>"+item+"</div><div class='CSSValue'>"+d.highlight(view[item])+"</div></div>";}
+el.right.html.content.update(str);break;case"dom":d.dom.open(node,el.right.html.content,lib.env.ie);break;}}}},inspector:{enabled:false,el:null,inspect:function(_element,_bgInspector){with(firebug){var pos=internal.targetWindow.firebug.lib.util.Element.getPosition(_element);internal.targetWindow.firebug.el[_bgInspector&&"bgInspector"||"borderInspector"].environment.addStyle({"width":_element.offsetWidth+"px","height":_element.offsetHeight+"px","top":