function getCookie(name) {
  var start = document.cookie.indexOf(name+"=");
  if(start < 0) { return null; }
  var len = start + name.length + 1;
  var end = document.cookie.indexOf(';',len );
  if(end==-1) { end = document.cookie.length; }
  return unescape(document.cookie.substring(len,end));
}

function setCookie(name,value,maxAgeInSeconds,path,domain,secure ) {
  var expiresDate = null;
  if(maxAgeInSeconds) {
    var today = new Date();
    expiresDate = new Date(today.getTime() + maxAgeInSeconds*1000); 
  }
  var cstr = name+'='+escape(value);
  if(maxAgeInSeconds) { 
    cstr += ';max-age='+maxAgeInSeconds+';expires='+expiresDate.toGMTString();
  }
  if(path) { 
    cstr += ';path='+path;
  }
  if(domain) { 
    cstr += ';domain='+domain;
  }
  if(secure) { 
    cstr += ';secure';
  }
  document.cookie = cstr;
}

function deleteCookie( name, path, domain ) {
  if(getCookie(name)) {
    document.cookie = name + '=' +
      ( ( path ) ? ';path=' + path : '') +
      ( ( domain ) ? ';domain=' + domain : '' ) +
      ';expires=Thu, 01-Jan-1970 00:00:01 GMT;max-age=-1';
  }
}

function add_bike_to_compare_cookie(code) {
  var bsbcl = getCookie('bsbcl');
  var wcode = '|'+code+'|';
  var newval = null;
  if(null === bsbcl || bsbcl.length === 0) {
    newval = wcode;
  } else if(bsbcl.indexOf(wcode) > -1) { 
    return;
  } else {
    newval = bsbcl+wcode;
  }
  if(newval) { setCookie('bsbcl',newval,null,'/'); }  
}

function remove_bike_from_compare_cookie(code) {
  var bsbcl = getCookie('bsbcl');
  var newval = null;
  if(null === bsbcl || bsbcl.length === 0) {
    return;
  } else {
    newval = bsbcl.replace('|'+code+'|','');
    if(newval) {
      setCookie('bsbcl',newval,null,'/');
      return true;
    } else {
      deleteCookie('bsbcl','/');
      return false;
    }
  }
}

function select_for_compare(code) {
  add_bike_to_compare_cookie(code);
  $('#act_unselect_'+code).show().removeClass('hidden');
  $('#act_select_'+code).hide().addClass('hidden');
  $('.act_unselect_all').show().removeClass('hidden');
  $('.act_compare').show().removeClass('hidden');
  $('.act_compare_disabled').hide().addClass('hidden');
}

function unselect_for_compare(code) {
  var someleft = remove_bike_from_compare_cookie(code);
  $('#act_unselect_'+code).hide().addClass('hidden');
  $('#act_select_'+code).show().removeClass('hidden');
  if(!someleft) {
    $('.act_compare').hide().addClass('hidden');
    $('.act_unselect_all').hide().addClass('hidden');
    $('.act_compare_disabled').show().removeClass('hidden');
  }
}

function clear_selected_for_compare() {
  deleteCookie('bsbcl','/');
  $('#act_unselect_'+code).hide().addClass('hidden');
  $('#act_select_'+code).show().removeClass('hidden');
  $('.act_compare').hide().addClass('hidden');
  $('.act_unselect_all').hide().addClass('hidden');
  $('.act_compare_disabled').show().removeClass('hidden');
}


function isIE() {
  if(navigator.userAgent.match(/MSIE \d+\.\d+/)) {
    return true;
  } else {
    return false;
  }
}

function isIE67() {
  if(navigator.userAgent.match(/MSIE [67]\.\d+/)) {
    return true;
  } else {
    return false;
  }
}

function isIOS() {
  if(navigator.userAgent.match(/iPhone/)) {
    return true;
  } else {
    return false;
  }
}

function isAndroid() {
  if(navigator.userAgent.match(/Android/)) {
    return true;
  } else {
    return false;
  }
}

function resetmainbodyzindexforie() {
  if(isIE()) {
    var zi = 1000;
    $('div.mainbody').children('div').each(function() { 
      $(this).css('z-index', zi);
      zi -= 2;
    });
  }
}

function dwe(mto, addr) {
  buf = "";
  if(mto) { buf = buf + 'mai' + 'lt' + 'o:'; }
  buf = buf + addr + '&#' + '64' + 'bright' + 'spoke' +'.com';
  return buf;
} 

function toggleFeedback() {
  $('#block-feedback-form').find('.feedback-link').click();
}

function bounceFeedback() {
  $('#block-feedback-form').find('.feedback-link').animate({height:"+=15px"},100).animate({height:"-=15px"},100).animate({height:"+=15px"},100).animate({height:"-=15px"},100);
//  mp_track('feedback bounce');  
}

$(document).ready(function() {
  if(!isIE()) {
    $('a.pgr,span.pgr').css('border','1px solid #C9CACC').css('background-color','#eee');
  }

  $('a.bikecomparebutton.act_select').hover(
    function() { $(this).css('background-position','0 -20px'); },
    function() { $(this).css('background-position','0 0px'); }
  );

  $('a.bikecomparebutton.act_unselect').hover(
    function() { $(this).css('background-position','0 -60px'); },
    function() { $(this).css('background-position','0 -40px'); }
  );

  $('a.bikecomparebutton.act_compare').hover(
    function() { $(this).css('background-position','0 -100px'); },
    function() { $(this).css('background-position','0 -80px'); }
  );

  $('span.bikecomparebutton.act_compare_disabled').hover(
    function() { $(this).css('background-position','0 -140px'); },
    function() { $(this).css('background-position','0 -120px'); }
  );

  $('label.lblaslink').hover(
    function() { $(this).css('cursor','pointer'); },
    function() { $(this).css('cursor','default'); }
  );

  $('#sbbnimg,#absimg').css('background','url(/img/header_links.png) no-repeat top left');

  $('#sbbnimg').css('height','23px').css('width','193px').css('overflow','hidden').css('margin-left','-12px').css('margin-top','-4px').css('background-position','0 0px');
  $('#sbbnimg').hover(
    function() { $(this).css('background-position','0 -24px').css('cursor','pointer'); },
    function() { $(this).css('background-position','0 0px').css('cursor','default'); }
  );
  $('#sbbnimg').click(function() { $('#edit-biketitle').focus(); });
  $('#sbbnstatic').css('display','none');

  $('#absimg').css('height','17px').css('width','240px').css('overflow','hidden').css('margin-top','2px').css('background-position','-197px -12px');
  $('#absimg').click(function() { window.location = '/t/advanced-bike-search.html'; });
  $('#absimg').hover(
    function() { $(this).css('background-position','-197px -30px').css('cursor','pointer'); },
    function() { $(this).css('background-position','-197px -12px').css('cursor','default'); }
  );
  $('.abstext').css('display','none');

  $('#searchimg').hover(
    function() { $(this).attr('src','/img/search_button_hover.png'); },
    function() { $(this).attr('src','/img/search_button.png'); }
  );
  
  $('input.calc').hover(
    function() { $(this).attr('src','/img/calculate_button_hover.png'); },
    function() { $(this).attr('src','/img/calculate_button.png'); }
  );
  
  $('.mtquestions').html('<a href="' + dwe(true,'questions') + '">' + dwe(false,'questions') + '</a>');
  $('.mtwlb').html('<a href="' + dwe(true,'welovebikes') + '">' + dwe(false,'welovebikes') + '</a>');
  $('.mtfb').html('<a href="' + dwe(true,'feedback') + '">' + dwe(false,'feedback') + '</a>');
  $('tr.searchresult').click(function(event) {
    //console.log(event.target);
    if(!( $(event.target).is('a') || $(event.target).is('img') )) {
      event.preventDefault();
      document.location = $(this).find('a:first').attr('href');
    }
  });
  /*
  $('tr.searchresult').hover(
    function(){ $(this).css('cursor','pointer'); $(this).find('a').each( function() { $(this).addClass('hover'); } ) },
    function(){ $(this).css('cursor','default'); $(this).find('a').each( function() { $(this).removeClass('hover'); } ) });
 */


  // biketitle_autocomplete.js
  $('div.btsearch input[type="text"]').addClass("idleField");
  $('div.btsearch input[type="text"]').focus(function() {
    $(this).removeClass("idleField").addClass("focusField");
    if(this.value == this.defaultValue) {
      this.value = '';
    } else if(this.value != this.defaultValue) {
      this.select();
    }
  // mp_track('bikefinder focus');
  });
  $('div.btsearch input[type="text"]').blur(function() {
    $(this).removeClass("focusField").addClass("idleField");
    if($.trim(this.value) == '') {
      this.value = (this.defaultValue ? this.defaultValue : '');
    }
  });
  $(function() {
    resetmainbodyzindexforie();
  });
  // /biketitle_autocomplete.js
  if($('.comptable').length > 0) {
    $('.comptable').tableHover({colClass: 'comphover', rowClass: 'comphover', cellClass: 'comphover', headRows: false, footRows: true, headCols: false, footCols: true,ignoreCols: [1]});
  }
}); // document.ready

