/* * GMapEZ -- Turn specially-marked HTML into Google Maps * Copyright (C) July 2005 - Oct 2006 by Chris Houser <chouser@n01se.net> * * This code is licensed under the GNU General Public License (GPL) * * If you use this code on a web page, please include on that page a * link to http://n01se.net/gmapez/ -- this is a request, not * a requirement.  Thanks. */(function(){  var startdate = new Date();  // configuration -- if you're using your own copy of gmapez.js, you  // may want to modify these:  var overlaysPerStep = 25;  var imgBase = 'http://gmapez.googlepages.com/';  var upperImgBase = 'http://gmapez.upper.googlepages.com/';  var shadowServer = 'http://n01se.net/shadow.cgi?src=';  if( window.ez_preload ) {    // we're already loaded    return;  }  var _lastId = 0;  function newId() {    return 'ez_' + (++_lastId);  }  function loadfunc() {    if( ! GBrowserIsCompatible() ) {      if( document.getElementsByTagName ) {        // Find all divs marked as GMapEZ        var divs = document.getElementsByTagName( 'div' );        for( var i = 0; i < divs.length; ++i ) {          var div = divs[ i ];          if( div.className.indexOf( 'GMapEZ' ) > -1 ) {            div.innerHTML =  [              "<div>This map cannot be displayed.  The site's key may be ",              "incorrect, or your browser may not compatible (see if ",              "your browser is listed ",              '<a href="http://maps.google.com/support/bin/answer.py?answer=16532">here</a>).</div>',              '<div class="firefoxref"><iframe src="http://pagead2.googlesyndication.com/cpa/ads?client=ca-pub-1237864095616304&amp;cpa_choice=CAAQyaj8zwEaCIwcWMzeycafKMu293M&amp;oe=UTF-8&amp;dt=1148266564041&amp;lmt=1148266562&amp;format=180x60_as_rimg&amp;output=html&amp;region=_google_cpa_region_&amp;cc=100&amp;u_h=1024&amp;u_w=1280&amp;u_ah=1050&amp;u_aw=1400&amp;u_cd=24&amp;u_tz=-240&amp;u_his=1&amp;u_java=true&amp;u_nplug=11&amp;u_nmime=133" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" frameborder="0" height="60" scrolling="no" width="180"></iframe></div>'              ].join('\n');            div.style.visibility = 'visible';            div.style.padding = '0.3em';            div.style.background = '#eee';            div.style.overflow = 'auto';          }        }      }      else {        alert( [          'Your browser is not capable of displaying',          'Google Maps on this page. Try using Firefox:',          'http://getfirefox.com/' ].join('\n') );      }      return;    }    addOnUnload( GUnload );    function getTotalOffset( elem ) {      point = new GPoint( 0, 0 );      while( elem ) {        point.x += elem.offsetLeft;        point.y += elem.offsetTop;        //alert( elem.offsetTop + ' = ' + point.y );        elem = elem.offsetParent;      }      return point;    }    function GSmallMapTypeControl() {      GMapTypeControl.call( this, true );    }    GSmallMapTypeControl.prototype = new GMapTypeControl();    GSmallMapTypeControl.prototype.constructor = GSmallMapTypeControl;    window.GSmallMapTypeControl = GSmallMapTypeControl;    var CtrlTable = {      'GOverviewMapControl': true,      'GLargeMapControl': true,      'GSmallMapControl': true,      'GSmallZoomControl': true,      'GSmallMapTypeControl': true,      'GMapTypeControl': true,      'GMenuMapTypeControl': true,      'GHierarchicalMapTypeControl': true,      'GScaleControl': true    };    var MapTypeTable = {      'G_NORMAL_MAP' : null,      'G_SATELLITE_MAP' : null,      'G_HYBRID_MAP' : null,      'G_PHYSICAL_MAP' : null,      'G_MAP_TYPE' : 'G_NORMAL_MAP',      'G_SATELLITE_TYPE' : 'G_SATELLITE_MAP',      'G_HYBRID_TYPE' : 'G_HYBRID_MAP'    };    var idmarkers = {};    function markerForUrl( url ) {      var matcha = /#(.*)/.exec( url );      if( matcha )        return idmarkers[ matcha[ 1 ] ];      else        return null;    }    // For this event handler, "this" is the clicked anchor    function anchorClick() {      var marker = markerForUrl( this.href );      if( marker ) {        if( /\bZOOM\b/.exec( this.className ) ) {          var mapType = marker.mapType || marker.ezmap.map.getCurrentMapType();          var zoomLevel;          if( marker.span ) {            zoomLevel = mapType.getSpanZoomLevel(              marker.point, marker.span, marker.ezmap.viewsize );          }          else {            zoomLevel = marker.ezmap.map.getZoom();          }          marker.ezmap.map.setCenter( marker.point, zoomLevel, mapType );        }        marker.doOpen();        return false;      }      else {        return true;      }    }    function wordMap( str ) {      var wmap = {};      var list = str.split(' ');      for( var j = 0; j < list.length; ++j ) {        wmap[ list[ j ] ] = true;      }      return wmap;    }    function parseParams( str, params ) {      var matchparam;      for( var word in wordMap( str ) ) {        matchparam = /^(\w+):(.*)$/.exec( word );        if( matchparam && matchparam[1] in params ) {          params[ matchparam[1] ] = matchparam[2];        }      }      return params;    }    var markerOpener = {      markers: [],      addMarker: function( marker ) {        this.markers.push( marker );      },      chainOpen: function( i ) {        /*         * This is a work-around for a Google Maps bug.  If I try to open         * all the info windows at once, only the last one succeeds.         *         * Otherwise, it is equivalent to:         *   for( i = 0; i < this.markers.length; ++i )         *     this.markers[ i ].doOpen();         */        i = i || 0;        if( i < this.markers.length ) {          var onOpen = GEvent.bind(              this.markers[ i ].ezmap.map,              "infowindowopen",              this,              function(){                GEvent.removeListener( onOpen );                this.chainOpen( i + 1 );              });          this.markers[ i ].doOpen( true );        }        else {          //alert('GMapEZ loadtime: ' + ( new Date() - startdate ) );        }      }    };    var laterFuncs = [];    var lastFunc = null;    function doNow() {      if( laterFuncs.length > 0 ) {        laterFuncs.shift().call();        setTimeout( doNow, 1 );      }      else {        if( lastFunc ) {          lastFunc.call();        }      }    }    function doLater( obj, func ) {      laterFuncs.push( function() { func.call( obj ); } );    }    var MiniIcon = new GIcon();    MiniIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";    MiniIcon.iconSize = new GSize(12, 20);    MiniIcon.shadowSize = new GSize(22, 20);    MiniIcon.iconAnchor = new GPoint(6, 20);    MiniIcon.infoWindowAnchor = new GPoint(5, 1);    G_DEFAULT_ICON.transparent = null;    function EZInfoMarker( ezmap ) {      this.ezmap = ezmap;      this.icon = G_DEFAULT_ICON;      this.point = null;      this.title = null;      this.blowup = false;      this.tabs = [];      this.infoZoomOffset = undefined;      this.infoZoomLevel = undefined;      this.infoMapType = null;    }    EZInfoMarker.prototype = new GMarker( new GLatLng( 0, 0 ) );    EZInfoMarker.prototype.constructor = EZInfoMarker;    EZInfoMarker.prototype.initialize = function( map ) {      GMarker.call(          this,          this.point,          {            icon: this.icon,            clickable: ( this.tabs.length > 0 || this.blowup ),            title: this.title          });      GMarker.prototype.initialize.call( this, map );    };    EZInfoMarker.prototype.doOpen = function( autoopen ) {      if( ! autoopen ) {        var body = document.body || document.getElementsByTagName('body')[0];        if( 'scrollLeft' in body ) {          // http://www.howtocreate.co.uk/tutorials/javascript/browserwindow          var myWidth = 0, myHeight = 0;          if( typeof( window.innerWidth ) == 'number' ) {            //Non-IE            myWidth = window.innerWidth;            myHeight = window.innerHeight;          } else if( document.documentElement &&              ( document.documentElement.clientWidth ||              document.documentElement.clientHeight ) )          {            //IE 6+ in 'standards compliant mode'            myWidth = document.documentElement.clientWidth;            myHeight = document.documentElement.clientHeight;          } else if( document.body &&              ( document.body.clientWidth || document.body.clientHeight ) )          {            //IE 4 compatible            myWidth = document.body.clientWidth;            myHeight = document.body.clientHeight;          }          var mapdiv = this.ezmap.div;          var totalOffset = getTotalOffset( mapdiv );          if( totalOffset.x < body.scrollLeft ||              totalOffset.x + mapdiv.offsetWidth > body.scrollLeft+myWidth ||              totalOffset.y < body.scrollTop ||              totalOffset.y + mapdiv.offsetHeight > body.scrollTop+myHeight)          {            //alert( totalOffset.x + ', ' + totalOffset.y );            scrollTo( totalOffset.x, totalOffset.y );          }        }      }      var zoom = null;      if( this.tabs.length > 0 ) {        var opts = { maxWidth: this.ezmap.div.offsetWidth - 100 };        if( this.icon ) {          this.openInfoWindowTabs( this.tabs, opts );        }        else {          // "INVISIBLE" markers are never added as overlays -- GMap2          // knows nothing about them.          this.ezmap.map.openInfoWindowTabs( this.point, this.tabs, opts );        }        for( var i = 0; i < this.tabs.length; ++i ) {          this.setupInfoForm( this.tabs[ i ] );        }      }      else if( this.blowup ) {        if( this.infoZoomOffset != undefined )          zoom = this.ezmap.map.getZoom() + this.infoZoomOffset;        else if( this.infoZoomLevel != undefined )          zoom = this.infoZoomLevel;        if( zoom >= this.ezmap.map.getCurrentMapType().numZoomLevels )          zoom = this.ezmap.map.getCurrentMapType().numZoomLevels - 1;        else if( zoom < 0 )          zoom = 0;        this.showMapBlowup( { zoomLevel: zoom, mapType: this.infoMapType } );      }      else {        this.ezmap.map.closeInfoWindow();      }    };    EZInfoMarker.prototype.setupInfoForm = function( tab ) {      var div, a;      var tabElem = tab.contentElem;      var classes = tabElem.className ? wordMap( tabElem.className ) : {};      if( classes.DirectionsToHere ||          classes.DirectionsFromHere ||          classes.SearchNearby )      {        if( tab.infoFormId ) {          div = document.getElementById( tab.infoFormId );          div.innerHTML = '';        }        else {          div = document.createElement('div');          div.className = 'ez_infoForm';          tab.infoFormId = div.id = newId();          tabElem.appendChild( div );        }        var _this = this;        if( classes.DirectionsToHere || classes.DirectionsFromHere ) {          div.appendChild( document.createTextNode( 'Get directions: ' ) );          if( classes.DirectionsToHere ) {            a = document.createElement('a');            a.innerHTML = 'To here';            a.onclick = function() { _this.showForm( tab ); };            a.href = 'javascript:void(null)';            div.appendChild( a );          }          if( classes.DirectionsToHere && classes.DirectionsFromHere ) {            div.appendChild( document.createTextNode( ' - ' ) );          }          if( classes.DirectionsFromHere ) {            a = document.createElement('a');            a.innerHTML = 'From here';            a.onclick = function() {};            a.href = 'javascript:void(null)';            div.appendChild( a );          }          div.appendChild( document.createElement('br') );        }        if( classes.SearchNearby ) {          a = document.createElement('a');          a.innerHTML = 'Search nearby';          a.onclick = function() {};          a.href = 'javascript:void(null)';          div.appendChild( a );        }      }    };    EZInfoMarker.prototype.showForm = function( tab ) {      var div = document.getElementById( tab.infoFormId );      div.innerHTML = '<b>Get directions:</b> To here - ';      var a = document.createElement('a');      a.innerHTML = 'From here';      a.onclick = function() {};      a.href = 'javascript:void(null)';      div.appendChild( a );      var x = document.createElement('div');      x.innerHTML = 'Start address';      div.appendChild( x );      this.ezmap.map.getInfoWindow().reset();    };    function EZPolyline( color, weight, opacity ) {      this.points = [];      this.initialize = function( map ) {        GPolyline.call( this, this.points, color, weight, opacity );        GPolyline.prototype.initialize.call( this, map );      };    };    EZPolyline.prototype = new GPolyline();    EZPolyline.prototype.constructor = EZPolyline;    function EZMap( div, classes ) {      this.div = div;      this.classes = classes;      this.divData = null;      this.map = undefined;      this.viewsize = null;      this.extentMarker = null;      this.overlayList = [];      this.loading = null;      this.bar = null;      this.maxstep = 0;      this.step = 0;      this.oi = 0;      this.initFrame();    }    EZMap.prototype.logWarning = function( str ) {      if( ! this.warningNode ) {        this.warningVis = false;        this.warningNode = document.createElement('ul');        this.warningNode.className = 'warnings';        this.div.appendChild( this.warningNode );        var warnBtn = document.createElement('button');        warnBtn.className = 'warnings';        warnBtn.innerHTML = 'Warnings...';        this.div.appendChild( warnBtn );        var ezmap = this;        warnBtn.onclick = function() { ezmap.toggleWarnings(); };      }      var li = document.createElement('li');      li.innerHTML = str;      this.warningNode.appendChild( li );    };    EZMap.prototype.toggleWarnings = function() {      this.warningVis = ! this.warningVis;      this.warningNode.style.display = this.warningVis ? 'block' : 'none';    };    EZMap.prototype.processMarkers = function( parentNode, polyline ) {      var lastOverlay, marker, textContent, imgs;      var matchll, matchspn, matchtype;      for( var node = parentNode.firstChild; node; node = node.nextSibling){        lastOverlay = this.overlayList[ this.overlayList.length - 1 ];        switch( node.nodeName ) {        case 'A':          matchll = /\Wll=([-.\d]*),([-.\d]*)/.exec( node.href );          if( matchll ) {            marker = new EZInfoMarker( this );            marker.title = node.getAttribute('title');            this.overlayList.push( marker );            if( node.id || node.name )              idmarkers[ node.id || node.name ] = marker;            textContent = node.innerHTML.replace( /<[^>]*>/g, '' );            if( /\bOPEN\b/.exec( textContent ) )              markerOpener.addMarker( marker );            if( /\bEXTENT\b/.exec( textContent ) ) {              marker.icon = null;              this.extentMarker = marker;            }            if( /\bINVISIBLE\b/.exec( textContent ) ) {              marker.icon = null;            }            marker.point = new GLatLng(                parseFloat( matchll[1] ),                parseFloat( matchll[2] ) );            if( polyline ) {              marker.icon = null;              polyline.points.push( marker.point );            }            matchspn = /\Wspn=([-.\d]*),([-.\d]*)/.exec( node.href );            if( matchspn ) {              marker.span = new GLatLng(                  parseFloat( matchspn[1] ),                  parseFloat( matchspn[2] ) );            }            matchtype = /\Wt=(.)/.exec( node.href );            if( matchtype ) {              switch( matchtype[1] ) {                case 'k': marker.mapType = G_SATELLITE_MAP; break;                case 'h': marker.mapType = G_HYBRID_MAP; break;                // XXX need a GMapType letter for use by ZOOM links              }            }            // build icon            imgs = node.getElementsByTagName('img')            if( imgs.length < 1 ) {              var matchcolor =                  /\b(ORANGE|PURPLE|YELLOW|GREEN|BLUE|RED|AQUA|WHITE|GRAY)\b/                  .exec( textContent );              var matchsym =                  /\b([0-9A-Za-z]|BLANK|HASH|DOLLAR|DOT|START|END)\b/                  .exec( textContent );              var matchmini = /\bMINI\b/.exec( textContent );              if( matchcolor || matchsym || matchmini ) {                var upper = matchsym && matchsym[0].match(/^[A-Z]$/);                marker.icon = new GIcon( matchmini ? MiniIcon : G_DEFAULT_ICON );                marker.icon.image = [                  upper ? upperImgBase : imgBase,                  matchmini ? 'mini' : 'marker',                  '-',                  matchcolor ? matchcolor[0] : 'ORANGE',                  '-',                  matchmini ? 'BLANK' : ( matchsym ? matchsym[0] : 'DOT' ),                  upper ? '-UPPER' : '',                  '.png' ].join('');                marker.icon.printImage    = marker.icon.image;                marker.icon.mozPrintImage = marker.icon.image;              }            }            else {              marker.icon = new GIcon( G_DEFAULT_ICON, imgs[ 0 ].src );              marker.icon.printImage    = imgs[ 0 ].src;              marker.icon.mozPrintImage = imgs[ 0 ].src;              marker.icon.transparent = null;              marker.icon.iconAnchor = null;              marker.icon.infoWindowAnchor = null;              var params = parseParams( imgs[ 0 ].className, {                width: null, height: null,                iconAnchor: null, infoWindowAnchor: null, imageMap: null } );              var match;              var width = parseInt( params.width );              var height = parseInt( params.height );              marker.icon.iconSize = new GSize( width, height );              if( params.iconAnchor ) {                match = /(\d+),(\d+)/.exec( params.iconAnchor );                if( match ) {                  marker.icon.iconAnchor = new GPoint(                    parseInt( match[1] ),                    parseInt( match[2] ) );                }              }              if( marker.icon.iconAnchor === null ) {                marker.icon.iconAnchor = new GPoint(                  Math.round( width / 2 ),                  Math.max( 1, height - 2 ) );              }              if( params.infoWindowAnchor ) {                match = /(\d+),(\d+)/.exec( params.infoWindowAnchor );                if( match ) {                  marker.icon.infoWindowAnchor = new GPoint(                    parseInt( match[1] ),                    parseInt( match[2] ) );                }              }              if( marker.icon.infoWindowAnchor === null ) {                marker.icon.infoWindowAnchor = new GPoint(                  Math.round( width / 2 ),                  0 );              }              if( params.imageMap ) {                marker.icon.imageMap = [];                var parts = params.imageMap.split(/\s*,\s*/);                for( var i = 0; i < parts.length; ++i ) {                  marker.icon.imageMap.push( parseInt( parts[ i ] ) );                }                //alert( marker.icon.imageMap );              }              if( imgs.length > 1 ) {                marker.icon.shadow = imgs[ 1 ].src;                params = parseParams( imgs[ 1 ].className, { width:0, height:0 });                marker.icon.shadowSize = new GSize( params.width, params.height);              }              else {                marker.icon.shadow = shadowServer + imgs[ 0 ].src;                marker.icon.shadowSize = new GSize(                    Math.floor( width + height * 0.55 ), height );              }              if( imgs.length > 2 ) {                marker.icon.transparent = imgs[ 2 ].src;              }              if( imgs.length > 3 ) {                marker.icon.printImage = imgs[ 3 ].src;              }              if( imgs.length > 4 ) {                marker.icon.printShadow = imgs[ 4 ].src;              }              if( imgs.length > 5 ) {                marker.icon.mozPrintShadow = imgs[ 5 ].src;              }            }          }          else {            this.logWarning( "No ll param for marker [" + node.innerHTML +              ":" + (node.id || node.name) + "]" );          }          break;        case 'DIV':          if( ! lastOverlay ) {            this.logWarning( "div block given before any markers" );            continue;          }          else {            var infoClasses = wordMap( node.className );            if( 'GMapEZ' in infoClasses ) {              // infoWindow blowup              // XXX replace this with a nested map to allow for use              // in tabs?              lastOverlay.blowup = true;              var matchzoom = /ZOOMLEVEL([-+=]?)(\d+)/.exec( node.innerHTML );              if( matchzoom ) {                var num = parseInt( matchzoom[ 2 ] );                if( matchzoom[ 1 ] == '-' )                  lastOverlay.infoZoomOffset = num;                else if( matchzoom[ 1 ] == '+' )                  lastOverlay.infoZoomOffset = - num;                else                  lastOverlay.infoZoomLevel = num;              }              for( typeName in MapTypeTable ) {                if( typeName in infoClasses ) {                  if( MapTypeTable[ typeName ] ) {                    lastOverlay.infoMapType = window[ MapTypeTable[ typeName ] ];                  }                  else {                    lastOverlay.infoMapType = window[ typeName ];                  }                  break;                }              }            }            else {              // XXX remove title attribute from div node?              lastOverlay.tabs.push(                  new GInfoWindowTab( node.getAttribute('title'), node ));            }          }          break;        case 'LI':          this.processMarkers( node, polyline );          break;        case 'OL':          var params = parseParams( node.className,              { color: null, weight: null, opacity: null } );          if( params.color && ! /^#[0-9a-zA-Z]{6}$/.exec( params.color ) )            this.logWarning( 'Polyline color should be a 6-digit' +                ' hex color like "#123abc", not "' + params.color + '"' );          if( params.weight != null ) {            var w = parseInt( params.weight );            if( w < 1 || isNaN( w ) )              this.logWarning( 'Polyline weight should be an' +                  ' interger above 0, not "' + params.weight + '"' );            params.weight = w;          }          if( params.opacity ) {            var o = parseFloat( params.opacity );            if( o < 0 || o > 1 || isNaN( o ) )              this.logWarning( 'Polyline opacity should be ' +                  ' between 0 and 1, not "' + params.opacity + '"' );            params.opacity = o;          }          var newline = new EZPolyline(              params.color,              params.weight,              params.opacity );          this.overlayList.push( newline );          this.processMarkers( node, newline );          break;        case '#text':        case '#comment':          // ignore text and comments          break;        default:          this.logWarning( "Unknown or misplaced node " + node.nodeName );          break;        }      }    };    EZMap.prototype.onClick = function( overlay, point ) {      if( overlay && overlay.doOpen ) {        overlay.doOpen();      }      else if( point ) {        this.map.closeInfoWindow();      }    };    EZMap.prototype.nextStep = function( func ) {      if( this.maxstep > 0 ) {        this.bar.style.width = Math.round( this.step / this.maxstep * 100 ) + '%';      }      this.step += 1;      doLater( this, func );    };    EZMap.prototype.initFrame = function() {      this.divData = this.div;      this.div = this.div.cloneNode( false );      this.divData.parentNode.insertBefore( this.div, this.divData );      this.divData.parentNode.removeChild( this.divData );      this.div.style.visibility = 'visible';      this.loading = document.createElement('div');      this.loading.className = 'loadprogress';      this.loading.style.marginTop = ( this.div.offsetHeight / 3 ) + 'px';      this.loading.innerHTML = '<div class="box"><div class="logo"></div><div class="trough"><div class="bar"></div></div></div>';      this.bar = this.loading.getElementsByTagName('div')[3];      this.div.appendChild( this.loading );      this.nextStep( this.initParse );    };    EZMap.prototype.initParse = function() {      this.processMarkers( this.divData );      this.divData = null;      this.map = new GMap2( this.div );      this.map.getContainer().appendChild( this.loading );      GEvent.bind( this.map, 'click', this, this.onClick );      if( 'ScrollWheelZoom' in this.classes ) {        this.map.enableScrollWheelZoom();      }      if( ! this.extentMarker && this.overlayList.length == 1 )        this.extentMarker = this.overlayList[ 0 ];      // map type      var mapType = G_NORMAL_MAP;      if( this.extentMarker && this.extentMarker.mapType ) {        mapType = this.extentMarker.mapType;      }      for( typeName in MapTypeTable ) {        if( typeName in this.classes ) {          if( MapTypeTable[ typeName ] ) {            mapType = window[ MapTypeTable[ typeName ] ];          }          else {            mapType = window[ typeName ];          }          break;        }      }      // center and zoom      this.viewsize = new GSize( this.div.offsetWidth, this.div.offsetHeight );      var center, zoomLevel;      if( this.extentMarker ) {        center = this.extentMarker.point;        if( this.extentMarker.span ) {          zoomLevel = mapType.getSpanZoomLevel(              center, this.extentMarker.span, this.viewsize );        }        else {          zoomLevel = 10;        }      }      else if( this.overlayList.length > 1 ) {        var autoBounds;        for( var i = 0; i < this.overlayList.length; ++i ) {          if( this.overlayList[ i ].point ) {            if( ! autoBounds ) {              autoBounds = new GLatLngBounds(                  this.overlayList[ i ].point,                  this.overlayList[ i ].point );            }            else {              autoBounds.extend( this.overlayList[ i ].point );            }          }        }        var sw = autoBounds.getSouthWest();        var ne = autoBounds.getNorthEast();        center = new GLatLng(          ( sw.lat() + ne.lat() ) / 2,          ( sw.lng() + ne.lng() ) / 2 );        zoomLevel = mapType.getBoundsZoomLevel( autoBounds, this.viewsize);      }      else {        center = new GLatLng( 41.075210, -85.130310 );        zoomLevel = 10;      }      // apply center, zoom, and map type      this.map.setCenter( center, zoomLevel, mapType );      this.maxstep = Math.floor( this.overlayList.length / overlaysPerStep ) + 2;      this.initOverlays();    };    EZMap.prototype.initOverlays = function() {      var overlay;      var steplimit = Math.min(this.overlayList.length, this.oi+overlaysPerStep);      for( ; this.oi < steplimit; ++this.oi ) {        overlay = this.overlayList[ this.oi ];        if( overlay.points || overlay.icon )          this.map.addOverlay( overlay );        this.overlayList[ this.oi ] = null;      }      if( this.oi < this.overlayList.length )        this.nextStep( this.initOverlays );      else        this.nextStep( this.initControls );    };    EZMap.prototype.initControls = function() {      for( var ctrl in CtrlTable ) {        if( ctrl in this.classes ) {          this.map.addControl( new window[ ctrl ]() );        }      }      this.nextStep( this.initLoading );    };    EZMap.prototype.initLoading = function() {      this.loading.parentNode.removeChild( this.loading );      this.loading = null;    };    // Find all anchor tags linking to GMapEZ markers    var anchors = document.getElementsByTagName( 'a' );    for( var mi = 0; mi < anchors.length; ++mi ) {      if( ! anchors[ mi ].onclick ) {        anchors[ mi ].onclick = anchorClick;      }    }    // Find all divs marked as GMapEZ    var divs = document.getElementsByTagName( 'div' );    for( var i = 0; i < divs.length; ++i ) {      var div = divs[ i ];      var classes = wordMap( div.className );      if( 'GMapEZ' in classes ) {        new EZMap( div, classes );      }    }    lastFunc = function() {      // Examine current page location for a reference to a GMapEZ marker      var marker = markerForUrl( document.location );      if( marker )        markerOpener.addMarker( marker );      // Open all the markers we need to      markerOpener.chainOpen();    };    doNow();  }  function chainWindowFunc( funcname, newfunc ) {    var oldfunc = window[ funcname ];    if( oldfunc ) {      window[ funcname ] = function() { oldfunc(); newfunc(); };    }    else {      window[ funcname ] = newfunc;    }  }  window.addOnLoad   = function( func ) { chainWindowFunc( "onload",   func );};  window.addOnUnload = function( func ) { chainWindowFunc( "onunload", func );};  window.ez_preload = function() {    if( window.G_INCOMPAT ) {      // If the key failed to validate, cause all keys to appear valid      // and try again.      window.G_INCOMPAT = false;      window.GValidateKey = function(){ return true; }      GLoad();    }    addOnLoad( loadfunc );  }  var key = '';  var gmapversion = '2';  (function(){    var metas = document.getElementsByTagName( 'meta' );    var match;    for( var i = 0; i < metas.length; ++i ) {      match = /gmapkey:?(.*)/.exec( metas[ i ].name );      if( match ) {        if( ! match[ 1 ] ) {          key = metas[ i ].content;        }        else if( (new RegExp( match[ 1 ] )).exec( window.location.href ) ) {          key = metas[ i ].content;          break;        }      }      else if( metas[ i ].name == 'gmapversion' ) {        gmapversion = metas[ i ].content;      }    }  })();  if( ! window.GMap2 ) {    document.write( [      '<script src="http://maps.google.com/maps?file=api&v='      + gmapversion + '&key=' + key      + '" type="text/javascript"></script>' ].join('\n') );  }  document.write( [    '<script type="text/javascript">',    '  ez_preload();',    '</script>',    '<style type="text/css">',    'div.GMapEZ {',    '  visibility: hidden;',    '  border: 1px #888 solid;',    '}',    'div.GMapEZ ul.warnings {',    '  position: absolute;',    '  top: 0;',    '  left: 0;',    '  margin: 0;',    '  padding-right: 0.5em;',    '  padding-left: 1.5em;',    '  display: none;',    '  border: 1px #888 solid;',    '  background: #fff;',    '  z-index: 100000000;',    '  text-align: left;',    '  font-family: Arial;',    '  font-size: 9pt;',    '  overflow: auto;',    '}',    'div.GMapEZ button.warnings {',    '  display: block;',    '  position: absolute;',    '  z-index: 100000000;',    '  bottom: 20px;',    '  right: 0;',    '  color: #f00;',    '}',    'div.GMapEZ .firefoxref {',    '  text-align: center;',    '  margin: 1em;',    '}',    'div.GMapEZ .loadprogress {',    '  position: relative;',    '  z-index: 100000000;',    '  text-align: center;',    '}',    'div.GMapEZ .loadprogress .box {',    '  font-family: Arial, sans-serif;',    '  background: #fff;',    '  border: 1px #bbb inset;',    '  width: 136px;',    '  height: 45px;',    '  margin: auto;',    '}',    'div.GMapEZ .loadprogress .logo {',    '  margin: 8px;',    '  margin-bottom: 0;',    '  width: 120px;',    '  height: 28px;',    "  filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +        imgBase + "logo3.png',sizingMethod='scale');",    '}',    'div.GMapEZ .loadprogress .box > .logo {',    '  position: relative;',    '  background: url(' + imgBase + 'logo3.png) no-repeat;',    '}',    'div.GMapEZ .loadprogress .trough {',    '  margin: 8px;',    '  margin-top: -5px;',    '  background: #ccc;',    '  font-size: 1px;',    '  height: 8px;',    '  text-align: left;',    '}',    'div.GMapEZ .loadprogress .bar {',    '  height: 8px;',    '  width: 0px;',    '  background: #55a url(' + imgBase + 'progressbar.png);',    '}',    'v\\:* {',    '  behavior:url(#default#VML);',    '}',    '</style>'  ].join('\n'));})();