<!DOCTYPE html>
<html>

<head>
  <link data-require="bootstrap-css@3.0.2" data-semver="3.0.2" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" />
  <link data-require="jqueryui@*" data-semver="1.10.0" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/css/smoothness/jquery-ui-1.10.0.custom.min.css" />
  <link rel="stylesheet" href="footable.core.css" />
  <script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
  <script data-require="jqueryui@*" data-semver="1.10.0" src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.0/jquery-ui.js"></script>
  <script data-require="bootstrap@*" data-semver="3.0.2" src="//netdna.bootstrapcdn.com/bootstrap/3.0.2/js/bootstrap.min.js"></script>
  <script src="footable.js"></script>
  <script src="footable.filter.js"></script>
  <script src="footable.paginate.js"></script>
  <script data-require="prototype@*" data-semver="1.7.1+0" src="//cdnjs.cloudflare.com/ajax/libs/prototype/1.7.1.0/prototype.js"></script>
</head>

<body>
  <div>
    <div id="demo">
      <p>
        Search:
        <input id="filter" type="text" />Status:
        <select class="filter-status">
          <option></option>
          <option value="active">Active</option>
          <option value="disabled">Disabled</option>
          <option value="suspended">Suspended</option>
          <option value="Artigo Científico em Revista Internacional">Article in International Journal</option>
          <option value="Artigo Científico em Revista Nacional">Article in National Journal</option>
          <option value="occupational">Occupational endorsements</option>
          <option value="special">Special training programs</option>
        </select>
        <a href="#clear" class="clear-filter" title="clear filter">[clear]</a>
        <a href="#api" class="filter-api" title="Filter using the Filter API">[filter API]</a>
      </p>
      <table class="table demo default footable" data-filter="#filter" data-filter-text-only="false" data-page-size="3" data-page-navigation=".pagination">
        <thead>
          <tr>
            <th data-toggle="true" class="footable-first-column">
              First Name
            </th>
            <th>
              Last Name
            </th>
            <th data-hide="phone,tablet">
              Job Title
            </th>
            <th data-hide="phone,tablet">
              DOB
            </th>
            <th data-hide="phone" class="footable-last-column">
              Status
            </th>
          </tr>
        </thead>
        <tbody>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              Isidra
            </td>
            <td>
              <a href="#">Boudreaux</a>
            </td>
            <td>Traffic Court Referee</td>
            <td data-value="78025368997">22 Jun 1972</td>
            <td data-value="1" class="footable-last-column">
              <span class="status-metro status-active" title="Active">Active</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              Shona
            </td>
            <td>Woldt</td>
            <td>
              <a href="#">Airline Transport Pilot</a>
            </td>
            <td data-value="370961043292">3 Oct 1981</td>
            <td data-value="2" class="footable-last-column">
              <span class="status-metro status-disabled" title="Disabled">Disabled</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              Granville
            </td>
            <td>Leonardo</td>
            <td>Business Services Sales Representative</td>
            <td data-value="-22133780420">19 Apr 1969</td>
            <td data-value="3" class="footable-last-column">
              <span class="status-metro status-suspended" title="Suspended">Suspended</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              Easer
            </td>
            <td>Dragoo</td>
            <td>Drywall Stripper</td>
            <td data-value="250833505574">13 Dec 1977</td>
            <td data-value="1" class="footable-last-column">
              <span class="status-metro status-active" title="Active">Active</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              Maple
            </td>
            <td>Halladay</td>
            <td>Aviation Tactical Readiness Officer</td>
            <td data-value="694116650726">30 Dec 1991</td>
            <td data-value="3" class="footable-last-column">
              <span class="status-metro status-suspended" title="Suspended">Suspended</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              Maxine
            </td>
            <td>
              <a href="#">Woldt</a>
            </td>
            <td>
              <a href="#">Business Services Sales Representative</a>
            </td>
            <td data-value="561440464855">17 Oct 1987</td>
            <td data-value="2" class="footable-last-column">
              <span class="status-metro status-disabled" title="Disabled">Disabled</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              Lorraine
            </td>
            <td>Mcgaughy</td>
            <td>Hemodialysis Technician</td>
            <td data-value="437400551390">11 Nov 1983</td>
            <td data-value="2" class="footable-last-column">
              <span class="status-metro status-disabled" title="Disabled">Disabled</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              Lizzee
            </td>
            <td>
              <a href="#">Goodlow</a>
            </td>
            <td>Technical Services Librarian</td>
            <td data-value="-257733999319">1 Nov 1961</td>
            <td data-value="3" class="footable-last-column">
              <span class="status-metro status-suspended" title="Suspended">Suspended</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              Judi
            </td>
            <td>Badgett</td>
            <td>Electrical Lineworker</td>
            <td data-value="362134712000">23 Jun 1981</td>
            <td data-value="1" class="footable-last-column">
              <span class="status-metro status-active" title="Active">Active</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              Lauri
            </td>
            <td>Hyland</td>
            <td>Blackjack Supervisor</td>
            <td data-value="500874333932">15 Nov 1985</td>
            <td data-value="3" class="footable-last-column">
              <span class="status-metro status-suspended" title="Suspended">Suspended</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              First 1</td>
            <td>Blah Blah 1</td>
            <td>Some thing 1</td>
            <td></td>
            <td class="footable-last-column">
              <span class="status-metro status-suspended">Article in International Journal</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              First 2</td>
            <td>Blah Blah 2</td>
            <td>Some thing 2</td>
            <td></td>
            <td class="footable-last-column">
              <span class="status-metro status-suspended">Article in International Journal</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              First 3</td>
            <td>Blah Blah 3</td>
            <td>Some thing 3</td>
            <td></td>
            <td class="footable-last-column">
              <span class="status-metro status-suspended">Article in National Journal</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              First 4</td>
            <td>Blah Blah 4</td>
            <td>Some thing 4</td>
            <td></td>
            <td class="footable-last-column">
              <span class="status-metro status-suspended">Article in National Journal</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              First 5</td>
            <td>Blah Blah 5</td>
            <td>Some thing 5</td>
            <td></td>
            <td class="footable-last-column">
              <span class="status-metro status-suspended">special training programs</span>
            </td>
          </tr>
          <tr class="" style="display: table-row;">
            <td class="footable-first-column">
              <span class="footable-toggle"></span>
              First 6</td>
            <td>Blah Blah 6</td>
            <td>Some thing 6</td>
            <td></td>
            <td class="footable-last-column">
              <span class="status-metro status-suspended">occupational endorsements</span>
            </td>
          </tr>
        </tbody>
        <tfoot class="hide-if-no-paging">
          <tr>
            <td colspan="5" class="text-center">
            <ul class="pagination"></ul>
            </td>
          </tr>
        </tfoot>
      </table>
    </div>
  </div>
  <script type="text/javascript">
    (function($) {
      window.footable.options.filter.filterFunction = function(index) {
        var $t = $(this),
          $table = $t.parents('table:first'),
          filter = $table.data('current-filter').toUpperCase(),
          columns = $t.find('td');

        var regEx = new RegExp("\\b" + filter + "\\b");
        var result = false;
        for (i = 0; i < columns.length; i++) {
          var text = $(columns[i]).text();
          result = regEx.test(text.toUpperCase());
          if (result === true)
            break;


          if (!$table.data('filter-text-only')) {
            text = $(columns[i]).data("value");
            if (text)
              result = regEx.test(text.toString().toUpperCase());
          }

          if (result === true)
            break;
        }

        return result;
      };

      $('table').footable().bind('footable_filtering', function(e) {
        var selected = $('.filter-status').find(':selected').text();
        if (selected && selected.length > 0) {
          e.filter += (e.filter && e.filter.length > 0) ? ' ' + selected : selected;
          e.clear = !e.filter;
        }
      });

      $('.clear-filter').click(function(e) {
        e.preventDefault();
        $('.filter-status').val('');
        $('table.demo').trigger('footable_clear_filter');
      });

      $('.filter-status').change(function(e) {
        e.preventDefault();
        $('table.demo').trigger('footable_filter', {
          filter: $('#filter').val()
        });
      });

      $('.filter-api').click(function(e) {
        e.preventDefault();

        //get the footable filter object
        var footableFilter = $('table').data('footable-filter');

        alert('about to filter table by "dragoo"');
        //filter by 'tech'
        footableFilter.filter('dragoo');

        //clear the filter
        if (confirm('clear filter now?')) {
          footableFilter.clearFilter();
        }
      });

      $('.filter-status').change(function(e) {
        e.preventDefault();
        $('table.demo').data('footable-filter').filter($('#filter').val());
      });
    })(jQuery);
  </script>
