diff --git a/README.md b/README.md
index b5984de2..9a2b652a 100644
--- a/README.md
+++ b/README.md
@@ -65,6 +65,51 @@ tablesorter can successfully parse and sort many types of data including linked
View the [complete listing here](//github.com/Mottie/tablesorter/wiki/Changes).
+#### Version 2.17.8 (9/15/2014)
+
+* Core
+ * Fix `widthFixed` option to ignore info block tbodies.
+ * Make `emptyTo` & `stringTo` settings case insensitive.
+ * An empty string `headerTemplate` option will now prevent adding an inner div to the header.
+* Docs
+ * Fix setting active accordion from hash script.
+ * Add `emptyTo` clarification.
+ * Main readme: Add related projects section.
+* Editable
+ * Autoresort true no longer breaks the table.
+ * Update demo to use row id instead of index.
+ * Update validate function to allow setting it per column.
+ * Add `editable_focus`, `editable_blur` and `editable_selectAll` options. See [issue #708](//github.com/Mottie/tablesorter/issues/708).
+ * Add `editable_wrapContent` option.
+ * Add `editable_trimContent` option.
+ * Validate function now includes a contenteditable element parameter.
+ * All text callback parameters are now trimmed.
+ * Trim everything & revert widget changes.
+ * Refocus edited element after resort only.
+ * Switch form focus to focusout.
+* Filter
+ * Add `filter_defaultFilter` option.
+ * fix issue with using class selectors.
+ * Make happy with spaces within the query.
+ * Will override exact/partial select filters. Fixes [issue #721](//github.com/Mottie/tablesorter/issues/721).
+ * Fixes [issue #704](//github.com/Mottie/tablesorter/issues/704).
+ * Add `filter_excludeFilter` option; add multiple exclusions separated by spaces, not commas.
+ * Prevent multiple searches during initialization.
+ * Ensure initial filter settings get applied.
+ * Selects will exactly match the selected option unless "filter-match" class is set. Fixes [issue #721](//github.com/Mottie/tablesorter/issues/721).
+* Pager
+ * Update cache & rows copy. Fixes [issue #703](//github.com/Mottie/tablesorter/issues/703).
+ * Use native javascript to populate & set the goto select. Fixes [issue #711](//github.com/Mottie/tablesorter/issues/711).
+ * Custom pager controls. Fix control updates for multiple tables.
+ * Fix pager widget to be properly applied after a page move.
+* StickyHeaders: Fix issue so it works with jQuery v1.2.6 again.
+* Zebra: Apply style to one row. Fixes [issue #715](//github.com/Mottie/tablesorter/issues/715).
+* Parser
+ * Duration parser - added with [demo](//mottie.github.io/tablesorter/docs/example-parsers-duration.html).
+ * Select parser - Fix for IE10+ not allowing select options to be clicked.
+ * IgnoreArticles parser - Added `ignoreArticlesExcept` option.
+ * url parser - ensure it is used by the filter widget.
+
#### Version 2.17.7 (8/9/2014)
* Core: Do not detach rows before appending to prevent ajax rows from disappearing. Fixes [issue #701](//github.com/Mottie/tablesorter/issues/701).
@@ -111,67 +156,3 @@ View the [complete listing here](//github.com/Mottie/tablesorter/wiki/Changes).
* Remove selected attribute from page selector options. Fixes [issue #700](//github.com/Mottie/tablesorter/issues/700).
* Resizable
* Update `$.tablesorter.addHeaderResizeEvent` function's first parameter `table` to accept table DOM elements as well as jQuery objects. Fixes [issue #687](//github.com/Mottie/tablesorter/issues/687).
-
-#### Version 2.17.5 (7/17/2014)
-
-* Core
- * Update `config.totalRows` variable before initialization. Fixes [issue #670](//github.com/Mottie/tablesorter/issues/670).
- * Add `config.table` variable; useful for functions that only pass the `config`.
- * Ensure widget init functions are only called once; and set indicator for all widgets, not just ones with options (for `hasWidget`).
-
-* Docs
- * Add [custom filter widget search types demo](//mottie.github.io/tablesorter/docs/example-filter-custom-search.html).
- * Add `imgAttr` parser "utility option" instructions.
-
-* Filter
- * Force cache build on initial search when `delayInit` is `true`. Fixes [issue #678](//github.com/Mottie/tablesorter/issues/678).
- * Make `config.filteredRows` count available within `filterInit` event. Fixes [issue #670](//github.com/Mottie/tablesorter/issues/670).
- * Selects now obtain parsed data when it is set for a particular column. Fixes [issue #684](//github.com/Mottie/tablesorter/issues/684).
- * Ignore change event if input value hasn't changed, otherwise it interferes with other events within the table. Fixes [issue #685](//github.com/Mottie/tablesorter/issues/685).
- * Ensure search query is parsed for both specific filter types and non-filter type searches, if the column is set to use parsed data.
- * Filter initialization ("filterInit") event is now delayed to prevent filterStart & filterEnd event spamming. Fixes [issue #668](//github.com/Mottie/tablesorter/issues/668).
- * Filter formatter functions are now required to call a function after initialization to delay "filterInit" event. Fixes [issue #668](//github.com/Mottie/tablesorter/issues/668).
-
-* Output
- * Update download method which allows downloading files without modifying the server htaccess. Fixes [issue #681](//github.com/Mottie/tablesorter/issues/681).
-
-* Pager
- * Initialize without building cache when `delayInit` is `true`. Fixes [issue #678](//github.com/Mottie/tablesorter/issues/678).
-
-* Parsers
- * Update input/select element binding
- * Add image alt parser; set `config.imgAttr` with attribute to target (default is `"alt"`).
- * Add `select-text` parser which grabs the currently selected option text instead of the select value.
-
-* Resizable
- * Remove unused grip code
-
-#### Version 2.17.4 (7/4/2014)
-
-* Docs
- * Copied the tablesorter `initialized` option from the event section into the configuration; renamed the event appropriately (`tablesorter-initialized` event)
- * Added notes about how to bind to "init" events; they should be bound before initializing tablesorter because in most cases, the events fire before the binding occurs.
-
-* Core
- * Add `$.tablesorter.hasWidget(table, 'widgetId')` function. It returns a boolean value of `true` when the named widget is actively applied to the table.
-
-* Filter
- * Add `filter_searchFiltered` option to allow disabling the search of already filtered rows.
- * The `filter_initialized` flag now gets set appropriately. Fixes [issue #668](//github.com/Mottie/tablesorter/issues/668).
- * Include any column filter in determination of searching already filtered rows. Fixes [issue #669](//github.com/Mottie/tablesorter/issues/669).
- * Add internal `config.filteredRows` variable. Provides a value of the number of currently filtered (visible) rows. Fixes [issue #670](//github.com/Mottie/tablesorter/issues/670).
- * Add internal `config.totalRows` variable. Provides a value of the total number of rows in the current table, not including info-tbody rows.
- * Fix change/search event being ignored for selects & filterFormatter extensions.
- * `filterInit` and `filterEnd` events now pass `config` as a parameter.
-
-* Pager
- * Removed from beta status
- * Filtered rows now equals the total rows when `ajaxProcessing` returns an array. Fixes [issue #667](//github.com/Mottie/tablesorter/issues/667).
- * Update the `config.filteredRows` when using ajax to match the internal `config.pager.filteredRows`. See [issue #670](//github.com/Mottie/tablesorter/issues/670).
- * Widget only: ensure `pagerComplete` event fires on initialization.
-
-* Resizable
- * Bind mousemove to document instead of table header. Makes resizable handle use consistent with other resizing libraries, as the user would expect. Fixes [issue #665](//github.com/Mottie/tablesorter/issues/665).
- * Add `resizable_throttle` option to allow throttling of the mousemove/resize event. Set this option to `true` or a number between 1 and 10 to add a throttling delay. Fixes [issue #662](//github.com/Mottie/tablesorter/issues/662).
-
-* UITheme: non-existent columns no longer cause a js error. Fixes [issue #672](//github.com/Mottie/tablesorter/issues/672).
diff --git a/addons/pager/jquery.tablesorter.pager.js b/addons/pager/jquery.tablesorter.pager.js
index 1020c898..a3c54cc1 100644
--- a/addons/pager/jquery.tablesorter.pager.js
+++ b/addons/pager/jquery.tablesorter.pager.js
@@ -1,6 +1,6 @@
/*!
* tablesorter pager plugin
- * updated 8/1/2014 (v2.17.6)
+ * updated 9/15/2014 (v2.17.8)
*/
/*jshint browser:true, jquery:true, unused:false */
;(function($) {
diff --git a/addons/pager/jquery.tablesorter.pager.min.js b/addons/pager/jquery.tablesorter.pager.min.js
index 7e32c30e..ef9a49b9 100644
--- a/addons/pager/jquery.tablesorter.pager.min.js
+++ b/addons/pager/jquery.tablesorter.pager.min.js
@@ -1,2 +1,2 @@
-/* tablesorter pager plugin updated 8/1/2014 (v2.17.6) */
-;(function(h){var k=h.tablesorter;h.extend({tablesorterPager:new function(){this.defaults={container:null,ajaxUrl:null,customAjaxUrl:function(b,a){return a},ajaxObject:{dataType:"json"},processAjaxOnInit:!0,ajaxProcessing:function(b){return[0,[],null]},output:"{startRow} to {endRow} of {totalRows} rows",updateArrows:!0,page:0,pageReset:0,size:10,savePages:!0,storageKey:"tablesorter-pager",fixedHeight:!1,countChildRows:!1,removeRows:!1,cssFirst:".first",cssPrev:".prev",cssNext:".next",cssLast:".last", cssGoto:".gotoPage",cssPageDisplay:".pagedisplay",cssPageSize:".pagesize",cssErrorRow:"tablesorter-errorRow",cssDisabled:"disabled",totalRows:0,totalPages:0,filteredRows:0,filteredPages:0,ajaxCounter:0,currentFilters:[],startRow:0,endRow:0,$size:null,last:{}};var w=this,p=function(b,a){var d=b.cssDisabled,e=!!a,g=e||0===b.page,f=Math.min(b.totalPages,b.filteredPages),e=e||b.page===f-1||0===f;b.updateArrows&&(b.$container.find(b.cssFirst+","+b.cssPrev)[g?"addClass":"removeClass"](d).attr("aria-disabled", g),b.$container.find(b.cssNext+","+b.cssLast)[e?"addClass":"removeClass"](d).attr("aria-disabled",e))},t=function(b,a,d){var e,g,f,l,c=b.config;l=c.$table.hasClass("hasFilters");f=[];e=a.size||10;f=[c.widgetOptions&&c.widgetOptions.filter_filteredRow||"filtered",c.selectorRemove.replace(/^(\w+\.)/g,"")];a.countChildRows&&f.push(c.cssChildRow);f.join("|");l&&!a.ajaxUrl?h.isEmptyObject(c.cache)?a.filteredRows=a.totalRows=c.$tbodies.eq(0).children("tr").not(a.countChildRows?"":"."+c.cssChildRow).length: (a.filteredRows=0,h.each(c.cache[0].normalized,function(d,b){a.filteredRows+=a.regexRows.test(b[c.columns].$row[0].className)?0:1})):l||(a.filteredRows=a.totalRows);a.totalPages=Math.ceil(a.totalRows/e);c.totalRows=a.totalRows;c.filteredRows=a.filteredRows;a.filteredPages=Math.ceil(a.filteredRows/e)||0;if(0<=Math.min(a.totalPages,a.filteredPages)&&(f=a.size*a.page>a.filteredRows,a.startRow=f?1:0===a.filteredRows?0:a.size*a.page+1,a.page=f?0:a.page,a.endRow=Math.min(a.filteredRows,a.totalRows,a.size* (a.page+1)),l=a.$container.find(a.cssPageDisplay),f=(a.ajaxData&&a.ajaxData.output?a.ajaxData.output||a.output:a.output).replace(/\{page([\-+]\d+)?\}/gi,function(c,b){return a.totalPages?a.page+(b?parseInt(b,10):1):0}).replace(/\{\w+(\s*:\s*\w+)?\}/gi,function(c){var b,d;b=c.replace(/[{}\s]/g,"");c=b.split(":");d=a.ajaxData;var e=/(rows?|pages?)$/i.test(b)?0:"";return/(startRow|page)/.test(c[0])&&"input"===c[1]?(b=(""+("page"===c[0]?a.totalPages:a.totalRows)).length,d="page"===c[0]?a.page+1:a.startRow, ''):1"+e+"";a.$goto.html(f).val(a.page+1)}l.find(".ts-startRow, .ts-page").unbind("change").bind("change",function(){var b=h(this).val(),b=h(this).hasClass("ts-startRow")?Math.floor(b/a.size)+1:b;c.$table.trigger("pageSet.pager", [b])})}p(a);a.initialized&&!1!==d&&(c.$table.trigger("pagerComplete",a),a.savePages&&k.storage&&k.storage(b,a.storageKey,{page:a.page,size:a.size}))},u=function(b,a){var d,e=b.config,g=e.$tbodies.eq(0);a.fixedHeight&&(g.find("tr.pagerSavedHeightSpacer").remove(),d=h.data(b,"pagerSavedHeight"))&&(d-=g.height(),5'))}, z=function(b,a){var d=b.config.$tbodies.eq(0);d.find("tr.pagerSavedHeightSpacer").remove();h.data(b,"pagerSavedHeight",d.height());u(b,a);h.data(b,"pagerLastSize",a.size)},v=function(b,a){if(!a.ajaxUrl){var d,e=0,g=b.config,f=g.$tbodies.eq(0).children("tr"),h=f.length,c=a.page*a.size,m=c+a.size,n=g.widgetOptions&&g.widgetOptions.filter_filteredRow||"filtered",s=0;for(d=0;d=c&& s";for(g=0;g"+e[f][g]+"";p+=""}d.processAjaxOnInit&&r.$tbodies.eq(0).html(p)}d.processAjaxOnInit=!0;n&&n.length===b&&(m=(l=q.hasClass("hasStickyHeaders"))?r.widgetOptions.$sticky.children("thead:first").children("tr").children():"",c=q.find("tfoot tr:first").children(),r.$headers.filter("th").each(function(a){var b=h(this),d;b.find("."+k.css.icon).length?(d=b.find("."+ k.css.icon).clone(!0),b.find(".tablesorter-header-inner").html(n[a]).append(d),l&&m.length&&(d=m.eq(a).find("."+k.css.icon).clone(!0),m.eq(a).find(".tablesorter-header-inner").html(n[a]).append(d))):(b.find(".tablesorter-header-inner").html(n[a]),l&&m.length&&m.eq(a).find(".tablesorter-header-inner").html(n[a]));c.eq(a).html(n[a])}))}r.showProcessing&&k.isProcessing(a);d.totalPages=Math.ceil(d.totalRows/(d.size||10));d.last.totalRows=d.totalRows;d.last.currentFilters=d.currentFilters;d.last.sortList= (r.sortList||[]).join(",");t(a,d);u(a,d);q.trigger("updateCache",[function(){d.initialized&&setTimeout(function(){q.trigger("applyWidgets").trigger("pagerChange",d)},0)}])}d.initialized||(d.initialized=!0,h(a).trigger("applyWidgets").trigger("pagerInitialized",d))},H=function(b,a){var d=G(b,a),e=h(document),g,f=b.config;""!==d&&(f.showProcessing&&k.isProcessing(b,!0),e.bind("ajaxError.pager",function(d,c,f,g){B(null,b,a,c,g);e.unbind("ajaxError.pager")}),g=++a.ajaxCounter,a.ajaxObject.url=d,a.ajaxObject.success= function(d,c,f){g(a&&a.length||0))e.debug&&k.log("Pager: no rows for pager to render");else{d.page>=d.totalPages&&C(b,d);d.isDisabled=!1;d.initialized&&c.trigger("pagerChange",d);if(d.removeRows){k.clearTableBody(b);e=k.processTbody(b,e.$tbodies.eq(0),!0);g=m?0:n;f=m?0:n;for(l=0;ln&&l<=s&&(l++,e.append(a[g]))),g++;k.processTbody(b,e,!1)}else v(b,d);t(b,d);d.isDisabled||u(b,d);c.trigger("applyWidgets");b.isUpdating&&c.trigger("updateComplete", b)}},D=function(b,a){a.ajax?p(a,!0):(a.isDisabled=!0,h.data(b,"pagerLastPage",a.page),h.data(b,"pagerLastSize",a.size),a.page=0,a.size=a.totalRows,a.totalPages=1,h(b).addClass("pagerDisabled").removeAttr("aria-describedby").find("tr.pagerSavedHeightSpacer").remove(),x(b,b.config.rowsCopy,a),b.config.debug&&k.log("pager disabled"));a.$size.add(a.$goto).add(a.$container.find(".ts-startRow, .ts-page")).each(function(){h(this).attr("aria-disabled","true").addClass(a.cssDisabled)[0].disabled=!0})},E=function(b){var a= b.config,d=a.pager;a.$table.trigger("updateCache",[function(){var e,g=[],f=b.config.cache[0].normalized;d.totalRows=f.length;for(e=0;ea.page&&(a.page=0);a.page>l-1&&0!==l&&(a.page=l-1);f.currentFilters=""===(f.currentFilters||[]).join("")?[]:f.currentFilters; a.currentFilters=""===(a.currentFilters||[]).join("")?[]:a.currentFilters;if(f.page!==a.page||f.size!==a.size||f.totalRows!==a.totalRows||(f.currentFilters||[]).join(",")!==(a.currentFilters||[]).join(",")||f.sortList!==(e.sortList||[]).join(","))e.debug&&k.log("Pager changing to page "+a.page),a.last={page:a.page,size:a.size,sortList:(e.sortList||[]).join(","),totalRows:a.totalRows,currentFilters:a.currentFilters||[]},a.ajax?H(b,a):a.ajax||x(b,e.rowsCopy,a),h.data(b,"pagerLastPage",a.page),a.initialized&& !1!==d&&(g.trigger("pageMoved",a).trigger("applyWidgets"),b.isUpdating&&g.trigger("updateComplete"))}},y=function(b,a,d){d.size=a||d.size||10;d.$size.val(d.size);h.data(b,"pagerLastPage",d.page);h.data(b,"pagerLastSize",d.size);d.totalPages=Math.ceil(d.totalRows/d.size);d.filteredPages=Math.ceil(d.filteredRows/d.size);q(b,d)},I=function(b,a){a.page=0;q(b,a)},C=function(b,a){a.page=Math.min(a.totalPages,a.filteredPages)-1;q(b,a)},J=function(b,a){a.page++;a.page>=Math.min(a.totalPages,a.filteredPages)- 1&&(a.page=Math.min(a.totalPages,a.filteredPages)-1);q(b,a)},K=function(b,a){a.page--;0>=a.page&&(a.page=0);q(b,a)},F=function(b,a,d){var e,g=b.config;a.$size.add(a.$goto).add(a.$container.find(".ts-startRow, .ts-page")).removeClass(a.cssDisabled).removeAttr("disabled").attr("aria-disabled","false");a.isDisabled=!1;a.page=h.data(b,"pagerLastPage")||a.page||0;a.size=h.data(b,"pagerLastSize")||parseInt(a.$size.find("option[selected]").val(),10)||a.size||10;a.$size.val(a.size);a.totalPages=Math.ceil(Math.min(a.totalRows, a.filteredRows)/a.size);b.id&&(e=b.id+"_pager_info",a.$container.find(a.cssPageDisplay).attr("id",e),g.$table.attr("aria-describedby",e));d&&(g.$table.trigger("updateRows"),y(b,a.size,a),A(b,a),u(b,a),g.debug&&k.log("pager enabled"))};w.appender=function(b,a){var d=b.config,e=d.pager;e.ajax||(d.rowsCopy=a,e.totalRows=e.countChildRows?d.$tbodies.eq(0).children("tr").length:a.length,e.size=h.data(b,"pagerLastSize")||e.size||10,e.totalPages=Math.ceil(e.totalRows/e.size),x(b,a,e),t(b,e,!1))};w.construct= function(b){return this.each(function(){if(this.config&&this.hasInitialized){var a,d,e,g=this,f=g.config,l=f.widgetOptions,c=f.pager=h.extend(!0,{},h.tablesorterPager.defaults,b),m=f.$table,n=c.$container=h(c.container).addClass("tablesorter-pager").show();f.debug&&k.log("Pager initializing");c.oldAjaxSuccess=c.oldAjaxSuccess||c.ajaxObject.success;f.appender=w.appender;k.filter&&0<=h.inArray("filter",f.widgets)&&(c.currentFilters=f.$table.data("lastSearch")||k.filter.setDefaults(g,f,f.widgetOptions)|| [],k.setFilters(g,c.currentFilters,!1));c.savePages&&k.storage&&(a=k.storage(g,c.storageKey)||{},c.page=isNaN(a.page)?c.page:a.page,c.size=(isNaN(a.size)?c.size:a.size)||10,h.data(g,"pagerLastSize",c.size));c.regexRows=new RegExp("("+(l.filter_filteredRow||"filtered")+"|"+f.selectorRemove.replace(/^(\w+\.)/g,"")+"|"+f.cssChildRow+")");m.unbind("filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize ".split(" ").join(".pager ")).bind("filterStart.pager",function(a, b){c.currentFilters=b;!1!==c.pageReset&&(f.lastCombinedFilter||"")!==(b||[]).join("")&&(c.page=c.pageReset)}).bind("filterEnd.pager sortEnd.pager",function(){c.initialized&&(f.delayInit&&f.rowsCopy&&0===f.rowsCopy.length&&E(g),t(g,c,!1),q(g,c,!1),u(g,c))}).bind("disable.pager",function(a){a.stopPropagation();D(g,c)}).bind("enable.pager",function(a){a.stopPropagation();F(g,c,!0)}).bind("destroy.pager",function(a){a.stopPropagation();D(g,c);c.$container.hide();g.config.appender=null;c.initialized=!1; delete g.config.rowsCopy;h(g).unbind("destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager");k.storage&&k.storage(g,c.storageKey,"")}).bind("update.pager updateRows.pager updateAll.pager addRows.pager ",function(a){a.stopPropagation();u(g,c);a=f.$tbodies.eq(0).children("tr");c.totalRows=a.length-(c.countChildRows?0:a.filter("."+f.cssChildRow).length);c.totalPages=Math.ceil(c.totalRows/c.size);t(g,c);v(g,c)}).bind("pageSize.pager",function(a,b){a.stopPropagation();y(g,parseInt(b, 10)||10,c);v(g,c);t(g,c,!1);c.$size.length&&c.$size.val(c.size)}).bind("pageSet.pager",function(a,b){a.stopPropagation();c.page=(parseInt(b,10)||1)-1;c.$goto.length&&c.$goto.val(c.size);q(g,c,!0);t(g,c,!1)});d=[c.cssFirst,c.cssPrev,c.cssNext,c.cssLast];e=[I,K,J,C];n.find(d.join(",")).attr("tabindex",0).unbind("click.pager").bind("click.pager",function(a){a.stopPropagation();var b=h(this),f=d.length;if(!b.hasClass(c.cssDisabled))for(a=0;a/.test(p)?h(p):h('