/**
 * Parse a JSON response.
 *
 * The result is either the JSON object, or an object with 'status' 0 and 'data' an error message.
 */
function parseJson(data) {
  if(null === data) { data = ''; }
  if ((data.substring(0, 1) != '{') && (data.substring(0, 1) != '[')) {
    return { status: 0, data: data.length ? data : 'Unspecified error' };
  }
  // alert('calling eval')
  return eval('(' + data + ');');
}

// biketitle_autocomplete.js

/**
 * Attaches the autocomplete behaviour to all required fields
 */
btautocompleteAutoAttach = function () {
  var acdb = [];
  $('div.btsearch input.autocomplete').each(function () {
    var uri = this.value;
    if (!acdb[uri]) {
      acdb[uri] = new ACDB(uri);
    }
    var input = $('#' + this.id.substr(0, this.id.length - 13)).attr('autocomplete', 'OFF')[0];
    $(input.form).submit(btautocompleteSubmit);
    var ignored = new btjsAC(input, acdb[uri]);
  });
};

/**
 * Prevents the form from submitting if the suggestions popup is open
 * and closes the suggestions popup when doing so.
 */
btautocompleteSubmit = function () {
  $('#autocomplete').each(function () { 
    this.owner.hidePopup(); 
    this.owner.setStatus('begin');
  });
  return true;
};

/**
 * An AutoComplete object
 */
btjsAC = function (input, db) {
  var ac = this;
  this.input = input;
  this.db = db;

  $(this.input)
    .keydown(function (event) { return ac.onkeydown(this, event); })
    .keyup(function (event) { ac.onkeyup(this, event); })
    .blur(function () { ac.hidePopup(); ac.db.cancel(); });
};

/**
 * Handler for the "keydown" event
 */
btjsAC.prototype.onkeydown = function (input, e) {
  if (!e) {
    e = window.event;
  }
  switch (e.keyCode) {
    case 40: // down arrow
      this.selectDown();
      return false;
    case 38: // up arrow
      this.selectUp();
      return false;
    default: // all other keys
      return true;
  }
};

/**
 * Handler for the "keyup" event
 */
btjsAC.prototype.onkeyup = function (input, e) {
  if (!e) {
    e = window.event;
  }
  switch (e.keyCode) {
    case 16: // shift
    case 17: // ctrl
    case 18: // alt
    case 20: // caps lock
    case 33: // page up
    case 34: // page down
    case 35: // end
    case 36: // home
    case 37: // left arrow
    case 38: // up arrow
    case 39: // right arrow
    case 40: // down arrow
      return true;

    case 9:  // tab
    case 27: // esc
    case 13: // enter
      this.hidePopup(e.keyCode);      
      return true;

    default: // all other keys
      if (input.value.length > 2) {
        this.populatePopup();
      } else {
        this.hidePopup(e.keyCode);
      }
      return true;
  }
};

/**
 * Puts the currently highlighted suggestion into the autocomplete field
 */
btjsAC.prototype.select = function (node) {
//  mp_track('bikefinder nodeselected');
  this.input.value = node.autocompleteValue;
  this.input.form.submit();
};

/**
 * Highlights the next suggestion
 */
btjsAC.prototype.selectDown = function () {
  if (this.selected && this.selected.nextSibling) {
    this.highlight(this.selected.nextSibling);
  }
  else {
    var lis = $('li', this.popup);
    if (lis.size() > 0) {
      this.highlight(lis.get(0));
    }
  }
};

/**
 * Highlights the previous suggestion
 */
btjsAC.prototype.selectUp = function () {
  if (this.selected && this.selected.previousSibling) {
    this.highlight(this.selected.previousSibling);
  }
};

/**
 * Highlights a suggestion
 */
btjsAC.prototype.highlight = function (node) {
  if (this.selected) {
    $(this.selected).removeClass('selected');
  }
  $(node).addClass('selected');
  this.selected = node;
};

/**
 * Unhighlights a suggestion
 */
btjsAC.prototype.unhighlight = function (node) {
  $(node).removeClass('selected');
  this.selected = false;
};

/**
 * Hides the autocomplete suggestions
 */
btjsAC.prototype.hidePopup = function (keycode) {
  // Select item if the right key or mousebutton was pressed
  if (this.selected && ((keycode && keycode != 46 && keycode != 8 && keycode != 27) || !keycode)) {
    this.input.value = this.selected.autocompleteValue;
  }
  // Hide popup
  var popup = this.popup;
  if (popup) {
    this.popup = null;
    $(popup).fadeOut('fast', function() { $(popup).remove(); });
  }
  this.selected = false;
};

/**
 * Positions the suggestions popup and starts a search
 */
btjsAC.prototype.populatePopup = function () {
  // Show popup
  if (this.popup) {
    $(this.popup).remove();
  }
  this.selected = false;
  this.popup = document.createElement('div');
  this.popup.id = 'autocomplete';
  this.popup.owner = this;
  $(this.popup).css({
    marginTop: this.input.offsetHeight +'px',
    width: (this.input.offsetWidth - 4) +'px',
    display: 'none'
  });

  $(this.input).before(this.popup);

  // Do search
  this.db.owner = this;
  this.db.search(this.input.value);
};

/**
 * Fills the suggestion popup with any matches received
 */
btjsAC.prototype.found = function (matches) {
  // If no value in the textfield, do not show the popup.
  if (!this.input.value.length) {
    return false;
  }
  
  // Prepare matches
  var ul = document.createElement('ul');
  var ac = this;
  fsel = function () { ac.select(this); };
  fhl = function () { ac.highlight(this); };
  fuhl = function () { ac.unhighlight(this); };
  for(var key in matches) {
    var li = document.createElement('li');
    $(li)
      .html('<div>'+ matches[key] +'</div>')
      .mousedown(fsel)
      .mouseover(fhl)
      .mouseout(fuhl);
    li.autocompleteValue = key;
    $(ul).append(li);
  }

  // Show popup with matches, if any
  if (this.popup) {
    if (ul.childNodes.length > 0) {
      $(this.popup).empty().append(ul).show();
    }
    else {
      $(this.popup).css({visibility: 'hidden'});
      this.hidePopup();
    }
  }
};

btjsAC.prototype.setStatus = function (status) {
  switch (status) {
    case 'begin':
      $(this.input).addClass('throbbing');
      break;
    case 'cancel':
    case 'error':
    case 'found':
      $(this.input).removeClass('throbbing');
      break;
  }
};

/**
 * An AutoComplete DataBase object
 */
ACDB = function (uri) {
  this.uri = uri;
  this.delay = 150;
  this.cache = {};
};

/**
 * Performs a cached and delayed search
 */
ACDB.prototype.search = function (searchString) {
//  mp_track('bikefinder search',{'searchString':searchString});
  var db = this;
  searchString = $.trim(searchString.toLowerCase());
  this.searchString = searchString;

  foundincache = this.cache[searchString];
  if(foundincache) { 
    return this.owner.found(foundincache);
  }      

  // Not found in cache, initiate delayed search
  if (this.timer) {
    clearTimeout(this.timer);
  }
  this.timer = setTimeout(function() {
    db.owner.setStatus('begin');

    // Ajax GET request for autocompletion
    $.ajax({
      type: "GET",
      url: db.uri +'?q='+ encodeURIComponent(searchString),
      success: function (data) {
        // Parse back result
        //var matches = parseJson(data);
        var matches = data;
        if (typeof matches['status'] == 'undefined' || matches['status'] != 0) {
          db.cache[searchString] = matches;
          // Verify if these are still the matches the user wants to see
          if (db.searchString == searchString) {
            db.owner.found(matches);
          }
          db.owner.setStatus('found');
        }
      },
      error: function (xmlhttp) {
        //alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ db.uri);
      }
    });
  }, this.delay);
};

/**
 * Cancels the current autocomplete request
 */
ACDB.prototype.cancel = function() {
  if(this.owner) { this.owner.setStatus('cancel'); }
  if(this.timer) { clearTimeout(this.timer); }
  this.searchString = '';
};

