(function(){
  var cleanNumber = function(i) {
    return i.replace(/[^\-?0-9.]/g, '');
  },

  compareNumberReverse = function(a, b) {
    a = parseFloat(a);
    b = parseFloat(b);

    a = isNaN(a) ? 0 : a;
    b = isNaN(b) ? 0 : b;

    return b - a;
  };

  Tablesort.extend('reverse_number', function(item) {
    return item.match(/^-?[£\x24Û¢´€]?\d+\s*([,\.]\d{0,2})/) || // Prefixed currency
      item.match(/^-?\d+\s*([,\.]\d{0,2})?[£\x24Û¢´€]/) || // Suffixed currency
      item.match(/^-?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/); // Number
  }, function(a, b) {
    a = cleanNumber(a);
    b = cleanNumber(b);

    return compareNumberReverse(b, a);
  });
}());

(function(){
  var cleanNumber = function(i) {
      var n = parseFloat(i.replace(/[^\-?0-9.]/g, ''));

      return isNaN(n) ? null : n;
  },

  compareNumberReverse = function(a, b) {
      // Treat null as always greater
      if (a === null) return 1;
      if (b === null) return -1;

      return a - b;
  };

  Tablesort.extend('reverse_number', function(item) {
    return item.match(/^-?[£\x24Û¢´€]?\d+\s*([,\.]\d{0,2})/) || // Prefixed currency
      item.match(/^-?\d+\s*([,\.]\d{0,2})?[£\x24Û¢´€]/) || // Suffixed currency
      item.match(/^-?(\d)*-?([,\.]){0,1}-?(\d)+([E,e][\-+][\d]+)?%?$/); // Number
  }, function(a, b) {
      return compareNumberReverse(cleanNumber(a), cleanNumber(b));
  });
}());

Sort null risk levels correctly
Sort null risk levels correctly

I'm a little surprised that the Tablesort comparator works in the exact
opposite way to pretty much every other comparator, but it's late, and I
could be missing something.

addresses #344