</body>

</html>
@font-face {
  font-family: 'footable';
  src: url('fonts/footable.eot');
  src: url('fonts/footable.eot?#iefix') format('embedded-opentype'), url('fonts/footable.woff') format('woff'), url('fonts/footable.ttf') format('truetype'), url('fonts/footable.svg#footable') format('svg');
  font-weight: normal;
  font-style: normal;
}
@media screen and (-webkit-min-device-pixel-ratio: 0) {
  @font-face {
    font-family: 'footable';
    src: url('fonts/footable.svg#footable') format('svg');
    font-weight: normal;
    font-style: normal;
  }
}
.footable {
  width: 100%;
  /** SORTING **/

  /** PAGINATION **/

}
.footable.breakpoint > tbody > tr.footable-detail-show > td {
  border-bottom: none;
}
.footable.breakpoint > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e001";
}
.footable.breakpoint > tbody > tr:hover:not(.footable-row-detail) {
  cursor: pointer;
}
.footable.breakpoint > tbody > tr > td.footable-cell-detail {
  background: #eee;
  border-top: none;
}
.footable.breakpoint > tbody > tr > td > span.footable-toggle {
  display: inline-block;
  font-family: 'footable';
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  -webkit-font-smoothing: antialiased;
  padding-right: 5px;
  font-size: 14px;
  color: #888888;
}
.footable.breakpoint > tbody > tr > td > span.footable-toggle:before {
  content: "\e000";
}
.footable.breakpoint.toggle-circle > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e005";
}
.footable.breakpoint.toggle-circle > tbody > tr > td > span.footable-toggle:before {
  content: "\e004";
}
.footable.breakpoint.toggle-circle-filled > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e003";
}
.footable.breakpoint.toggle-circle-filled > tbody > tr > td > span.footable-toggle:before {
  content: "\e002";
}
.footable.breakpoint.toggle-square > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e007";
}
.footable.breakpoint.toggle-square > tbody > tr > td > span.footable-toggle:before {
  content: "\e006";
}
.footable.breakpoint.toggle-square-filled > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e009";
}
.footable.breakpoint.toggle-square-filled > tbody > tr > td > span.footable-toggle:before {
  content: "\e008";
}
.footable.breakpoint.toggle-arrow > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e00f";
}
.footable.breakpoint.toggle-arrow > tbody > tr > td > span.footable-toggle:before {
  content: "\e011";
}
.footable.breakpoint.toggle-arrow-small > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e013";
}
.footable.breakpoint.toggle-arrow-small > tbody > tr > td > span.footable-toggle:before {
  content: "\e015";
}
.footable.breakpoint.toggle-arrow-circle > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e01b";
}
.footable.breakpoint.toggle-arrow-circle > tbody > tr > td > span.footable-toggle:before {
  content: "\e01d";
}
.footable.breakpoint.toggle-arrow-circle-filled > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e00b";
}
.footable.breakpoint.toggle-arrow-circle-filled > tbody > tr > td > span.footable-toggle:before {
  content: "\e00d";
}
.footable.breakpoint.toggle-arrow-tiny > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e01f";
}
.footable.breakpoint.toggle-arrow-tiny > tbody > tr > td > span.footable-toggle:before {
  content: "\e021";
}
.footable.breakpoint.toggle-arrow-alt > tbody > tr.footable-detail-show > td > span.footable-toggle:before {
  content: "\e017";
}
.footable.breakpoint.toggle-arrow-alt > tbody > tr > td > span.footable-toggle:before {
  content: "\e019";
}
.footable.breakpoint.toggle-medium > tbody > tr > td > span.footable-toggle {
  font-size: 18px;
}
.footable.breakpoint.toggle-large > tbody > tr > td > span.footable-toggle {
  font-size: 24px;
}
.footable > thead > tr > th {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: -moz-none;
  -ms-user-select: none;
  user-select: none;
}
.footable > thead > tr > th.footable-sortable:hover {
  cursor: pointer;
}
.footable > thead > tr > th.footable-sorted > span.footable-sort-indicator:before {
  content: "\e013";
}
.footable > thead > tr > th.footable-sorted-desc > span.footable-sort-indicator:before {
  content: "\e012";
}
.footable > thead > tr > th > span.footable-sort-indicator {
  display: inline-block;
  font-family: 'footable';
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  -webkit-font-smoothing: antialiased;
  padding-left: 5px;
}
.footable > thead > tr > th > span.footable-sort-indicator:before {
  content: "\e022";
}
.footable > tfoot .pagination {
  margin: 0;
}
.footable.no-paging .hide-if-no-paging {
  display: none;
}
.footable-row-detail-inner {
  display: table;
}
.footable-row-detail-row {
  display: table-row;
  line-height: 1.5em;
}
.footable-row-detail-group {
  display: block;
  line-height: 2em;
  font-size: 1.2em;
  font-weight: bold;
}
.footable-row-detail-name {
  display: table-cell;
  font-weight: bold;
  padding-right: 0.5em;
}
.footable-row-detail-value {
  display: table-cell;
}
.footable-odd {
  background-color: #f7f7f7;
}
/*!
 * FooTable - Awesome Responsive Tables
 * Version : 2.0.1.4
 * http://fooplugins.com/plugins/footable-jquery/
 *
 * Requires jQuery - http://jquery.com/
 *
 * Copyright 2014 Steven Usher & Brad Vincent
 * Released under the MIT license
 * You are free to use FooTable in commercial projects as long as this copyright header is left intact.
 *
 * Date: 16 Feb 2014
 */