$(document).ready(btautocompleteAutoAttach);

/****/
/*

$('.hl')

*/

$(document).ready(function() {
    var oldval;
    var dirty = false;

    function ajax_calc_single() {
      sra = ($('input#sra').val()); 
      sl = ($('input#sl').val()); 
      hta = ($('input#hta').val()); 
      sph = ($('input#sph').val()); 
      $('#stemcalc_single input').each(function() { $(this).addClass('idlef'); });
      $.ajax({
        type: "GET",
        url: '/ajax/stem-calc?sra='+encodeURIComponent(sra)+'&sl='+encodeURIComponent(sl)+'&hta='+encodeURIComponent(hta)+'&sph='+sph,
        success: function (data) {
          $('span.result').each(function() { $(this).animate({ opacity: 0},333,(function() {
            $('span#sa').html(data.nsa + '&deg; (' + data.nsaf + '&deg; when flipped)')
            $('span#sh').html(data.sh + ' mm (' + data.shf + ' mm when flipped)')
            $('span#sr').html(data.sr + ' mm (' + data.srf + ' mm when flipped)')
            $('#stemcalc_single input').each(function() { $(this).removeClass('idlef'); });
          })).animate({opacity: 1},333); });
        },
        error: function (xmlhttp) {
          //console.log('An HTTP error '+ xmlhttp.status +' occured.\n');
          $('#stemcalc_single input').each(function() { $(this).removeClass('idlef'); });
        }
      });
    }
    
    function ajax_calc_double() {
      sra_a = ($('input#sra_a').val()); 
      sl_a = ($('input#sl_a').val()); 
      hta_a = ($('input#hta_a').val()); 
      sph_a = ($('input#sph_a').val()); 
      sra_b = ($('input#sra_b').val()); 
      sl_b = ($('input#sl_b').val()); 
      hta_b = ($('input#hta_b').val()); 
      sph_b = ($('input#sph_b').val());
      $('#stemcalc_double input').each(function() { $(this).addClass('idlef'); });
      $.ajax({
        type: "GET",
        url: '/ajax/stem-calc?form=double&sra_a='+encodeURIComponent(sra_a)+'&sl_a='+encodeURIComponent(sl_a)+'&hta_a='+encodeURIComponent(hta_a)+'&sph_a='+encodeURIComponent(sph_a)+'&sra_b='+encodeURIComponent(sra_b)+'&sl_b='+encodeURIComponent(sl_b)+'&hta_b='+encodeURIComponent(hta_b)+'&sph_b='+encodeURIComponent(sph_b),
        success: function (data) {
         $('span.result').each(function() { $(this).animate({ opacity: 0},333,(function() {
            $('span#sa_a').html(data.nsa_a + '&deg;')
            $('span#sa_b').html(data.nsa_b + '&deg;')
            $('span#sa_d').html(data.nsa_d + '&deg;')
            $('span#sh_a').html(data.sh_a + ' mm')
            $('span#sh_b').html(data.sh_b + ' mm')
            $('span#sh_d').html(data.sh_d + ' mm')
            $('span#sr_a').html(data.sr_a + ' mm')
            $('span#sr_b').html(data.sr_b + ' mm')
            $('span#sr_d').html(data.sr_d + ' mm')
            $('#stemcalc_double input').each(function() { $(this).removeClass('idlef'); });
          })).animate({opacity: 1},333); });
        },
        error: function (xmlhttp) {
          //console.log('An HTTP error '+ xmlhttp.status +' occured.\n');
          $('#stemcalc_double input').each(function() { $(this).removeClass('idlef'); });
        }
      });
    }

    function calculate_single(setdirty) {
      _calculate('single',setdirty);
    }

    function calculate_double(setdirty) {
      _calculate('double',setdirty);
    }

    function _calculate(whichform,setdirty) {
      var abortpost = false;
//      $('#stemcalc_'+whichform+' input').each(function() { if($(this).is('.focusf')) { abortpost = true; } });
      if(whichform == 'single' && $('#tab_two').is('.active_tab')) { abortpost = true; }
      if(whichform == 'double' && $('#tab_one').is('.active_tab')) { abortpost = true; }
      if(!abortpost) {
        if(whichform == 'single') {
          ajax_calc_single();
        } else {
          ajax_calc_double();
        }
      } else if(setdirty) {
        dirty = true;
      }            
    }

      $('#calc_single').click(function() { 
        ajax_calc_single();
        return false;
      });
    
      $('#calc_double').click(function() { 
        ajax_calc_double();
        return false;
      });
    
    var $stem_calc_img_div = $('#stem_calc_img_div');

    function unhl() { $stem_calc_img_div.css('background-position','0 0'); }
    function hlsl() { $stem_calc_img_div.css('background-position','0 -366px');}
    function hlsra() { $stem_calc_img_div.css('background-position','0 -732px'); }
    function hlsph() { $stem_calc_img_div.css('background-position','0 -1098px'); }
    function hlhta() { $stem_calc_img_div.css('background-position','0 -1464px'); }
    function hlsr() { $stem_calc_img_div.css('background-position','0 -1830px'); }
    function hlsa() { $stem_calc_img_div.css('background-position','-292px 0'); }
    function hlsh() { $stem_calc_img_div.css('background-position','-292px -366px'); }
    
    $('#stem_calc_img_div').css('background','url(/img/stem_calc_sprite.png) no-repeat top left');
    setTimeout(function() { $('#stem_calc_img_img').css('display','none'); },200);
    
    $('.hl').mouseout(function() { unhl(); });
    $('.hlsl').mouseover(function() { hlsl(); });
    $('.hlsra').mouseover(function() { hlsra(); });
    $('.hlhta').mouseover(function() { hlhta(); });
    $('.hlsph').mouseover(function() { hlsph(); });
    $('.hlsr').mouseover(function() { hlsr(); });
    $('.hlsa').mouseover(function() { hlsa(); });
    $('.hlsh').mouseover(function() { hlsh(); });

    $('div.tab').hover(
      function(){ if($(this).is('.inactive_tab')) { $(this).addClass('hover_tab').css('cursor','pointer'); } },
      function(){ $(this).removeClass('hover_tab').css('cursor','default'); }
    );

    $('div#tab_one').click(function() {
      if($(this).is('.inactive_tab')) {
        $('div#tab_one').removeClass('inactive_tab').addClass('active_tab').removeClass('hover_tab');
        $('div#single').removeClass('hidden').show();
        $('div#double').addClass('hidden').hide();
        $('div#tab_two').removeClass('active_tab').addClass('inactive_tab');
        if(dirty) { calculate_single(); }
      }
    });
    $('div#tab_two').click(function() {
      if($(this).is('.inactive_tab')) {
        $('div#tab_two').removeClass('inactive_tab').addClass('active_tab').removeClass('hover_tab');
        $('div#double').removeClass('hidden').show();
        $('div#single').addClass('hidden').hide();
        $('div#tab_one').removeClass('active_tab').addClass('inactive_tab');
        if(dirty) { calculate_double(); }
      }
    });
    $('.stemcalc input').focus(function() { 
      oldval = $(this).val(); 
      $(this).removeClass('errf').addClass('focusf').select(); 
    });
    $('form#stemcalc_single input').blur(function() { 
      $(this).removeClass('focusf');
      if(dirty) { setTimeout(function() { calculate_single(false); }, 333); }
    });
    $('form#stemcalc_double input').blur(function() { 
      $(this).removeClass('focusf');
      if(dirty) { setTimeout(function() { calculate_double(false); }, 333); }
    });

    $('.calc').mouseover(function() { $(this).addClass('focusf'); });
    $('.calc').mouseout(function() { $(this).removeClass('focusf'); });

    $('#stemcalc_single input').change(function() {
      if($(this).val() == '' || isNaN( $(this).val() )) { 
        $(this).addClass("errf");
        var elt =$(this);
        var val = oldval;
        setTimeout(function() {
          elt.removeClass("errf");
          elt.val(val); 
        },500);
      } else {
          if(($(this).attr('id') == 'sra' || $(this).attr('id') == 'sra_a' || $(this).attr('id') == 'sra_b') && $(this).val() > 45) {
            $(this).addClass("autocorrectf");
            $(this).val($(this).val()-90);
            var elt = $(this);
            setTimeout(function() { elt.removeClass("autocorrectf"); },300);
          }
          setTimeout(function() { calculate_single(true); }, 333);
      }
    });
    $('#stemcalc_double input').change(function() {
      if($(this).val() == '' || isNaN( $(this).val() )) { 
        $(this).addClass("errf");
        var elt =$(this);
        var val = oldval;
        setTimeout(function() {
          elt.removeClass("errf");
          elt.val(val); 
        },500);
      } else {
          if(($(this).attr('id') == 'sra' || $(this).attr('id') == 'sra_a' || $(this).attr('id') == 'sra_b') && $(this).val() > 45) {
            $(this).addClass("autocorrectf");
            $(this).val($(this).val()-90);
            var elt = $(this);
            setTimeout(function() { elt.removeClass("autocorrectf"); },300);
          }
          setTimeout(function() { calculate_double(true); }, 333);
      }
    });
    
});

