commit 466b3a5860771d7e71089924ce62e68ab79e1cb5 Author: Rob Garrison Date: Wed Jun 22 18:19:27 2011 -0500 alphanumeric sort diff --git a/README.markdown b/README.markdown new file mode 100644 index 00000000..52105268 --- /dev/null +++ b/README.markdown @@ -0,0 +1,84 @@ +Originally posted by Jeremy Satterfield in his [blog][1], [jQuery plugins][2] and on [Snipplr][3]. This fork by [Mottie][4]. + +tablesorter is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. +tablesorter can successfully parse and sort many types of data including linked data in a cell. + +###Features ([Demo][http://mottie.github.com/tablesorter/]) + +* Multi-column sorting. +* Parsers for sorting text, alphanumeric text, URIs, integers, currency, floats, IP addresses, dates (ISO, long and short formats), time. [Add your own easily](docs/example-parsers.html) +* Support for ROWSPAN and COLSPAN on TH elements. +* Support secondary "hidden" sorting (e.g., maintain alphabetical sort when sorting on other criteria). +* Extensibility via [widget system](docs/example-widgets.html). +* Cross-browser: IE 6.0+, FF 2+, Safari 2.0+, Opera 9.0+. +* Small code size. +* Works with jQuery 1.2.3+ + +###Documentation + +Included all original [document pages](http://mottie.github.com/tablesorter/docs/index.html). +Also check out my blog post on [undocumented options](http://wowmotty.blogspot.com/2011/06/jquery-tablesorter-missing-docs.html) which I will add to the document pages when I get around to it. + +###Licensing + +* Copyright (c) 2007 Christian Bach +* Main Examples and docs at: http://tablesorter.com +* Dual licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php) and [GPL](http://www.gnu.org/licenses/gpl.html) licenses: + +###Change Log + +#### Version 2.0.6 (2011-06-22) + +* Forked original files and docs from [tablesorter.com](http://tablesorter.com) to GitHub. +* Replaced alphabetical sort with an alphanumeric sort + * This "slower" sort can be disabled by setting the `sortLocaleCompare` option to `true` + * The `sortLocaleCompare` option's default was changed to `false`. + * Added a very basic demo. +* Added `tableClass` option + * The value is "tablesorter" by default and should no longer be required in the default markup. + * This class is applied to the table in the script and should match the css styling. +* Each header cell now has its content wrapped with a span. + * This allows applying the direction icon to the span instead of the entire cell. + * Although, this might just be extra markup with the advent of multiple background images and gradient backgrounds available in CSS3. +* Reformatted the code to make jSLint "happier". + +### Version 2.0.5b (?) + +* General + * Added "cssChildRow" option - attach a child row to its parent. + * Added "sortLocaleCompare" to use the native `String.localeCampare` method during text sort. + * Added "onRenderHeader" function that is called when classes are added to the header cells. + * Added "selectorHeaders" option to target the the header cells. + * Changed multisort function + +#### Version 2.0.3 (2008-03-17) + +* Bug fixes - Missing semicolon, broke the minified version. + +#### Version 2.0.2 (2008-03-14) + +* General + * Added support for the new metadata plugin. + * Added support for jQuery 1.2.3. + * Added support for decimal numbers and negative and positive digits. + * Updated documenation and website with new examples. + * Removed packed version. + +* Bug fixes + * Sort force (Thanks to David Lynch). + +#### Version 2.0.1 (2007-09-17) + +* General + * Removed the need for Dimensions plugin when using the pagnation plugin thanks to offset being included in the jQuery 1.2 core. + * Added support for jQuery 1.2. + * Added new Minified version of tablesorter. + * Updated documenation and website with new examples. + +* Bug fixes + * If row values are identical the original order is kept (Thanks to David hull). + * If thead includes a table $('tbody:first', table) breaks (Thanks to David Hull). + +* Speed improvements: + * appendToTable, setting innerHTML to "" before appending new content to table body. + * zebra widget. (Thanks to James Dempster). diff --git a/addons/pager/icons/first.png b/addons/pager/icons/first.png new file mode 100644 index 00000000..6f11fcb0 Binary files /dev/null and b/addons/pager/icons/first.png differ diff --git a/addons/pager/icons/last.png b/addons/pager/icons/last.png new file mode 100644 index 00000000..72079357 Binary files /dev/null and b/addons/pager/icons/last.png differ diff --git a/addons/pager/icons/next.png b/addons/pager/icons/next.png new file mode 100644 index 00000000..4a2f9d4e Binary files /dev/null and b/addons/pager/icons/next.png differ diff --git a/addons/pager/icons/prev.png b/addons/pager/icons/prev.png new file mode 100644 index 00000000..15d1584b Binary files /dev/null and b/addons/pager/icons/prev.png differ diff --git a/addons/pager/jquery.tablesorter.pager.css b/addons/pager/jquery.tablesorter.pager.css new file mode 100644 index 00000000..a8236dc0 --- /dev/null +++ b/addons/pager/jquery.tablesorter.pager.css @@ -0,0 +1,25 @@ +div.tablesorterPager { + padding: 10px 0 10px 0; + background-color: #D6D2C2; + text-align: center; +} +div.tablesorterPager span { + padding: 0 5px 0 5px; +} +div.tablesorterPager input.prev { + width: auto; + margin-right: 10px; +} +div.tablesorterPager input.next { + width: auto; + margin-left: 10px; +} +div.tablesorterPager input { + font-size: 8px; + width: 50px; + border: 1px solid #330000; + text-align: center; +} + + + \ No newline at end of file diff --git a/addons/pager/jquery.tablesorter.pager.js b/addons/pager/jquery.tablesorter.pager.js new file mode 100644 index 00000000..5a34d825 --- /dev/null +++ b/addons/pager/jquery.tablesorter.pager.js @@ -0,0 +1,184 @@ +(function($) { + $.extend({ + tablesorterPager: new function() { + + function updatePageDisplay(c) { + var s = $(c.cssPageDisplay,c.container).val((c.page+1) + c.seperator + c.totalPages); + } + + function setPageSize(table,size) { + var c = table.config; + c.size = size; + c.totalPages = Math.ceil(c.totalRows / c.size); + c.pagerPositionSet = false; + moveToPage(table); + fixPosition(table); + } + + function fixPosition(table) { + var c = table.config; + if(!c.pagerPositionSet && c.positionFixed) { + var c = table.config, o = $(table); + if(o.offset) { + c.container.css({ + top: o.offset().top + o.height() + 'px', + position: 'absolute' + }); + } + c.pagerPositionSet = true; + } + } + + function moveToFirstPage(table) { + var c = table.config; + c.page = 0; + moveToPage(table); + } + + function moveToLastPage(table) { + var c = table.config; + c.page = (c.totalPages-1); + moveToPage(table); + } + + function moveToNextPage(table) { + var c = table.config; + c.page++; + if(c.page >= (c.totalPages-1)) { + c.page = (c.totalPages-1); + } + moveToPage(table); + } + + function moveToPrevPage(table) { + var c = table.config; + c.page--; + if(c.page <= 0) { + c.page = 0; + } + moveToPage(table); + } + + + function moveToPage(table) { + var c = table.config; + if(c.page < 0 || c.page > (c.totalPages-1)) { + c.page = 0; + } + + renderTable(table,c.rowsCopy); + } + + function renderTable(table,rows) { + + var c = table.config; + var l = rows.length; + var s = (c.page * c.size); + var e = (s + c.size); + if(e > rows.length ) { + e = rows.length; + } + + + var tableBody = $(table.tBodies[0]); + + // clear the table body + + $.tablesorter.clearTableBody(table); + + for(var i = s; i < e; i++) { + + //tableBody.append(rows[i]); + + var o = rows[i]; + var l = o.length; + for(var j=0; j < l; j++) { + + tableBody[0].appendChild(o[j]); + + } + } + + fixPosition(table,tableBody); + + $(table).trigger("applyWidgets"); + + if( c.page >= c.totalPages ) { + moveToLastPage(table); + } + + updatePageDisplay(c); + } + + this.appender = function(table,rows) { + + var c = table.config; + + c.rowsCopy = rows; + c.totalRows = rows.length; + c.totalPages = Math.ceil(c.totalRows / c.size); + + renderTable(table,rows); + }; + + this.defaults = { + size: 10, + offset: 0, + page: 0, + totalRows: 0, + totalPages: 0, + container: null, + cssNext: '.next', + cssPrev: '.prev', + cssFirst: '.first', + cssLast: '.last', + cssPageDisplay: '.pagedisplay', + cssPageSize: '.pagesize', + seperator: "/", + positionFixed: true, + appender: this.appender + }; + + this.construct = function(settings) { + + return this.each(function() { + + config = $.extend(this.config, $.tablesorterPager.defaults, settings); + + var table = this, pager = config.container; + + $(this).trigger("appendCache"); + + config.size = parseInt($(".pagesize",pager).val()); + + $(config.cssFirst,pager).click(function() { + moveToFirstPage(table); + return false; + }); + $(config.cssNext,pager).click(function() { + moveToNextPage(table); + return false; + }); + $(config.cssPrev,pager).click(function() { + moveToPrevPage(table); + return false; + }); + $(config.cssLast,pager).click(function() { + moveToLastPage(table); + return false; + }); + $(config.cssPageSize,pager).change(function() { + setPageSize(table,parseInt($(this).val())); + return false; + }); + }); + }; + + } + }); + // extend plugin scope + $.fn.extend({ + tablesorterPager: $.tablesorterPager.construct + }); + +})(jQuery); \ No newline at end of file diff --git a/changelog b/changelog new file mode 100644 index 00000000..15f3ab2c --- /dev/null +++ b/changelog @@ -0,0 +1,70 @@ +tablesorter changelog +====================== +http://tablesorter.com + + +Changes in version 2.0.6 (2011-06-22) +------------------------------------- + +General +* Forked original files and docs from [tablesorter.com](http://tablesorter.com) to GitHub. +* Replaced alphabetical sort with an alphanumeric sort + * This "slower" sort can be disabled by setting the `sortLocaleCompare` option to `true` + * The `sortLocaleCompare` option's default was changed to `false`. + * Added a very basic demo. +* Added `tableClass` option + * The value is "tablesorter" by default and should no longer be required in the default markup. + * This class is applied to the table in the script and should match the css styling. +* Each header cell now has its content wrapped with a span. + * This allows applying the direction icon to the span instead of the entire cell. + * Although, this might just be extra markup with the advent of multiple background images and gradient backgrounds available in CSS3. +* Reformatted the code to make jSLint "happier". + + +Changes in version 2.0.5b (???) +------------------------------------- + +* General + * Added "cssChildRow" option + * Added "sortLocaleCompare" to use the native `String.localeCampare` method. + * Added "onRenderHeader" function that is called when classes are added to the header cells. + * Added "selectorHeaders" option to target the the header cells. + + +Changes in version 2.0.3 (2008-03-17) +------------------------------------- + +Bug fixes +* Missing semicolon, broke the minified version + + +Changes in version 2.0.2 (2008-03-14) +------------------------------------- + +General +* Added support for the new metadata plugin +* Added support for jQuery 1.2.3 +* Added support for decimal numbers and negative and positive digits +* Updated documenation and website with new examples +* Removed packed version. + +Bug fixes +* Sort force (Thanks to David Lynch) + + +Changes in version 2.0.1 (2007-09-17) +------------------------------------- + +General +* Removed the need for Dimensions plugin when using the pagnation plugin thanks to offset being included in the jQuery 1.2 core. +* Added support for jQuery 1.2 +* Added new Minified version of tablesorter +* Updated documenation and website with new examples + +Bug fixes +* If row values are identical the original order is kept (Thanks to David hull) +* If thead includes a table $('tbody:first', table) breaks (Thanks to David Hull) + +Speed improvements: +* appendToTable, setting innerHTML to "" before appending new content to table body. +* zebra widget. (Thanks to James Dempster) \ No newline at end of file diff --git a/css/blue/black-asc.gif b/css/blue/black-asc.gif new file mode 100644 index 00000000..74157867 Binary files /dev/null and b/css/blue/black-asc.gif differ diff --git a/css/blue/black-bg.gif b/css/blue/black-bg.gif new file mode 100644 index 00000000..fac668fc Binary files /dev/null and b/css/blue/black-bg.gif differ diff --git a/css/blue/black-desc.gif b/css/blue/black-desc.gif new file mode 100644 index 00000000..3b30b3c5 Binary files /dev/null and b/css/blue/black-desc.gif differ diff --git a/css/blue/blue.zip b/css/blue/blue.zip new file mode 100644 index 00000000..9945a92a Binary files /dev/null and b/css/blue/blue.zip differ diff --git a/css/blue/style.css b/css/blue/style.css new file mode 100644 index 00000000..1b0dc7a1 --- /dev/null +++ b/css/blue/style.css @@ -0,0 +1,39 @@ +/* Blue Theme */ +table.tablesorter { + font-family:arial; + background-color: #CDCDCD; + margin:10px 0pt 15px; + font-size: 8pt; + width: 100%; + text-align: left; +} +table.tablesorter thead tr th, table.tablesorter tfoot tr th { + background-color: #e6EEEE; + border: 1px solid #FFF; + font-size: 8pt; + padding: 4px; +} +table.tablesorter thead tr .header { + background-image: url(black-bg.gif); + background-repeat: no-repeat; + background-position: center right; + cursor: pointer; +} +table.tablesorter tbody td { + color: #3D3D3D; + padding: 4px; + background-color: #FFF; + vertical-align: top; +} +table.tablesorter tbody tr.odd td { + background-color:#F0F0F6; +} +table.tablesorter thead tr .headerSortUp { + background-image: url(black-asc.gif); +} +table.tablesorter thead tr .headerSortDown { + background-image: url(black-desc.gif); +} +table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp { +background-color: #8dbdd8; +} diff --git a/css/blue/white-asc.gif b/css/blue/white-asc.gif new file mode 100644 index 00000000..e5cd8dc9 Binary files /dev/null and b/css/blue/white-asc.gif differ diff --git a/css/blue/white-bg.gif b/css/blue/white-bg.gif new file mode 100644 index 00000000..26db2c16 Binary files /dev/null and b/css/blue/white-bg.gif differ diff --git a/css/blue/white-desc.gif b/css/blue/white-desc.gif new file mode 100644 index 00000000..3599e0a7 Binary files /dev/null and b/css/blue/white-desc.gif differ diff --git a/css/green/asc.png b/css/green/asc.png new file mode 100644 index 00000000..66e39cad Binary files /dev/null and b/css/green/asc.png differ diff --git a/css/green/bg.png b/css/green/bg.png new file mode 100644 index 00000000..ca837161 Binary files /dev/null and b/css/green/bg.png differ diff --git a/css/green/desc.png b/css/green/desc.png new file mode 100644 index 00000000..431f63ab Binary files /dev/null and b/css/green/desc.png differ diff --git a/css/green/green.zip b/css/green/green.zip new file mode 100644 index 00000000..6a14d240 Binary files /dev/null and b/css/green/green.zip differ diff --git a/css/green/style.css b/css/green/style.css new file mode 100644 index 00000000..4a545898 --- /dev/null +++ b/css/green/style.css @@ -0,0 +1,39 @@ +table.tablesorter { + font-size: 12px; + background-color: #4D4D4D; + width: 1024px; + border: 1px solid #000; +} +table.tablesorter th { + text-align: left; + padding: 5px; + background-color: #6E6E6E; +} +table.tablesorter td { + color: #FFF; + padding: 5px; +} +table.tablesorter .even { + background-color: #3D3D3D; +} +table.tablesorter .odd { + background-color: #6E6E6E; +} +table.tablesorter .header { + background-image: url(bg.png); + background-repeat: no-repeat; + border-left: 1px solid #FFF; + border-right: 1px solid #000; + border-top: 1px solid #FFF; + padding-left: 30px; + padding-top: 8px; + height: auto; +} +table.tablesorter .headerSortUp { + background-image: url(asc.png); + background-repeat: no-repeat; +} +table.tablesorter .headerSortDown { + background-image: url(desc.png); + background-repeat: no-repeat; +} \ No newline at end of file diff --git a/docs/assets/ajax-content.html b/docs/assets/ajax-content.html new file mode 100644 index 00000000..e2f9e1b5 --- /dev/null +++ b/docs/assets/ajax-content.html @@ -0,0 +1,40 @@ + + Peter + Parker + 28 + $9.99 + 20% + Jul 6, 2006 8:14 AM + + + John + Hood + 33 + $19.99 + 25% + Dec 10, 2002 5:14 AM + + + Clark + Kent + 18 + $15.89 + 44% + Jan 12, 2003 11:14 AM + + + Bruce + Almighty + 45 + $153.19 + 44% + Jan 18, 2001 9:12 AM + + + Bruce + Evans + 22 + $13.19 + 11% + Jan 18, 2007 9:12 AM + \ No newline at end of file diff --git a/docs/css/jq.css b/docs/css/jq.css new file mode 100644 index 00000000..d7dcfc56 --- /dev/null +++ b/docs/css/jq.css @@ -0,0 +1,32 @@ +body,div,h1{font-family:'trebuchet ms', verdana, arial;margin:0;padding:0;} +body{background-color:#fff;color:#333;margin:0;padding:0;} +h1{font-size:large;font-weight:400;margin:0;} +h2{color:#333;font-size:small;font-weight:400;margin:0;} +.demo{width:600px;margin:0 auto;} +.demo h1,.demo h1 a{font-size:120%;text-align:center;text-decoration:none;} +.demo p{text-align:center;} +.demo table.tablesorter{font-size:14px;} +pre{background-color:#eee;border:1px solid #ddd;border-left-width:5px;color:#333;font-size:small;overflow-x:auto;padding:15px;} +pre.normal{background-color:transparent;border:none;border-left-width:0;overflow-x:auto;} +#logo{background:url(images/jq.png);display:block;float:right;height:31px;margin-right:10px;margin-top:10px;width:110px;} +#main{margin:0 20px 20px;padding:0 15px 15px 0;} +#content{padding:20px;} +#busy{background-color:#e95555;border:1px ridge #ccc;color:#eee;display:none;padding:3px;position:absolute;right:7px;top:7px;} +hr{height:1px;} +code{font-size:108%;font-style:normal;padding:0;} +ul{color:#333;list-style:square;} +#banner{margin:20px;padding-bottom:10px;text-align:left;} +#banner *{color:#232121;font-family:Georgia, Palatino, Times New Roman;font-size:30px;font-style:normal;font-weight:400;margin:0;padding:0;} +#banner h1{display:block;float:left;} +#banner h1 em{color:#6cf;} +#banner h2{float:right;font-size:26px;margin:10px 10px -10px -10px;} +#banner h3{clear:both;display:block;font-size:12px;margin-top:-20px;} +#banner a{border-top:1px solid #888;display:block;font-size:14px;margin:5px 0 0;padding:10px 0 0;text-align:right;width:auto;} +a.external{background-image:url(../img/external.png);background-position:center right;background-repeat:no-repeat;padding-right:12px;} +form{font-size:10pt;margin-bottom:20px;width:auto;} +form fieldset{padding:10px;text-align:left;width:140px;} +div#main h1{border-bottom:1px solid #CDCDCD;display:block;margin-top:20px;padding:10px 0 2px;} +table#tablesorter-demo {margin: 10px 0 0 0;} +table#options *{font-size:small;} +p.tip em {padding: 2px; background-color: #6cf; color: #FFF;} +div.digg {float: right;} \ No newline at end of file diff --git a/docs/example-ajax.html b/docs/example-ajax.html new file mode 100644 index 00000000..d1f30813 --- /dev/null +++ b/docs/example-ajax.html @@ -0,0 +1,121 @@ + + + + jQuery plugin: Tablesorter 2.0 - Appending table data with ajax + + + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+ Append new table data +
+
+
+

*Note* This demo will only work when the ajax page is online - switch to jQuery v1.4.4 to test it locally

+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + diff --git a/docs/example-empty-table.html b/docs/example-empty-table.html new file mode 100644 index 00000000..6f521c1d --- /dev/null +++ b/docs/example-empty-table.html @@ -0,0 +1,79 @@ + + + + jQuery plugin: Tablesorter 2.0 - Initializing tablesorter on a empty table + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
+ + Append new table data +
+
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + diff --git a/docs/example-extending-defaults.html b/docs/example-extending-defaults.html new file mode 100644 index 00000000..5b1322d8 --- /dev/null +++ b/docs/example-extending-defaults.html @@ -0,0 +1,113 @@ + + + + jQuery plugin: Tablesorter 2.0 - Extending default options + + + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-meta-headers.html b/docs/example-meta-headers.html new file mode 100644 index 00000000..9ffe696f --- /dev/null +++ b/docs/example-meta-headers.html @@ -0,0 +1,112 @@ + + + + jQuery plugin: Tablesorter 2.0 - Disable headers using metadata + + + + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-meta-parsers.html b/docs/example-meta-parsers.html new file mode 100644 index 00000000..73987ed9 --- /dev/null +++ b/docs/example-meta-parsers.html @@ -0,0 +1,104 @@ + + + + jQuery plugin: Tablesorter 2.0 - Setting column parser using metadata + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-meta-sort-list.html b/docs/example-meta-sort-list.html new file mode 100644 index 00000000..2b21d3ec --- /dev/null +++ b/docs/example-meta-sort-list.html @@ -0,0 +1,108 @@ + + + + jQuery plugin: Tablesorter 2.0 - Setting initial sorting order with metadata + + + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-option-debug.html b/docs/example-option-debug.html new file mode 100644 index 00000000..2c527126 --- /dev/null +++ b/docs/example-option-debug.html @@ -0,0 +1,117 @@ + + + + jQuery plugin: Tablesorter 2.0 - Enabling debug mode + + + + + + + + + + + + + + + + + + + + + + +
+ +

+ NOTE! If firebug is installed the debuging information will be displayed in the firebug console. +

+ +

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+ +
+ +

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-option-digits.html b/docs/example-option-digits.html new file mode 100644 index 00000000..4982c5e6 --- /dev/null +++ b/docs/example-option-digits.html @@ -0,0 +1,109 @@ + + + + jQuery plugin: Tablesorter 2.0 - Enabling debug mode + + + + + + + + + + + + + + + + + + + + + +
+ +

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDiff
PeterParker289.9920.3%+3
JohnHood3319.9925.1%-7
ClarkKent1815.8944.2%-15
BruceAlmighty45153.1944%+19
BruceEvans56153.1923%+9
+ +
+ +

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-option-sort-force.html b/docs/example-option-sort-force.html new file mode 100644 index 00000000..4bec8719 --- /dev/null +++ b/docs/example-option-sort-force.html @@ -0,0 +1,112 @@ + + + + jQuery plugin: Tablesorter 2.0 - Force a default sorting order + + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-option-sort-key.html b/docs/example-option-sort-key.html new file mode 100644 index 00000000..be0ada83 --- /dev/null +++ b/docs/example-option-sort-key.html @@ -0,0 +1,109 @@ + + + + jQuery plugin: Tablesorter 2.0 - Change multi-column sorting key + + + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-option-sort-list.html b/docs/example-option-sort-list.html new file mode 100644 index 00000000..66b6c868 --- /dev/null +++ b/docs/example-option-sort-list.html @@ -0,0 +1,112 @@ + + + + jQuery plugin: Tablesorter 2.0 - Set a initial sorting order + + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-option-sort-order.html b/docs/example-option-sort-order.html new file mode 100644 index 00000000..a763fc9b --- /dev/null +++ b/docs/example-option-sort-order.html @@ -0,0 +1,109 @@ + + + + jQuery plugin: Tablesorter 2.0 - Set a initial sort order + + + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-option-text-extraction.html b/docs/example-option-text-extraction.html new file mode 100644 index 00000000..5292c234 --- /dev/null +++ b/docs/example-option-text-extraction.html @@ -0,0 +1,89 @@ + + + + jQuery plugin: Tablesorter 2.0 - Dealing with markup inside cells + + + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-options-headers.html b/docs/example-options-headers.html new file mode 100644 index 00000000..e1726ca9 --- /dev/null +++ b/docs/example-options-headers.html @@ -0,0 +1,119 @@ + + + + jQuery plugin: Tablesorter 2.0 - Disable headers using options + + + + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-pager.html b/docs/example-pager.html new file mode 100644 index 00000000..94d2bfbd --- /dev/null +++ b/docs/example-pager.html @@ -0,0 +1,306 @@ + + + + jQuery plugin: Tablesorter 2.0 - Pager plugin + + + + + + + + + + + + + + + + + + + + + +
+ +

Javascript

+
+$(function(){
+	$("table")
+		.tablesorter({
+			widthFixed: true,
+			widgets: ['zebra']
+		})
+		.tablesorterPager({
+			container: $("#pager")
+		});
+});
+

