/* * GMapEZ -- Turn specially-marked HTML into Google Maps * Copyright (C) July 2005 - May 2006 by Chris Houser <chouser@bluweb.com> * * 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://bluweb.com/chouser/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://bluweb.com/us/chouser/gmapez/';  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 GSmallMapTypeControl() {      GMapTypeControl.call( this, true );    }    GSmallMapTypeControl.prototype = new GMapTypeControl();    GSmallMapTypeControl.prototype.constructor = GSmallMapTypeControl;    window.GSmallMapTypeControl = GSmallMapTypeControl;    var CtrlTable = {      'GLargeMapControl': true,      'GSmallMapControl': true,      'GSmallZoomControl': true,      'GSmallMapTypeControl': true,      'GMapTypeControl': true,      'GScaleControl': true    };    var MapTypeTable = {      'G_MAP_TYPE' : true,      'G_SATELLITE_TYPE' : true,      'G_HYBRID_TYPE' : true,      'G_KATRINA_TYPE' : true    };    var idmarkers = {};    function markerForUrl( url ) {      var matcha = /#(.*)/.exec( url );      if( matcha )        return idmarkers[ matcha[ 1 ] ];      else        return null;    }    function wordMap( str ) {      var wmap = {};      var list = str.split(' ');      for( var j = 0; j < list.length; ++j ) {        wmap[ list[ j ] ] = true;      }      return wmap;    }    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 ],              "infowindowopen",              this,              function(){                GEvent.removeListener( onOpen );                this.chainOpen( i + 1 );              });          this.markers[ i ].doOpen();        }        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);    function EZInfoMarker( ezmap, point, icon, title ) {      this.ezmap = ezmap;      this.point = point;      this.icon = icon;      this.title = title;      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() {      var zoom = null;      if( this.tabs.length > 0 ) {        this.openInfoWindowTabs( this.tabs, {          maxWidth: this.ezmap.div.offsetWidth - 100 } );      }      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();      }    };    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.mapType = undefined;      this.autoBounds = undefined;      this.center = undefined;      this.span = undefined;      this.explicitExtent = false;      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 ) {      for( var node = parentNode.firstChild; node; node = node.nextSibling){        var lastOverlay = this.overlayList[ this.overlayList.length - 1 ];        switch( node.nodeName ) {        case 'A':          var textContent = node.innerHTML.replace( /<[^>]*>/g, '' );          var openThisMarker = /\bOPEN\b/.exec( textContent );          textContent = textContent.replace( /\bOPEN\b/, '' );          textContent = textContent.replace( /^\s*/, '' );          textContent = textContent.replace( /\s*$/, '' );          if( textContent == 'EXTENT' )            this.explicitExtent = true;          var matchll = /\Wll=([-.\d]*),([-.\d]*)/.exec( node.href );          if( matchll ) {            var lat = parseFloat( matchll[1] );            var lng = parseFloat( matchll[2] );            var point = new GLatLng( lat, lng );            if( polyline ) {              polyline.points.push( point );            }            if( textContent == 'EXTENT'                || ( ! this.explicitExtent && this.overlayList.length < 1 ) )            {              this.center = point;              var matchspn = /\Wspn=([-.\d]*),([-.\d]*)/.exec( node.href );              if( matchspn ) {                this.span = new GLatLng(                    parseFloat( matchspn[1] ),                    parseFloat( matchspn[2] ) );              }              var matchtype = /\Wt=(.)/.exec( node.href );              if( matchtype ) {                switch( matchtype[1] ) {                  case 'k': this.mapType = G_SATELLITE_TYPE; break;                  case 'h': this.mapType = G_HYBRID_TYPE; break;                }              }            }            if( textContent != 'EXTENT' ) {              if( ! this.autoBounds ) {                this.autoBounds = new GLatLngBounds( point, point );              }              else {                this.autoBounds.extend( point );              }              var iconmodel = G_DEFAULT_ICON;              var iconbase = 'marker';              var sym = null;              var color = 'ORANGE';              var matchcolor =                  /\b(ORANGE|PURPLE|YELLOW|GREEN|BLUE|RED|AQUA|WHITE|GRAY)\b/                  .exec( textContent );              if( matchcolor )                color = matchcolor[0];              var matchsym =                  /\b([0-9A-Za-z]|BLANK|HASH|DOLLAR|DOT|START|END)\b/                  .exec( textContent );              if( matchsym )                sym = matchsym[ 0 ];              var matchmini = /\bMINI\b/.exec( textContent );              if( matchmini ) {                iconmodel = MiniIcon;                iconbase = 'mini';                sym = 'BLANK';              }              if( sym || ! polyline ) {                var icon = new GIcon( iconmodel );                icon.image = [                  imgBase, 'iconEZ2/', iconbase, '-', color, '-',                  ( sym || 'DOT' ), '.png' ].join('');                var marker = new EZInfoMarker(                    this, point, icon, node.getAttribute('title') );                this.overlayList.push( marker );                idmarkers[ node.id || node.name ] = marker;                if( openThisMarker )                  markerOpener.addMarker( marker );              }            }          }          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              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 ) {                  lastOverlay.infoMapType = window[ typeName ];                  break;                }              }            }            else {              lastOverlay.tabs.push(                  new GInfoWindowTab( node.getAttribute('title'), node ));            }          }          break;        case 'LI':          this.processMarkers( node, polyline );          break;        case 'OL':          var params = { color: null, weight: null, opacity: null };          for( var word in wordMap( node.className ) ) {            var matchparam = /^(color|weight|opacity):(.*)$/.exec( word );            if( matchparam )              params[ matchparam[1] ] = matchparam[2];          }          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 = div.cloneNode( true );      this.div.innerHTML = '';      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 );      // map type      if( this.overlayList.length > 1 && ! this.explicitExtent ) {        this.mapType = null;      }      for( typeName in MapTypeTable ) {        if( typeName in this.classes ) {          this.mapType = window[ typeName ];          break;        }      }      this.mapType = this.mapType || G_MAP_TYPE;      // center and zoom      var viewsize = new GSize( this.div.offsetWidth, this.div.offsetHeight );      var zoomLevel;      if( this.overlayList.length == 1 || this.explicitExtent ) {        if( this.span ) {          zoomLevel = this.mapType.getSpanZoomLevel(              this.center, this.span, viewsize );        }      }      else if( this.overlayList.length > 1 ) {        var sw = this.autoBounds.getSouthWest();        var ne = this.autoBounds.getNorthEast();        this.center = new GLatLng(          ( sw.lat() + ne.lat() ) / 2,          ( sw.lng() + ne.lng() ) / 2 );        zoomLevel = this.mapType.getBoundsZoomLevel( this.autoBounds, viewsize);      }      else {        this.center = new GLatLng( 41.075210, -85.130310 );        zoomLevel = 10;      }      // apply center, zoom, and map type      this.map.setCenter( this.center, zoomLevel, this.mapType );      this.maxstep = Math.floor( this.overlayList.length / overlaysPerStep ) + 2;      this.initOverlays();    };    EZMap.prototype.initOverlays = function() {      var steplimit = Math.min(this.overlayList.length, this.oi+overlaysPerStep);      for( ; this.oi < steplimit; ++this.oi ) {        this.map.addOverlay( this.overlayList[ this.oi ] );        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 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() {      // Find all anchor tags linking to GMapEZ markers      var anchors = document.getElementsByTagName( 'a' );      for( var mi = 0; mi < anchors.length; ++mi ) {        var marker = markerForUrl( anchors[ mi ].href );        if( marker )          GEvent.bindDom( anchors[ mi ], "click", marker, marker.doOpen );      }      // 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;      }    }  })();  document.write( [    '<script src="http://maps.google.com/maps?file=api&v='    + gmapversion + '&key=' + key    + '" type="text/javascript"></script>',    '<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'));})();