/******feedback.js******************/
feedbackSetup = function() {
  $block = $('#block-feedback-form');
  $block.children().eq(0)
    .wrap('<div class="feedback-link"></div>').parent()
    .prepend('<span id="feedback-form-toggle">[ + ]</span> ')
    .css('cursor', 'pointer')
    .toggle(function() {
        feedbackFormToggle(this, false);
      },
      function() {
        feedbackFormToggle(this, true);
      }
    );
  $block.find('form')
    .find(':input[name="ajax"]').val(1).end()
    .submit(function() {
      $('#feedback-submit', this).fadeOut('fast', function() {
        feedbackFormSubmit($(this).parents('form').get(0));
      });
      return false;
    });
  // Attach auto-submit to admin view form.
  $('fieldset.feedback-messages :input[type="checkbox"]').click(function() {
    $(this).parents('form').submit();
  });
  $block.show();
};

feedbackFormToggle = function(node, enable) {
  $(node).parent().find('.content').slideToggle('medium');
  if(enable) {
    $('#feedback-form-toggle', node).html('[ + ]');
  } else {
    $('#feedback-form-toggle', node).html('[ &minus; ]');
  }
};

feedbackFormSubmit = function(form) {
  var $form = $(form);
  $.post(form.action, $form.serialize(), function(data) {
    // Collapse the form.
    $('#block-feedback-form').find('.feedback-link').click();
    // Display status message.
    $form.parent().parent().append('<div id="feedback-status-message">' + data.message + '</div>');
    // Reset form values.
    $(':input[name="message"]', $form).val('');
    $('#feedback-submit', $form).show();
    // Blend out status message.
    window.setTimeout(function() {
      $('#feedback-status-message').fadeOut('slow', function() {
        $(this).remove();
      });
    }, 3000);
  }, 'json');
//  mp_track('feedback submit');
  return false;
};

  $(document).ready(function() {
    feedbackSetup();
  });