Demo

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameMajorSexEnglishJapaneseCalculusGeometry
NameMajorSexEnglishJapaneseCalculusGeometry
Student01Languagesmale80707580
Student02Mathematicsmale908810090
Student03Languagesfemale85958085
Student04Languagesmale6055100100
Student05Languagesfemale68809580
Student06Mathematicsmale1009910090
Student07Mathematicsmale85689090
Student08Languagesmale100909085
Student09Mathematicsmale80506575
Student10Languagesmale8510010090
Student11Languagesmale8685100100
Student12Mathematicsfemale100757085
Student13Languagesfemale1008010090
Student14Languagesfemale50455590
Student15Languagesmale953510090
Student16Languagesfemale100503070
Student17Languagesfemale801005565
Student18Mathematicsmale30495575
Student19Languagesmale68908870
Student20Mathematicsmale40454080
Student21Languagesmale5045100100
Student22Mathematicsmale1009910090
Student23Languagesfemale85808080
student23Mathematicsmale8277079
student24Languagesfemale100911382
student25Mathematicsmale22968253
student26Languagesfemale37295659
student27Mathematicsmale86826923
student28Languagesfemale4425431
student29Mathematicsmale77472238
student30Languagesfemale19352310
student31Mathematicsmale90271750
student32Languagesfemale60753338
student33Mathematicsmale4313715
student34Languagesfemale77978144
student35Mathematicsmale5815195
student36Languagesfemale70617094
student37Mathematicsmale6036184
student38Languagesfemale6339011
student39Mathematicsmale50463238
student40Languagesfemale5175253
student41Mathematicsmale43342878
student42Languagesfemale11896095
student43Mathematicsmale48921888
student44Languagesfemale8225973
student45Mathematicsmale91733739
student46Languagesfemale481210
student47Mathematicsmale8910611
student48Languagesfemale90322118
student49Mathematicsmale42494972
student50Languagesfemale56376754
student51Mathematicsmale48315563
student52Languagesfemale38917174
student53Mathematicsmale26385100
student54Languagesfemale75811623
student55Mathematicsmale65521553
student56Languagesfemale23527994
student57Mathematicsmale80226112
student58Languagesfemale5357979
student59Mathematicsmale96323517
student60Languagesfemale16766527
student61Mathematicsmale20572223
student62Languagesfemale19838778
student63Mathematicsmale258330
student64Languagesfemale021993
student65Mathematicsmale20861396
student66Languagesfemale28358757
student67Mathematicsmale36502910
student68Languagesfemale6090966
student69Mathematicsmale34614398
student70Languagesfemale13379183
student71Mathematicsmale47805782
student72Languagesfemale69433737
student73Mathematicsmale54609421
student74Languagesfemale71143446
student75Mathematicsmale89963117
student76Languagesfemale28482994
student77Mathematicsmale100652024
student78Languagesfemale11969033
student79Mathematicsmale53559339
student80Languagesfemale11008444
student81Mathematicsmale63789643
student82Languagesfemale41698235
student83Mathematicsmale9498139
student84Languagesfemale94729177
student85Mathematicsmale71324525
student86Languagesfemale9896437
student87Mathematicsmale8917367
student88Languagesfemale43416879
student89Mathematicsmale7382237
student90Languagesfemale94839337
student91Mathematicsmale8284261
student92Languagesfemale46413069
student93Mathematicsmale47198583
student94Languagesfemale39146462
student95Mathematicsmale71314628
student96Languagesfemale90944540
student97Mathematicsmale468925
student98Languagesfemale41434799
student99Mathematicsmale71908973
student100Languagesfemale31641856
student101Mathematicsmale52136999
student102Languagesfemale86398318
student103Mathematicsmale23659880
student104Languagesfemale781005766
student105Mathematicsmale69214397
student106Languagesfemale2727838
student107Mathematicsmale86964634
student108Languagesfemale13846664
student109Mathematicsmale35959881
student110Languagesfemale30286254
student111Mathematicsmale60313585
student112Languagesfemale19811969
student113Mathematicsmale6659854
student114Languagesfemale38804016
student115Mathematicsmale5849697
student116Languagesfemale59976954
student117Mathematicsmale0347949
student118Languagesfemale1871285
student119Mathematicsmale9387759
student120Languagesfemale42232690
student121Mathematicsmale17396689
student122Languagesfemale26759018
student123Mathematicsmale34237780
student124Languagesfemale5267742
student125Mathematicsmale5628581
student126Languagesfemale51356744
student127Mathematicsmale64644434
student128Languagesfemale67917982
student129Mathematicsmale4261579
student130Languagesfemale7210369
student131Mathematicsmale9477511
student132Languagesfemale27958548
student133Mathematicsmale92114061
student134Languagesfemale4185660
student135Mathematicsmale8422652
student136Languagesfemale7604721
student137Mathematicsmale51813090
student138Languagesfemale5861673
student139Mathematicsmale48383731
student140Languagesfemale33265660
student141Mathematicsmale84842975
student142Languagesfemale7235654
student143Mathematicsmale31427082
student144Languagesfemale94875035
student145Mathematicsmale91528026
student146Languagesfemale78657979
student147Mathematicsmale50905971
student148Languagesfemale15686633
student149Mathematicsmale17363413
student150Languagesfemale30956973
student151Mathematicsmale20534958
student152Languagesfemale19896060
student153Mathematicsmale5282203
student154Languagesfemale66985366
student155Mathematicsmale5852258
student156Languagesfemale3443688
student157Mathematicsmale4309114
student158Languagesfemale34186731
student159Mathematicsmale79733452
student160Languagesfemale15613727
student161Mathematicsmale74771545
student162Languagesfemale52621958
student163Mathematicsmale77602795
student164Languagesfemale9619357
student165Mathematicsmale51637519
student166Languagesfemale32447299
student167Mathematicsmale82845763
student168Languagesfemale53128567
student169Mathematicsmale4916846
student170Languagesfemale39341665
student171Mathematicsmale10068884
student172Languagesfemale14256352
student173Mathematicsmale74261560
student174Languagesfemale1158892
student175Mathematicsmale6247231
student176Languagesfemale65263242
student177Mathematicsmale83786924
student178Languagesfemale14100743
student179Mathematicsmale2835897
student180Languagesfemale1483962
student181Mathematicsmale1442469
student182Languagesfemale6452722
student183Mathematicsmale15262785
student184Languagesfemale9149407
student185Mathematicsmale87894287
student186Languagesfemale75766188
student187Mathematicsmale11486630
student188Languagesfemale7379272
student189Mathematicsmale98365815
student190Languagesfemale8028656
student191Mathematicsmale3633974
student192Languagesfemale5923390
student193Mathematicsmale9461933
student194Languagesfemale82497242
student195Mathematicsmale8059830
student196Languagesfemale89179027
student197Mathematicsmale4622667
student198Languagesfemale65757377
student199Mathematicsmale77975413
student200Languagesfemale78195796
student201Mathematicsmale92211180
student202Languagesfemale45499340
student203Mathematicsmale74258753
student204Languagesfemale1571234
student205Mathematicsmale82979573
student206Languagesfemale82605898
student207Mathematicsmale266411100
student208Languagesfemale6496045
student209Mathematicsmale96819663
student210Languagesfemale2439069
student211Mathematicsmale8664710
student212Languagesfemale764507
student213Mathematicsmale59122677
student214Languagesfemale21259382
student215Mathematicsmale22186451
student216Languagesfemale92419828
student217Mathematicsmale32481417
student218Languagesfemale62368556
student219Mathematicsmale33379087
student220Languagesfemale24436084
student221Mathematicsmale6593751
student222Languagesfemale9197576
student223Mathematicsmale86293227
student224Languagesfemale63596891
student225Mathematicsmale57739568
student226Languagesfemale38545987
student227Mathematicsmale53627264
student228Languagesfemale62847273
student229Mathematicsmale1308358
student230Languagesfemale35658087
student231Mathematicsmale76202850
student232Languagesfemale9176633
student233Mathematicsmale9229961
student234Languagesfemale47699839
student235Mathematicsmale21443882
student236Languagesfemale19865178
student237Mathematicsmale28454936
student238Languagesfemale78194981
student239Mathematicsmale72694720
student240Languagesfemale17436656
student241Mathematicsmale901944
student242Languagesfemale618251
student243Mathematicsmale1377213
student244Languagesfemale8005854
student245Mathematicsmale8331859
student246Languagesfemale90992912
student247Mathematicsmale89238159
student248Languagesfemale7226283
student249Mathematicsmale28105047
student250Languagesfemale8914894
student251Mathematicsmale15233769
student252Languagesfemale27821036
student253Mathematicsmale49456423
student254Languagesfemale79756374
student255Mathematicsmale2566475
student256Languagesfemale36262958
student257Mathematicsmale17226673
student258Languagesfemale70919745
student259Mathematicsmale34307830
student260Languagesfemale77578677
student261Mathematicsmale1259687
student262Languagesfemale11609771
student263Mathematicsmale12303558
student264Languagesfemale46152340
student265Mathematicsmale4481926
student266Languagesfemale15683215
student267Mathematicsmale5585098
student268Languagesfemale42303224
student269Mathematicsmale781009957
student270Languagesfemale55338725
student271Mathematicsmale25972993
student272Languagesfemale39351843
student273Mathematicsmale35179958
student274Languagesfemale86522724
student275Mathematicsmale97387376
student276Languagesfemale206198
student277Mathematicsmale9336947
student278Languagesfemale423152
student279Mathematicsmale6118962
student280Languagesfemale99898794
student281Mathematicsmale4895900
student282Languagesfemale60473130
student283Mathematicsmale64241076
student284Languagesfemale9937468
student285Mathematicsmale0986869
student286Languagesfemale66824959
student287Mathematicsmale86143717
student288Languagesfemale27489327
student289Mathematicsmale8489668
student290Languagesfemale9902057
student291Mathematicsmale50967242
student292Languagesfemale9822792
student293Mathematicsmale1994287
student294Languagesfemale9897922
student295Mathematicsmale75307764
student296Languagesfemale5198553
student297Mathematicsmale25958672
student298Languagesfemale20753735
student299Mathematicsmale4924111
student300Languagesfemale2832891
student301Mathematicsmale4163425
student302Languagesfemale29167790
student303Mathematicsmale89415182
student304Languagesfemale40912434
student305Mathematicsmale7474978
student306Languagesfemale6375562
student307Mathematicsmale30733490
student308Languagesfemale82919593
student309Mathematicsmale6247382
student310Languagesfemale39101257
student311Mathematicsmale89642067
student312Languagesfemale56369241
student313Mathematicsmale99809974
student314Languagesfemale31796493
student315Mathematicsmale5327055
student316Languagesfemale35152960
student317Mathematicsmale31476960
student318Languagesfemale88281366
student319Mathematicsmale65121640
student320Languagesfemale28171940
student321Mathematicsmale241004470
student322Languagesfemale20598352
student323Mathematicsmale17608291
student324Languagesfemale95994337
student325Mathematicsmale30189931
student326Languagesfemale3478386
student327Mathematicsmale9863435
student328Languagesfemale54239846
student329Mathematicsmale97934518
student330Languagesfemale2774077
student331Mathematicsmale9704137
student332Languagesfemale52377620
student333Mathematicsmale74186819
student334Languagesfemale77100339
student335Mathematicsmale38537718
student336Languagesfemale18132610
student337Mathematicsmale90478770
student338Languagesfemale38493674
student339Mathematicsmale100641372
student340Languagesfemale74254152
student341Mathematicsmale37131613
student342Languagesfemale24341583
student343Mathematicsmale2056728
student344Languagesfemale4522572
student345Mathematicsmale19117535
student346Languagesfemale6583115
student347Mathematicsmale16663611
student348Languagesfemale1239540
student349Mathematicsmale752742
student350Languagesfemale88926055
student351Mathematicsmale92709145
student352Languagesfemale74765944
student353Mathematicsmale63696094
student354Languagesfemale3685548
student355Mathematicsmale39962148
student356Languagesfemale4134275
student357Mathematicsmale6434733
student358Languagesfemale95146355
student359Mathematicsmale701001382
student360Languagesfemale522410021
student361Mathematicsmale040869
student362Languagesfemale024932
student363Mathematicsmale23108694
student364Languagesfemale1538649
student365Mathematicsmale7623310
student366Languagesfemale35357894
student367Mathematicsmale294243100
student368Languagesfemale668510
student369Mathematicsmale74155683
student370Languagesfemale7543908
student371Mathematicsmale4060470
student372Languagesfemale62421749
student373Mathematicsmale31464454
student374Languagesfemale30344787
student375Mathematicsmale9694152
student376Languagesfemale85432992
student377Mathematicsmale7904025
student378Languagesfemale36407285
student379Mathematicsmale5368882
student380Languagesfemale87783879
student381Mathematicsmale89978338
student382Languagesfemale21194910
student383Mathematicsmale47126850
student384Languagesfemale37124995
student385Mathematicsmale8408851
student386Languagesfemale89612748
student387Mathematicsmale10478761
student388Languagesfemale1692656
student389Mathematicsmale57331347
student390Languagesfemale90357775
student391Mathematicsmale31474753
student392Languagesfemale942412
student393Mathematicsmale6119817
student394Languagesfemale457577
student395Mathematicsmale6729212
student396Languagesfemale516456
student397Mathematicsmale93147714
student398Languagesfemale1893427
student399Mathematicsmale93775791
student400Languagesfemale67778032
student401Mathematicsmale5889417
student402Languagesfemale3056053
student403Mathematicsmale28253259
student404Languagesfemale62348164
student405Mathematicsmale29842623
student406Languagesfemale7086377
student407Mathematicsmale8654799
student408Languagesfemale9381089
student409Mathematicsmale84214658
student410Languagesfemale21841849
student411Mathematicsmale2796340
student412Languagesfemale9301991
student413Mathematicsmale31928743
student414Languagesfemale53259843
student415Mathematicsmale36758089
student416Languagesfemale37681254
student417Mathematicsmale25891253
student418Languagesfemale922846
student419Mathematicsmale11286058
student420Languagesfemale1373517
student421Mathematicsmale67303885
student422Languagesfemale68793441
student423Mathematicsmale72459341
student424Languagesfemale56464538
student425Mathematicsmale8621840
student426Languagesfemale99854119
student427Mathematicsmale7135389
student428Languagesfemale22911216
student429Mathematicsmale1532693
student430Languagesfemale35463474
student431Mathematicsmale33839720
student432Languagesfemale9920326
student433Mathematicsmale48428318
student434Languagesfemale4442530
student435Mathematicsmale78486045
student436Languagesfemale4757890
student437Mathematicsmale881210053
student438Languagesfemale4805160
student439Mathematicsmale70898516
student440Languagesfemale71943433
student441Mathematicsmale68137218
student442Languagesfemale7539721
student443Mathematicsmale65366087
student444Languagesfemale43212434
student445Mathematicsmale85776528
student446Languagesfemale61907891
student447Mathematicsmale9207812
student448Languagesfemale33306290
student449Mathematicsmale8616745
student450Languagesfemale100862423
student451Mathematicsmale1425645
student452Languagesfemale86399888
student453Mathematicsmale72687719
student454Languagesfemale94523100
student455Mathematicsmale34678979
student456Languagesfemale9204745
student457Mathematicsmale64582698
student458Languagesfemale439359100
student459Mathematicsmale82359781
student460Languagesfemale183524100
student461Mathematicsmale79804351
student462Languagesfemale56101767
student463Mathematicsmale36441485
student464Languagesfemale2640692
student465Mathematicsmale59934378
student466Languagesfemale7884883
student467Mathematicsmale41378060
student468Languagesfemale44279777
student469Mathematicsmale29196482
student470Languagesfemale50962746
student471Mathematicsmale49155145
student472Languagesfemale38353178
student473Mathematicsmale1802365
student474Languagesfemale91172376
student475Mathematicsmale57393563
student476Languagesfemale33736214
student477Mathematicsmale96168840
student478Languagesfemale30631613
student479Mathematicsmale74393787
student480Languagesfemale26369479
student481Mathematicsmale19586512
student482Languagesfemale73362248
student483Mathematicsmale7894757
student484Languagesfemale5951935
student485Mathematicsmale677110085
student486Languagesfemale33301546
student487Mathematicsmale12191637
student488Languagesfemale80982914
student489Mathematicsmale70511431
student490Languagesfemale95381592
student491Mathematicsmale60317412
student492Languagesfemale62569068
student493Mathematicsmale63112991
student494Languagesfemale4112520
student495Mathematicsmale6053144
student496Languagesfemale1135528
student497Mathematicsmale11964237
student498Languagesfemale16727974
student499Mathematicsmale9212266
student500Languagesfemale34226434
student501Mathematicsmale50938661
student502Languagesfemale50224044
student503Mathematicsmale383917
student504Languagesfemale98169355
student505Mathematicsmale86893628
student506Languagesfemale16531350
student507Mathematicsmale5757338
student508Languagesfemale34796977
student509Mathematicsmale241659
student510Languagesfemale606299100
student511Mathematicsmale65525295
student512Languagesfemale5873941
student513Mathematicsmale39752876
student514Languagesfemale4666478
student515Mathematicsmale5160998
student516Languagesfemale17201297
student517Mathematicsmale72179673
student518Languagesfemale92216227
student519Mathematicsmale5042433
student520Languagesfemale5237157
student521Mathematicsmale58403554
student522Languagesfemale9385753
student523Mathematicsmale79201818
student524Languagesfemale149427
student525Mathematicsmale95412998
student526Languagesfemale3459921
student527Mathematicsmale39664129
student528Languagesfemale328125
student529Mathematicsmale33443785
student530Languagesfemale69255979
student531Mathematicsmale13504952
student532Languagesfemale54834531
student533Mathematicsmale15249751
student534Languagesfemale7516963
student535Mathematicsmale9183856
student536Languagesfemale50137480
student537Mathematicsmale54757410
student538Languagesfemale76397046
student539Mathematicsmale84723940
student540Languagesfemale10047214
student541Mathematicsmale426111
student542Languagesfemale57716561
student543Mathematicsmale7854134
student544Languagesfemale14763647
student545Mathematicsmale15196396
student546Languagesfemale27823356
student547Mathematicsmale70239690
student548Languagesfemale612278
student549Mathematicsmale22376436
student550Languagesfemale75969440
student551Mathematicsmale4382921
student552Languagesfemale7968718
student553Mathematicsmale65765244
student554Languagesfemale41627354
student555Mathematicsmale25982140
student556Languagesfemale17709682
student557Mathematicsmale43912743
student558Languagesfemale33372433
student559Mathematicsmale87871031
student560Languagesfemale48409774
student561Mathematicsmale63759155
student562Languagesfemale66825995
student563Mathematicsmale21955838
student564Languagesfemale9299745
student565Mathematicsmale5979420
student566Languagesfemale64952412
student567Mathematicsmale70463674
student568Languagesfemale16259149
student569Mathematicsmale73332488
student570Languagesfemale9619527
student571Mathematicsmale18127646
student572Languagesfemale61714963
student573Mathematicsmale46328517
student574Languagesfemale42421137
student575Mathematicsmale49764120
student576Languagesfemale22278012
student577Mathematicsmale76341866
student578Languagesfemale96772917
student579Mathematicsmale62516772
student580Languagesfemale96672254
student581Mathematicsmale77112388
student582Languagesfemale6282433
student583Mathematicsmale392312100
student584Languagesfemale10212071
student585Mathematicsmale11277100
student586Languagesfemale40349778
student587Mathematicsmale2518319
student588Languagesfemale18763025
student589Mathematicsmale24574681
student590Languagesfemale2103194
student591Mathematicsmale91847513
student592Languagesfemale79449710
student593Mathematicsmale42606730
student594Languagesfemale61577535
student595Mathematicsmale42468171
student596Languagesfemale92637574
student597Mathematicsmale86374051
student598Languagesfemale5210473
student599Mathematicsmale100281476
student600Languagesfemale31762043
student601Mathematicsmale402766
student602Languagesfemale587921
student603Mathematicsmale754691
student604Languagesfemale2830153
student605Mathematicsmale38939892
student606Languagesfemale43968991
student607Mathematicsmale43491483
student608Languagesfemale50617298
student609Mathematicsmale4499983
student610Languagesfemale5367382
student611Mathematicsmale40849954
student612Languagesfemale29966569
student613Mathematicsmale1276599
student614Languagesfemale4783494
student615Mathematicsmale3727224
student616Languagesfemale94394924
student617Mathematicsmale0752141
student618Languagesfemale5936418
student619Mathematicsmale2266133
student620Languagesfemale4387448
student621Mathematicsmale100155152
student622Languagesfemale63719917
student623Mathematicsmale143444100
student624Languagesfemale2385727
student625Mathematicsmale23143240
student626Languagesfemale34497254
student627Mathematicsmale21168126
student628Languagesfemale54693434
student629Mathematicsmale72116331
student630Languagesfemale8798947
student631Mathematicsmale43525358
student632Languagesfemale5014420
student633Mathematicsmale89836787
student634Languagesfemale079916
student635Mathematicsmale59178458
student636Languagesfemale94953660
student637Mathematicsmale39426346
student638Languagesfemale019610
student639Mathematicsmale50164171
student640Languagesfemale8604613
student641Mathematicsmale45855936
student642Languagesfemale8335057
student643Mathematicsmale8306014
student644Languagesfemale76807338
student645Mathematicsmale2614582
student646Languagesfemale9316422
student647Mathematicsmale85947616
student648Languagesfemale57453216
student649Mathematicsmale16169013
student650Languagesfemale4331887
student651Mathematicsmale16243244
student652Languagesfemale5998334
student653Mathematicsmale73184783
student654Languagesfemale992510093
student655Mathematicsmale0739784
student656Languagesfemale0289475
student657Mathematicsmale65905863
student658Languagesfemale84358641
student659Mathematicsmale4539599
student660Languagesfemale32103162
student661Mathematicsmale61285461
student662Languagesfemale70961454
student663Mathematicsmale6392298
student664Languagesfemale41104623
student665Mathematicsmale81918021
student666Languagesfemale79716568
student667Mathematicsmale47691890
student668Languagesfemale2616700
student669Mathematicsmale66109335
student670Languagesfemale66682713
student671Mathematicsmale86792645
student672Languagesfemale50532574
student673Mathematicsmale9753914
student674Languagesfemale28796942
student675Mathematicsmale607259
student676Languagesfemale53213943
student677Mathematicsmale37654591
student678Languagesfemale76806027
student679Mathematicsmale85273455
student680Languagesfemale66114117
student681Mathematicsmale27618982
student682Languagesfemale402613
student683Mathematicsmale2516695
student684Languagesfemale63448563
student685Mathematicsmale97957883
student686Languagesfemale5121387
student687Mathematicsmale63928723
student688Languagesfemale22965959
student689Mathematicsmale33801523
student690Languagesfemale34751924
student691Mathematicsmale36684854
student692Languagesfemale32362012
student693Mathematicsmale68917450
student694Languagesfemale87919637
student695Mathematicsmale239144
student696Languagesfemale9462977
student697Mathematicsmale1474575
student698Languagesfemale73921990
student699Mathematicsmale8207978
student700Languagesfemale763510039
student701Mathematicsmale27518949
student702Languagesfemale0647237
student703Mathematicsmale93469487
student704Languagesfemale6922172
student705Mathematicsmale1752113
student706Languagesfemale1325219
student707Mathematicsmale75617273
student708Languagesfemale8437736
student709Mathematicsmale81194514
student710Languagesfemale62173927
student711Mathematicsmale8869681
student712Languagesfemale53825929
student713Mathematicsmale83347134
student714Languagesfemale9552614
student715Mathematicsmale6715313
student716Languagesfemale8297825
student717Mathematicsmale65503146
student718Languagesfemale27462537
student719Mathematicsmale98423544
student720Languagesfemale9014444
student721Mathematicsmale3168293
student722Languagesfemale3434370
student723Mathematicsmale59771421
student724Languagesfemale16535759
student725Mathematicsmale7914416
student726Languagesfemale108199
student727Mathematicsmale89487916
student728Languagesfemale8872387
student729Mathematicsmale17539584
student730Languagesfemale65523961
student731Mathematicsmale44309672
student732Languagesfemale70793233
student733Mathematicsmale30474611
student734Languagesfemale761001649
student735Mathematicsmale39369089
student736Languagesfemale1941929
student737Mathematicsmale23737887
student738Languagesfemale87714464
student739Mathematicsmale22198220
student740Languagesfemale94526739
student741Mathematicsmale14175187
student742Languagesfemale5663983
student743Mathematicsmale99924698
student744Languagesfemale19768388
student745Mathematicsmale15776881
student746Languagesfemale48814838
student747Mathematicsmale2913861
student748Languagesfemale7163030
student749Mathematicsmale19683053
student750Languagesfemale91182762
student751Mathematicsmale73333836
student752Languagesfemale99387550
student753Mathematicsmale55713490
student754Languagesfemale52409883
student755Mathematicsmale1463611
student756Languagesfemale1319496
student757Mathematicsmale49665592
student758Languagesfemale0198082
student759Mathematicsmale2635873
student760Languagesfemale8287639
student761Mathematicsmale52118357
student762Languagesfemale83688425
student763Mathematicsmale1725670
student764Languagesfemale1758084
student765Mathematicsmale7564785
student766Languagesfemale76329339
student767Mathematicsmale20758465
student768Languagesfemale25471289
student769Mathematicsmale86947945
student770Languagesfemale65815535
student771Mathematicsmale62414143
student772Languagesfemale1446243
student773Mathematicsmale17557278
student774Languagesfemale9546356
student775Mathematicsmale7205648
student776Languagesfemale30881956
student777Mathematicsmale42448856
student778Languagesfemale42695663
student779Mathematicsmale7857783
student780Languagesfemale15862498
student781Mathematicsmale4684369
student782Languagesfemale67981552
student783Mathematicsmale33326357
student784Languagesfemale35951653
student785Mathematicsmale78545482
student786Languagesfemale8185914
student787Mathematicsmale42412314
student788Languagesfemale591008636
student789Mathematicsmale1926012
student790Languagesfemale10034570
student791Mathematicsmale381217
student792Languagesfemale3155193
student793Mathematicsmale11339877
student794Languagesfemale461786
student795Mathematicsmale5786727
student796Languagesfemale5746236
student797Mathematicsmale57676661
student798Languagesfemale93888725
student799Mathematicsmale59966441
student800Languagesfemale6276923
student801Mathematicsmale35833255
student802Languagesfemale42581583
student803Mathematicsmale41904012
student804Languagesfemale8143837
student805Mathematicsmale87773320
student806Languagesfemale53873037
student807Mathematicsmale13358516
student808Languagesfemale20829034
student809Mathematicsmale5821614
student810Languagesfemale14282356
student811Mathematicsmale4997368
student812Languagesfemale31461163
student813Mathematicsmale7497643
student814Languagesfemale42839575
student815Mathematicsmale2654529
student816Languagesfemale79596988
student817Mathematicsmale68182684
student818Languagesfemale39139915
student819Mathematicsmale2248716
student820Languagesfemale12538811
student821Mathematicsmale33908029
student822Languagesfemale3795486
student823Mathematicsmale9178851
student824Languagesfemale31586731
student825Mathematicsmale22305098
student826Languagesfemale55585610
student827Mathematicsmale56765753
student828Languagesfemale1129881
student829Mathematicsmale67926671
student830Languagesfemale30614449
student831Mathematicsmale0414461
student832Languagesfemale72524585
student833Mathematicsmale60991294
student834Languagesfemale83587542
student835Mathematicsmale9505377
student836Languagesfemale33287062
student837Mathematicsmale3982755
student838Languagesfemale411004547
student839Mathematicsmale81692729
student840Languagesfemale9012649
student841Mathematicsmale45382034
student842Languagesfemale325311
student843Mathematicsmale55778649
student844Languagesfemale61609176
student845Mathematicsmale8085749
student846Languagesfemale63897371
student847Mathematicsmale79159742
student848Languagesfemale99187343
student849Mathematicsmale30523856
student850Languagesfemale65866734
student851Mathematicsmale7343655
student852Languagesfemale42435173
student853Mathematicsmale870980
student854Languagesfemale29411245
student855Mathematicsmale5739090
student856Languagesfemale80529654
student857Mathematicsmale43838246
student858Languagesfemale7917131
student859Mathematicsmale6813707
student860Languagesfemale51441552
student861Mathematicsmale9170178
student862Languagesfemale4116578
student863Mathematicsmale20635585
student864Languagesfemale5938726
student865Mathematicsmale4894432
student866Languagesfemale26679839
student867Mathematicsmale48793866
student868Languagesfemale1632153
student869Mathematicsmale13205085
student870Languagesfemale4922039
student871Mathematicsmale8262353
student872Languagesfemale6607464
student873Mathematicsmale66483914
student874Languagesfemale43833100
student875Mathematicsmale214990
student876Languagesfemale79807180
student877Mathematicsmale84252688
student878Languagesfemale38466660
student879Mathematicsmale35279851
student880Languagesfemale5759267
student881Mathematicsmale7687788
student882Languagesfemale2140817
student883Mathematicsmale5046866
student884Languagesfemale83863092
student885Mathematicsmale63466694
student886Languagesfemale7671262
student887Mathematicsmale7418686
student888Languagesfemale65774488
student889Mathematicsmale67326119
student890Languagesfemale85968541
student891Mathematicsmale1487705
student892Languagesfemale81284528
student893Mathematicsmale9191883
student894Languagesfemale407024
student895Mathematicsmale18195189
student896Languagesfemale70352512
student897Mathematicsmale7290741
student898Languagesfemale8417186
student899Mathematicsmale1423886
student900Languagesfemale7837601
student901Mathematicsmale66953168
student902Languagesfemale23608065
student903Mathematicsmale76896396
student904Languagesfemale3469070
student905Mathematicsmale65449679
student906Languagesfemale6877865
student907Mathematicsmale86619943
student908Languagesfemale88953213
student909Mathematicsmale531005982
student910Languagesfemale3579535
student911Mathematicsmale230177
student912Languagesfemale9687263
student913Mathematicsmale23923996
student914Languagesfemale9497658
student915Mathematicsmale49312971
student916Languagesfemale21577957
student917Mathematicsmale03510089
student918Languagesfemale64827552
student919Mathematicsmale16666968
student920Languagesfemale92951127
student921Mathematicsmale16888590
student922Languagesfemale56152698
student923Mathematicsmale78274017
student924Languagesfemale95104432
student925Mathematicsmale99855218
student926Languagesfemale73317149
student927Mathematicsmale21791063
student928Languagesfemale92718012
student929Mathematicsmale23293388
student930Languagesfemale4189884
student931Mathematicsmale97177921
student932Languagesfemale72409392
student933Mathematicsmale7558326
student934Languagesfemale15982728
student935Mathematicsmale7688806
student936Languagesfemale84234292
student937Mathematicsmale71568671
student938Languagesfemale7395822
student939Mathematicsmale1555460
student940Languagesfemale2031308
student941Mathematicsmale97544181
student942Languagesfemale83418664
student943Mathematicsmale7195327
student944Languagesfemale0273091
student945Mathematicsmale99751722
student946Languagesfemale92531090
student947Mathematicsmale4449432
student948Languagesfemale0974879
student949Mathematicsmale97557974
student950Languagesfemale6598932
student951Mathematicsmale56733881
student952Languagesfemale84946150
student953Mathematicsmale4820770
student954Languagesfemale39981420
student955Mathematicsmale4152465
student956Languagesfemale78229231
student957Mathematicsmale28382654
student958Languagesfemale49613554
student959Mathematicsmale81152817
student960Languagesfemale5480582
student961Mathematicsmale7523537
student962Languagesfemale5565120
student963Mathematicsmale86427036
student964Languagesfemale54455480
student965Mathematicsmale38186992
student966Languagesfemale33894683
student967Mathematicsmale4395576
student968Languagesfemale13261286
student969Mathematicsmale94228559
student970Languagesfemale9358610
student971Mathematicsmale35728536
student972Languagesfemale37519693
student973Mathematicsmale71107959
student974Languagesfemale71317393
student975Mathematicsmale80268697
student976Languagesfemale69216769
student977Mathematicsmale38861039
student978Languagesfemale48903981
student979Mathematicsmale9083342
student980Languagesfemale1919184
student981Mathematicsmale98255046
student982Languagesfemale38882116
student983Mathematicsmale71481843
student984Languagesfemale79851816
student985Mathematicsmale51669068
student986Languagesfemale100956591
student987Mathematicsmale6742424
student988Languagesfemale93809435
student989Mathematicsmale65785794
student990Languagesfemale27922191
student991Mathematicsmale77152676
student992Languagesfemale28845167
student993Mathematicsmale3786250
student994Languagesfemale59772074
student995Mathematicsmale6266875
student996Languagesfemale88703343
student997Mathematicsmale73334253
student998Languagesfemale6410231
student999Mathematicsmale91931635
student1000Languagesfemale30689540
student1001Mathematicsmale2524832
student1002Languagesfemale50775381
student1003Mathematicsmale67441065
student1004Languagesfemale29533486
student1005Mathematicsmale77692275
student1006Languagesfemale48829540
student1007Mathematicsmale30712963
student1008Languagesfemale4531471
student1009Mathematicsmale81122044
student1010Languagesfemale17668242
student1011Mathematicsmale15113218
student1012Languagesfemale27345919
student1013Mathematicsmale18672514
student1014Languagesfemale24645224
student1015Mathematicsmale36874846
student1016Languagesfemale3317068
student1017Mathematicsmale4826380
student1018Languagesfemale53638557
student1019Mathematicsmale5873024
student1020Languagesfemale8590810
student1021Mathematicsmale69285276
student1022Languagesfemale7522752
+
+
+ + + + + + +
+
+ +
+ + + + diff --git a/docs/example-parsers.html b/docs/example-parsers.html new file mode 100644 index 00000000..e89b1676 --- /dev/null +++ b/docs/example-parsers.html @@ -0,0 +1,112 @@ + + + + jQuery plugin: Tablesorter 2.0 - Writing custom parsers + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameMajorGenderEnglishJapaneseCalculusOverall grades
Student01Languagesmale807075bad
Student02Mathematicsmale9088100good
Student03Languagesfemale859580medium
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + + diff --git a/docs/example-trigger-sort.html b/docs/example-trigger-sort.html new file mode 100644 index 00000000..bc582257 --- /dev/null +++ b/docs/example-trigger-sort.html @@ -0,0 +1,111 @@ + + + + jQuery plugin: Tablesorter 2.0 - Sort table using a link outside the table + + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+ Sort first and third columns +
+
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + diff --git a/docs/example-triggers.html b/docs/example-triggers.html new file mode 100644 index 00000000..c39f2c36 --- /dev/null +++ b/docs/example-triggers.html @@ -0,0 +1,1097 @@ + + + + jQuery plugin: Tablesorter 2.0 - Triggers sortStart and sortEnd + + + + + + + + + + + + + + + + + + +
+

Demo

+
+
    +
  • ...
  • +
  • ...
  • +
  • ...
  • +
+ +

Javascript

+
+

