text: // Molly Geolocation code
  function submitAutomaticLocation(position, method) {
    $('.location').html(gettext('Location found; please wait while we put a name to it.'))
    $('.location-accuracy').hide()
    $.post(base+'geolocation/', {
      csrfmiddlewaretoken: $(csrfToken).find('[name=csrfmiddlewaretoken]').val(),
      longitude: position.coords.longitude,
      latitude: position.coords.latitude,
      accuracy: position.coords.accuracy,
      method: method,
      format: 'json',
      force: 'True'
    }, locationFound, 'json');
  }
  
  function automaticLocation(position) {
    submitAutomaticLocation(position, 'html5')
  }
  
  function automaticLocationAndSave(position) {
    submitAutomaticLocation(position, 'html5request')
  }
  
  function locationFailure(d) {
    $('.location-accuracy').hide()
    // Show error
    if (d.code == 1) { // PERMISSION_DENIED
      $('.location').html('<i>' + gettext('You did not give permission for the site to know your location.') + '</i>');
      $.post(base+'geolocation/', {
        csrfmiddlewaretoken: $(csrfToken).find('[name=csrfmiddlewaretoken]').val(),
        method: 'denied'
      });
    } else if (d.code == 2 || d.code == 3) { // POSITION_UNAVAILABLE / TIMEOUT
      $('.location').html('<i>' + gettext("We couldn't get a fix on your location right now") + '</i>')
      $.post(base+'geolocation/', {
        csrfmiddlewaretoken: $(csrfToken).find('[name=csrfmiddlewaretoken]').val(),
        method: 'error'
      });
    } else {
      // Unknown error
      $('.location').html('<i>' + gettext('An error occurred') + ': ' + d.message + '</i>')
    }
    // Default back to location after 5 seconds
    window.setTimeout(function() {
      $('.location').text(locationName);
      $('.location-accuracy').show()
    }, 5000);
  }
  
  $(document).bind('molly-page-change', function(){
    if(geo_position_js.init()) {
      // Add automatic location buttons if geolocation API is available
      $('.update-location-form').append('<ul class="link-list location-automatic-list"><li><input type="submit" value="' + gettext('Get location automatically') + '" class="automatic-update as-text-link" /></li></ul>');
      $('.current-location-box p').prepend('<input type="submit" value="' + gettext('Determine location automatically') + '" class="automatic-update automatic-update-button" />')
      $('.automatic-update, .location-automatic-list').click(function(){
        $('.update-location-box').slideUp();
        $('.current-location-box').slideDown();
        $('.alternate-location-box').slideUp();
        $('.location').html(gettext('Please wait while we attempt to determine your location&hellip;'))
        $('.location-accuracy').hide()
        geo_position_js.getCurrentPosition(automaticLocationAndSave, locationFailure, {
          enableHighAccuracy: true,
          maximumAge: 30000
        });
        return false;
      });
      $('.automatic-update, .location-automatic-list').addClass('has-ajax-handler')
    }
    
    // Switch to update view from display
    $('.update-location-form').append('<input type="button" value="' + gettext('Cancel Update') + '" class="cancel-update as-text-link" />');
    $('.current-location-box form input').click(function(){
      $('.current-location-box').hide();
      $('.cancel-update').click(function(){
        $('.update-location-box').slideUp();
        $('.alternate-location-box').slideUp();
        $('.current-location-box').slideDown();
      })
      $('.cancel-update').addClass('has-ajax-handler')
      $('.alternate-location-box').hide();
      $('.update-location-box').slideDown();
      $(window).scrollTop($('#location-box').offset().top)
      return false;
    });
    $('.current-location-box form input').addClass('has-ajax-handler')
    $('.update-location-form').submit(function() {
      $('.update-location-box').slideUp();
      $('.alternate-location-box').slideUp();
      $('.current-location-box').slideDown();
      $('.location').html(gettext('Please wait while we attempt to determine your location&hellip;'))
      $.post(base+'geolocation/', {
        csrfmiddlewaretoken: $(this).find('[name=csrfmiddlewaretoken]').val(),
        format: 'json',
        method: 'geocoded',
        name: $(this).find('.update-location-name').val()
      }, locationFound, 'json');
      return false;
    })
    $('.specific-location-form').submit(specificLocationFormSubmit)
    $('.favourite-location-form').submit(favouriteLocationFormSubmit)
    $('.update-location-form, .specific-location-form, .favourite-location-form').addClass('has-ajax-handler')
  
    // Detect in placeholder tag is supported
    if ('placeholder' in document.createElement('input')) {
      // Translators: Examples of what can be entered into the 'Set location' field, e.g., postcode, partial match, street name
      $('.update-location-name').attr('placeholder', gettext('e.g., OX2 6NN, kebl, St Clements'))
    } else {
      $('.update-location-name').focus(function(){
        $(this).val('');
        $(this).css('color', '#000000')
        $(this).unbind('focus')
      });
      $('.update-location-name').val(gettext('e.g., OX2 6NN, kebl, St Clements'))
      $('.update-location-name').css('color', '#a3a3a3')
    }
  });
  
  $(function(){
    
    if(geo_position_js.init()) {
      // Attempt to do location if available
      if (locationRequired) {
        geo_position_js.getCurrentPosition(automaticLocation, locationFailure, {
          enableHighAccuracy: true,
          maximumAge: 30000
        });
      }
      // If this page is open a while, then automatically send geolocation updates back
      function periodic_location_update(){
        setTimeout(function(){
          geo_position_js.getCurrentPosition(automaticLocation, locationFailure, {
            enableHighAccuracy: true,
            maximumAge: 30000
          });
          periodic_location_update();
        }, 600000)
      }
      if (autoLocationUpdating) {
        periodic_location_update();
      }
    }
  });
  
  function specificLocationForm(location, favourite) {
    f  = '  <form class="specific-location-form" method="post" action="'+base+'geolocation/">'
       +      csrfToken
       + '    <input type="hidden" name="method" value="manual"/>'
       + '    <input type="hidden" name="accuracy" value="'+location.accuracy+'"/>'
       + '    <input type="hidden" name="longitude" value="'+location.location[0]+'"/>'
       + '    <input type="hidden" name="latitude" value="'+location.location[1]+'"/>'
       + '    <input type="hidden" name="return_url" value="'+window.location.pathname+'"/>'
       + '    <input type="hidden" name="name" value="'+location.name+'"/>'
       + '    <input type="submit" class="as-text-link" value="'+location.name+'" style="font-weight: normal;" />'
       + '  </form>'
    if (favourite != null)
    {
      f += '  <form class="favourite-location-form" method="post" action="'+base+'geolocation/favourites/">'
         +      csrfToken
      if (favourite) {
        f += '    <input type="hidden" name="action" value="remove"/>'
           + '    <input type="hidden" name="id" value="'+location.id+'"/>'
           + '    <input type="hidden" name="return_url" value="'+window.location.pathname+'"/>'
           + '    <input type="submit" class="unfavourite" value="(' + gettext('Remove from favourites') + ')"/>'
      } else {
        f += '    <input type="hidden" name="action" value="add"/>'
           + '    <input type="hidden" name="accuracy" value="'+location.accuracy+'"/>'
           + '    <input type="hidden" name="longitude" value="'+location.location[0]+'"/>'
           + '    <input type="hidden" name="latitude" value="'+location.location[1]+'"/>'
           + '    <input type="hidden" name="return_url" value="'+window.location.pathname+'"/>'
           + '    <input type="hidden" name="name" value="'+location.name+'"/>'
           + '    <input type="submit" class="favourite" value="(' + gettext('Add as favourite') + ')"/>'
      }
      f += '  </form>'
    }
    return f
  }
  
  function specificLocationFormSubmit() {
    $('.update-location-box').slideUp();
    $('.alternate-location-box').slideUp();
    $('.current-location-box').slideDown();
    $.post($(this).attr('action'), {
          csrfmiddlewaretoken: $(this).find('[name=csrfmiddlewaretoken]').val(),
          longitude: $(this).find('[name=longitude]').val(),
          latitude: $(this).find('[name=latitude]').val(),
          accuracy: $(this).find('[name=accuracy]').val(),
          name: $(this).find('[name=name]').val(),
          return_url: $(this).find('[name=return_url]').val(),
          method: $(this).find('[name=method]').val(),
          id: $(this).find('[name=id]').val(),
          action: $(this).find('[name=action]').val(),
          format: 'json',
          force: 'True'
      }, locationFound, 'json');
    return false;
  }
  
  function favouriteLocationFormSubmit() {
    $.post($(this).attr('action'), {
          csrfmiddlewaretoken: $(this).find('[name=csrfmiddlewaretoken]').val(),
          longitude: $(this).find('[name=longitude]').val(),
          latitude: $(this).find('[name=latitude]').val(),
          accuracy: $(this).find('[name=accuracy]').val(),
          name: $(this).find('[name=name]').val(),
          return_url: $(this).find('[name=return_url]').val(),
          method: $(this).find('[name=method]').val(),
          id: $(this).find('[name=id]').val(),
          action: $(this).find('[name=action]').val(),
          format: 'json',
          force: 'True'
      }, locationFound, 'json');
    return false;
  }
  
  function locationFound(data) {
    if (data.name) {
      $('.location').html(data.name)
      locationName = data.name
      var within = interpolate(gettext('within approx. %(accuracy)s'),
                               { accuracy: data.accuracy }, true);
      $('.location-accuracy').html(within)
      $('.location-accuracy').show()
      
      if (data.alternatives != null && data.alternatives.length > 0) {
        $('.alternate-location-box').empty()
        $('.alternate-location-box').append( '<div class="header">'
                                           + '  <h2>' + gettext('Or did you mean&hellip;') + '</h2>'
                                           + '</div>'
                                           + '<ul class="alternate-locations-list link-list">'
                                           + '</ul>');
        for (i in data.alternatives) {
          $('.alternate-locations-list').append('<li>' + specificLocationForm(data.alternatives[i], null) + '</li>')
        }
        $('.alternate-location-box').slideDown();
      } else {
        $('.alternate-location-box').slideUp();
      }
      $('.update-location-lists').empty()
      if (data.favourites.length > 0) {
        $('.update-location-lists').append( '<div class="header">'
                                          + '  <h2>' + gettext('Or select a favourite location') + '</h2>'
                                          + '</div>'
                                          + '<ul class="favourite-locations-list link-list">'
                                          + '</ul>');
        for (i in data.favourites) {
          $('.favourite-locations-list').append('<li>' + specificLocationForm(data.favourites[i], true) + '</i>')
        }
      }
      if (data.history.length > 0) {
        $('.update-location-lists').append( '<div class="header">'
                                          + '  <h2>' + gettext('Or select from history') + '</h2>'
                                          + '</div>'
                                          + '<ul class="historic-locations-list link-list">'
                                          + '<li>'
                                          + '    <form class="specific-location-form" method="post" action="'+base+'geolocation/clear/">'
                                          +        csrfToken
                                          + '      <input type="submit" value="' + gettext('Clear history') + '" class="as-text-link" />'
                                          + '    </form>'
                                          + '</li>'
                                          + '</ul>');
        for (i in data.history.reverse()) {
          $('.historic-locations-list').prepend('<li>' + specificLocationForm(data.history[i], false) + '</i>')
        }
      }
      $(document).trigger('molly-location-update')
    } else {
      locationFailure({message: data.error, code: -1})
    }
    $('.specific-location-form').submit(specificLocationFormSubmit)
    $('.favourite-location-form').submit(favouriteLocationFormSubmit)
    $('.update-location-form, .update-location-form, .favourite-location-form').addClass('has-ajax-handler')
    
  }
  
  // Copyright 2007, Google Inc.
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are met:
  //
  //  1. Redistributions of source code must retain the above copyright notice,
  //     this list of conditions and the following disclaimer.
  //  2. Redistributions in binary form must reproduce the above copyright notice,
  //     this list of conditions and the following disclaimer in the documentation
  //     and/or other materials provided with the distribution.
  //  3. Neither the name of Google Inc. nor the names of its contributors may be
  //     used to endorse or promote products derived from this software without
  //     specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
  // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  //
  // Sets up google.gears.*, which is *the only* supported way to access Gears.
  //
  // Circumvent this file at your own risk!
  //
  // In the future, Gears may automatically define google.gears.* without this
  // file. Gears may use these objects to transparently fix bugs and compatibility
  // issues. Applications that use the code below will continue to work seamlessly
  // when that happens.
  
  (function() {
    // We are already defined. Hooray!
    if (window.google && google.gears) {
      return;
    }
  
    var factory = null;
  
    // Firefox
    if (typeof GearsFactory != 'undefined') {
      factory = new GearsFactory();
    } else {
      // IE
      try {
        factory = new ActiveXObject('Gears.Factory');
        // privateSetGlobalObject is only required and supported on IE Mobile on
        // WinCE.
        if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {
          factory.privateSetGlobalObject(this);
        }
      } catch (e) {
        // Safari
        if ((typeof navigator.mimeTypes != 'undefined')
             && navigator.mimeTypes["application/x-googlegears"]) {
          factory = document.createElement("object");
          factory.style.display = "none";
          factory.width = 0;
          factory.height = 0;
          factory.type = "application/x-googlegears";
          document.documentElement.appendChild(factory);
          if(factory && (typeof factory.create == 'undefined')) {
            // If NP_Initialize() returns an error, factory will still be created.
            // We need to make sure this case doesn't cause Gears to appear to
            // have been initialized.
            factory = null;
          }
        }
      }
    }
  
    // *Do not* define any objects if Gears is not installed. This mimics the
    // behavior of Gears defining the objects in the future.
    if (!factory) {
      return;
    }
  
    // Now set up the objects, being careful not to overwrite anything.
    //
    // Note: In Internet Explorer for Windows Mobile, you can't add properties to
    // the window object. However, global objects are automatically added as
    // properties of the window object in all browsers.
    if (!window.google) {
      google = {};
    }
  
    if (!google.gears) {
      google.gears = {factory: factory};
    }
  })();
  
  /*!
   * geo-location-javascript v0.4.3
   * http://code.google.com/p/geo-location-javascript/
   *
   * Copyright (c) 2009 Stan Wiechers
   * Licensed under the MIT licenses.
   *
   * Revision: $Rev$: 
   * Author: $Author$:
   * Date: $Date$:    
   */
  var bb_successCallback;
  var bb_errorCallback;
  var bb_blackberryTimeout_id=-1;
  
  function handleBlackBerryLocationTimeout()
  {
  	if(bb_blackberryTimeout_id!=-1)
  	{
  		bb_errorCallback({message:gettext("Timeout error"), code:3});
  	}
  }
  function handleBlackBerryLocation()
  {
  		clearTimeout(bb_blackberryTimeout_id);
  		bb_blackberryTimeout_id=-1;
          if (bb_successCallback && bb_errorCallback)
          {
                  if(blackberry.location.latitude==0 && blackberry.location.longitude==0)
                  {
                          //http://dev.w3.org/geo/api/spec-source.html#position_unavailable_error
                          //POSITION_UNAVAILABLE (numeric value 2)
                          bb_errorCallback({message:gettext("Position unavailable"), code:2});
                  }
                  else
                  {  
                          var timestamp=null;
                          //only available with 4.6 and later
                          //http://na.blackberry.com/eng/deliverables/8861/blackberry_location_568404_11.jsp
                          if (blackberry.location.timestamp)
                          {
                                  timestamp=new Date(blackberry.location.timestamp);
                          }
                          bb_successCallback({timestamp:timestamp, coords: {latitude:blackberry.location.latitude,longitude:blackberry.location.longitude}});
                  }
                  //since blackberry.location.removeLocationUpdate();
                  //is not working as described http://na.blackberry.com/eng/deliverables/8861/blackberry_location_removeLocationUpdate_568409_11.jsp
                  //the callback are set to null to indicate that the job is done
  
                  bb_successCallback = null;
                  bb_errorCallback = null;
          }
  }
  
  var geo_position_js=function() {
  
          var pub = {};
          var provider=null;
  
          pub.getCurrentPosition = function(successCallback,errorCallback,options)
          {
                  provider.getCurrentPosition(successCallback, errorCallback,options);
          }
  
          pub.init = function()
          {			
                  try
                  {
                          if (typeof(geo_position_js_simulator)!="undefined")
                          {
                                  provider=geo_position_js_simulator;
                          }
                          else if (typeof(bondi)!="undefined" && typeof(bondi.geolocation)!="undefined")
                          {
                                  provider=bondi.geolocation;
                          }
                          else if (typeof(navigator.geolocation)!="undefined")
                          {
                                  var positionWatchId = null;
                                  provider=navigator.geolocation;
                                  pub.getCurrentPosition = function(successCallback, errorCallback, options)
                                  {
                                      if (positionWatchId == null)
                                      {
                                          var positionRequestCount = 0;
                                          var lastPosition = null;
                                          function _successCallback(p, timeout)
                                          {
                                              // Added by Molly project to use watchPosition rather than getCurrentPosition
                                              // to give better accuracy results
                                              positionRequestCount += 1;
                                              clearTimeout(positionWatchTimeout);
                                              lastPosition = p;
                                              if (positionRequestCount > 10 || p.coords.accuracy <= 150 || p.coords.accuracy == 18000 || timeout) {
                                                  provider.clearWatch(positionWatchId);
                                                  positionWatchId = null;
                                                  //for mozilla geode,it returns the coordinates slightly differently
                                                  if(typeof(p.latitude)!="undefined")
                                                  {
                                                      successCallback({timestamp:p.timestamp, coords: {latitude:p.latitude,longitude:p.longitude}});
                                                  }
                                                  else
                                                  {
                                                      successCallback(p);
                                                  }
                                              } else {
                                                  positionWatchTimeout = setTimeout(function(){
                                                      _successCallback(lastPosition, true);
                                                  }, 5000);
                                              }
                                          }
                                          var positionWatchId = provider.watchPosition(_successCallback,errorCallback,options);
                                          var positionWatchTimeout = setTimeout(function(){
                                              provider.getCurrentPosition(function(p, timeout){
                                                provider.clearWatch(positionWatchId);
                                                positionWatchId = null;
                                                successCallback(p);
                                              },errorCallback,$.extend(options, {timeout: 5000}));
                                          }, 5000);
                                      } else {
                                          errorCallback({message: gettext('There is already a location request pending'), code: -1})
                                      }
                                  }
                          }
                           else if(typeof(window.google)!="undefined" && typeof(google.gears)!="undefined")
                          {
                                  provider=google.gears.factory.create('beta.geolocation');
                          }
                          else if ( typeof(Mojo) !="undefined" && typeof(Mojo.Service.Request)!="Mojo.Service.Request")
                          {
                                  provider=true;
                                  pub.getCurrentPosition = function(successCallback, errorCallback, options)
                                  {
  
                                  parameters={};
                                  if(options)
                                  {
                                           //http://developer.palm.com/index.php?option=com_content&view=article&id=1673#GPS-getCurrentPosition
                                           if (options.enableHighAccuracy && options.enableHighAccuracy==true)
                                           {
                                                  parameters.accuracy=1;
                                           }
                                           if (options.maximumAge)
                                           {
                                                  parameters.maximumAge=options.maximumAge;
                                           }
                                           if (options.responseTime)
                                           {
                                                  if(options.responseTime<5)
                                                  {
                                                          parameters.responseTime=1;
                                                  }
                                                  else if (options.responseTime<20)
                                                  {
                                                          parameters.responseTime=2;
                                                  }
                                                  else
                                                  {
                                                          parameters.timeout=3;
                                                  }
                                           }
                                  }
  
  
                                   r=new Mojo.Service.Request('palm://com.palm.location', {
                                          method:"getCurrentPosition",
                                              parameters:parameters,
                                              onSuccess: function(p){successCallback({timestamp:p.timestamp, coords: {latitude:p.latitude, longitude:p.longitude,heading:p.heading}});},
                                              onFailure: function(e){
                                                                  if (e.errorCode==1)
                                                                  {
                                                                          errorCallback({code:3,message:gettext("Timeout error")});
                                                                  }
                                                                  else if (e.errorCode==2)
                                                                  {
                                                                          errorCallback({code:2,message:gettext("Position unavailable")});
                                                                  }
                                                                  else
                                                                  {
                                                                          errorCallback({code:0,message:gettext("Unknown Error") + ": webOS-code"+errorCode});
                                                                  }
                                                          }
                                              });
                                  }
  
                          }
                          else if (typeof(device)!="undefined" && typeof(device.getServiceObject)!="undefined")
                          {
                                  provider=device.getServiceObject("Service.Location", "ILocation");
  
                                  //override default method implementation
                                  pub.getCurrentPosition = function(successCallback, errorCallback, options)
                                  {
                                          function callback(transId, eventCode, result) {
                                              if (eventCode == 4)
                                                  {
                                                  errorCallback({message:gettext("Position unavailable"), code:2});
                                              }
                                                  else
                                                  {
                                                          //no timestamp of location given?
                                                          successCallback({timestamp:null, coords: {latitude:result.ReturnValue.Latitude, longitude:result.ReturnValue.Longitude, altitude:result.ReturnValue.Altitude,heading:result.ReturnValue.Heading}});
                                                  }
                                          }
                                          //location criteria
                                      var criteria = new Object();
                                  criteria.LocationInformationClass = "BasicLocationInformation";
                                          //make the call
                                          provider.ILocation.GetLocation(criteria,callback);
                                  }
                          }
                          else if(typeof(window.blackberry)!="undefined" && blackberry.location.GPSSupported)
                          {
  
                                  // set to autonomous mode
  								if(typeof(blackberry.location.setAidMode)=="undefined")
  								{
  	                                return false;									
  								}
  								blackberry.location.setAidMode(2);
                                  //override default method implementation
                                  pub.getCurrentPosition = function(successCallback,errorCallback,options)
                                  {
  										//alert(parseFloat(navigator.appVersion));
                                          //passing over callbacks as parameter didn't work consistently
                                          //in the onLocationUpdate method, thats why they have to be set
                                          //outside
                                          bb_successCallback=successCallback;
                                          bb_errorCallback=errorCallback;
                                          //function needs to be a string according to
                                          //http://www.tonybunce.com/2008/05/08/Blackberry-Browser-Amp-GPS.aspx
  										if(options['timeout'])  
  										{
  										 	bb_blackberryTimeout_id=setTimeout("handleBlackBerryLocationTimeout()",options['timeout']);
  										}
  										else
  										//default timeout when none is given to prevent a hanging script
  										{
  											bb_blackberryTimeout_id=setTimeout("handleBlackBerryLocationTimeout()",60000);
  										}										
  										blackberry.location.onLocationUpdate("handleBlackBerryLocation()");
                                          blackberry.location.refreshLocation();
                                  }
                                  provider=blackberry.location;				
                          }
                  }
                  catch (e){ 
  					alert("error="+e);
  					if(typeof(console)!="undefined")
  					{
  						console.log(e);
  					}
  					return false;
  				}
                  return  provider!=null;
          }
  
  
          return pub;
  }();
  