/****bike.js**********************/
(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY;};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev]);}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev]);};var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;while(p&&p!=this){try{p=p.parentNode;}catch(e){p=this;}}if(p==this){return false;}var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);}if(e.type=="mouseover"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);},cfg.timeout);}}};return this.mouseover(handleHover).mouseout(handleHover);};})(jQuery);
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(9($){2 q=9(a){2 b=a.w;2 d=b.8;2 e=[];6(2 i=0;i<d;i++){2 f=b[i].Z;2 g=f.8;6(2 j=0;j<g;j++){2 c=f[j];2 h=c.12||1;2 n=c.10||1;2 o=-1;3(!e[i]){e[i]=[]}2 m=e[i];z(m[++o]){}c.E=o;6(2 k=i;k<i+h;k++){3(!e[k]){e[k]=[]}2 p=e[k];6(2 l=o;l<o+n;l++){p[l]=1}}}}};2 u=9(a){2 v=0,i,k,r=(a.Y)?a.Y.w:0;3(r){6(i=0;i<r.8;i++){r[i].T=v++}}6(k=0;k<a.H.8;k++){r=a.H[k].w;3(r){6(i=0;i<r.8;i++){r[i].T=v++}}}r=(a.W)?a.W.w:0;3(r){6(i=0;i<r.8;i++){r[i].T=v++}}};$.U.1D=9(m){2 n=$.1A({1o:5,1n:5,1r:5,1i:B,1g:5,1f:B,1e:5,1d:B,1c:5,1b:B,1a:5,19:[],17:B,16:5,15:B,K:\'1s\',J:\'\',I:\'\',G:\'\'},m);1q V.1E(9(){2 d=[],A=[],4=V,r,13=0,L=[-1,-1];3(!4.H||!4.H.8){1q}2 f=9(a,b){2 c,X,S,N,7,s;6(S=0;S<a.8;S++,13++){X=a[S];6(N=0;N<X.Z.8;N++){c=X.Z[N];3((b==\'R\'&&n.1g)||(b==\'Q\'&&n.1f)||(b==\'P\'&&n.1i)){s=c.12;z(--s>=0){A[13+s].1p(c)}}3((b==\'R\'&&n.1c)||(b==\'P\'&&n.1d)||(b==\'Q\'&&n.1b)){s=c.10;z(--s>=0){7=c.E+s;3($.1C(7+1,n.19)>-1){1B}3(!d[7]){d[7]=[]}d[7].1p(c)}}3((b==\'R\'&&n.1n)||(b==\'P\'&&n.1o)||(b==\'Q\'&&n.1r)){c.C=5}}}};2 g=9(e){2 p=e.11;z(p!=V&&p.C!==5){p=p.D}3(p.C===5){l(p,5)}};2 j=9(e){2 p=e.11;z(p!=V&&p.C!==5){p=p.D}3(p.C===5){l(p,B)}};2 k=9(e){2 t=e.11;z(t&&t!=4&&!t.C)t=t.D;3(t.C&&n.G!=\'\'){2 x=t.E,y=t.D.T,s=\'\';$(\'1m.\'+n.G+\', 1l.\'+n.G,4).1k(n.G);3(x!=L[0]||y!=L[1]){3(n.K!=\'\'){s+=\',.\'+n.K}3(n.J!=\'\'){s+=\',.\'+n.J}3(n.I!=\'\'){s+=\',.\'+n.I}3(s!=\'\'){$(\'1m, 1l\',4).1z(s.1y(1)).18(n.G)}L=[x,y]}1h{L=[-1,-1]}}};2 l=9(a,b){3(b){$.U.M=$.U.18}1h{$.U.M=$.U.1k}2 h=d[a.E]||[],F=[],i=0,7,O;3(n.J!=\'\'){z(n.1a&&++i<a.10&&d[a.E+i]){h=h.14(d[a.E+i])}$(h).M(n.J)}3(n.K!=\'\'){7=a.D.T;3(A[7]){F=F.14(A[7])}i=0;z(n.1e&&++i<a.12){3(A[7+i]){F=F.14(A[7+i])}}$(F).M(n.K)}3(n.I!=\'\'){O=a.D.D.1x.1w();3((O==\'R\'&&n.16)||(O==\'P\'&&n.17)||(O==\'Q\'&&n.15)){$(a).M(n.I)}}};q(4);u(4);6(r=0;r<4.w.8;r++){A[r]=[]}3(4.Y){f(4.Y.w,\'P\')}6(r=0;r<4.H.8;r++){f(4.H[r].w,\'R\')}3(4.W){f(4.W.w,\'Q\')}$(V).1j(\'1v\',g).1j(\'1u\',j).1t(k)})}})(1F);',62,104,'||var|if|tbl|true|for|rI|length|function|||||||||||||||||||||||rows|||while|rowIndex|false|thover|parentNode|realIndex|rH|clickClass|tBodies|cellClass|colClass|rowClass|lastClick|tableHoverHover|cI|nn|THEAD|TFOOT|TBODY|rowI|realRIndex|fn|this|tFoot|row|tHead|cells|colSpan|target|rowSpan|rCnt|concat|footCells|bodyCells|headCells|addClass|ignoreCols|spanCols|footCols|bodyCols|headCols|spanRows|footRows|bodyRows|else|headRows|bind|removeClass|th|td|allowBody|allowHead|push|return|allowFoot|hover|click|mouseout|mouseover|toUpperCase|nodeName|substring|filter|extend|break|inArray|tableHover|each|jQuery'.split('|'),0,{}));
clickedrow = -1;
function resetZindices(zi) {
  if(isIE()) {
    $('.hint',this).ancestors('div').each(function() { 
      $(this).css('z-index', zi);
      zi -= 2;
    });
  } 
}

  $(document).ready(function() {
    $('#bike_geometry').tableHover({colClass: 'hover', cellClass: 'hovercell', clickClass: 'click', headRows: true, footRows: true, headCols: true, footCols: true}); 

    $('#bike_geometry td').click(function(event){
      var row = $(event.target).parent().parent().children().index($(event.target).parent());
      if(row == clickedrow) {
        clickedrow = -1;
      } else {
        clickedrow = row;
      }
    });

   $('#bike_geometry th').click(function() { 
     clickedrow = -1; 
     $('#sketch').css('backgroundPosition','0px 0px');
   });

   $('#bike_geometry td').hover(
     function(){
       var row = $(this).parent().parent().children().index($(this).parent());
       $('#sketch').css('backgroundPosition','0px -' + (row*300) + 'px');
     },
     function() {
      var row = clickedrow;
      if(row == -1) { row = 0; }
      $('#sketch').css('backgroundPosition','0px -' + (row*300) + 'px');
    });
 
 
    var hoverconfig = {    
     sensitivity: 3, // number = sensitivity threshold (must be 1 or higher)    
     interval: 250, // number = milliseconds for onMouseOver polling interval    
     over: function() { // function = onMouseOver callback (REQUIRED) 
       $('.hint',this).fadeIn();
       resetZindices(2000);
       var is_empty = $('.hint',this).text().length == 0;
       var hint_type = $('.label',this).text();
//       mp_track('hint open',{'is_empty':is_empty,'hint_type':hint_type});
     },
     timeout: 500, // number = milliseconds delay before onMouseOut    
     out: function() { // function = onMouseOut callback (REQUIRED)
       $('.hint',this).fadeOut();
//       resetZindices(1000);
       var is_empty = $('.hint',this).text().length == 0;
       var hint_type = $('.label',this).text();
//       mp_track('hint close',{'is_empty':is_empty,'hint_type':hint_type});
     }     
    };    
   $('.hintwrap').hoverIntent(hoverconfig);
   $('.hintmorelink').click(
     function(event) {
       $t = $(this);
       event.preventDefault();
       if($t.text() == '[show more]') {
         $t.parent().siblings('.hintmoretext').fadeIn('fast'); 
         $t.html('[show less]');         
//         mp_track('hint show more');
       } else {
         $t.parent().siblings('.hintmoretext').fadeOut('fast'); 
         $t.html('[show more]');         
//         mp_track('hint show less');
       }
     }
   );

  }); // document.ready
  
function strip_commas_and_whitespace(str) {
  return str.replace(',','').replace(' ','');
}

function cost_focus(fldid,defval) {
  $f = $(fldid);
  $f.removeClass("idlef").addClass("focusf");
  if($f.val() == defval) {
    $f.val('');
  } else {
    $f.select();
  }
}

function cost_blur(fldid,defval) {
  $f = $(fldid);
  $f.val(strip_commas_and_whitespace($f.val()));
  $f.removeClass("focusf");
  if($.trim($f.val()) == '' || $.trim($f.val()) == defval) {
    $f.addClass("idlef");
    $f.val(defval);
    $('#cwarn').text('');
  } else if(isNaN($.trim($f.val()))) {
    $f.addClass("errf");
    $('#cwarn').text('<- Must be number.');
    setTimeout(function() {
      $f.removeClass("errf");
      $f.addClass("idlef");        
      $f.val(defval);
      $('#cwarn').text('');
     },1200);
  }
}

$(document).ready(function() {

    $('#advsearch').bind("submit",function() {
      if($('#clt').val() == 'max') { $('#clt').val(''); }
      if($('#cgt').val() == 'min') { $('#cgt').val(''); }
    });

    $('#advsearch select').focus(function() { $(this).removeClass('idlef').removeClass('whitebg').addClass('focusf');});
    $('#advsearch select').blur(function() { 
      $(this).removeClass('focusf'); 
      if($(this).val()=='') {
        $(this).addClass('idlef');
      } else {
        $(this).addClass('whitebg');
      }
    });

    $('#advsearch select').each(function() { 
      if($(this).val()=='') { 
        $(this).addClass('idlef'); 
      } else {
        $(this).addClass('whitebg');
      } 
    });
    
    $('#search').hover(
      function() { $(this).css('background-position','0 -23px'); },  
      function() { $(this).css('background-position','0 0'); }
    );  
    $('#search').mousedown(
      function() { $(this).css('background-position','0 -46px'); }
    );
    $('#search').mouseup(
      function() { $(this).css('background-position','0 -23px'); }
    );
        
    $('#togglemore').click(function(event) {
      event.preventDefault();
      var $moreoptions = $('div#moreoptions');
      if($moreoptions.is('.hidden')) {
        $moreoptions.removeClass('hidden');
//        $moreoptions.slideDown('slow')
        $(this).html('[-] fewer options');
      } else {   
        $moreoptions.addClass('hidden');
//        $moreoptions.slideUp('slow');
        $(this).html('[+] more options');
      }
    });

/*
    $('#togglemoreg').click(function(event) {
      event.preventDefault();
      var $moreoptionsg = $('div#moreoptionsg');
      if($moreoptionsg.is('.hidden')) {
        $moreoptionsg.slideDown()
        $moreoptionsg.removeClass('hidden');
        $(this).html('gears/speeds [-]');
      } else {   
        $moreoptionsg.slideUp();
        $moreoptionsg.addClass('hidden');
        $(this).html('gears/speeds [+]');
      }
    });
*/    
    if($('#clt').val()=='' || $('#clt').val()=='max') {
      $('#clt').val('max').addClass("idlef");
    }
    if($('#cgt').val()=='' || $('#cgt').val()=='min') {
      $('#cgt').val('min').addClass("idlef");
    }
    $('#clt').focus(function() { cost_focus('#clt','max') });
    $('#cgt').focus(function() { cost_focus('#cgt','min') });
    $('#clt').blur(function() { cost_blur('#clt','max') });
    $('#cgt').blur(function() { cost_blur('#cgt','min') });
  });  
  
/****** drag table **********/
/*
  dragtable v1.0
  June 26, 2008
  Dan Vanderkam, http://danvk.org/dragtable/
                 http://code.google.com/p/dragtable/

  Instructions:
    - Download this file
    - Add <script src="dragtable.js"></script> to your HTML.
    - Add class="draggable" to any table you might like to reorder.
    - Drag the headers around to reorder them.

  This is code was based on:
    - Stuart Langridge's SortTable (kryogenix.org/code/browser/sorttable)
    - Mike Hall's draggable class (http://www.brainjar.com/dhtml/drag/)
    - A discussion of permuting table columns on comp.lang.javascript

  Licensed under the MIT license.
 */

// Here's the notice from Mike Hall's draggable script:
//*****************************************************************************
// Do not remove this notice.
//
// Copyright 2001 by Mike Hall.
// See http://www.brainjar.com for terms of use.
//*****************************************************************************
dragtable = {
  // How far should the mouse move before it's considered a drag, not a click?
  dragRadius2: 100,
  setMinDragDistance: function(x) {
    dragtable.dragRadius2 = x * x;
  },

  // How long should cookies persist? (in days)
  cookieDays: 365,
  setCookieDays: function(x) {
    dragtable.cookieDays = x;
  },

  // Determine browser and version.
  Browser: function() {
    var ua, s, i;

    this.isIE    = false;
    this.isNS    = false;
    this.version = null;
    ua = navigator.userAgent;

    s = "MSIE";
    if ((i = ua.indexOf(s)) >= 0) {
      this.isIE = true;
      this.version = parseFloat(ua.substr(i + s.length));
      return;
    }

    s = "Netscape6/";
    if ((i = ua.indexOf(s)) >= 0) {
      this.isNS = true;
      this.version = parseFloat(ua.substr(i + s.length));
      return;
    }

    // Treat any other "Gecko" browser as NS 6.1.
    s = "Gecko";
    if ((i = ua.indexOf(s)) >= 0) {
      this.isNS = true;
      this.version = 6.1;
      return;
    }
  },
  browser: null,

  // Detect all draggable tables and attach handlers to their headers.
  init: function() {
    // Don't initialize twice
    if (arguments.callee.done) return;
    arguments.callee.done = true;
    if (_dgtimer) clearInterval(_dgtimer);
    if (!document.createElement || !document.getElementsByTagName) return;

    dragtable.dragObj.zIndex = 0;
    dragtable.browser = new dragtable.Browser();
    forEach(document.getElementsByTagName('table'), function(table) {
      if (table.className.search(/\bdraggable\b/) != -1) {
        dragtable.makeDraggable(table);
      }
    });
  },

  // The thead business is taken straight from sorttable.
  makeDraggable: function(table) {
    if (table.getElementsByTagName('thead').length == 0) {
      the = document.createElement('thead');
      the.appendChild(table.rows[0]);
      table.insertBefore(the,table.firstChild);
    }

    // Safari doesn't support table.tHead, sigh
    if (table.tHead == null) {
      table.tHead = table.getElementsByTagName('thead')[0];
    }

    var headers = table.tHead.rows[0].cells;
    for (var i = 0; i < headers.length; i++) {
      headers[i].onmousedown = dragtable.dragStart;
    }

		// Replay reorderings from cookies if there are any.
		if (dragtable.cookiesEnabled() && table.id &&
				table.className.search(/\bforget-ordering\b/) == -1) {
			dragtable.replayDrags(table);
		}
  },

  // Global object to hold drag information.
  dragObj: new Object(),

  // Climb up the DOM until there's a tag that matches.
  findUp: function(elt, tag) {
    do {
      if (elt.nodeName && elt.nodeName.search(tag) != -1)
        return elt;
    } while (elt = elt.parentNode);
    return null;
  },

  // clone an element, copying its style and class.
  fullCopy: function(elt, deep) {
    var new_elt = elt.cloneNode(deep);
    new_elt.className = elt.className;
    forEach(elt.style,
        function(value, key, object) {
          if (value == null) return;
          if (typeof(value) == "string" && value.length == 0) return;

          new_elt.style[key] = elt.style[key];
        });
    return new_elt;
  },

  eventPosition: function(event) {
    var x, y;
    if (dragtable.browser.isIE) {
      x = window.event.clientX + document.documentElement.scrollLeft
        + document.body.scrollLeft;
      y = window.event.clientY + document.documentElement.scrollTop
        + document.body.scrollTop;
      return {x: x, y: y};
    }
    return {x: event.pageX, y: event.pageY};
  },

 // Determine the position of this element on the page. Many thanks to Magnus
 // Kristiansen for help making this work with "position: fixed" elements.
 absolutePosition: function(elt, stopAtRelative) {
   var ex = 0, ey = 0;
   do {
     var curStyle = dragtable.browser.isIE ? elt.currentStyle
                                           : window.getComputedStyle(elt, '');
     var supportFixed = !(dragtable.browser.isIE &&
                          dragtable.browser.version < 7);
     if (stopAtRelative && curStyle.position == 'relative') {
       break;
     } else if (supportFixed && curStyle.position == 'fixed') {
       // Get the fixed el's offset
       ex += parseInt(curStyle.left, 10);
       ey += parseInt(curStyle.top, 10);
       // Compensate for scrolling
       ex += document.body.scrollLeft;
       ey += document.body.scrollTop;
       // End the loop
       break;
     } else {
       ex += elt.offsetLeft;
       ey += elt.offsetTop;
     }
   } while (elt = elt.offsetParent);
   return {x: ex, y: ey};
 },

  // MouseDown handler -- sets up the appropriate mousemove/mouseup handlers
  // and fills in the global dragtable.dragObj object.
  dragStart: function(event, id) {
    $('body').css('cursor', 'move');     
    var el;
    var x, y;
    var dragObj = dragtable.dragObj;

    var browser = dragtable.browser;
    if (browser.isIE)
      dragObj.origNode = window.event.srcElement;
    else
      dragObj.origNode = event.target;
    var pos = dragtable.eventPosition(event);

    // Drag the entire table cell, not just the element that was clicked.
    dragObj.origNode = dragtable.findUp(dragObj.origNode, /T[DH]/);

    // Since a column header can't be dragged directly, duplicate its contents
    // in a div and drag that instead.
    var table = dragtable.findUp(dragObj.origNode, "TABLE");
    dragObj.table = table;
    dragObj.startCol = dragtable.findColumn(table, pos.x);
    if (dragObj.startCol == -1) return;

    var new_elt = dragtable.fullCopy(table, false);
    new_elt.style.margin = '0';

    // Copy the entire column
    var copySectionColumn = function(sec, col) {
      var new_sec = dragtable.fullCopy(sec, false);
      forEach(sec.rows, function(row) {
        var cell = row.cells[col];
        var new_tr = dragtable.fullCopy(row, false);
        if (row.offsetHeight) new_tr.style.height = row.offsetHeight + "px";
        var new_td = dragtable.fullCopy(cell, true);
        if (cell.offsetWidth) new_td.style.width = cell.offsetWidth + "px";
        new_tr.appendChild(new_td);
        new_sec.appendChild(new_tr);
      });
      return new_sec;
    };

    // First the heading
    if (table.tHead) {
      new_elt.appendChild(copySectionColumn(table.tHead, dragObj.startCol));
    }
    forEach(table.tBodies, function(tb) {
      new_elt.appendChild(copySectionColumn(tb, dragObj.startCol));
    });
    if (table.tFoot) {
      new_elt.appendChild(copySectionColumn(table.tFoot, dragObj.startCol));
    }

    var obj_pos = dragtable.absolutePosition(dragObj.origNode, true);
    new_elt.style.position = "absolute";
    new_elt.style.left = obj_pos.x + "px";
    new_elt.style.top = obj_pos.y + "px";
    new_elt.style.width = dragObj.origNode.offsetWidth + "px";
    new_elt.style.height = dragObj.origNode.offsetHeight + "px";
    new_elt.style.opacity = 0.7;

    // Hold off adding the element until this is clearly a drag.
    dragObj.addedNode = false;
    dragObj.tableContainer = dragObj.table.parentNode || document.body;
    dragObj.elNode = new_elt;

    // Save starting positions of cursor and element.
    dragObj.cursorStartX = pos.x;
    dragObj.cursorStartY = pos.y;
    dragObj.elStartLeft  = parseInt(dragObj.elNode.style.left, 10);
    dragObj.elStartTop   = parseInt(dragObj.elNode.style.top,  10);

    if (isNaN(dragObj.elStartLeft)) dragObj.elStartLeft = 0;
    if (isNaN(dragObj.elStartTop))  dragObj.elStartTop  = 0;

    // Update element's z-index.
    dragObj.elNode.style.zIndex = ++dragObj.zIndex;

    // Capture mousemove and mouseup events on the page.
    if (browser.isIE) {
      document.attachEvent("onmousemove", dragtable.dragMove);
      document.attachEvent("onmouseup",   dragtable.dragEnd);
      window.event.cancelBubble = true;
      window.event.returnValue = false;
    } else {
      document.addEventListener("mousemove", dragtable.dragMove, true);
      document.addEventListener("mouseup",   dragtable.dragEnd, true);
      event.preventDefault();
    }
  },

  // Move the floating column header with the mouse
  dragMove: function(event) {
    var x, y;
    var dragObj = dragtable.dragObj;

    // Get cursor position with respect to the page.
    var pos = dragtable.eventPosition(event);

    var dx = dragObj.cursorStartX - pos.x;
    var dy = dragObj.cursorStartY - pos.y;
    if (!dragObj.addedNode && dx * dx + dy * dy > dragtable.dragRadius2) {
      dragObj.tableContainer.insertBefore(dragObj.elNode, dragObj.table);
      dragObj.addedNode = true;
    }

    // Move drag element by the same amount the cursor has moved.
    var style = dragObj.elNode.style;
    style.left = (dragObj.elStartLeft + pos.x - dragObj.cursorStartX) + "px";
    style.top  = (dragObj.elStartTop  + pos.y - dragObj.cursorStartY) + "px";

    if (dragtable.browser.isIE) {
      window.event.cancelBubble = true;
      window.event.returnValue = false;
    } else {
      event.preventDefault();
    }
  },

  // Stop capturing mousemove and mouseup events.
  // Determine which (if any) column we're over and shuffle the table.
  dragEnd: function(event) {
    $('body').css('cursor', 'default');     
    if (dragtable.browser.isIE) {
      document.detachEvent("onmousemove", dragtable.dragMove);
      document.detachEvent("onmouseup", dragtable.dragEnd);
    } else {
      document.removeEventListener("mousemove", dragtable.dragMove, true);
      document.removeEventListener("mouseup", dragtable.dragEnd, true);
    }

    // If the floating header wasn't added, the mouse didn't move far enough.
    var dragObj = dragtable.dragObj;
    if (!dragObj.addedNode) {
      return;
    }
    dragObj.tableContainer.removeChild(dragObj.elNode);

    // Determine whether the drag ended over the table, and over which column.
    var pos = dragtable.eventPosition(event);
    var table_pos = dragtable.absolutePosition(dragObj.table);
    if (pos.y < table_pos.y ||
        pos.y > table_pos.y + dragObj.table.offsetHeight) {
      return;
    }
    var targetCol = dragtable.findColumn(dragObj.table, pos.x);
    if (targetCol != -1 && targetCol != dragObj.startCol) {
      dragtable.moveColumn(dragObj.table, dragObj.startCol, targetCol);
      if (dragObj.table.id && dragtable.cookiesEnabled() &&
					dragObj.table.className.search(/\bforget-ordering\b/) == -1) {
        dragtable.rememberDrag(dragObj.table.id, dragObj.startCol, targetCol);
      }
    }
  },

  // Which column does the x value fall inside of? x should include scrollLeft.
  findColumn: function(table, x) {
    var header = table.tHead.rows[0].cells;
    for (var i = 0; i < header.length; i++) {
      //var left = header[i].offsetLeft;
      var pos = dragtable.absolutePosition(header[i]);
      //if (left <= x && x <= left + header[i].offsetWidth) {
      if (pos.x <= x && x <= pos.x + header[i].offsetWidth) {
        return i;
      }
    }
    return -1;
  },

  // Move a column of table from start index to finish index.
  // Based on the "Swapping table columns" discussion on comp.lang.javascript.
  // Assumes there are columns at sIdx and fIdx
  moveColumn: function(table, sIdx, fIdx) {
    var row, cA;
    var i=table.rows.length;
    while (i--){
      row = table.rows[i]
      var x = row.removeChild(row.cells[sIdx]);
      if (fIdx < row.cells.length) {
        row.insertBefore(x, row.cells[fIdx]);
      } else {
        row.appendChild(x);
      }
    }

    // For whatever reason, sorttable tracks column indices this way.
    // Without a manual update, clicking one column will sort on another.
    var headrow = table.tHead.rows[0].cells;
    for (var i=0; i<headrow.length; i++) {
      headrow[i].sorttable_columnindex = i;
    }
  },

  // Are cookies enabled? We should not attempt to set cookies on a local file.
  cookiesEnabled: function() {
    return (window.location.protocol != 'file:') && navigator.cookieEnabled;
  },

  // Store a column swap in a cookie for posterity.
  rememberDrag: function(id, a, b) {
    var cookieName = "dragtable-" + id;
    var prev = dragtable.readCookie(cookieName);
    var new_val = "";
    if (prev) new_val = prev + ",";
    new_val += a + "/" + b;
    dragtable.createCookie(cookieName, new_val, dragtable.cookieDays);
  },

	// Replay all column swaps for a table.
	replayDrags: function(table) {
		if (!dragtable.cookiesEnabled()) return;
		var dragstr = dragtable.readCookie("dragtable-" + table.id);
		if (!dragstr) return;
		var drags = dragstr.split(',');
		for (var i = 0; i < drags.length; i++) {
			var pair = drags[i].split("/");
			if (pair.length != 2) continue;
			var a = parseInt(pair[0]);
			var b = parseInt(pair[1]);
			if (isNaN(a) || isNaN(b)) continue;
			dragtable.moveColumn(table, a, b);
		}
	},

  // Cookie functions based on http://www.quirksmode.org/js/cookies.html
  // Cookies won't work for local files.
  cookiesEnabled: function() {
    return (window.location.protocol != 'file:') && navigator.cookieEnabled;
  },

  createCookie: function(name,value,days) {
    if (days) {
      var date = new Date();
      date.setTime(date.getTime()+(days*24*60*60*1000));
      var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";

		var path = document.location.pathname;
    document.cookie = name+"="+value+expires+"; path="+path
  },

  readCookie: function(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
      var c = ca[i];
      while (c.charAt(0)==' ') c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
  },

  eraseCookie: function(name) {
    dragtable.createCookie(name,"",-1);
  }

}

/* ******************************************************************
   Supporting functions: bundled here to avoid depending on a library
   ****************************************************************** */

// Dean Edwards/Matthias Miller/John Resig
// has a hook for dragtable.init already been added? (see below)
var dgListenOnLoad = false;

/* for Mozilla/Opera9 */
if (document.addEventListener) {
  dgListenOnLoad = true;
  document.addEventListener("DOMContentLoaded", dragtable.init, false);
}

/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
  dgListenOnLoad = true;
  document.write("<script id=__dt_onload defer src=//0)><\/script>");
  var script = document.getElementById("__dt_onload");
  script.onreadystatechange = function() {
    if (this.readyState == "complete") {
      dragtable.init(); // call the onload handler
    }
  };
/*@end @*/

/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
  dgListenOnLoad = true;
  var _dgtimer = setInterval(function() {
    if (/loaded|complete/.test(document.readyState)) {
      dragtable.init(); // call the onload handler
    }
  }, 10);
}

/* for other browsers */
/* Avoid this unless it's absolutely necessary (it breaks sorttable) */
if (!dgListenOnLoad) {
  window.onload = dragtable.init;
}

// Dean's forEach: http://dean.edwards.name/base/forEach.js
/*
  forEach, version 1.0
  Copyright 2006, Dean Edwards
  License: http://www.opensource.org/licenses/mit-license.php
*/

// array-like enumeration
if (!Array.forEach) { // mozilla already supports this
  Array.forEach = function(array, block, context) {
    for (var i = 0; i < array.length; i++) {
      block.call(context, array[i], i, array);
    }
  };
}

// generic enumeration
Function.prototype.forEach = function(object, block, context) {
  for (var key in object) {
    if (typeof this.prototype[key] == "undefined") {
      block.call(context, object[key], key, object);
    }
  }
};

// character enumeration
String.forEach = function(string, block, context) {
  Array.forEach(string.split(""), function(chr, index) {
    block.call(context, chr, index, string);
  });
};

// globally resolve forEach enumeration
var forEach = function(object, block, context) {
  if (object) {
    var resolve = Object; // default
    if (object instanceof Function) {
      // functions have a "length" property
      resolve = Function;
    } else if (object.forEach instanceof Function) {
      // the object implements a custom forEach method so use that
      object.forEach(block, context);
      return;
    } else if (typeof object == "string") {
      // the object is a string
      resolve = String;
    } else if (typeof object.length == "number") {
      // the object is array-like
      resolve = Array;
    }
    resolve.forEach(object, block, context);
  }
};
///////
$(function(){
  if(($('select#mechanical')).length != 0) {
    $('select#mechanical').selectToUISlider({labels:5}).hide();
    $('select#performance').selectToUISlider({labels:5}).hide();
    $('select#fitness').selectToUISlider({labels:5}).hide();
    $('select#style').selectToUISlider({labels:5}).hide();
    $('select#comfort').selectToUISlider({labels:5}).hide();
    $('select#simplicity').selectToUISlider({labels:5}).hide();
    $('select#frequency').selectToUISlider({labelSrc:'value',labels:5}).hide();
    $('select#distance').selectToUISlider({labelSrc:'text',labels:5,tooltip:false}).hide();
  }
  $('input.jqui_button').button();
});
//////
/* guess my ride feedback form */
$(document).ready(function() {
  $('input.gmrfb_submit').click(function(e) {
    this.form.rsp.value = this.value;
  });

  $('form.gmrfb_form').submit(function(e) {
    e.preventDefault()
    var $form = $(this)
    $.post('/ajax/gmrfb', $form.serialize(), function(data) {
      msg = "Who can keep track of that sort of thing?"
      btncls = 'dontknow'
      if(data.recorded == 'Yes') {
        msg = "I knew it!"
        btncls = 'yes'
      } else if(data.recorded == 'No') {
        msg = "Of course not. What were we thinking?"
        btncls = 'no'
      }
      $('#gmrfb_searchlink').removeClass('hidden').show('fade');
      $('.gmrfb_response',$form).html(msg).removeClass('hidden').show('fade');
      $('input[type=submit]',$form).attr('disabled','disabled').button('option','disabled','true')
      $('input.'+btncls,$form).fadeTo(200,0.8).siblings('input[type=submit]').fadeTo(200,0.2);
      $('input[type=submit]',$form).button('refresh');
    }, 'json');
    return false;
  });
});

////
// file: selectotuislider.jquery.js
/*
 * --------------------------------------------------------------------
 * jQuery-Plugin - selectToUISlider - creates a UI slider component from a select element(s)
 * by Scott Jehl, scott@filamentgroup.com
 * http://www.filamentgroup.com
 * reference article: http://www.filamentgroup.com/lab/update_jquery_ui_16_slider_from_a_select_element/
 * demo page: http://www.filamentgroup.com/examples/slider_v2/index.html
 * 
 * Copyright (c) 2008 Filament Group, Inc
 * Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
 *
 * Usage Notes: please refer to our article above for documentation
 *  
 * --------------------------------------------------------------------
 */


jQuery.fn.selectToUISlider = function(settings){
	var selects = jQuery(this);
	
	//accessible slider options
	var options = jQuery.extend({
		labels: 3, //number of visible labels
		tooltip: true, //show tooltips, boolean
		tooltipSrc: 'text',//accepts 'value' as well
		labelSrc: 'value',//accepts 'value' as well	,
		sliderOptions: null
	}, settings);


	//handle ID attrs - selects each need IDs for handles to find them
	var handleIds = (function(){
		var tempArr = [];
		selects.each(function(){
			tempArr.push('handle_'+jQuery(this).attr('id'));
		});
		return tempArr;
	})();
	
	//array of all option elements in select element (ignores optgroups)
	var selectOptions = (function(){
		var opts = [];
		selects.eq(0).find('option').each(function(){
			opts.push({
				value: jQuery(this).attr('value'),
				text: jQuery(this).text()
			});
		});
		return opts;
	})();
	
	//array of opt groups if present
	var groups = (function(){
		if(selects.eq(0).find('optgroup').size()>0){
			var groupedData = [];
			selects.eq(0).find('optgroup').each(function(i){
				groupedData[i] = {};
				groupedData[i].label = jQuery(this).attr('label');
				groupedData[i].options = [];
				jQuery(this).find('option').each(function(){
					groupedData[i].options.push({text: jQuery(this).text(), value: jQuery(this).attr('value')});
				});
			});
			return groupedData;
		}
		else return null;
	})();	
	
	//check if obj is array
	function isArray(obj) {
		return obj.constructor == Array;
	}
	//return tooltip text from option index
	function ttText(optIndex){
		return (options.tooltipSrc == 'text') ? selectOptions[optIndex].text : selectOptions[optIndex].value;
	}
	
	//plugin-generated slider options (can be overridden)
	var sliderOptions = {
		step: 1,
		min: 0,
		orientation: 'horizontal',
		max: selectOptions.length-1,
		range: selects.length > 1,//multiple select elements = true
		slide: function(e, ui) {//slide function
				var thisHandle = jQuery(ui.handle);
				//handle feedback 
				var textval = ttText(ui.value);
				thisHandle
					.attr('aria-valuetext', textval)
					.attr('aria-valuenow', ui.value)
					.find('.ui-slider-tooltip .ttContent')
						.text( textval );

				//control original select menu
				var currSelect = jQuery('#' + thisHandle.attr('id').split('handle_')[1]);
				currSelect.find('option').eq(ui.value).attr('selected', 'selected');
		},
		values: (function(){
			var values = [];
			selects.each(function(){
				values.push( jQuery(this).get(0).selectedIndex );
			});
			return values;
		})()
	};
	
	//slider options from settings
	options.sliderOptions = (settings) ? jQuery.extend(sliderOptions, settings.sliderOptions) : sliderOptions;
		
	//select element change event	
	selects.bind('change keyup click', function(){
		var thisIndex = jQuery(this).get(0).selectedIndex;
		var thisHandle = jQuery('#handle_'+ jQuery(this).attr('id'));
		var handleIndex = thisHandle.data('handleNum');
		thisHandle.parents('.ui-slider:eq(0)').slider("values", handleIndex, thisIndex);
	});
	

	//create slider component div
	var sliderComponent = jQuery('<div></div>');

	//CREATE HANDLES
	selects.each(function(i){
		var hidett = '';
		
		//associate label for ARIA
		var thisLabel = jQuery('label[for=' + jQuery(this).attr('id') +']');
		//labelled by aria doesn't seem to work on slider handle. Using title attr as backup
		var labelText = (thisLabel.size()>0) ? 'Slider control for '+ thisLabel.text()+'' : '';
		var thisLabelId = thisLabel.attr('id') || thisLabel.attr('id', 'label_'+handleIds[i]).attr('id');
		
		
		if( options.tooltip == false ){hidett = ' style="display: none;"';}
		jQuery('<a '+
				'href="#" tabindex="0" '+
				'id="'+handleIds[i]+'" '+
				'class="ui-slider-handle" '+
				'role="slider" '+
				'aria-labelledby="'+thisLabelId+'" '+
				'aria-valuemin="'+options.sliderOptions.min+'" '+
				'aria-valuemax="'+options.sliderOptions.max+'" '+
				'aria-valuenow="'+options.sliderOptions.values[i]+'" '+
				'aria-valuetext="'+ttText(options.sliderOptions.values[i])+'" '+
			'><span class="screenReaderContext">'+labelText+'</span>'+
			'<span class="ui-slider-tooltip ui-widget-content ui-corner-all"'+ hidett +'><span class="ttContent"></span>'+
				'<span class="ui-tooltip-pointer-down ui-widget-content"><span class="ui-tooltip-pointer-down-inner"></span></span>'+
			'</span></a>')
			.data('handleNum',i)
			.appendTo(sliderComponent);
	});
	
	//CREATE SCALE AND TICS
	
	//write dl if there are optgroups
	if(groups) {
		var inc = 0;
		var scale = sliderComponent.append('<dl class="ui-slider-scale ui-helper-reset" role="presentation"></dl>').find('.ui-slider-scale:eq(0)');
		jQuery(groups).each(function(h){
			scale.append('<dt style="width: '+ (100/groups.length).toFixed(2) +'%' +'; left:'+ (h/(groups.length-1) * 100).toFixed(2)  +'%' +'"><span>'+this.label+'</span></dt>');//class name becomes camelCased label
			var groupOpts = this.options;
			jQuery(this.options).each(function(i){
				var style = (inc == selectOptions.length-1 || inc == 0) ? 'style="display: none;"' : '' ;
				var labelText = (options.labelSrc == 'text') ? groupOpts[i].text : groupOpts[i].value;
				scale.append('<dd style="left:'+ leftVal(inc) +'"><span class="ui-slider-label">'+ labelText +'</span><span class="ui-slider-tic ui-widget-content"'+ style +'></span></dd>');
				inc++;
			});
		});
	}
	//write ol
	else {
		var scale = sliderComponent.append('<ol class="ui-slider-scale ui-helper-reset" role="presentation"></ol>').find('.ui-slider-scale:eq(0)');
		jQuery(selectOptions).each(function(i){
			var style = (i == selectOptions.length-1 || i == 0) ? ' style="display: none;"' : '' ;
			var labelText = (options.labelSrc == 'text') ? this.text : this.value;
			scale.append('<li style="left:'+ leftVal(i) +'"><span class="ui-slider-label">'+ labelText +'</span><span class="ui-slider-tic ui-widget-content"'+ style +'></span></li>');
		});
	}
	
	function leftVal(i){
		return (i/(selectOptions.length-1) * 100).toFixed(2)  +'%';
		
	}
	

	
	
	//show and hide labels depending on labels pref
	//show the last one if there are more than 1 specified
	if(options.labels > 1) sliderComponent.find('.ui-slider-scale li:last span.ui-slider-label, .ui-slider-scale dd:last span.ui-slider-label').addClass('ui-slider-label-show');

	//set increment
	var increm = Math.max(1, Math.round(selectOptions.length / options.labels));
	//show em based on inc
	for(var j=0; j<selectOptions.length; j+=increm){
		if((selectOptions.length - j) > increm){//don't show if it's too close to the end label
			sliderComponent.find('.ui-slider-scale li:eq('+ j +') span.ui-slider-label, .ui-slider-scale dd:eq('+ j +') span.ui-slider-label').addClass('ui-slider-label-show');
		}
	}

	//style the dt's
	sliderComponent.find('.ui-slider-scale dt').each(function(i){
		jQuery(this).css({
			'left': ((100 /( groups.length))*i).toFixed(2) + '%'
		});
	});
	

	//inject and return 
	sliderComponent
	.insertAfter(jQuery(this).eq(this.length-1))
	.slider(options.sliderOptions)
	.attr('role','application')
	.find('.ui-slider-label')
	.each(function(){
		jQuery(this).css('marginLeft', -jQuery(this).width()/2);
	});
	
	//update tooltip arrow inner color
	sliderComponent.find('.ui-tooltip-pointer-down-inner').each(function(){
				var bWidth = jQuery('.ui-tooltip-pointer-down-inner').css('borderTopWidth');
				var bColor = jQuery(this).parents('.ui-slider-tooltip').css('backgroundColor')
				jQuery(this).css('border-top', bWidth+' solid '+bColor);
	});
	
	var values = sliderComponent.slider('values');
	
	if(isArray(values)){
		jQuery(values).each(function(i){
			sliderComponent.find('.ui-slider-tooltip .ttContent').eq(i).text( ttText(this) );
		});
	}
	else {
		sliderComponent.find('.ui-slider-tooltip .ttContent').eq(0).text( ttText(values) );
	}
	
	return this;
}
// end file:selecttouislider.jquery.js
//////

