diff --git a/.gitignore b/.gitignore
index 8a14284..76906b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
 /nbproject/
 /images/
 /tests/templates/
+/tests/cache/
 /dist/
 /build/tmp.js
 index.html
\ No newline at end of file
diff --git a/build/html2canvas.js b/build/html2canvas.js
index 143fe70..6d17d7f 100644
--- a/build/html2canvas.js
+++ b/build/html2canvas.js
@@ -1,5 +1,5 @@
 /* 
- * html2canvas v0.20 <http://html2canvas.hertzen.com>
+ * html2canvas v0.25 <http://html2canvas.hertzen.com>
  * Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
  * http://www.twitter.com/niklasvh 
  * 
@@ -52,9 +52,19 @@ function html2canvas(el, userOptions) {
         reorderZ: true,
         throttle:true,
         letterRendering:false,
+        proxyUrl: null,
+        logger: function(a){
+            if (window.console && window.console.log){
+                window.console.log(a);     
+            }else{
+                alert(a);
+            }
+        },
+        canvasWidth:0,
+        canvasHeight:0,
         renderOrder: "canvas flash html"
     });
-    
+
     this.element = el;
     
     var imageLoaded,
@@ -71,6 +81,7 @@ function html2canvas(el, userOptions) {
     this.ignoreElements = "IFRAME|OBJECT|PARAM";
     this.needReorder = false;
     this.blockElements = new RegExp("(BR|PARAM)");
+    this.pageOrigin = window.location.protocol + window.location.hostname;
 
     this.ignoreRe = new RegExp("("+this.ignoreElements+")");
     
@@ -132,16 +143,22 @@ html2canvas.prototype.init = function(){
        
     this.canvas = this.ctx.canvas;
         */
-    this.log('Finding background images');
+    this.log('Finding background-images');
         
+    this.images.push('start');
+    
     this.getImages(this.element);
             
     this.log('Finding images');
