PageSourceSearch

https://www.easternct.edu/_files/js/tablesaw.js

js easternct.edu collected 2026-10-02 03:19:30 UTC 35,328 bytes, 1,261 lines download raw bytes

1/*! Tablesaw - v1.0.4 - 2015-02-19
2* https://github.com/filamentgroup/tablesaw
3* Copyright (c) 2015 Filament Group; Licensed MIT */
4;(function( $ ) {
5	var div = document.createElement('div'),
6		all = div.getElementsByTagName('i'),
7		$doc = $( document.documentElement );
8
9	div.innerHTML = '<!--[if lte IE 8]><i></i><![endif]-->';
10	if( all[ 0 ] ) {
11		$doc.addClass( 'ie-lte8' );
12	}
13
14	// Cut the mustard
15	if( !( 'querySelector' in document ) ||
16			( window.blackberry && !window.WebKitPoint ) ||
17			window.operamini ) {
18		return;
19	} else {
20		$doc.addClass( 'tablesaw-enhanced' );
21
22		// DOM-ready auto-init of plugins.
23		// Many plugins bind to an "enhance" event to init themselves on dom ready, or when new markup is inserted into the DOM
24		$( function(){
25			$( document ).trigger( "enhance.tablesaw" );
26		});
27	}
28
29})( jQuery );
30/*
31* tablesaw: A set of plugins for responsive tables
32* Stack and Column Toggle tables
33* Copyright (c) 2013 Filament Group, Inc.
34* MIT License
35*/
36
37if( typeof Tablesaw === "undefined" ) {
38	Tablesaw = {
39		i18n: {
40			modes: [ 'Stack', 'Swipe', 'Toggle' ],
41			columns: 'Col<span class=\"a11y-sm\">umn</span>s',
42			columnBtnText: 'Columns',
43			columnsDialogError: 'No eligible columns.',
44			sort: 'Sort By'
45		}
46	};
47}
48if( !Tablesaw.config ) {
49	Tablesaw.config = {};
50}
51
52;(function( $ ) {
53	var pluginName = "table",
54		classes = {
55			toolbar: "tablesaw-bar"
56		},
57		events = {
58			create: "tablesawcreate",
59			destroy: "tablesawdestroy",
60			refresh: "tablesawrefresh"
61		},
62		defaultMode = "stack",
63		initSelector = "table[data-tablesaw-mode],table[data-tablesaw-sortable]";
64
65	var Table = function( element ) {
66		if( !element ) {
67			throw new Error( "Tablesaw requires an element." );
68		}
69
70		this.table = element;
71		this.$table = $( element );
72
73		this.mode = this.$table.attr( "data-tablesaw-mode" ) || defaultMode;
74
75		this.init();
76	};
77
78	Table.prototype.init = function() {
79		// assign an id if there is none
80		if ( !this.$table.attr( "id" ) ) {
81			this.$table.attr( "id", pluginName + "-" + Math.round( Math.random() * 10000 ) );
82		}
83
84		this.createToolbar();
85
86		var colstart = this._initCells();
87
88		this.$table.trigger( events.create, [ this, colstart ] );
89	};
90
91	Table.prototype._initCells = function() {
92		var colstart,
93			thrs = this.table.querySelectorAll( "thead tr" ),
94			self = this;
95
96		$( thrs ).each( function(){
97			var coltally = 0;
98
99			$( this ).children().each( function(){
100				var span = parseInt( this.getAttribute( "colspan" ), 10 ),
101					sel = ":nth-child(" + ( coltally + 1 ) + ")";
102
103				colstart = coltally + 1;
104
105				if( span ){
106					for( var k = 0; k < span - 1; k++ ){
107						coltally++;
108						sel += ", :nth-child(" + ( coltally + 1 ) + ")";
109					}
110				}
111
112				// Store "cells" data on header as a reference to all cells in the same column as this TH
113				this.cells = self.$table.find("tr").not( $( thrs ).eq( 0 ) ).not( this ).children( sel );
114				coltally++;
115			});
116		});
117
118		return colstart;
119	};
120
121	Table.prototype.refresh = function() {
122		this._initCells();
123
124		this.$table.trigger( events.refresh );
125	};
126
127	Table.prototype.createToolbar = function() {
128		// Insert the toolbar
129		// TODO move this into a separate component
130		var $toolbar = this.$table.prev( '.' + classes.toolbar );
131		if( !$toolbar.length ) {
132			$toolbar = $( '<div>' )
133				.addClass( classes.toolbar )
134				.insertBefore( this.$table );
135		}
136		this.$toolbar = $toolbar;
137
138		if( this.mode ) {
139			this.$toolbar.addClass( 'mode-' + this.mode );
140		}
141	};
142
143	Table.prototype.destroy = function() {
144		// Don’t remove the toolbar. Some of the table features are not yet destroy-friendly.
145		this.$table.prev( '.' + classes.toolbar ).each(function() {
146			this.className = this.className.replace( /\bmode\-\w*\b/gi, '' );
147		});
148
149		var tableId = this.$table.attr( 'id' );
150		$( document ).unbind( "." + tableId );
151		$( window ).unbind( "." + tableId );
152
153		// other plugins
154		this.$table.trigger( events.destroy, [ this ] );
155
156		this.$table.removeAttr( 'data-tablesaw-mode' );
157
158		this.$table.removeData( pluginName );
159	};
160
161	// Collection method.
162	$.fn[ pluginName ] = function() {
163		return this.each( function() {
164			var $t = $( this );
165
166			if( $t.data( pluginName ) ){
167				return;
168			}
169
170			var table = new Table( this );
171			$t.data( pluginName, table );
172		});
173	};
174
175	$( document ).on( "enhance.tablesaw", function( e ) {
176		$( e.target ).find( initSelector )[ pluginName ]();
177	});
178
179}( jQuery ));
180
181;(function( win, $, undefined ){
182
183	var classes = {
184		stackTable: 'tablesaw-stack',
185		cellLabels: 'tablesaw-cell-label',
186		cellContentLabels: 'tablesaw-cell-content'
187	};
188
189	var data = {
190		obj: 'tablesaw-stack'
191	};
192
193	var attrs = {
194		labelless: 'data-tablesaw-no-labels',
195		hideempty: 'data-tablesaw-hide-empty'
196	};
197
198	var Stack = function( element ) {
199
200		this.$table = $( element );
201
202		this.labelless = this.$table.is( '[' + attrs.labelless + ']' );
203		this.hideempty = this.$table.is( '[' + attrs.hideempty + ']' );
204
205		if( !this.labelless ) {
206			// allHeaders references headers, plus all THs in the thead, which may include several rows, or not
207			this.allHeaders = this.$table.find( "th" );
208		}
209
210		this.$table.data( data.obj, this );
211	};
212
213	Stack.prototype.init = function( colstart ) {
214		this.$table.addClass( classes.stackTable );
215
216		if( this.labelless ) {
217			return;
218		}
219
220		// get headers in reverse order so that top-level headers are appended last
221		var reverseHeaders = $( this.allHeaders );
222		var hideempty = this.hideempty;
223		
224		// create the hide/show toggles
225		reverseHeaders.each(function(){
226			var $t = $( this ),
227				$cells = $( this.cells ).filter(function() {
228					return !$( this ).parent().is( "[" + attrs.labelless + "]" ) && ( !hideempty || !$( this ).is( ":empty" ) );
229				}),
230				hierarchyClass = $cells.not( this ).filter( "thead th" ).length && " tablesaw-cell-label-top",
231				// TODO reduce coupling with sortable
232				$sortableButton = $t.find( ".tablesaw-sortable-btn" ),
233				html = $sortableButton.length ? $sortableButton.html() : $t.html();
234
235			if( html !== "" ){
236				if( hierarchyClass ){
237					var iteration = parseInt( $( this ).attr( "colspan" ), 10 ),
238						filter = "";
239
240					if( iteration ){
241						filter = "td:nth-child("+ iteration +"n + " + ( colstart ) +")";
242					}
243					$cells.filter( filter ).prepend( "<b class='" + classes.cellLabels + hierarchyClass + "'>" + html + "</b>"  );
244				} else {
245					$cells.wrapInner( "<span class='" + classes.cellContentLabels + "'></span>" );
246					$cells.prepend( "<b class='" + classes.cellLabels + "'>" + html + "</b>"  );
247				}
248			}
249		});
250	};
251
252	Stack.prototype.destroy = function() {
253		this.$table.removeClass( classes.stackTable );
254		this.$table.find( '.' + classes.cellLabels ).remove();
255		this.$table.find( '.' + classes.cellContentLabels ).each(function() {
256			$( this ).replaceWith( this.childNodes );
257		});
258	};
259
260	// on tablecreate, init
261	$( document ).on( "tablesawcreate", function( e, Tablesaw, colstart ){
262		if( Tablesaw.mode === 'stack' ){
263			var table = new Stack( Tablesaw.table );
264			table.init( colstart );
265		}
266
267	} );
268
269	$( document ).on( "tablesawdestroy", function( e, Tablesaw ){
270
271		if( Tablesaw.mode === 'stack' ){
272			$( Tablesaw.table ).data( data.obj ).destroy();
273		}
274
275	} );
276
277}( this, jQuery ));
278;(function( $ ) {
279	var pluginName = "tablesawbtn",
280		initSelector = ".btn",
281		methods = {
282			_create: function(){
283				return $( this ).each(function() {
284					$( this )
285						.trigger( "beforecreate." + pluginName )
286						[ pluginName ]( "_init" )
287						.trigger( "create." + pluginName );
288				});
289			},
290			_init: function(){
291				var oEl = $( this ),
292					sel = this.getElementsByTagName( "select" )[ 0 ];
293
294				if( sel ) {
295					$( this )
296						.addClass( "btn-select" )
297						[ pluginName ]( "_select", sel );
298				}
299				return oEl;
300			},
301			_select: function( sel ) {
302				var update = function( oEl, sel ) {
303					var opts = $( sel ).find( "option" ),
304						label, el, children;
305
306					opts.each(function() {
307						var opt = this;
308						if( opt.selected ) {
309							label = document.createTextNode( opt.text );
310						}
311					});
312
313					children = oEl.childNodes;
314					if( opts.length > 0 ){
315						for( var i = 0, l = children.length; i < l; i++ ) {
316							el = children[ i ];
317
318							if( el && el.nodeType === 3 ) {
319								oEl.replaceChild( label, el );
320							}
321						}
322					}
323				};
324
325				update( this, sel );
326				$( this ).bind( "change refresh", function() {
327					update( this, sel );
328				});
329			}
330		};
331
332	// Collection method.
333	$.fn[ pluginName ] = function( arrg, a, b, c ) {
334		return this.each(function() {
335
336		// if it's a method
337		if( arrg && typeof( arrg ) === "string" ){
338			return $.fn[ pluginName ].prototype[ arrg ].call( this, a, b, c );
339		}
340
341		// don't re-init
342		if( $( this ).data( pluginName + "active" ) ){
343			return $( this );
344		}
345
346		// otherwise, init
347
348		$( this ).data( pluginName + "active", true );
349			$.fn[ pluginName ].prototype._create.call( this );
350		});
351	};
352
353	// add methods
354	$.extend( $.fn[ pluginName ].prototype, methods );
355
356	$( document ).on( "enhance", function( e ) {
357		$( initSelector, e.target )[ pluginName ]();
358	});
359
360}( jQuery ));
361;(function( win, $, undefined ){
362
363	var ColumnToggle = function( element ) {
364
365		this.$table = $( element );
366
367		this.classes = {
368			columnToggleTable: 'tablesaw-columntoggle',
369			columnBtnContain: 'tablesaw-columntoggle-btnwrap tablesaw-advance',
370			columnBtn: 'tablesaw-columntoggle-btn tablesaw-nav-btn down',
371			popup: 'tablesaw-columntoggle-popup',
372			priorityPrefix: 'tablesaw-priority-',
373			// TODO duplicate class, also in tables.js
374			toolbar: 'tablesaw-bar'
375		};
376
377		// Expose headers and allHeaders properties on the widget
378		// headers references the THs within the first TR in the table
379		this.headers = this.$table.find( 'tr:first > th' );
380
381		this.$table.data( 'tablesaw-coltoggle', this );
382	};
383
384	ColumnToggle.prototype.init = function() {
385
386		var tableId,
387			id,
388			$menuButton,
389			$popup,
390			$menu,
391			$btnContain,
392			self = this;
393
394		this.$table.addClass( this.classes.columnToggleTable );
395
396		tableId = this.$table.attr( "id" );
397		id = tableId + "-popup";
398		$btnContain = $( "<div class='" + this.classes.columnBtnContain + "'></div>" );
399		$menuButton = $( "<a href='#" + id + "' class='btn btn-micro " + this.classes.columnBtn +"' data-popup-link>" +
400										"<span>" + Tablesaw.i18n.columnBtnText + "</span></a>" );
401		$popup = $( "<div class='dialog-table-coltoggle " + this.classes.popup + "' id='" + id + "'></div>" );
402		$menu = $( "<div class='btn-group'></div>" );
403
404		var hasNonPersistentHeaders = false;
405		$( this.headers ).not( "td" ).each( function() {
406			var $this = $( this ),
407				priority = $this.attr("data-tablesaw-priority"),
408				$cells = $this.add( this.cells );
409
410			if( priority && priority !== "persist" ) {
411				$cells.addClass( self.classes.priorityPrefix + priority );
412
413				$("<label><input type='checkbox' checked>" + $this.text() + "</label>" )
414					.appendTo( $menu )
415					.children( 0 )
416					.data( "cells", $cells );
417
418				hasNonPersistentHeaders = true;
419			}
420		});
421
422		if( !hasNonPersistentHeaders ) {
423			$menu.append( '<label>' + Tablesaw.i18n.columnsDialogError + '</label>' );
424		}
425
426		$menu.appendTo( $popup );
427
428		// bind change event listeners to inputs - TODO: move to a private method?
429		$menu.find( 'input[type="checkbox"]' ).on( "change", function(e) {
430			var checked = e.target.checked;
431
432			$( e.target ).data( "cells" )
433				.toggleClass( "tablesaw-cell-hidden", !checked )
434				.toggleClass( "tablesaw-cell-visible", checked );
435
436			self.$table.trigger( 'tablesawcolumns' );
437		});
438
439		$menuButton.appendTo( $btnContain );
440		$btnContain.appendTo( this.$table.prev( '.' + this.classes.toolbar ) );
441
442		var closeTimeout;
443		function openPopup() {
444			$btnContain.addClass( 'visible' );
445			$menuButton.removeClass( 'down' ).addClass( 'up' );
446
447			$( document ).unbind( 'click.' + tableId, closePopup );
448
449			window.clearTimeout( closeTimeout );
450			closeTimeout = window.setTimeout(function() {
451				$( document ).one( 'click.' + tableId, closePopup );
452			}, 15 );
453		}
454
455		function closePopup( event ) {
456			// Click came from inside the popup, ignore.
457			if( event && $( event.target ).closest( "." + self.classes.popup ).length ) {
458				return;
459			}
460
461			$( document ).unbind( 'click.' + tableId );
462			$menuButton.removeClass( 'up' ).addClass( 'down' );
463			$btnContain.removeClass( 'visible' );
464		}
465
466		$menuButton.on( "click.tablesaw", function( event ) {
467			event.preventDefault();
468
469			if( !$btnContain.is( ".visible" ) ) {
470				openPopup();
471			} else {
472				closePopup();
473			}
474		});
475
476		$popup.appendTo( $btnContain );
477
478		this.$menu = $menu;
479
480		$(window).on( "resize." + tableId, function(){
481			self.refreshToggle();
482		});
483
484		this.refreshToggle();
485	};
486
487	ColumnToggle.prototype.refreshToggle = function() {
488		this.$menu.find( "input" ).each( function() {
489			var $this = $( this );
490
491			this.checked = $this.data( "cells" ).eq( 0 ).css( "display" ) === "table-cell";
492		});
493	};
494
495	ColumnToggle.prototype.refreshPriority = function(){
496		var self = this;
497		$(this.headers).not( "td" ).each( function() {
498			var $this = $( this ),
499				priority = $this.attr("data-tablesaw-priority"),
500				$cells = $this.add( this.cells );
501
502			if( priority && priority !== "persist" ) {
503				$cells.addClass( self.classes.priorityPrefix + priority );
504			}
505		});
506	};
507
508	ColumnToggle.prototype.destroy = function() {
509		// table toolbars, document and window .tableId events
510		// removed in parent tables.js destroy method
511
512		this.$table.removeClass( this.classes.columnToggleTable );
513		this.$table.find( 'th, td' ).each(function() {
514			var $cell = $( this );
515			$cell.removeClass( 'tablesaw-cell-hidden' )
516				.removeClass( 'tablesaw-cell-visible' );
517
518			this.className = this.className.replace( /\bui\-table\-priority\-\d\b/g, '' );
519		});
520	};
521
522	// on tablecreate, init
523	$( document ).on( "tablesawcreate", function( e, Tablesaw ){
524
525		if( Tablesaw.mode === 'columntoggle' ){
526			var table = new ColumnToggle( Tablesaw.table );
527			table.init();
528		}
529
530	} );
531
532	$( document ).on( "tablesawdestroy", function( e, Tablesaw ){
533		if( Tablesaw.mode === 'columntoggle' ){
534			$( Tablesaw.table ).data( 'tablesaw-coltoggle' ).destroy();
535		}
536	} );
537
538}( this, jQuery ));
539;(function( win, $, undefined ){
540
541	$.extend( Tablesaw.config, {
542		swipe: {
543			horizontalThreshold: 15,
544			verticalThreshold: 30
545		}
546	});
547
548	function createSwipeTable( $table ){
549
550		var $btns = $( "<div class='tablesaw-advance'></div>" ),
551			$prevBtn = $( "<a href='#' class='tablesaw-nav-btn btn btn-micro left' title='Previous Column'></a>" ).appendTo( $btns ),
552			$nextBtn = $( "<a href='#' class='tablesaw-nav-btn btn btn-micro right' title='Next Column'></a>" ).appendTo( $btns ),
553			hideBtn = 'disabled',
554			persistWidths = 'tablesaw-fix-persist',
555			$headerCells = $table.find( "thead th" ),
556			$headerCellsNoPersist = $headerCells.not( '[data-tablesaw-priority="persist"]' ),
557			headerWidths = [],
558			$head = $( document.head || 'head' ),
559			tableId = $table.attr( 'id' ),
560			// TODO switch this to an nth-child feature test
561			isIE8 = $( 'html' ).is( '.ie-lte8' );
562
563		if( !$headerCells.length ) {
564			throw new Error( "tablesaw swipe: no header cells found. Are you using <th> inside of <thead>?" );
565		}
566
567		// Calculate initial widths
568		$table.css('width', 'auto');
569		$headerCells.each(function() {
570			headerWidths.push( $( this ).outerWidth() );
571		});
572		$table.css( 'width', '' );
573
574		$btns.appendTo( $table.prev( '.tablesaw-bar' ) );
575
576		$table.addClass( "tablesaw-swipe" );
577
578		if( !tableId ) {
579			tableId = 'tableswipe-' + Math.round( Math.random() * 10000 );
580			$table.attr( 'id', tableId );
581		}
582
583		function $getCells( headerCell ) {
584			return $( headerCell.cells ).add( headerCell );
585		}
586
587		function showColumn( headerCell ) {
588			$getCells( headerCell ).removeClass( 'tablesaw-cell-hidden' );
589		}
590
591		function hideColumn( headerCell ) {
592			$getCells( headerCell ).addClass( 'tablesaw-cell-hidden' );
593		}
594
595		function persistColumn( headerCell ) {
596			$getCells( headerCell ).addClass( 'tablesaw-cell-persist' );
597		}
598
599		function isPersistent( headerCell ) {
600			return $( headerCell ).is( '[data-tablesaw-priority="persist"]' );
601		}
602
603		function unmaintainWidths() {
604			$table.removeClass( persistWidths );
605			$( '#' + tableId + '-persist' ).remove();
606		}
607
608		function maintainWidths() {
609			var prefix = '#' + tableId + '.tablesaw-swipe ',
610				styles = [],
611				tableWidth = $table.width(),
612				hash = [],
613				newHash;
614
615			$headerCells.each(function( index ) {
616				var width;
617				if( isPersistent( this ) ) {
618					width = $( this ).outerWidth();
619
620					// Only save width on non-greedy columns (take up less than 75% of table width)
621					if( width < tableWidth * 0.75 ) {
622						hash.push( index + '-' + width );
623						styles.push( prefix + ' .tablesaw-cell-persist:nth-child(' + ( index + 1 ) + ') { width: ' + width + 'px; }' );
624					}
625				}
626			});
627			newHash = hash.join( '_' );
628
629			$table.addClass( persistWidths );
630
631			var $style = $( '#' + tableId + '-persist' );
632			// If style element not yet added OR if the widths have changed
633			if( !$style.length || $style.data( 'hash' ) !== newHash ) {
634				// Remove existing
635				$style.remove();
636
637				if( styles.length ) {
638					$( '<style>' + styles.join( "\n" ) + '</style>' )
639						.attr( 'id', tableId + '-persist' )
640						.data( 'hash', newHash )
641						.appendTo( $head );
642				}
643			}
644		}
645
646		function getNext(){
647			var next = [],
648				checkFound;
649
650			$headerCellsNoPersist.each(function( i ) {
651				var $t = $( this ),
652					isHidden = $t.css( "display" ) === "none" || $t.is( ".tablesaw-cell-hidden" );
653
654				if( !isHidden && !checkFound ) {
655					checkFound = true;
656					next[ 0 ] = i;
657				} else if( isHidden && checkFound ) {
658					next[ 1 ] = i;
659
660					return false;
661				}
662			});
663
664			return next;
665		}
666
667		function getPrev(){
668			var next = getNext();
669			return [ next[ 1 ] - 1 , next[ 0 ] - 1 ];
670		}
671
672		function nextpair( fwd ){
673			return fwd ? getNext() : getPrev();
674		}
675
676		function canAdvance( pair ){
677			return pair[ 1 ] > -1 && pair[ 1 ] < $headerCellsNoPersist.length;
678		}
679
680		function matchesMedia() {
681			var matchMedia = $table.attr( "data-tablesaw-swipe-media" );
682			return !matchMedia || ( "matchMedia" in win ) && win.matchMedia( matchMedia ).matches;
683		}
684
685		function fakeBreakpoints() {
686			if( !matchesMedia() ) {
687				return;
688			}
689
690			var extraPaddingPixels = 20,
691				containerWidth = $table.parent().width(),
692				persist = [],
693				sum = 0,
694				sums = [],
695				visibleNonPersistantCount = $headerCells.length;
696
697			$headerCells.each(function( index ) {
698				var $t = $( this ),
699					isPersist = $t.is( '[data-tablesaw-priority="persist"]' );
700
701				persist.push( isPersist );
702
703				sum += headerWidths[ index ] + ( isPersist ? 0 : extraPaddingPixels );
704				sums.push( sum );
705
706				// is persistent or is hidden
707				if( isPersist || sum > containerWidth ) {
708					visibleNonPersistantCount--;
709				}
710			});
711
712			var needsNonPersistentColumn = visibleNonPersistantCount === 0;
713
714			$headerCells.each(function( index ) {
715				if( persist[ index ] ) {
716
717					// for visual box-shadow
718					persistColumn( this );
719					return;
720				}
721
722				if( sums[ index ] <= containerWidth || needsNonPersistentColumn ) {
723					needsNonPersistentColumn = false;
724					showColumn( this );
725				} else {
726					hideColumn( this );
727				}
728			});
729
730			if( !isIE8 ) {
731				unmaintainWidths();
732			}
733			$table.trigger( 'tablesawcolumns' );
734		}
735
736		function advance( fwd ){
737			var pair = nextpair( fwd );
738			if( canAdvance( pair ) ){
739				if( isNaN( pair[ 0 ] ) ){
740					if( fwd ){
741						pair[0] = 0;
742					}
743					else {
744						pair[0] = $headerCellsNoPersist.length - 1;
745					}
746				}
747
748				if( !isIE8 ) {
749					maintainWidths();
750				}
751
752				hideColumn( $headerCellsNoPersist.get( pair[ 0 ] ) );
753				showColumn( $headerCellsNoPersist.get( pair[ 1 ] ) );
754
755				$table.trigger( 'tablesawcolumns' );
756			}
757		}
758
759		$prevBtn.add( $nextBtn ).click(function( e ){
760			advance( !!$( e.target ).closest( $nextBtn ).length );
761			e.preventDefault();
762		});
763
764		function getCoord( event, key ) {
765			return ( event.touches || event.originalEvent.touches )[ 0 ][ key ];
766		}
767
768		$table
769			.bind( "touchstart.swipetoggle", function( e ){
770				var originX = getCoord( e, 'pageX' ),
771					originY = getCoord( e, 'pageY' ),
772					x,
773					y;
774
775				$( win ).off( "resize", fakeBreakpoints );
776
777				$( this )
778					.bind( "touchmove", function( e ){
779						x = getCoord( e, 'pageX' );
780						y = getCoord( e, 'pageY' );
781						var cfg = Tablesaw.config.swipe;
782						if( Math.abs( x - originX ) > cfg.horizontalThreshold && Math.abs( y - originY ) < cfg.verticalThreshold ) {
783							e.preventDefault();
784						}
785					})
786					.bind( "touchend.swipetoggle", function(){
787						var cfg = Tablesaw.config.swipe;
788						if( Math.abs( y - originY ) < cfg.verticalThreshold ) {
789							if( x - originX < -1 * cfg.horizontalThreshold ){
790								advance( true );
791							}
792							if( x - originX > cfg.horizontalThreshold ){
793								advance( false );
794							}
795						}
796
797						window.setTimeout(function() {
798							$( win ).on( "resize", fakeBreakpoints );
799						}, 300);
800						$( this ).unbind( "touchmove touchend" );
801					});
802
803			})
804			.bind( "tablesawcolumns.swipetoggle", function(){
805				$prevBtn[ canAdvance( getPrev() ) ? "removeClass" : "addClass" ]( hideBtn );
806				$nextBtn[ canAdvance( getNext() ) ? "removeClass" : "addClass" ]( hideBtn );
807			})
808			.bind( "tablesawnext.swipetoggle", function(){
809				advance( true );
810			} )
811			.bind( "tablesawprev.swipetoggle", function(){
812				advance( false );
813			} )
814			.bind( "tablesawdestroy.swipetoggle", function(){
815				var $t = $( this );
816
817				$t.removeClass( 'tablesaw-swipe' );
818				$t.prev( '.tablesaw-bar' ).find( '.tablesaw-advance' ).remove();
819				$( win ).off( "resize", fakeBreakpoints );
820
821				$t.unbind( ".swipetoggle" );
822			});
823
824		fakeBreakpoints();
825		$( win ).on( "resize", fakeBreakpoints );
826	}
827
828
829
830	// on tablecreate, init
831	$( document ).on( "tablesawcreate", function( e, Tablesaw ){
832
833		if( Tablesaw.mode === 'swipe' ){
834			createSwipeTable( Tablesaw.$table );
835		}
836
837	} );
838
839}( this, jQuery ));
840
841;(function( $ ) {
842	function getSortValue( cell ) {
843		return $.map( cell.childNodes, function( el ) {
844				var $el = $( el );
845				if( $el.is( 'input, select' ) ) {
846					return $el.val();
847				} else if( $el.hasClass( 'tablesaw-cell-label' ) ) {
848					return;
849				}
850				return $.trim( $el.text() );
851			}).join( '' );
852	}
853
854	var pluginName = "tablesaw-sortable",
855		initSelector = "table[data-" + pluginName + "]",
856		sortableSwitchSelector = "[data-" + pluginName + "-switch]",
857		attrs = {
858			defaultCol: "data-tablesaw-sortable-default-col"
859		},
860		classes = {
861			head: pluginName + "-head",
862			ascend: pluginName + "-ascending",
863			descend: pluginName + "-descending",
864			switcher: pluginName + "-switch",
865			tableToolbar: 'tablesaw-toolbar',
866			sortButton: pluginName + "-btn"
867		},
868		methods = {
869			_create: function( o ){
870				return $( this ).each(function() {
871					var init = $( this ).data( "init" + pluginName );
872					if( init ) {
873						return false;
874					}
875					$( this )
876						.data( "init"+ pluginName, true )
877						.trigger( "beforecreate." + pluginName )
878						[ pluginName ]( "_init" , o )
879						.trigger( "create." + pluginName );
880				});
881			},
882			_init: function(){
883				var el = $( this ),
884					heads,
885					$switcher;
886
887				var addClassToTable = function(){
888						el.addClass( pluginName );
889					},
890					addClassToHeads = function( h ){
891						$.each( h , function( i , v ){
892							$( v ).addClass( classes.head );
893						});
894					},
895					makeHeadsActionable = function( h , fn ){
896						$.each( h , function( i , v ){
897							var b = $( "<button class='" + classes.sortButton + "'/>" );
898							b.bind( "click" , { col: v } , fn );
899							$( v ).wrapInner( b );
900						});
901					},
902					clearOthers = function( sibs ){
903						$.each( sibs , function( i , v ){
904							var col = $( v );
905							col.removeAttr( attrs.defaultCol );
906							col.removeClass( classes.ascend );
907							col.removeClass( classes.descend );
908						});
909					},
910					headsOnAction = function( e ){
911						if( $( e.target ).is( 'a[href]' ) ) {
912							return;
913						}
914
915						e.stopPropagation();
916						var head = $( this ).parent(),
917							v = e.data.col,
918							newSortValue = heads.index( head );
919
920						clearOthers( head.siblings() );
921						if( head.hasClass( classes.descend ) ){
922							el[ pluginName ]( "sortBy" , v , true);
923							newSortValue += '_asc';
924						} else {
925							el[ pluginName ]( "sortBy" , v );
926							newSortValue += '_desc';
927						}
928						if( $switcher ) {
929							$switcher.find( 'select' ).val( newSortValue ).trigger( 'refresh' );
930						}
931
932						e.preventDefault();
933					},
934					handleDefault = function( heads ){
935						$.each( heads , function( idx , el ){
936							var $el = $( el );
937							if( $el.is( "[" + attrs.defaultCol + "]" ) ){
938								if( !$el.hasClass( classes.descend ) ) {
939									$el.addClass( classes.ascend );
940								}
941							}
942						});
943					},
944					addSwitcher = function( heads ){
945						$switcher = $( '<div>' ).addClass( classes.switcher ).addClass( classes.tableToolbar ).html(function() {
946							var html = [ '<label>' + Tablesaw.i18n.sort + ':' ];
947
948							html.push( '<span class="btn btn-small">&#160;<select>' );
949							heads.each(function( j ) {
950								var $t = $( this ),
951									isDefaultCol = $t.is( "[" + attrs.defaultCol + "]" ),
952									isDescending = $t.hasClass( classes.descend ),
953									isNumeric = false;
954
955								// Check only the first three rows to see if the column is numbers.
956								$( this.cells ).slice( 0, 3 ).each(function() {
957									if( !isNaN( parseInt( getSortValue( this ), 10 ) ) ) {
958										isNumeric = true;
959										return false;
960									}
961								});
962
963								html.push( '<option' + ( isDefaultCol && !isDescending ? ' selected' : '' ) + ' value="' + j + '_asc">' + $t.text() + ' ' + ( isNumeric ? '↑' : '(A-Z)' ) + '</option>' );
964								html.push( '<option' + ( isDefaultCol && isDescending ? ' selected' : '' ) + ' value="' + j + '_desc">' + $t.text() + ' ' + ( isNumeric ? '↓' : '(Z-A)' ) + '</option>' );
965							});
966							html.push( '</select></span></label>' );
967
968							return html.join('');
969						});
970
971						var $toolbar = el.prev( '.tablesaw-bar' ),
972							$firstChild = $toolbar.children().eq( 0 );
973
974						if( $firstChild.length ) {
975							$switcher.insertBefore( $firstChild );
976						} else {
977							$switcher.appendTo( $toolbar );
978						}
979						$switcher.find( '.btn' ).tablesawbtn();
980						$switcher.find( 'select' ).on( 'change', function() {
981							var val = $( this ).val().split( '_' ),
982								head = heads.eq( val[ 0 ] );
983
984							clearOthers( head.siblings() );
985							el[ pluginName ]( 'sortBy', head.get( 0 ), val[ 1 ] === 'asc' );
986						});
987					};
988
989					addClassToTable();
990					heads = el.find( "thead th[data-" + pluginName + "-col]" );
991					addClassToHeads( heads );
992					makeHeadsActionable( heads , headsOnAction );
993					handleDefault( heads );
994
995					if( el.is( sortableSwitchSelector ) ) {
996						addSwitcher( heads, el.find('tbody tr:nth-child(-n+3)') );
997					}
998			},
999			getColumnNumber: function( col ){
1000				return $( col ).prevAll().length;
1001			},
1002			getTableRows: function(){
1003				return $( this ).find( "tbody tr" );
1004			},
1005			sortRows: function( rows , colNum , ascending, col ){
1006				var cells, fn, sorted;
1007				var getCells = function( rows ){
1008						var cells = [];
1009						$.each( rows , function( i , r ){
1010							cells.push({
1011								cell: getSortValue( $( r ).children().get( colNum ) ),
1012								rowNum: i
1013							});
1014						});
1015						return cells;
1016					},
1017					getSortFxn = function( ascending, forceNumeric ){
1018						var fn,
1019							regex = /[^\-\+\d\.]/g;
1020						if( ascending ){
1021							fn = function( a , b ){
1022								if( forceNumeric || !isNaN( parseFloat( a.cell ) ) ) {
1023									return parseFloat( a.cell.replace( regex, '' ) ) - parseFloat( b.cell.replace( regex, '' ) );
1024								} else {
1025									return a.cell.toLowerCase() > b.cell.toLowerCase() ? 1 : -1;
1026								}
1027							};
1028						} else {
1029							fn = function( a , b ){
1030								if( forceNumeric || !isNaN( parseFloat( a.cell ) ) ) {
1031									return parseFloat( b.cell.replace( regex, '' ) ) - parseFloat( a.cell.replace( regex, '' ) );
1032								} else {
1033									return a.cell.toLowerCase() < b.cell.toLowerCase() ? 1 : -1;
1034								}
1035							};
1036						}
1037						return fn;
1038					},
1039					applyToRows = function( sorted , rows ){
1040						var newRows = [], i, l, cur;
1041						for( i = 0, l = sorted.length ; i < l ; i++ ){
1042							cur = sorted[ i ].rowNum;
1043							newRows.push( rows[cur] );
1044						}
1045						return newRows;
1046					};
1047
1048				cells = getCells( rows );
1049				var customFn = $( col ).data( 'tablesaw-sort' );
1050				fn = ( customFn && typeof customFn === "function" ? customFn( ascending ) : false ) ||
1051					getSortFxn( ascending, $( col ).is( '[data-sortable-numeric]' ) );
1052				sorted = cells.sort( fn );
1053				rows = applyToRows( sorted , rows );
1054				return rows;
1055			},
1056			replaceTableRows: function( rows ){
1057				var el = $( this ),
1058					body = el.find( "tbody" );
1059				body.html( rows );
1060			},
1061			makeColDefault: function( col , a ){
1062				var c = $( col );
1063				c.attr( attrs.defaultCol , "true" );
1064				if( a ){
1065					c.removeClass( classes.descend );
1066					c.addClass( classes.ascend );
1067				} else {
1068					c.removeClass( classes.ascend );
1069					c.addClass( classes.descend );
1070				}
1071			},
1072			sortBy: function( col , ascending ){
1073				var el = $( this ), colNum, rows;
1074
1075				colNum = el[ pluginName ]( "getColumnNumber" , col );
1076				rows = el[ pluginName ]( "getTableRows" );
1077				rows = el[ pluginName ]( "sortRows" , rows , colNum , ascending, col );
1078				el[ pluginName ]( "replaceTableRows" , rows );
1079				el[ pluginName ]( "makeColDefault" , col , ascending );
1080			}
1081		};
1082
1083	// Collection method.
1084	$.fn[ pluginName ] = function( arrg ) {
1085		var args = Array.prototype.slice.call( arguments , 1),
1086			returnVal;
1087
1088		// if it's a method
1089		if( arrg && typeof( arrg ) === "string" ){
1090			returnVal = $.fn[ pluginName ].prototype[ arrg ].apply( this[0], args );
1091			return (typeof returnVal !== "undefined")? returnVal:$(this);
1092		}
1093		// check init
1094		if( !$( this ).data( pluginName + "data" ) ){
1095			$( this ).data( pluginName + "active", true );
1096			$.fn[ pluginName ].prototype._create.call( this , arrg );
1097		}
1098		return $(this);
1099	};
1100	// add methods
1101	$.extend( $.fn[ pluginName ].prototype, methods );
1102
1103	$( document ).on( "tablesawcreate", function( e, Tablesaw ) {
1104		if( Tablesaw.$table.is( initSelector ) ) {
1105			Tablesaw.$table[ pluginName ]();
1106		}
1107	});
1108
1109}( jQuery ));
1110
1111;(function( win, $, undefined ){
1112
1113	var MM = {
1114		attr: {
1115			init: 'data-tablesaw-minimap'
1116		}
1117	};
1118
1119	function createMiniMap( $table ){
1120
1121		var $btns = $( '<div class="tablesaw-advance minimap">' ),
1122			$dotNav = $( '<ul class="tablesaw-advance-dots">' ).appendTo( $btns ),
1123			hideDot = 'tablesaw-advance-dots-hide',
1124			$headerCells = $table.find( 'thead th' );
1125
1126		// populate dots
1127		$headerCells.each(function(){
1128			$dotNav.append( '<li><i></i></li>' );
1129		});
1130
1131		$btns.appendTo( $table.prev( '.tablesaw-bar' ) );
1132
1133		function showMinimap( $table ) {
1134			var mq = $table.attr( MM.attr.init );
1135			return !mq || win.matchMedia && win.matchMedia( mq ).matches;
1136		}
1137
1138		function showHideNav(){
1139			if( !showMinimap( $table ) ) {
1140				$btns.hide();
1141				return;
1142			}
1143			$btns.show();
1144
1145			// show/hide dots
1146			var dots = $dotNav.find( "li" ).removeClass( hideDot );
1147			$table.find( "thead th" ).each(function(i){
1148				if( $( this ).css( "display" ) === "none" ){
1149					dots.eq( i ).addClass( hideDot );
1150				}
1151			});
1152		}
1153
1154		// run on init and resize
1155		showHideNav();
1156		$( win ).on( "resize", showHideNav );
1157
1158
1159		$table
1160			.bind( "tablesawcolumns.minimap", function(){
1161				showHideNav();
1162			})
1163			.bind( "tablesawdestroy.minimap", function(){
1164				var $t = $( this );
1165
1166				$t.prev( '.tablesaw-bar' ).find( '.tablesaw-advance' ).remove();
1167				$( win ).off( "resize", showHideNav );
1168
1169				$t.unbind( ".minimap" );
1170			});
1171	}
1172
1173
1174
1175	// on tablecreate, init
1176	$( document ).on( "tablesawcreate", function( e, Tablesaw ){
1177
1178		if( ( Tablesaw.mode === 'swipe' || Tablesaw.mode === 'columntoggle' ) && Tablesaw.$table.is( '[ ' + MM.attr.init + ']' ) ){
1179			createMiniMap( Tablesaw.$table );
1180		}
1181
1182	} );
1183
1184}( this, jQuery ));
1185
1186;(function( win, $ ) {
1187
1188	var S = {
1189		selectors: {
1190			init: 'table[data-tablesaw-mode-switch]'
1191		},
1192		attributes: {
1193			excludeMode: 'data-tablesaw-mode-exclude'
1194		},
1195		classes: {
1196			main: 'tablesaw-modeswitch',
1197			toolbar: 'tablesaw-toolbar'
1198		},
1199		modes: [ 'stack', 'swipe', 'columntoggle' ],
1200		init: function( table ) {
1201			var $table = $( table ),
1202				ignoreMode = $table.attr( S.attributes.excludeMode ),
1203				$toolbar = $table.prev( '.tablesaw-bar' ),
1204				modeVal = '',
1205				$switcher = $( '<div>' ).addClass( S.classes.main + ' ' + S.classes.toolbar ).html(function() {
1206					var html = [ '<label>' + Tablesaw.i18n.columns + ':' ],
1207						dataMode = $table.attr( 'data-tablesaw-mode' ),
1208						isSelected;
1209
1210					html.push( '<span class="btn btn-small">&#160;<select>' );
1211					for( var j=0, k = S.modes.length; j<k; j++ ) {
1212						if( ignoreMode && ignoreMode.toLowerCase() === S.modes[ j ] ) {
1213							continue;
1214						}
1215
1216						isSelected = dataMode === S.modes[ j ];
1217
1218						if( isSelected ) {
1219							modeVal = S.modes[ j ];
1220						}
1221
1222						html.push( '<option' +
1223							( isSelected ? ' selected' : '' ) +
1224							' value="' + S.modes[ j ] + '">' + Tablesaw.i18n.modes[ j ] + '</option>' );
1225					}
1226					html.push( '</select></span></label>' );
1227
1228					return html.join('');
1229				});
1230
1231			var $otherToolbarItems = $toolbar.find( '.tablesaw-advance' ).eq( 0 );
1232			if( $otherToolbarItems.length ) {
1233				$switcher.insertBefore( $otherToolbarItems );
1234			} else {
1235				$switcher.appendTo( $toolbar );
1236			}
1237
1238			$switcher.find( '.btn' ).tablesawbtn();
1239			$switcher.find( 'select' ).bind( 'change', S.onModeChange );
1240		},
1241		onModeChange: function() {
1242			var $t = $( this ),
1243				$switcher = $t.closest( '.' + S.classes.main ),
1244				$table = $t.closest( '.tablesaw-bar' ).nextUntil( $table ).eq( 0 ),
1245				val = $t.val();
1246
1247			$switcher.remove();
1248			$table.data( 'table' ).destroy();
1249
1250			$table.attr( 'data-tablesaw-mode', val );
1251			$table.table();
1252		}
1253	};
1254
1255	$( win.document ).on( "tablesawcreate", function( e, Tablesaw ) {
1256		if( Tablesaw.$table.is( S.selectors.init ) ) {
1257			S.init( Tablesaw.table );
1258		}
1259	});
1260
1261})( this, jQuery );

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.