function init(){
  // add .js class to body, indicating javascript is enabled
  $('body').addClass('js');

  // Recreate $.post with 'error' callback
  $.post = function( url, data, callback, type ) {
		if ( jQuery.isFunction( data ) ) {
			callback = data;
			data = {};
		}
    settings = {
			type: "POST",
			url: url,
			data: data,
			dataType: type
		};
    if ( jQuery.isFunction( callback ) ) {
      settings.success = callback;
    } else {
      if ( jQuery.isFunction( callback.success ) ) {
        settings.success = callback.success;
      }
      if ( jQuery.isFunction( callback.error ) ) {
        settings.error = callback.error;
      }
    }

		return jQuery.ajax(settings);
	}
  // Create missing function
  $.postJSON = function(url, data, callback) {

    // Force disable jQuery cache setting
    var cache = jQuery.ajaxSettings.cache; jQuery.ajaxSettings.cache = false;

    $.post(url, data, callback, "json");

    // Restore jQuery caching setting
    jQuery.ajaxSettings.cache = cache;
  };

  // IE/IE6 Specific jQuery
  if ($.browser.msie) {
    // Replace built-in fade functions in IE to disable cleartype bug
    jQuery.fn.fadeIn = function(speed, callback) {
      return this.animate({opacity: 'show'}, speed, function() {
        if (jQuery.browser.msie)
          this.style.removeAttribute('filter');
        if (jQuery.isFunction(callback))
          callback();
      });
    };

    jQuery.fn.fadeOut = function(speed, callback) {
      return this.animate({opacity: 'hide'}, speed, function() {
        if (jQuery.browser.msie)
          this.style.removeAttribute('filter');
        if (jQuery.isFunction(callback))
          callback();
      });
    };

    jQuery.fn.fadeTo = function(speed,to,callback) {
      return this.animate({opacity: to}, speed, function() {
        if (to == 1 && jQuery.browser.msie)
          this.style.removeAttribute('filter');
        if (jQuery.isFunction(callback))
          callback();
      });
    };

    if ($.browser.version < '7.0') {
    }
  }

  // Init Fee calculator
  var feecalc = $('#feecalculator'),
      visible = {
        type:       true,
        residences: false,
        business:   false,
        apartments: false,
        taxExempt:  false,
        employees:  false,
        units:      false,
        total:      false
      };
  function initcalc () {
    feecalc.data({total: 0, base: 0, addl: 0, qty: 0, per: 0, visible: $.extend({},visible) });
    var vis = feecalc.data('visible'),
        res = '';
    for (i in vis) {
      var el = $('#'+i),
      tgt = el.parent('.step')
      res += ',#'+i;
      if (vis[i]) { tgt.slideDown(); } else { tgt.slideUp(); }
    }
    resetfields(res.slice(1));
  }
  function resetfields(fields) {
    $(fields).each(function(){
      if ($(this).is('select')) { $(this)[0].selectedIndex = 0; } else { $(this)[0].value = ''; }
    });
  }
  initcalc();
  $('select',feecalc).change(function(){
    // Determine steps to show/hide
    switch (true) {
      // Type
      case ($(this).is('#type')):
        for (i in feecalc.data('visible')) {
          feecalc.data('visible')[i] = (i==$(this).val() || i == 'type') ? true : false;
        }
        break;
      // Business
      case ($(this).is('#business')):
        var selected = $(':selected',this).text();
        // Don't require 'employees' for 'Booth Worker' option
        if (selected.search(/Booth Worker/) != -1) {
          feecalc.data('visible')['employees'] = false;
          feecalc.data('visible')['total'] = true;
        } else {
          feecalc.data('visible')['employees'] = true;
          feecalc.data('visible')['total'] = false;
          // Determine whether or not addl 'units' value should be requested
          var patt = /\(Per (.*)\)/gi;
          if (patt.test(selected)) {
            var matches = selected.match(patt),
                unit = matches[0].slice(5,6).toUpperCase() + matches[0].slice(6,-1).toLowerCase()+'s';
            feecalc.data('visible')['units'] = unit;
          } else {
            feecalc.data('visible')['units'] = false;
          }
        }
        resetfields('#employees');
        resetfields('#units');
        break;
      // Tax Exempt
      case ($(this).is('#taxExempt')):
        // Determine whether or not addl 'units' value should be requested
        var selected = $(':selected',this).text(),
            patt = /Churches/gi;
        if (patt.test(selected)) {
          feecalc.data('visible')['employees'] = false;
          feecalc.data('visible')['total'] = true;
        } else {
          feecalc.data('visible')['employees'] = true;
          feecalc.data('visible')['total'] = false;
        }
        resetfields('#employees');
        break;
      // Employees
      case ($(this).is('#employees')):
        feecalc.data('visible')['total'] = ($('#units',feecalc).parent('.step').is(':hidden') || /([\d\.])+/.test($('#units',feecalc).val())) ? true : false;
        break;
      // Residences
      case ($(this).is('#residences')):
        feecalc.data('visible')['total'] = true;
        break;
    }
    updateCalc();
  });
  $('button',feecalc).click(function(){
    feecalc.data('visible')['total'] = true;
    updateCalc();
  });
  function updateCalc() {
    // Separate 'hide' from 'show'
    var vis = feecalc.data('visible'),
        show = [],
        hide = [];
    for (i in vis) { if (!vis[i]) { hide.push(i); } else { show.push(i); } }
    var show = '#'+show.join(",#");
    if (feecalc.data('visible')['units']) {
      $('span',$('#units',feecalc).prev('label')).text(feecalc.data('visible')['units']);
    }
    // Perform action
    if (hide.length > 0) {
      hide = '#'+hide.join(",#");
      var els = $(hide,feecalc).parent('.step'),
          runonce = false,
          runttl = els.length;
      els.slideUp(500,function(){
        if (els.filter(':visible').length == 0 && !runonce) {
          runonce = true; resetfields(hide);
          var els2 = $(show,feecalc).parent('.step').filter(':hidden'),
              runonce2 = false;
          if (els2.length > 0) {
            els2.slideDown(500,function(){
              if (els2.filter(':hidden').length == 0 && !runonce2 && $('#total',feecalc).parent('.step').is(':visible')) { runonce2 = true; getTotal(); }
            });
          } else {
            if ($('#total',feecalc).parent('.step').is(':visible')) { getTotal(); }
          }
        }
      });
    } else {
      if ($('#total',feecalc).parent('.step').is(':visible')) { getTotal(); }
    }
  };
  function getTotal() {
    var init = {total: 0, base: 0, addl: 0, qty: 0, per: 0};
    for (i in init) { feecalc.data(i,init[i]); }
    // Base
    if ($('#business',feecalc).parent('.step').is(':visible')) {
      feecalc.data('base', $('#business').val());
    }
    if ($('#apartments',feecalc).parent('.step').is(':visible')) {
      feecalc.data('per',$('#per-apt').val());
      feecalc.data('qty',$('#apartments').val());
      feecalc.data('base', parseFloat(feecalc.data('per')) * parseFloat(feecalc.data('qty')));
    }
    if ($('#residences',feecalc).parent('.step').is(':visible')) {
      feecalc.data('base', $('#residences').val());
    }
    if ($('#taxExempt',feecalc).parent('.step').is(':visible')) {
      feecalc.data('base', $('#taxExempt').val());
    }
    // Units
    if ($('#units',feecalc).parent('.step').is(':visible')) {
      feecalc.data('base', parseFloat(feecalc.data('base')) * parseFloat($('#units').val()));
    }
    // Employees
    if ($('#employees',feecalc).parent('.step').is(':visible')) {
      feecalc.data('addl', $('#employees').val());
    }
    // Total
    feecalc.data('total',(parseFloat(feecalc.data('base'))+parseFloat(feecalc.data('addl'))));
    var totals = {
        permonth: feecalc.data('total').toFixed(2),
        perbill:  (feecalc.data('total')*4).toFixed(2),
        peryear:  (feecalc.data('total')*12).toFixed(2)
    };
    for (i in totals) {
      if (totals[i] > 999) {
        var s = new String(totals[i]);
        var patt = /((\d{1})(\d{3})(\.|,))/gi;
        if(s.indexOf('.') < 0) { s += '.00'; }
        while (patt.test(s)) {
          s = s.replace(patt,"$2,$3$4")
        }
        totals[i] = s;
      }
      $('td.'+i,feecalc).text('$'+totals[i]);
    }
  }
function dump(arr,level) {
var dumped_text = "";
if(!level) level = 0;

//The padding given at the beginning of the line.
var level_padding = "";
for(var j=0;j<level+1;j++) level_padding += "    ";

if(typeof(arr) == 'object') { //Array/Hashes/Objects
 for(var item in arr) {
  var value = arr[item];

  if(typeof(value) == 'object') { //If it is an array,
   dumped_text += level_padding + "'" + item + "' ...\n";
   dumped_text += dump(value,level+1);
  } else {
   dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
  }
 }
} else { //Stings/Chars/Numbers etc.
 dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
}
return dumped_text;
}
}