+	
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameMajorSexEnglishJapaneseCalculusGeometry
NameMajorSexEnglishJapaneseCalculusGeometry
Student01Languagesmale80707580
Student02Mathematicsmale908810090
Student03Languagesfemale85958085
Student04Languagesmale6055100100
Student05Languagesfemale68809580
Student06Mathematicsmale1009910090
Student07Mathematicsmale85689090
Student08Languagesmale100909085
Student09Mathematicsmale80506575
Student10Languagesmale8510010090
Student11Languagesmale8685100100
Student12Mathematicsfemale100757085
Student13Languagesfemale1008010090
Student14Languagesfemale50455590
Student15Languagesmale953510090
Student16Languagesfemale100503070
Student17Languagesfemale801005565
Student18Mathematicsmale30495575
Student19Languagesmale68908870
Student20Mathematicsmale40454080
Student21Languagesmale5045100100
Student22Mathematicsmale1009910090
Student23Languagesfemale85808080
student23Mathematicsmale8277079
student24Languagesfemale100911382
student25Mathematicsmale22968253
student26Languagesfemale37295659
student27Mathematicsmale86826923
student28Languagesfemale4425431
student29Mathematicsmale77472238
student30Languagesfemale19352310
student31Mathematicsmale90271750
student32Languagesfemale60753338
student33Mathematicsmale4313715
student34Languagesfemale77978144
student35Mathematicsmale5815195
student36Languagesfemale70617094
student37Mathematicsmale6036184
student38Languagesfemale6339011
student39Mathematicsmale50463238
student40Languagesfemale5175253
student41Mathematicsmale43342878
student42Languagesfemale11896095
student43Mathematicsmale48921888
student44Languagesfemale8225973
student45Mathematicsmale91733739
student46Languagesfemale481210
student47Mathematicsmale8910611
student48Languagesfemale90322118
student49Mathematicsmale42494972
student50Languagesfemale56376754
student51Mathematicsmale48315563
student52Languagesfemale38917174
student53Mathematicsmale26385100
student54Languagesfemale75811623
student55Mathematicsmale65521553
student56Languagesfemale23527994
student57Mathematicsmale80226112
student58Languagesfemale5357979
student59Mathematicsmale96323517
student60Languagesfemale16766527
student61Mathematicsmale20572223
student62Languagesfemale19838778
student63Mathematicsmale258330
student64Languagesfemale021993
student65Mathematicsmale20861396
student66Languagesfemale28358757
student67Mathematicsmale36502910
student68Languagesfemale6090966
student69Mathematicsmale34614398
student70Languagesfemale13379183
student71Mathematicsmale47805782
student72Languagesfemale69433737
student73Mathematicsmale54609421
student74Languagesfemale71143446
student75Mathematicsmale89963117
student76Languagesfemale28482994
student77Mathematicsmale100652024
student78Languagesfemale11969033
student79Mathematicsmale53559339
student80Languagesfemale11008444
student81Mathematicsmale63789643
student82Languagesfemale41698235
student83Mathematicsmale9498139
student84Languagesfemale94729177
student85Mathematicsmale71324525
student86Languagesfemale9896437
student87Mathematicsmale8917367
student88Languagesfemale43416879
student89Mathematicsmale7382237
student90Languagesfemale94839337
student91Mathematicsmale8284261
student92Languagesfemale46413069
student93Mathematicsmale47198583
student94Languagesfemale39146462
student95Mathematicsmale71314628
student96Languagesfemale90944540
student97Mathematicsmale468925
student98Languagesfemale41434799
student99Mathematicsmale71908973
student100Languagesfemale31641856
student101Mathematicsmale52136999
student102Languagesfemale86398318
student103Mathematicsmale23659880
student104Languagesfemale781005766
student105Mathematicsmale69214397
student106Languagesfemale2727838
student107Mathematicsmale86964634
student108Languagesfemale13846664
student109Mathematicsmale35959881
student110Languagesfemale30286254
student111Mathematicsmale60313585
student112Languagesfemale19811969
student113Mathematicsmale6659854
student114Languagesfemale38804016
student115Mathematicsmale5849697
student116Languagesfemale59976954
student117Mathematicsmale0347949
student118Languagesfemale1871285
student119Mathematicsmale9387759
student120Languagesfemale42232690
student121Mathematicsmale17396689
student122Languagesfemale26759018
student123Mathematicsmale34237780
student124Languagesfemale5267742
student125Mathematicsmale5628581
student126Languagesfemale51356744
student127Mathematicsmale64644434
student128Languagesfemale67917982
student129Mathematicsmale4261579
student130Languagesfemale7210369
student131Mathematicsmale9477511
student132Languagesfemale27958548
student133Mathematicsmale92114061
student134Languagesfemale4185660
student135Mathematicsmale8422652
student136Languagesfemale7604721
student137Mathematicsmale51813090
student138Languagesfemale5861673
student139Mathematicsmale48383731
student140Languagesfemale33265660
student141Mathematicsmale84842975
student142Languagesfemale7235654
student143Mathematicsmale31427082
student144Languagesfemale94875035
student145Mathematicsmale91528026
student146Languagesfemale78657979
student147Mathematicsmale50905971
student148Languagesfemale15686633
student149Mathematicsmale17363413
student150Languagesfemale30956973
student151Mathematicsmale20534958
student152Languagesfemale19896060
student153Mathematicsmale5282203
student154Languagesfemale66985366
student155Mathematicsmale5852258
student156Languagesfemale3443688
student157Mathematicsmale4309114
student158Languagesfemale34186731
student159Mathematicsmale79733452
student160Languagesfemale15613727
student161Mathematicsmale74771545
student162Languagesfemale52621958
student163Mathematicsmale77602795
student164Languagesfemale9619357
student165Mathematicsmale51637519
student166Languagesfemale32447299
student167Mathematicsmale82845763
student168Languagesfemale53128567
student169Mathematicsmale4916846
student170Languagesfemale39341665
student171Mathematicsmale10068884
student172Languagesfemale14256352
student173Mathematicsmale74261560
student174Languagesfemale1158892
student175Mathematicsmale6247231
student176Languagesfemale65263242
student177Mathematicsmale83786924
student178Languagesfemale14100743
student179Mathematicsmale2835897
student180Languagesfemale1483962
student181Mathematicsmale1442469
student182Languagesfemale6452722
student183Mathematicsmale15262785
student184Languagesfemale9149407
student185Mathematicsmale87894287
student186Languagesfemale75766188
student187Mathematicsmale11486630
student188Languagesfemale7379272
student189Mathematicsmale98365815
student190Languagesfemale8028656
student191Mathematicsmale3633974
student192Languagesfemale5923390
student193Mathematicsmale9461933
student194Languagesfemale82497242
student195Mathematicsmale8059830
student196Languagesfemale89179027
student197Mathematicsmale4622667
student198Languagesfemale65757377
student199Mathematicsmale77975413
student200Languagesfemale78195796
student201Mathematicsmale92211180
student202Languagesfemale45499340
student203Mathematicsmale74258753
student204Languagesfemale1571234
student205Mathematicsmale82979573
student206Languagesfemale82605898
student207Mathematicsmale266411100
student208Languagesfemale6496045
student209Mathematicsmale96819663
student210Languagesfemale2439069
student211Mathematicsmale8664710
student212Languagesfemale764507
student213Mathematicsmale59122677
student214Languagesfemale21259382
student215Mathematicsmale22186451
student216Languagesfemale92419828
student217Mathematicsmale32481417
student218Languagesfemale62368556
student219Mathematicsmale33379087
student220Languagesfemale24436084
student221Mathematicsmale6593751
student222Languagesfemale9197576
student223Mathematicsmale86293227
student224Languagesfemale63596891
student225Mathematicsmale57739568
student226Languagesfemale38545987
student227Mathematicsmale53627264
student228Languagesfemale62847273
student229Mathematicsmale1308358
student230Languagesfemale35658087
student231Mathematicsmale76202850
student232Languagesfemale9176633
student233Mathematicsmale9229961
student234Languagesfemale47699839
student235Mathematicsmale21443882
student236Languagesfemale19865178
student237Mathematicsmale28454936
student238Languagesfemale78194981
student239Mathematicsmale72694720
student240Languagesfemale17436656
student241Mathematicsmale901944
student242Languagesfemale618251
student243Mathematicsmale1377213
student244Languagesfemale8005854
student245Mathematicsmale8331859
student246Languagesfemale90992912
student247Mathematicsmale89238159
student248Languagesfemale7226283
student249Mathematicsmale28105047
student250Languagesfemale8914894
student251Mathematicsmale15233769
student252Languagesfemale27821036
student253Mathematicsmale49456423
student254Languagesfemale79756374
student255Mathematicsmale2566475
student256Languagesfemale36262958
student257Mathematicsmale17226673
student258Languagesfemale70919745
student259Mathematicsmale34307830
student260Languagesfemale77578677
student261Mathematicsmale1259687
student262Languagesfemale11609771
student263Mathematicsmale12303558
student264Languagesfemale46152340
student265Mathematicsmale4481926
student266Languagesfemale15683215
student267Mathematicsmale5585098
student268Languagesfemale42303224
student269Mathematicsmale781009957
student270Languagesfemale55338725
student271Mathematicsmale25972993
student272Languagesfemale39351843
student273Mathematicsmale35179958
student274Languagesfemale86522724
student275Mathematicsmale97387376
student276Languagesfemale206198
student277Mathematicsmale9336947
student278Languagesfemale423152
student279Mathematicsmale6118962
student280Languagesfemale99898794
student281Mathematicsmale4895900
student282Languagesfemale60473130
student283Mathematicsmale64241076
student284Languagesfemale9937468
student285Mathematicsmale0986869
student286Languagesfemale66824959
student287Mathematicsmale86143717
student288Languagesfemale27489327
student289Mathematicsmale8489668
student290Languagesfemale9902057
student291Mathematicsmale50967242
student292Languagesfemale9822792
student293Mathematicsmale1994287
student294Languagesfemale9897922
student295Mathematicsmale75307764
student296Languagesfemale5198553
student297Mathematicsmale25958672
student298Languagesfemale20753735
student299Mathematicsmale4924111
student300Languagesfemale2832891
student301Mathematicsmale4163425
student302Languagesfemale29167790
student303Mathematicsmale89415182
student304Languagesfemale40912434
student305Mathematicsmale7474978
student306Languagesfemale6375562
student307Mathematicsmale30733490
student308Languagesfemale82919593
student309Mathematicsmale6247382
student310Languagesfemale39101257
student311Mathematicsmale89642067
student312Languagesfemale56369241
student313Mathematicsmale99809974
student314Languagesfemale31796493
student315Mathematicsmale5327055
student316Languagesfemale35152960
student317Mathematicsmale31476960
student318Languagesfemale88281366
student319Mathematicsmale65121640
student320Languagesfemale28171940
student321Mathematicsmale241004470
student322Languagesfemale20598352
student323Mathematicsmale17608291
student324Languagesfemale95994337
student325Mathematicsmale30189931
student326Languagesfemale3478386
student327Mathematicsmale9863435
student328Languagesfemale54239846
student329Mathematicsmale97934518
student330Languagesfemale2774077
student331Mathematicsmale9704137
student332Languagesfemale52377620
student333Mathematicsmale74186819
student334Languagesfemale77100339
student335Mathematicsmale38537718
student336Languagesfemale18132610
student337Mathematicsmale90478770
student338Languagesfemale38493674
student339Mathematicsmale100641372
student340Languagesfemale74254152
student341Mathematicsmale37131613
student342Languagesfemale24341583
student343Mathematicsmale2056728
student344Languagesfemale4522572
student345Mathematicsmale19117535
student346Languagesfemale6583115
student347Mathematicsmale16663611
student348Languagesfemale1239540
student349Mathematicsmale752742
student350Languagesfemale88926055
student351Mathematicsmale92709145
student352Languagesfemale74765944
student353Mathematicsmale63696094
student354Languagesfemale3685548
student355Mathematicsmale39962148
student356Languagesfemale4134275
student357Mathematicsmale6434733
student358Languagesfemale95146355
student359Mathematicsmale701001382
student360Languagesfemale522410021
student361Mathematicsmale040869
student362Languagesfemale024932
student363Mathematicsmale23108694
student364Languagesfemale1538649
student365Mathematicsmale7623310
student366Languagesfemale35357894
student367Mathematicsmale294243100
student368Languagesfemale668510
student369Mathematicsmale74155683
student370Languagesfemale7543908
student371Mathematicsmale4060470
student372Languagesfemale62421749
student373Mathematicsmale31464454
student374Languagesfemale30344787
student375Mathematicsmale9694152
student376Languagesfemale85432992
student377Mathematicsmale7904025
student378Languagesfemale36407285
student379Mathematicsmale5368882
student380Languagesfemale87783879
student381Mathematicsmale89978338
student382Languagesfemale21194910
student383Mathematicsmale47126850
student384Languagesfemale37124995
student385Mathematicsmale8408851
student386Languagesfemale89612748
student387Mathematicsmale10478761
student388Languagesfemale1692656
student389Mathematicsmale57331347
student390Languagesfemale90357775
student391Mathematicsmale31474753
student392Languagesfemale942412
student393Mathematicsmale6119817
student394Languagesfemale457577
student395Mathematicsmale6729212
student396Languagesfemale516456
student397Mathematicsmale93147714
student398Languagesfemale1893427
student399Mathematicsmale93775791
student400Languagesfemale67778032
student401Mathematicsmale5889417
student402Languagesfemale3056053
student403Mathematicsmale28253259
student404Languagesfemale62348164
student405Mathematicsmale29842623
student406Languagesfemale7086377
student407Mathematicsmale8654799
student408Languagesfemale9381089
student409Mathematicsmale84214658
student410Languagesfemale21841849
student411Mathematicsmale2796340
student412Languagesfemale9301991
student413Mathematicsmale31928743
student414Languagesfemale53259843
student415Mathematicsmale36758089
student416Languagesfemale37681254
student417Mathematicsmale25891253
student418Languagesfemale922846
student419Mathematicsmale11286058
student420Languagesfemale1373517
student421Mathematicsmale67303885
student422Languagesfemale68793441
student423Mathematicsmale72459341
student424Languagesfemale56464538
student425Mathematicsmale8621840
student426Languagesfemale99854119
student427Mathematicsmale7135389
student428Languagesfemale22911216
student429Mathematicsmale1532693
student430Languagesfemale35463474
student431Mathematicsmale33839720
student432Languagesfemale9920326
student433Mathematicsmale48428318
student434Languagesfemale4442530
student435Mathematicsmale78486045
student436Languagesfemale4757890
student437Mathematicsmale881210053
student438Languagesfemale4805160
student439Mathematicsmale70898516
student440Languagesfemale71943433
student441Mathematicsmale68137218
student442Languagesfemale7539721
student443Mathematicsmale65366087
student444Languagesfemale43212434
student445Mathematicsmale85776528
student446Languagesfemale61907891
student447Mathematicsmale9207812
student448Languagesfemale33306290
student449Mathematicsmale8616745
student450Languagesfemale100862423
student451Mathematicsmale1425645
student452Languagesfemale86399888
student453Mathematicsmale72687719
student454Languagesfemale94523100
student455Mathematicsmale34678979
student456Languagesfemale9204745
student457Mathematicsmale64582698
student458Languagesfemale439359100
student459Mathematicsmale82359781
student460Languagesfemale183524100
student461Mathematicsmale79804351
student462Languagesfemale56101767
student463Mathematicsmale36441485
student464Languagesfemale2640692
student465Mathematicsmale59934378
student466Languagesfemale7884883
student467Mathematicsmale41378060
student468Languagesfemale44279777
student469Mathematicsmale29196482
student470Languagesfemale50962746
student471Mathematicsmale49155145
student472Languagesfemale38353178
student473Mathematicsmale1802365
student474Languagesfemale91172376
student475Mathematicsmale57393563
student476Languagesfemale33736214
student477Mathematicsmale96168840
student478Languagesfemale30631613
student479Mathematicsmale74393787
student480Languagesfemale26369479
student481Mathematicsmale19586512
student482Languagesfemale73362248
student483Mathematicsmale7894757
student484Languagesfemale5951935
student485Mathematicsmale677110085
student486Languagesfemale33301546
student487Mathematicsmale12191637
student488Languagesfemale80982914
student489Mathematicsmale70511431
student490Languagesfemale95381592
student491Mathematicsmale60317412
student492Languagesfemale62569068
student493Mathematicsmale63112991
student494Languagesfemale4112520
student495Mathematicsmale6053144
student496Languagesfemale1135528
student497Mathematicsmale11964237
student498Languagesfemale16727974
student499Mathematicsmale9212266
student500Languagesfemale34226434
student501Mathematicsmale50938661
student502Languagesfemale50224044
student503Mathematicsmale383917
student504Languagesfemale98169355
student505Mathematicsmale86893628
student506Languagesfemale16531350
student507Mathematicsmale5757338
student508Languagesfemale34796977
student509Mathematicsmale241659
student510Languagesfemale606299100
student511Mathematicsmale65525295
student512Languagesfemale5873941
student513Mathematicsmale39752876
student514Languagesfemale4666478
student515Mathematicsmale5160998
student516Languagesfemale17201297
student517Mathematicsmale72179673
student518Languagesfemale92216227
student519Mathematicsmale5042433
student520Languagesfemale5237157
student521Mathematicsmale58403554
student522Languagesfemale9385753
student523Mathematicsmale79201818
student524Languagesfemale149427
student525Mathematicsmale95412998
student526Languagesfemale3459921
student527Mathematicsmale39664129
student528Languagesfemale328125
student529Mathematicsmale33443785
student530Languagesfemale69255979
student531Mathematicsmale13504952
student532Languagesfemale54834531
student533Mathematicsmale15249751
student534Languagesfemale7516963
student535Mathematicsmale9183856
student536Languagesfemale50137480
student537Mathematicsmale54757410
student538Languagesfemale76397046
student539Mathematicsmale84723940
student540Languagesfemale10047214
student541Mathematicsmale426111
student542Languagesfemale57716561
student543Mathematicsmale7854134
student544Languagesfemale14763647
student545Mathematicsmale15196396
student546Languagesfemale27823356
student547Mathematicsmale70239690
student548Languagesfemale612278
student549Mathematicsmale22376436
student550Languagesfemale75969440
student551Mathematicsmale4382921
student552Languagesfemale7968718
student553Mathematicsmale65765244
student554Languagesfemale41627354
student555Mathematicsmale25982140
student556Languagesfemale17709682
student557Mathematicsmale43912743
student558Languagesfemale33372433
student559Mathematicsmale87871031
student560Languagesfemale48409774
student561Mathematicsmale63759155
student562Languagesfemale66825995
student563Mathematicsmale21955838
student564Languagesfemale9299745
student565Mathematicsmale5979420
student566Languagesfemale64952412
student567Mathematicsmale70463674
student568Languagesfemale16259149
student569Mathematicsmale73332488
student570Languagesfemale9619527
student571Mathematicsmale18127646
student572Languagesfemale61714963
student573Mathematicsmale46328517
student574Languagesfemale42421137
student575Mathematicsmale49764120
student576Languagesfemale22278012
student577Mathematicsmale76341866
student578Languagesfemale96772917
student579Mathematicsmale62516772
student580Languagesfemale96672254
student581Mathematicsmale77112388
student582Languagesfemale6282433
student583Mathematicsmale392312100
student584Languagesfemale10212071
student585Mathematicsmale11277100
student586Languagesfemale40349778
student587Mathematicsmale2518319
student588Languagesfemale18763025
student589Mathematicsmale24574681
student590Languagesfemale2103194
student591Mathematicsmale91847513
student592Languagesfemale79449710
student593Mathematicsmale42606730
student594Languagesfemale61577535
student595Mathematicsmale42468171
student596Languagesfemale92637574
student597Mathematicsmale86374051
student598Languagesfemale5210473
student599Mathematicsmale100281476
student600Languagesfemale31762043
student601Mathematicsmale402766
student602Languagesfemale587921
student603Mathematicsmale754691
student604Languagesfemale2830153
student605Mathematicsmale38939892
student606Languagesfemale43968991
student607Mathematicsmale43491483
student608Languagesfemale50617298
student609Mathematicsmale4499983
student610Languagesfemale5367382
student611Mathematicsmale40849954
student612Languagesfemale29966569
student613Mathematicsmale1276599
student614Languagesfemale4783494
student615Mathematicsmale3727224
student616Languagesfemale94394924
student617Mathematicsmale0752141
student618Languagesfemale5936418
student619Mathematicsmale2266133
student620Languagesfemale4387448
student621Mathematicsmale100155152
student622Languagesfemale63719917
student623Mathematicsmale143444100
student624Languagesfemale2385727
student625Mathematicsmale23143240
student626Languagesfemale34497254
student627Mathematicsmale21168126
student628Languagesfemale54693434
student629Mathematicsmale72116331
student630Languagesfemale8798947
student631Mathematicsmale43525358
student632Languagesfemale5014420
student633Mathematicsmale89836787
student634Languagesfemale079916
student635Mathematicsmale59178458
student636Languagesfemale94953660
student637Mathematicsmale39426346
student638Languagesfemale019610
student639Mathematicsmale50164171
student640Languagesfemale8604613
student641Mathematicsmale45855936
student642Languagesfemale8335057
student643Mathematicsmale8306014
student644Languagesfemale76807338
student645Mathematicsmale2614582
student646Languagesfemale9316422
student647Mathematicsmale85947616
student648Languagesfemale57453216
student649Mathematicsmale16169013
student650Languagesfemale4331887
student651Mathematicsmale16243244
student652Languagesfemale5998334
student653Mathematicsmale73184783
student654Languagesfemale992510093
student655Mathematicsmale0739784
student656Languagesfemale0289475
student657Mathematicsmale65905863
student658Languagesfemale84358641
student659Mathematicsmale4539599
student660Languagesfemale32103162
student661Mathematicsmale61285461
student662Languagesfemale70961454
student663Mathematicsmale6392298
student664Languagesfemale41104623
student665Mathematicsmale81918021
student666Languagesfemale79716568
student667Mathematicsmale47691890
student668Languagesfemale2616700
student669Mathematicsmale66109335
student670Languagesfemale66682713
student671Mathematicsmale86792645
student672Languagesfemale50532574
student673Mathematicsmale9753914
student674Languagesfemale28796942
student675Mathematicsmale607259
student676Languagesfemale53213943
student677Mathematicsmale37654591
student678Languagesfemale76806027
student679Mathematicsmale85273455
student680Languagesfemale66114117
student681Mathematicsmale27618982
student682Languagesfemale402613
student683Mathematicsmale2516695
student684Languagesfemale63448563
student685Mathematicsmale97957883
student686Languagesfemale5121387
student687Mathematicsmale63928723
student688Languagesfemale22965959
student689Mathematicsmale33801523
student690Languagesfemale34751924
student691Mathematicsmale36684854
student692Languagesfemale32362012
student693Mathematicsmale68917450
student694Languagesfemale87919637
student695Mathematicsmale239144
student696Languagesfemale9462977
student697Mathematicsmale1474575
student698Languagesfemale73921990
student699Mathematicsmale8207978
student700Languagesfemale763510039
student701Mathematicsmale27518949
student702Languagesfemale0647237
student703Mathematicsmale93469487
student704Languagesfemale6922172
student705Mathematicsmale1752113
student706Languagesfemale1325219
student707Mathematicsmale75617273
student708Languagesfemale8437736
student709Mathematicsmale81194514
student710Languagesfemale62173927
student711Mathematicsmale8869681
student712Languagesfemale53825929
student713Mathematicsmale83347134
student714Languagesfemale9552614
student715Mathematicsmale6715313
student716Languagesfemale8297825
student717Mathematicsmale65503146
student718Languagesfemale27462537
student719Mathematicsmale98423544
student720Languagesfemale9014444
student721Mathematicsmale3168293
student722Languagesfemale3434370
student723Mathematicsmale59771421
student724Languagesfemale16535759
student725Mathematicsmale7914416
student726Languagesfemale108199
student727Mathematicsmale89487916
student728Languagesfemale8872387
student729Mathematicsmale17539584
student730Languagesfemale65523961
student731Mathematicsmale44309672
student732Languagesfemale70793233
student733Mathematicsmale30474611
student734Languagesfemale761001649
student735Mathematicsmale39369089
student736Languagesfemale1941929
student737Mathematicsmale23737887
student738Languagesfemale87714464
student739Mathematicsmale22198220
student740Languagesfemale94526739
student741Mathematicsmale14175187
student742Languagesfemale5663983
student743Mathematicsmale99924698
student744Languagesfemale19768388
student745Mathematicsmale15776881
student746Languagesfemale48814838
student747Mathematicsmale2913861
student748Languagesfemale7163030
student749Mathematicsmale19683053
student750Languagesfemale91182762
student751Mathematicsmale73333836
student752Languagesfemale99387550
student753Mathematicsmale55713490
student754Languagesfemale52409883
student755Mathematicsmale1463611
student756Languagesfemale1319496
student757Mathematicsmale49665592
student758Languagesfemale0198082
student759Mathematicsmale2635873
student760Languagesfemale8287639
student761Mathematicsmale52118357
student762Languagesfemale83688425
student763Mathematicsmale1725670
student764Languagesfemale1758084
student765Mathematicsmale7564785
student766Languagesfemale76329339
student767Mathematicsmale20758465
student768Languagesfemale25471289
student769Mathematicsmale86947945
student770Languagesfemale65815535
student771Mathematicsmale62414143
student772Languagesfemale1446243
student773Mathematicsmale17557278
student774Languagesfemale9546356
student775Mathematicsmale7205648
student776Languagesfemale30881956
student777Mathematicsmale42448856
student778Languagesfemale42695663
student779Mathematicsmale7857783
student780Languagesfemale15862498
student781Mathematicsmale4684369
student782Languagesfemale67981552
student783Mathematicsmale33326357
student784Languagesfemale35951653
student785Mathematicsmale78545482
student786Languagesfemale8185914
student787Mathematicsmale42412314
student788Languagesfemale591008636
student789Mathematicsmale1926012
student790Languagesfemale10034570
student791Mathematicsmale381217
student792Languagesfemale3155193
student793Mathematicsmale11339877
student794Languagesfemale461786
student795Mathematicsmale5786727
student796Languagesfemale5746236
student797Mathematicsmale57676661
student798Languagesfemale93888725
student799Mathematicsmale59966441
student800Languagesfemale6276923
student801Mathematicsmale35833255
student802Languagesfemale42581583
student803Mathematicsmale41904012
student804Languagesfemale8143837
student805Mathematicsmale87773320
student806Languagesfemale53873037
student807Mathematicsmale13358516
student808Languagesfemale20829034
student809Mathematicsmale5821614
student810Languagesfemale14282356
student811Mathematicsmale4997368
student812Languagesfemale31461163
student813Mathematicsmale7497643
student814Languagesfemale42839575
student815Mathematicsmale2654529
student816Languagesfemale79596988
student817Mathematicsmale68182684
student818Languagesfemale39139915
student819Mathematicsmale2248716
student820Languagesfemale12538811
student821Mathematicsmale33908029
student822Languagesfemale3795486
student823Mathematicsmale9178851
student824Languagesfemale31586731
student825Mathematicsmale22305098
student826Languagesfemale55585610
student827Mathematicsmale56765753
student828Languagesfemale1129881
student829Mathematicsmale67926671
student830Languagesfemale30614449
student831Mathematicsmale0414461
student832Languagesfemale72524585
student833Mathematicsmale60991294
student834Languagesfemale83587542
student835Mathematicsmale9505377
student836Languagesfemale33287062
student837Mathematicsmale3982755
student838Languagesfemale411004547
student839Mathematicsmale81692729
student840Languagesfemale9012649
student841Mathematicsmale45382034
student842Languagesfemale325311
student843Mathematicsmale55778649
student844Languagesfemale61609176
student845Mathematicsmale8085749
student846Languagesfemale63897371
student847Mathematicsmale79159742
student848Languagesfemale99187343
student849Mathematicsmale30523856
student850Languagesfemale65866734
student851Mathematicsmale7343655
student852Languagesfemale42435173
student853Mathematicsmale870980
student854Languagesfemale29411245
student855Mathematicsmale5739090
student856Languagesfemale80529654
student857Mathematicsmale43838246
student858Languagesfemale7917131
student859Mathematicsmale6813707
student860Languagesfemale51441552
student861Mathematicsmale9170178
student862Languagesfemale4116578
student863Mathematicsmale20635585
student864Languagesfemale5938726
student865Mathematicsmale4894432
student866Languagesfemale26679839
student867Mathematicsmale48793866
student868Languagesfemale1632153
student869Mathematicsmale13205085
student870Languagesfemale4922039
student871Mathematicsmale8262353
student872Languagesfemale6607464
student873Mathematicsmale66483914
student874Languagesfemale43833100
student875Mathematicsmale214990
student876Languagesfemale79807180
student877Mathematicsmale84252688
student878Languagesfemale38466660
student879Mathematicsmale35279851
student880Languagesfemale5759267
student881Mathematicsmale7687788
student882Languagesfemale2140817
student883Mathematicsmale5046866
student884Languagesfemale83863092
student885Mathematicsmale63466694
student886Languagesfemale7671262
student887Mathematicsmale7418686
student888Languagesfemale65774488
student889Mathematicsmale67326119
student890Languagesfemale85968541
student891Mathematicsmale1487705
student892Languagesfemale81284528
student893Mathematicsmale9191883
student894Languagesfemale407024
student895Mathematicsmale18195189
student896Languagesfemale70352512
student897Mathematicsmale7290741
student898Languagesfemale8417186
student899Mathematicsmale1423886
student900Languagesfemale7837601
student901Mathematicsmale66953168
student902Languagesfemale23608065
student903Mathematicsmale76896396
student904Languagesfemale3469070
student905Mathematicsmale65449679
student906Languagesfemale6877865
student907Mathematicsmale86619943
student908Languagesfemale88953213
student909Mathematicsmale531005982
student910Languagesfemale3579535
student911Mathematicsmale230177
student912Languagesfemale9687263
student913Mathematicsmale23923996
student914Languagesfemale9497658
student915Mathematicsmale49312971
student916Languagesfemale21577957
student917Mathematicsmale03510089
student918Languagesfemale64827552
student919Mathematicsmale16666968
student920Languagesfemale92951127
student921Mathematicsmale16888590
student922Languagesfemale56152698
student923Mathematicsmale78274017
student924Languagesfemale95104432
student925Mathematicsmale99855218
student926Languagesfemale73317149
student927Mathematicsmale21791063
student928Languagesfemale92718012
student929Mathematicsmale23293388
student930Languagesfemale4189884
student931Mathematicsmale97177921
student932Languagesfemale72409392
student933Mathematicsmale7558326
student934Languagesfemale15982728
student935Mathematicsmale7688806
student936Languagesfemale84234292
student937Mathematicsmale71568671
student938Languagesfemale7395822
student939Mathematicsmale1555460
student940Languagesfemale2031308
student941Mathematicsmale97544181
student942Languagesfemale83418664
student943Mathematicsmale7195327
student944Languagesfemale0273091
student945Mathematicsmale99751722
student946Languagesfemale92531090
student947Mathematicsmale4449432
student948Languagesfemale0974879
student949Mathematicsmale97557974
student950Languagesfemale6598932
student951Mathematicsmale56733881
student952Languagesfemale84946150
student953Mathematicsmale4820770
student954Languagesfemale39981420
student955Mathematicsmale4152465
student956Languagesfemale78229231
student957Mathematicsmale28382654
student958Languagesfemale49613554
student959Mathematicsmale81152817
student960Languagesfemale5480582
student961Mathematicsmale7523537
student962Languagesfemale5565120
student963Mathematicsmale86427036
student964Languagesfemale54455480
student965Mathematicsmale38186992
student966Languagesfemale33894683
student967Mathematicsmale4395576
student968Languagesfemale13261286
student969Mathematicsmale94228559
student970Languagesfemale9358610
student971Mathematicsmale35728536
student972Languagesfemale37519693
student973Mathematicsmale71107959
student974Languagesfemale71317393
student975Mathematicsmale80268697
student976Languagesfemale69216769
student977Mathematicsmale38861039
student978Languagesfemale48903981
student979Mathematicsmale9083342
student980Languagesfemale1919184
student981Mathematicsmale98255046
student982Languagesfemale38882116
student983Mathematicsmale71481843
student984Languagesfemale79851816
student985Mathematicsmale51669068
student986Languagesfemale100956591
student987Mathematicsmale6742424
student988Languagesfemale93809435
student989Mathematicsmale65785794
student990Languagesfemale27922191
student991Mathematicsmale77152676
student992Languagesfemale28845167
student993Mathematicsmale3786250
student994Languagesfemale59772074
student995Mathematicsmale6266875
student996Languagesfemale88703343
student997Mathematicsmale73334253
student998Languagesfemale6410231
student999Mathematicsmale91931635
student1000Languagesfemale30689540
student1001Mathematicsmale2524832
student1002Languagesfemale50775381
student1003Mathematicsmale67441065
student1004Languagesfemale29533486
student1005Mathematicsmale77692275
student1006Languagesfemale48829540
student1007Mathematicsmale30712963
student1008Languagesfemale4531471
student1009Mathematicsmale81122044
student1010Languagesfemale17668242
student1011Mathematicsmale15113218
student1012Languagesfemale27345919
student1013Mathematicsmale18672514
student1014Languagesfemale24645224
student1015Mathematicsmale36874846
student1016Languagesfemale3317068
student1017Mathematicsmale4826380
student1018Languagesfemale53638557
student1019Mathematicsmale5873024
student1020Languagesfemale8590810
student1021Mathematicsmale69285276
student1022Languagesfemale7522752
+
+ +
+ + + + diff --git a/docs/example-update-cell.html b/docs/example-update-cell.html new file mode 100644 index 00000000..14fd33bb --- /dev/null +++ b/docs/example-update-cell.html @@ -0,0 +1,119 @@ + + + + jQuery plugin: Tablesorter 2.0 - Appending table data with ajax + + + + + + + + + + + + + + + + + + +
+

Demo

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDate
PeterParker28$9.9920%Jul 6, 2006 8:14 AM
JohnHood33$19.9925%Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944%Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%Jan 18, 2007 9:12 AM
+
+
+
+

Javascript

+
+

+	
+

HTML

+
+

+	
+
+ + + diff --git a/docs/example-widgets.html b/docs/example-widgets.html new file mode 100644 index 00000000..ac9445f1 --- /dev/null +++ b/docs/example-widgets.html @@ -0,0 +1,348 @@ + + + + jQuery plugin: Tablesorter 2.0 - Writing custom widgets + + + + + + + + + + + + + + + + + +
+ +

Javascript

+
+// add new widget called repeatHeaders
+$.tablesorter.addWidget({
+	// give the widget a id
+	id: "repeatHeaders",
+	// format is called when the on init and when a sorting has finished
+	format: function(table) {
+		// cache and collect all TH headers
+		if(!this.headers) {
+			var h = this.headers = []; 
+			$("thead th",table).each(function() {
+				h.push(
+					"" + $(this).text() + ""
+				);
+				
+			});
+		}
+		
+		// remove appended headers by classname.
+		$("tr.repated-header",table).remove();
+		
+		// loop all tr elements and insert a copy of the "headers"	
+		for(var i=0; i < table.tBodies[0].rows.length; i++) {
+			// insert a copy of the table head every 10th row
+			if((i%5) == 4) {
+				$("tbody tr:eq(" + i + ")",table).before(
+					$("").html(this.headers.join(""))
+				
+				);	
+			}
+		}
+	}
+});
+
+// call the tablesorter plugin and assign widgets with id "zebra" (Default widget in the core) and the newly created "repeatHeaders"
+$("table").tablesorter({
+	widgets: ['zebra','repeatHeaders']
+});
+
+ +

