if(!Object.prototype.toJSONString){Array.prototype.toJSONString=function(){var a=['['],b,i,l=this.length,v;function p(s){if(b){a.push(',');}
a.push(s);b=true;}
for(i=0;i<l;i+=1){v=this[i];switch(typeof v){case'object':if(v){if(typeof v.toJSONString==='function'){p(v.toJSONString());}}else{p("null");}
break;case'string':case'number':case'boolean':p(v.toJSONString());}}
a.push(']');return a.join('');};Boolean.prototype.toJSONString=function(){return String(this);};Date.prototype.toJSONString=function(){function f(n){return n<10?'0'+n:n;}
return'"'+this.getFullYear()+'-'+
f(this.getMonth()+1)+'-'+
f(this.getDate())+'T'+
f(this.getHours())+':'+
f(this.getMinutes())+':'+
f(this.getSeconds())+'"';};Number.prototype.toJSONString=function(){return isFinite(this)?String(this):"null";};(function(s){var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};s.parseJSON=function(filter){try{if(/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(this)){var j=eval('('+this+')');if(typeof filter==='function'){function walk(k,v){if(v&&typeof v==='object'){for(var i in v){if(v.hasOwnProperty(i)){v[i]=walk(i,v[i]);}}}
return filter(k,v);}
j=walk('',j);}
return j;}}catch(e){}
throw new SyntaxError("parseJSON");};s.toJSONString=function(){if(/["\\\x00-\x1f]/.test(this)){return'"'+this.replace(/([\x00-\x1f\\"])/g,function(a,b){var c=m[b];if(c){return c;}
c=b.charCodeAt();return'\\u00'+
Math.floor(c/16).toString(16)+
(c%16).toString(16);})+'"';}
return'"'+this+'"';};})(String.prototype);}
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(input){var output="";var chr1,chr2,chr3,enc1,enc2,enc3,enc4;var i=0;input=Base64._utf8_encode(input);while(i<input.length){chr1=input.charCodeAt(i++);chr2=input.charCodeAt(i++);chr3=input.charCodeAt(i++);enc1=chr1>>2;enc2=((chr1&3)<<4)|(chr2>>4);enc3=((chr2&15)<<2)|(chr3>>6);enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64;}else if(isNaN(chr3)){enc4=64;}
output=output+
this._keyStr.charAt(enc1)+this._keyStr.charAt(enc2)+
this._keyStr.charAt(enc3)+this._keyStr.charAt(enc4);}
return output;},decode:function(input){var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;var output=new Array();while(i<input.length){enc1=this._keyStr.indexOf(input.charAt(i++));enc2=this._keyStr.indexOf(input.charAt(i++));enc3=this._keyStr.indexOf(input.charAt(i++));enc4=this._keyStr.indexOf(input.charAt(i++));chr1=(enc1<<2)|(enc2>>4);chr2=((enc2&15)<<4)|(enc3>>2);chr3=((enc3&3)<<6)|enc4;output.push(chr1);if(enc3!=64){output.push(chr2);}
if(enc4!=64){output.push(chr3);}}
return output;},_utf8_encode:function(string){string=string.replace(/\r\n/g,"\n");var utftext="";for(var n=0;n<string.length;n++){var c=string.charCodeAt(n);if(c<128){utftext+=String.fromCharCode(c);}
else if((c>127)&&(c<2048)){utftext+=String.fromCharCode((c>>6)|192);utftext+=String.fromCharCode((c&63)|128);}
else{utftext+=String.fromCharCode((c>>12)|224);utftext+=String.fromCharCode(((c>>6)&63)|128);utftext+=String.fromCharCode((c&63)|128);}}
return utftext;},_utf8_decode:function(utftext){var string="";var i=0;var c=c1=c2=0;while(i<utftext.length){c=utftext.charCodeAt(i);if(c<128){string+=String.fromCharCode(c);i++;}
else if((c>191)&&(c<224)){c2=utftext.charCodeAt(i+1);string+=String.fromCharCode(((c&31)<<6)|(c2&63));i+=2;}
else{c2=utftext.charCodeAt(i+1);c3=utftext.charCodeAt(i+2);string+=String.fromCharCode(((c&15)<<12)|((c2&63)<<6)|(c3&63));i+=3;}}
return string;}}
function ArrayList()
{this.data=[];}
ArrayList.prototype.add=function(value)
{this.data[this.data.length]=value;}
ArrayList.prototype.remove=function(value)
{for(var i=0;i<this.data.length;++i)
{if(this.data[i]===value)
{this.removeAt(i);break;}}}
ArrayList.prototype.removeAt=function(index)
{var i;if((index<0)||(index>this.data.length-1))
{throw"Index out of bounds";}
for(i=index;i<this.data.length-1;++i)
{this.data[i]=this.data[i+1];}
this.data.length=this.data.length-1;}
ArrayList.prototype.get=function(index)
{if((index<0)||(index>this.data.length-1))
{throw"Index out of bounds";}
return this.data[index];}
ArrayList.prototype.indexOf=function(value)
{var i;for(i=0;i<this.data.length;++i)
{if(data[i]===value)
{return i;}}
throw"Object not found";}
ArrayList.prototype.getLength=function()
{return this.data.length;}
function Event()
{this.handlers=new ArrayList();}
Event.prototype={attach:function(handler)
{this.handlers.add(handler);},detach:function(handler)
{this.handlers.remove(handler);},fire:function(source)
{var i;for(i=0;i<this.handlers.getLength();++i)
{this.handlers.get(i).apply(null,arguments);}}};function Rectangle(left,top,width,height)
{this.left=left;this.top=top;this.width=width;this.height=height;}
Rectangle.prototype.right=function()
{return this.left+this.width-1;};Rectangle.prototype.bottom=function()
{return this.top+this.height-1;};Rectangle.prototype.area=function()
{return this.width*this.height;};Rectangle.prototype.toString=function()
{return"("+this.left.toString()+", "+this.top.toString()+")"+" "
+this.width.toString()+" x "+this.height.toString();};Rectangle.prototype.containsPoint=function(x,y)
{return(x>=this.left)&&(x<=this.right())&&(y>=this.top)&&(y<=this.bottom());};Rectangle.prototype.intersects=function(other)
{return!((this.left>other.right())||(this.right()<other.left)||(this.top>other.bottom())||(this.bottom()<other.top));};function Money(amount,symbol)
{this.amount=amount;this.symbol=symbol;}
Money.prototype.toString=function()
{var s=this.amount.toString();if(s.indexOf(".")==-1)
{s+=".";}
s+="00";return(this.symbol+s.substring(0,s.indexOf(".")+3));}
function mod(n,k)
{return n-(Math.floor(n/k)*k);}
function trace(msg)
{if(typeof(jsTrace)!='undefined')
{jsTrace.send(msg);}}
function bind(object,method)
{return function()
{method.apply(object,arguments);}}
function eventSource(event)
{event=event||window.event;return event.target||event.srcElement;}
function Application(environment,gardenID,gardenWidth,gardenHeight,gardenPlotMapBlob,viewRevisionBlob)
{this.environment=environment;this.garden=new Garden(this,gardenID,gardenWidth,gardenHeight,gardenPlotMapBlob);this.order=new Order(this);this.initializeItemDefinitions();this.initializeTools();this.toolControlsByTool=null;this.toolControlGroup=null;this.itemDefinitionButtonGroup=null;this.view=new View(this.garden,viewRevisionBlob);this.initializeUI();this.selectedItemDefinitionChanged=new Event();this.toolControllersByTool=null;this.itemOverlayManager=null;this.initializeToolControllers();this.initializeObservers();this.selectedTool=null;this.selectedItemDefinition=null;this.itemDefinitionButtonGroup.selectIndex(0);this.toolControlGroup.selectIndex(0);}
Application.prototype.toString=function()
{return"Gardens for Growing Application ("+this.environment+")";};Application.prototype.isProduction=function()
{return this.environment=="production"||this.environment=="production_remote";};Application.prototype.getSelectedTool=function()
{return this.selectedTool;};Application.prototype.setSelectedTool=function(tool)
{if(this.selectedTool!==null)
{this.toolControllersByTool[this.selectedTool].deselect();}
this.selectedTool=tool;this.toolControllersByTool[this.selectedTool].select();};Application.prototype.getSelectedItemDefinition=function()
{return this.selectedItemDefinition;}
Application.prototype.setSelectedItemDefinition=function(itemDefinition)
{var oldItemDefinition=this.selectedItemDefinition;this.selectedItemDefinition=itemDefinition;this.selectedItemDefinitionChanged.fire(this,itemDefinition,oldItemDefinition);}
Application.prototype.submitOrder=function()
{form=document.getElementById("orderForm");form.order.value=this.order.toArray().toJSONString();form.submit();};Application.prototype.initializeToolControllers=function()
{this.toolControllersByTool={spade:new AddRemoveItemToolController(this),hand:new ScrollToolController(this),info:new InfoToolController(this)};};Application.prototype.initializeObservers=function()
{this.itemOverlayManager=new ItemOverlayManager(this);};Application.prototype.initializeItemDefinitions=function()
{this.itemDefinitions=[new ItemDefinition(1,"Daisy",5,1,1,3),new ItemDefinition(3,"Sunflower",5,1,1,3),new ItemDefinition(6,"Lily",10,1,1,3),new ItemDefinition(2,"Tulip",10,1,1,3),new ItemDefinition(4,"Dahlia",25,1,1,3),new ItemDefinition(5,"Rose",50,1,1,3),new ItemDefinition(7,"Hydrangea",100,2,2,3),new ItemDefinition(8,"Lily Pond",250,4,4,3),new ItemDefinition(9,"Gazebo",1000,4,6,1)];};Application.prototype.initializeTools=function()
{this.tools=["spade","hand","info"];};Application.prototype.initializeUI=function()
{this.initializeMap();this.initializeBasket();this.initializeToolControls();this.initializeItemDefinitionButtons();};Application.prototype.initializeMap=function()
{var gardenMapType=new GardenMapType(this.view);var mapOptions={mapTypes:[gardenMapType]};var mapContainer=document.getElementById("map");this.map=new GMap2(mapContainer,mapOptions);this.map.addControl(new GLargeMapControl());this.map.setCenter(new GLatLng(-72,-72),2);};Application.prototype.initializeBasket=function()
{var basketFrame=document.getElementById("basketFrame");this.instructions=document.getElementById("instructions");this.basket=new Basket(basketFrame,this.order);this.basket.donateClicked.attach(bind(this,this.basketDonateClicked));this.basket.clearClicked.attach(bind(this,this.basketClearClicked));this.basket.itemClicked.attach(bind(this,this.basketItemClicked));this.basket.render();};Application.prototype.initializeToolControls=function()
{var i,tool,control;this.toolControlGroup=new SingleSelectGroup();this.toolControlGroup.selectionChanged.attach(bind(this,this.toolSelectionChanged));this.toolControlsByTool={};for(i=0;i<this.tools.length;++i)
{tool=this.tools[i];control=new ToolControl(tool);this.toolControlGroup.add(control);this.toolControlsByTool[tool]=control;this.map.addControl(control,new GControlPosition(G_ANCHOR_TOP_LEFT,new GSize(80+i*(32+15),10)));}};Application.prototype.initializeItemDefinitionButtons=function()
{var i,button;var itemDefinitions=document.getElementById("itemsFrame");var group=new SingleSelectGroup();group.selectionChanged.attach(bind(this,this.itemDefinitionSelectionChanged));this.itemDefinitionButtonGroup=group;for(i=0;i<this.itemDefinitions.length;++i)
{button=new ItemDefinitionButton(itemDefinitions,this.itemDefinitions[i]);group.add(button)
button.render();}};Application.prototype.basketItemClicked=function(source,item)
{this.map.panTo(item.primaryPlot.bounds.getNorthEast());};Application.prototype.basketDonateClicked=function(source)
{this.submitOrder();};Application.prototype.basketClearClicked=function(source)
{this.order.clear();};Application.prototype.itemDefinitionSelectionChanged=function(source,selection,oldSelection)
{this.setSelectedItemDefinition(selection.itemDefinition);if(this.selectedTool!="spade")
{this.toolControlGroup.select(this.toolControlsByTool["spade"]);}};Application.prototype.toolSelectionChanged=function(source,selection,oldSelection)
{this.setSelectedTool(selection.tool);};function ItemOverlayManager(application)
{this.application=application;this.overlayByPrimaryPlotHashCode={};this.application.order.itemAdded.attach(bind(this,this.orderItemAdded));this.application.order.itemRemoved.attach(bind(this,this.orderItemRemoved));}
ItemOverlayManager.prototype.orderItemAdded=function(source,item)
{var overlay=new ItemOverlay(this.application.garden,item);var plotHashCode=this.getPlotHashCode(item.primaryPlot);this.overlayByPrimaryPlotHashCode[plotHashCode]=overlay;this.application.map.addOverlay(overlay);};ItemOverlayManager.prototype.orderItemRemoved=function(source,item)
{var plotHashCode=this.getPlotHashCode(item.primaryPlot);var overlay=this.overlayByPrimaryPlotHashCode[plotHashCode];if(undefined!==overlay)
{this.application.map.removeOverlay(overlay);this.overlayByPrimaryPlotHashCode[plotHashCode]=undefined;}};ItemOverlayManager.prototype.getPlotHashCode=function(plot)
{return plot.i.toString()+"_"+plot.j.toString();};function ToolController()
{this.selected=false;}
ToolController.prototype.select=function()
{if(this.selected)
{throw"ToolController already selected";}
this.selected=true;};ToolController.prototype.deselect=function()
{if(!this.selected)
{throw"ToolController not selected";}
this.selected=false;};function ScrollToolController(application)
{ToolController.call(this);this.application=application;}
ScrollToolController.prototype=new ToolController();ScrollToolController.prototype.select=function()
{ToolController.prototype.select.call(this);this.application.map.enableDragging();};ScrollToolController.prototype.toString=function()
{return"ScrollToolController";};function InfoToolController(application)
{ToolController.call(this);this.application=application;this.ignoreNextMapClickEvent=false;}
InfoToolController.prototype=new ToolController();InfoToolController.prototype.toString=function()
{return"InfoToolController";};InfoToolController.prototype.select=function()
{ToolController.prototype.select.call(this);this.onMapClickListenerHandle=GEvent.bind(this.application.map,"click",this,this.onMapClick);this.overlay=new InfoToolOverlay(this.application,this);var map=this.application.map;map.addOverlay(this.overlay);map.disableDragging();Util.setMapCursor(map,Cursor.INFO);};InfoToolController.prototype.deselect=function()
{ToolController.prototype.deselect.call(this);this.application.map.removeOverlay(this.overlay);this.overlay=null;GEvent.removeListener(this.onMapClickListenerHandle);};InfoToolController.prototype.onMapClick=function(marker,latlng)
{if(latlng===undefined)
{this.ignoreNextMapClickEvent=true;}
else
{if(this.ignoreNextMapClickEvent)
{this.ignoreNextMapClickEvent=false;}
else
{var plot=this.application.garden.getPlot(latlng);Util.openItemInfoWindow(this.application.map,plot);}}};function AddRemoveItemToolController(application)
{ToolController.call(this);this.application=application;}
AddRemoveItemToolController.prototype=new ToolController();AddRemoveItemToolController.prototype.toString=function()
{return"AddRemoveItemToolController";};AddRemoveItemToolController.prototype.select=function()
{ToolController.prototype.select.call(this);this.onMapClickListenerHandle=GEvent.bind(this.application.map,"click",this,this.onMapClick);this.overlay=new AddRemoveItemToolOverlay(this.application,this);var map=this.application.map;map.addOverlay(this.overlay);map.disableDragging();Util.setMapCursor(map,Cursor.SPADE);};AddRemoveItemToolController.prototype.deselect=function()
{ToolController.prototype.deselect.call(this);this.application.map.removeOverlay(this.overlay);this.overlay=null;GEvent.removeListener(this.onMapClickListenerHandle);};AddRemoveItemToolController.prototype.onMapClick=function(marker,latlng)
{this.addOrRemoveItem(this.application.garden.getPlot(latlng));};AddRemoveItemToolController.prototype.addOrRemoveItem=function(plot)
{if(plot!==null)
{if(plot.containsItem())
{this.removeItem(plot);}
else
{if(plot.isUsable())
{this.addItem(plot);}}}};AddRemoveItemToolController.prototype.addItem=function(plot)
{if(plot.canPlace(this.application.selectedItemDefinition))
{plot.place(this.application.selectedItemDefinition);}}
AddRemoveItemToolController.prototype.removeItem=function(plot)
{plot.getItem().remove();}
function Garden(application,id,width,height,plotMap)
{this.application=application;this.id=id;this.width=width;this.height=height;this.plotMap=plotMap;}
Garden.prototype.getPlot=function(latlng)
{var lat=latlng.lat();var lng=latlng.lng();if((lat>=90)||(lat<-90)||(lng>=180)||(lng<-180))
{return null;}
var i=Math.floor(latlng.lng()/this.getLongitudePerPlot());var j=Math.floor(latlng.lat()/this.getLatitudePerPlot());return new Plot(this.application,i,j);};Garden.prototype.getBounds=function()
{return new Rectangle(Math.floor(this.width/-2),Math.floor(this.height/-2),this.width,this.height);};Garden.prototype.getLongitudePerPlot=function()
{return 360.0/this.width;};Garden.prototype.getLatitudePerPlot=function()
{return 180.0/this.height;};function Item(definition,primaryPlot)
{this.definition=definition;this.primaryPlot=primaryPlot;}
Item.prototype.toString=function()
{return this.definition.toString()+" "+this.primaryPlot.toString();};Item.prototype.getPlots=function()
{var di,dj,i,j,plot;var plots=[];for(di=0;di<this.definition.width;++di)
{for(dj=0;dj<this.definition.height;++dj)
{i=this.primaryPlot.i+di;j=this.primaryPlot.j+dj;plot=new Plot(this.primaryPlot.application,i,j);plots.push(plot);}}
return plots;};Item.prototype.remove=function()
{var order=this.primaryPlot.garden.application.order;order.removeItem(this);};function ItemDefinition(id,name,price,width,height,stageCount)
{this.id=id;this.name=name;this.price=price;this.width=width;this.height=height;this.stageCount=stageCount;}
ItemDefinition.prototype={toString:function()
{return this.name;},getFormattedPrice:function(currencySymbol)
{currencySymbol=currencySymbol||"$";return new Money(this.price,currencySymbol).toString();}};function Plot(application,i,j)
{this.application=application;this.garden=application.garden;this.i=i;this.j=j;var sw=new GLatLng((j+1)*this.garden.getLatitudePerPlot(),i*this.garden.getLongitudePerPlot());var ne=new GLatLng(j*this.garden.getLatitudePerPlot(),(i+1)*this.garden.getLongitudePerPlot());this.bounds=new GLatLngBounds(sw,ne);}
Plot.prototype.isAvailable=function()
{return this.isUsable()&&!this.containsItem()};Plot.prototype.isUsable=function()
{var i=this.i+Math.ceil(this.garden.width/2);var j=this.j+Math.ceil(this.garden.height/2);var k=i*this.garden.height+j;var bit=this.garden.plotMap[Math.floor(k/8)]&(1<<(k%8));return(0==bit);};Plot.prototype.containsItem=function()
{return this.application.order.containsItemOnPlot(this);};Plot.prototype.getItem=function()
{var item;var column=this.application.order.itemsByPlotCoordinates[this.i];if(undefined===column)
{return null;}
else
{item=column[this.j];return((undefined===item)?null:item);}};Plot.prototype.canPlace=function(itemDefinition)
{var canPlace=true;var di,dj,i,j,plot;for(di=0;di<itemDefinition.width;++di)
{for(dj=0;dj<itemDefinition.height;++dj)
{i=this.i+di;j=this.j+dj;if(!this.application.garden.getBounds().containsPoint(i,j))
{canPlace=false;}
else
{plot=new Plot(this.application,i,j);if(!plot.isAvailable())
{canPlace=false;}}}}
return canPlace;};Plot.prototype.place=function(itemDefinition)
{return this.application.order.addItem(this,itemDefinition);};Plot.prototype.toString=function()
{return"plot ("+this.i.toString()+", "+this.j.toString()+")";};function Order()
{this.items=new ArrayList();this.itemsByPlotCoordinates=[];this.itemAdded=new Event();this.itemRemoved=new Event();this.itemsChanged=new Event();}
Order.prototype.isEmpty=function()
{return(this.items.getLength()==0);};Order.prototype.clear=function()
{var i;var n=this.items.getLength();for(i=0;i<n;++i)
{this.removeItem(this.items.get(0));}};Order.prototype.containsItemOnPlot=function(plot)
{column=this.itemsByPlotCoordinates[plot.i];return((undefined!==column)&&(undefined!==column[plot.j]));};Order.prototype.addItem=function(plot,itemDefinition)
{var i;var itemPlot;if(!plot.canPlace(itemDefinition))
{throw"Object not placeable";}
var item=new Item(itemDefinition,plot);var itemPlots=item.getPlots();for(i=0;i<itemPlots.length;++i)
{itemPlot=itemPlots[i];if(undefined===this.itemsByPlotCoordinates[itemPlot.i])
{this.itemsByPlotCoordinates[itemPlot.i]=[];}
this.itemsByPlotCoordinates[itemPlot.i][itemPlot.j]=item;}
this.items.add(item);this.itemAdded.fire(this,item);this.itemsChanged.fire(this);};Order.prototype.removeItem=function(item)
{var i;var itemPlots=item.getPlots();for(i=0;i<itemPlots.length;++i)
{itemPlot=itemPlots[i];this.itemsByPlotCoordinates[itemPlot.i][itemPlot.j]=undefined;}
this.items.remove(item);this.itemRemoved.fire(this,item);this.itemsChanged.fire(this);};Order.prototype.getTotal=function()
{var i;var total=0;for(i=0;i<this.items.getLength();++i)
{total+=this.items.get(i).definition.price;}
return total;};Order.prototype.getFormattedTotal=function(currencySymbol)
{currencySymbol=currencySymbol||"$";return new Money(this.getTotal(),currencySymbol).toString();};Order.prototype.toArray=function()
{var i;var item;var item_array
var array=[];for(i=0;i<this.items.getLength();++i)
{item=this.items.get(i);array[i]=[item.definition.id,item.primaryPlot.i,item.primaryPlot.j]}
return array;};function View(garden,revisionBlob)
{this.garden=garden
this.initZoomLevels();this.revision=new ViewRevision(this,revisionBlob);}
View.prototype={initZoomLevels:function()
{var i;var zoomLevels=[];for(i=0;i<View.ZOOM_LEVELS;++i)
{zoomLevels.push(new ZoomLevel(i,this.garden.getBounds(),View.PLOT_WIDTH_BY_ZOOM_LEVEL[i],View.PLOT_HEIGHT_BY_ZOOM_LEVEL[i],View.TILE_WIDTH,View.TILE_HEIGHT));}
this.zoomLevels=zoomLevels;}};$.extend(View,{TILE_WIDTH:256,TILE_HEIGHT:256,PLOT_WIDTH_BY_ZOOM_LEVEL:[4,16,32],PLOT_HEIGHT_BY_ZOOM_LEVEL:[4,16,32],ZOOM_LEVELS:3});function ZoomLevel(index,bounds,plotWidth,plotHeight,tileWidth,tileHeight)
{this.index=index;this.bounds=bounds;this.plotWidth=plotWidth;this.plotHeight=plotHeight;this.tileWidth=tileWidth;this.tileHeight=tileHeight;}
ZoomLevel.prototype={getPixelBounds:function()
{var width=this.bounds.width*this.plotWidth;var height=this.bounds.height*this.plotHeight;return new Rectangle(Math.floor(width/-2),Math.floor(height/-2),width,height);},getTileBounds:function()
{return this.pixelBoundsToTileBounds(this.getPixelBounds());},pixelBoundsToTileBounds:function(pixelBounds)
{var iMin=Math.floor(pixelBounds.left/this.tileWidth);var iMax=Math.floor(pixelBounds.right()/this.tileWidth);var jMin=Math.floor(pixelBounds.top/this.tileHeight);var jMax=Math.floor(pixelBounds.bottom()/this.tileHeight);return new Rectangle(iMin,jMin,iMax-iMin+1,jMax-jMin+1);}};function ViewRevision(view,blob)
{this.view=view;this.blob=blob;this.zoomLevelOffsets=this.calculateZoomLevelOffsets();}
ViewRevision.prototype={getTileRevision:function(z,i,j)
{return this.blob[this.k(z,i,j)];},k:function(z,i,j)
{var tileBounds=this.view.zoomLevels[z].getTileBounds();i-=tileBounds.left;j-=tileBounds.top;return this.zoomLevelOffsets[z]+
i+
j*tileBounds.width;},calculateZoomLevelOffsets:function()
{var i;var zoomLevel;var offsets=[];var zoomLevels=this.view.zoomLevels;if(zoomLevels.length>0)
{offsets[0]=0;for(i=1;i<zoomLevels.length;++i)
{offsets[i]=offsets[i-1]+zoomLevels[i-1].getTileBounds().area();}}
return offsets;}};function EquirectangularProjection(zoomLevels,dimensions)
{this.zoomLevels=zoomLevels;this.dimensions=dimensions||EquirectangularProjection.createDefaultDimensions(zoomLevels);}
EquirectangularProjection.prototype=new GProjection();EquirectangularProjection.DEFAULT_WIDTH_PER_ZOOM_LEVEL=100;EquirectangularProjection.DEFAULT_HEIGHT_PER_ZOOM_LEVEL=100;EquirectangularProjection.createDefaultDimensions=function(zoomLevels)
{var i,width,height;var array=[];for(i=0;i<zoomLevels;++i)
{width=(i+1)*EquirectangularProjection.DEFAULT_WIDTH_PER_ZOOM_LEVEL;height=(i+1)*EquirectangularProjection.DEFAULT_HEIGHT_PER_ZOOM_LEVEL;array[i]=[width,height];}
return array;};EquirectangularProjection.prototype.fromLatLngToPixel=function(latlng,zoom)
{var x=Math.round(latlng.lng()*this.getPixelsPerLongitudeDegree(zoom));var y=Math.round(latlng.lat()*this.getPixelsPerLatitudeDegree(zoom));return new GPoint(x,y);};EquirectangularProjection.prototype.fromPixelToLatLng=function(pixel,zoom,unbounded)
{var lng=pixel.x/this.getPixelsPerLongitudeDegree(zoom);var lat=pixel.y/this.getPixelsPerLatitudeDegree(zoom);return new GLatLng(lat,lng,unbounded);};EquirectangularProjection.prototype.tileCheckRange=function(tile,zoom,tilesize)
{var tileRectangle=new Rectangle(tile.x*tilesize,tile.y*tilesize,tilesize,tilesize);return this.bounds(zoom).intersects(tileRectangle);};EquirectangularProjection.prototype.getPixelsPerLatitudeDegree=function(zoom)
{return this.dimensions[zoom][1]/180;};EquirectangularProjection.prototype.getPixelsPerLongitudeDegree=function(zoom)
{return this.dimensions[zoom][0]/360;};EquirectangularProjection.prototype.getWrapWidth=function(zoom)
{return 1000000;};EquirectangularProjection.prototype.bounds=function(zoom)
{var width=this.dimensions[zoom][0];var height=this.dimensions[zoom][1];return new Rectangle(width/-2,height/-2,width,height);};EquirectangularProjection.prototype.projectLatLngBounds=function(bounds,zoom)
{var sw=bounds.getSouthWest();var ne=bounds.getNorthEast();var swPixel=this.fromLatLngToPixel(sw,zoom);var nePixel=this.fromLatLngToPixel(ne,zoom);return new Rectangle(swPixel.x,nePixel.y,nePixel.x-swPixel.x,swPixel.y-nePixel.y);};function GardenEquirectangularProjection(view)
{var pixelBounds;var dimensions=[]
for(var i=0;i<view.zoomLevels.length;++i)
{pixelBounds=view.zoomLevels[i].getPixelBounds();dimensions.push([pixelBounds.width,pixelBounds.height]);}
EquirectangularProjection.call(this,view.zoomLevels.length,dimensions);}
GardenEquirectangularProjection.prototype=new EquirectangularProjection(1);GardenEquirectangularProjection.prototype.fromPixelToLatLng=function(pixel,zoom,unbounded)
{return EquirectangularProjection.prototype.fromPixelToLatLng.call(this,pixel,zoom,true);}
function GardenTileLayer(copyrights,minResolution,maxResolution,view)
{GTileLayer.call(this,copyrights,minResolution,maxResolution);this.view=view;this.garden=view.garden;}
GardenTileLayer.prototype=new GTileLayer(new GCopyrightCollection(),0,0);GardenTileLayer.prototype.getTileUrl=function(tile,zoom)
{return this.getTileProtocolAndHost(tile,zoom)+
this.getTileDirectory(tile,zoom)+
this.getTileFilename(tile,zoom)+"?"+this.view.revision.getTileRevision(zoom,tile.x,tile.y);};GardenTileLayer.prototype.getTileProtocolAndHost=function(tile,zoom)
{return this.garden.application.isProduction()?"http://tile"+(mod(tile.x,4)).toString()+".gardensforgrowing.org":"";};GardenTileLayer.prototype.getTileDirectory=function(tile,zoom)
{return this.garden.application.isProduction()?"/"+this.garden.id.toString()+"/":"/images/tiles/"+this.garden.id.toString()+"/";};GardenTileLayer.prototype.getTileFilename=function(tile,zoom)
{return zoom.toString()+"_"+tile.x.toString()+"_"+tile.y.toString()+".png";};function GardenMapType(view)
{var tileLayer=new GardenTileLayer(new GCopyrightCollection(),0,view.zoomLevels.length-1,view);GMapType.call(this,[tileLayer],new GardenEquirectangularProjection(view),"Garden",{errorMessage:"Image missing"});}
GardenMapType.prototype=new GMapType([],null,null);Util={};Util.centerMapOnPlot=function(map,plot)
{map.setCenter(plot.bounds.getNorthEast());};Util.openItemInfoWindow=function(map,plot)
{new PlotInfoWindow(map,plot).open();};Util.getPixelRectangleFromPlot=function(map,plot,widthPlots,heightPlots)
{widthPlots=widthPlots||1;heightPlots=heightPlots||1;garden=plot.garden;var nw=new GLatLng(plot.j*garden.getLatitudePerPlot(),plot.i*garden.getLongitudePerPlot());var se=new GLatLng((plot.j+heightPlots)*garden.getLatitudePerPlot(),(plot.i+widthPlots)*garden.getLongitudePerPlot());var nwPoint=map.fromLatLngToDivPixel(nw);var sePoint=map.fromLatLngToDivPixel(se);return new Rectangle(nwPoint.x,nwPoint.y,sePoint.x-nwPoint.x,sePoint.y-nwPoint.y);};Util.setMapCursor=function(map,cursor)
{var paneContainer=map.getContainer().firstChild.firstChild;if(paneContainer.style.cursor!=cursor)
{paneContainer.style.cursor=cursor;}};Util.getPixelRectangleFromItem=function(map,item)
{return Util.getPixelRectangleFromPlot(map,item.primaryPlot,item.definition.width,item.definition.height);};Util.applyPixelRectangleToStyle=function(style,rectangle)
{style.left=rectangle.left.toString()+"px";style.top=rectangle.top.toString()+"px";style.width=rectangle.width.toString()+"px";style.height=rectangle.height.toString()+"px";};function Basket(parent,order)
{this.parent=parent;this.order=order;this.donateClicked=new Event();this.clearClicked=new Event();this.itemClicked=new Event();this.order.itemAdded.attach(bind(this,this.onOrderItemAdded));this.order.itemRemoved.attach(bind(this,this.onOrderItemRemoved));this.createControls();this.update();}
Basket.prototype={render:function()
{this.parent.appendChild(this.element);},createControls:function()
{this.element=document.createElement("div");this.element.id="basket";this.ledgerTableFrame=document.createElement("div");this.ledgerTableFrame.id="basketLedgerTableFrame";this.element.appendChild(this.ledgerTableFrame);this.instructionsDiv=document.createElement("div");this.instructionsDiv.id="basketInstructions";this.instructionsDiv.innerHTML="Your basket is empty. Choose a flower below and click on the map to plant it.";this.ledgerTableFrame.appendChild(this.instructionsDiv);this.ledgerTable=this.createLedgerTable();this.ledgerTableFrame.appendChild(this.ledgerTable);var footerTable=document.createElement("table");footerTable.id="basketFooterTable";this.element.appendChild(footerTable);var footerTableBody=document.createElement("tbody");footerTable.appendChild(footerTableBody);var tr=document.createElement("tr");footerTableBody.appendChild(tr);this.totalCell=document.createElement("td");this.totalCell.id="basketFooterTableTotalCell";tr.appendChild(this.totalCell);var actionsCell=document.createElement("td");actionsCell.id="basketFooterTableActionsCell";tr.appendChild(actionsCell);this.clearLink=document.createElement("a");this.clearLink.id="clearLink";this.clearLink.onclick=bind(this,this.onClearLinkClick);this.clearLink.href="#";this.clearLink.innerHTML="Clear";actionsCell.appendChild(this.clearLink);this.donateButton=document.createElement("button");this.donateButton.id="donateButton";this.donateButton.onclick=bind(this,this.onDonateButtonClick);this.donateButton.innerHTML="Donate";actionsCell.appendChild(this.donateButton);},update:function()
{this.donateButton.disabled=this.order.isEmpty();this.totalCell.innerHTML="Total: "+
this.order.getFormattedTotal();this.updateLedgerTable();this.ledgerTable.style.display=this.order.isEmpty()?"none":"block";this.instructionsDiv.style.display=this.order.isEmpty()?"block":"none";},updateLedgerTable:function()
{this.ledgerTableFrame.removeChild(this.ledgerTable);this.ledgerTable=this.createLedgerTable();this.ledgerTableFrame.appendChild(this.ledgerTable);},createLedgerTable:function()
{var i;var tr,td,img,a;var item;var table=document.createElement("table");table.id="basketLedgerTable";var tbody=document.createElement("tbody");table.appendChild(tbody);for(i=0;i<this.order.items.getLength();++i)
{item=this.order.items.get(i);tr=document.createElement("tr");tr.className="basketLedgerTableItemRow";tbody.appendChild(tr);td=document.createElement("td");tr.appendChild(td);img=document.createElement("img");img.src="/images/items/"+
item.definition.id+"_small_"+
(item.definition.stageCount-1)+".png";img.style.width=img.style.height="16px";td.appendChild(img);td=document.createElement("td");td.className="itemName";tr.appendChild(td);a=document.createElement("a");a.href="#";a.onclick=bind(this,this.onItemNameClick);a.innerHTML=item.definition.name;a.item=item;td.appendChild(a);td=document.createElement("td");td.className="itemPrice";td.innerHTML=item.definition.getFormattedPrice();tr.appendChild(td);}
return table;},onItemNameClick:function(event)
{var a=eventSource(event);this.itemClicked.fire(this,a.item);},onClearLinkClick:function()
{this.clearClicked.fire(this);},onDonateButtonClick:function()
{this.donateClicked.fire(this);},onOrderItemAdded:function()
{this.update();this.ledgerTableFrame.scrollTop=this.ledgerTableFrame.scrollHeight;},onOrderItemRemoved:function()
{this.update();}};function ItemDefinitionButton(parent,itemDefinition)
{this.parent=parent;this.itemDefinition=itemDefinition;this.onMouseUp=new Event();this.createElement();}
ItemDefinitionButton.SELECTED_CLASS_NAME="selectedItemDefinitionButton";ItemDefinitionButton.prototype={createElement:function()
{var div=document.createElement("div");div.className="itemDefinitionButton";div.onmouseup=bind(this,this.onDivMouseUp);this.element=div;var img=document.createElement("img");img.src="/images/tools/"+this.itemDefinition.id.toString()+".png";div.appendChild(img);var nameLabel=document.createElement("div");nameLabel.className="itemDefinitionButtonNameLabel";nameLabel.innerHTML=this.itemDefinition.name;div.appendChild(nameLabel);var priceLabel=document.createElement("div");priceLabel.className="itemDefinitionButtonPriceLabel";priceLabel.innerHTML="$"+this.itemDefinition.price.toString();div.appendChild(priceLabel);},render:function()
{this.parent.appendChild(this.element);},select:function()
{$(this.element).addClass(ItemDefinitionButton.SELECTED_CLASS_NAME);},deselect:function()
{$(this.element).removeClass(ItemDefinitionButton.SELECTED_CLASS_NAME);},onDivMouseUp:function()
{this.onMouseUp.fire(this);}};function ToolControl(tool)
{GControl.call(this);this.tool=tool;this.onMouseUp=new Event();this.createControls();}
ToolControl.prototype=new GControl();ToolControl.SELECTED_CLASS="selectedToolControl";ToolControl.prototype.select=function()
{$(this.element).addClass(ToolControl.SELECTED_CLASS);};ToolControl.prototype.deselect=function()
{$(this.element).removeClass(ToolControl.SELECTED_CLASS);};ToolControl.prototype.createControls=function()
{var div=document.createElement("div");div.className="toolControl";div.onmouseup=bind(this,this.onDivMouseUp);this.element=div;var img=document.createElement("img");img.src="/images/tools/"+this.tool+".png";img.width=32;img.height=32;div.appendChild(img);};ToolControl.prototype.onDivMouseUp=function()
{this.onMouseUp.fire(this);};ToolControl.prototype.initialize=function(map)
{var container=map.getContainer();container.appendChild(this.element);return this.element;};ToolControl.prototype.getDefaultPosition=function()
{return new GControlPosition(G_ANCHOR_TOP_LEFT,new GSize(7,7));};function SingleSelectGroup()
{this.elements=new ArrayList();this.selectedElement=null;this.selectionChanged=new Event();}
SingleSelectGroup.prototype={add:function(element)
{element.onMouseUp.attach(bind(this,this.onElementMouseUp));this.elements.add(element);},remove:function(element)
{throw"Not yet implemented";},onElementMouseUp:function(source)
{this.select(source);},selectIndex:function(index)
{if((index>=0)&&(index<this.elements.getLength()))
{this.select(this.elements.get(index));}
else
{throw"Index out of range";}},select:function(element)
{var oldSelection;if(element!==this.selectedElement)
{oldSelection=this.selectedElement;this.selectedElement=element;if(oldSelection!==null)
{oldSelection.deselect();}
this.selectedElement.select();this.selectionChanged.fire(this,this.selectedElement,oldSelection);}}};Cursor={SPADE:"url(/images/cursors/spade.cur), default",SPADE_DISABLED:"url(/images/cursors/spade_disabled.cur), default",SPADE_DESTROY:"url(/images/cursors/spade_destroy.cur), default",INFO:"url(/images/cursors/info.cur), default"};function PlotOverlay(garden)
{GOverlay.call(this);this.plot=null;this.garden=garden;this.map=null;}
PlotOverlay.prototype=new GOverlay();PlotOverlay.prototype.setPlot=function(plot)
{if(plot!=this.plot)
{this.plot=plot;this.redraw(true);}};PlotOverlay.prototype.getPlot=function()
{return this.plot;};PlotOverlay.prototype.initialize=function(map)
{this.map=map;this.overlayDiv=document.createElement("div");this.overlayDiv.style.position="absolute";this.overlayDiv.className="overlay";this.getMapPane().appendChild(this.overlayDiv);};PlotOverlay.prototype.remove=function()
{this.overlayDiv.parentNode.removeChild(this.overlayDiv);};PlotOverlay.prototype.copy=function()
{return null;};PlotOverlay.prototype.redraw=function(force)
{return null;};PlotOverlay.prototype.getMapPane=function()
{return this.map.getPane(G_MAP_MAP_PANE);}
function CursorOverlay(garden)
{PlotOverlay.call(this,garden);}
CursorOverlay.prototype=new PlotOverlay(null);CursorOverlay.prototype.mapMousemove=function(latlng)
{var plot=this.garden.getPlot(latlng);this.setPlot(plot);};CursorOverlay.prototype.mapMouseout=function(latlng)
{};CursorOverlay.prototype.initialize=function(map)
{PlotOverlay.prototype.initialize.call(this,map);this.mapMousemoveListener=GEvent.bind(map,"mousemove",this,this.mapMousemove);this.mapMouseoutListener=GEvent.bind(map,"mouseout",this,this.mapMouseout);};CursorOverlay.prototype.remove=function()
{GEvent.removeListener(this.mapMousemoveListener);GEvent.removeListener(this.mapMouseoutListener);PlotOverlay.prototype.remove.call(this);}
function ItemOverlay(garden,item)
{PlotOverlay.call(this,garden);this.item=item;}
ItemOverlay.prototype=new PlotOverlay(null);ItemOverlay.prototype.initialize=function(map)
{PlotOverlay.prototype.initialize.call(this,map);this.image=document.createElement("img");this.image.src=this.getItemImageUrl();this.overlayDiv.appendChild(this.image);};ItemOverlay.prototype.redraw=function(force)
{var rectangle;if(force)
{rectangle=Util.getPixelRectangleFromItem(this.map,this.item);Util.applyPixelRectangleToStyle(this.overlayDiv.style,rectangle);this.image.src=this.getItemImageUrl();this.image.style.width=rectangle.width+"px";this.image.style.height=rectangle.height+"px";}};ItemOverlay.prototype.getItemImageUrl=function()
{return"/images/items/"+
this.item.definition.id+"_"+
this.map.getZoom().toString()+"_"+
(this.item.definition.stageCount-1).toString()+".png";}
function ToolOverlay(garden,tool)
{CursorOverlay.call(this,garden);this.tool=tool;}
ToolOverlay.prototype=new CursorOverlay();function AddRemoveItemToolOverlay(application,tool)
{ToolOverlay.call(this,application.garden,tool);this.application=application;}
AddRemoveItemToolOverlay.prototype=new ToolOverlay(null);AddRemoveItemToolOverlay.prototype.copy=function()
{return new AddRemoveItemToolOverlay(this.garden,this.tool);};AddRemoveItemToolOverlay.prototype.initialize=function(map)
{ToolOverlay.prototype.initialize.call(this,map);this.box=document.createElement("div");this.box.className="spadeBox";this.overlayDiv.appendChild(this.box);};AddRemoveItemToolOverlay.prototype.setBoxPosition=function(plot,width,height)
{width=width||1;height=height||1;Util.applyPixelRectangleToStyle(this.box.style,Util.getPixelRectangleFromPlot(this.application.map,plot,width,height));};AddRemoveItemToolOverlay.prototype.redraw=function(force)
{var item;var itemDefinition;if(force)
{if(this.plot===null)
{this.box.style.visibility="hidden";}
else
{this.box.style.visibility="visible";if(this.plot.containsItem())
{item=this.plot.getItem();this.setBoxPosition(item.primaryPlot,item.definition.width,item.definition.height);this.box.className="spadeBox spadeBoxDestroy";Util.setMapCursor(this.application.map,Cursor.SPADE_DESTROY);}
else
{itemDefinition=this.application.getSelectedItemDefinition();this.setBoxPosition(this.plot,itemDefinition.width,itemDefinition.height);if(this.plot.canPlace(itemDefinition))
{this.box.className="spadeBox";Util.setMapCursor(this.application.map,Cursor.SPADE);}
else
{this.box.className="spadeBox spadeBoxDisabled";Util.setMapCursor(this.application.map,Cursor.SPADE_DISABLED);}}}}};function InfoToolOverlay(application,tool)
{ToolOverlay.call(this,application.garden,tool);this.application=application;}
InfoToolOverlay.prototype=new ToolOverlay(null);InfoToolOverlay.prototype.copy=function()
{return new InfoToolOverlay(this.application,this.tool);};InfoToolOverlay.prototype.initialize=function(map)
{ToolOverlay.prototype.initialize.call(this,map);this.box=document.createElement("div");this.box.className="addRemoveToolOverlayBox";this.overlayDiv.appendChild(this.box);};InfoToolOverlay.prototype.redraw=function(force)
{if(force&&(this.plot!==null))
{Util.applyPixelRectangleToStyle(this.box.style,Util.getPixelRectangleFromPlot(this.application.map,this.plot));}};function PlotInfoWindow(map,plot)
{this.map=map;this.plot=plot;this.isOpen=false;}
PlotInfoWindow.loadingHtml="loading ...";PlotInfoWindow.prototype={open:function()
{if(this.isOpen)return;this.map.openInfoWindowHtml(this.getPosition(),PlotInfoWindow.loadingHtml,{onOpenFn:bind(this,this.onOpen),onCloseFn:bind(this,this.onClose),maxWidth:200});},close:function()
{if(!this.isOpen)return;this.map.closeInfoWindow();},updateInfoWindow:function(html)
{var tabs=[new GInfoWindowTab("",html)];this.map.updateInfoWindow(tabs);},getUrl:function()
{return'/gardens/'+
this.plot.garden.id.toString()+'/plot_info_window?i='+
this.plot.i.toString()+'&j='+
this.plot.j.toString();},getPosition:function()
{return this.plot.bounds.getNorthEast();},onOpen:function()
{GDownloadUrl(this.getUrl(),bind(this,this.onDownloadComplete));},onClose:function()
{this.isOpen=false;},onDownloadComplete:function(text,responseCode)
{if((text!==null)&&(responseCode==200))
{this.updateInfoWindow(text)}}};