-    this.each(document.images,function(i,e){
+    // console.log(this.element.ownerDocument);
+   
+    
+   
+    this.each(this.element.ownerDocument.images,function(i,e){
         _.preloadImage(_.getAttr(e,'src'));
     });
-      
-        
+    this.images.splice(0,1);  
+    //  console.log(this.images);   
     if (this.images.length == 0){
         this.start();
     }  
@@ -154,9 +171,10 @@ html2canvas.prototype.init = function(){
  */
  
 html2canvas.prototype.start = function(){
-          
+    //     console.log(this.images);
     if (this.images.length == 0 || this.imagesLoaded==this.images.length/2){    
-        this.log('Started parsing');
+        
+        this.log('Finished loading '+this.imagesLoaded+' images, Started parsing');
         this.bodyOverflow = document.getElementsByTagName('body')[0].style.overflow;
         document.getElementsByTagName('body')[0].style.overflow = "hidden";
         var rootStack = new this.storageContext($(document).width(),$(document).height());  
@@ -275,8 +293,8 @@ html2canvas.prototype.drawBackground = function(el,bounds,ctx){
     var background_image = this.getCSS(el,"background-image");
     var background_repeat = this.getCSS(el,"background-repeat");
         
-    if (typeof background_image != "undefined" && /^(1|none)$/.test(background_image)==false){
-            
+    if (typeof background_image != "undefined" && /^(1|none)$/.test(background_image)==false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)==false){
+         
         background_image = this.backgroundImageUrl(background_image);
         var image = this.loadImage(background_image);
 					
@@ -284,7 +302,6 @@ html2canvas.prototype.drawBackground = function(el,bounds,ctx){
         var bgp = this.getBackgroundPosition(el,bounds,image),
         bgy;
 
-
         if (image){
             switch(background_repeat){
 					
@@ -297,10 +314,70 @@ html2canvas.prototype.drawBackground = function(el,bounds,ctx){
                     break;
                           
                 case "no-repeat":
-                        
-                    this.drawBackgroundRepeat(ctx,image,bgp.left+bounds.left,bgp.top+bounds.top,Math.min(bounds.width,image.width),Math.min(bounds.height,image.height),bounds.left,bounds.top);
-                    // ctx.drawImage(image,(bounds.left+bgp.left),(bounds.top+bgp.top));	                      
-                    break;
+                    /*
+                    this.drawBackgroundRepeat(
+                        ctx,
+                        image,
+                        bgp.left+bounds.left, // sx
+                        bgp.top+bounds.top, // sy
+                        Math.min(bounds.width,image.width),
+                        Math.min(bounds.height,image.height),
+                        bounds.left,
+                        bounds.top
+                        );*/
+                            
+      
+                    // console.log($(el).css('background-image'));
+                    var bgw = bounds.width-bgp.left,
+                    bgh = bounds.height-bgp.top,
+                    bgsx = bgp.left,
+                    bgsy = bgp.top,
+                    bgdx = bgp.left+bounds.left,
+                    bgdy = bgp.top+bounds.top;
+
+                    //
+                    //     bgw = Math.min(bgw,image.width);
+                    //  bgh = Math.min(bgh,image.height);     
+                    
+                    if (bgsx<0){
+                        bgsx = Math.abs(bgsx);
+                        bgdx += bgsx; 
+                        bgw = Math.min(bounds.width,image.width-bgsx);
+                    }else{
+                        bgw = Math.min(bgw,image.width);
+                        bgsx = 0;
+                    }
+                           
+                    if (bgsy<0){
+                        bgsy = Math.abs(bgsy);
+                        bgdy += bgsy; 
+                        // bgh = bgh-bgsy;
+                        bgh = Math.min(bounds.height,image.height-bgsy);
+                    }else{
+                        bgh = Math.min(bgh,image.height); 
+                        bgsy = 0;
+                    }    
+    
+                  
+                    //   bgh = Math.abs(bgh);
+                    //   bgw = Math.abs(bgw);
+                    if (bgh>0 && bgw > 0){        
+                        this.drawImage(
+                            ctx,
+                            image,
+                            bgsx, // source X : 0 
+                            bgsy, // source Y : 1695
+                            bgw, // source Width : 18
+                            bgh, // source Height : 1677
+                            bgdx, // destination X :906
+                            bgdy, // destination Y : 1020
+                            bgw, // destination width : 18
+                            bgh // destination height : 1677
+                            );
+                            
+                        // ctx.drawImage(image,(bounds.left+bgp.left),(bounds.top+bgp.top));	                      
+                        break;
+                    }
                         
                 default:
                     var height,
@@ -365,6 +442,8 @@ html2canvas.prototype.backgroundImageUrl = function(src){
         src = src.substr(4);
         src = src.substr(0,src.length-1);  
     }
+    
+    
     return src;            
 }
     
@@ -375,8 +454,9 @@ html2canvas.prototype.backgroundImageUrl = function(src){
     
 html2canvas.prototype.getBackgroundPosition = function(el,bounds,image){
     var bgpos = this.getCSS(el,"backgroundPosition") || "0 0";
+   // var bgpos = $(el).css("backgroundPosition") || "0 0";
     var bgposition = bgpos.split(" "),
-    top,
+    topPos,
     left,
     percentage;
 
@@ -388,6 +468,8 @@ html2canvas.prototype.getBackgroundPosition = function(el,bounds,image){
         bgposition[1] = val;
     }  
 
+    
+
     if (bgposition[0].toString().indexOf("%")!=-1){   
    
         percentage = (parseFloat(bgposition[0])/100);        
@@ -400,15 +482,29 @@ html2canvas.prototype.getBackgroundPosition = function(el,bounds,image){
     if (bgposition[1].toString().indexOf("%")!=-1){  
 
         percentage = (parseFloat(bgposition[1])/100);     
-        top =  ((bounds.height * percentage)-(image.height*percentage));
+        topPos =  ((bounds.height * percentage)-(image.height*percentage));
     }else{
-        top = parseInt(bgposition[1],10);
+        
+        topPos = parseInt(bgposition[1],10);
+        
     }
+    
+
+    
+    
+    var returnObj = {}
+    /*
+        "top": topPos,
+        "left": left
+    };*/
+    
+
+    returnObj.top = topPos;
+    returnObj.left = left;
+    
+
           
-    return {
-        top: top,
-        left: left
-    };
+    return returnObj;
          
 }
 
@@ -627,7 +723,7 @@ html2canvas.prototype.newElement = function(el,parentStack){
     if (el.nodeName=="IMG"){
         image = _.loadImage(_.getAttr(el,'src'));
         if (image){
-            
+          //   console.log(image.width);
             this.drawImage(
                 ctx,
                 image,
@@ -641,7 +737,7 @@ html2canvas.prototype.newElement = function(el,parentStack){
                 bounds.height - (borders[0].width + borders[2].width + parseInt(_.getCSS(el,'padding-top'),10) + parseInt(_.getCSS(el,'padding-bottom'),10)) //dh       
                 );
            
-        }else{
+        }else {
             this.log("Error loading <img>:" + _.getAttr(el,'src'));
         }
     }
@@ -717,7 +813,8 @@ html2canvas.prototype.getImages = function(el) {
     if (el.nodeType==1 || typeof el.nodeType == "undefined"){
         var background_image = this.getCSS(el,'background-image');
            
-        if (background_image && background_image != "1" && background_image != "none" && background_image.substring(0,7)!="-webkit" && background_image.substring(0,4)!="-moz"){
+        if (background_image && background_image != "1" && background_image != "none" && background_image.substring(0,7)!="-webkit" && background_image.substring(0,3)!="-o-" && background_image.substring(0,4)!="-moz"){
+            
             var src = this.backgroundImageUrl(background_image);                    
             this.preloadImage(src);                    
         }
@@ -748,28 +845,83 @@ html2canvas.prototype.preloadImage = function(src){
 
 
     if (this.getIndex(this.images,src)==-1){
-        this.images.push(src);
-                   
-        var img = new Image();   
-        // TODO remove jQuery dependancy
-        var _ = this;
-        $(img).load(function(){
-            _.imagesLoaded++;               
-            _.start();        
+        if (this.isSameOrigin(src)){
+            this.images.push(src);
+            //     console.log('a'+src);
+            var img = new Image();   
+            // TODO remove jQuery dependancy
+            var _ = this;
+            $(img).load(function(){
+                _.imagesLoaded++;               
+                _.start();        
                 
-        });	
-        img.onerror = function(){
-            _.images.splice(_.images.indexOf(img.src),2);
-            _.imagesLoaded++;
-            _.start();                           
+            });	
+            img.onerror = function(){
+                _.images.splice(_.images.indexOf(img.src),2);
+                //  _.imagesLoaded++;
+                _.start();                           
+            }
+            img.src = src; 
+            this.images.push(img);
+        }else if (this.opts.proxyUrl){
+            //    console.log('b'+src);
+            this.images.push(src);
+            var img = new Image();   
+            this.proxyGetImage(src,img);
+            this.images.push(img);
         }
-        img.src = src; 
-        this.images.push(img);
-                  
     }     
           
 }
+
+html2canvas.prototype.proxyGetImage = function(url,img){
+    var _ = this;
     
+    var link = document.createElement("a");
+    link.href = url;
+    url = link.href; // work around for pages with base href="" set
+
+    
+    // todo remove jQuery dependency and enable xhr2 requests where available (no need for base64 / json)
+    $.ajax({
+        data:{
+            xhr2:false,
+            url:url
+        },
+        url: this.opts.proxyUrl,
+        dataType: "jsonp",
+        success: function(a){
+            
+            if (a.substring(0,6)=="error:"){
+                _.images.splice(_.images.indexOf(url),2);
+                _.start();  
+                _.log('Proxy was unable to load '+url+' '+a);
+            }else{
+                // document.createElement(a);
+                // console.log(img);
+                img.onload = function(){
+                    //   console.log('w'+img.width);
+                    _.imagesLoaded++;               
+                    _.start();   
+               
+                }
+            
+                img.src = a; 
+            }
+
+
+        },
+        error: function(){
+           
+            _.images.splice(_.images.indexOf(url),2);
+            //  _.imagesLoaded++;
+            _.start();          
+        }
+        
+        
+    });
+    
+}
 html2canvas.prototype.Renderer = function(queue){
      
     var _ = this;
@@ -795,25 +947,26 @@ html2canvas.prototype.Renderer = function(queue){
                 var s = document.getElementsByTagName('script')[0]; 
                 s.parentNode.insertBefore(script, s);
                         
-                   */      
+                    
                 if (typeof FlashCanvas != "undefined") {  
                     _.canvas = initCanvas(document.getElementById("testflash"));
                     FlashCanvas.initElement(_.canvas);
                     _.ctx = _.canvas.getContext("2d");
-                   // _.canvas = document.createElement('canvas');
+                    // _.canvas = document.createElement('canvas');
                     //
                     _.log('Using Flashcanvas renderer');
                     _.canvasRenderer(queue);
                     
                     return false;
                 }  
+                     */    
                 
                 break;
-                case "html":
-                    // TODO add renderer
-                    _log("Using HTML renderer");
-                    return false;
-                    break;
+            case "html":
+                // TODO add renderer
+                _.log("Using HTML renderer");
+                return false;
+                break;
              
              
         }
@@ -822,7 +975,7 @@ html2canvas.prototype.Renderer = function(queue){
          
     });
     
-    this.log('No renderer chosen, rendering quit');
+//    this.log('No renderer chosen, rendering quit');
     return this;
      
 // this.canvasRenderer(queue);
@@ -849,6 +1002,11 @@ html2canvas.prototype.Renderer = function(queue){
 }
 
 
+html2canvas.prototype.throttler = function(queue){
+    
+    
+    };
+
 
 
 html2canvas.prototype.canvasRenderer = function(queue){
@@ -859,9 +1017,9 @@ html2canvas.prototype.canvasRenderer = function(queue){
     
     
         
-
-    this.canvas.width = $(document).width();
-    this.canvas.height = $(document).height();
+  
+    this.canvas.width = Math.max($(document).width(),this.opts.canvasWidth);   
+    this.canvas.height = Math.max($(document).height(),this.opts.canvasHeight);
     
     this.ctx = this.canvas.getContext("2d");
     
@@ -885,6 +1043,9 @@ html2canvas.prototype.canvasRenderer = function(queue){
                         }else if(renderItem.name=="fillText"){
                             _.ctx.fillText(renderItem.arguments[0],renderItem.arguments[1],renderItem.arguments[2]);
                         }else if(renderItem.name=="drawImage"){
+                          //  console.log(renderItem);
+                         // console.log(renderItem.arguments[0].width);
+                          if (renderItem.arguments[8] > 0 && renderItem.arguments[7]){
                             _.ctx.drawImage(
                                 renderItem.arguments[0],
                                 renderItem.arguments[1],
@@ -896,6 +1057,7 @@ html2canvas.prototype.canvasRenderer = function(queue){
                                 renderItem.arguments[7],
                                 renderItem.arguments[8]
                                 );
+                              }      
                         }else{
                             this.log(renderItem);
                         }
@@ -1298,21 +1460,11 @@ html2canvas.prototype.parsing = function(el,stack){
     
 
 // Simple logger
-html2canvas.prototype.log = function(a){
-    
+html2canvas.prototype.log = function(a){    
     if (this.opts.logging){
         
-        if (window.console && window.console.log){
-           console.log(a);     
-        }else{
-            alert(a);
-        }
-    /*
-        if (typeof(window.console) != "undefined" && console.log){
-            console.log(a);
-        }else{
-            alert(a);
-        }*/
+        this.opts.logger(a);
+
     }
 }                    
 
@@ -1464,3 +1616,12 @@ html2canvas.prototype.getIndex = function(array,src){
     }
     
 }
+
+
+html2canvas.prototype.isSameOrigin = function(url){
+    var link = document.createElement("a");
+    link.href = url;
+
+    return ((link.protocol + link.hostname) == this.pageOrigin);
+}
+
diff --git a/build/html2canvas.min.js b/build/html2canvas.min.js
index 3c41bb4..416b2ff 100644
--- a/build/html2canvas.min.js
+++ b/build/html2canvas.min.js
@@ -1,45 +1,49 @@
 /* 
- * html2canvas v0.20 <http://html2canvas.hertzen.com>
+ * html2canvas v0.25 <http://html2canvas.hertzen.com>
  * Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
  * http://www.twitter.com/niklasvh 
  * 
  * Released under MIT License
  */
 
-function html2canvas(a,b){this.opts=this.extendObj(b||{},{logging:!1,ready:function(a){document.body.appendChild(a.canvas)},iframeDefault:"default",flashCanvasPath:"http://html2canvas.hertzen.com/external/flashcanvas/flashcanvas.js",renderViewport:!1,reorderZ:!0,throttle:!0,letterRendering:!1,renderOrder:"canvas flash html"});this.element=a;this.imagesLoaded=0;this.images=[];this.fontData=[];this.numDraws=0;this.contextStacks=[];this.ignoreElements="IFRAME|OBJECT|PARAM";this.needReorder=!1;this.blockElements=
-/(BR|PARAM)/;this.ignoreRe=RegExp("("+this.ignoreElements+")");this.support={rangeBounds:!1};if(document.createRange){var c=document.createRange();if(c.getBoundingClientRect){var d=document.createElement("boundtest");d.style.height="123px";d.style.display="block";document.getElementsByTagName("body")[0].appendChild(d);c.selectNode(d);if(c.getBoundingClientRect().height==123)this.support.rangeBounds=!0;document.getElementsByTagName("body")[0].removeChild(d)}}this.init();return this}
-html2canvas.prototype.init=function(){var a=this;this.log("Finding background images");this.getImages(this.element);this.log("Finding images");this.each(document.images,function(b,c){a.preloadImage(a.getAttr(c,"src"))});this.images.length==0&&this.start()};
-html2canvas.prototype.start=function(){if(this.images.length==0||this.imagesLoaded==this.images.length/2){this.log("Started parsing");this.bodyOverflow=document.getElementsByTagName("body")[0].style.overflow;document.getElementsByTagName("body")[0].style.overflow="hidden";var a=new this.storageContext($(document).width(),$(document).height());a.opacity=this.getCSS(this.element,"opacity");this.parseElement(this.element,this.newElement(this.element,a))}};
+function html2canvas(a,b){this.opts=this.extendObj(b||{},{logging:!1,ready:function(a){document.body.appendChild(a.canvas)},storageReady:function(a){a.Renderer(a.contextStacks)},iframeDefault:"default",flashCanvasPath:"http://html2canvas.hertzen.com/external/flashcanvas/flashcanvas.js",renderViewport:!1,reorderZ:!0,throttle:!0,letterRendering:!1,proxyUrl:null,logger:function(a){window.console&&window.console.log?window.console.log(a):alert(a)},canvasWidth:0,canvasHeight:0,renderOrder:"canvas flash html"});
+this.element=a;this.imagesLoaded=0;this.images=[];this.fontData=[];this.numDraws=0;this.contextStacks=[];this.ignoreElements="IFRAME|OBJECT|PARAM";this.needReorder=!1;this.blockElements=/(BR|PARAM)/;this.pageOrigin=window.location.protocol+window.location.hostname;this.ignoreRe=RegExp("("+this.ignoreElements+")");this.support={rangeBounds:!1};if(document.createRange){var d=document.createRange();if(d.getBoundingClientRect){var c=document.createElement("boundtest");c.style.height="123px";c.style.display=
+"block";document.getElementsByTagName("body")[0].appendChild(c);d.selectNode(c);if(d.getBoundingClientRect().height==123)this.support.rangeBounds=!0;document.getElementsByTagName("body")[0].removeChild(c)}}this.init();return this}
+html2canvas.prototype.init=function(){var a=this;this.log("Finding background-images");this.images.push("start");this.getImages(this.element);this.log("Finding images");this.each(this.element.ownerDocument.images,function(b,d){a.preloadImage(a.getAttr(d,"src"))});this.images.splice(0,1);this.images.length==0&&this.start()};
+html2canvas.prototype.start=function(){if(this.images.length==0||this.imagesLoaded==this.images.length/2){this.log("Finished loading "+this.imagesLoaded+" images, Started parsing");this.bodyOverflow=document.getElementsByTagName("body")[0].style.overflow;document.getElementsByTagName("body")[0].style.overflow="hidden";var a=new this.storageContext($(document).width(),$(document).height());a.opacity=this.getCSS(this.element,"opacity");this.parseElement(this.element,this.newElement(this.element,a))}};
 html2canvas.prototype.stackingContext=function(a){this.canvas=document.createElement("canvas");this.canvas.width=a;this.canvas.height=a;if(this.canvas.getContext)this.ctx=this.canvas.getContext("2d");this.ctx.textBaseline="bottom";return this.ctx};
-html2canvas.prototype.storageContext=function(a,b){this.storage=[];this.width=a;this.height=b;this.fillRect=function(a,b,e,f){this.storage.push({type:"function",name:"fillRect",arguments:[a,b,e,f]})};this.drawImage=function(a,b,e,f,g,k,i,j,h){this.storage.push({type:"function",name:"drawImage",arguments:[a,b,e,f,g,k,i,j,h]})};this.fillText=function(a,b,e){this.storage.push({type:"function",name:"fillText",arguments:[a,b,e]})};return this};
+html2canvas.prototype.storageContext=function(a,b){this.storage=[];this.width=a;this.height=b;this.fillRect=function(a,b,e,f){this.storage.push({type:"function",name:"fillRect",arguments:[a,b,e,f]})};this.drawImage=function(a,b,e,f,g,j,h,k,i){this.storage.push({type:"function",name:"drawImage",arguments:[a,b,e,f,g,j,h,k,i]})};this.fillText=function(a,b,e){this.storage.push({type:"function",name:"fillText",arguments:[a,b,e]})};return this};
 html2canvas.prototype.finish=function(){this.log("Finished rendering");document.getElementsByTagName("body")[0].style.overflow=this.bodyOverflow;this.opts.ready(this)};
-html2canvas.prototype.drawBackground=function(a,b,c){var d=this.getCSS(a,"background-image"),e=this.getCSS(a,"background-repeat");if(typeof d!="undefined"&&/^(1|none)$/.test(d)==!1){var d=this.backgroundImageUrl(d),f=this.loadImage(d),a=this.getBackgroundPosition(a,b,f);if(f)switch(e){case "repeat-x":this.drawbackgroundRepeatX(c,f,a,b.left,b.top,b.width,b.height);break;case "repeat-y":this.drawbackgroundRepeatY(c,f,a,b.left,b.top,b.width,b.height);break;case "no-repeat":this.drawBackgroundRepeat(c,
-f,a.left+b.left,a.top+b.top,Math.min(b.width,f.width),Math.min(b.height,f.height),b.left,b.top);break;default:var g;a.top-=Math.ceil(a.top/f.height)*f.height;for(d=b.top+a.top;d<b.height+b.top;)e=Math.min(f.height,b.height+b.top-d),e=Math.floor(d+f.height)>e+d?e+d-d:f.height,d<b.top?(g=b.top-d,d=b.top):g=0,this.drawbackgroundRepeatX(c,f,a,b.left,d,b.width,e),g>0&&(a.top+=g),d=Math.floor(d+f.height)-g}else this.log("Error loading background:"+d)}};
-html2canvas.prototype.backgroundImageUrl=function(a){a.substr(0,5)=='url("'?(a=a.substr(5),a=a.substr(0,a.length-2)):(a=a.substr(4),a=a.substr(0,a.length-1));return a};
-html2canvas.prototype.getBackgroundPosition=function(a,b,c){var a=(this.getCSS(a,"backgroundPosition")||"0 0").split(" "),d,e;a.length==1&&(d=a,a=[],a[0]=d,a[1]=d);a[0].toString().indexOf("%")!=-1?(e=parseFloat(a[0])/100,d=b.width*e-c.width*e):d=parseInt(a[0],10);a[1].toString().indexOf("%")!=-1?(e=parseFloat(a[1])/100,b=b.height*e-c.height*e):b=parseInt(a[1],10);return{top:b,left:d}};
-html2canvas.prototype.drawbackgroundRepeatY=function(a,b,c,d,e,f,g){var k=Math.min(b.width,f),i;c.top-=Math.ceil(c.top/b.height)*b.height;for(i=e+c.top;i<g+e;)f=Math.floor(i+b.height)>g+e?g+e-i:b.height,this.drawBackgroundRepeat(a,b,d+c.left,i,k,f,d,e),i=Math.floor(i+b.height)};
-html2canvas.prototype.drawbackgroundRepeatX=function(a,b,c,d,e,f,g){var g=Math.min(b.height,g),k,i;c.left-=Math.ceil(c.left/b.width)*b.width;for(i=d+c.left;i<f+d;)k=Math.floor(i+b.width)>f+d?f+d-i:b.width,this.drawBackgroundRepeat(a,b,i,e+c.top,k,g,d,e),i=Math.floor(i+b.width)};html2canvas.prototype.drawBackgroundRepeat=function(a,b,c,d,e,f,g,k){var i=0,j=0;g-c>0&&(i=g-c);k-d>0&&(j=k-d);this.drawImage(a,b,i,j,e-i,f-j,c+i,d+j,e-i,f-j)};
-html2canvas.prototype.getBorderData=function(a){var b=[],c=this;this.each(["top","right","bottom","left"],function(d,e){b.push({width:parseInt(c.getCSS(a,"border-"+e+"-width"),10),color:c.getCSS(a,"border-"+e+"-color")})});return b};
-html2canvas.prototype.drawBorders=function(a,b,c,d,e,f){var g=this.getBorderData(a),k=this;this.each(g,function(a,j){if(j.width>0){var h=c,l=d,m=e,n=f-g[2].width;switch(a){case 0:n=g[0].width;break;case 1:h=c+e-g[1].width;m=g[1].width;break;case 2:l=l+f-g[2].width;n=g[2].width;break;case 3:m=g[3].width}k.newRect(b,h,l,m,n,j.color)}});return g};
-html2canvas.prototype.newElement=function(a,b){var c=this.getBounds(a),d=c.left,e=c.top,f=c.width,g=c.height,k=this.getCSS(a,"background-color"),b=b||{},i=this.formatZ(this.getCSS(a,"zIndex"),this.getCSS(a,"position"),b.zIndex,a.parentNode),j=this.getCSS(a,"opacity"),h={ctx:new this.storageContext,zIndex:i,opacity:j*b.opacity},i=this.contextStacks.push(h),j=this.contextStacks[i-1].ctx;this.setContextVariable(j,"globalAlpha",h.opacity);h=this.drawBorders(a,j,c.left,c.top,c.width,c.height);this.ignoreRe.test(a.nodeName)&&
-this.opts.iframeDefault!="transparent"&&(k=this.opts.iframeDefault=="default"?"#efefef":this.opts.iframeDefault);this.newRect(j,d+h[3].width,e+h[0].width,f-(h[1].width+h[3].width),g-(h[0].width+h[2].width),k);this.drawBackground(a,{left:d+h[3].width,top:e+h[0].width,width:f-(h[1].width+h[3].width),height:g-(h[0].width+h[2].width)},j);a.nodeName=="IMG"&&((f=this.loadImage(this.getAttr(a,"src")))?this.drawImage(j,f,0,0,f.width,f.height,d+parseInt(this.getCSS(a,"padding-left"),10)+h[3].width,e+parseInt(this.getCSS(a,
-"padding-top"),10)+h[0].width,c.width-(h[1].width+h[3].width+parseInt(this.getCSS(a,"padding-left"),10)+parseInt(this.getCSS(a,"padding-right"),10)),c.height-(h[0].width+h[2].width+parseInt(this.getCSS(a,"padding-top"),10)+parseInt(this.getCSS(a,"padding-bottom"),10))):this.log("Error loading <img>:"+this.getAttr(a,"src")));return this.contextStacks[i-1]};html2canvas.prototype.printText=function(a,b,c,d){this.trim(a).length>0&&(d.fillText(a,b,c),this.numDraws++)};
-html2canvas.prototype.newRect=function(a,b,c,d,e,f){f!="transparent"&&(this.setContextVariable(a,"fillStyle",f),a.fillRect(b,c,d,e),this.numDraws++)};html2canvas.prototype.drawImage=function(a,b,c,d,e,f,g,k,i,j){a.drawImage(b,c,d,e,f,g,k,i,j);this.numDraws++};
-html2canvas.prototype.getImages=function(a){var b=this;this.ignoreRe.test(a.nodeName)||this.each($(a).contents(),function(a,d){RegExp("("+this.ignoreElements+")").test(d.nodeName)||b.getImages(d)});if(a.nodeType==1||typeof a.nodeType=="undefined")(a=this.getCSS(a,"background-image"))&&a!="1"&&a!="none"&&a.substring(0,7)!="-webkit"&&a.substring(0,4)!="-moz"&&this.preloadImage(this.backgroundImageUrl(a))};
-html2canvas.prototype.loadImage=function(a){a=this.getIndex(this.images,a);return a!=-1?this.images[a+1]:!1};html2canvas.prototype.preloadImage=function(a){if(this.getIndex(this.images,a)==-1){this.images.push(a);var b=new Image,c=this;$(b).load(function(){c.imagesLoaded++;c.start()});b.onerror=function(){c.images.splice(c.images.indexOf(b.src),2);c.imagesLoaded++;c.start()};b.src=a;this.images.push(b)}};
-html2canvas.prototype.Renderer=function(a){var b=this;this.each(this.opts.renderOrder.split(" "),function(c,d){switch(d){case "canvas":if(b.canvas=document.createElement("canvas"),b.canvas.getContext)return b.canvasRenderer(a),!1}})};
-html2canvas.prototype.canvasRenderer=function(a){var b=this,a=this.sortQueue(a);this.canvas.width=$(document).width();this.canvas.height=$(document).height();this.ctx=this.canvas.getContext("2d");this.ctx.textBaseline="bottom";this.each(a,function(a,d){d.ctx.storage&&b.each(d.ctx.storage,function(a,c){switch(c.type){case "variable":b.ctx[c.name]=c.arguments;break;case "function":c.name=="fillRect"?b.ctx.fillRect(c.arguments[0],c.arguments[1],c.arguments[2],c.arguments[3]):c.name=="fillText"?b.ctx.fillText(c.arguments[0],
-c.arguments[1],c.arguments[2]):c.name=="drawImage"?b.ctx.drawImage(c.arguments[0],c.arguments[1],c.arguments[2],c.arguments[3],c.arguments[4],c.arguments[5],c.arguments[6],c.arguments[7],c.arguments[8]):this.log(c)}})})};
-html2canvas.prototype.sortQueue=function(a){if(!this.opts.reorderZ||!this.needReorder)return a;var b=0;this.each(a,function(a,c){if(b<c.zIndex.length)b=c.zIndex.length});var c=0;this.each(a,function(d,e){for(var f=a.length.toString().length-c.toString().length;b>e.zIndex.length;)e.zIndex+="0";for(e.zIndex+=c;b+f+c.toString().length>e.zIndex.length;)e.zIndex+="0";c++});return a=a.sort(function(a,b){return a.zIndex<b.zIndex?-1:a.zIndex>b.zIndex?1:0})};
-html2canvas.prototype.setContextVariable=function(a,b,c){a.storage?a.storage.push({type:"variable",name:b,arguments:c}):a[b]=c};
-html2canvas.prototype.newText=function(a,b,c){var d=this.getCSS(a,"font-family"),e=this.getCSS(a,"font-size"),f=this.getCSS(a,"color"),g=this.getCSS(a,"font-weight"),k=this.getCSS(a,"font-style"),i=this.getCSS(a,"font-variant"),j=this.getCSS(a,"text-decoration"),h=this.getCSS(a,"text-align"),l=this.getCSS(a,"letter-spacing");b.nodeValue=this.textTransform(b.nodeValue,this.getCSS(a,"text-transform"));if(this.trim(b.nodeValue).length>0){switch(g){case "401":g="bold"}if(j!="none")var m=this.fontMetrics(d,
-e);a=i+" "+g+" "+k+" "+e+" "+d;h=h.replace(["-webkit-auto"],["auto"]);h=this.opts.letterRendering==!1&&/^(left|right|justify|auto)$/.test(h)&&/^(normal|none)$/.test(l)?b.nodeValue.split(/(\b| )/):b.nodeValue.split("");this.setContextVariable(c,"fillStyle",f);this.setContextVariable(c,"font",a);for(l=0;l<h.length;l++){a=b.splitText(h[l].length);this.support.rangeBounds?(document.createRange?(d=document.createRange(),d.selectNode(b)):d=document.body.createTextRange(),d=d.getBoundingClientRect()?d.getBoundingClientRect():
-{}):(e=b.parentNode,g=document.createElement("wrapper"),k=b.cloneNode(!0),g.appendChild(b.cloneNode(!0)),e.replaceChild(g,b),d=this.getBounds(g),e.replaceChild(k,g));this.printText(b.nodeValue,d.left,d.bottom,c);switch(j){case "underline":this.newRect(c,d.left,Math.round(d.top+m.baseline+m.lineWidth),d.width,1,f);break;case "overline":this.newRect(c,d.left,d.top,d.width,1,f);break;case "line-through":this.newRect(c,d.left,Math.ceil(d.top+m.middle+m.lineWidth),d.width,1,f)}b=a}}};
-html2canvas.prototype.fontMetrics=function(a,b){var c=this.fontData.indexOf(a+"-"+b);if(c>-1)return this.fontData[c+1];c=document.createElement("div");document.getElementsByTagName("body")[0].appendChild(c);$(c).css({visibility:"hidden",fontFamily:a,fontSize:b,margin:0,padding:0});var d=document.createElement("img");d.src="http://html2canvas.hertzen.com/images/8.jpg";d.width=1;d.height=1;$(d).css({margin:0,padding:0});var e=document.createElement("span");$(e).css({fontFamily:a,fontSize:b,margin:0,
-padding:0});e.appendChild(document.createTextNode("Hidden Text"));c.appendChild(e);c.appendChild(d);var f=d.offsetTop-e.offsetTop+1;c.removeChild(e);c.appendChild(document.createTextNode("Hidden Text"));$(c).css("line-height","normal");$(d).css("vertical-align","super");d={baseline:f,lineWidth:1,middle:d.offsetTop-c.offsetTop+1};this.fontData.push(a+"-"+b);this.fontData.push(d);$(c).remove();return d};
-html2canvas.prototype.textTransform=function(a,b){switch(b){case "lowercase":return a.toLowerCase();case "capitalize":return a.replace(/(^|\s|:|-|\(|\))([a-z])/g,function(a,b,e){return b+e.toUpperCase()});case "uppercase":return a.toUpperCase();default:return a}};html2canvas.prototype.trim=function(a){return a.replace(/^\s*/,"").replace(/\s*$/,"")};html2canvas.prototype.parseElement=function(a,b){var c=this;this.each(a.children,function(a,e){c.parsing(e,b)});this.Renderer(this.contextStacks);this.finish()};
-html2canvas.prototype.parsing=function(a,b){if(this.getCSS(a,"display")!="none"&&this.getCSS(a,"visibility")!="hidden"){var c=this,b=this.newElement(a,b)||b,d=b.ctx;if(!this.ignoreRe.test(a.nodeName)){var e=this.contentsInZ(a);e.length==1?e[0].nodeType==1?this.parsing(e[0],b):e[0].nodeType==3&&this.newText(a,e[0],b.ctx):this.each(e,function(e,g){g.nodeType==1?c.parsing(g,b):g.nodeType==3&&c.newText(a,g,d)})}}};html2canvas.prototype.log=function(){};
-html2canvas.prototype.getBounds=function(a){window.scroll(0,0);if(a.getBoundingClientRect)return a=a.getBoundingClientRect(),a.top=a.top,a.left=a.left,a;else{var b=$(a).offset();return{left:b.left+parseInt(this.getCSS(a,"border-left-width"),10),top:b.top+parseInt(this.getCSS(a,"border-top-width"),10),width:$(a).innerWidth(),height:$(a).innerHeight()}}};html2canvas.prototype.each=function(a,b){for(var b=b||function(){},c=0;c<a.length;c++)if(b(c,a[c])===!1)break};html2canvas.prototype.contentsInZ=function(a){return $(a).contents()};
-html2canvas.prototype.getAttr=function(a,b){return a.getAttribute(b)};html2canvas.prototype.extendObj=function(a,b){for(var c in a)b[c]=a[c];return b};html2canvas.prototype.leadingZero=function(a,b){var c="000000000"+a;return c.substr(c.length-b)};
-html2canvas.prototype.formatZ=function(a,b,c,d){c||(c="0");if(b!="static"&&c.charAt(0)=="0")this.needReorder=!0,c="1"+c.slice(1);if(a=="auto")if(a=this.getCSS(d,"position"),a!="static"&&typeof a!="undefined")a=0;else return c;b=this.leadingZero(this.numDraws,9);a=this.leadingZero(a+1,9);return c+""+a+""+b};html2canvas.prototype.getContents=function(a){return a.nodeName=="iframe"?a.contentDocument||a.contentWindow.document:a.childNodes};html2canvas.prototype.getCSS=function(a,b){return $(a).css(b)};
-html2canvas.prototype.getIndex=function(a,b){if(a.indexOf)return a.indexOf(b);else{for(var c=0;c<a.length;c++)if(this[c]==b)return c;return-1}};
+html2canvas.prototype.drawBackground=function(a,b,d){var c=this.getCSS(a,"background-image"),e=this.getCSS(a,"background-repeat");if(typeof c!="undefined"&&/^(1|none)$/.test(c)==!1&&/^(-webkit|-moz|linear-gradient|-o-)/.test(c)==!1){var c=this.backgroundImageUrl(c),f=this.loadImage(c),a=this.getBackgroundPosition(a,b,f);if(f)switch(e){case "repeat-x":this.drawbackgroundRepeatX(d,f,a,b.left,b.top,b.width,b.height);break;case "repeat-y":this.drawbackgroundRepeatY(d,f,a,b.left,b.top,b.width,b.height);
+break;case "no-repeat":var c=b.width-a.left,e=b.height-a.top,g=a.left,j=a.top,h=a.left+b.left,k=a.top+b.top;g<0?(g=Math.abs(g),h+=g,c=Math.min(b.width,f.width-g)):(c=Math.min(c,f.width),g=0);j<0?(j=Math.abs(j),k+=j,e=Math.min(b.height,f.height-j)):(e=Math.min(e,f.height),j=0);if(e>0&&c>0){this.drawImage(d,f,g,j,c,e,h,k,c,e);break}default:a.top-=Math.ceil(a.top/f.height)*f.height;for(c=b.top+a.top;c<b.height+b.top;)e=Math.min(f.height,b.height+b.top-c),e=Math.floor(c+f.height)>e+c?e+c-c:f.height,c<
+b.top?(g=b.top-c,c=b.top):g=0,this.drawbackgroundRepeatX(d,f,a,b.left,c,b.width,e),g>0&&(a.top+=g),c=Math.floor(c+f.height)-g}else this.log("Error loading background:"+c)}};html2canvas.prototype.backgroundImageUrl=function(a){a.substr(0,5)=='url("'?(a=a.substr(5),a=a.substr(0,a.length-2)):(a=a.substr(4),a=a.substr(0,a.length-1));return a};
+html2canvas.prototype.getBackgroundPosition=function(a,b,d){var c=(this.getCSS(a,"backgroundPosition")||"0 0").split(" "),e;c.length==1&&(a=c,c=[],c[0]=a,c[1]=a);c[0].toString().indexOf("%")!=-1?(e=parseFloat(c[0])/100,a=b.width*e-d.width*e):a=parseInt(c[0],10);c[1].toString().indexOf("%")!=-1?(e=parseFloat(c[1])/100,b=b.height*e-d.height*e):b=parseInt(c[1],10);d={};d.top=b;d.left=a;return d};
+html2canvas.prototype.drawbackgroundRepeatY=function(a,b,d,c,e,f,g){var j=Math.min(b.width,f),h;d.top-=Math.ceil(d.top/b.height)*b.height;for(h=e+d.top;h<g+e;)f=Math.floor(h+b.height)>g+e?g+e-h:b.height,this.drawBackgroundRepeat(a,b,c+d.left,h,j,f,c,e),h=Math.floor(h+b.height)};
+html2canvas.prototype.drawbackgroundRepeatX=function(a,b,d,c,e,f,g){var g=Math.min(b.height,g),j,h;d.left-=Math.ceil(d.left/b.width)*b.width;for(h=c+d.left;h<f+c;)j=Math.floor(h+b.width)>f+c?f+c-h:b.width,this.drawBackgroundRepeat(a,b,h,e+d.top,j,g,c,e),h=Math.floor(h+b.width)};html2canvas.prototype.drawBackgroundRepeat=function(a,b,d,c,e,f,g,j){var h=0,k=0;g-d>0&&(h=g-d);j-c>0&&(k=j-c);this.drawImage(a,b,h,k,e-h,f-k,d+h,c+k,e-h,f-k)};
+html2canvas.prototype.getBorderData=function(a){var b=[],d=this;this.each(["top","right","bottom","left"],function(c,e){b.push({width:parseInt(d.getCSS(a,"border-"+e+"-width"),10),color:d.getCSS(a,"border-"+e+"-color")})});return b};
+html2canvas.prototype.drawBorders=function(a,b,d,c,e,f){var g=this.getBorderData(a),j=this;this.each(g,function(a,k){if(k.width>0){var i=d,l=c,m=e,n=f-g[2].width;switch(a){case 0:n=g[0].width;break;case 1:i=d+e-g[1].width;m=g[1].width;break;case 2:l=l+f-g[2].width;n=g[2].width;break;case 3:m=g[3].width}j.newRect(b,i,l,m,n,k.color)}});return g};
+html2canvas.prototype.newElement=function(a,b){var d=this.getBounds(a),c=d.left,e=d.top,f=d.width,g=d.height,j=this.getCSS(a,"background-color"),b=b||{},h=this.formatZ(this.getCSS(a,"zIndex"),this.getCSS(a,"position"),b.zIndex,a.parentNode),k=this.getCSS(a,"opacity"),i={ctx:new this.storageContext,zIndex:h,opacity:k*b.opacity},h=this.contextStacks.push(i),k=this.contextStacks[h-1].ctx;this.setContextVariable(k,"globalAlpha",i.opacity);i=this.drawBorders(a,k,d.left,d.top,d.width,d.height);this.ignoreRe.test(a.nodeName)&&
+this.opts.iframeDefault!="transparent"&&(j=this.opts.iframeDefault=="default"?"#efefef":this.opts.iframeDefault);this.newRect(k,c+i[3].width,e+i[0].width,f-(i[1].width+i[3].width),g-(i[0].width+i[2].width),j);this.drawBackground(a,{left:c+i[3].width,top:e+i[0].width,width:f-(i[1].width+i[3].width),height:g-(i[0].width+i[2].width)},k);a.nodeName=="IMG"&&((f=this.loadImage(this.getAttr(a,"src")))?this.drawImage(k,f,0,0,f.width,f.height,c+parseInt(this.getCSS(a,"padding-left"),10)+i[3].width,e+parseInt(this.getCSS(a,
+"padding-top"),10)+i[0].width,d.width-(i[1].width+i[3].width+parseInt(this.getCSS(a,"padding-left"),10)+parseInt(this.getCSS(a,"padding-right"),10)),d.height-(i[0].width+i[2].width+parseInt(this.getCSS(a,"padding-top"),10)+parseInt(this.getCSS(a,"padding-bottom"),10))):this.log("Error loading <img>:"+this.getAttr(a,"src")));return this.contextStacks[h-1]};html2canvas.prototype.printText=function(a,b,d,c){this.trim(a).length>0&&(c.fillText(a,b,d),this.numDraws++)};
+html2canvas.prototype.newRect=function(a,b,d,c,e,f){f!="transparent"&&(this.setContextVariable(a,"fillStyle",f),a.fillRect(b,d,c,e),this.numDraws++)};html2canvas.prototype.drawImage=function(a,b,d,c,e,f,g,j,h,k){a.drawImage(b,d,c,e,f,g,j,h,k);this.numDraws++};
+html2canvas.prototype.getImages=function(a){var b=this;this.ignoreRe.test(a.nodeName)||this.each($(a).contents(),function(a,c){RegExp("("+this.ignoreElements+")").test(c.nodeName)||b.getImages(c)});if(a.nodeType==1||typeof a.nodeType=="undefined")(a=this.getCSS(a,"background-image"))&&a!="1"&&a!="none"&&a.substring(0,7)!="-webkit"&&a.substring(0,3)!="-o-"&&a.substring(0,4)!="-moz"&&this.preloadImage(this.backgroundImageUrl(a))};
+html2canvas.prototype.loadImage=function(a){a=this.getIndex(this.images,a);return a!=-1?this.images[a+1]:!1};html2canvas.prototype.preloadImage=function(a){if(this.getIndex(this.images,a)==-1)if(this.isSameOrigin(a)){this.images.push(a);var b=new Image,d=this;$(b).load(function(){d.imagesLoaded++;d.start()});b.onerror=function(){d.images.splice(d.images.indexOf(b.src),2);d.start()};b.src=a;this.images.push(b)}else this.opts.proxyUrl&&(this.images.push(a),b=new Image,this.proxyGetImage(a,b),this.images.push(b))};
+html2canvas.prototype.proxyGetImage=function(a,b){var d=this,c=document.createElement("a");c.href=a;a=c.href;$.ajax({data:{xhr2:!1,url:a},url:this.opts.proxyUrl,dataType:"jsonp",success:function(c){c.substring(0,6)=="error:"?(d.images.splice(d.images.indexOf(a),2),d.start(),d.log("Proxy was unable to load "+a+" "+c)):(b.onload=function(){d.imagesLoaded++;d.start()},b.src=c)},error:function(){d.images.splice(d.images.indexOf(a),2);d.start()}})};
+html2canvas.prototype.Renderer=function(a){var b=this;this.log("Renderer initiated");this.each(this.opts.renderOrder.split(" "),function(d,c){switch(c){case "canvas":b.canvas=document.createElement("canvas");if(b.canvas.getContext)return b.canvasRenderer(a),b.log("Using canvas renderer"),!1;break;case "html":return b.log("Using HTML renderer"),!1}});return this};html2canvas.prototype.throttler=function(){};
+html2canvas.prototype.canvasRenderer=function(a){var b=this,a=this.sortQueue(a);this.canvas.width=Math.max($(document).width(),this.opts.canvasWidth);this.canvas.height=Math.max($(document).height(),this.opts.canvasHeight);this.ctx=this.canvas.getContext("2d");this.ctx.textBaseline="bottom";this.each(a,function(a,c){c.ctx.storage&&b.each(c.ctx.storage,function(a,c){switch(c.type){case "variable":b.ctx[c.name]=c.arguments;break;case "function":c.name=="fillRect"?b.ctx.fillRect(c.arguments[0],c.arguments[1],
+c.arguments[2],c.arguments[3]):c.name=="fillText"?b.ctx.fillText(c.arguments[0],c.arguments[1],c.arguments[2]):c.name=="drawImage"?c.arguments[8]>0&&c.arguments[7]&&b.ctx.drawImage(c.arguments[0],c.arguments[1],c.arguments[2],c.arguments[3],c.arguments[4],c.arguments[5],c.arguments[6],c.arguments[7],c.arguments[8]):this.log(c)}})})};
+html2canvas.prototype.sortQueue=function(a){if(!this.opts.reorderZ||!this.needReorder)return a;var b=0;this.each(a,function(a,d){if(b<d.zIndex.length)b=d.zIndex.length});var d=0;this.each(a,function(c,e){for(var f=a.length.toString().length-d.toString().length;b>e.zIndex.length;)e.zIndex+="0";for(e.zIndex+=d;b+f+d.toString().length>e.zIndex.length;)e.zIndex+="0";d++});return a=a.sort(function(a,b){return a.zIndex<b.zIndex?-1:a.zIndex>b.zIndex?1:0})};
+html2canvas.prototype.setContextVariable=function(a,b,d){a.storage?a.storage.push({type:"variable",name:b,arguments:d}):a[b]=d};
+html2canvas.prototype.newText=function(a,b,d){var c=this.getCSS(a,"font-family"),e=this.getCSS(a,"font-size"),f=this.getCSS(a,"color"),g=this.getCSS(a,"font-weight"),j=this.getCSS(a,"font-style"),h=this.getCSS(a,"font-variant"),k=this.getCSS(a,"text-decoration"),i=this.getCSS(a,"text-align"),l=this.getCSS(a,"letter-spacing");b.nodeValue=this.textTransform(b.nodeValue,this.getCSS(a,"text-transform"));if(this.trim(b.nodeValue).length>0){switch(g){case 401:g="bold";break;case 400:g="normal"}if(k!="none")var m=
+this.fontMetrics(c,e);a=h+" "+g+" "+j+" "+e+" "+c;i=i.replace(["-webkit-auto"],["auto"]);i=this.opts.letterRendering==!1&&/^(left|right|justify|auto)$/.test(i)&&/^(normal|none)$/.test(l)?b.nodeValue.split(/(\b| )/):b.nodeValue.split("");this.setContextVariable(d,"fillStyle",f);this.setContextVariable(d,"font",a);for(l=0;l<i.length;l++){a=b.splitText(i[l].length);this.support.rangeBounds?(document.createRange?(c=document.createRange(),c.selectNode(b)):c=document.body.createTextRange(),c=c.getBoundingClientRect()?
+c.getBoundingClientRect():{}):(e=b.parentNode,g=document.createElement("wrapper"),j=b.cloneNode(!0),g.appendChild(b.cloneNode(!0)),e.replaceChild(g,b),c=this.getBounds(g),e.replaceChild(j,g));this.printText(b.nodeValue,c.left,c.bottom,d);switch(k){case "underline":this.newRect(d,c.left,Math.round(c.top+m.baseline+m.lineWidth),c.width,1,f);break;case "overline":this.newRect(d,c.left,c.top,c.width,1,f);break;case "line-through":this.newRect(d,c.left,Math.ceil(c.top+m.middle+m.lineWidth),c.width,1,f)}b=
+a}}};
+html2canvas.prototype.fontMetrics=function(a,b){var d=this.fontData.indexOf(a+"-"+b);if(d>-1)return this.fontData[d+1];d=document.createElement("div");document.getElementsByTagName("body")[0].appendChild(d);$(d).css({visibility:"hidden",fontFamily:a,fontSize:b,margin:0,padding:0});var c=document.createElement("img");c.src="http://html2canvas.hertzen.com/images/8.jpg";c.width=1;c.height=1;$(c).css({margin:0,padding:0});var e=document.createElement("span");$(e).css({fontFamily:a,fontSize:b,margin:0,padding:0});
+e.appendChild(document.createTextNode("Hidden Text"));d.appendChild(e);d.appendChild(c);var f=c.offsetTop-e.offsetTop+1;d.removeChild(e);d.appendChild(document.createTextNode("Hidden Text"));$(d).css("line-height","normal");$(c).css("vertical-align","super");c={baseline:f,lineWidth:1,middle:c.offsetTop-d.offsetTop+1};this.fontData.push(a+"-"+b);this.fontData.push(c);$(d).remove();return c};
+html2canvas.prototype.textTransform=function(a,b){switch(b){case "lowercase":return a.toLowerCase();case "capitalize":return a.replace(/(^|\s|:|-|\(|\))([a-z])/g,function(a,b,e){return b+e.toUpperCase()});case "uppercase":return a.toUpperCase();default:return a}};html2canvas.prototype.trim=function(a){return a.replace(/^\s*/,"").replace(/\s*$/,"")};
+html2canvas.prototype.parseElement=function(a,b){var d=this;this.each(a.children,function(a,e){d.parsing(e,b)});this.log("Render queue stored");this.opts.storageReady(this);this.finish()};
+html2canvas.prototype.parsing=function(a,b){if(this.getCSS(a,"display")!="none"&&this.getCSS(a,"visibility")!="hidden"){var d=this,b=this.newElement(a,b)||b,c=b.ctx;if(!this.ignoreRe.test(a.nodeName)){var e=this.contentsInZ(a);e.length==1?e[0].nodeType==1?this.parsing(e[0],b):e[0].nodeType==3&&this.newText(a,e[0],b.ctx):this.each(e,function(e,g){g.nodeType==1?d.parsing(g,b):g.nodeType==3&&d.newText(a,g,c)})}}};html2canvas.prototype.log=function(a){this.opts.logging&&this.opts.logger(a)};
+html2canvas.prototype.getBounds=function(a){window.scroll(0,0);if(a.getBoundingClientRect)return a=a.getBoundingClientRect(),a.top=a.top,a.left=a.left,a;else{var b=$(a).offset();return{left:b.left+parseInt(this.getCSS(a,"border-left-width"),10),top:b.top+parseInt(this.getCSS(a,"border-top-width"),10),width:$(a).innerWidth(),height:$(a).innerHeight()}}};html2canvas.prototype.each=function(a,b){for(var b=b||function(){},d=0;d<a.length;d++)if(b(d,a[d])===!1)break};html2canvas.prototype.contentsInZ=function(a){return $(a).contents()};
+html2canvas.prototype.getAttr=function(a,b){return a.getAttribute(b)};html2canvas.prototype.extendObj=function(a,b){for(var d in a)b[d]=a[d];return b};html2canvas.prototype.leadingZero=function(a,b){var d="000000000"+a;return d.substr(d.length-b)};
+html2canvas.prototype.formatZ=function(a,b,d,c){d||(d="0");if(b!="static"&&d.charAt(0)=="0")this.needReorder=!0,d="1"+d.slice(1);if(a=="auto")if(a=this.getCSS(c,"position"),a!="static"&&typeof a!="undefined")a=0;else return d;b=this.leadingZero(this.numDraws,9);a=this.leadingZero(a+1,9);return d+""+a+""+b};html2canvas.prototype.getContents=function(a){return a.nodeName=="iframe"?a.contentDocument||a.contentWindow.document:a.childNodes};html2canvas.prototype.getCSS=function(a,b){return $(a).css(b)};
+html2canvas.prototype.getIndex=function(a,b){if(a.indexOf)return a.indexOf(b);else{for(var d=0;d<a.length;d++)if(this[d]==b)return d;return-1}};html2canvas.prototype.isSameOrigin=function(a){var b=document.createElement("a");b.href=a;return b.protocol+b.hostname==this.pageOrigin};
diff --git a/build/jquery.plugin.html2canvas.js b/build/jquery.plugin.html2canvas.js
index 86de74f..f20581a 100644
--- a/build/jquery.plugin.html2canvas.js
+++ b/build/jquery.plugin.html2canvas.js
@@ -1,5 +1,5 @@
 /* 
- * html2canvas v0.20 <http://html2canvas.hertzen.com>
+ * html2canvas v0.25 <http://html2canvas.hertzen.com>
  * Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
  * http://www.twitter.com/niklasvh 
  * 
@@ -34,15 +34,16 @@
  */
 			
 (function( $ ){
-    $.fn.html2canvas = function() {
+    $.fn.html2canvas = function(options) {
   
         var date = new Date();
         var message,
         timeoutTimer,
         timer = date.getTime();
         
-        new html2canvas(this.get(0), {
-            logging: true,
+        var object = $.extend({},{
+            logging: false,
+            proxyUrl: "http://html2canvas.appspot.com/", // running html2canvas-python proxy
             ready: function(renderer) {
                 
                 var finishTime = new Date();
@@ -79,7 +80,9 @@
                 });
             }
             
-        });
+        },options)
+        
+        new html2canvas(this.get(0), object);
         
         
         function throwMessage(msg,duration){
diff --git a/loading.gif b/loading.gif
new file mode 100644
index 0000000..7eca290
Binary files /dev/null and b/loading.gif differ
diff --git a/readme.md b/readme.md
index a4d446e..ebc541c 100644
--- a/readme.md
+++ b/readme.md
@@ -33,4 +33,4 @@ There are still a lot of CSS properties missing, including most CSS3 properties
 
 ### Examples ###
 
-For more information and examples, please visit the <a href="http://html2canvas.hertzen.com">homepage</a>.
\ No newline at end of file
+For more information and examples, please visit the <a href="http://html2canvas.hertzen.com">homepage</a> or try the <a href="http://html2canvas.hertzen.com/screenshots.html">test console</a>.
\ No newline at end of file
diff --git a/screenshots.html b/screenshots.html
new file mode 100644
index 0000000..7bca272
--- /dev/null
+++ b/screenshots.html
@@ -0,0 +1,304 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>JavaScript screenshot creator</title>
+
+        <style type="text/css">
+            a {
+color: #0B0B0B;
+background-color: #FDF9EE;
+padding: 0 8px;
+text-decoration: none;
+font: normal 12px/16px "Trebuchet MS", Arial, Helvetica, sans-serif;
+}
+
+a:hover {
+color: #0B0B0B;
+background-color: #EFEBDE;
+padding: 0 8px;
+text-decoration: none;
+font: normal 12px/16px "Trebuchet MS", Arial, Helvetica, sans-serif;
+}
+            body {
+font: normal 14px/19px Arial, Helvetica, sans-serif;
+background-color: white;
+color: #4E4628;
+}
+            
+            textarea {
+background-color: #EFEBDE;
+color: #0B0B0B;
+border: #C3BCA4 1px solid;
+
+
+
+
+font: normal 11px Arial, Helvetica, sans-serif;
+width:500px;
+height:150px;
+}
+
+h2 {
+background-color: white;
+color: #0B0B0B;
+font: normal 28px/46px Georgia, "Times New Roman", Times, serif;
+margin:0;
+clear:both;
+}
+
+h3 {
+
+color: #786E4E;
+padding: 0 0 10px 55px;
+
+
+height: 37px;
+font: normal 24px/30px Georgia, "Times New Roman", Times, serif;
+}
+ul{
+    float:left;
+    margin:0;
+
+}
+
+table{
+    margin:0 auto;
+    width:400px;
+    border:1px solid black;
+}
+#content{
+    clear:both;
+    text-align:center;
+}
+
+#about{
+    padding:0 10px;
+   width:450px;
+    float:left;
+}
+            
+            </style>
+
+        <script type="text/javascript" src="external/jquery-1.6.2.min.js"></script>
+        <script type="text/javascript" src="build/html2canvas.js?22"></script>
+        <script type="text/javascript" src="build/jquery.plugin.html2canvas.js"></script>
+        <script type="text/javascript"> 
+            
+            var date = new Date();
+            var message,
+            timeoutTimer,
+            timer;
+            
+            function addRow(table,field,val){
+               var tr = $('<tr />').appendTo( $(table));
+               
+               tr.append($('<td />').css('font-weight','bold').text(field)).append($('<td />').text(val));
+                
+                
+                
+            }
+            
+            function throwMessage(msg,duration){
+            
+                window.clearTimeout(timeoutTimer);
+                timeoutTimer = window.setTimeout(function(){
+                    message.fadeOut(function(){
+                        message.remove();   
+                    });                   
+                },duration || 2000);
+                $(message).remove();
+                message = $('<div />').html(msg).css({
+                    margin:0,
+                    padding:10,
+                    background: "#000",
+                    opacity:0.7,
+                    position:"fixed",
+                    top:10,
+                    right:10,
+                    fontFamily: 'Tahoma' ,
+                    color:'#fff',
+                    fontSize:12,
+                    borderRadius:12,
+                    width:'auto',
+                    height:'auto',
+                    textAlign:'center',
+                    textDecoration:'none'
+                }).hide().fadeIn().appendTo('body');
+            }
+            
+            $(function(){
+                
+                $('ul li a').click(function(e){
+                    e.preventDefault();
+                    $('#url').val(this.href);
+                    $('button').click();                  
+                })
+                
+                var iframe,d;
+                
+                
+
+                
+                $('input[type="button"]').click(function(){
+                    $(iframe.contentWindow).unbind('load');
+                    $(iframe).contents().find('body').html2canvas({
+                        canvasHeight: d.body.scrollHeight,
+                        canvasWidth: d.body.scrollWidth,
+                        logging:true
+                                            
+                    });             
+                    
+                });
+                
+                $('button').click(function(){
+                    
+                    $(this).prop('disabled',true);
+                    var url = $('#url').val();
+                    $('#content').append($('<img />').attr('src','loading.gif').css('margin-top',40));
+                    
+                    var urlParts = document.createElement('a');
+                    urlParts.href = url;
+                    
+                    $.ajax({
+                        data: {
+                            xhr2:false,
+                            url:urlParts.href
+                            
+                        },
+                        url: "http://html2canvas.appspot.com",
+                        dataType: "jsonp",
+                        success: function(html){
+                            
+                            
+                            iframe = document.createElement('iframe');
+                            $(iframe).css({
+                                'visibility':'hidden'
+                            }).width($(window).width()).height($(window).height());
+                            $('#content').append(iframe);
+                            d = iframe.contentWindow.document; 
+                           
+                            d.open();
+                            
+                            $(iframe.contentWindow).load(function(){
+
+                                timer = date.getTime();
+                                
+                                $(iframe).contents().find('body').html2canvas({
+                                    canvasHeight: d.body.scrollHeight,
+                                    canvasWidth: d.body.scrollWidth,
+                                    logging:true,
+                                    logger:function(msg){
+                                      $('#logger').val(function(e,i){
+                                          return i+"\n"+msg;
+                                      });
+                                        
+                                    },
+                                    ready: function(renderer) {
+                                        $("#content").empty();               
+                                        var finishTime = new Date();
+                      
+                                          var table = $('<table />');  
+                                        $('#content')
+                                        .append('<h2>Screenshot</h2>')
+                                        .append(renderer.canvas)
+                                        .append('<h3>Details</h3>')
+                                        .append(table);
+                                        
+                                        
+                                        
+                                         addRow(table,"Creation time",((finishTime.getTime()-timer)/1000) + " seconds");
+                                         addRow(table,"Total draws", renderer.numDraws);
+                                         addRow(table,"Context stacks", renderer.contextStacks.length);
+                                         addRow(table,"Loaded images", renderer.images.length/2);
+                                         addRow(table,"Performed z-index reorder", renderer.needReorder);
+                                          addRow(table,"Used rangeBounds", renderer.support.rangeBounds);
+                              
+
+
+                                        throwMessage('Screenshot created in '+ ((finishTime.getTime()-timer)/1000) + " seconds<br />Total of "+renderer.numDraws+" draws performed",4000);
+                
+                
+                                 
+                                    }
+                                            
+                                });
+
+                            });
+
+                            $('base').attr('href',urlParts.protocol+"//"+urlParts.hostname+"/");
+                            html = html.replace("<head>","<head><base href='"+urlParts.protocol+"//"+urlParts.hostname+"/' />");
+
+                            d.write(html);
+
+                            d.close();
+                         
+                        }
+        
+        
+                    });
+                    
+
+                });
+                   
+               
+                    
+          
+            
+            });        
+        </script> 
+        <base />
+    </head>
+    <body>
+        <div style="float:left;width:500px;">
+        <h1>JavaScript screenshot creator</h1>
+        <label for="url">Website URL:</label>
+        <input type="url" id="url" value="http://www.yahoo.com" /><button>Get screenshot!</button>
+        <!-- <input type="button" value="Try anyway" />--><br />
+        
+        <small>Tested with Google Chrome 12, Firefox 4 and Opera 12</small>
+        </div>
+        <div style="float:right;">
+                                       <div style="margin-left:17px;float:right;"> 
+                                    <!-- Place this tag in your head or just before your close body tag --> 
+                                    <script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script> 
+ 
+                                    <!-- Place this tag where you want the +1 button to render --> 
+                                    <g:plusone size="tall"></g:plusone> 
+                                </div> 
+ 
+                                <div style="float:right;"> 
+ 
+                                    <a href="http://twitter.com/share" class="twitter-share-button" data-url="http://html2canvas.hertzen.com/" data-text="html2canvas - screenshots with #JavaScript" data-count="vertical" data-via="niklasvh">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script> 
+                                </div> 
+        </div>
+        
+        
+        <div style="clear:both;"></div>
+        <h3>Recommended (tested) pages:</h3>
+        
+        <ul>
+            
+            <li><a href="http://www.yahoo.com">yahoo.com</a></li>
+            <li><a href="http://www.google.com">google.com</a></li>
+            <li><a href="https://github.com/niklasvh/html2canvas">github.com</a></li>
+            <li><a href="http://www.smashingmagazine.com">smashingmagazine.com</a></li>
+            <li><a href="http://www.cnn.com">cnn.com</a></li>           
+            <li><a href="http://www.facebook.com/google">facebook.com/google</a></li>
+            <li><a href="http://www.youtube.com/">youtube.com</a></li>
+
+
+            <li><a href="http://eu.battle.net/en/">battle.net</a></li>
+
+
+        </ul>
+        <div style="float:left;">
+        <textarea id="logger"></textarea>
+        </div>
+        <div id="about"><b> About</b><br />
+            The whole screenshot is created with JavaScript. The only server interaction that is happening on this page is the proxy for loading the external pages/images into JSONP/CORS enabled page and onwards onto the JavaScript renderer script.
+            There are a lot of problems of loading external pages, even with a proxy, and as such many pages will not render at all. If you wish to try the script properly, I recommend you get a copy of the source from <a href="https://github.com/niklasvh/html2canvas">here</a> instead.
+        </div>
+        <div id="content"></div>
+
+    </body>
+</html>
diff --git a/src/Background.js b/src/Background.js
index 62044f8..9c0344b 100644
--- a/src/Background.js
+++ b/src/Background.js
@@ -6,8 +6,8 @@ html2canvas.prototype.drawBackground = function(el,bounds,ctx){
     var background_image = this.getCSS(el,"background-image");
     var background_repeat = this.getCSS(el,"background-repeat");
         
-    if (typeof background_image != "undefined" && /^(1|none)$/.test(background_image)==false){
-            
+    if (typeof background_image != "undefined" && /^(1|none)$/.test(background_image)==false && /^(-webkit|-moz|linear-gradient|-o-)/.test(background_image)==false){
+         
         background_image = this.backgroundImageUrl(background_image);
         var image = this.loadImage(background_image);
 					
@@ -15,7 +15,6 @@ html2canvas.prototype.drawBackground = function(el,bounds,ctx){
         var bgp = this.getBackgroundPosition(el,bounds,image),
         bgy;
 
-
         if (image){
             switch(background_repeat){
 					
@@ -28,10 +27,70 @@ html2canvas.prototype.drawBackground = function(el,bounds,ctx){
                     break;
                           
                 case "no-repeat":
-                        
-                    this.drawBackgroundRepeat(ctx,image,bgp.left+bounds.left,bgp.top+bounds.top,Math.min(bounds.width,image.width),Math.min(bounds.height,image.height),bounds.left,bounds.top);
-                    // ctx.drawImage(image,(bounds.left+bgp.left),(bounds.top+bgp.top));	                      
-                    break;
+                    /*
+                    this.drawBackgroundRepeat(
+                        ctx,
+                        image,
+                        bgp.left+bounds.left, // sx
+                        bgp.top+bounds.top, // sy
+                        Math.min(bounds.width,image.width),
+                        Math.min(bounds.height,image.height),
+                        bounds.left,
+                        bounds.top
+                        );*/
+                            
+      
+                    // console.log($(el).css('background-image'));
+                    var bgw = bounds.width-bgp.left,
+                    bgh = bounds.height-bgp.top,
+                    bgsx = bgp.left,
+                    bgsy = bgp.top,
+                    bgdx = bgp.left+bounds.left,
+                    bgdy = bgp.top+bounds.top;
+
+                    //
+                    //     bgw = Math.min(bgw,image.width);
+                    //  bgh = Math.min(bgh,image.height);     
+                    
+                    if (bgsx<0){
+                        bgsx = Math.abs(bgsx);
+                        bgdx += bgsx; 
+                        bgw = Math.min(bounds.width,image.width-bgsx);
+                    }else{
+                        bgw = Math.min(bgw,image.width);
+                        bgsx = 0;
+                    }
+                           
+                    if (bgsy<0){
+                        bgsy = Math.abs(bgsy);
+                        bgdy += bgsy; 
+                        // bgh = bgh-bgsy;
+                        bgh = Math.min(bounds.height,image.height-bgsy);
+                    }else{
+                        bgh = Math.min(bgh,image.height); 
+                        bgsy = 0;
+                    }    
+    
+                  
+                    //   bgh = Math.abs(bgh);
+                    //   bgw = Math.abs(bgw);
+                    if (bgh>0 && bgw > 0){        
+                        this.drawImage(
+                            ctx,
+                            image,
+                            bgsx, // source X : 0 
+                            bgsy, // source Y : 1695
+                            bgw, // source Width : 18
+                            bgh, // source Height : 1677
+                            bgdx, // destination X :906
+                            bgdy, // destination Y : 1020
+                            bgw, // destination width : 18
+                            bgh // destination height : 1677
+                            );
+                            
+                        // ctx.drawImage(image,(bounds.left+bgp.left),(bounds.top+bgp.top));	                      
+                        break;
+                    }
                         
                 default:
                     var height,
@@ -96,6 +155,8 @@ html2canvas.prototype.backgroundImageUrl = function(src){
         src = src.substr(4);
         src = src.substr(0,src.length-1);  
     }
+    
+    
     return src;            
 }
     
@@ -106,8 +167,9 @@ html2canvas.prototype.backgroundImageUrl = function(src){
     
 html2canvas.prototype.getBackgroundPosition = function(el,bounds,image){
     var bgpos = this.getCSS(el,"backgroundPosition") || "0 0";
+   // var bgpos = $(el).css("backgroundPosition") || "0 0";
     var bgposition = bgpos.split(" "),
-    top,
+    topPos,
     left,
     percentage;
 
@@ -119,6 +181,8 @@ html2canvas.prototype.getBackgroundPosition = function(el,bounds,image){
         bgposition[1] = val;
     }  
 
+    
+
     if (bgposition[0].toString().indexOf("%")!=-1){   
    
         percentage = (parseFloat(bgposition[0])/100);        
@@ -131,15 +195,29 @@ html2canvas.prototype.getBackgroundPosition = function(el,bounds,image){
     if (bgposition[1].toString().indexOf("%")!=-1){  
 
         percentage = (parseFloat(bgposition[1])/100);     
-        top =  ((bounds.height * percentage)-(image.height*percentage));
+        topPos =  ((bounds.height * percentage)-(image.height*percentage));
     }else{
-        top = parseInt(bgposition[1],10);
+        
+        topPos = parseInt(bgposition[1],10);
+        
     }
+    
+
+    
+    
+    var returnObj = {}
+    /*
+        "top": topPos,
+        "left": left
+    };*/
+    
+
+    returnObj.top = topPos;
+    returnObj.left = left;
+    
+
           
-    return {
-        top: top,
-        left: left
-    };
+    return returnObj;
          
 }
 
diff --git a/src/Core.js b/src/Core.js
index 7cb41c5..f564808 100644
--- a/src/Core.js
+++ b/src/Core.js
@@ -22,9 +22,19 @@ function html2canvas(el, userOptions) {
         reorderZ: true,
         throttle:true,
         letterRendering:false,
+        proxyUrl: null,
+        logger: function(a){
+            if (window.console && window.console.log){
+                window.console.log(a);     
+            }else{
+                alert(a);
+            }
+        },
+        canvasWidth:0,
+        canvasHeight:0,
         renderOrder: "canvas flash html"
     });
-    
+
     this.element = el;
     
     var imageLoaded,
@@ -41,6 +51,7 @@ function html2canvas(el, userOptions) {
     this.ignoreElements = "IFRAME|OBJECT|PARAM";
     this.needReorder = false;
     this.blockElements = new RegExp("(BR|PARAM)");
+    this.pageOrigin = window.location.protocol + window.location.hostname;
 
     this.ignoreRe = new RegExp("("+this.ignoreElements+")");
     
@@ -102,16 +113,22 @@ html2canvas.prototype.init = function(){
        
     this.canvas = this.ctx.canvas;
         */
-    this.log('Finding background images');
+    this.log('Finding background-images');
         
+    this.images.push('start');
+    
     this.getImages(this.element);
             
     this.log('Finding images');
-    this.each(document.images,function(i,e){
+    // console.log(this.element.ownerDocument);
+   
+    
+   
+    this.each(this.element.ownerDocument.images,function(i,e){
         _.preloadImage(_.getAttr(e,'src'));
     });
-      
-        
+    this.images.splice(0,1);  
+    //  console.log(this.images);   
     if (this.images.length == 0){
         this.start();
     }  
@@ -124,9 +141,10 @@ html2canvas.prototype.init = function(){
  */
  
 html2canvas.prototype.start = function(){
-          
+    //     console.log(this.images);
     if (this.images.length == 0 || this.imagesLoaded==this.images.length/2){    
-        this.log('Started parsing');
+        
+        this.log('Finished loading '+this.imagesLoaded+' images, Started parsing');
         this.bodyOverflow = document.getElementsByTagName('body')[0].style.overflow;
         document.getElementsByTagName('body')[0].style.overflow = "hidden";
         var rootStack = new this.storageContext($(document).width(),$(document).height());  
diff --git a/src/Draw.js b/src/Draw.js
index 613e9fb..39f72a1 100644
--- a/src/Draw.js
+++ b/src/Draw.js
@@ -72,7 +72,7 @@ html2canvas.prototype.newElement = function(el,parentStack){
     if (el.nodeName=="IMG"){
         image = _.loadImage(_.getAttr(el,'src'));
         if (image){
-            
+          //   console.log(image.width);
             this.drawImage(
                 ctx,
                 image,
@@ -86,7 +86,7 @@ html2canvas.prototype.newElement = function(el,parentStack){
                 bounds.height - (borders[0].width + borders[2].width + parseInt(_.getCSS(el,'padding-top'),10) + parseInt(_.getCSS(el,'padding-bottom'),10)) //dh       
                 );
            
-        }else{
+        }else {
             this.log("Error loading <img>:" + _.getAttr(el,'src'));
         }
     }
diff --git a/src/Images.js b/src/Images.js
index 2aee524..83a8206 100644
--- a/src/Images.js
+++ b/src/Images.js
@@ -18,7 +18,8 @@ html2canvas.prototype.getImages = function(el) {
     if (el.nodeType==1 || typeof el.nodeType == "undefined"){
         var background_image = this.getCSS(el,'background-image');
            
-        if (background_image && background_image != "1" && background_image != "none" && background_image.substring(0,7)!="-webkit" && background_image.substring(0,4)!="-moz"){
+        if (background_image && background_image != "1" && background_image != "none" && background_image.substring(0,7)!="-webkit" && background_image.substring(0,3)!="-o-" && background_image.substring(0,4)!="-moz"){
+            
             var src = this.backgroundImageUrl(background_image);                    
             this.preloadImage(src);                    
         }
@@ -49,25 +50,80 @@ html2canvas.prototype.preloadImage = function(src){
 
 
     if (this.getIndex(this.images,src)==-1){
-        this.images.push(src);
-                   
-        var img = new Image();   
-        // TODO remove jQuery dependancy
-        var _ = this;
-        $(img).load(function(){
-            _.imagesLoaded++;               
-            _.start();        
+        if (this.isSameOrigin(src)){
+            this.images.push(src);
+            //     console.log('a'+src);
+            var img = new Image();   
+            // TODO remove jQuery dependancy
+            var _ = this;
+            $(img).load(function(){
+                _.imagesLoaded++;               
+                _.start();        
                 
-        });	
-        img.onerror = function(){
-            _.images.splice(_.images.indexOf(img.src),2);
-            _.imagesLoaded++;
-            _.start();                           
+            });	
+            img.onerror = function(){
+                _.images.splice(_.images.indexOf(img.src),2);
+                //  _.imagesLoaded++;
+                _.start();                           
+            }
+            img.src = src; 
+            this.images.push(img);
+        }else if (this.opts.proxyUrl){
+            //    console.log('b'+src);
+            this.images.push(src);
+            var img = new Image();   
+            this.proxyGetImage(src,img);
+            this.images.push(img);
         }
-        img.src = src; 
-        this.images.push(img);
-                  
     }     
           
 }
-    
\ No newline at end of file
+
+html2canvas.prototype.proxyGetImage = function(url,img){
+    var _ = this;
+    
+    var link = document.createElement("a");
+    link.href = url;
+    url = link.href; // work around for pages with base href="" set
+
+    
+    // todo remove jQuery dependency and enable xhr2 requests where available (no need for base64 / json)
+    $.ajax({
+        data:{
+            xhr2:false,
+            url:url
+        },
+        url: this.opts.proxyUrl,
+        dataType: "jsonp",
+        success: function(a){
+            
+            if (a.substring(0,6)=="error:"){
+                _.images.splice(_.images.indexOf(url),2);
+                _.start();  
+                _.log('Proxy was unable to load '+url+' '+a);
+            }else{
+                // document.createElement(a);
+                // console.log(img);
+                img.onload = function(){
+                    //   console.log('w'+img.width);
+                    _.imagesLoaded++;               
+                    _.start();   
+               
+                }
+            
+                img.src = a; 
+            }
+
+
+        },
+        error: function(){
+           
+            _.images.splice(_.images.indexOf(url),2);
+            //  _.imagesLoaded++;
+            _.start();          
+        }
+        
+        
+    });
+    
+}
\ No newline at end of file
diff --git a/src/LICENSE b/src/LICENSE
index 3f8d405..4161c97 100644
--- a/src/LICENSE
+++ b/src/LICENSE
@@ -1,5 +1,5 @@
 /* 
- * html2canvas v0.20 <http://html2canvas.hertzen.com>
+ * html2canvas v0.25 <http://html2canvas.hertzen.com>
  * Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
  * http://www.twitter.com/niklasvh 
  * 
diff --git a/src/Renderer.js b/src/Renderer.js
index b3d562e..9c9057a 100644
--- a/src/Renderer.js
+++ b/src/Renderer.js
@@ -23,25 +23,26 @@ html2canvas.prototype.Renderer = function(queue){
                 var s = document.getElementsByTagName('script')[0]; 
                 s.parentNode.insertBefore(script, s);
                         
-                   */      
+                    
                 if (typeof FlashCanvas != "undefined") {  
                     _.canvas = initCanvas(document.getElementById("testflash"));
                     FlashCanvas.initElement(_.canvas);
                     _.ctx = _.canvas.getContext("2d");
-                   // _.canvas = document.createElement('canvas');
+                    // _.canvas = document.createElement('canvas');
                     //
                     _.log('Using Flashcanvas renderer');
                     _.canvasRenderer(queue);
                     
                     return false;
                 }  
+                     */    
                 
                 break;
-                case "html":
-                    // TODO add renderer
-                    _log("Using HTML renderer");
-                    return false;
-                    break;
+            case "html":
+                // TODO add renderer
+                _.log("Using HTML renderer");
+                return false;
+                break;
              
              
         }
@@ -50,7 +51,7 @@ html2canvas.prototype.Renderer = function(queue){
          
     });
     
-    this.log('No renderer chosen, rendering quit');
+//    this.log('No renderer chosen, rendering quit');
     return this;
      
 // this.canvasRenderer(queue);
@@ -77,6 +78,11 @@ html2canvas.prototype.Renderer = function(queue){
 }
 
 
+html2canvas.prototype.throttler = function(queue){
+    
+    
+    };
+
 
 
 html2canvas.prototype.canvasRenderer = function(queue){
@@ -87,9 +93,9 @@ html2canvas.prototype.canvasRenderer = function(queue){
     
     
         
-
-    this.canvas.width = $(document).width();
-    this.canvas.height = $(document).height();
+  
+    this.canvas.width = Math.max($(document).width(),this.opts.canvasWidth);   
+    this.canvas.height = Math.max($(document).height(),this.opts.canvasHeight);
     
     this.ctx = this.canvas.getContext("2d");
     
@@ -113,6 +119,9 @@ html2canvas.prototype.canvasRenderer = function(queue){
                         }else if(renderItem.name=="fillText"){
                             _.ctx.fillText(renderItem.arguments[0],renderItem.arguments[1],renderItem.arguments[2]);
                         }else if(renderItem.name=="drawImage"){
+                          //  console.log(renderItem);
+                         // console.log(renderItem.arguments[0].width);
+                          if (renderItem.arguments[8] > 0 && renderItem.arguments[7]){
                             _.ctx.drawImage(
                                 renderItem.arguments[0],
                                 renderItem.arguments[1],
@@ -124,6 +133,7 @@ html2canvas.prototype.canvasRenderer = function(queue){
                                 renderItem.arguments[7],
                                 renderItem.arguments[8]
                                 );
+                              }      
                         }else{
                             this.log(renderItem);
                         }
diff --git a/src/Util.js b/src/Util.js
index 98d669a..b749192 100644
--- a/src/Util.js
+++ b/src/Util.js
@@ -1,20 +1,10 @@
 
 // Simple logger
-html2canvas.prototype.log = function(a){
-    
+html2canvas.prototype.log = function(a){    
     if (this.opts.logging){
         
-        if (window.console && window.console.log){
-           console.log(a);     
-        }else{
-            alert(a);
-        }
-    /*
-        if (typeof(window.console) != "undefined" && console.log){
-            console.log(a);
-        }else{
-            alert(a);
-        }*/
+        this.opts.logger(a);
+
     }
 }                    
 
@@ -165,4 +155,12 @@ html2canvas.prototype.getIndex = function(array,src){
         return -1;
     }
     
-}
\ No newline at end of file
+}
+
+
+html2canvas.prototype.isSameOrigin = function(url){
+    var link = document.createElement("a");
+    link.href = url;
+
+    return ((link.protocol + link.hostname) == this.pageOrigin);
+}
diff --git a/src/plugins/jquery.plugin.html2canvas.js b/src/plugins/jquery.plugin.html2canvas.js
index 640ebd1..09730e3 100644
--- a/src/plugins/jquery.plugin.html2canvas.js
+++ b/src/plugins/jquery.plugin.html2canvas.js
@@ -4,15 +4,16 @@
  */
 			
 (function( $ ){
-    $.fn.html2canvas = function() {
+    $.fn.html2canvas = function(options) {
   
         var date = new Date();
         var message,
         timeoutTimer,
         timer = date.getTime();
         
-        new html2canvas(this.get(0), {
-            logging: true,
+        var object = $.extend({},{
+            logging: false,
+            proxyUrl: "http://html2canvas.appspot.com/", // running html2canvas-python proxy
             ready: function(renderer) {
                 
                 var finishTime = new Date();
@@ -49,7 +50,9 @@
                 });
             }
             
-        });
+        },options)
+        
+        new html2canvas(this.get(0), object);
         
         
         function throwMessage(msg,duration){
diff --git a/tests/proxy.html b/tests/proxy.html
new file mode 100644
index 0000000..db66c1c
--- /dev/null
+++ b/tests/proxy.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>External content tests</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        
+        
+        <script type="text/javascript" src="../external/jquery-1.6.2.js"></script>
+        <script type="text/javascript" src="../build/html2canvas.js"></script>
+        <script type="text/javascript" src="../build/jquery.plugin.html2canvas.js"></script>
+        <script type="text/javascript">
+            $(window).ready(function() {       
+                $('body').html2canvas();
+            });
+        </script>
+
+<base href="http://www.google.com/" />
+    </head>
+    <body>         
+        <h1>External image</h1>
+        <img src="http://www.google.com/logos/2011/gregormendel11-hp.jpg" style="border:5px solid black;" />
+        
+        <h1>External image (using &lt;base&gt; href)</h1>
+        <img src="/logos/2011/gregormendel11-res.jpg" />
+        
+    </body>
+</html>