Demo

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameMajorSexEnglishJapaneseCalculusGeometry
NameMajorSexEnglishJapaneseCalculusGeometry
Student01Languagesmale80707580
Student02Mathematicsmale908810090
Student03Languagesfemale85958085
Student04Languagesmale6055100100
Student05Languagesfemale68809580
Student06Mathematicsmale1009910090
Student07Mathematicsmale85689090
Student08Languagesmale100909085
Student09Mathematicsmale80506575
Student10Languagesmale8510010090
Student11Languagesmale8685100100
Student12Mathematicsfemale100757085
Student13Languagesfemale1008010090
Student14Languagesfemale50455590
Student15Languagesmale953510090
Student16Languagesfemale100503070
Student17Languagesfemale801005565
Student18Mathematicsmale30495575
Student19Languagesmale68908870
Student20Mathematicsmale40454080
Student21Languagesmale5045100100
Student22Mathematicsmale1009910090
Student23Languagesfemale85808080
+
+ + + + diff --git a/docs/img/external.png b/docs/img/external.png new file mode 100644 index 00000000..419c06fb Binary files /dev/null and b/docs/img/external.png differ diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..cfd18d86 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,553 @@ + + + + jQuery plugin: Tablesorter 2.0 + + + + + + + + + + + + + + + + +
+
+
+ +

+ Author: Christian Bach
+ Version: 2.0.6 (changelog)
+ Licence: + Dual licensed under MIT + or GPL licenses. +

+ +

+ Update! New version!, and the tablesorter docs are now available in russian, head over to tablesorter.ru +

+ +

+ Helping out! If you like tablesorter and you're feeling generous, take a look at my Amazon Wish List or make a donation. +

+ +
+ + + + + + + + + +
+ +

Comments and love letters can be sent to: .

+ +

+ + + + + + +

Contents

+
    +
  1. Introduction
  2. +
  3. Demo
  4. +
  5. Getting started
  6. + +
  7. Examples
  8. + +
  9. Configuration
  10. +
  11. Download
  12. +
  13. Compatibility
  14. +
  15. Support
  16. +
  17. Credits
  18. +
+ + +

Introduction

+

+ tablesorter is a jQuery plugin for turning a + standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. + tablesorter can successfully parse and sort many types of data including linked data in a cell. + It has many useful features including: +

+ + + + +

Demo

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NameAgeTotalDiscountDifferenceDate
PeterParker28$9.9920.9%+12.1Jul 6, 2006 8:14 AM
JohnHood33$19.9925%+12Dec 10, 2002 5:14 AM
ClarkKent18$15.8944%-26Jan 12, 2003 11:14 AM
BruceAlmighty45$153.1944.7%+77Jan 18, 2001 9:12 AM
BruceEvans22$13.1911%-100.9Jan 18, 2007 9:12 AM
BruceEvans22$13.1911%0Jan 18, 2007 9:12 AM
+ +

+ TIP! Sort multiple columns simultaneously by holding down the shift key and clicking a second, third or even fourth column header! +

+ + + +

Getting started

+

+ To use the tablesorter plugin, include the jQuery + library and the tablesorter plugin inside the <head> tag + of your HTML document: +

+ +
+<script type="text/javascript" src="/path/to/jquery-latest.js"></script>
+<script type="text/javascript" src="/path/to/jquery.tablesorter.js"></script>
+
+ + +

tablesorter works on standard HTML tables. You must include THEAD and TBODY tags:

+ +
+<table id="myTable" class="tablesorter">
+	<thead>
+		<tr>
+			<th>Last Name</th>
+			<th>First Name</th>
+			<th>Email</th>
+			<th>Due</th>
+			<th>Web Site</th>
+		</tr>
+	</thead>
+	<tbody>
+		<tr>
+			<td>Smith</td>
+			<td>John</td>
+			<td>jsmith@gmail.com</td>
+			<td>$50.00</td>
+			<td>http://www.jsmith.com</td>
+		</tr>
+		<tr>
+			<td>Bach</td>
+			<td>Frank</td>
+			<td>fbach@yahoo.com</td>
+			<td>$50.00</td>
+			<td>http://www.frank.com</td>
+		</tr>
+		<tr>
+			<td>Doe</td>
+			<td>Jason</td>
+			<td>jdoe@hotmail.com</td>
+			<td>$100.00</td>
+			<td>http://www.jdoe.com</td>
+		</tr>
+		<tr>
+			<td>Conway</td>
+			<td>Tim</td>
+			<td>tconway@earthlink.net</td>
+			<td>$50.00</td>
+			<td>http://www.timconway.com</td>
+		</tr>
+	</tbody>
+</table>
+ +

Start by telling tablesorter to sort your table when the document is loaded:

+ +
+$(function(){
+	$("#myTable").tablesorter();
+});
+ +

+ Click on the headers and you'll see that your table is now sortable! You can + also pass in configuration options when you initialize the table. This tells + tablesorter to sort on the first and second column in ascending order. +

+ +
+$(function(){
+	$("#myTable").tablesorter( {sortList: [[0,0], [1,0]]} );
+});
+ +

+ NOTE! tablesorter will auto-detect most data types including numbers, dates, ip-adresses for more information see Examples +

+ + +

Examples

+

+ These examples will show what's possible with tablesorter. You need Javascript enabled to + run these samples, just like you and your users will need Javascript enabled to use tablesorter. +

+ + Basic + + Metadata - setting inline options + + + Advanced + + + Companion plugins + + + +

Configuration

+ +

+ tablesorter has many options you can pass in at initialization to achieve different effects: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDefaultDescriptionLink
sortListArraynullAn array of instructions for per-column sorting and direction in the format: [[columnIndex, sortDirection], ... ] where columnIndex is a zero-based index for your columns left-to-right and sortDirection is 0 for Ascending and 1 for Descending. A valid argument that sorts ascending first by column 1 and then column 2 looks like: [[0,0],[1,0]]Example
sortInitialOrderStringascWhen clicking the header for the first time, the direction it sorts. Valid arguments are "asc" for Ascending or "desc" for Descending.Example
sortMultiSortKeyStringshiftKeyThe key used to select more than one column for multi-column sorting. Defaults to the shift key. Other options might be ctrlKey, altKey.
Reference: http://developer.mozilla.org/en/docs/DOM:event#Properties
Example
textExtractionString Or Functionsimple + Defines which method is used to extract data from a table cell for sorting. + Built-in options include "simple" and "complex". Use complex if you have data marked up + inside of a table cell like: <td><strong><em>123 Main Street</em></strong></td>. + Complex can be slow in large tables so consider writing your own text extraction function "myTextExtraction" which you define like: +
var myTextExtraction = function(node){
+	// extract data from markup and return it 
+	return node.childNodes[0].childNodes[0].innerHTML;
+}
+$(function(){
+	$("#myTable").tableSorter( {textExtraction: myTextExtraction} );
+});
+ + tablesorter will pass a jQuery object containing the contents of the current cell for you to parse and return. Thanks to Josh Nathanson for the examples. +
Example
headersObjectnull + An object of instructions for per-column controls in the format: headers: { 0: { option: setting }, ... } For example, to disable + sorting on the first two columns of a table: headers: { 0: { sorter: false}, 1: {sorter: false} } + Example
sortForceArraynullUse to add an additional forced sort that will be appended to the dynamic selections by the user. For example, can be used to sort people alphabetically after some other user-selected sort that results in rows with the same value like dates or money due. It can help prevent data from appearing as though it has a random secondary sort.Example
widthFixedBooleanfalseIndicates if tablesorter should apply fixed widths to the table columns. This is useful for the Pager companion. Requires the jQuery dimension plugin to work.Example
cancelSelectionBooleantrueIndicates if tablesorter should disable selection of text in the table header (TH). Makes header behave more like a button.
cssHeaderString"header"The CSS style used to style the header in its unsorted state. Example from the blue skin: +
+th.header {
+	background-image: url(../img/small.gif);
+	cursor: pointer;
+	font-weight: bold;
+	background-repeat: no-repeat;
+	background-position: center left;
+	padding-left: 20px;
+	border-right: 1px solid #dad9c7;
+	margin-left: -1px;
+}
+
cssAscString"headerSortUp"The CSS style used to style the header when sorting ascending. Example from the blue skin: +
+th.headerSortUp {
+	background-image: url(../img/small_asc.gif);
+	background-color: #3399FF;
+}
+
+
cssDescString"headerSortDown"The CSS style used to style the header when sorting descending. Example from the blue skin: +
+th.headerSortDown {
+	background-image: url(../img/small_desc.gif);
+	background-color: #3399FF;
+}
+
+
debugBooleanfalse + Boolean flag indicating if tablesorter should display debuging information usefull for development. + Example
+ + + + +

Download

+ +

Full release - Plugin, Documentation, Add-ons, Themes jquery.tablesorter.zip

+ + +

Pick n choose - Place at least the required files in a directory on your webserver that is accessible to a web browser. Record this location.

+ + Required: + + + Optional/Add-Ons: + + + + + Themes: + + + +

Browser Compatibility

+ +

tablesorter has been tested successfully in the following browsers with Javascript enabled:

+ + +

jQuery Browser Compatibility

+ + +

Support

+

+ Support is available through the + jQuery Mailing List. +

+

Access to the jQuery Mailing List is also available through Nabble Forums.

+ + + +

Credits

+

+ Written by Christian Bach. +

+

+ Documentation written by Brian Ghidinelli, + based on Mike Alsup's great documention. +

+

+ John Resig for the fantastic jQuery +

