2012-10-17 15:15:54 +00:00
/*! tableSorter 2.4+ widgets - updated 10/17/2012 */
2012-09-29 13:42:58 +00:00
; ( function ( a ) {
a . tablesorter = a . tablesorter || { } ;
a . tablesorter . themes = { bootstrap : { table : "table table-bordered table-striped" , header : "bootstrap-header" , icons : "" , sortNone : "bootstrap-icon-unsorted" , sortAsc : "icon-chevron-up" , sortDesc : "icon-chevron-down" , active : "" , hover : "" , filterRow : "" , even : "" , odd : "" } , jui : { table : "ui-widget ui-widget-content ui-corner-all" , header : "ui-widget-header ui-corner-all ui-state-default" , icons : "ui-icon" , sortNone : "ui-icon-carat-2-n-s" , sortAsc : "ui-icon-carat-1-n" , sortDesc : "ui-icon-carat-1-s" , active : "ui-state-active" , hover : "ui-state-hover" , filterRow : "" , even : "ui-widget-content" , odd : "ui-state-default" } } ;
2012-10-14 01:16:05 +00:00
a . tablesorter . storage = function ( e , b , c ) { var d , i = ! 1 ; d = { } ; var f = e . id || a ( ".tablesorter" ) . index ( a ( e ) ) , g = window . location . pathname ; try { i = ! ! localStorage . getItem } catch ( m ) { } a . parseJSON && ( i ? d = a . parseJSON ( localStorage [ b ] ) || { } : ( d = document . cookie . split ( /[;\s|=]/ ) , e = a . inArray ( b , d ) + 1 , d = 0 !== e ? a . parseJSON ( d [ e ] ) || { } : { } ) ) ; if ( c && JSON && JSON . hasOwnProperty ( "stringify" ) ) { if ( ! d [ g ] || ! d [ g ] [ f ] ) d [ g ] || ( d [ g ] = { } ) ; d [ g ] [ f ] = c ; i ? localStorage [ b ] = JSON . stringify ( d ) : ( e = new Date , e . setTime ( e . getTime ( ) + 31536E6 ) , document . cookie = b + "=" + JSON . stringify ( d ) . replace ( /\"/g , '"' ) + "; expires=" + e . toGMTString ( ) + "; path=/" ) } else return d && d . hasOwnProperty ( g ) && d [ g ] . hasOwnProperty ( f ) ? d [ g ] [ f ] : { } } ;
a . tablesorter . addWidget ( { id : "uitheme" , format : function ( e ) { var b , c , d , i , f = a ( e ) , g = e . config , m = g . widgetOptions , n = "object" === typeof m . uitheme ? "jui" : m . uitheme || "jui" , h = "object" === typeof m . uitheme && ! Object . prototype . toString . call ( m . uitheme ) . test ( "Array" ) ? m . uitheme : a . tablesorter . themes [ a . tablesorter . themes . hasOwnProperty ( n ) ? n : "jui" ] , l = a ( g . headerList ) , p = "tr." + ( m . stickyHeaders || "tablesorter-stickyHeader" ) , q = h . sortNone + " " + h . sortDesc + " " + h . sortAsc ; g . debug && ( b = new Date ) ; if ( ! f . hasClass ( "tablesorter-" + n ) || g . theme === n || ! e . hasInitialized ) "" !== h . even && ( m . zebra [ 0 ] += " " + h . even ) , "" !== h . odd && ( m . zebra [ 1 ] += " " + h . odd ) , f . removeClass ( "" === g . theme ? "" : "tablesorter-" + g . theme ) . addClass ( "tablesorter-" + n + " " + h . table ) , g . theme = "" , l . addClass ( h . header ) . filter ( ":not(.sorter-false)" ) . hover ( function ( ) { a ( this ) . addClass ( h . hover ) } , function ( ) { a ( this ) . removeClass ( h . hover ) } ) , l . find ( ".tablesorter-wrapper" ) . length || l . wrapInner ( '<div class="tablesorter-wrapper" style="position:relative;height:100%;width:100%"></div>' ) , g . cssIcon && l . find ( "." + g . cssIcon ) . addClass ( h . icons ) , f . hasClass ( "hasFilters" ) && l . find ( ".tablesorter-filter-row" ) . addClass ( h . filterRow ) ; a . each ( l , function ( b ) { d = a ( this ) ; i = g . cssIcon ? d . find ( "." + g . cssIcon ) : d ; this . sortDisabled ? ( d . removeClass ( q ) , i . removeClass ( q + " tablesorter-icon " + h . icons ) ) : ( f . hasClass ( "hasStickyHeaders" ) && f . find ( p ) . find ( "th" ) . eq ( b ) . add ( d ) , c = d . hasClass ( g . cssAsc ) ? h . sortDesc : d . hasClass ( g . cssDesc ) ? h . sortAsc : d . hasClass ( g . cssHeader ) ? h . sortNone : "" , d [ c === h . sortNone ? "removeClass" : "addClass" ] ( h . active ) , i . removeClass ( q ) . addClass ( c ) ) } ) ; g . debug && a . tablesorter . benchmark ( "Applying " + n + " theme" , b ) } , remove : function ( e , b , c ) { var e = a ( e ) , d = "object" === typeof c . uitheme ? "jui" : c . uitheme || "jui" , c = "object" === typeof c . uitheme ? c . uitheme : a . tablesorter . themes [ a . tablesorter . themes . hasOwnProperty ( d ) ? d : "jui" ] , i = e . children ( "thead" ) . children ( ) , f = c . sortNone + " " + c . sortDesc + " " + c . sortAsc ; e . removeClass ( "tablesorter-" + d + " " + c . table ) . find ( b . cssHeader ) . removeClass ( c . header ) ; i . unbind ( "mouseenter mouseleave" ) . removeClass ( c . hover + " " + f + " " + c . active ) . find ( ".tablesorter-filter-row" ) . removeClass ( c . filterRow ) ; i . find ( ".tablesorter-icon" ) . removeClass ( c . icons ) } } ) ;
a . tablesorter . addWidget ( { id : "columns" , format : function ( e ) { var b , c , d , i , f , g , m , n , h , l = a ( e ) , p = e . config , q = p . widgetOptions , s = l . children ( "tbody:not(." + p . cssInfoBlock + ")" ) , u = p . sortList , v = u . length , k = [ "primary" , "secondary" , "tertiary" ] , k = p . widgetColumns && p . widgetColumns . hasOwnProperty ( "css" ) ? p . widgetColumns . css || k : q && q . hasOwnProperty ( "columns" ) ? q . columns || k : k ; g = k . length - 1 ; m = k . join ( " " ) ; p . debug && ( f = new Date ) ; for ( h = 0 ; h < s . length ; h ++ ) b = a . tablesorter . processTbody ( e , a ( s [ h ] ) , ! 0 ) , c = b . children ( "tr" ) , c . each ( function ( ) { i = a ( this ) ; if ( "none" !== this . style . display && ( d = i . children ( ) . removeClass ( m ) , u && u [ 0 ] && ( d . eq ( u [ 0 ] [ 0 ] ) . addClass ( k [ 0 ] ) , 1 < v ) ) ) for ( n = 1 ; n < v ; n ++ ) d . eq ( u [ n ] [ 0 ] ) . addClass ( k [ n ] || k [ g ] ) } ) , a . tablesorter . processTbody ( e , b , ! 1 ) ; c = ! 1 !== q . columns _thead ? "thead tr" : "" ; ! 1 !== q . columns _tfoot && ( c += ( "" === c ? "" : "," ) + "tfoot tr" ) ; if ( c . length && ( i = l . find ( c ) . children ( ) . removeClass ( m ) , u && u [ 0 ] && ( i . filter ( '[data-column="' + u [ 0 ] [ 0 ] + '"]' ) . addClass ( k [ 0 ] ) , 1 < v ) ) ) for ( n = 1 ; n < v ; n ++ ) i . filter ( '[data-column="' + u [ n ] [ 0 ] + '"]' ) . addClass ( k [ n ] || k [ g ] ) ; p . debug && a . tablesorter . benchmark ( "Applying Columns widget" , f ) } , remove : function ( e , b ) { var c , d , i = a ( e ) . children ( "tbody:not(." + b . cssInfoBlock + ")" ) , f = ( b . widgetOptions . columns || [ "primary" , "secondary" , "tertiary" ] ) . join ( " " ) ; for ( c = 0 ; c < i . length ; c ++ ) d = a . tablesorter . processTbody ( e , a ( i [ c ] ) , ! 0 ) , d . children ( "tr" ) . each ( function ( ) { a ( this ) . children ( ) . removeClass ( f ) } ) , a . tablesorter . processTbody ( e , d , ! 1 ) } } ) ;
2012-10-17 15:15:54 +00:00
a . tablesorter . addWidget ( { id : "filter" , format : function ( e ) { if ( e . config . parsers && ! a ( e ) . hasClass ( "hasFilters" ) ) { var b , c , d , i , f , g , m , n , h , l , p , q , s , u , v , k , x , F = "" , z = a . tablesorter , r = e . config , A = a ( r . headerList ) , j = r . widgetOptions , y = j . filter _cssFilter || "tablesorter-filter" , t = a ( e ) . addClass ( "hasFilters" ) , D = t . children ( "tbody:not(." + r . cssInfoBlock + ")" ) , E = r . parsers . length , B = [ /^\/((?:\\\/|[^\/])+)\/([mig]{0,3})?$/ , RegExp ( r . cssChildRow ) , /undefined|number/ , /(^[\"|\'|=])|([\"|\'|=]$)/ , /[\"\'=]/g , /[^\w,. \-()]/g , /[<>=]/g ] , L = A . map ( function ( b ) { return z . getData ? "parsed" === z . getData ( A . filter ( '[data-column="' + b + '"]:last' ) , r . headers [ b ] , "filter" ) : a ( this ) . hasClass ( "filter-parsed" ) } ) . get ( ) , G , H , C = function ( b ) { var d = a . isArray ( b ) , e = t . find ( "thead" ) . eq ( 0 ) . children ( "tr" ) . find ( "select." + y + ", input." + y ) , c = d ? b : e . map ( function ( ) { return a ( this ) . val ( ) || "" } ) . get ( ) , f = ( c || [ ] ) . join ( "" ) ; d && e . each ( function ( c , d ) { a ( d ) . val ( b [ c ] || "" ) } ) ; ! 0 === j . filter _hideFilters && t . find ( ".tablesorter-filter-row" ) . trigger ( "" === f ? "mouseleave" : "mouseenter" ) ; if ( ! ( F === f && ! 1 !== b ) ) if ( t . trigger ( "filterStart" , [ c ] ) , r . showProcessing ) setTimeout ( function ( ) { I ( b , c , f ) ; return ! 1 } , 30 ) ; else return I ( b , c , f ) , ! 1 } , I = function ( g , i , h ) { var l , p , s , q , x , w , y ; r . debug && ( y = new Date ) ; for ( d = 0 ; d < D . length ; d ++ ) { g = a . tablesorter . processTbody ( e , a ( D [ d ] ) , ! 0 ) ; l = g . children ( "tr" ) ; x = l . length ; if ( "" === h ) l . show ( ) . removeClass ( "filtered" ) ; else for ( c = 0 ; c < x ; c ++ ) if ( ! B [ 1 ] . test ( l [ c ] . className ) ) { q = ! 0 ; s = l . eq ( c ) . nextUntil ( "tr:not(." + r . cssChildRow + ")" ) ; k = s . length && ( j && j . hasOwnProperty ( "filter_childRows" ) && "undefined" !== typeof j . filter _childRows ? j . filter _childRows : 1 ) ? s . text ( ) : "" ; k = j . filter _ignoreCase ? k . toLocaleLowerCase ( ) : k ; p = l . eq ( c ) . children ( "td" ) ; for ( b = 0 ; b < E ; b ++ ) if ( i [ b ] ) { m = j . filter _useParsedData || L [ b ] ? r . cache [ d ] . normalized [ c ] [ b ] : a . trim ( p . eq ( b ) . text ( ) ) ; n = ! B [ 2 ] . test ( typeof m ) && j . filter _ignoreCase ? m . toLocaleLowerCase ( ) : m ; w = q ; f = j . filter _ignoreCase ? i [ b ] . toLocaleLowerCase ( ) : i [ b ] ; if ( j . filter _functions && j . filter _functions [ b ] ) ! 0 === j . filter _functions [ b ] ? w = A . filter ( '[data-column="' + b + '"]:last' ) . hasClass ( "filter-match" ) ? 0 <= n . search ( f ) : i [ b ] === m : "function" === typeof j . filter _functions [ b ] ? w = j . filter _functions [ b ] ( m , r . cache [ d ] . normalized [ c ] [ b ] , i [ b ] , b ) : "function" === typeof j . filter _functions [ b ] [ i [ b ] ] && ( w = j . filter _functions [ b ] [ i [ b ] ] ( m , r . cache [ d ] . normalized [ c ] [ b ] , i [ b ] , b ) ) ; else if ( B [ 0 ] . test ( f ) ) { u = B [ 0 ] . exec ( f ) ; try { w = RegExp ( u [ 1 ] , u [ 2 ] ) . test ( n ) } catch ( C ) { w = ! 1 } } else B [ 3 ] . test ( f ) && n === f . replace ( B [ 4 ] , "" ) ? w = ! 0 : /^\!/ . test ( f ) ? ( f = f . replace ( "!" , "" ) , v = n . search ( a . trim ( f ) ) , w = "" === f ? ! 0 : ! ( j . filter _startsWith ? 0 === v : 0 <= v ) ) : /^[<>]=?/ . test ( f ) ? ( u = isNaN ( n ) ? a . tablesorter . formatFloat ( n . replace ( B [ 5 ] , "" ) , e ) : a . tablesorter . formatFloat ( n , e ) , v = a . tablesorter . formatFloat ( f . replace ( B [ 5 ] , "" ) . replace ( B [ 6 ] , "" ) , e ) , />/ . test ( f ) && ( w = />=/ . test ( f ) ? u >= v : u > v ) , /</ . test ( f ) && ( w = /<=/ . test ( f ) ? u <= v : u < v ) ) : /[\?|\*]/ . test ( f ) ? w = RegExp ( f . replace ( /\?/g , "\\S{1}" ) . replace ( /\*/g , "\\S*" ) ) . test ( n ) : ( m = ( n + k ) . indexOf ( f ) , w = ! j . filter _startsWith && 0 <= m || j . filter _startsWith && 0 === m ) ; q = w ? q ? ! 0 : ! 1 : ! 1 } l [ c ] . style . display = q ? "" : "none" ; l . eq ( c ) [ q ? "removeClass" : "addClass" ] ( "filtered" ) ; if ( s . length ) s [ q ? "show" : "hide" ] ( ) } a . tablesorter . processTbody ( e , g , ! 1 ) } F = h ; r . debug && z . benchmark ( "Completed filter widget search" , y ) ; t . trigger ( "applyWidgets" ) ; t . trigger ( "filterEnd" ) } , J = function ( b , f ) { var g , h = [ ] , b = parseInt ( b , 10 ) ; g = '<option value="">' + ( A . filter ( '[data-column="' + b + '"]:last' ) . attr ( "data-placeholder" ) || "" ) + "</option>" ; for ( d = 0 ; d < D . length ; d ++ ) { i = r . cache [ d ] . row . length ; for ( c = 0 ; c < i ; c ++ ) j . filter _useParsedData ? h . push ( "" + r . cache [ d ] . normalized [ c ] [ b ] ) : ( k = r . cache [ d ] . row [ c ] [ 0 ] . cells [ b ] ) && h . push ( r . supportsTextContent ? k . textContent : a ( k ) . text ( ) ) } h = a . grep ( h , function ( b , c ) { return a . inArray ( b , h ) === c } ) ; h = z . sortText ? h . sort ( function ( a , c ) { return z . sortText ( e , a , c , b ) } ) : h . sort ( ! 0 ) ; for ( d = 0 ; d < h . length ; d ++ ) g += '<option value="' + h [ d ] + '">' + h [ d ] + "</option>" ; t . find ( "thead" ) . find ( "select." + y + '[data-column="' + b + '"]' ) [ f ? "html" : "append" ] ( g ) } , K = function ( a ) { for ( b = 0 ; b < E ; b ++ ) k = A . filter ( '[data-column="' + b + '"]:last' ) , k . hasClass ( "filter-select" ) && ( ! k . hasClass ( "filter-false" ) && ! ( j . filter _functions && ! 0 === j . filter _functions [ b ] ) ) && ( j . filter _functions || ( j . filter _functions = { } ) , j . filter _functions [ b ] = ! 0 , J ( b , a ) ) } ; r . debu
a . tablesorter . addWidget ( { id : "stickyHeaders" , format : function ( e ) { if ( ! a ( e ) . hasClass ( "hasStickyHeaders" ) ) { var b = a ( e ) . addClass ( "hasStickyHeaders" ) , c = e . config , d = c . widgetOptions , i = a ( window ) , f = a ( e ) . children ( "thead:first" ) , g = f . children ( "tr:not(.sticky-false)" ) . children ( ) , e = d . stickyHeaders || "tablesorter-stickyHeader" , m = g . eq ( 0 ) , n = b . find ( "tfoot" ) , h = f . clone ( ) . addClass ( e ) . css ( { width : f . outerWidth ( ! 0 ) , position : "fixed" , margin : 0 , top : 0 , visibility : "hidden" , zIndex : 1 } ) , l = h . find ( "tr" ) . children ( ) , p = "" , q = 0 , s = function ( ) { var c = navigator . userAgent ; q = 0 ; "collapse" !== b . css ( "border-collapse" ) && ! /webkit/i . test ( c ) && ( q = /msie/i . test ( c ) ? parseInt ( f . css ( "padding-left" ) , 10 ) : parseInt ( b . css ( "border-spacing" ) , 10 ) ) ; h . css ( { left : f . offset ( ) . left - i . scrollLeft ( ) - q , width : f . outerWidth ( ) } ) ; l . each ( function ( b ) { b = g . eq ( b ) ; a ( this ) . css ( { width : b . width ( ) , height : b . height ( ) } ) } ) . find ( ".tablesorter-header-inner" ) . each ( function ( b ) { b = g . eq ( b ) . find ( ".tablesorter-header-inner" ) . width ( ) ; a ( this ) . width ( b ) } ) } ; h . find ( "tr.sticky-false" ) . remove ( ) ; l . find ( ".tablesorter-resizer" ) . remove ( ) ; b . bind ( "sortEnd.tsSticky" , function ( ) { g . each ( function ( b ) { b = l . eq ( b ) ; b . attr ( "class" , a ( this ) . attr ( "class" ) ) ; c . cssIcon && b . find ( "." + c . cssIcon ) . attr ( "class" , a ( this ) . find ( "." + c . cssIcon ) . attr ( "class" ) ) } ) } ) . bind ( "pagerComplete.tsSticky" , function ( ) { s ( ) } ) ; g . find ( "*" ) . andSelf ( ) . filter ( c . selectorSort ) . each ( function ( b ) { var c = a ( this ) ; l . eq ( b ) . bind ( "mouseup" , function ( b ) { c . trigger ( b , ! 0 ) } ) . bind ( "mousedown" , function ( ) { this . onselectstart = function ( ) { return ! 1 } ; return ! 1 } ) } ) ; f . after ( h ) ; i . bind ( "scroll.tsSticky" , function ( ) { var a = m . offset ( ) , c = i . scrollTop ( ) , d = b . height ( ) - ( m . height ( ) + ( n . height ( ) || 0 ) ) , a = c > a . top && c < a . top + d ? "visible" : "hidden" ; h . css ( { left : f . offset ( ) . left - i . scrollLeft ( ) - q , visibility : a } ) ; a !== p && ( s ( ) , p = a ) } ) . bind ( "resize.tsSticky" , function ( ) { s ( ) } ) } } , remove : function ( e , b , c ) { e = a ( e ) ; c = c . stickyHeaders || "tablesorter-stickyHeader" ; e . removeClass ( "hasStickyHeaders" ) . unbind ( "sortEnd.tsSticky pagerComplete.tsSticky" ) . find ( "." + c ) . remove ( ) ; a ( window ) . unbind ( "scroll.tsSticky resize.tsSticky" ) } } ) ;
a . tablesorter . addWidget ( { id : "resizable" , format : function ( e ) { if ( ! a ( e ) . hasClass ( "hasResizable" ) ) { a ( e ) . addClass ( "hasResizable" ) ; var b , c , d , i , f , g = a ( e ) , m = e . config , n = m . widgetOptions , h = 0 , l = null , p = null , q = function ( ) { h = 0 ; l = p = null ; a ( window ) . trigger ( "resize" ) } ; if ( d = a . tablesorter . storage && ! 1 !== n . resizable ? a . tablesorter . storage ( e , "tablesorter-resizable" ) : { } ) for ( c in d ) ! isNaN ( c ) && c < m . headerList . length && a ( m . headerList [ c ] ) . width ( d [ c ] ) ; g . children ( "thead:first" ) . find ( "tr" ) . each ( function ( ) { i = a ( this ) . children ( ) ; a ( this ) . find ( ".tablesorter-wrapper" ) . length || i . wrapInner ( '<div class="tablesorter-wrapper" style="position:relative;height:100%;width:100%"></div>' ) ; i = i . slice ( 0 , - 1 ) ; f = f ? f . add ( i ) : i } ) ; f . each ( function ( ) { b = a ( this ) ; c = parseInt ( b . css ( "padding-right" ) , 10 ) + 8 ; b . find ( ".tablesorter-wrapper" ) . append ( '<div class="tablesorter-resizer" style="cursor:w-resize;position:absolute;height:100%;width:16px;right:-' + c + 'px;top:0;z-index:1;"></div>' ) } ) . bind ( "mousemove.tsresize" , function ( a ) { if ( 0 !== h && l ) { var b = a . pageX - h ; l . width ( l . width ( ) + b ) ; p . width ( p . width ( ) - b ) ; h = a . pageX } } ) . bind ( "mouseup.tsresize" , function ( ) { a . tablesorter . storage && l && ( d [ l . index ( ) ] = l . width ( ) , d [ p . index ( ) ] = p . width ( ) , ! 1 !== n . resizable && a . tablesorter . storage ( e , "tablesorter-resizable" , d ) ) ; q ( ) } ) . find ( ".tablesorter-resizer" ) . bind ( "mousedown" , function ( b ) { l = a ( b . target ) . parents ( "th:last" ) ; p = l . next ( ) ; h = b . pageX } ) ; g . find ( "thead:first" ) . bind ( "mouseup.tsresize mouseleave.tsresize" , function ( ) { q ( ) } ) . bind ( "contextmenu.tsresize" , function ( ) { a . tablesorter . resizableReset ( e ) ; var b = a . isEmptyObject ? a . isEmptyObject ( d ) : d === { } ; d = { } ; return b } ) } } , remove : function ( e ) { a ( e ) . removeClass ( "hasResizable" ) . find ( "thead" ) . unbind ( "mouseup.tsresize mouseleave.tsresize contextmenu.tsresize" ) . find ( "tr" ) . children ( ) . unbind ( "mousemove.tsresize mouseup.tsresize" ) . find ( ".tablesorter-wrapper" ) . each ( function ( ) { a ( this ) . find ( ".tablesorter-resizer" ) . remove ( ) ; a ( this ) . replaceWith ( a ( this ) . contents ( ) ) } ) ; a . tablesorter . resizableReset ( e ) } } ) ; a . tablesorter . resizableReset = function ( e ) { a ( e . config . headerList ) . width ( "auto" ) ; a . tablesorter . storage ( e , "tablesorter-resizable" , { } ) } ;
a . tablesorter . addWidget ( { id : "saveSort" , init : function ( a , b ) { b . format ( a , ! 0 ) } , format : function ( e , b ) { var c , d , i = e . config ; c = ! 1 !== i . widgetOptions . saveSort ; var f = { sortList : i . sortList } ; i . debug && ( d = new Date ) ; a ( e ) . hasClass ( "hasSaveSort" ) ? c && ( e . hasInitialized && a . tablesorter . storage ) && ( a . tablesorter . storage ( e , "tablesorter-savesort" , f ) , i . debug && a . tablesorter . benchmark ( "saveSort widget: Saving last sort: " + i . sortList , d ) ) : ( a ( e ) . addClass ( "hasSaveSort" ) , f = "" , a . tablesorter . storage && ( f = ( c = a . tablesorter . storage ( e , "tablesorter-savesort" ) ) && c . hasOwnProperty ( "sortList" ) && a . isArray ( c . sortList ) ? c . sortList : "" , i . debug && a . tablesorter . benchmark ( 'saveSort: Last sort loaded: "' + f + '"' , d ) ) , b && f && 0 < f . length ? i . sortList = f : e . hasInitialized && ( f && 0 < f . length ) && a ( e ) . trigger ( "sorton" , [ f ] ) ) } , remove : function ( e ) { a . tablesorter . storage ( e , "tablesorter-savesort" , "" ) } } )
} ) ( jQuery ) ;