(function ($, w, undefined) {
	w.footable = {
		options: {
			delay: 100, // The number of millseconds to wait before triggering the react event
			breakpoints: { // The different screen resolution breakpoints
				phone: 480,
				tablet: 1024
			},
			parsers: {  // The default parser to parse the value out of a cell (values are used in building up row detail)
				alpha: function (cell) {
					return $(cell).data('value') || $.trim($(cell).text());
				},
				numeric: function (cell) {
					var val = $(cell).data('value') || $(cell).text().replace(/[^0-9.\-]/g, '');
					val = parseFloat(val);
					if (isNaN(val)) val = 0;
					return val;
				}
			},
			addRowToggle: true,
			calculateWidthOverride: null,
			toggleSelector: ' > tbody > tr:not(.footable-row-detail)', //the selector to show/hide the detail row
			columnDataSelector: '> thead > tr:last-child > th, > thead > tr:last-child > td', //the selector used to find the column data in the thead
			detailSeparator: ':', //the separator character used when building up the detail row
			toggleHTMLElement: '<span />', // override this if you want to insert a click target rather than use a background image.
			createGroupedDetail: function (data) {
				var groups = { '_none': { 'name': null, 'data': [] } };
				for (var i = 0; i < data.length; i++) {
					var groupid = data[i].group;
					if (groupid !== null) {
						if (!(groupid in groups))
							groups[groupid] = { 'name': data[i].groupName || data[i].group, 'data': [] };

						groups[groupid].data.push(data[i]);
					} else {
						groups._none.data.push(data[i]);
					}
				}
				return groups;
			},
			createDetail: function (element, data, createGroupedDetail, separatorChar, classes) {
				/// <summary>This function is used by FooTable to generate the detail view seen when expanding a collapsed row.</summary>
				/// <param name="element">This is the div that contains all the detail row information, anything could be added to it.</param>
				/// <param name="data">
				///  This is an array of objects containing the cell information for the current row.
				///  These objects look like the below:
				///    obj = {
				///      'name': String, // The name of the column
				///      'value': Object, // The value parsed from the cell using the parsers. This could be a string, a number or whatever the parser outputs.
				///      'display': String, // This is the actual HTML from the cell, so if you have images etc you want moved this is the one to use and is the default value used.
				///      'group': String, // This is the identifier used in the data-group attribute of the column.
				///      'groupName': String // This is the actual name of the group the column belongs to.
				///    }
				/// </param>
				/// <param name="createGroupedDetail">The grouping function to group the data</param>
				/// <param name="separatorChar">The separator charactor used</param>
				/// <param name="classes">The array of class names used to build up the detail row</param>

				var groups = createGroupedDetail(data);
				for (var group in groups) {
					if (groups[group].data.length === 0) continue;
					if (group !== '_none') element.append('<div class="' + classes.detailInnerGroup + '">' + groups[group].name + '</div>');

					for (var j = 0; j < groups[group].data.length; j++) {
						var separator = (groups[group].data[j].name) ? separatorChar : '';
						element.append('<div class="' + classes.detailInnerRow + '"><div class="' + classes.detailInnerName + '">' + groups[group].data[j].name + separator + '</div><div class="' + classes.detailInnerValue + '">' + groups[group].data[j].display + '</div></div>');
					}
				}
			},
			classes: {
				main: 'footable',
				loading: 'footable-loading',
				loaded: 'footable-loaded',
				toggle: 'footable-toggle',
				disabled: 'footable-disabled',
				detail: 'footable-row-detail',
				detailCell: 'footable-row-detail-cell',
				detailInner: 'footable-row-detail-inner',
				detailInnerRow: 'footable-row-detail-row',
				detailInnerGroup: 'footable-row-detail-group',
				detailInnerName: 'footable-row-detail-name',
				detailInnerValue: 'footable-row-detail-value',
				detailShow: 'footable-detail-show'
			},
			triggers: {
				initialize: 'footable_initialize',                      //trigger this event to force FooTable to reinitialize
				resize: 'footable_resize',                              //trigger this event to force FooTable to resize
				redraw: 'footable_redraw',								//trigger this event to force FooTable to redraw
				toggleRow: 'footable_toggle_row',                       //trigger this event to force FooTable to toggle a row
				expandFirstRow: 'footable_expand_first_row',            //trigger this event to force FooTable to expand the first row
				expandAll: 'footable_expand_all',                       //trigger this event to force FooTable to expand all rows
				collapseAll: 'footable_collapse_all'                    //trigger this event to force FooTable to collapse all rows
			},
			events: {
				alreadyInitialized: 'footable_already_initialized',     //fires when the FooTable has already been initialized
				initializing: 'footable_initializing',                  //fires before FooTable starts initializing
				initialized: 'footable_initialized',                    //fires after FooTable has finished initializing
				resizing: 'footable_resizing',                          //fires before FooTable resizes
				resized: 'footable_resized',                            //fires after FooTable has resized
				redrawn: 'footable_redrawn',                            //fires after FooTable has redrawn
				breakpoint: 'footable_breakpoint',                      //fires inside the resize function, when a breakpoint is hit
				columnData: 'footable_column_data',                     //fires when setting up column data. Plugins should use this event to capture their own info about a column
				rowDetailUpdating: 'footable_row_detail_updating',      //fires before a detail row is updated
				rowDetailUpdated: 'footable_row_detail_updated',        //fires when a detail row is being updated
				rowCollapsed: 'footable_row_collapsed',                 //fires when a row is collapsed
				rowExpanded: 'footable_row_expanded',                   //fires when a row is expanded
				rowRemoved: 'footable_row_removed',                     //fires when a row is removed
				reset: 'footable_reset'                                 //fires when FooTable is reset
			},
			debug: false, // Whether or not to log information to the console.
			log: null
		},

		version: {
			major: 0, minor: 5,
			toString: function () {
				return w.footable.version.major + '.' + w.footable.version.minor;
			},
			parse: function (str) {
				version = /(\d+)\.?(\d+)?\.?(\d+)?/.exec(str);
				return {
					major: parseInt(version[1], 10) || 0,
					minor: parseInt(version[2], 10) || 0,
					patch: parseInt(version[3], 10) || 0
				};
			}
		},

		plugins: {
			_validate: function (plugin) {
				///<summary>Simple validation of the <paramref name="plugin"/> to make sure any members called by FooTable actually exist.</summary>
				///<param name="plugin">The object defining the plugin, this should implement a string property called "name" and a function called "init".</param>

				if (!$.isFunction(plugin)) {
					if (w.footable.options.debug === true) console.error('Validation failed, expected type "function", received type "{0}".', typeof plugin);
					return false;
				}
				var p = new plugin();
				if (typeof p['name'] !== 'string') {
					if (w.footable.options.debug === true) console.error('Validation failed, plugin does not implement a string property called "name".', p);
					return false;
				}
				if (!$.isFunction(p['init'])) {
					if (w.footable.options.debug === true) console.error('Validation failed, plugin "' + p['name'] + '" does not implement a function called "init".', p);
					return false;
				}
				if (w.footable.options.debug === true) console.log('Validation succeeded for plugin "' + p['name'] + '".', p);
				return true;
			},
			registered: [], // An array containing all registered plugins.
			register: function (plugin, options) {
				///<summary>Registers a <paramref name="plugin"/> and its default <paramref name="options"/> with FooTable.</summary>
				///<param name="plugin">The plugin that should implement a string property called "name" and a function called "init".</param>
				///<param name="options">The default options to merge with the FooTable's base options.</param>

				if (w.footable.plugins._validate(plugin)) {
					w.footable.plugins.registered.push(plugin);
					if (typeof options === 'object') $.extend(true, w.footable.options, options);
				}
			},
			load: function (instance) {
				var loaded = [], registered, i;
				for (i = 0; i < w.footable.plugins.registered.length; i++) {
					try {
						registered = w.footable.plugins.registered[i];
						loaded.push(new registered(instance));
					} catch (err) {
						if (w.footable.options.debug === true) console.error(err);
					}
				}
				return loaded;
			},
			init: function (instance) {
				///<summary>Loops through all registered plugins and calls the "init" method supplying the current <paramref name="instance"/> of the FooTable as the first parameter.</summary>
				///<param name="instance">The current instance of the FooTable that the plugin is being initialized for.</param>

				for (var i = 0; i < instance.plugins.length; i++) {
					try {
						instance.plugins[i]['init'](instance);
					} catch (err) {
						if (w.footable.options.debug === true) console.error(err);
					}
				}
			}
		}
	};

	var instanceCount = 0;

	$.fn.footable = function (options) {
		///<summary>The main constructor call to initialize the plugin using the supplied <paramref name="options"/>.</summary>
		///<param name="options">
		///<para>A JSON object containing user defined options for the plugin to use. Any options not supplied will have a default value assigned.</para>
		///<para>Check the documentation or the default options object above for more information on available options.</para>
		///</param>

		options = options || {};
		var o = $.extend(true, {}, w.footable.options, options); //merge user and default options
		return this.each(function () {
			instanceCount++;
			var footable = new Footable(this, o, instanceCount);
			$(this).data('footable', footable);
		});
	};

	//helper for using timeouts
	function Timer() {
		///<summary>Simple timer object created around a timeout.</summary>
		var t = this;
		t.id = null;
		t.busy = false;
		t.start = function (code, milliseconds) {
			///<summary>Starts the timer and waits the specified amount of <paramref name="milliseconds"/> before executing the supplied <paramref name="code"/>.</summary>
			///<param name="code">The code to execute once the timer runs out.</param>
			///<param name="milliseconds">The time in milliseconds to wait before executing the supplied <paramref name="code"/>.</param>

			if (t.busy) {
				return;
			}
			t.stop();
			t.id = setTimeout(function () {
				code();
				t.id = null;
				t.busy = false;
			}, milliseconds);
			t.busy = true;
		};
		t.stop = function () {
			///<summary>Stops the timer if its runnning and resets it back to its starting state.</summary>

			if (t.id !== null) {
				clearTimeout(t.id);
				t.id = null;
				t.busy = false;
			}
		};
	}

	function Footable(t, o, id) {
		///<summary>Inits a new instance of the plugin.</summary>
		///<param name="t">The main table element to apply this plugin to.</param>
		///<param name="o">The options supplied to the plugin. Check the defaults object to see all available options.</param>
		///<param name="id">The id to assign to this instance of the plugin.</param>

		var ft = this;
		ft.id = id;
		ft.table = t;
		ft.options = o;
		ft.breakpoints = [];
		ft.breakpointNames = '';
		ft.columns = {};
		ft.plugins = w.footable.plugins.load(ft);

		var opt = ft.options,
            cls = opt.classes,
            evt = opt.events,
            trg = opt.triggers,
            indexOffset = 0;

		// This object simply houses all the timers used in the FooTable.
		ft.timers = {
			resize: new Timer(),
			register: function (name) {
				ft.timers[name] = new Timer();
				return ft.timers[name];
			}
		};

		ft.init = function () {
			var $window = $(w), $table = $(ft.table);

			w.footable.plugins.init(ft);

			if ($table.hasClass(cls.loaded)) {
				//already loaded FooTable for the table, so don't init again
				ft.raise(evt.alreadyInitialized);
				return;
			}

			//raise the initializing event
			ft.raise(evt.initializing);

			$table.addClass(cls.loading);

			// Get the column data once for the life time of the plugin
			$table.find(opt.columnDataSelector).each(function () {
				var data = ft.getColumnData(this);
				ft.columns[data.index] = data;
			});

			// Create a nice friendly array to work with out of the breakpoints object.
			for (var name in opt.breakpoints) {
				ft.breakpoints.push({ 'name': name, 'width': opt.breakpoints[name] });
				ft.breakpointNames += (name + ' ');
			}

			// Sort the breakpoints so the smallest is checked first
			ft.breakpoints.sort(function (a, b) {
				return a['width'] - b['width'];
			});

			$table
                .unbind(trg.initialize)
                //bind to FooTable initialize trigger
                .bind(trg.initialize, function () {
                	//remove previous "state" (to "force" a resize)
                	$table.removeData('footable_info');
                	$table.data('breakpoint', '');

                	//trigger the FooTable resize
                	$table.trigger(trg.resize);

                	//remove the loading class
                	$table.removeClass(cls.loading);

                	//add the FooTable and loaded class
                	$table.addClass(cls.loaded).addClass(cls.main);

                	//raise the initialized event
                	ft.raise(evt.initialized);
                })
                .unbind(trg.redraw)
                //bind to FooTable redraw trigger
                .bind(trg.redraw, function () {
                	ft.redraw();
                })
                .unbind(trg.resize)
                //bind to FooTable resize trigger
                .bind(trg.resize, function () {
                	ft.resize();
                })
                .unbind(trg.expandFirstRow)
                //bind to FooTable expandFirstRow trigger
                .bind(trg.expandFirstRow, function () {
                	$table.find(opt.toggleSelector).first().not('.' + cls.detailShow).trigger(trg.toggleRow);
                })
                .unbind(trg.expandAll)
                //bind to FooTable expandFirstRow trigger
                .bind(trg.expandAll, function () {
                	$table.find(opt.toggleSelector).not('.' + cls.detailShow).trigger(trg.toggleRow);
                })
                .unbind(trg.collapseAll)
                //bind to FooTable expandFirstRow trigger
                .bind(trg.collapseAll, function () {
                	$table.find('.' + cls.detailShow).trigger(trg.toggleRow);
                });

			//trigger a FooTable initialize
			$table.trigger(trg.initialize);

			//bind to window resize
			$window
                .bind('resize.footable', function () {
                	ft.timers.resize.stop();
                	ft.timers.resize.start(function () {
                		ft.raise(trg.resize);
                	}, opt.delay);
                });
		};

		ft.addRowToggle = function () {
			if (!opt.addRowToggle) return;

			var $table = $(ft.table),
                hasToggleColumn = false;

			//first remove all toggle spans
			$table.find('span.' + cls.toggle).remove();

			for (var c in ft.columns) {
				var col = ft.columns[c];
				if (col.toggle) {
					hasToggleColumn = true;
					var selector = '> tbody > tr:not(.' + cls.detail + ',.' + cls.disabled + ') > td:nth-child(' + (parseInt(col.index, 10) + 1) + ')';
					$table.find(selector).not('.' + cls.detailCell).prepend($(opt.toggleHTMLElement).addClass(cls.toggle));
					return;
				}
			}
			//check if we have an toggle column. If not then add it to the first column just to be safe
			if (!hasToggleColumn) {
				$table
                    .find('> tbody > tr:not(.' + cls.detail + ',.' + cls.disabled + ') > td:first-child')
                    .not('.' + cls.detailCell)
                    .prepend($(opt.toggleHTMLElement).addClass(cls.toggle));
			}
		};

		ft.setColumnClasses = function () {
			$table = $(ft.table);
			for (var c in ft.columns) {
				var col = ft.columns[c];
				if (col.className !== null) {
					var selector = '', first = true;
					$.each(col.matches, function (m, match) { //support for colspans
						if (!first) selector += ', ';
						selector += '> tbody > tr:not(.' + cls.detail + ') > td:nth-child(' + (parseInt(match, 10) + 1) + ')';
						first = false;
					});
					//add the className to the cells specified by data-class="blah"
					$table.find(selector).not('.' + cls.detailCell).addClass(col.className);
				}
			}
		};

		//moved this out into it's own function so that it can be called from other add-ons
		ft.bindToggleSelectors = function () {
			var $table = $(ft.table);

			if (!ft.hasAnyBreakpointColumn()) return;

			$table.find(opt.toggleSelector).unbind(trg.toggleRow).bind(trg.toggleRow, function (e) {
				var $row = $(this).is('tr') ? $(this) : $(this).parents('tr:first');
				ft.toggleDetail($row);
			});

			$table.find(opt.toggleSelector).unbind('click.footable').bind('click.footable', function (e) {
				if ($table.is('.breakpoint') && $(e.target).is('td,.' + cls.toggle)) {
					$(this).trigger(trg.toggleRow);
				}
			});
		};

		ft.parse = function (cell, column) {
			var parser = opt.parsers[column.type] || opt.parsers.alpha;
			return parser(cell);
		};

		ft.getColumnData = function (th) {
			var $th = $(th), hide = $th.data('hide'), index = $th.index();
			hide = hide || '';
			hide = jQuery.map(hide.split(','), function (a) {
				return jQuery.trim(a);
			});
			var data = {
				'index': index,
				'hide': {},
				'type': $th.data('type') || 'alpha',
				'name': $th.data('name') || $.trim($th.text()),
				'ignore': $th.data('ignore') || false,
				'toggle': $th.data('toggle') || false,
				'className': $th.data('class') || null,
				'matches': [],
				'names': {},
				'group': $th.data('group') || null,
				'groupName': null
			};

			if (data.group !== null) {
				var $group = $(ft.table).find('> thead > tr.footable-group-row > th[data-group="' + data.group + '"], > thead > tr.footable-group-row > td[data-group="' + data.group + '"]').first();
				data.groupName = ft.parse($group, { 'type': 'alpha' });
			}

			var pcolspan = parseInt($th.prev().attr('colspan') || 0, 10);
			indexOffset += pcolspan > 1 ? pcolspan - 1 : 0;
			var colspan = parseInt($th.attr('colspan') || 0, 10), curindex = data.index + indexOffset;
			if (colspan > 1) {
				var names = $th.data('names');
				names = names || '';
				names = names.split(',');
				for (var i = 0; i < colspan; i++) {
					data.matches.push(i + curindex);
					if (i < names.length) data.names[i + curindex] = names[i];
				}
			} else {
				data.matches.push(curindex);
			}

			data.hide['default'] = ($th.data('hide') === "all") || ($.inArray('default', hide) >= 0);

			var hasBreakpoint = false;
			for (var name in opt.breakpoints) {
				data.hide[name] = ($th.data('hide') === "all") || ($.inArray(name, hide) >= 0);
				hasBreakpoint = hasBreakpoint || data.hide[name];
			}
			data.hasBreakpoint = hasBreakpoint;
			var e = ft.raise(evt.columnData, { 'column': { 'data': data, 'th': th } });
			return e.column.data;
		};

		ft.getViewportWidth = function () {
			return window.innerWidth || (document.body ? document.body.offsetWidth : 0);
		};

		ft.calculateWidth = function ($table, info) {
			if (jQuery.isFunction(opt.calculateWidthOverride)) {
				return opt.calculateWidthOverride($table, info);
			}
			if (info.viewportWidth < info.width) info.width = info.viewportWidth;
			if (info.parentWidth < info.width) info.width = info.parentWidth;
			return info;
		};

		ft.hasBreakpointColumn = function (breakpoint) {
			for (var c in ft.columns) {
				if (ft.columns[c].hide[breakpoint]) {
					if (ft.columns[c].ignore) {
						continue;
					}
					return true;
				}
			}
			return false;
		};

		ft.hasAnyBreakpointColumn = function () {
			for (var c in ft.columns) {
				if (ft.columns[c].hasBreakpoint) {
					return true;
				}
			}
			return false;
		};

		ft.resize = function () {
			var $table = $(ft.table);

			if (!$table.is(':visible')) {
				return;
			} //we only care about FooTables that are visible

			if (!ft.hasAnyBreakpointColumn()) {
				return;
			} //we only care about FooTables that have breakpoints

			var info = {
				'width': $table.width(),                  //the table width
				'viewportWidth': ft.getViewportWidth(),   //the width of the viewport
				'parentWidth': $table.parent().width()    //the width of the parent
			};

			info = ft.calculateWidth($table, info);

			var pinfo = $table.data('footable_info');
			$table.data('footable_info', info);
			ft.raise(evt.resizing, { 'old': pinfo, 'info': info });

			// This (if) statement is here purely to make sure events aren't raised twice as mobile safari seems to do
			if (!pinfo || (pinfo && pinfo.width && pinfo.width !== info.width)) {

				var current = null, breakpoint;
				for (var i = 0; i < ft.breakpoints.length; i++) {
					breakpoint = ft.breakpoints[i];
					if (breakpoint && breakpoint.width && info.width <= breakpoint.width) {
						current = breakpoint;
						break;
					}
				}

				var breakpointName = (current === null ? 'default' : current['name']),
                    hasBreakpointFired = ft.hasBreakpointColumn(breakpointName),
                    previousBreakpoint = $table.data('breakpoint');

				$table
                    .data('breakpoint', breakpointName)
                    .removeClass('default breakpoint').removeClass(ft.breakpointNames)
                    .addClass(breakpointName + (hasBreakpointFired ? ' breakpoint' : ''));

				//only do something if the breakpoint has changed
				if (breakpointName !== previousBreakpoint) {
					//trigger a redraw
					$table.trigger(trg.redraw);
					//raise a breakpoint event
					ft.raise(evt.breakpoint, { 'breakpoint': breakpointName, 'info': info });
				}
			}

			ft.raise(evt.resized, { 'old': pinfo, 'info': info });
		};

		ft.redraw = function () {
			//add the toggler to each row
			ft.addRowToggle();

			//bind the toggle selector click events
			ft.bindToggleSelectors();

			//set any cell classes defined for the columns
			ft.setColumnClasses();

			var $table = $(ft.table),
                breakpointName = $table.data('breakpoint'),
                hasBreakpointFired = ft.hasBreakpointColumn(breakpointName);

			$table
                .find('> tbody > tr:not(.' + cls.detail + ')').data('detail_created', false).end()
                .find('> thead > tr:last-child > th')
                .each(function () {
                	var data = ft.columns[$(this).index()], selector = '', first = true;
                	$.each(data.matches, function (m, match) {
                		if (!first) {
                			selector += ', ';
                		}
                		var count = match + 1;
                		selector += '> tbody > tr:not(.' + cls.detail + ') > td:nth-child(' + count + ')';
                		selector += ', > tfoot > tr:not(.' + cls.detail + ') > td:nth-child(' + count + ')';
                		selector += ', > colgroup > col:nth-child(' + count + ')';
                		first = false;
                	});

                	selector += ', > thead > tr[data-group-row="true"] > th[data-group="' + data.group + '"]';
                	var $column = $table.find(selector).add(this);
                	if (breakpointName !== '') {
                		if (data.hide[breakpointName] === false) $column.addClass('footable-visible').show();
                		else $column.removeClass('footable-visible').hide();
                	}

                	if ($table.find('> thead > tr.footable-group-row').length === 1) {
                		var $groupcols = $table.find('> thead > tr:last-child > th[data-group="' + data.group + '"]:visible, > thead > tr:last-child > th[data-group="' + data.group + '"]:visible'),
                            $group = $table.find('> thead > tr.footable-group-row > th[data-group="' + data.group + '"], > thead > tr.footable-group-row > td[data-group="' + data.group + '"]'),
                            groupspan = 0;

                		$.each($groupcols, function () {
                			groupspan += parseInt($(this).attr('colspan') || 1, 10);
                		});

                		if (groupspan > 0) $group.attr('colspan', groupspan).show();
                		else $group.hide();
                	}
                })
                .end()
                .find('> tbody > tr.' + cls.detailShow).each(function () {
                	ft.createOrUpdateDetailRow(this);
                });

			$table.find('> tbody > tr.' + cls.detailShow + ':visible').each(function () {
				var $next = $(this).next();
				if ($next.hasClass(cls.detail)) {
					if (!hasBreakpointFired) $next.hide();
					else $next.show();
				}
			});

			// adding .footable-first-column and .footable-last-column to the first and last th and td of each row in order to allow
			// for styling if the first or last column is hidden (which won't work using :first-child or :last-child)
			$table.find('> thead > tr > th.footable-last-column, > tbody > tr > td.footable-last-column').removeClass('footable-last-column');
			$table.find('> thead > tr > th.footable-first-column, > tbody > tr > td.footable-first-column').removeClass('footable-first-column');
			$table.find('> thead > tr, > tbody > tr')
                .find('> th.footable-visible:last, > td.footable-visible:last')
                .addClass('footable-last-column')
                .end()
                .find('> th.footable-visible:first, > td.footable-visible:first')
                .addClass('footable-first-column');

			ft.raise(evt.redrawn);
		};

		ft.toggleDetail = function (row) {
			var $row = (row.jquery) ? row : $(row),
                $next = $row.next();

			//check if the row is already expanded
			if ($row.hasClass(cls.detailShow)) {
				$row.removeClass(cls.detailShow);

				//only hide the next row if it's a detail row
				if ($next.hasClass(cls.detail)) $next.hide();

				ft.raise(evt.rowCollapsed, { 'row': $row[0] });

			} else {
				ft.createOrUpdateDetailRow($row[0]);
				$row.addClass(cls.detailShow)
					.next().show();

				ft.raise(evt.rowExpanded, { 'row': $row[0] });
			}
		};

		ft.removeRow = function (row) {
			var $row = (row.jquery) ? row : $(row);
			if ($row.hasClass(cls.detail)) {
				$row = $row.prev();
			}
			var $next = $row.next();
			if ($row.data('detail_created') === true) {
				//remove the detail row
				$next.remove();
			}
			$row.remove();

			//raise event
			ft.raise(evt.rowRemoved);
		};

		ft.appendRow = function (row) {
			var $row = (row.jquery) ? row : $(row);
			$(ft.table).find('tbody').append($row);

			//redraw the table
			ft.redraw();
		};

		ft.getColumnFromTdIndex = function (index) {
			/// <summary>Returns the correct column data for the supplied index taking into account colspans.</summary>
			/// <param name="index">The index to retrieve the column data for.</param>
			/// <returns type="json">A JSON object containing the column data for the supplied index.</returns>
			var result = null;
			for (var column in ft.columns) {
				if ($.inArray(index, ft.columns[column].matches) >= 0) {
					result = ft.columns[column];
					break;
				}
			}
			return result;
		};

		ft.createOrUpdateDetailRow = function (actualRow) {
			var $row = $(actualRow), $next = $row.next(), $detail, values = [];
			if ($row.data('detail_created') === true) return true;

			if ($row.is(':hidden')) return false; //if the row is hidden for some reason (perhaps filtered) then get out of here
			ft.raise(evt.rowDetailUpdating, { 'row': $row, 'detail': $next });
			$row.find('> td:hidden').each(function () {
				var index = $(this).index(), column = ft.getColumnFromTdIndex(index), name = column.name;
				if (column.ignore === true) return true;

				if (index in column.names) name = column.names[index];
				values.push({ 'name': name, 'value': ft.parse(this, column), 'display': $.trim($(this).html()), 'group': column.group, 'groupName': column.groupName });
				return true;
			});
			if (values.length === 0) return false; //return if we don't have any data to show
			var colspan = $row.find('> td:visible').length;
			var exists = $next.hasClass(cls.detail);
			if (!exists) { // Create
				$next = $('<tr class="' + cls.detail + '"><td class="' + cls.detailCell + '"><div class="' + cls.detailInner + '"></div></td></tr>');
				$row.after($next);
			}
			$next.find('> td:first').attr('colspan', colspan);
			$detail = $next.find('.' + cls.detailInner).empty();
			opt.createDetail($detail, values, opt.createGroupedDetail, opt.detailSeparator, cls);
			$row.data('detail_created', true);
			ft.raise(evt.rowDetailUpdated, { 'row': $row, 'detail': $next });
			return !exists;
		};

		ft.raise = function (eventName, args) {

			if (ft.options.debug === true && $.isFunction(ft.options.log)) ft.options.log(eventName, 'event');

			args = args || {};
			var def = { 'ft': ft };
			$.extend(true, def, args);
			var e = $.Event(eventName, def);
			if (!e.ft) {
				$.extend(true, e, def);
			} //pre jQuery 1.6 which did not allow data to be passed to event object constructor
			$(ft.table).trigger(e);
			return e;
		};

		//reset the state of FooTable
		ft.reset = function () {
			var $table = $(ft.table);
			$table.removeData('footable_info')
                .data('breakpoint', '')
                .removeClass(cls.loading)
                .removeClass(cls.loaded);

			$table.find(opt.toggleSelector).unbind(trg.toggleRow).unbind('click.footable');

			$table.find('> tbody > tr').removeClass(cls.detailShow);

			$table.find('> tbody > tr.' + cls.detail).remove();

			ft.raise(evt.reset);
		};

		ft.init();
		return ft;
	}
})(jQuery, window);
(function ($, w, undefined) {
    if (w.footable === undefined || w.footable === null)
        throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');

    var defaults = {
        filter: {
            enabled: true,
            input: '.footable-filter',
            timeout: 300,
            minimum: 2,
            disableEnter: false,
            filterFunction: function(index) {
                var $t = $(this),
                    $table = $t.parents('table:first'),
                    filter = $table.data('current-filter').toUpperCase(),
                    text = $t.find('td').text();
                if (!$table.data('filter-text-only')) {
                    $t.find('td[data-value]').each(function () {
                        text += $(this).data('value');
                    });
                }
                return text.toUpperCase().indexOf(filter) >= 0;
            }
        }
    };

    function Filter() {
        var p = this;
        p.name = 'Footable Filter';
        p.init = function (ft) {
            p.footable = ft;
            if (ft.options.filter.enabled === true) {
                if ($(ft.table).data('filter') === false) return;
                ft.timers.register('filter');
                $(ft.table)
                    .unbind('.filtering')
                    .bind({
                        'footable_initialized.filtering': function (e) {
                            var $table = $(ft.table);
                            var data = {
                                'input': $table.data('filter') || ft.options.filter.input,
                                'timeout': $table.data('filter-timeout') || ft.options.filter.timeout,
                                'minimum': $table.data('filter-minimum') || ft.options.filter.minimum,
                                'disableEnter': $table.data('filter-disable-enter') || ft.options.filter.disableEnter
                            };
                            if (data.disableEnter) {
                                $(data.input).keypress(function (event) {
                                    if (window.event)
                                        return (window.event.keyCode !== 13);
                                    else
                                        return (event.which !== 13);
                                });
                            }
                            $table.bind('footable_clear_filter', function () {
                                $(data.input).val('');
                                p.clearFilter();
                            });
                            $table.bind('footable_filter', function (event, args) {
                                p.filter(args.filter);
                            });
                            $(data.input).keyup(function (eve) {
                                ft.timers.filter.stop();
                                if (eve.which === 27) {
                                    $(data.input).val('');
                                }
                                ft.timers.filter.start(function () {
                                    var val = $(data.input).val() || '';
                                    p.filter(val);
                                }, data.timeout);
                            });
                        },
                        'footable_redrawn.filtering': function (e) {
                            var $table = $(ft.table),
                                filter = $table.data('filter-string');
                            if (filter) {
                                p.filter(filter);
                            }
                        }
                })
                //save the filter object onto the table so we can access it later
                .data('footable-filter', p);
            }
        };

        p.filter = function (filterString) {
            var ft = p.footable,
                $table = $(ft.table),
                minimum = $table.data('filter-minimum') || ft.options.filter.minimum,
                clear = !filterString;

            //raise a pre-filter event so that we can cancel the filtering if needed
            var event = ft.raise('footable_filtering', { filter: filterString, clear: clear });
            if (event && event.result === false) return;
            if (event.filter && event.filter.length < minimum) {
              return; //if we do not have the minimum chars then do nothing
            }

          if (event.clear) {
                p.clearFilter();
            } else {
                var filters = event.filter.split(' ');

                $table.find('> tbody > tr').hide().addClass('footable-filtered');
                var rows = $table.find('> tbody > tr:not(.footable-row-detail)');
                $.each(filters, function (i, f) {
                    if (f && f.length > 0) {
                        $table.data('current-filter', f);
                        rows = rows.filter(ft.options.filter.filterFunction);
                    }
                });
                rows.each(function () {
                    p.showRow(this, ft);
                    $(this).removeClass('footable-filtered');
                });
                $table.data('filter-string', event.filter);
                ft.raise('footable_filtered', { filter: event.filter, clear: false });
            }
        };

        p.clearFilter = function () {
            var ft = p.footable,
                $table = $(ft.table);

            $table.find('> tbody > tr:not(.footable-row-detail)').removeClass('footable-filtered').each(function () {
                p.showRow(this, ft);
            });
            $table.removeData('filter-string');
            ft.raise('footable_filtered', { clear: true });
        };

        p.showRow = function (row, ft) {
            var $row = $(row), $next = $row.next(), $table = $(ft.table);
            if ($row.is(':visible')) return; //already visible - do nothing
            if ($table.hasClass('breakpoint') && $row.hasClass('footable-detail-show') && $next.hasClass('footable-row-detail')) {
                $row.add($next).show();
                ft.createOrUpdateDetailRow(row);
            }
            else $row.show();
        };
    }

    w.footable.plugins.register(Filter, defaults);

})(jQuery, window);
(function ($, w, undefined) {
	if (w.footable === undefined || w.footable === null)
		throw new Error('Please check and make sure footable.js is included in the page and is loaded prior to this script.');

	var defaults = {
		paginate: true,
		pageSize: 10,
		pageNavigation: '.pagination',
		firstText: '&laquo;',
		previousText: '&lsaquo;',
		nextText: '&rsaquo;',
		lastText: '&raquo;',
		limitNavigation: 0,
		limitPreviousText: '...',
		limitNextText: '...'
	};

	function pageInfo(ft) {
		var $table = $(ft.table), data = $table.data();
		this.pageNavigation = data.pageNavigation || ft.options.pageNavigation;
		this.pageSize = data.pageSize || ft.options.pageSize;
		this.firstText = data.firstText || ft.options.firstText;
		this.previousText = data.previousText || ft.options.previousText;
		this.nextText = data.nextText || ft.options.nextText;
		this.lastText = data.lastText || ft.options.lastText;
		this.limitNavigation = parseInt(data.limitNavigation || ft.options.limitNavigation || defaults.limitNavigation, 10);
		this.limitPreviousText = data.limitPreviousText || ft.options.limitPreviousText;
		this.limitNextText = data.limitNextText || ft.options.limitNextText;
		this.limit = this.limitNavigation > 0;
		this.currentPage = data.currentPage || 0;
		this.pages = [];
		this.control = false;
	}

	function Paginate() {
		var p = this;
		p.name = 'Footable Paginate';

		p.init = function (ft) {
			if (ft.options.paginate === true) {
				if ($(ft.table).data('page') === false) return;
				p.footable = ft;
				$(ft.table)
					.unbind('.paging')
					.bind({
						'footable_initialized.paging footable_row_removed.paging footable_redrawn.paging footable_sorted.paging footable_filtered.paging': function () {
							p.setupPaging();
						}
					})
					//save the filter object onto the table so we can access it later
					.data('footable-paging', p);
			}
		};

		p.setupPaging = function () {
			var ft = p.footable,
				$tbody = $(ft.table).find('> tbody');

			ft.pageInfo = new pageInfo(ft);

			p.createPages(ft, $tbody);
			p.createNavigation(ft, $tbody);
			p.fillPage(ft, $tbody, ft.pageInfo.currentPage);
		};

		p.createPages = function (ft, tbody) {
			var pages = 1;
			var info = ft.pageInfo;
			var pageCount = pages * info.pageSize;
			var page = [];
			var lastPage = [];
			info.pages = [];
			var rows = tbody.find('> tr:not(.footable-filtered,.footable-row-detail)');
			rows.each(function (i, row) {
				page.push(row);
				if (i === pageCount - 1) {
					info.pages.push(page);
					pages++;
					pageCount = pages * info.pageSize;
					page = [];
				} else if (i >= rows.length - (rows.length % info.pageSize)) {
					lastPage.push(row);
				}
			});
			if (lastPage.length > 0) info.pages.push(lastPage);
			if (info.currentPage >= info.pages.length) info.currentPage = info.pages.length - 1;
			if (info.currentPage < 0) info.currentPage = 0;
			if (info.pages.length === 1) {
				//we only have a single page
				$(ft.table).addClass('no-paging');
			} else {
				$(ft.table).removeClass('no-paging');
			}
		};

		p.createNavigation = function (ft, tbody) {
			var $nav = $(ft.table).find(ft.pageInfo.pageNavigation);
			//if we cannot find the navigation control within the table, then try find it outside
			if ($nav.length === 0) {
				$nav = $(ft.pageInfo.pageNavigation);
				//if the navigation control is inside another table, then get out
				if ($nav.parents('table:first').length > 0 && $nav.parents('table:first') !== $(ft.table)) return;
				//if we found more than one navigation control, write error to console
				if ($nav.length > 1 && ft.options.debug === true) console.error('More than one pagination control was found!');
			}
			//if we still cannot find the control, then don't do anything
			if ($nav.length === 0) return;
			//if the nav is not a UL, then find or create a UL
			if (!$nav.is('ul')) {
				if ($nav.find('ul:first').length === 0) {
					$nav.append('<ul />');
				}
				$nav = $nav.find('ul');
			}
			$nav.find('li').remove();
			var info = ft.pageInfo;
			info.control = $nav;
			if (info.pages.length > 0) {
				$nav.append('<li class="footable-page-arrow"><a data-page="first" href="#first">' + ft.pageInfo.firstText + '</a>');
				$nav.append('<li class="footable-page-arrow"><a data-page="prev" href="#prev">' + ft.pageInfo.previousText + '</a></li>');
				if (info.limit){
					$nav.append('<li class="footable-page-arrow"><a data-page="limit-prev" href="#limit-prev">' + ft.pageInfo.limitPreviousText + '</a></li>');
				}
				if (!info.limit){
					$.each(info.pages, function (i, page) {
						if (page.length > 0) {
							$nav.append('<li class="footable-page"><a data-page="' + i + '" href="#">' + (i + 1) + '</a></li>');
						}
					});
				}
				if (info.limit){
					$nav.append('<li class="footable-page-arrow"><a data-page="limit-next" href="#limit-next">' + ft.pageInfo.limitNextText + '</a></li>');
					p.createLimited($nav, info, 0);
				}
				$nav.append('<li class="footable-page-arrow"><a data-page="next" href="#next">' + ft.pageInfo.nextText + '</a></li>');
				$nav.append('<li class="footable-page-arrow"><a data-page="last" href="#last">' + ft.pageInfo.lastText + '</a></li>');
			}
			$nav.off('click', 'a[data-page]').on('click', 'a[data-page]', function (e) {
				e.preventDefault();
				var page = $(this).data('page');
				var newPage = info.currentPage;
				if (page === 'first') {
					newPage = 0;
				} else if (page === 'prev') {
					if (newPage > 0) newPage--;
				} else if (page === 'next') {
					if (newPage < info.pages.length - 1) newPage++;
				} else if (page === 'last') {
					newPage = info.pages.length - 1;
				} else if (page === 'limit-prev') {
					newPage = -1;
					var first = $nav.find('.footable-page:first a').data('page');
					p.createLimited($nav, info, first - info.limitNavigation);
					p.setPagingClasses($nav, info.currentPage, info.pages.length);
				} else if (page === 'limit-next') {
					newPage = -1;
					var last = $nav.find('.footable-page:last a').data('page');
					p.createLimited($nav, info, last + 1);
					p.setPagingClasses($nav, info.currentPage, info.pages.length);
				} else {
					newPage = page;
				}
				if (newPage >= 0){
					if (info.limit && info.currentPage != newPage){
						var start = newPage;
						while (start % info.limitNavigation !== 0){ start -= 1; }
						p.createLimited($nav, info, start);
					}
					p.paginate(ft, newPage);
				}
			});
			p.setPagingClasses($nav, info.currentPage, info.pages.length);
		};

		p.createLimited = function(nav, info, start){
			start = start || 0;
			nav.find('li.footable-page').remove();
			var i, page,
				$prev = nav.find('li.footable-page-arrow > a[data-page="limit-prev"]').parent(),
				$next = nav.find('li.footable-page-arrow > a[data-page="limit-next"]').parent();
			for (i = info.pages.length - 1; i >=0 ; i--){
				page = info.pages[i];
				if (i >= start && i < start + info.limitNavigation && page.length > 0) {
					$prev.after('<li class="footable-page"><a data-page="' + i + '" href="#">' + (i + 1) + '</a></li>');
				}
			}
			if (start === 0){ $prev.hide(); }
			else { $prev.show(); }
			if (start + info.limitNavigation >= info.pages.length){ $next.hide(); }
			else { $next.show(); }
		};

		p.paginate = function (ft, newPage) {
			var info = ft.pageInfo;
			if (info.currentPage !== newPage) {
				var $tbody = $(ft.table).find('> tbody');

				//raise a pre-pagin event so that we can cancel the paging if needed
				var event = ft.raise('footable_paging', { page: newPage, size: info.pageSize });
				if (event && event.result === false) return;

				p.fillPage(ft, $tbody, newPage);
				info.control.find('li').removeClass('active disabled');
				p.setPagingClasses(info.control, info.currentPage, info.pages.length);
			}
		};

		p.setPagingClasses = function (nav, currentPage, pageCount) {
			nav.find('li.footable-page > a[data-page=' + currentPage + ']').parent().addClass('active');
			if (currentPage >= pageCount - 1) {
				nav.find('li.footable-page-arrow > a[data-page="next"]').parent().addClass('disabled');
				nav.find('li.footable-page-arrow > a[data-page="last"]').parent().addClass('disabled');
			}
			if (currentPage < 1) {
				nav.find('li.footable-page-arrow > a[data-page="first"]').parent().addClass('disabled');
				nav.find('li.footable-page-arrow > a[data-page="prev"]').parent().addClass('disabled');
			}
		};

		p.fillPage = function (ft, tbody, pageNumber) {
			ft.pageInfo.currentPage = pageNumber;
			$(ft.table).data('currentPage', pageNumber);
			tbody.find('> tr').hide();
			$(ft.pageInfo.pages[pageNumber]).each(function () {
				p.showRow(this, ft);
			});
		};

		p.showRow = function (row, ft) {
			var $row = $(row), $next = $row.next(), $table = $(ft.table);
			if ($table.hasClass('breakpoint') && $row.hasClass('footable-detail-show') && $next.hasClass('footable-row-detail')) {
				$row.add($next).show();
				ft.createOrUpdateDetailRow(row);
			}
			else $row.show();
		};
	}

	w.footable.plugins.register(Paginate, defaults);

})(jQuery, window);