+
+ + + + diff --git a/docs/js/chili/chili-1.8b.js b/docs/js/chili/chili-1.8b.js new file mode 100644 index 00000000..c17ec4ce --- /dev/null +++ b/docs/js/chili/chili-1.8b.js @@ -0,0 +1,392 @@ +/* +=============================================================================== +Chili is the jQuery code highlighter plugin +............................................................................... + Copyright 2007 / Andrea Ercolino +------------------------------------------------------------------------------- +LICENSE: http://www.opensource.org/licenses/mit-license.php +WEBSITE: http://noteslog.com/chili/ +=============================================================================== + +=============================================================================== +Metaobjects is the jQuery metadata plugin on steroids +............................................................................... + Copyright 2007 / Andrea Ercolino +------------------------------------------------------------------------------- +LICENSE: http://www.opensource.org/licenses/mit-license.php +WEBSITE: http://noteslog.com/metaobjects/ +=============================================================================== +*/ + +//----------------------------------------------------------------------------- +( function($) { + +ChiliBook = { //implied global + + version: "1.8b" // 2007-05-26 + + , automatic: true + , automaticSelector: "code" + + , codeLanguage: function( el ) { + var recipeName = $( el ).attr( "class" ); + return recipeName ? recipeName : ''; + } + + , metadataSelector: "object.chili" // use an empty string for not executing + + , recipeLoading: true + , recipeFolder: "" // used like: recipeFolder + recipeName + '.js' + , stylesheetLoading: true + , stylesheetFolder: "" // used like: stylesheetFolder + recipeName + '.css' + + , defaultReplacement: '$$' + + , replaceSpace: " " // use an empty string for not replacing + , replaceTab: "    " // use an empty string for not replacing + , replaceNewLine: " 
" // use an empty string for not replacing + + , recipes: {} //repository + , queue: {} //register + + //fix for IE: copy of PREformatted text strips off all html, losing newlines + , preFixCopy: document.selection && document.selection.createRange + , preContent: "" + , preElement: null +}; + + +$.metaobjects = function( options ) { + + options = $.extend( { + context: document + , clean: true + , selector: 'object.metaobject' + }, options ); + + function jsValue( value ) { + eval( 'value = ' + value + ";" ); + return value; + } + + return $( options.selector, options.context ) + .each( function() { + + var settings = { target: this.parentNode }; + $( '> param[@name=metaparam]', this ) + .each( function() { + $.extend( settings, jsValue( this.value ) ); + } ); + + $( '> param', this ) + .not( '[@name=metaparam]' ) + .each( function() { + var name = this.name, value = jsValue( this.value ); + $( settings.target ) + .each( function() { + this[ name ] = value; + } ); + } ); + + if( options.clean ) { + $( this ).remove(); + } + } ); +}; + +$.fn.chili = function( options ) { + var book = $.extend( {}, ChiliBook, options || {} ); + + function cook( ingredients, recipe ) { + + function prepareStep( stepName, step ) { + var exp = ( typeof step.exp == "string" ) ? step.exp : step.exp.source; + steps.push( { + stepName: stepName + , exp: "(" + exp + ")" + , length: 1 // add 1 to account for the newly added parentheses + + (exp // count number of submatches in here + .replace( /\\./g, "%" ) // disable any escaped character + .replace( /\[.*?\]/g, "%" ) // disable any character class + .match( /\((?!\?)/g ) // match any open parenthesis, not followed by a ? + || [] // make sure it is an empty array if there are no matches + ).length // get the number of matches + , replacement: (step.replacement) ? step.replacement : book.defaultReplacement + } ); + } // function prepareStep( stepName, step ) + + function knowHow() { + var prevLength = 0; + var exps = new Array; + for (var i = 0; i < steps.length; i++) { + var exp = steps[ i ].exp; + // adjust backreferences + exp = exp.replace( /\\\\|\\(\d+)/g, function( m, aNum ) { + return !aNum ? m : "\\" + ( prevLength + 1 + parseInt( aNum, 10 ) ); + } ); + exps.push( exp ); + prevLength += steps[ i ].length; + } + var source = exps.join( "|" ); + return new RegExp( source, (recipe.ignoreCase) ? "gi" : "g" ); + } // function knowHow() + + function escapeHTML( str ) { + return str.replace( /&/g, "&" ).replace( / 1 ) { + return; + } + var ingredients = el.childNodes[0] && el.childNodes[0].data; + if( ! ingredients ) { + return; + } + // hack for IE: \r is used instead of \n + ingredients = ingredients.replace(/\r\n?/g, "\n"); + + var dish = cook( ingredients, recipe ); // all happens here + + if( book.replaceTab ) { + dish = dish.replace( /\t/g, book.replaceTab ); + } + if( book.replaceNewLine ) { + dish = dish.replace( /\n/g, book.replaceNewLine ); + } + + $( el ).html( dish ); + if( ChiliBook.preFixCopy ) { + $( el ) + .parents() + .filter( "pre" ) + .bind( "mousedown", function() { + ChiliBook.preElement = this; + } ) + .bind( "mouseup", function() { + if( ChiliBook.preElement == this ) { + ChiliBook.preContent = document.selection.createRange().htmlText; + } + } ) + ; + } + } // function makeDish( el ) + + function getPath( recipeName, options ) { + var settingsDef = { + recipeFolder: book.recipeFolder + , recipeFile: recipeName + ".js" + , stylesheetFolder: book.stylesheetFolder + , stylesheetFile: recipeName + ".css" + }; + var settings; + if( options && typeof options == "object" ) { + settings = $.extend( settingsDef, options ); + } + else { + settings = settingsDef; + } + return { + recipe : settings.recipeFolder + settings.recipeFile + , stylesheet: settings.stylesheetFolder + settings.stylesheetFile + }; + } //function getPath( recipeName, options ) + +//----------------------------------------------------------------------------- +// initializations + if( book.metadataSelector ) { + $.metaobjects( { context: this, selector: book.metadataSelector } ); + } + +//----------------------------------------------------------------------------- +// the coloring starts here + this + .each( function() { + var el = this; + var recipeName = book.codeLanguage( el ); + if( '' != recipeName ) { + var path = getPath( recipeName, el.chili ); + if( book.recipeLoading || el.chili ) { + /* dynamic setups come here */ + if( ! book.queue[ path.recipe ] ) { + /* this is a new recipe to download */ + try { + book.queue[ path.recipe ] = [ el ]; + $.getJSON( path.recipe, function( recipeLoaded ) { + recipeLoaded.path = path.recipe; + book.recipes[ path.recipe ] = recipeLoaded; + if( book.stylesheetLoading ) { + checkCSS( path.stylesheet ); + } + var q = book.queue[ path.recipe ]; + for( var i = 0, iTop = q.length; i < iTop; i++ ) { + makeDish( q[ i ], path.recipe ); + } + } ); + } + catch( recipeNotAvailable ) { + alert( "the recipe for '" + recipeName + "' was not found in '" + path.recipe + "'" ); + } + } + else { + /* not a new recipe, so just enqueue this element */ + book.queue[ path.recipe ].push( el ); + } + /* a recipe could have been already downloaded */ + makeDish( el, path.recipe ); + } + else { + /* static setups come here */ + makeDish( el, path.recipe ); + } + } + } ); + + return this; +//----------------------------------------------------------------------------- +}; + +//main +$( function() { + + if( ChiliBook.automatic ) { + if( ChiliBook.elementPath ) { + //preserve backward compatibility + ChiliBook.automaticSelector = ChiliBook.elementPath; + if( ChiliBook.elementClass ) { + ChiliBook.codeLanguage = function ( el ) { + var selectClass = new RegExp( "\\b" + ChiliBook.elementClass + "\\b", "gi" ); + var elClass = $( el ).attr( "class" ); + if( ! elClass ) { + return ''; + } + var recipeName = $.trim( elClass.replace( selectClass, "" ) ); + return recipeName; + }; + } + } + + $( ChiliBook.automaticSelector ).chili(); + } + + if( ChiliBook.preFixCopy ) { + function preformatted( text ) { + if( '' == text ) { + return ""; + } + do { + var newline_flag = (new Date()).valueOf(); + } + while( text.indexOf( newline_flag ) > -1 ); + text = text.replace( /\]*?\>/ig, newline_flag ); + var el = document.createElement( '
' );
+			el.innerHTML = text;
+			text = el.innerText.replace( new RegExp( newline_flag, "g" ), '\r\n' );
+			return text;
+		}
+
+		$( "body" )
+		.bind( "copy", function() {
+			if( '' != ChiliBook.preContent ) {
+				window.clipboardData.setData( 'Text', preformatted( ChiliBook.preContent ) );
+				event.returnValue = false;
+			}
+		} )
+		.bind( "mousedown", function() {
+			ChiliBook.preContent = "";
+		} )
+		.bind( "mouseup", function() {
+			ChiliBook.preElement = null;
+		} )
+		;
+	}
+
+} );
+
+} ) ( jQuery );
diff --git a/docs/js/chili/chili-1.8b.pack.js b/docs/js/chili/chili-1.8b.pack.js
new file mode 100644
index 00000000..21758e2e
--- /dev/null
+++ b/docs/js/chili/chili-1.8b.pack.js
@@ -0,0 +1 @@
+(function($){ChiliBook={version:"1.8b",automatic:true,automaticSelector:"code",codeLanguage:function(el){var recipeName=$(el).attr("class");return recipeName?recipeName:''},metadataSelector:"object.chili",recipeLoading:true,recipeFolder:"",stylesheetLoading:true,stylesheetFolder:"",defaultReplacement:'$$',replaceSpace:" ",replaceTab:"    ",replaceNewLine:" 
",recipes:{},queue:{},preFixCopy:document.selection&&document.selection.createRange,preContent:"",preElement:null};$.metaobjects=function(options){options=$.extend({context:document,clean:true,selector:'object.metaobject'},options);function jsValue(value){eval('value = '+value+";");return value}return $(options.selector,options.context).each(function(){var settings={target:this.parentNode};$('> param[@name=metaparam]',this).each(function(){$.extend(settings,jsValue(this.value))});$('> param',this).not('[@name=metaparam]').each(function(){var name=this.name,value=jsValue(this.value);$(settings.target).each(function(){this[name]=value})});if(options.clean){$(this).remove()}})};$.fn.chili=function(options){var book=$.extend({},ChiliBook,options||{});function cook(ingredients,recipe){function prepareStep(stepName,step){var exp=(typeof step.exp=="string")?step.exp:step.exp.source;steps.push({stepName:stepName,exp:"("+exp+")",length:1+(exp.replace(/\\./g,"%").replace(/\[.*?\]/g,"%").match(/\((?!\?)/g)||[]).length,replacement:(step.replacement)?step.replacement:book.defaultReplacement})}function knowHow(){var prevLength=0;var exps=new Array;for(var i=0;i1){return}var ingredients=el.childNodes[0]&&el.childNodes[0].data;if(!ingredients){return}ingredients=ingredients.replace(/\r\n?/g,"\n");var dish=cook(ingredients,recipe);if(book.replaceTab){dish=dish.replace(/\t/g,book.replaceTab)}if(book.replaceNewLine){dish=dish.replace(/\n/g,book.replaceNewLine)}$(el).html(dish);if(ChiliBook.preFixCopy){$(el).parents().filter("pre").bind("mousedown",function(){ChiliBook.preElement=this}).bind("mouseup",function(){if(ChiliBook.preElement==this){ChiliBook.preContent=document.selection.createRange().htmlText}})}}function getPath(recipeName,options){var settingsDef={recipeFolder:book.recipeFolder,recipeFile:recipeName+".js",stylesheetFolder:book.stylesheetFolder,stylesheetFile:recipeName+".css"};var settings;if(options&&typeof options=="object"){settings=$.extend(settingsDef,options)}else{settings=settingsDef}return{recipe:settings.recipeFolder+settings.recipeFile,stylesheet:settings.stylesheetFolder+settings.stylesheetFile}}if(book.metadataSelector){$.metaobjects({context:this,selector:book.metadataSelector})}$(this).each(function(){var el=this;var recipeName=book.codeLanguage(el);if(''!=recipeName){var path=getPath(recipeName,el.chili);if(book.recipeLoading||el.chili){if(!book.queue[path.recipe]){try{book.queue[path.recipe]=[el];$.getJSON(path.recipe,function(recipeLoaded){recipeLoaded.path=path.recipe;book.recipes[path.recipe]=recipeLoaded;if(book.stylesheetLoading){checkCSS(path.stylesheet)}var q=book.queue[path.recipe];for(var i=0,iTop=q.length;i-1);text=text.replace(/\]*?\>/ig,newline_flag);var el=document.createElement('
');el.innerHTML=text;text=el.innerText.replace(new RegExp(newline_flag,"g"),'\r\n');return text}$("body").bind("copy",function(){if(''!=ChiliBook.preContent){window.clipboardData.setData('Text',preformatted(ChiliBook.preContent));event.returnValue=false}}).bind("mousedown",function(){ChiliBook.preContent=""}).bind("mouseup",function(){ChiliBook.preElement=null})}})})(jQuery);
\ No newline at end of file
diff --git a/docs/js/chili/cplusplus.css b/docs/js/chili/cplusplus.css
new file mode 100644
index 00000000..fa9343b4
--- /dev/null
+++ b/docs/js/chili/cplusplus.css
@@ -0,0 +1,18 @@
+/*
+===============================================================================
+Chili is the jQuery code highlighter plugin
+...............................................................................
+                                               Copyright 2007 / Andrea Ercolino
+-------------------------------------------------------------------------------
+LICENSE: http://www.opensource.org/licenses/mit-license.php
+WEBSITE: http://noteslog.com/chili/
+===============================================================================
+*/
+
+.cplusplus .mlcom    { color: #4040c2; }
+.cplusplus .com      { color: green; }
+.cplusplus .string   { color: teal; }
+.cplusplus .keyword  { color: navy; font-weight: bold; }
+.cplusplus .datatype { color: blue; }
+.cplusplus .preproc  { color: red; }
+.cplusplus .number   { color: red; }
diff --git a/docs/js/chili/cplusplus.js b/docs/js/chili/cplusplus.js
new file mode 100644
index 00000000..8783c77c
--- /dev/null
+++ b/docs/js/chili/cplusplus.js
@@ -0,0 +1,22 @@
+/*
+===============================================================================
+Chili is the jQuery code highlighter plugin
+...............................................................................
+                                               Copyright 2007 / Andrea Ercolino
+-------------------------------------------------------------------------------
+LICENSE: http://www.opensource.org/licenses/mit-license.php
+WEBSITE: http://noteslog.com/chili/
+===============================================================================
+*/
+
+{
+	steps: {
+		  mlcom   : { exp: /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\// }
+		, com     : { exp: /\/\/.*/ }
+		, preproc : { exp: /[\^\n]\s*#\w+/ }
+		, string  : { exp: /(?:\'[^\'\\\n]*(?:\\.[^\'\\\n]*)*\')|(?:\"[^\"\\\n]*(?:\\.[^\"\\\n]*)*\")/ }
+		, number  : { exp: /\b[+-]?(?:\d*\.?\d+|\d+\.?\d*)(?:[eE][+-]?\d+)?\b/ }
+		, datatype: { exp: /\b(?:ATOM|BOOL|BOOLEAN|BYTE|CHAR|COLORREF|DWORD|DWORD32|DWORD64|DWORDLONG|DWORD_PTR|FILE|FLOAT|HACCEL|HALF_PTR|HANDLE|HBITMAP|HBRUSH|HCOLORSPACE|HCONV|HCONVLIST|HCURSOR|HDC|HDDEDATA|HDESK|HDROP|HDWP|HENHMETAFILE|HFILE|HFONT|HGDIOBJ|HGLOBAL|HHOOK|HICON|HINSTANCE|HKEY|HKL|HLOCAL|HMENU|HMETAFILE|HMODULE|HMONITOR|HPALETTE|HPEN|HRESULT|HRGN|HRSRC|HSZ|HWINSTA|HWND|INT|INT32|INT64|INT_PTR|LANGID|LCID|LCTYPE|LGRPID|LONG|LONG32|LONG64|LONGLONG|LONG_PTR|LPARAM|LPBOOL|LPBYTE|LPCOLORREF|LPCSTR|LPCTSTR|LPCVOID|LPCWSTR|LPDWORD|LPHANDLE|LPINT|LPLONG|LPSTR|LPTSTR|LPVOID|LPWORD|LPWSTR|LRESULT|PBOOL|PBOOLEAN|PBYTE|PCHAR|PCSTR|PCTSTR|PCWSTR|PDWORD32|PDWORD64|PDWORDLONG|PDWORD_PTR|PFLOAT|PHALF_PTR|PHANDLE|PHKEY|PINT|PINT32|PINT64|PINT_PTR|PLCID|PLONG|PLONG32|PLONG64|PLONGLONG|PLONG_PTR|POINTER_32|POINTER_64|PSHORT|PSIZE_T|PSSIZE_T|PSTR|PTBYTE|PTCHAR|PTSTR|PUCHAR|PUHALF_PTR|PUINT|PUINT32|PUINT64|PUINT_PTR|PULONG|PULONG32|PULONG64|PULONGLONG|PULONG_PTR|PUSHORT|PVOID|PWCHAR|PWORD|PWSTR|SC_HANDLE|SC_LOCK|SERVICE_STATUS_HANDLE|SHORT|SIZE_T|SSIZE_T|TBYTE|TCHAR|UCHAR|UHALF_PTR|UINT|UINT32|UINT64|UINT_PTR|ULONG|ULONG32|ULONG64|ULONGLONG|ULONG_PTR|USHORT|USN|VOID|WCHAR|WORD|WPARAM|_EXCEPTION_POINTERS|_FPIEEE_RECORD|_HEAPINFO|_HFILE|_PNH|__finddata64_t|__int16|__int32|__int64|__int8|__stat64|__time64_t|__timeb64|__wchar_t|__wfinddata64_t|_complex|_dev_t|_diskfree_t|_exception|_finddata_t|_finddatai64_t|_off_t|_onexit_t|_purecall_handler|_stat|_stati64|_timeb|_utimbuf|_wfinddata_t|_wfinddatai64_t|bool|char|clock_t|div_t|double|float|fpos_t|int|intptr_t|jmp_buf|lconv|ldiv_t|long|mbstate_t|ptrdiff_t|short|sig_atomic_t|signed|size_t|terminate_function|time_t|tm|uintptr_t|va_list|wchar_t|wctrans_t|wctype_t|wint_t)\b/ }
+		, keyword : { exp: /\b(?:__declspec|__exception|__finally|__try|break|case|catch|class|const|const_cast|continue|default|delete|deprecated|dllexport|dllimport|do|dynamic_cast|else|enum|explicit|extern|false|for|friend|goto|if|inline|mutable|naked|namespace|new|noinline|noreturn|nothrow|private|protected|public|register|reinterpret_cast|return|selectany|sizeof|static|static_cast|struct|switch|template|this|thread|throw|true|try|typedef|typeid|typename|union|using|uuid|virtual|void|volatile|whcar_t|while)\b/ }
+	}
+}
diff --git a/docs/js/chili/csharp.css b/docs/js/chili/csharp.css
new file mode 100644
index 00000000..ec305f1a
--- /dev/null
+++ b/docs/js/chili/csharp.css
@@ -0,0 +1,17 @@
+/*
+===============================================================================
+Chili is the jQuery code highlighter plugin
+...............................................................................
+                                               Copyright 2007 / Andrea Ercolino
+-------------------------------------------------------------------------------
+LICENSE: http://www.opensource.org/licenses/mit-license.php
+WEBSITE: http://noteslog.com/chili/
+===============================================================================
+*/
+
+.csharp .mlcom    { color: #4040c2; }
+.csharp .com      { color: green; }
+.csharp .string   { color: teal; }
+.csharp .keyword  { color: navy; font-weight: bold; }
+.csharp .preproc  { color: red; }
+.csharp .number   { color: red; }
diff --git a/docs/js/chili/csharp.js b/docs/js/chili/csharp.js
new file mode 100644
index 00000000..386e41f3
--- /dev/null
+++ b/docs/js/chili/csharp.js
@@ -0,0 +1,21 @@
+/*
+===============================================================================
+Chili is the jQuery code highlighter plugin
+...............................................................................
+                                               Copyright 2007 / Andrea Ercolino
+-------------------------------------------------------------------------------
+LICENSE: http://www.opensource.org/licenses/mit-license.php
+WEBSITE: http://noteslog.com/chili/
+===============================================================================
+*/
+
+{
+	steps: {
+		  mlcom  : { exp: /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\// }
+		, com    : { exp: /\/\/.*/ }
+		, string : { exp: /(?:\'[^\'\\\n]*(?:\\.[^\'\\\n]*)*\')|(?:\"[^\"\\\n]*(?:\\.[^\"\\\n]*)*\")/ }
+		, preproc: { exp: /^\s*#.*/ }
+		, number : { exp: /\b[+-]?(?:\d*\.?\d+|\d+\.?\d*)(?:[eE][+-]?\d+)?\b/ }
+		, keyword: { exp: /\b(?:abstract|as|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|get|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|set|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|while)\b/ }
+	}
+}
diff --git a/docs/js/chili/css.css b/docs/js/chili/css.css
new file mode 100644
index 00000000..9e82c389
--- /dev/null
+++ b/docs/js/chili/css.css
@@ -0,0 +1,17 @@
+/*
+===============================================================================
+Chili is the jQuery code highlighter plugin
+...............................................................................
+                                               Copyright 2007 / Andrea Ercolino
+-------------------------------------------------------------------------------
+LICENSE: http://www.opensource.org/licenses/mit-license.php
+WEBSITE: http://noteslog.com/chili/
+===============================================================================
+*/
+
+.css .mlcom  { color: #4040c2; }
+.css .color  { color: green; }
+.css .string { color: teal; }
+.css .attrib { color: navy; font-weight: bold; }
+.css .value  { color: blue; }
+.css .number { color: red; }
diff --git a/docs/js/chili/css.js b/docs/js/chili/css.js
new file mode 100644
index 00000000..882c168c
--- /dev/null
+++ b/docs/js/chili/css.js
@@ -0,0 +1,21 @@
+/*
+===============================================================================
+Chili is the jQuery code highlighter plugin
+...............................................................................
+                                               Copyright 2007 / Andrea Ercolino
+-------------------------------------------------------------------------------
+LICENSE: http://www.opensource.org/licenses/mit-license.php
+WEBSITE: http://noteslog.com/chili/
+===============================================================================
+*/
+
+{
+	steps: {
+		  mlcom : { exp: /\/\*[^*]*\*+(?:[^\/][^*]*\*+)*\// }
+		, string: { exp: /(?:\'[^\'\\\n]*(?:\\.[^\'\\\n]*)*\')|(?:\"[^\"\\\n]*(?:\\.[^\"\\\n]*)*\")/ }
+		, number: { exp: /(?:\b[+-]?(?:\d*\.?\d+|\d+\.?\d*))(?:%|(?:(?:px|pt|em|)\b))/ }
+		, attrib: { exp: /\b(?:z-index|x-height|word-spacing|widths|width|widows|white-space|volume|voice-family|visibility|vertical-align|units-per-em|unicode-range|unicode-bidi|text-transform|text-shadow|text-indent|text-decoration|text-align|table-layout|stress|stemv|stemh|src|speech-rate|speak-punctuation|speak-numeral|speak-header|speak|slope|size|right|richness|quotes|position|play-during|pitch-range|pitch|pause-before|pause-after|pause|page-break-inside|page-break-before|page-break-after|page|padding-top|padding-right|padding-left|padding-bottom|padding|overflow|outline-width|outline-style|outline-color|outline|orphans|min-width|min-height|max-width|max-height|mathline|marks|marker-offset|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|height|font-weight|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-family|font|float|empty-cells|elevation|display|direction|descent|definition-src|cursor|cue-before|cue-after|cue|counter-reset|counter-increment|content|color|clip|clear|centerline|caption-side|cap-height|bottom|border-width|border-top-width|border-top-style|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-left-width|border-left-style|border-left-color|border-left|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-color|border-bottom|border|bbox|baseline|background-repeat|background-position|background-image|background-color|background-attachment|background|azimuth|ascent)\b/ }
+		, value : { exp: /\b(?:xx-small|xx-large|x-soft|x-small|x-slow|x-low|x-loud|x-large|x-high|x-fast|wider|wait|w-resize|visible|url|uppercase|upper-roman|upper-latin|upper-alpha|underline|ultra-expanded|ultra-condensed|tv|tty|transparent|top|thin|thick|text-top|text-bottom|table-row-group|table-row|table-header-group|table-footer-group|table-column-group|table-column|table-cell|table-caption|sw-resize|super|sub|status-bar|static|square|spell-out|speech|solid|soft|smaller|small-caption|small-caps|small|slower|slow|silent|show|separate|semi-expanded|semi-condensed|se-resize|scroll|screen|s-resize|run-in|rtl|rightwards|right-side|right|ridge|rgb|repeat-y|repeat-x|repeat|relative|projection|print|pre|portrait|pointer|overline|outside|outset|open-quote|once|oblique|nw-resize|nowrap|normal|none|no-repeat|no-open-quote|no-close-quote|ne-resize|narrower|n-resize|move|mix|middle|message-box|medium|marker|ltr|lowercase|lower-roman|lower-latin|lower-greek|lower-alpha|lower|low|loud|local|list-item|line-through|lighter|level|leftwards|left-side|left|larger|large|landscape|justify|italic|invert|inside|inset|inline-table|inline|icon|higher|high|hide|hidden|help|hebrew|handheld|groove|format|fixed|faster|fast|far-right|far-left|fantasy|extra-expanded|extra-condensed|expanded|embossed|embed|e-resize|double|dotted|disc|digits|default|decimal-leading-zero|decimal|dashed|cursive|crosshair|cross|crop|counters|counter|continuous|condensed|compact|collapse|code|close-quote|circle|center-right|center-left|center|caption|capitalize|braille|bottom|both|bolder|bold|block|blink|bidi-override|below|behind|baseline|avoid|auto|aural|attr|armenian|always|all|absolute|above)\b/ }
+		, color : { exp: /(?:\#[a-zA-Z0-9]{3,6})|(?:yellow|white|teal|silver|red|purple|olive|navy|maroon|lime|green|gray|fuchsia|blue|black|aqua)/ }
+	}
+}
diff --git a/docs/js/chili/delphi.css b/docs/js/chili/delphi.css
new file mode 100644
index 00000000..f5311a15
--- /dev/null
+++ b/docs/js/chili/delphi.css
@@ -0,0 +1,17 @@
+/*
+===============================================================================
+Chili is the jQuery code highlighter plugin
+...............................................................................
+                                               Copyright 2007 / Andrea Ercolino
+-------------------------------------------------------------------------------
+LICENSE: http://www.opensource.org/licenses/mit-license.php
+WEBSITE: http://noteslog.com/chili/
+===============================================================================
+*/
+
+.delphi .mlcom   { color: #4040c2; }
+.delphi .com     { color: green; }
+.delphi .string  { color: teal; }
+.delphi .keyword { color: navy; font-weight: bold; }
+.delphi .direct  { color: red; }
+.delphi .number  { color: red; }
diff --git a/docs/js/chili/delphi.js b/docs/js/chili/delphi.js
new file mode 100644
index 00000000..7512795f
--- /dev/null
+++ b/docs/js/chili/delphi.js
@@ -0,0 +1,21 @@
+/*
+===============================================================================
+Chili is the jQuery code highlighter plugin
+...............................................................................
+                                               Copyright 2007 / Andrea Ercolino
+-------------------------------------------------------------------------------
+LICENSE: http://www.opensource.org/licenses/mit-license.php
+WEBSITE: http://noteslog.com/chili/
+===============================================================================
+*/
+
+{
+	steps: {
+		  mlcom  : { exp: /(?:\(\*[\s\S]*?\*\))|(?:{(?!\$)[\s\S]*?})/ }
+		, com    : { exp: /\/\/.*/ }
+		, string : { exp: /(?:\'[^\'\\\n]*(?:\\.[^\'\\\n]*)*\')/ }
+		, number : { exp: /(?:\b[+-]?(?:\d*\.?\d+|\d+\.?\d*)(?:[eE][+-]?\d+)?\b)|(?:\$[a-zA-Z0-9]+\b)/ }
+		, direct : { exp: /\{\$[a-zA-Z]+ .+\}/ }
+		, keyword: { exp: /\b(?:abs|addr|and|ansichar|ansistring|array|as|asm|begin|boolean|byte|cardinal|case|char|class|comp|const|constructor|currency|destructor|div|do|double|downto|else|end|except|exports|extended|false|file|finalization|finally|for|function|goto|if|implementation|in|inherited|initialization|int64|integer|interface|is|label|library|longint|longword|mod|nil|not|object|of|on|or|packed|pansichar|pansistring|pchar|pcurrency|pdatetime|pextended|pint64|pointer|private|procedure|program|property|protected|pshortstring|pstring|public|published|pvariant|pwidechar|pwidestring|raise|real|real48|record|repeat|set|shl|shortint|shortstring|shr|single|smallint|string|then|threadvar|to|true|try|type|unit|until|uses|val|var|varirnt|while|widechar|widestring|with|word|write|writeln|xor)\b/ }
+	}
+}
diff --git a/docs/js/chili/html.css b/docs/js/chili/html.css
new file mode 100644
index 00000000..b6876617
--- /dev/null
+++ b/docs/js/chili/html.css
@@ -0,0 +1,17 @@
+/*
+===============================================================================
+Chili is the jQuery code highlighter plugin
+...............................................................................
+                                               Copyright 2007 / Andrea Ercolino
+-------------------------------------------------------------------------------
+LICENSE: http://www.opensource.org/licenses/mit-license.php
+WEBSITE: http://noteslog.com/chili/
+===============================================================================
+*/
+
+.html .php    { color: red; font-weight: bold; }
+.html .tag    { color: navy; font-weight: bold; }
+.html .aname  { color: purple; }
+.html .avalue { color: fuchsia; }
+.html .mlcom  { color: green; }
+.html .entity { color: teal; }
diff --git a/docs/js/chili/html.js b/docs/js/chili/html.js
new file mode 100644
index 00000000..17fdf6db
--- /dev/null
+++ b/docs/js/chili/html.js
@@ -0,0 +1,23 @@
+/*
+===============================================================================
+Chili is the jQuery code highlighter plugin
+...............................................................................
+                                               Copyright 2007 / Andrea Ercolino
+-------------------------------------------------------------------------------
+LICENSE: http://www.opensource.org/licenses/mit-license.php
+WEBSITE: http://noteslog.com/chili/
+===============================================================================
+*/
+
+{
+    steps: {
+          mlcom : { exp: /\/g,'-->\n');
+				
+		$("#html pre").text(html);
+	}
+	$("pre.javascript").chili();
+	$("pre.html").chili();
+	$("pre.css").chili();
+});
\ No newline at end of file
diff --git a/docs/js/jquery-latest.js b/docs/js/jquery-latest.js
new file mode 100644
index 00000000..5d5a1d58
--- /dev/null
+++ b/docs/js/jquery-latest.js
@@ -0,0 +1,8936 @@
+/*!
+ * jQuery JavaScript Library v1.6.1
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Thu May 12 15:04:36 2011 -0400
+ */
+(function( window, undefined ) {
+
+// Use the correct document accordingly with window argument (sandbox)
+var document = window.document,
+	navigator = window.navigator,
+	location = window.location;
+var jQuery = (function() {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+		// The jQuery object is actually just the init constructor 'enhanced'
+		return new jQuery.fn.init( selector, context, rootjQuery );
+	},
+
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$,
+
+	// A central reference to the root jQuery(document)
+	rootjQuery,
+
+	// A simple way to check for HTML strings or ID strings
+	// (both of which we optimize for)
+	quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+	// Check if a string has a non-whitespace character in it
+	rnotwhite = /\S/,
+
+	// Used for trimming whitespace
+	trimLeft = /^\s+/,
+	trimRight = /\s+$/,
+
+	// Check for digits
+	rdigit = /\d/,
+
+	// Match a standalone tag
+	rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+	// JSON RegExp
+	rvalidchars = /^[\],:{}\s]*$/,
+	rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+	rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+	rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+	// Useragent RegExp
+	rwebkit = /(webkit)[ \/]([\w.]+)/,
+	ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+	rmsie = /(msie) ([\w.]+)/,
+	rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+	// Keep a UserAgent string for use with jQuery.browser
+	userAgent = navigator.userAgent,
+
+	// For matching the engine and version of the browser
+	browserMatch,
+
+	// The deferred used on DOM ready
+	readyList,
+
+	// The ready event handler
+	DOMContentLoaded,
+
+	// Save a reference to some core methods
+	toString = Object.prototype.toString,
+	hasOwn = Object.prototype.hasOwnProperty,
+	push = Array.prototype.push,
+	slice = Array.prototype.slice,
+	trim = String.prototype.trim,
+	indexOf = Array.prototype.indexOf,
+
+	// [[Class]] -> type pairs
+	class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+	constructor: jQuery,
+	init: function( selector, context, rootjQuery ) {
+		var match, elem, ret, doc;
+
+		// Handle $(""), $(null), or $(undefined)
+		if ( !selector ) {
+			return this;
+		}
+
+		// Handle $(DOMElement)
+		if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+		}
+
+		// The body element only exists once, optimize finding it
+		if ( selector === "body" && !context && document.body ) {
+			this.context = document;
+			this[0] = document.body;
+			this.selector = selector;
+			this.length = 1;
+			return this;
+		}
+
+		// Handle HTML strings
+		if ( typeof selector === "string" ) {
+			// Are we dealing with HTML string or an ID?
+			if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+				// Assume that strings that start and end with <> are HTML and skip the regex check
+				match = [ null, selector, null ];
+
+			} else {
+				match = quickExpr.exec( selector );
+			}
+
+			// Verify a match, and that no context was specified for #id
+			if ( match && (match[1] || !context) ) {
+
+				// HANDLE: $(html) -> $(array)
+				if ( match[1] ) {
+					context = context instanceof jQuery ? context[0] : context;
+					doc = (context ? context.ownerDocument || context : document);
+
+					// If a single string is passed in and it's a single tag
+					// just do a createElement and skip the rest
+					ret = rsingleTag.exec( selector );
+
+					if ( ret ) {
+						if ( jQuery.isPlainObject( context ) ) {
+							selector = [ document.createElement( ret[1] ) ];
+							jQuery.fn.attr.call( selector, context, true );
+
+						} else {
+							selector = [ doc.createElement( ret[1] ) ];
+						}
+
+					} else {
+						ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+						selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
+					}
+
+					return jQuery.merge( this, selector );
+
+				// HANDLE: $("#id")
+				} else {
+					elem = document.getElementById( match[2] );
+
+					// Check parentNode to catch when Blackberry 4.6 returns
+					// nodes that are no longer in the document #6963
+					if ( elem && elem.parentNode ) {
+						// Handle the case where IE and Opera return items
+						// by name instead of ID
+						if ( elem.id !== match[2] ) {
+							return rootjQuery.find( selector );
+						}
+
+						// Otherwise, we inject the element directly into the jQuery object
+						this.length = 1;
+						this[0] = elem;
+					}
+
+					this.context = document;
+					this.selector = selector;
+					return this;
+				}
+
+			// HANDLE: $(expr, $(...))
+			} else if ( !context || context.jquery ) {
+				return (context || rootjQuery).find( selector );
+
+			// HANDLE: $(expr, context)
+			// (which is just equivalent to: $(context).find(expr)
+			} else {
+				return this.constructor( context ).find( selector );
+			}
+
+		// HANDLE: $(function)
+		// Shortcut for document ready
+		} else if ( jQuery.isFunction( selector ) ) {
+			return rootjQuery.ready( selector );
+		}
+
+		if (selector.selector !== undefined) {
+			this.selector = selector.selector;
+			this.context = selector.context;
+		}
+
+		return jQuery.makeArray( selector, this );
+	},
+
+	// Start with an empty selector
+	selector: "",
+
+	// The current version of jQuery being used
+	jquery: "1.6.1",
+
+	// The default length of a jQuery object is 0
+	length: 0,
+
+	// The number of elements contained in the matched element set
+	size: function() {
+		return this.length;
+	},
+
+	toArray: function() {
+		return slice.call( this, 0 );
+	},
+
+	// Get the Nth element in the matched element set OR
+	// Get the whole matched element set as a clean array
+	get: function( num ) {
+		return num == null ?
+
+			// Return a 'clean' array
+			this.toArray() :
+
+			// Return just the object
+			( num < 0 ? this[ this.length + num ] : this[ num ] );
+	},
+
+	// Take an array of elements and push it onto the stack
+	// (returning the new matched element set)
+	pushStack: function( elems, name, selector ) {
+		// Build a new jQuery matched element set
+		var ret = this.constructor();
+
+		if ( jQuery.isArray( elems ) ) {
+			push.apply( ret, elems );
+
+		} else {
+			jQuery.merge( ret, elems );
+		}
+
+		// Add the old object onto the stack (as a reference)
+		ret.prevObject = this;
+
+		ret.context = this.context;
+
+		if ( name === "find" ) {
+			ret.selector = this.selector + (this.selector ? " " : "") + selector;
+		} else if ( name ) {
+			ret.selector = this.selector + "." + name + "(" + selector + ")";
+		}
+
+		// Return the newly-formed element set
+		return ret;
+	},
+
+	// Execute a callback for every element in the matched set.
+	// (You can seed the arguments with an array of args, but this is
+	// only used internally.)
+	each: function( callback, args ) {
+		return jQuery.each( this, callback, args );
+	},
+
+	ready: function( fn ) {
+		// Attach the listeners
+		jQuery.bindReady();
+
+		// Add the callback
+		readyList.done( fn );
+
+		return this;
+	},
+
+	eq: function( i ) {
+		return i === -1 ?
+			this.slice( i ) :
+			this.slice( i, +i + 1 );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	slice: function() {
+		return this.pushStack( slice.apply( this, arguments ),
+			"slice", slice.call(arguments).join(",") );
+	},
+
+	map: function( callback ) {
+		return this.pushStack( jQuery.map(this, function( elem, i ) {
+			return callback.call( elem, i, elem );
+		}));
+	},
+
+	end: function() {
+		return this.prevObject || this.constructor(null);
+	},
+
+	// For internal use only.
+	// Behaves like an Array's method, not like a jQuery method.
+	push: push,
+	sort: [].sort,
+	splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+	var options, name, src, copy, copyIsArray, clone,
+		target = arguments[0] || {},
+		i = 1,
+		length = arguments.length,
+		deep = false;
+
+	// Handle a deep copy situation
+	if ( typeof target === "boolean" ) {
+		deep = target;
+		target = arguments[1] || {};
+		// skip the boolean and the target
+		i = 2;
+	}
+
+	// Handle case when target is a string or something (possible in deep copy)
+	if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+		target = {};
+	}
+
+	// extend jQuery itself if only one argument is passed
+	if ( length === i ) {
+		target = this;
+		--i;
+	}
+
+	for ( ; i < length; i++ ) {
+		// Only deal with non-null/undefined values
+		if ( (options = arguments[ i ]) != null ) {
+			// Extend the base object
+			for ( name in options ) {
+				src = target[ name ];
+				copy = options[ name ];
+
+				// Prevent never-ending loop
+				if ( target === copy ) {
+					continue;
+				}
+
+				// Recurse if we're merging plain objects or arrays
+				if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+					if ( copyIsArray ) {
+						copyIsArray = false;
+						clone = src && jQuery.isArray(src) ? src : [];
+
+					} else {
+						clone = src && jQuery.isPlainObject(src) ? src : {};
+					}
+
+					// Never move original objects, clone them
+					target[ name ] = jQuery.extend( deep, clone, copy );
+
+				// Don't bring in undefined values
+				} else if ( copy !== undefined ) {
+					target[ name ] = copy;
+				}
+			}
+		}
+	}
+
+	// Return the modified object
+	return target;
+};
+
+jQuery.extend({
+	noConflict: function( deep ) {
+		if ( window.$ === jQuery ) {
+			window.$ = _$;
+		}
+
+		if ( deep && window.jQuery === jQuery ) {
+			window.jQuery = _jQuery;
+		}
+
+		return jQuery;
+	},
+
+	// Is the DOM ready to be used? Set to true once it occurs.
+	isReady: false,
+
+	// A counter to track how many items to wait for before
+	// the ready event fires. See #6781
+	readyWait: 1,
+
+	// Hold (or release) the ready event
+	holdReady: function( hold ) {
+		if ( hold ) {
+			jQuery.readyWait++;
+		} else {
+			jQuery.ready( true );
+		}
+	},
+
+	// Handle when the DOM is ready
+	ready: function( wait ) {
+		// Either a released hold or an DOMready/load event and not yet ready
+		if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
+			// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+			if ( !document.body ) {
+				return setTimeout( jQuery.ready, 1 );
+			}
+
+			// Remember that the DOM is ready
+			jQuery.isReady = true;
+
+			// If a normal DOM Ready event fired, decrement, and wait if need be
+			if ( wait !== true && --jQuery.readyWait > 0 ) {
+				return;
+			}
+
+			// If there are functions bound, to execute
+			readyList.resolveWith( document, [ jQuery ] );
+
+			// Trigger any bound ready events
+			if ( jQuery.fn.trigger ) {
+				jQuery( document ).trigger( "ready" ).unbind( "ready" );
+			}
+		}
+	},
+
+	bindReady: function() {
+		if ( readyList ) {
+			return;
+		}
+
+		readyList = jQuery._Deferred();
+
+		// Catch cases where $(document).ready() is called after the
+		// browser event has already occurred.
+		if ( document.readyState === "complete" ) {
+			// Handle it asynchronously to allow scripts the opportunity to delay ready
+			return setTimeout( jQuery.ready, 1 );
+		}
+
+		// Mozilla, Opera and webkit nightlies currently support this event
+		if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", jQuery.ready, false );
+
+		// If IE event model is used
+		} else if ( document.attachEvent ) {
+			// ensure firing before onload,
+			// maybe late but safe also for iframes
+			document.attachEvent( "onreadystatechange", DOMContentLoaded );
+
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", jQuery.ready );
+
+			// If IE and not a frame
+			// continually check to see if the document is ready
+			var toplevel = false;
+
+			try {
+				toplevel = window.frameElement == null;
+			} catch(e) {}
+
+			if ( document.documentElement.doScroll && toplevel ) {
+				doScrollCheck();
+			}
+		}
+	},
+
+	// See test/unit/core.js for details concerning isFunction.
+	// Since version 1.3, DOM methods and functions like alert
+	// aren't supported. They return false on IE (#2968).
+	isFunction: function( obj ) {
+		return jQuery.type(obj) === "function";
+	},
+
+	isArray: Array.isArray || function( obj ) {
+		return jQuery.type(obj) === "array";
+	},
+
+	// A crude way of determining if an object is a window
+	isWindow: function( obj ) {
+		return obj && typeof obj === "object" && "setInterval" in obj;
+	},
+
+	isNaN: function( obj ) {
+		return obj == null || !rdigit.test( obj ) || isNaN( obj );
+	},
+
+	type: function( obj ) {
+		return obj == null ?
+			String( obj ) :
+			class2type[ toString.call(obj) ] || "object";
+	},
+
+	isPlainObject: function( obj ) {
+		// Must be an Object.
+		// Because of IE, we also have to check the presence of the constructor property.
+		// Make sure that DOM nodes and window objects don't pass through, as well
+		if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+			return false;
+		}
+
+		// Not own constructor property must be Object
+		if ( obj.constructor &&
+			!hasOwn.call(obj, "constructor") &&
+			!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+			return false;
+		}
+
+		// Own properties are enumerated firstly, so to speed up,
+		// if last one is own, then all properties are own.
+
+		var key;
+		for ( key in obj ) {}
+
+		return key === undefined || hasOwn.call( obj, key );
+	},
+
+	isEmptyObject: function( obj ) {
+		for ( var name in obj ) {
+			return false;
+		}
+		return true;
+	},
+
+	error: function( msg ) {
+		throw msg;
+	},
+
+	parseJSON: function( data ) {
+		if ( typeof data !== "string" || !data ) {
+			return null;
+		}
+
+		// Make sure leading/trailing whitespace is removed (IE can't handle it)
+		data = jQuery.trim( data );
+
+		// Attempt to parse using the native JSON parser first
+		if ( window.JSON && window.JSON.parse ) {
+			return window.JSON.parse( data );
+		}
+
+		// Make sure the incoming data is actual JSON
+		// Logic borrowed from http://json.org/json2.js
+		if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+			.replace( rvalidtokens, "]" )
+			.replace( rvalidbraces, "")) ) {
+
+			return (new Function( "return " + data ))();
+
+		}
+		jQuery.error( "Invalid JSON: " + data );
+	},
+
+	// Cross-browser xml parsing
+	// (xml & tmp used internally)
+	parseXML: function( data , xml , tmp ) {
+
+		if ( window.DOMParser ) { // Standard
+			tmp = new DOMParser();
+			xml = tmp.parseFromString( data , "text/xml" );
+		} else { // IE
+			xml = new ActiveXObject( "Microsoft.XMLDOM" );
+			xml.async = "false";
+			xml.loadXML( data );
+		}
+
+		tmp = xml.documentElement;
+
+		if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
+			jQuery.error( "Invalid XML: " + data );
+		}
+
+		return xml;
+	},
+
+	noop: function() {},
+
+	// Evaluates a script in a global context
+	// Workarounds based on findings by Jim Driscoll
+	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+	globalEval: function( data ) {
+		if ( data && rnotwhite.test( data ) ) {
+			// We use execScript on Internet Explorer
+			// We use an anonymous function so that context is window
+			// rather than jQuery in Firefox
+			( window.execScript || function( data ) {
+				window[ "eval" ].call( window, data );
+			} )( data );
+		}
+	},
+
+	nodeName: function( elem, name ) {
+		return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+	},
+
+	// args is for internal usage only
+	each: function( object, callback, args ) {
+		var name, i = 0,
+			length = object.length,
+			isObj = length === undefined || jQuery.isFunction( object );
+
+		if ( args ) {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.apply( object[ name ], args ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( ; i < length; ) {
+					if ( callback.apply( object[ i++ ], args ) === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( isObj ) {
+				for ( name in object ) {
+					if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( ; i < length; ) {
+					if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
+						break;
+					}
+				}
+			}
+		}
+
+		return object;
+	},
+
+	// Use native String.trim function wherever possible
+	trim: trim ?
+		function( text ) {
+			return text == null ?
+				"" :
+				trim.call( text );
+		} :
+
+		// Otherwise use our own trimming functionality
+		function( text ) {
+			return text == null ?
+				"" :
+				text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
+		},
+
+	// results is for internal usage only
+	makeArray: function( array, results ) {
+		var ret = results || [];
+
+		if ( array != null ) {
+			// The window, strings (and functions) also have 'length'
+			// The extra typeof function check is to prevent crashes
+			// in Safari 2 (See: #3039)
+			// Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+			var type = jQuery.type( array );
+
+			if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
+				push.call( ret, array );
+			} else {
+				jQuery.merge( ret, array );
+			}
+		}
+
+		return ret;
+	},
+
+	inArray: function( elem, array ) {
+
+		if ( indexOf ) {
+			return indexOf.call( array, elem );
+		}
+
+		for ( var i = 0, length = array.length; i < length; i++ ) {
+			if ( array[ i ] === elem ) {
+				return i;
+			}
+		}
+
+		return -1;
+	},
+
+	merge: function( first, second ) {
+		var i = first.length,
+			j = 0;
+
+		if ( typeof second.length === "number" ) {
+			for ( var l = second.length; j < l; j++ ) {
+				first[ i++ ] = second[ j ];
+			}
+
+		} else {
+			while ( second[j] !== undefined ) {
+				first[ i++ ] = second[ j++ ];
+			}
+		}
+
+		first.length = i;
+
+		return first;
+	},
+
+	grep: function( elems, callback, inv ) {
+		var ret = [], retVal;
+		inv = !!inv;
+
+		// Go through the array, only saving the items
+		// that pass the validator function
+		for ( var i = 0, length = elems.length; i < length; i++ ) {
+			retVal = !!callback( elems[ i ], i );
+			if ( inv !== retVal ) {
+				ret.push( elems[ i ] );
+			}
+		}
+
+		return ret;
+	},
+
+	// arg is for internal usage only
+	map: function( elems, callback, arg ) {
+		var value, key, ret = [],
+			i = 0,
+			length = elems.length,
+			// jquery objects are treated as arrays
+			isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
+
+		// Go through the array, translating each of the items to their
+		if ( isArray ) {
+			for ( ; i < length; i++ ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+
+		// Go through every key on the object,
+		} else {
+			for ( key in elems ) {
+				value = callback( elems[ key ], key, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+		}
+
+		// Flatten any nested arrays
+		return ret.concat.apply( [], ret );
+	},
+
+	// A global GUID counter for objects
+	guid: 1,
+
+	// Bind a function to a context, optionally partially applying any
+	// arguments.
+	proxy: function( fn, context ) {
+		if ( typeof context === "string" ) {
+			var tmp = fn[ context ];
+			context = fn;
+			fn = tmp;
+		}
+
+		// Quick check to determine if target is callable, in the spec
+		// this throws a TypeError, but we will just return undefined.
+		if ( !jQuery.isFunction( fn ) ) {
+			return undefined;
+		}
+
+		// Simulated bind
+		var args = slice.call( arguments, 2 ),
+			proxy = function() {
+				return fn.apply( context, args.concat( slice.call( arguments ) ) );
+			};
+
+		// Set the guid of unique handler to the same of original handler, so it can be removed
+		proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+
+		return proxy;
+	},
+
+	// Mutifunctional method to get and set values to a collection
+	// The value/s can be optionally by executed if its a function
+	access: function( elems, key, value, exec, fn, pass ) {
+		var length = elems.length;
+
+		// Setting many attributes
+		if ( typeof key === "object" ) {
+			for ( var k in key ) {
+				jQuery.access( elems, k, key[k], exec, fn, value );
+			}
+			return elems;
+		}
+
+		// Setting one attribute
+		if ( value !== undefined ) {
+			// Optionally, function values get executed if exec is true
+			exec = !pass && exec && jQuery.isFunction(value);
+
+			for ( var i = 0; i < length; i++ ) {
+				fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+			}
+
+			return elems;
+		}
+
+		// Getting an attribute
+		return length ? fn( elems[0], key ) : undefined;
+	},
+
+	now: function() {
+		return (new Date()).getTime();
+	},
+
+	// Use of jQuery.browser is frowned upon.
+	// More details: http://docs.jquery.com/Utilities/jQuery.browser
+	uaMatch: function( ua ) {
+		ua = ua.toLowerCase();
+
+		var match = rwebkit.exec( ua ) ||
+			ropera.exec( ua ) ||
+			rmsie.exec( ua ) ||
+			ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
+			[];
+
+		return { browser: match[1] || "", version: match[2] || "0" };
+	},
+
+	sub: function() {
+		function jQuerySub( selector, context ) {
+			return new jQuerySub.fn.init( selector, context );
+		}
+		jQuery.extend( true, jQuerySub, this );
+		jQuerySub.superclass = this;
+		jQuerySub.fn = jQuerySub.prototype = this();
+		jQuerySub.fn.constructor = jQuerySub;
+		jQuerySub.sub = this.sub;
+		jQuerySub.fn.init = function init( selector, context ) {
+			if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+				context = jQuerySub( context );
+			}
+
+			return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+		};
+		jQuerySub.fn.init.prototype = jQuerySub.fn;
+		var rootjQuerySub = jQuerySub(document);
+		return jQuerySub;
+	},
+
+	browser: {}
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+	jQuery.browser[ browserMatch.browser ] = true;
+	jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+	jQuery.browser.safari = true;
+}
+
+// IE doesn't match non-breaking spaces with \s
+if ( rnotwhite.test( "\xA0" ) ) {
+	trimLeft = /^[\s\xA0]+/;
+	trimRight = /[\s\xA0]+$/;
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+	DOMContentLoaded = function() {
+		document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+		jQuery.ready();
+	};
+
+} else if ( document.attachEvent ) {
+	DOMContentLoaded = function() {
+		// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+		if ( document.readyState === "complete" ) {
+			document.detachEvent( "onreadystatechange", DOMContentLoaded );
+			jQuery.ready();
+		}
+	};
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+	if ( jQuery.isReady ) {
+		return;
+	}
+
+	try {
+		// If IE is used, use the trick by Diego Perini
+		// http://javascript.nwbox.com/IEContentLoaded/
+		document.documentElement.doScroll("left");
+	} catch(e) {
+		setTimeout( doScrollCheck, 1 );
+		return;
+	}
+
+	// and execute any waiting functions
+	jQuery.ready();
+}
+
+// Expose jQuery to the global object
+return jQuery;
+
+})();
+
+
+var // Promise methods
+	promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
+	// Static reference to slice
+	sliceDeferred = [].slice;
+
+jQuery.extend({
+	// Create a simple deferred (one callbacks list)
+	_Deferred: function() {
+		var // callbacks list
+			callbacks = [],
+			// stored [ context , args ]
+			fired,
+			// to avoid firing when already doing so
+			firing,
+			// flag to know if the deferred has been cancelled
+			cancelled,
+			// the deferred itself
+			deferred  = {
+
+				// done( f1, f2, ...)
+				done: function() {
+					if ( !cancelled ) {
+						var args = arguments,
+							i,
+							length,
+							elem,
+							type,
+							_fired;
+						if ( fired ) {
+							_fired = fired;
+							fired = 0;
+						}
+						for ( i = 0, length = args.length; i < length; i++ ) {
+							elem = args[ i ];
+							type = jQuery.type( elem );
+							if ( type === "array" ) {
+								deferred.done.apply( deferred, elem );
+							} else if ( type === "function" ) {
+								callbacks.push( elem );
+							}
+						}
+						if ( _fired ) {
+							deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
+						}
+					}
+					return this;
+				},
+
+				// resolve with given context and args
+				resolveWith: function( context, args ) {
+					if ( !cancelled && !fired && !firing ) {
+						// make sure args are available (#8421)
+						args = args || [];
+						firing = 1;
+						try {
+							while( callbacks[ 0 ] ) {
+								callbacks.shift().apply( context, args );
+							}
+						}
+						finally {
+							fired = [ context, args ];
+							firing = 0;
+						}
+					}
+					return this;
+				},
+
+				// resolve with this as context and given arguments
+				resolve: function() {
+					deferred.resolveWith( this, arguments );
+					return this;
+				},
+
+				// Has this deferred been resolved?
+				isResolved: function() {
+					return !!( firing || fired );
+				},
+
+				// Cancel
+				cancel: function() {
+					cancelled = 1;
+					callbacks = [];
+					return this;
+				}
+			};
+
+		return deferred;
+	},
+
+	// Full fledged deferred (two callbacks list)
+	Deferred: function( func ) {
+		var deferred = jQuery._Deferred(),
+			failDeferred = jQuery._Deferred(),
+			promise;
+		// Add errorDeferred methods, then and promise
+		jQuery.extend( deferred, {
+			then: function( doneCallbacks, failCallbacks ) {
+				deferred.done( doneCallbacks ).fail( failCallbacks );
+				return this;
+			},
+			always: function() {
+				return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
+			},
+			fail: failDeferred.done,
+			rejectWith: failDeferred.resolveWith,
+			reject: failDeferred.resolve,
+			isRejected: failDeferred.isResolved,
+			pipe: function( fnDone, fnFail ) {
+				return jQuery.Deferred(function( newDefer ) {
+					jQuery.each( {
+						done: [ fnDone, "resolve" ],
+						fail: [ fnFail, "reject" ]
+					}, function( handler, data ) {
+						var fn = data[ 0 ],
+							action = data[ 1 ],
+							returned;
+						if ( jQuery.isFunction( fn ) ) {
+							deferred[ handler ](function() {
+								returned = fn.apply( this, arguments );
+								if ( returned && jQuery.isFunction( returned.promise ) ) {
+									returned.promise().then( newDefer.resolve, newDefer.reject );
+								} else {
+									newDefer[ action ]( returned );
+								}
+							});
+						} else {
+							deferred[ handler ]( newDefer[ action ] );
+						}
+					});
+				}).promise();
+			},
+			// Get a promise for this deferred
+			// If obj is provided, the promise aspect is added to the object
+			promise: function( obj ) {
+				if ( obj == null ) {
+					if ( promise ) {
+						return promise;
+					}
+					promise = obj = {};
+				}
+				var i = promiseMethods.length;
+				while( i-- ) {
+					obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
+				}
+				return obj;
+			}
+		});
+		// Make sure only one callback list will be used
+		deferred.done( failDeferred.cancel ).fail( deferred.cancel );
+		// Unexpose cancel
+		delete deferred.cancel;
+		// Call given func if any
+		if ( func ) {
+			func.call( deferred, deferred );
+		}
+		return deferred;
+	},
+
+	// Deferred helper
+	when: function( firstParam ) {
+		var args = arguments,
+			i = 0,
+			length = args.length,
+			count = length,
+			deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
+				firstParam :
+				jQuery.Deferred();
+		function resolveFunc( i ) {
+			return function( value ) {
+				args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
+				if ( !( --count ) ) {
+					// Strange bug in FF4:
+					// Values changed onto the arguments object sometimes end up as undefined values
+					// outside the $.when method. Cloning the object into a fresh array solves the issue
+					deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
+				}
+			};
+		}
+		if ( length > 1 ) {
+			for( ; i < length; i++ ) {
+				if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
+					args[ i ].promise().then( resolveFunc(i), deferred.reject );
+				} else {
+					--count;
+				}
+			}
+			if ( !count ) {
+				deferred.resolveWith( deferred, args );
+			}
+		} else if ( deferred !== firstParam ) {
+			deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
+		}
+		return deferred.promise();
+	}
+});
+
+
+
+jQuery.support = (function() {
+
+	var div = document.createElement( "div" ),
+		documentElement = document.documentElement,
+		all,
+		a,
+		select,
+		opt,
+		input,
+		marginDiv,
+		support,
+		fragment,
+		body,
+		bodyStyle,
+		tds,
+		events,
+		eventName,
+		i,
+		isSupported;
+
+	// Preliminary tests
+	div.setAttribute("className", "t");
+	div.innerHTML = "   
a"; + + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; + + // Can't get basic test support + if ( !all || !all.length || !a ) { + return {}; + } + + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName( "tbody" ).length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName( "link" ).length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute( "href" ) === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.55$/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", function click() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + div.detachEvent( "onclick", click ); + }); + div.cloneNode( true ).fireEvent( "onclick" ); + } + + // Check if a radio maintains it's value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; + + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.firstChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + div.innerHTML = ""; + + // Figure out if the W3C box model works as expected + div.style.width = div.style.paddingLeft = "1px"; + + // We use our own, invisible, body + body = document.createElement( "body" ); + bodyStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0, + // Set background to avoid IE crashes when removing (#9028) + background: "none" + }; + for ( i in bodyStyle ) { + body.style[ i ] = bodyStyle[ i ]; + } + body.appendChild( div ); + documentElement.insertBefore( body, documentElement.firstChild ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + support.boxModel = div.offsetWidth === 2; + + if ( "zoom" in div.style ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } + + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE < 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + div.innerHTML = ""; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( document.defaultView && document.defaultView.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Remove the body element we added + body.innerHTML = ""; + documentElement.removeChild( body ); + + // Technique from Juriy Zaytsev + // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + } ) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + return support; +})(); + +// Keep track of boxModel +jQuery.boxModel = jQuery.support.boxModel; + + + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([a-z])([A-Z])/g; + +jQuery.extend({ + cache: {}, + + // Please use with caution + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ jQuery.expando ] = id = ++jQuery.uuid; + } else { + id = jQuery.expando; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery + // metadata on plain JS objects when the object is serialized using + // JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name); + } else { + cache[ id ] = jQuery.extend(cache[ id ], name); + } + } + + thisCache = cache[ id ]; + + // Internal jQuery data is stored in a separate object inside the object's data + // cache in order to avoid key collisions between internal data and user-defined + // data + if ( pvt ) { + if ( !thisCache[ internalKey ] ) { + thisCache[ internalKey ] = {}; + } + + thisCache = thisCache[ internalKey ]; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should + // not attempt to inspect the internal events object using jQuery.data, as this + // internal data object is undocumented and subject to change. + if ( name === "events" && !thisCache[name] ) { + return thisCache[ internalKey ] && thisCache[ internalKey ].events; + } + + return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var internalKey = jQuery.expando, isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + + // See jQuery.data for more information + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ]; + + if ( thisCache ) { + delete thisCache[ name ]; + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !isEmptyDataObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( pvt ) { + delete cache[ id ][ internalKey ]; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject(cache[ id ]) ) { + return; + } + } + + var internalCache = cache[ id ][ internalKey ]; + + // Browsers that fail expando deletion also refuse to delete expandos on + // the window, but it will allow it on all other JS objects; other browsers + // don't care + if ( jQuery.support.deleteExpando || cache != window ) { + delete cache[ id ]; + } else { + cache[ id ] = null; + } + + // We destroyed the entire user cache at once because it's faster than + // iterating through each key, but we need to continue to persist internal + // data if it existed + if ( internalCache ) { + cache[ id ] = {}; + // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery + // metadata on plain JS objects when the object is serialized using + // JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + + cache[ id ][ internalKey ] = internalCache; + + // Otherwise, we need to eliminate the expando on the node to avoid + // false lookups in the cache for entries that no longer exist + } else if ( isNode ) { + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( jQuery.support.deleteExpando ) { + delete elem[ jQuery.expando ]; + } else if ( elem.removeAttribute ) { + elem.removeAttribute( jQuery.expando ); + } else { + elem[ jQuery.expando ] = null; + } + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + if ( elem.nodeName ) { + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + + if ( match ) { + return !(match === true || elem.getAttribute("classid") !== match); + } + } + + return true; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var data = null; + + if ( typeof key === "undefined" ) { + if ( this.length ) { + data = jQuery.data( this[0] ); + + if ( this[0].nodeType === 1 ) { + var attr = this[0].attributes, name; + for ( var i = 0, l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( this[0], name, data[ name ] ); + } + } + } + } + + return data; + + } else if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + var parts = key.split("."); + parts[1] = parts[1] ? "." + parts[1] : ""; + + if ( value === undefined ) { + data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); + + // Try to fetch any internally stored data first + if ( data === undefined && this.length ) { + data = jQuery.data( this[0], key ); + data = dataAttr( this[0], key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + + } else { + return this.each(function() { + var $this = jQuery( this ), + args = [ parts[0], value ]; + + $this.triggerHandler( "setData" + parts[1] + "!", args ); + jQuery.data( this, key, value ); + $this.triggerHandler( "changeData" + parts[1] + "!", args ); + }); + } + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + !jQuery.isNaN( data ) ? parseFloat( data ) : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON +// property to be considered empty objects; this property always exists in +// order to make sure JSON.stringify does not expose internal metadata +function isEmptyDataObject( obj ) { + for ( var name in obj ) { + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + + + + +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery.data( elem, deferDataKey, undefined, true ); + if ( defer && + ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) && + ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery.data( elem, queueDataKey, undefined, true ) && + !jQuery.data( elem, markDataKey, undefined, true ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.resolve(); + } + }, 0 ); + } +} + +jQuery.extend({ + + _mark: function( elem, type ) { + if ( elem ) { + type = (type || "fx") + "mark"; + jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true ); + } + }, + + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 ); + if ( count ) { + jQuery.data( elem, key, count, true ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, + + queue: function( elem, type, data ) { + if ( elem ) { + type = (type || "fx") + "queue"; + var q = jQuery.data( elem, type, undefined, true ); + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery.data( elem, type, jQuery.makeArray(data), true ); + } else { + q.push( data ); + } + } + return q || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + fn = queue.shift(), + defer; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + } + + if ( fn ) { + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift("inprogress"); + } + + fn.call(elem, function() { + jQuery.dequeue(elem, type); + }); + } + + if ( !queue.length ) { + jQuery.removeData( elem, type + "queue", true ); + handleQueueMarkDefer( elem, type, "queue" ); + } + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + } + + if ( data === undefined ) { + return jQuery.queue( this[0], type ); + } + return this.each(function() { + var queue = jQuery.queue( this, type, data ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[time] || time : time; + type = type || "fx"; + + return this.queue( type, function() { + var elem = this; + setTimeout(function() { + jQuery.dequeue( elem, type ); + }, time ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) { + count++; + tmp.done( resolve ); + } + } + resolve(); + return defer.promise(); + } +}); + + + + +var rclass = /[\n\t\r]/g, + rspace = /\s+/, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea)?$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + rinvalidChar = /\:/, + formHook, boolHook; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.attr ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.prop ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this); + self.addClass( value.call(this, i, self.attr("class") || "") ); + }); + } + + if ( value && typeof value === "string" ) { + var classNames = (value || "").split( rspace ); + + for ( var i = 0, l = this.length; i < l; i++ ) { + var elem = this[i]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className ) { + elem.className = value; + + } else { + var className = " " + elem.className + " ", + setClass = elem.className; + + for ( var c = 0, cl = classNames.length; c < cl; c++ ) { + if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { + setClass += " " + classNames[c]; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + self.removeClass( value.call(this, i, self.attr("class")) ); + }); + } + + if ( (value && typeof value === "string") || value === undefined ) { + var classNames = (value || "").split( rspace ); + + for ( var i = 0, l = this.length; i < l; i++ ) { + var elem = this[i]; + + if ( elem.nodeType === 1 && elem.className ) { + if ( value ) { + var className = (" " + elem.className + " ").replace(rclass, " "); + for ( var c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[c] + " ", " "); + } + elem.className = jQuery.trim( className ); + + } else { + elem.className = ""; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this); + self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space seperated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " "; + for ( var i = 0, l = this.length; i < l; i++ ) { + if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + return (elem.value || "").replace(rreturn, ""); + } + + return undefined; + } + + var isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var self = jQuery(this), val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attrFn: { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true + }, + + attrFix: { + // Always normalize to ensure hook usage + tabindex: "tabIndex" + }, + + attr: function( elem, name, value, pass ) { + var nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return undefined; + } + + if ( pass && name in jQuery.attrFn ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( !("getAttribute" in elem) ) { + return jQuery.prop( elem, name, value ); + } + + var ret, hooks, + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // Normalize the name if needed + name = notxml && jQuery.attrFix[ name ] || name; + + hooks = jQuery.attrHooks[ name ]; + + if ( !hooks ) { + // Use boolHook for boolean attributes + if ( rboolean.test( name ) && + (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) { + + hooks = boolHook; + + // Use formHook for forms and if the name contains certain characters + } else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) { + hooks = formHook; + } + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return undefined; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml ) { + return hooks.get( elem, name ); + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, name ) { + var propName; + if ( elem.nodeType === 1 ) { + name = jQuery.attrFix[ name ] || name; + + if ( jQuery.support.getSetAttribute ) { + // Use removeAttribute in browsers that support it + elem.removeAttribute( name ); + } else { + jQuery.attr( elem, name, "" ); + elem.removeAttributeNode( elem.getAttributeNode( name ) ); + } + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) { + elem[ propName ] = false; + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabIndex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return undefined; + } + + var ret, hooks, + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // Try to normalize/fix the name + name = notxml && jQuery.propFix[ name ] || name; + + hooks = jQuery.propHooks[ name ]; + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return (elem[ name ] = value); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: {} +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + return elem[ jQuery.propFix[ name ] || name ] ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = value; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// Use the value property for back compat +// Use the formHook for button elements in IE6/7 (#1954) +jQuery.attrHooks.value = { + get: function( elem, name ) { + if ( formHook && jQuery.nodeName( elem, "button" ) ) { + return formHook.get( elem, name ); + } + return elem.value; + }, + set: function( elem, value, name ) { + if ( formHook && jQuery.nodeName( elem, "button" ) ) { + return formHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !jQuery.support.getSetAttribute ) { + + // propFix is more comprehensive and contains all fixes + jQuery.attrFix = jQuery.propFix; + + // Use this for any attribute on a form in IE6/7 + formHook = jQuery.attrHooks.name = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + // Return undefined if nodeValue is empty string + return ret && ret.nodeValue !== "" ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Check form objects in IE (multiple bugs related) + // Only use nodeValue if the attribute node exists on the form + var ret = elem.getAttributeNode( name ); + if ( ret ) { + ret.nodeValue = value; + return value; + } + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return (elem.style.cssText = "" + value); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }); +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0); + } + } + }); +}); + + + + +var hasOwn = Object.prototype.hasOwnProperty, + rnamespaces = /\.(.*)$/, + rformElems = /^(?:textarea|input|select)$/i, + rperiod = /\./g, + rspaces = / /g, + rescape = /[^\w\s.|`]/g, + fcleanup = function( nm ) { + return nm.replace(rescape, "\\$&"); + }; + +/* + * A number of helper functions used for managing events. + * Many of the ideas behind this code originated from + * Dean Edwards' addEvent library. + */ +jQuery.event = { + + // Bind an event to an element + // Original by Dean Edwards + add: function( elem, types, handler, data ) { + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + if ( handler === false ) { + handler = returnFalse; + } else if ( !handler ) { + // Fixes bug #7229. Fix recommended by jdalton + return; + } + + var handleObjIn, handleObj; + + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + } + + // Make sure that the function being executed has a unique ID + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure + var elemData = jQuery._data( elem ); + + // If no elemData is found then we must be trying to bind to one of the + // banned noData elements + if ( !elemData ) { + return; + } + + var events = elemData.events, + eventHandle = elemData.handle; + + if ( !events ) { + elemData.events = events = {}; + } + + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.handle.apply( eventHandle.elem, arguments ) : + undefined; + }; + } + + // Add elem as a property of the handle function + // This is to prevent a memory leak with non-native events in IE. + eventHandle.elem = elem; + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = types.split(" "); + + var type, i = 0, namespaces; + + while ( (type = types[ i++ ]) ) { + handleObj = handleObjIn ? + jQuery.extend({}, handleObjIn) : + { handler: handler, data: data }; + + // Namespaced event handlers + if ( type.indexOf(".") > -1 ) { + namespaces = type.split("."); + type = namespaces.shift(); + handleObj.namespace = namespaces.slice(0).sort().join("."); + + } else { + namespaces = []; + handleObj.namespace = ""; + } + + handleObj.type = type; + if ( !handleObj.guid ) { + handleObj.guid = handler.guid; + } + + // Get the current list of functions bound to this event + var handlers = events[ type ], + special = jQuery.event.special[ type ] || {}; + + // Init the event handler queue + if ( !handlers ) { + handlers = events[ type ] = []; + + // Check for a special event handler + // Only use addEventListener/attachEvent if the special + // events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add the function to the element's handler list + handlers.push( handleObj ); + + // Keep track of which events have been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, pos ) { + // don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + if ( handler === false ) { + handler = returnFalse; + } + + var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ), + events = elemData && elemData.events; + + if ( !elemData || !events ) { + return; + } + + // types is actually an event object here + if ( types && types.type ) { + handler = types.handler; + types = types.type; + } + + // Unbind all events for the element + if ( !types || typeof types === "string" && types.charAt(0) === "." ) { + types = types || ""; + + for ( type in events ) { + jQuery.event.remove( elem, type + types ); + } + + return; + } + + // Handle multiple events separated by a space + // jQuery(...).unbind("mouseover mouseout", fn); + types = types.split(" "); + + while ( (type = types[ i++ ]) ) { + origType = type; + handleObj = null; + all = type.indexOf(".") < 0; + namespaces = []; + + if ( !all ) { + // Namespaced event handlers + namespaces = type.split("."); + type = namespaces.shift(); + + namespace = new RegExp("(^|\\.)" + + jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)"); + } + + eventType = events[ type ]; + + if ( !eventType ) { + continue; + } + + if ( !handler ) { + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( all || namespace.test( handleObj.namespace ) ) { + jQuery.event.remove( elem, origType, handleObj.handler, j ); + eventType.splice( j--, 1 ); + } + } + + continue; + } + + special = jQuery.event.special[ type ] || {}; + + for ( j = pos || 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( handler.guid === handleObj.guid ) { + // remove the given handler for the given type + if ( all || namespace.test( handleObj.namespace ) ) { + if ( pos == null ) { + eventType.splice( j--, 1 ); + } + + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + + if ( pos != null ) { + break; + } + } + } + + // remove generic event handler if no more handlers exist + if ( eventType.length === 0 || pos != null && eventType.length === 1 ) { + if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + ret = null; + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + var handle = elemData.handle; + if ( handle ) { + handle.elem = null; + } + + delete elemData.events; + delete elemData.handle; + + if ( jQuery.isEmptyObject( elemData ) ) { + jQuery.removeData( elem, undefined, true ); + } + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Event object or event type + var type = event.type || event, + namespaces = [], + exclusive; + + if ( type.indexOf("!") >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.exclusive = exclusive; + event.namespace = namespaces.join("."); + event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)"); + + // triggerHandler() and global events don't bubble or run the default action + if ( onlyHandlers || !elem ) { + event.preventDefault(); + event.stopPropagation(); + } + + // Handle a global trigger + if ( !elem ) { + // TODO: Stop taunting the data cache; remove global events and always attach to document + jQuery.each( jQuery.cache, function() { + // internalKey variable is just used to make it easier to find + // and potentially change this stuff later; currently it just + // points to jQuery.expando + var internalKey = jQuery.expando, + internalCache = this[ internalKey ]; + if ( internalCache && internalCache.events && internalCache.events[ type ] ) { + jQuery.event.trigger( event, data, internalCache.handle.elem ); + } + }); + return; + } + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + event.target = elem; + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + var cur = elem, + // IE doesn't like method names with a colon (#3533, #8272) + ontype = type.indexOf(":") < 0 ? "on" + type : ""; + + // Fire event on the current element, then bubble up the DOM tree + do { + var handle = jQuery._data( cur, "handle" ); + + event.currentTarget = cur; + if ( handle ) { + handle.apply( cur, data ); + } + + // Trigger an inline bound script + if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) { + event.result = false; + event.preventDefault(); + } + + // Bubble up to document, then to window + cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window; + } while ( cur && !event.isPropagationStopped() ); + + // If nobody prevented the default action, do it now + if ( !event.isDefaultPrevented() ) { + var old, + special = jQuery.event.special[ type ] || {}; + + if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction)() check here because IE6/7 fails that test. + // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch. + try { + if ( ontype && elem[ type ] ) { + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + jQuery.event.triggered = type; + elem[ type ](); + } + } catch ( ieError ) {} + + if ( old ) { + elem[ ontype ] = old; + } + + jQuery.event.triggered = undefined; + } + } + + return event.result; + }, + + handle: function( event ) { + event = jQuery.event.fix( event || window.event ); + // Snapshot the handlers list since a called handler may add/remove events. + var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0), + run_all = !event.exclusive && !event.namespace, + args = Array.prototype.slice.call( arguments, 0 ); + + // Use the fix-ed Event rather than the (read-only) native event + args[0] = event; + event.currentTarget = this; + + for ( var j = 0, l = handlers.length; j < l; j++ ) { + var handleObj = handlers[ j ]; + + // Triggered event must 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event. + if ( run_all || event.namespace_re.test( handleObj.namespace ) ) { + // Pass in a reference to the handler function itself + // So that we can later remove it + event.handler = handleObj.handler; + event.data = handleObj.data; + event.handleObj = handleObj; + + var ret = handleObj.handler.apply( this, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + + if ( event.isImmediatePropagationStopped() ) { + break; + } + } + } + return event.result; + }, + + props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "), + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // store a copy of the original event object + // and "clone" to set read-only properties + var originalEvent = event; + event = jQuery.Event( originalEvent ); + + for ( var i = this.props.length, prop; i; ) { + prop = this.props[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary + if ( !event.target ) { + // Fixes #1925 where srcElement might not be defined either + event.target = event.srcElement || document; + } + + // check if target is a textnode (safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && event.fromElement ) { + event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; + } + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && event.clientX != null ) { + var eventDocument = event.target.ownerDocument || document, + doc = eventDocument.documentElement, + body = eventDocument.body; + + event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); + event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); + } + + // Add which for key events + if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { + event.which = event.charCode != null ? event.charCode : event.keyCode; + } + + // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) + if ( !event.metaKey && event.ctrlKey ) { + event.metaKey = event.ctrlKey; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && event.button !== undefined ) { + event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); + } + + return event; + }, + + // Deprecated, use jQuery.guid instead + guid: 1E8, + + // Deprecated, use jQuery.proxy instead + proxy: jQuery.proxy, + + special: { + ready: { + // Make sure the ready event is setup + setup: jQuery.bindReady, + teardown: jQuery.noop + }, + + live: { + add: function( handleObj ) { + jQuery.event.add( this, + liveConvert( handleObj.origType, handleObj.selector ), + jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) ); + }, + + remove: function( handleObj ) { + jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj ); + } + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + if ( elem.detachEvent ) { + elem.detachEvent( "on" + type, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !this.preventDefault ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // timeStamp is buggy for some events on Firefox(#3843) + // So we won't rely on the native value + this.timeStamp = jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Checks if an event happened on an element within another element +// Used in jQuery.event.special.mouseenter and mouseleave handlers +var withinElement = function( event ) { + // Check if mouse(over|out) are still within the same parent element + var parent = event.relatedTarget; + + // set the correct event type + event.type = event.data; + + // Firefox sometimes assigns relatedTarget a XUL element + // which we cannot access the parentNode property of + try { + + // Chrome does something similar, the parentNode property + // can be accessed but is null. + if ( parent && parent !== document && !parent.parentNode ) { + return; + } + + // Traverse up the tree + while ( parent && parent !== this ) { + parent = parent.parentNode; + } + + if ( parent !== this ) { + // handle event if we actually just moused on to a non sub-element + jQuery.event.handle.apply( this, arguments ); + } + + // assuming we've left the element since we most likely mousedover a xul element + } catch(e) { } +}, + +// In case of event delegation, we only need to rename the event.type, +// liveHandler will take care of the rest. +delegate = function( event ) { + event.type = event.data; + jQuery.event.handle.apply( this, arguments ); +}; + +// Create mouseenter and mouseleave events +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + setup: function( data ) { + jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); + }, + teardown: function( data ) { + jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); + } + }; +}); + +// submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function( data, namespaces ) { + if ( !jQuery.nodeName( this, "form" ) ) { + jQuery.event.add(this, "click.specialSubmit", function( e ) { + var elem = e.target, + type = elem.type; + + if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) { + trigger( "submit", this, arguments ); + } + }); + + jQuery.event.add(this, "keypress.specialSubmit", function( e ) { + var elem = e.target, + type = elem.type; + + if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) { + trigger( "submit", this, arguments ); + } + }); + + } else { + return false; + } + }, + + teardown: function( namespaces ) { + jQuery.event.remove( this, ".specialSubmit" ); + } + }; + +} + +// change delegation, happens here so we have bind. +if ( !jQuery.support.changeBubbles ) { + + var changeFilters, + + getVal = function( elem ) { + var type = elem.type, val = elem.value; + + if ( type === "radio" || type === "checkbox" ) { + val = elem.checked; + + } else if ( type === "select-multiple" ) { + val = elem.selectedIndex > -1 ? + jQuery.map( elem.options, function( elem ) { + return elem.selected; + }).join("-") : + ""; + + } else if ( jQuery.nodeName( elem, "select" ) ) { + val = elem.selectedIndex; + } + + return val; + }, + + testChange = function testChange( e ) { + var elem = e.target, data, val; + + if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) { + return; + } + + data = jQuery._data( elem, "_change_data" ); + val = getVal(elem); + + // the current data will be also retrieved by beforeactivate + if ( e.type !== "focusout" || elem.type !== "radio" ) { + jQuery._data( elem, "_change_data", val ); + } + + if ( data === undefined || val === data ) { + return; + } + + if ( data != null || val ) { + e.type = "change"; + e.liveFired = undefined; + jQuery.event.trigger( e, arguments[1], elem ); + } + }; + + jQuery.event.special.change = { + filters: { + focusout: testChange, + + beforedeactivate: testChange, + + click: function( e ) { + var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; + + if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) { + testChange.call( this, e ); + } + }, + + // Change has to be called before submit + // Keydown will be called before keypress, which is used in submit-event delegation + keydown: function( e ) { + var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; + + if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) || + (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || + type === "select-multiple" ) { + testChange.call( this, e ); + } + }, + + // Beforeactivate happens also before the previous element is blurred + // with this event you can't trigger a change event, but you can store + // information + beforeactivate: function( e ) { + var elem = e.target; + jQuery._data( elem, "_change_data", getVal(elem) ); + } + }, + + setup: function( data, namespaces ) { + if ( this.type === "file" ) { + return false; + } + + for ( var type in changeFilters ) { + jQuery.event.add( this, type + ".specialChange", changeFilters[type] ); + } + + return rformElems.test( this.nodeName ); + }, + + teardown: function( namespaces ) { + jQuery.event.remove( this, ".specialChange" ); + + return rformElems.test( this.nodeName ); + } + }; + + changeFilters = jQuery.event.special.change.filters; + + // Handle when the input is .focus()'d + changeFilters.focus = changeFilters.beforeactivate; +} + +function trigger( type, elem, args ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + // Don't pass args or remember liveFired; they apply to the donor event. + var event = jQuery.extend( {}, args[ 0 ] ); + event.type = type; + event.originalEvent = {}; + event.liveFired = undefined; + jQuery.event.handle.call( elem, event ); + if ( event.isDefaultPrevented() ) { + args[ 0 ].preventDefault(); + } +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + + function handler( donor ) { + // Donor event is always a native one; fix it and switch its type. + // Let focusin/out handler cancel the donor focus/blur event. + var e = jQuery.event.fix( donor ); + e.type = fix; + e.originalEvent = {}; + jQuery.event.trigger( e, null, e.target ); + if ( e.isDefaultPrevented() ) { + donor.preventDefault(); + } + } + }); +} + +jQuery.each(["bind", "one"], function( i, name ) { + jQuery.fn[ name ] = function( type, data, fn ) { + var handler; + + // Handle object literals + if ( typeof type === "object" ) { + for ( var key in type ) { + this[ name ](key, data, type[key], fn); + } + return this; + } + + if ( arguments.length === 2 || data === false ) { + fn = data; + data = undefined; + } + + if ( name === "one" ) { + handler = function( event ) { + jQuery( this ).unbind( event, handler ); + return fn.apply( this, arguments ); + }; + handler.guid = fn.guid || jQuery.guid++; + } else { + handler = fn; + } + + if ( type === "unload" && name !== "one" ) { + this.one( type, data, fn ); + + } else { + for ( var i = 0, l = this.length; i < l; i++ ) { + jQuery.event.add( this[i], type, handler, data ); + } + } + + return this; + }; +}); + +jQuery.fn.extend({ + unbind: function( type, fn ) { + // Handle object literals + if ( typeof type === "object" && !type.preventDefault ) { + for ( var key in type ) { + this.unbind(key, type[key]); + } + + } else { + for ( var i = 0, l = this.length; i < l; i++ ) { + jQuery.event.remove( this[i], type, fn ); + } + } + + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.live( types, data, fn, selector ); + }, + + undelegate: function( selector, types, fn ) { + if ( arguments.length === 0 ) { + return this.unbind( "live" ); + + } else { + return this.die( types, null, fn, selector ); + } + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +var liveMap = { + focus: "focusin", + blur: "focusout", + mouseenter: "mouseover", + mouseleave: "mouseout" +}; + +jQuery.each(["live", "die"], function( i, name ) { + jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) { + var type, i = 0, match, namespaces, preType, + selector = origSelector || this.selector, + context = origSelector ? this : jQuery( this.context ); + + if ( typeof types === "object" && !types.preventDefault ) { + for ( var key in types ) { + context[ name ]( key, data, types[key], selector ); + } + + return this; + } + + if ( name === "die" && !types && + origSelector && origSelector.charAt(0) === "." ) { + + context.unbind( origSelector ); + + return this; + } + + if ( data === false || jQuery.isFunction( data ) ) { + fn = data || returnFalse; + data = undefined; + } + + types = (types || "").split(" "); + + while ( (type = types[ i++ ]) != null ) { + match = rnamespaces.exec( type ); + namespaces = ""; + + if ( match ) { + namespaces = match[0]; + type = type.replace( rnamespaces, "" ); + } + + if ( type === "hover" ) { + types.push( "mouseenter" + namespaces, "mouseleave" + namespaces ); + continue; + } + + preType = type; + + if ( liveMap[ type ] ) { + types.push( liveMap[ type ] + namespaces ); + type = type + namespaces; + + } else { + type = (liveMap[ type ] || type) + namespaces; + } + + if ( name === "live" ) { + // bind live handler + for ( var j = 0, l = context.length; j < l; j++ ) { + jQuery.event.add( context[j], "live." + liveConvert( type, selector ), + { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } ); + } + + } else { + // unbind live handler + context.unbind( "live." + liveConvert( type, selector ), fn ); + } + } + + return this; + }; +}); + +function liveHandler( event ) { + var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, + elems = [], + selectors = [], + events = jQuery._data( this, "events" ); + + // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) + if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { + return; + } + + if ( event.namespace ) { + namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)"); + } + + event.liveFired = this; + + var live = events.live.slice(0); + + for ( j = 0; j < live.length; j++ ) { + handleObj = live[j]; + + if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) { + selectors.push( handleObj.selector ); + + } else { + live.splice( j--, 1 ); + } + } + + match = jQuery( event.target ).closest( selectors, event.currentTarget ); + + for ( i = 0, l = match.length; i < l; i++ ) { + close = match[i]; + + for ( j = 0; j < live.length; j++ ) { + handleObj = live[j]; + + if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) { + elem = close.elem; + related = null; + + // Those two events require additional checking + if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { + event.type = handleObj.preType; + related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; + + // Make sure not to accidentally match a child element with the same selector + if ( related && jQuery.contains( elem, related ) ) { + related = elem; + } + } + + if ( !related || related !== elem ) { + elems.push({ elem: elem, handleObj: handleObj, level: close.level }); + } + } + } + } + + for ( i = 0, l = elems.length; i < l; i++ ) { + match = elems[i]; + + if ( maxLevel && match.level > maxLevel ) { + break; + } + + event.currentTarget = match.elem; + event.data = match.handleObj.data; + event.handleObj = match.handleObj; + + ret = match.handleObj.origHandler.apply( match.elem, arguments ); + + if ( ret === false || event.isPropagationStopped() ) { + maxLevel = match.level; + + if ( ret === false ) { + stop = false; + } + if ( event.isImmediatePropagationStopped() ) { + break; + } + } + } + + return stop; +} + +function liveConvert( type, selector ) { + return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&"); +} + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.bind( name, data, fn ) : + this.trigger( name ); + }; + + if ( jQuery.attrFn ) { + jQuery.attrFn[ name ] = true; + } +}); + + + +/*! + * Sizzle CSS Selector Engine + * Copyright 2011, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){ + +var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, + done = 0, + toString = Object.prototype.toString, + hasDuplicate = false, + baseHasDuplicate = true, + rBackslash = /\\/g, + rNonWord = /\W/; + +// Here we check if the JavaScript engine is using some sort of +// optimization where it does not always call our comparision +// function. If that is the case, discard the hasDuplicate value. +// Thus far that includes Google Chrome. +[0, 0].sort(function() { + baseHasDuplicate = false; + return 0; +}); + +var Sizzle = function( selector, context, results, seed ) { + results = results || []; + context = context || document; + + var origContext = context; + + if ( context.nodeType !== 1 && context.nodeType !== 9 ) { + return []; + } + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + var m, set, checkSet, extra, ret, cur, pop, i, + prune = true, + contextXML = Sizzle.isXML( context ), + parts = [], + soFar = selector; + + // Reset the position of the chunker regexp (start from head) + do { + chunker.exec( "" ); + m = chunker.exec( soFar ); + + if ( m ) { + soFar = m[3]; + + parts.push( m[1] ); + + if ( m[2] ) { + extra = m[3]; + break; + } + } + } while ( m ); + + if ( parts.length > 1 && origPOS.exec( selector ) ) { + + if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { + set = posProcess( parts[0] + parts[1], context ); + + } else { + set = Expr.relative[ parts[0] ] ? + [ context ] : + Sizzle( parts.shift(), context ); + + while ( parts.length ) { + selector = parts.shift(); + + if ( Expr.relative[ selector ] ) { + selector += parts.shift(); + } + + set = posProcess( selector, set ); + } + } + + } else { + // Take a shortcut and set the context if the root selector is an ID + // (but not if it'll be faster if the inner selector is an ID) + if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML && + Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) { + + ret = Sizzle.find( parts.shift(), context, contextXML ); + context = ret.expr ? + Sizzle.filter( ret.expr, ret.set )[0] : + ret.set[0]; + } + + if ( context ) { + ret = seed ? + { expr: parts.pop(), set: makeArray(seed) } : + Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML ); + + set = ret.expr ? + Sizzle.filter( ret.expr, ret.set ) : + ret.set; + + if ( parts.length > 0 ) { + checkSet = makeArray( set ); + + } else { + prune = false; + } + + while ( parts.length ) { + cur = parts.pop(); + pop = cur; + + if ( !Expr.relative[ cur ] ) { + cur = ""; + } else { + pop = parts.pop(); + } + + if ( pop == null ) { + pop = context; + } + + Expr.relative[ cur ]( checkSet, pop, contextXML ); + } + + } else { + checkSet = parts = []; + } + } + + if ( !checkSet ) { + checkSet = set; + } + + if ( !checkSet ) { + Sizzle.error( cur || selector ); + } + + if ( toString.call(checkSet) === "[object Array]" ) { + if ( !prune ) { + results.push.apply( results, checkSet ); + + } else if ( context && context.nodeType === 1 ) { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) { + results.push( set[i] ); + } + } + + } else { + for ( i = 0; checkSet[i] != null; i++ ) { + if ( checkSet[i] && checkSet[i].nodeType === 1 ) { + results.push( set[i] ); + } + } + } + + } else { + makeArray( checkSet, results ); + } + + if ( extra ) { + Sizzle( extra, origContext, results, seed ); + Sizzle.uniqueSort( results ); + } + + return results; +}; + +Sizzle.uniqueSort = function( results ) { + if ( sortOrder ) { + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( var i = 1; i < results.length; i++ ) { + if ( results[i] === results[ i - 1 ] ) { + results.splice( i--, 1 ); + } + } + } + } + + return results; +}; + +Sizzle.matches = function( expr, set ) { + return Sizzle( expr, null, null, set ); +}; + +Sizzle.matchesSelector = function( node, expr ) { + return Sizzle( expr, null, null, [node] ).length > 0; +}; + +Sizzle.find = function( expr, context, isXML ) { + var set; + + if ( !expr ) { + return []; + } + + for ( var i = 0, l = Expr.order.length; i < l; i++ ) { + var match, + type = Expr.order[i]; + + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { + var left = match[1]; + match.splice( 1, 1 ); + + if ( left.substr( left.length - 1 ) !== "\\" ) { + match[1] = (match[1] || "").replace( rBackslash, "" ); + set = Expr.find[ type ]( match, context, isXML ); + + if ( set != null ) { + expr = expr.replace( Expr.match[ type ], "" ); + break; + } + } + } + } + + if ( !set ) { + set = typeof context.getElementsByTagName !== "undefined" ? + context.getElementsByTagName( "*" ) : + []; + } + + return { set: set, expr: expr }; +}; + +Sizzle.filter = function( expr, set, inplace, not ) { + var match, anyFound, + old = expr, + result = [], + curLoop = set, + isXMLFilter = set && set[0] && Sizzle.isXML( set[0] ); + + while ( expr && set.length ) { + for ( var type in Expr.filter ) { + if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { + var found, item, + filter = Expr.filter[ type ], + left = match[1]; + + anyFound = false; + + match.splice(1,1); + + if ( left.substr( left.length - 1 ) === "\\" ) { + continue; + } + + if ( curLoop === result ) { + result = []; + } + + if ( Expr.preFilter[ type ] ) { + match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + + if ( !match ) { + anyFound = found = true; + + } else if ( match === true ) { + continue; + } + } + + if ( match ) { + for ( var i = 0; (item = curLoop[i]) != null; i++ ) { + if ( item ) { + found = filter( item, match, i, curLoop ); + var pass = not ^ !!found; + + if ( inplace && found != null ) { + if ( pass ) { + anyFound = true; + + } else { + curLoop[i] = false; + } + + } else if ( pass ) { + result.push( item ); + anyFound = true; + } + } + } + } + + if ( found !== undefined ) { + if ( !inplace ) { + curLoop = result; + } + + expr = expr.replace( Expr.match[ type ], "" ); + + if ( !anyFound ) { + return []; + } + + break; + } + } + } + + // Improper expression + if ( expr === old ) { + if ( anyFound == null ) { + Sizzle.error( expr ); + + } else { + break; + } + } + + old = expr; + } + + return curLoop; +}; + +Sizzle.error = function( msg ) { + throw "Syntax error, unrecognized expression: " + msg; +}; + +var Expr = Sizzle.selectors = { + order: [ "ID", "NAME", "TAG" ], + + match: { + ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/, + NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/, + ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/, + TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, + CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/, + POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/, + PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/ + }, + + leftMatch: {}, + + attrMap: { + "class": "className", + "for": "htmlFor" + }, + + attrHandle: { + href: function( elem ) { + return elem.getAttribute( "href" ); + }, + type: function( elem ) { + return elem.getAttribute( "type" ); + } + }, + + relative: { + "+": function(checkSet, part){ + var isPartStr = typeof part === "string", + isTag = isPartStr && !rNonWord.test( part ), + isPartStrNotTag = isPartStr && !isTag; + + if ( isTag ) { + part = part.toLowerCase(); + } + + for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { + if ( (elem = checkSet[i]) ) { + while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + + checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? + elem || false : + elem === part; + } + } + + if ( isPartStrNotTag ) { + Sizzle.filter( part, checkSet, true ); + } + }, + + ">": function( checkSet, part ) { + var elem, + isPartStr = typeof part === "string", + i = 0, + l = checkSet.length; + + if ( isPartStr && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + var parent = elem.parentNode; + checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false; + } + } + + } else { + for ( ; i < l; i++ ) { + elem = checkSet[i]; + + if ( elem ) { + checkSet[i] = isPartStr ? + elem.parentNode : + elem.parentNode === part; + } + } + + if ( isPartStr ) { + Sizzle.filter( part, checkSet, true ); + } + } + }, + + "": function(checkSet, part, isXML){ + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML ); + }, + + "~": function( checkSet, part, isXML ) { + var nodeCheck, + doneName = done++, + checkFn = dirCheck; + + if ( typeof part === "string" && !rNonWord.test( part ) ) { + part = part.toLowerCase(); + nodeCheck = part; + checkFn = dirNodeCheck; + } + + checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML ); + } + }, + + find: { + ID: function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }, + + NAME: function( match, context ) { + if ( typeof context.getElementsByName !== "undefined" ) { + var ret = [], + results = context.getElementsByName( match[1] ); + + for ( var i = 0, l = results.length; i < l; i++ ) { + if ( results[i].getAttribute("name") === match[1] ) { + ret.push( results[i] ); + } + } + + return ret.length === 0 ? null : ret; + } + }, + + TAG: function( match, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( match[1] ); + } + } + }, + preFilter: { + CLASS: function( match, curLoop, inplace, result, not, isXML ) { + match = " " + match[1].replace( rBackslash, "" ) + " "; + + if ( isXML ) { + return match; + } + + for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) { + if ( elem ) { + if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) { + if ( !inplace ) { + result.push( elem ); + } + + } else if ( inplace ) { + curLoop[i] = false; + } + } + } + + return false; + }, + + ID: function( match ) { + return match[1].replace( rBackslash, "" ); + }, + + TAG: function( match, curLoop ) { + return match[1].replace( rBackslash, "" ).toLowerCase(); + }, + + CHILD: function( match ) { + if ( match[1] === "nth" ) { + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + match[2] = match[2].replace(/^\+|\s*/g, ''); + + // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' + var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec( + match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || + !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + + // calculate the numbers (first)n+(last) including if they are negative + match[2] = (test[1] + (test[2] || 1)) - 0; + match[3] = test[3] - 0; + } + else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + // TODO: Move to normal caching system + match[0] = done++; + + return match; + }, + + ATTR: function( match, curLoop, inplace, result, not, isXML ) { + var name = match[1] = match[1].replace( rBackslash, "" ); + + if ( !isXML && Expr.attrMap[name] ) { + match[1] = Expr.attrMap[name]; + } + + // Handle if an un-quoted value was used + match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" ); + + if ( match[2] === "~=" ) { + match[4] = " " + match[4] + " "; + } + + return match; + }, + + PSEUDO: function( match, curLoop, inplace, result, not ) { + if ( match[1] === "not" ) { + // If we're dealing with a complex expression, or a simple one + if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) { + match[3] = Sizzle(match[3], null, null, curLoop); + + } else { + var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not); + + if ( !inplace ) { + result.push.apply( result, ret ); + } + + return false; + } + + } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) { + return true; + } + + return match; + }, + + POS: function( match ) { + match.unshift( true ); + + return match; + } + }, + + filters: { + enabled: function( elem ) { + return elem.disabled === false && elem.type !== "hidden"; + }, + + disabled: function( elem ) { + return elem.disabled === true; + }, + + checked: function( elem ) { + return elem.checked === true; + }, + + selected: function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + parent: function( elem ) { + return !!elem.firstChild; + }, + + empty: function( elem ) { + return !elem.firstChild; + }, + + has: function( elem, i, match ) { + return !!Sizzle( match[3], elem ).length; + }, + + header: function( elem ) { + return (/h\d/i).test( elem.nodeName ); + }, + + text: function( elem ) { + var attr = elem.getAttribute( "type" ), type = elem.type; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); + }, + + radio: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; + }, + + checkbox: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; + }, + + file: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; + }, + + password: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; + }, + + submit: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; + }, + + image: function( elem ) { + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; + }, + + reset: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; + }, + + button: function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; + }, + + input: function( elem ) { + return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; + } + }, + setFilters: { + first: function( elem, i ) { + return i === 0; + }, + + last: function( elem, i, match, array ) { + return i === array.length - 1; + }, + + even: function( elem, i ) { + return i % 2 === 0; + }, + + odd: function( elem, i ) { + return i % 2 === 1; + }, + + lt: function( elem, i, match ) { + return i < match[3] - 0; + }, + + gt: function( elem, i, match ) { + return i > match[3] - 0; + }, + + nth: function( elem, i, match ) { + return match[3] - 0 === i; + }, + + eq: function( elem, i, match ) { + return match[3] - 0 === i; + } + }, + filter: { + PSEUDO: function( elem, match, i, array ) { + var name = match[1], + filter = Expr.filters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + + } else if ( name === "contains" ) { + return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; + + } else if ( name === "not" ) { + var not = match[3]; + + for ( var j = 0, l = not.length; j < l; j++ ) { + if ( not[j] === elem ) { + return false; + } + } + + return true; + + } else { + Sizzle.error( name ); + } + }, + + CHILD: function( elem, match ) { + var type = match[1], + node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + + case "nth": + var first = match[2], + last = match[3]; + + if ( first === 1 && last === 0 ) { + return true; + } + + var doneName = match[0], + parent = elem.parentNode; + + if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { + var count = 0; + + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + node.nodeIndex = ++count; + } + } + + parent.sizcache = doneName; + } + + var diff = elem.nodeIndex - last; + + if ( first === 0 ) { + return diff === 0; + + } else { + return ( diff % first === 0 && diff / first >= 0 ); + } + } + }, + + ID: function( elem, match ) { + return elem.nodeType === 1 && elem.getAttribute("id") === match; + }, + + TAG: function( elem, match ) { + return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match; + }, + + CLASS: function( elem, match ) { + return (" " + (elem.className || elem.getAttribute("class")) + " ") + .indexOf( match ) > -1; + }, + + ATTR: function( elem, match ) { + var name = match[1], + result = Expr.attrHandle[ name ] ? + Expr.attrHandle[ name ]( elem ) : + elem[ name ] != null ? + elem[ name ] : + elem.getAttribute( name ), + value = result + "", + type = match[2], + check = match[4]; + + return result == null ? + type === "!=" : + type === "=" ? + value === check : + type === "*=" ? + value.indexOf(check) >= 0 : + type === "~=" ? + (" " + value + " ").indexOf(check) >= 0 : + !check ? + value && result !== false : + type === "!=" ? + value !== check : + type === "^=" ? + value.indexOf(check) === 0 : + type === "$=" ? + value.substr(value.length - check.length) === check : + type === "|=" ? + value === check || value.substr(0, check.length + 1) === check + "-" : + false; + }, + + POS: function( elem, match, i, array ) { + var name = match[2], + filter = Expr.setFilters[ name ]; + + if ( filter ) { + return filter( elem, i, match, array ); + } + } + } +}; + +var origPOS = Expr.match.POS, + fescape = function(all, num){ + return "\\" + (num - 0 + 1); + }; + +for ( var type in Expr.match ) { + Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) ); + Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) ); +} + +var makeArray = function( array, results ) { + array = Array.prototype.slice.call( array, 0 ); + + if ( results ) { + results.push.apply( results, array ); + return results; + } + + return array; +}; + +// Perform a simple check to determine if the browser is capable of +// converting a NodeList to an array using builtin methods. +// Also verifies that the returned array holds DOM nodes +// (which is not the case in the Blackberry browser) +try { + Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + +// Provide a fallback method if it does not work +} catch( e ) { + makeArray = function( array, results ) { + var i = 0, + ret = results || []; + + if ( toString.call(array) === "[object Array]" ) { + Array.prototype.push.apply( ret, array ); + + } else { + if ( typeof array.length === "number" ) { + for ( var l = array.length; i < l; i++ ) { + ret.push( array[i] ); + } + + } else { + for ( ; array[i]; i++ ) { + ret.push( array[i] ); + } + } + } + + return ret; + }; +} + +var sortOrder, siblingCheck; + +if ( document.documentElement.compareDocumentPosition ) { + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { + return a.compareDocumentPosition ? -1 : 1; + } + + return a.compareDocumentPosition(b) & 4 ? -1 : 1; + }; + +} else { + sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + + siblingCheck = function( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; + }; +} + +// Utility function for retreiving the text value of an array of DOM nodes +Sizzle.getText = function( elems ) { + var ret = "", elem; + + for ( var i = 0; elems[i]; i++ ) { + elem = elems[i]; + + // Get the text from text nodes and CDATA nodes + if ( elem.nodeType === 3 || elem.nodeType === 4 ) { + ret += elem.nodeValue; + + // Traverse everything else, except comment nodes + } else if ( elem.nodeType !== 8 ) { + ret += Sizzle.getText( elem.childNodes ); + } + } + + return ret; +}; + +// Check to see if the browser returns elements by name when +// querying by getElementById (and provide a workaround) +(function(){ + // We're going to inject a fake input element with a specified name + var form = document.createElement("div"), + id = "script" + (new Date()).getTime(), + root = document.documentElement; + + form.innerHTML = ""; + + // Inject it into the root element, check its status, and remove it quickly + root.insertBefore( form, root.firstChild ); + + // The workaround has to do additional checks after a getElementById + // Which slows things down for other browsers (hence the branching) + if ( document.getElementById( id ) ) { + Expr.find.ID = function( match, context, isXML ) { + if ( typeof context.getElementById !== "undefined" && !isXML ) { + var m = context.getElementById(match[1]); + + return m ? + m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? + [m] : + undefined : + []; + } + }; + + Expr.filter.ID = function( elem, match ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + + return elem.nodeType === 1 && node && node.nodeValue === match; + }; + } + + root.removeChild( form ); + + // release memory in IE + root = form = null; +})(); + +(function(){ + // Check to see if the browser returns only elements + // when doing getElementsByTagName("*") + + // Create a fake element + var div = document.createElement("div"); + div.appendChild( document.createComment("") ); + + // Make sure no comments are found + if ( div.getElementsByTagName("*").length > 0 ) { + Expr.find.TAG = function( match, context ) { + var results = context.getElementsByTagName( match[1] ); + + // Filter out possible comments + if ( match[1] === "*" ) { + var tmp = []; + + for ( var i = 0; results[i]; i++ ) { + if ( results[i].nodeType === 1 ) { + tmp.push( results[i] ); + } + } + + results = tmp; + } + + return results; + }; + } + + // Check to see if an attribute returns normalized href attributes + div.innerHTML = ""; + + if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" && + div.firstChild.getAttribute("href") !== "#" ) { + + Expr.attrHandle.href = function( elem ) { + return elem.getAttribute( "href", 2 ); + }; + } + + // release memory in IE + div = null; +})(); + +if ( document.querySelectorAll ) { + (function(){ + var oldSizzle = Sizzle, + div = document.createElement("div"), + id = "__sizzle__"; + + div.innerHTML = "

"; + + // Safari can't handle uppercase or unicode characters when + // in quirks mode. + if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { + return; + } + + Sizzle = function( query, context, extra, seed ) { + context = context || document; + + // Only use querySelectorAll on non-XML documents + // (ID selectors don't work in non-HTML documents) + if ( !seed && !Sizzle.isXML(context) ) { + // See if we find a selector to speed up + var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query ); + + if ( match && (context.nodeType === 1 || context.nodeType === 9) ) { + // Speed-up: Sizzle("TAG") + if ( match[1] ) { + return makeArray( context.getElementsByTagName( query ), extra ); + + // Speed-up: Sizzle(".CLASS") + } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) { + return makeArray( context.getElementsByClassName( match[2] ), extra ); + } + } + + if ( context.nodeType === 9 ) { + // Speed-up: Sizzle("body") + // The body element only exists once, optimize finding it + if ( query === "body" && context.body ) { + return makeArray( [ context.body ], extra ); + + // Speed-up: Sizzle("#ID") + } else if ( match && match[3] ) { + var elem = context.getElementById( match[3] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id === match[3] ) { + return makeArray( [ elem ], extra ); + } + + } else { + return makeArray( [], extra ); + } + } + + try { + return makeArray( context.querySelectorAll(query), extra ); + } catch(qsaError) {} + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + var oldContext = context, + old = context.getAttribute( "id" ), + nid = old || id, + hasParent = context.parentNode, + relativeHierarchySelector = /^\s*[+~]/.test( query ); + + if ( !old ) { + context.setAttribute( "id", nid ); + } else { + nid = nid.replace( /'/g, "\\$&" ); + } + if ( relativeHierarchySelector && hasParent ) { + context = context.parentNode; + } + + try { + if ( !relativeHierarchySelector || hasParent ) { + return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra ); + } + + } catch(pseudoError) { + } finally { + if ( !old ) { + oldContext.removeAttribute( "id" ); + } + } + } + } + + return oldSizzle(query, context, extra, seed); + }; + + for ( var prop in oldSizzle ) { + Sizzle[ prop ] = oldSizzle[ prop ]; + } + + // release memory in IE + div = null; + })(); +} + +(function(){ + var html = document.documentElement, + matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector; + + if ( matches ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9 fails this) + var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ), + pseudoWorks = false; + + try { + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( document.documentElement, "[test!='']:sizzle" ); + + } catch( pseudoError ) { + pseudoWorks = true; + } + + Sizzle.matchesSelector = function( node, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']"); + + if ( !Sizzle.isXML( node ) ) { + try { + if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) { + var ret = matches.call( node, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || !disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9, so check for that + node.document && node.document.nodeType !== 11 ) { + return ret; + } + } + } catch(e) {} + } + + return Sizzle(expr, null, null, [node]).length > 0; + }; + } +})(); + +(function(){ + var div = document.createElement("div"); + + div.innerHTML = "
"; + + // Opera can't find a second classname (in 9.6) + // Also, make sure that getElementsByClassName actually exists + if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { + return; + } + + // Safari caches class attributes, doesn't catch changes (in 3.2) + div.lastChild.className = "e"; + + if ( div.getElementsByClassName("e").length === 1 ) { + return; + } + + Expr.order.splice(1, 0, "CLASS"); + Expr.find.CLASS = function( match, context, isXML ) { + if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { + return context.getElementsByClassName(match[1]); + } + }; + + // release memory in IE + div = null; +})(); + +function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 && !isXML ){ + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( elem.nodeName.toLowerCase() === cur ) { + match = elem; + break; + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) { + for ( var i = 0, l = checkSet.length; i < l; i++ ) { + var elem = checkSet[i]; + + if ( elem ) { + var match = false; + + elem = elem[dir]; + + while ( elem ) { + if ( elem.sizcache === doneName ) { + match = checkSet[elem.sizset]; + break; + } + + if ( elem.nodeType === 1 ) { + if ( !isXML ) { + elem.sizcache = doneName; + elem.sizset = i; + } + + if ( typeof cur !== "string" ) { + if ( elem === cur ) { + match = true; + break; + } + + } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { + match = elem; + break; + } + } + + elem = elem[dir]; + } + + checkSet[i] = match; + } + } +} + +if ( document.documentElement.contains ) { + Sizzle.contains = function( a, b ) { + return a !== b && (a.contains ? a.contains(b) : true); + }; + +} else if ( document.documentElement.compareDocumentPosition ) { + Sizzle.contains = function( a, b ) { + return !!(a.compareDocumentPosition(b) & 16); + }; + +} else { + Sizzle.contains = function() { + return false; + }; +} + +Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; + + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +var posProcess = function( selector, context ) { + var match, + tmpSet = [], + later = "", + root = context.nodeType ? [context] : context; + + // Position selectors must be done after the filter + // And so must :not(positional) so we move all PSEUDOs to the end + while ( (match = Expr.match.PSEUDO.exec( selector )) ) { + later += match[0]; + selector = selector.replace( Expr.match.PSEUDO, "" ); + } + + selector = Expr.relative[selector] ? selector + "*" : selector; + + for ( var i = 0, l = root.length; i < l; i++ ) { + Sizzle( selector, root[i], tmpSet ); + } + + return Sizzle.filter( later, tmpSet ); +}; + +// EXPOSE +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.filters; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})(); + + +var runtil = /Until$/, + rparentsprev = /^(?:parents|prevUntil|prevAll)/, + // Note: This RegExp should be improved, or likely pulled from Sizzle + rmultiselector = /,/, + isSimple = /^.[^:#\[\.,]*$/, + slice = Array.prototype.slice, + POS = jQuery.expr.match.POS, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var self = this, + i, l; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var targets = jQuery( target ); + return this.filter(function() { + for ( var i = 0, l = targets.length; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( typeof selector === "string" ? + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var ret = [], i, l, cur = this[0]; + + // Array + if ( jQuery.isArray( selectors ) ) { + var match, selector, + matches = {}, + level = 1; + + if ( cur && selectors.length ) { + for ( i = 0, l = selectors.length; i < l; i++ ) { + selector = selectors[i]; + + if ( !matches[ selector ] ) { + matches[ selector ] = POS.test( selector ) ? + jQuery( selector, context || this.context ) : + selector; + } + } + + while ( cur && cur.ownerDocument && cur !== context ) { + for ( selector in matches ) { + match = matches[ selector ]; + + if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) { + ret.push({ selector: selector, elem: cur, level: level }); + } + } + + cur = cur.parentNode; + level++; + } + } + + return ret; + } + + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { + break; + } + } + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + if ( !elem || typeof elem === "string" ) { + return jQuery.inArray( this[0], + // If it receives a string, the selector is used + // If it receives nothing, the siblings are used + elem ? jQuery( elem ) : this.parent().children() ); + } + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + andSelf: function() { + return this.add( this.prevObject ); + } +}); + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return jQuery.nth( elem, 2, "nextSibling" ); + }, + prev: function( elem ) { + return jQuery.nth( elem, 2, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( elem.parentNode.firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.makeArray( elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ), + // The variable 'args' was introduced in + // https://github.com/jquery/jquery/commit/52a0238 + // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed. + // http://code.google.com/p/v8/issues/detail?id=1050 + args = slice.call(arguments); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, args.join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + nth: function( cur, result, dir, elem ) { + result = result || 1; + var num = 0; + + for ( ; cur; cur = cur[dir] ) { + if ( cur.nodeType === 1 && ++num === result ) { + break; + } + } + + return cur; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return (elem === qualifier) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return (jQuery.inArray( elem, qualifier ) >= 0) === keep; + }); +} + + + + +var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, + rtagName = /<([\w:]+)/, + rtbody = /", "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }; + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE can't serialize and + + + + + + + + +
+

TableSorter v2.0.6

+

By Christian Bach, updated 6/22/2011 by Rob G
Docs included

+ + + + + + + + + + + + + + + + + + + + + + +
AlphaNumeric Sort *New*NumericAlphabeticalSites
abc 12310Koalahttp://www.google.com
abc 1234Oxhttp://www.yahoo.com
abc 910Girafeehttp://www.facebook.com
zyx 24767Bisonhttp://www.whitehouse.gov/
abc 113Chimphttp://www.ucla.edu/
abc 256Elephanthttp://www.wikipedia.org/
abc 9155Lionhttp://www.nytimes.com/
ABC 1087Zebrahttp://www.google.com
zyx 1999Koalahttp://www.mit.edu/
zyx 120Llamahttp://www.nasa.gov/
+ +
+ \ No newline at end of file diff --git a/js/jquery.metadata.js b/js/jquery.metadata.js new file mode 100644 index 00000000..9da403fd --- /dev/null +++ b/js/jquery.metadata.js @@ -0,0 +1,148 @@ +/* + * Metadata - jQuery plugin for parsing metadata from elements + * + * Copyright (c) 2006 John Resig, Yehuda Katz, J�örn Zaefferer, Paul McLanahan + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Revision: $Id: jquery.metadata.js 3640 2007-10-11 18:34:38Z pmclanahan $ + * + */ + +/** + * Sets the type of metadata to use. Metadata is encoded in JSON, and each property + * in the JSON will become a property of the element itself. + * + * There are four supported types of metadata storage: + * + * attr: Inside an attribute. The name parameter indicates *which* attribute. + * + * class: Inside the class attribute, wrapped in curly braces: { } + * + * elem: Inside a child element (e.g. a script tag). The + * name parameter indicates *which* element. + * html5: Values are stored in data-* attributes. + * + * The metadata for an element is loaded the first time the element is accessed via jQuery. + * + * As a result, you can define the metadata type, use $(expr) to load the metadata into the elements + * matched by expr, then redefine the metadata type and run another $(expr) for other elements. + * + * @name $.metadata.setType + * + * @example

This is a p

+ * @before $.metadata.setType("class") + * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label" + * @desc Reads metadata from the class attribute + * + * @example

This is a p

+ * @before $.metadata.setType("attr", "data") + * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label" + * @desc Reads metadata from a "data" attribute + * + * @example

This is a p

+ * @before $.metadata.setType("elem", "script") + * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label" + * @desc Reads metadata from a nested script element + * + * @example

This is a p

+ * @before $.metadata.setType("html5") + * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label" + * @desc Reads metadata from a series of data-* attributes + * + * @param String type The encoding type + * @param String name The name of the attribute to be used to get metadata (optional) + * @cat Plugins/Metadata + * @descr Sets the type of encoding to be used when loading metadata for the first time + * @type undefined + * @see metadata() + */ + +(function($) { + +$.extend({ + metadata : { + defaults : { + type: 'class', + name: 'metadata', + cre: /({.*})/, + single: 'metadata' + }, + setType: function( type, name ){ + this.defaults.type = type; + this.defaults.name = name; + }, + get: function( elem, opts ){ + var settings = $.extend({},this.defaults,opts); + // check for empty string in single property + if ( !settings.single.length ) settings.single = 'metadata'; + + var data = $.data(elem, settings.single); + // returned cached data if it already exists + if ( data ) return data; + + data = "{}"; + + var getData = function(data) { + if(typeof data != "string") return data; + + if( data.indexOf('{') < 0 ) { + data = eval("(" + data + ")"); + } + } + + var getObject = function(data) { + if(typeof data != "string") return data; + + data = eval("(" + data + ")"); + return data; + } + + if ( settings.type == "html5" ) { + var object = {}; + $( elem.attributes ).each(function() { + var name = this.nodeName; + if(name.match(/^data-/)) name = name.replace(/^data-/, ''); + else return true; + object[name] = getObject(this.nodeValue); + }); + } else { + if ( settings.type == "class" ) { + var m = settings.cre.exec( elem.className ); + if ( m ) + data = m[1]; + } else if ( settings.type == "elem" ) { + if( !elem.getElementsByTagName ) return; + var e = elem.getElementsByTagName(settings.name); + if ( e.length ) + data = $.trim(e[0].innerHTML); + } else if ( elem.getAttribute != undefined ) { + var attr = elem.getAttribute( settings.name ); + if ( attr ) + data = attr; + } + object = getObject(data.indexOf("{") < 0 ? "{" + data + "}" : data); + } + + $.data( elem, settings.single, object ); + return object; + } + } +}); + +/** + * Returns the metadata object for the first member of the jQuery object. + * + * @name metadata + * @descr Returns element's metadata object + * @param Object opts An object contianing settings to override the defaults + * @type jQuery + * @cat Plugins/Metadata + */ +$.fn.metadata = function( opts ){ + return $.metadata.get( this[0], opts ); +}; + +})(jQuery); \ No newline at end of file diff --git a/js/jquery.tablesorter.js b/js/jquery.tablesorter.js new file mode 100644 index 00000000..3c560d7e --- /dev/null +++ b/js/jquery.tablesorter.js @@ -0,0 +1,921 @@ +/* +* TableSorter 2.0 - Client-side table sorting with ease! +* Version 2.0.6 +* @requires jQuery v1.2.3 +* +* Copyright (c) 2007 Christian Bach +* Examples and docs at: http://tablesorter.com +* Dual licensed under the MIT and GPL licenses: +* http://www.opensource.org/licenses/mit-license.php +* http://www.gnu.org/licenses/gpl.html +* +* @description Create a sortable table with multi-column sorting capabilitys +* +* @example $('table').tablesorter(); +* @desc Create a simple tablesorter interface. +* +* @example $('table').tablesorter({ sortList:[[0,0],[1,0]] }); +* @desc Create a tablesorter interface and sort on the first and secound column column headers. +* +* @example $('table').tablesorter({ headers: { 0: { sorter: false}, 1: {sorter: false} } }); +* @desc Create a tablesorter interface and disableing the first and second column headers. +* +* @example $('table').tablesorter({ headers: { 0: {sorter:"integer"}, 1: {sorter:"currency"} } }); +* @desc Create a tablesorter interface and set a column parser for the first and second column. +* +* @param Object settings An object literal containing key/value pairs to provide optional settings. +* +* @option String cssHeader (optional) A string of the class name to be appended to sortable tr elements in the thead of the table. +* Default value: "header" +* +* @option String cssAsc (optional) A string of the class name to be appended to sortable tr elements in the thead on a ascending sort. +* Default value: "headerSortUp" +* +* @option String cssDesc (optional) A string of the class name to be appended to sortable tr elements in the thead on a descending sort. +* Default value: "headerSortDown" +* +* @option String sortInitialOrder (optional) A string of the inital sorting order can be asc or desc. +* Default value: "asc" +* +* @option String sortMultisortKey (optional) A string of the multi-column sort key. +* Default value: "shiftKey" +* +* @option String textExtraction (optional) A string of the text-extraction method to use. For complex html structures inside td +* cell set this option to "complex", on large tables the complex option can be slow. +* Default value: "simple" +* +* @option Object headers (optional) An array containing the forces sorting rules. This option let's you specify a default sorting rule. +* Default value: null +* +* @option Array sortList (optional) An array containing the forces sorting rules. This option let's you specify a default sorting rule. +* Default value: null +* +* @option Array sortForce (optional) An array containing forced sorting rules. This option let's you specify a default sorting rule, +* which is prepended to user-selected rules. +* Default value: null +* +* @option Boolean sortLocaleCompare (optional) Boolean flag indicating whatever to use String.localeCampare method or not. +* Default set to true. +* +* @option Array sortAppend (optional) An array containing forced sorting rules. This option let's you specify a default sorting rule, +* which is appended to user-selected rules. +* Default value: null +* +* @option Boolean widthFixed (optional) Boolean flag indicating if tablesorter should apply fixed widths to the table columns. +* This is useful when using the pager companion plugin. This options requires the dimension jquery plugin. +* Default value: false +* +* @option Boolean cancelSelection (optional) Boolean flag indicating if tablesorter should cancel selection of the table headers text. +* Default value: true +* +* @option Boolean debug (optional) Boolean flag indicating if tablesorter should display debuging information usefull for development. +* +* @type jQuery +* @name tablesorter +* @cat Plugins/Tablesorter +* @author Christian Bach/christian.bach@polyester.se +*/ +(function($){ + $.extend({ + tablesorter: new function(){ + + var parsers = [], widgets = [], tbl; + this.defaults = { + cssHeader: "header", + cssAsc: "headerSortUp", + cssDesc: "headerSortDown", + cssChildRow: "expand-child", + sortInitialOrder: "asc", + sortMultiSortKey: "shiftKey", + sortForce: null, + sortAppend: null, + sortLocaleCompare: false, + textExtraction: "simple", + parsers: {}, + widgets: [], + widgetZebra: { css: ["even", "odd"] }, + headers: {}, + widthFixed: false, + cancelSelection: true, + sortList: [], + headerList: [], + dateFormat: "us", + decimal: /\.|\,/g, + onRenderHeader: null, + selectorHeaders: 'thead th', + tableClass : 'tablesorter', + debug: false + }; + + /* debuging utils */ + function log(s) { + if (typeof console !== "undefined" && typeof console.debug !== "undefined") { + console.log(s); + } else { + alert(s); + } + } + + function benchmark(s, d) { + log(s + "," + (new Date().getTime() - d.getTime()) + "ms"); + } + + this.benchmark = benchmark; + + function getElementText(config, node) { + var text = ""; + if (!node) { return ""; } + if (!config.supportsTextContent) { config.supportsTextContent = node.textContent || false; } + if (config.textExtraction === "simple") { + if (config.supportsTextContent) { + text = node.textContent; + } else { + if (node.childNodes[0] && node.childNodes[0].hasChildNodes()) { + text = node.childNodes[0].innerHTML; + } else { + text = node.innerHTML; + } + } + } else { + if (typeof(config.textExtraction) === "function") { + text = config.textExtraction(node); + } else { + text = $(node).text(); + } + } + return text; + } + + /* parsers utils */ + function getParserById(name) { + var i, l = parsers.length; + for (i = 0; i < l; i++) { + if (parsers[i].id.toLowerCase() === name.toLowerCase()) { + return parsers[i]; + } + } + return false; + } + + function getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex) { + return rows[rowIndex].cells[cellIndex]; + } + + function trimAndGetNodeText(config, node) { + return $.trim(getElementText(config, node)); + } + + function detectParserForColumn(table, rows, rowIndex, cellIndex) { + var i, l = parsers.length, + node = false, + nodeValue = '', + keepLooking = true; + while (nodeValue === '' && keepLooking) { + rowIndex++; + if (rows[rowIndex]) { + node = getNodeFromRowAndCellIndex(rows, rowIndex, cellIndex); + nodeValue = trimAndGetNodeText(table.config, node); + if (table.config.debug) { + log('Checking if value was empty on row:' + rowIndex); + } + } else { + keepLooking = false; + } + } + for (i = 1; i < l; i++) { + if (parsers[i].is(nodeValue, table, node)) { + return parsers[i]; + } + } + // 0 is always the generic parser (text) + return parsers[0]; + } + + function buildParserCache(table, $headers) { + if (table.tBodies.length === 0) { return; } // In the case of empty tables + var rows = table.tBodies[0].rows, list, cells, l, i, p, parsersDebug = ""; + if (rows[0]) { + list = []; + cells = rows[0].cells; + l = cells.length; + for (i = 0; i < l; i++) { + p = false; + if ($.metadata && ($($headers[i]).metadata() && $($headers[i]).metadata().sorter)) { + p = getParserById($($headers[i]).metadata().sorter); + } else if ((table.config.headers[i] && table.config.headers[i].sorter)) { + p = getParserById(table.config.headers[i].sorter); + } + if (!p) { + p = detectParserForColumn(table, rows, -1, i); + } + if (table.config.debug) { + parsersDebug += "column:" + i + " parser:" + p.id + "\n"; + } + list.push(p); + } + } + if (table.config.debug) { + log(parsersDebug); + } + return list; + } + + /* utils */ + function buildCache(table) { + var totalRows = (table.tBodies[0] && table.tBodies[0].rows.length) || 0, + totalCells = (table.tBodies[0].rows[0] && table.tBodies[0].rows[0].cells.length) || 0, + parsers = table.config.parsers, + cache = { + row: [], + normalized: [] + }, + i, j, c, cols, cacheTime; + if (table.config.debug) { + cacheTime = new Date(); + } + for (i = 0; i < totalRows; ++i) { + /** Add the table data to main data array */ + c = $(table.tBodies[0].rows[i]); + cols = []; + // if this is a child row, add it to the last row's children and + // continue to the next row + if (c.hasClass(table.config.cssChildRow)) { + cache.row[cache.row.length - 1] = cache.row[cache.row.length - 1].add(c); + // go to the next for loop + continue; + } + cache.row.push(c); + for (j = 0; j < totalCells; ++j) { + cols.push(parsers[j].format(getElementText(table.config, c[0].cells[j]), table, c[0].cells[j])); + } + cols.push(cache.normalized.length); // add position for rowCache + cache.normalized.push(cols); + cols = null; + } + if (table.config.debug) { + benchmark("Building cache for " + totalRows + " rows:", cacheTime); + } + return cache; + } + + function getWidgetById(name) { + var i, l = widgets.length; + for (i = 0; i < l; i++) { + if (widgets[i].id.toLowerCase() === name.toLowerCase()) { + return widgets[i]; + } + } + } + + function applyWidget(table) { + var c = table.config.widgets, + i, l = c.length; + for (i = 0; i < l; i++) { + getWidgetById(c[i]).format(table); + } + } + + function appendToTable(table, cache) { + var c = cache, + r = c.row, + n = c.normalized, + totalRows = n.length, + checkCell = (n[0].length - 1), + tableBody = $(table.tBodies[0]), + rows = [], + i, j, l, pos, appendTime; + if (table.config.debug) { + appendTime = new Date(); + } + for (i = 0; i < totalRows; i++) { + pos = n[i][checkCell]; + rows.push(r[pos]); + if (!table.config.appender) { + l = r[pos].length; + for (j = 0; j < l; j++) { + tableBody[0].appendChild(r[pos][j]); + } + } + } + if (table.config.appender) { + table.config.appender(table, rows); + } + rows = null; + if (table.config.debug) { + benchmark("Rebuilt table:", appendTime); + } + // apply table widgets + applyWidget(table); + // trigger sortend + setTimeout(function () { + $(table).trigger("sortEnd"); + }, 0); + } + + // from: + // http://www.javascripttoolbox.com/lib/table/examples.php + // http://www.javascripttoolbox.com/temp/table_cellindex.html + function computeTableHeaderCellIndexes(t) { + var matrix = [], + lookup = {}, + thead = t.getElementsByTagName('THEAD')[0], + trs = thead.getElementsByTagName('TR'), + i, j, k, l, c, cells, rowIndex, cellId, rowSpan, colSpan, firstAvailCol, matrixrow; + for (i = 0; i < trs.length; i++) { + cells = trs[i].cells; + for (j = 0; j < cells.length; j++) { + c = cells[j]; + rowIndex = c.parentNode.rowIndex; + cellId = rowIndex + "-" + c.cellIndex; + rowSpan = c.rowSpan || 1; + colSpan = c.colSpan || 1; + if (typeof(matrix[rowIndex]) === "undefined") { + matrix[rowIndex] = []; + } + // Find first available column in the first row + for (k = 0; k < matrix[rowIndex].length + 1; k++) { + if (typeof(matrix[rowIndex][k]) === "undefined") { + firstAvailCol = k; + break; + } + } + lookup[cellId] = firstAvailCol; + for (k = rowIndex; k < rowIndex + rowSpan; k++) { + if (typeof(matrix[k]) === "undefined") { + matrix[k] = []; + } + matrixrow = matrix[k]; + for (l = firstAvailCol; l < firstAvailCol + colSpan; l++) { + matrixrow[l] = "x"; + } + } + } + } + return lookup; + } + + function formatSortingOrder(v) { + if (typeof(v) !== "Number") { + return (v.toLowerCase() === "desc") ? 1 : 0; + } else { + return (v === 1) ? 1 : 0; + } + } + + function checkHeaderMetadata(cell) { + return (($.metadata) && ($(cell).metadata().sorter === false)); + } + + function checkHeaderOptions(table, i) { + return ((table.config.headers[i]) && (table.config.headers[i].sorter === false)); + } + + function checkHeaderOptionsSortingLocked(table, i) { + if ((table.config.headers[i]) && (table.config.headers[i].lockedOrder)) { return table.config.headers[i].lockedOrder; } + return false; + } + + function buildHeaders(table) { + var meta = ($.metadata) ? true : false, + header_index = computeTableHeaderCellIndexes(table), + time, $tableHeaders; + if (table.config.debug) { + time = new Date(); + } + $tableHeaders = $(table.config.selectorHeaders, table) + .wrapInner("") + .each(function (index) { + this.column = header_index[this.parentNode.rowIndex + "-" + this.cellIndex]; + // this.column = index; + this.order = formatSortingOrder(table.config.sortInitialOrder); + this.count = this.order; + if (checkHeaderMetadata(this) || checkHeaderOptions(table, index)) { this.sortDisabled = true; } + if (checkHeaderOptionsSortingLocked(table, index)) { this.order = this.lockedOrder = checkHeaderOptionsSortingLocked(table, index); } + if (!this.sortDisabled) { + var $th = $(this).addClass(table.config.cssHeader); + if (table.config.onRenderHeader) { table.config.onRenderHeader.apply($th); } + } + // add cell to headerList + table.config.headerList[index] = this; + }); + if (table.config.debug) { + benchmark("Built headers:", time); + log($tableHeaders); + } + return $tableHeaders; + } + + function checkCellColSpan(table, rows, row) { + var i, cell, arr = [], + r = table.tHead.rows, + c = r[row].cells; + for (i = 0; i < c.length; i++) { + cell = c[i]; + if (cell.colSpan > 1) { + arr = arr.concat(checkCellColSpan(table, rows, row++)); // what is headerArr? + } else { + if (table.tHead.length === 1 || (cell.rowSpan > 1 || !r[row + 1])) { + arr.push(cell); + } + } + } + return arr; + } + + function isValueInArray(v, a) { + var i, l = a.length; + for (i = 0; i < l; i++) { + if (a[i][0] === v) { + return true; + } + } + return false; + } + + function setHeadersCss(table, $headers, list, css) { + // remove all header information + $headers.removeClass(css[0]).removeClass(css[1]); + var h = [], i, l; + $headers.each(function (offset) { + if (!this.sortDisabled) { + h[this.column] = $(this); + } + }); + l = list.length; + for (i = 0; i < l; i++) { + h[list[i][0]].addClass(css[list[i][1]]); + } + } + + function fixColumnWidth(table, $headers) { + var c = table.config, colgroup; + if (c.widthFixed) { + colgroup = $(''); + $("tr:first td", table.tBodies[0]).each(function () { + colgroup.append($('').css('width', $(this).width())); + }); + $(table).prepend(colgroup); + } + } + + function updateHeaderSortCount(table, sortList) { + var i, s, o, c = table.config, + l = sortList.length; + for (i = 0; i < l; i++) { + s = sortList[i]; + o = c.headerList[s[0]]; + o.count = s[1]; + o.count++; + } + } + + function getCachedSortType(parsers, i) { + return parsers[i].type; + } + + /* sorting methods - reverted sorting method back to version 2.0.3 */ + function multisort(table,sortList,cache){ + var dynamicExp = "var sortWrapper = function(a,b) {", + l = sortList.length, sortTime, i, c, s, e, order, orgOrderCol; + if (table.config.debug) { sortTime = new Date(); } + for (i=0; i < l; i++) { + c = sortList[i][0]; + order = sortList[i][1]; + s = (getCachedSortType(table.config.parsers,c) === "text") ? ((order === 0) ? "sortText" : "sortTextDesc") : ((order === 0) ? "sortNumeric" : "sortNumericDesc"); + e = "e" + i; + dynamicExp += "var " + e + " = " + s + "(a[" + c + "],b[" + c + "]); "; + dynamicExp += "if (" + e + ") { return " + e + "; } "; + dynamicExp += "else { "; + } + // if value is the same keep orignal order + orgOrderCol = cache.normalized[0].length - 1; + dynamicExp += "return a[" + orgOrderCol + "]-b[" + orgOrderCol + "];"; + for(i=0; i < l; i++) { + dynamicExp += "}; "; + } + dynamicExp += "return 0; "; + dynamicExp += "}; "; + eval(dynamicExp); + cache.normalized.sort(sortWrapper); + if (table.config.debug) { benchmark("Sorting on " + sortList.toString() + " and dir " + order+ " time:", sortTime); } + return cache; + } + + // http://www.webdeveloper.com/forum/showthread.php?t=107909 + function sortText(a, b){ + if ($.data(tbl[0], "tablesorter").sortLocaleCompare) { return a.localeCompare(b); } + if (a === b) { return 0; } + try { + var cnt = 0, ax, t, x = /^(\.)?\d/, + L = Math.min(a.length, b.length) + 1; + while (cnt < L && a.charAt(cnt) === b.charAt(cnt) && x.test(b.substring(cnt)) === false && x.test(a.substring(cnt)) === false) { cnt++; } + a = a.substring(cnt); + b = b.substring(cnt); + if (x.test(a) || x.test(b)) { + if (x.test(a) === false) { + return (a) ? 1 : -1; + } else if (x.test(b) === false) { + return (b) ? -1 : 1; + } else { + t = parseFloat(a) - parseFloat(b); + if (t !== 0) { return t; } else { t = a.search(/[^\.\d]/); } + if (t === -1) { t = b.search(/[^\.\d]/); } + a = a.substring(t); + b = b.substring(t); + } + } + return (a > b) ? 1 : -1; + } catch (er) { + return 0; + } + } + + function sortTextDesc(a,b){ + if ($.data(tbl[0], "tablesorter").sortLocaleCompare) { return b.localeCompare(a); } + return -sortText(a,b); + } + + function sortNumeric(a, b) { + return a - b; + } + + function sortNumericDesc(a, b) { + return b - a; + } + + /* public methods */ + this.construct = function(settings){ + return this.each(function(){ + // if no thead or tbody quit. + if (!this.tHead || !this.tBodies) { return; } + // declare + var $this, $document, $headers, cache, config, shiftDown = 0, + sortOrder, sortCSS, totalRows, $cell, i, j, a, s, o; + // new blank config object + this.config = {}; + // merge and extend. + config = $.extend(this.config, $.tablesorter.defaults, settings); + // store common expression for speed + tbl = $this = $(this).addClass(this.config.tableClass); + // save the settings where they read + $.data(this, "tablesorter", config); + // build headers + $headers = buildHeaders(this); + // try to auto detect column type, and store in tables config + this.config.parsers = buildParserCache(this, $headers); + // build the cache for the tbody cells + cache = buildCache(this); + // get the css class names, could be done else where. + sortCSS = [config.cssDesc, config.cssAsc]; + // fixate columns if the users supplies the fixedWidth option + fixColumnWidth(this); + // apply event handling to headers + // this is to big, perhaps break it out? + $headers + .click(function(e){ + totalRows = ($this[0].tBodies[0] && $this[0].tBodies[0].rows.length) || 0; + if (!this.sortDisabled && totalRows > 0) { + // Only call sortStart if sorting is enabled. + $this.trigger("sortStart"); + // store exp, for speed + $cell = $(this); + // get current column index + i = this.column; + // get current column sort order + this.order = this.count++ % 2; + // always sort on the locked order. + if(this.lockedOrder) { this.order = this.lockedOrder; } + // user only whants to sort on one + // column + if (!e[config.sortMultiSortKey]) { + // flush the sort list + config.sortList = []; + if (config.sortForce !== null) { + a = config.sortForce; + for (j = 0; j < a.length; j++) { + if (a[j][0] !== i) { + config.sortList.push(a[j]); + } + } + } + // add column to sort list + config.sortList.push([i, this.order]); + // multi column sorting + } else { + // the user has clicked on an all + // ready sortet column. + if (isValueInArray(i, config.sortList)) { + // revers the sorting direction + // for all tables. + for (j = 0; j < config.sortList.length; j++) { + s = config.sortList[j]; + o = config.headerList[s[0]]; + if (s[0] === i) { + o.count = s[1]; + o.count++; + s[1] = o.count % 2; + } + } + } else { + // add column to sort list array + config.sortList.push([i, this.order]); + } + } + setTimeout(function () { + // set css for headers + setHeadersCss($this[0], $headers, config.sortList, sortCSS); + appendToTable( + $this[0], multisort( + $this[0], config.sortList, cache) + ); + }, 1); + // stop normal event by returning false + return false; + } + // cancel selection + }) + .mousedown(function(){ + if (config.cancelSelection) { + this.onselectstart = function(){ + return false; + }; + return false; + } + }); + // apply easy methods that trigger binded events + $this + .bind("update", function(){ + var me = this; + setTimeout(function(){ + // rebuild parsers. + me.config.parsers = buildParserCache( + me, $headers); + // rebuild the cache map + cache = buildCache(me); + }, 1); + }) + .bind("updateCell", function(e, cell) { + var config = this.config, + // get position from the dom. + pos = [(cell.parentNode.rowIndex - 1), cell.cellIndex]; + // update cache + cache.normalized[pos[0]][pos[1]] = config.parsers[pos[1]].format( + getElementText(config, cell), cell); + }) + .bind("sorton", function(e, list) { + $(this).trigger("sortStart"); + config.sortList = list; + // update and store the sortlist + var sortList = config.sortList; + // update header count index + updateHeaderSortCount(this, sortList); + // set css for headers + setHeadersCss(this, $headers, sortList, sortCSS); + // sort the table and append it to the dom + appendToTable(this, multisort(this, sortList, cache)); + }) + .bind("appendCache", function () { + appendToTable(this, cache); + }) + .bind("applyWidgetId", function (e, id) { + getWidgetById(id).format(this); + }) + .bind("applyWidgets", function () { + // apply widgets + applyWidget(this); + }); + if ($.metadata && ($(this).metadata() && $(this).metadata().sortlist)) { + config.sortList = $(this).metadata().sortlist; + } + // if user has supplied a sort list to constructor. + if (config.sortList.length > 0) { + $this.trigger("sorton", [config.sortList]); + } + // apply widgets + applyWidget(this); + }); + }; + this.addParser = function(parser) { + var i, l = parsers.length, a = true; + for (i = 0; i < l; i++) { + if (parsers[i].id.toLowerCase() === parser.id.toLowerCase()) { + a = false; + } + } + if (a) { + parsers.push(parser); + } + }; + this.addWidget = function (widget) { + widgets.push(widget); + }; + this.formatFloat = function (s) { + var i = parseFloat(s); + return (isNaN(i)) ? 0 : i; + }; + this.formatInt = function (s) { + var i = parseInt(s, 10); + return (isNaN(i)) ? 0 : i; + }; + this.isDigit = function (s, config) { + // replace all an wanted chars and match. + return (/^[\-+]?\d*$/).test($.trim(s.replace(/[,.']/g, ''))); + }; + this.clearTableBody = function (table) { + if ($.browser.msie) { + var empty = function() { + while (this.firstChild) { + this.removeChild(this.firstChild); + } + }; + empty.apply(table.tBodies[0]); + } else { + table.tBodies[0].innerHTML = ""; + } + }; + } + })(); + + // extend plugin scope + $.fn.extend({ + tablesorter: $.tablesorter.construct + }); + + // make shortcut + var ts = $.tablesorter; + + // add default parsers + ts.addParser({ + id: "text", + is: function(s){ + return true; + }, + format: function(s) { + return $.trim(s.toLocaleLowerCase()); + }, + type: "text" + }); + + ts.addParser({ + id: "digit", + is: function(s, table){ + var c = table.config; + return $.tablesorter.isDigit(s, c); + }, + format: function(s){ + return $.tablesorter.formatFloat(s); + }, + type: "numeric" + }); + + ts.addParser({ + id: "currency", + is: function(s){ + return (/^[£$€?.]/).test(s); + }, + format: function(s){ + return $.tablesorter.formatFloat(s.replace(new RegExp(/[£$€]/g), "")); + }, + type: "numeric" + }); + + ts.addParser({ + id: "ipAddress", + is: function(s) { + return (/^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/).test(s); + }, + format: function(s){ + var i, item, a = s.split("."), + r = "", + l = a.length; + for (i = 0; i < l; i++) { + item = a[i]; + if (item.length === 2) { + r += "0" + item; + } else { + r += item; + } + } + return $.tablesorter.formatFloat(r); + }, + type: "numeric" + }); + + ts.addParser({ + id: "url", + is: function(s) { + return (/^(https?|ftp|file):\/\/$/).test(s); + }, + format: function(s) { + return $.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//), '')); + }, + type: "text" + }); + + ts.addParser({ + id: "isoDate", + is: function(s) { + return (/^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/).test(s); + }, + format: function (s) { + return $.tablesorter.formatFloat((s !== "") ? new Date(s.replace( + new RegExp(/-/g), "/")).getTime() : "0"); + }, + type: "numeric" + }); + + ts.addParser({ + id: "percent", + is: function(s) { + return (/\%$/).test($.trim(s)); + }, + format: function(s) { + return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g), "")); + }, + type: "numeric" + }); + + ts.addParser({ + id: "usLongDate", + is: function(s) { + return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/)); + }, + format: function(s) { + return $.tablesorter.formatFloat(new Date(s).getTime()); + }, + type: "numeric" + }); + + ts.addParser({ + id: "shortDate", + is: function(s) { + return (/\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/).test(s); + }, + format: function(s, table) { + var c = table.config; + s = s.replace(/\-/g, "/"); + if (c.dateFormat === "us") { + // reformat the string in ISO format + s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$1/$2"); + } else if (c.dateFormat === "uk") { + // reformat the string in ISO format + s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$2/$1"); + } else if (c.dateFormat === "dd/mm/yy" || c.dateFormat === "dd-mm-yy") { + s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, "$1/$2/$3"); + } + return $.tablesorter.formatFloat(new Date(s).getTime()); + }, + type: "numeric" + }); + + ts.addParser({ + id: "time", + is: function(s) { + return (/^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/).test(s); + }, + format: function(s) { + return $.tablesorter.formatFloat(new Date("2000/01/01 " + s).getTime()); + }, + type: "numeric" + }); + + ts.addParser({ + id: "metadata", + is: function(s) { + return false; + }, + format: function(s, table, cell) { + var c = table.config, + p = (!c.parserMetadataName) ? 'sortValue' : c.parserMetadataName; + return $(cell).metadata()[p]; + }, + type: "numeric" + }); + + // add default widgets + ts.addWidget({ + id: "zebra", + format: function(table) { + var $tr, row = -1, + odd, time; + if (table.config.debug) { + time = new Date(); + } + // loop through the visible rows + $("tr:visible", table.tBodies[0]).each(function (i) { + $tr = $(this); + // style children rows the same way the parent + // row was styled + if (!$tr.hasClass(table.config.cssChildRow)) { row++; } + odd = (row % 2 === 0); + $tr + .removeClass(table.config.widgetZebra.css[odd ? 0 : 1]) + .addClass(table.config.widgetZebra.css[odd ? 1 : 0]); + }); + if (table.config.debug) { + $.tablesorter.benchmark("Applying Zebra widget", time); + } + } + }); + +})(jQuery); \ No newline at end of file diff --git a/js/jquery.tablesorter.min.js b/js/jquery.tablesorter.min.js new file mode 100644 index 00000000..f155150e --- /dev/null +++ b/js/jquery.tablesorter.min.js @@ -0,0 +1,7 @@ +/* +* TableSorter 2.0 - Client-side table sorting with ease! +* Version 2.0.6 +* Copyright (c) 2007 Christian Bach +*/ + +(function(c){c.extend({tablesorter:new function(){function a(b){typeof console!=="undefined"&&typeof console.debug!=="undefined"?console.log(b):alert(b)}function k(b,d){a(b+","+((new Date).getTime()-d.getTime())+"ms")}function o(b,d){var a="";if(!d)return"";if(!b.supportsTextContent)b.supportsTextContent=d.textContent||!1;return a=b.textExtraction==="simple"?b.supportsTextContent?d.textContent:d.childNodes[0]&&d.childNodes[0].hasChildNodes()?d.childNodes[0].innerHTML:d.innerHTML:typeof b.textExtraction=== "function"?b.textExtraction(d):c(d).text()}function i(b){var d,a=p.length;for(d=0;d").each(function(a){this.column=d[this.parentNode.rowIndex+"-"+this.cellIndex];this.count=this.order=typeof b.config.sortInitialOrder!=="Number"?b.config.sortInitialOrder.toLowerCase()==="desc"?1:0:b.config.sortInitialOrder===1?1:0;if(c.metadata&&c(this).metadata().sorter===!1||b.config.headers[a]&&b.config.headers[a].sorter===!1)this.sortDisabled=!0;if(B(b,a))this.order=this.lockedOrder=B(b,a);if(!this.sortDisabled){var g= c(this).addClass(b.config.cssHeader);b.config.onRenderHeader&&b.config.onRenderHeader.apply(g)}b.config.headerList[a]=this});b.config.debug&&(k("Built headers:",r),a(h));return h}function G(b,a){var c,h=a.length;for(c=0;c"), c("tr:first td",b.tBodies[0]).each(function(){a.append(c("").css("width",c(this).width()))}),c(b).prepend(a))}function D(a,c,o){var h="var sortWrapper = function(a,b) {",e=c.length,g,f,l,j,m,i;a.config.debug&&(g=new Date);for(f=0;f0){d.trigger("sortStart");c(this);l=this.column;this.order=this.count++%2;if(this.lockedOrder)this.order=this.lockedOrder;if(a[e.sortMultiSortKey])if(G(l,e.sortList))for(j=0;j0&&d.trigger("sorton",[e.sortList]); x(this)}})};this.addParser=function(a){var c,k=p.length,h=!0;for(c=0;c= (c.totalPages-1)) { + c.page = (c.totalPages-1); + } + moveToPage(table); + } + + function moveToPrevPage(table) { + var c = table.config; + c.page--; + if(c.page <= 0) { + c.page = 0; + } + moveToPage(table); + } + + + function moveToPage(table) { + var c = table.config; + if(c.page < 0 || c.page > (c.totalPages-1)) { + c.page = 0; + } + + renderTable(table,c.rowsCopy); + } + + function renderTable(table,rows) { + + var c = table.config; + var l = rows.length; + var s = (c.page * c.size); + var e = (s + c.size); + if(e > rows.length ) { + e = rows.length; + } + + + var tableBody = $(table.tBodies[0]); + + // clear the table body + + $.tablesorter.clearTableBody(table); + + for(var i = s; i < e; i++) { + + //tableBody.append(rows[i]); + + var o = rows[i]; + var l = o.length; + for(var j=0; j < l; j++) { + + tableBody[0].appendChild(o[j]); + + } + } + + fixPosition(table,tableBody); + + $(table).trigger("applyWidgets"); + + if( c.page >= c.totalPages ) { + moveToLastPage(table); + } + + updatePageDisplay(c); + } + + this.appender = function(table,rows) { + + var c = table.config; + + c.rowsCopy = rows; + c.totalRows = rows.length; + c.totalPages = Math.ceil(c.totalRows / c.size); + + renderTable(table,rows); + }; + + this.defaults = { + size: 10, + offset: 0, + page: 0, + totalRows: 0, + totalPages: 0, + container: null, + cssNext: '.next', + cssPrev: '.prev', + cssFirst: '.first', + cssLast: '.last', + cssPageDisplay: '.pagedisplay', + cssPageSize: '.pagesize', + seperator: "/", + positionFixed: true, + appender: this.appender + }; + + this.construct = function(settings) { + + return this.each(function() { + + config = $.extend(this.config, $.tablesorterPager.defaults, settings); + + var table = this, pager = config.container; + + $(this).trigger("appendCache"); + + config.size = parseInt($(".pagesize",pager).val()); + + $(config.cssFirst,pager).click(function() { + moveToFirstPage(table); + return false; + }); + $(config.cssNext,pager).click(function() { + moveToNextPage(table); + return false; + }); + $(config.cssPrev,pager).click(function() { + moveToPrevPage(table); + return false; + }); + $(config.cssLast,pager).click(function() { + moveToLastPage(table); + return false; + }); + $(config.cssPageSize,pager).change(function() { + setPageSize(table,parseInt($(this).val())); + return false; + }); + }); + }; + + } + }); + // extend plugin scope + $.fn.extend({ + tablesorterPager: $.tablesorterPager.construct + }); + +})(jQuery); \ No newline at end of file