mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-05 03:24:36 -04:00
32677 lines
1.3 MiB
32677 lines
1.3 MiB
/*!
|
||
* jQuery JavaScript Library v1.11.1
|
||
* http://jquery.com/
|
||
*
|
||
* Includes Sizzle.js
|
||
* http://sizzlejs.com/
|
||
*
|
||
* Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
|
||
* Released under the MIT license
|
||
* http://jquery.org/license
|
||
*
|
||
* Date: 2014-05-01T17:42Z
|
||
*/
|
||
|
||
(function( global, factory ) {
|
||
|
||
if ( typeof module === "object" && typeof module.exports === "object" ) {
|
||
// For CommonJS and CommonJS-like environments where a proper window is present,
|
||
// execute the factory and get jQuery
|
||
// For environments that do not inherently posses a window with a document
|
||
// (such as Node.js), expose a jQuery-making factory as module.exports
|
||
// This accentuates the need for the creation of a real window
|
||
// e.g. var jQuery = require("jquery")(window);
|
||
// See ticket #14549 for more info
|
||
module.exports = global.document ?
|
||
factory( global, true ) :
|
||
function( w ) {
|
||
if ( !w.document ) {
|
||
throw new Error( "jQuery requires a window with a document" );
|
||
}
|
||
return factory( w );
|
||
};
|
||
} else {
|
||
factory( global );
|
||
}
|
||
|
||
// Pass this if window is not defined yet
|
||
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
|
||
|
||
// Can't do this because several apps including ASP.NET trace
|
||
// the stack via arguments.caller.callee and Firefox dies if
|
||
// you try to trace through "use strict" call chains. (#13335)
|
||
// Support: Firefox 18+
|
||
//
|
||
|
||
var deletedIds = [];
|
||
|
||
var slice = deletedIds.slice;
|
||
|
||
var concat = deletedIds.concat;
|
||
|
||
var push = deletedIds.push;
|
||
|
||
var indexOf = deletedIds.indexOf;
|
||
|
||
var class2type = {};
|
||
|
||
var toString = class2type.toString;
|
||
|
||
var hasOwn = class2type.hasOwnProperty;
|
||
|
||
var support = {};
|
||
|
||
|
||
|
||
var
|
||
version = "1.11.1",
|
||
|
||
// Define a local copy of jQuery
|
||
jQuery = function( selector, context ) {
|
||
// The jQuery object is actually just the init constructor 'enhanced'
|
||
// Need init if jQuery is called (just allow error to be thrown if not included)
|
||
return new jQuery.fn.init( selector, context );
|
||
},
|
||
|
||
// Support: Android<4.1, IE<9
|
||
// Make sure we trim BOM and NBSP
|
||
rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
|
||
|
||
// Matches dashed string for camelizing
|
||
rmsPrefix = /^-ms-/,
|
||
rdashAlpha = /-([\da-z])/gi,
|
||
|
||
// Used by jQuery.camelCase as callback to replace()
|
||
fcamelCase = function( all, letter ) {
|
||
return letter.toUpperCase();
|
||
};
|
||
|
||
jQuery.fn = jQuery.prototype = {
|
||
// The current version of jQuery being used
|
||
jquery: version,
|
||
|
||
constructor: jQuery,
|
||
|
||
// Start with an empty selector
|
||
selector: "",
|
||
|
||
// The default length of a jQuery object is 0
|
||
length: 0,
|
||
|
||
toArray: function() {
|
||
return slice.call( this );
|
||
},
|
||
|
||
// 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 just the one element from the set
|
||
( num < 0 ? this[ num + this.length ] : this[ num ] ) :
|
||
|
||
// Return all the elements in a clean array
|
||
slice.call( this );
|
||
},
|
||
|
||
// Take an array of elements and push it onto the stack
|
||
// (returning the new matched element set)
|
||
pushStack: function( elems ) {
|
||
|
||
// Build a new jQuery matched element set
|
||
var ret = jQuery.merge( this.constructor(), elems );
|
||
|
||
// Add the old object onto the stack (as a reference)
|
||
ret.prevObject = this;
|
||
ret.context = this.context;
|
||
|
||
// 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 );
|
||
},
|
||
|
||
map: function( callback ) {
|
||
return this.pushStack( jQuery.map(this, function( elem, i ) {
|
||
return callback.call( elem, i, elem );
|
||
}));
|
||
},
|
||
|
||
slice: function() {
|
||
return this.pushStack( slice.apply( this, arguments ) );
|
||
},
|
||
|
||
first: function() {
|
||
return this.eq( 0 );
|
||
},
|
||
|
||
last: function() {
|
||
return this.eq( -1 );
|
||
},
|
||
|
||
eq: function( i ) {
|
||
var len = this.length,
|
||
j = +i + ( i < 0 ? len : 0 );
|
||
return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
|
||
},
|
||
|
||
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: deletedIds.sort,
|
||
splice: deletedIds.splice
|
||
};
|
||
|
||
jQuery.extend = jQuery.fn.extend = function() {
|
||
var src, copyIsArray, copy, name, options, clone,
|
||
target = arguments[0] || {},
|
||
i = 1,
|
||
length = arguments.length,
|
||
deep = false;
|
||
|
||
// Handle a deep copy situation
|
||
if ( typeof target === "boolean" ) {
|
||
deep = target;
|
||
|
||
// skip the boolean and the target
|
||
target = arguments[ i ] || {};
|
||
i++;
|
||
}
|
||
|
||
// 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 ( i === length ) {
|
||
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({
|
||
// Unique for each copy of jQuery on the page
|
||
expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
|
||
|
||
// Assume jQuery is ready without the ready module
|
||
isReady: true,
|
||
|
||
error: function( msg ) {
|
||
throw new Error( msg );
|
||
},
|
||
|
||
noop: function() {},
|
||
|
||
// 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";
|
||
},
|
||
|
||
isWindow: function( obj ) {
|
||
/* jshint eqeqeq: false */
|
||
return obj != null && obj == obj.window;
|
||
},
|
||
|
||
isNumeric: function( obj ) {
|
||
// parseFloat NaNs numeric-cast false positives (null|true|false|"")
|
||
// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
|
||
// subtraction forces infinities to NaN
|
||
return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;
|
||
},
|
||
|
||
isEmptyObject: function( obj ) {
|
||
var name;
|
||
for ( name in obj ) {
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
|
||
isPlainObject: function( obj ) {
|
||
var key;
|
||
|
||
// 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;
|
||
}
|
||
|
||
try {
|
||
// Not own constructor property must be Object
|
||
if ( obj.constructor &&
|
||
!hasOwn.call(obj, "constructor") &&
|
||
!hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
|
||
return false;
|
||
}
|
||
} catch ( e ) {
|
||
// IE8,9 Will throw exceptions on certain host objects #9897
|
||
return false;
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Handle iteration over inherited properties before own properties.
|
||
if ( support.ownLast ) {
|
||
for ( key in obj ) {
|
||
return hasOwn.call( obj, key );
|
||
}
|
||
}
|
||
|
||
// Own properties are enumerated firstly, so to speed up,
|
||
// if last one is own, then all properties are own.
|
||
for ( key in obj ) {}
|
||
|
||
return key === undefined || hasOwn.call( obj, key );
|
||
},
|
||
|
||
type: function( obj ) {
|
||
if ( obj == null ) {
|
||
return obj + "";
|
||
}
|
||
return typeof obj === "object" || typeof obj === "function" ?
|
||
class2type[ toString.call(obj) ] || "object" :
|
||
typeof obj;
|
||
},
|
||
|
||
// 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 && jQuery.trim( 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 );
|
||
}
|
||
},
|
||
|
||
// Convert dashed to camelCase; used by the css and data modules
|
||
// Microsoft forgot to hump their vendor prefix (#9572)
|
||
camelCase: function( string ) {
|
||
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
|
||
},
|
||
|
||
nodeName: function( elem, name ) {
|
||
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
|
||
},
|
||
|
||
// args is for internal usage only
|
||
each: function( obj, callback, args ) {
|
||
var value,
|
||
i = 0,
|
||
length = obj.length,
|
||
isArray = isArraylike( obj );
|
||
|
||
if ( args ) {
|
||
if ( isArray ) {
|
||
for ( ; i < length; i++ ) {
|
||
value = callback.apply( obj[ i ], args );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
for ( i in obj ) {
|
||
value = callback.apply( obj[ i ], args );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// A special, fast, case for the most common use of each
|
||
} else {
|
||
if ( isArray ) {
|
||
for ( ; i < length; i++ ) {
|
||
value = callback.call( obj[ i ], i, obj[ i ] );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
} else {
|
||
for ( i in obj ) {
|
||
value = callback.call( obj[ i ], i, obj[ i ] );
|
||
|
||
if ( value === false ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return obj;
|
||
},
|
||
|
||
// Support: Android<4.1, IE<9
|
||
trim: function( text ) {
|
||
return text == null ?
|
||
"" :
|
||
( text + "" ).replace( rtrim, "" );
|
||
},
|
||
|
||
// results is for internal usage only
|
||
makeArray: function( arr, results ) {
|
||
var ret = results || [];
|
||
|
||
if ( arr != null ) {
|
||
if ( isArraylike( Object(arr) ) ) {
|
||
jQuery.merge( ret,
|
||
typeof arr === "string" ?
|
||
[ arr ] : arr
|
||
);
|
||
} else {
|
||
push.call( ret, arr );
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
},
|
||
|
||
inArray: function( elem, arr, i ) {
|
||
var len;
|
||
|
||
if ( arr ) {
|
||
if ( indexOf ) {
|
||
return indexOf.call( arr, elem, i );
|
||
}
|
||
|
||
len = arr.length;
|
||
i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
// Skip accessing in sparse arrays
|
||
if ( i in arr && arr[ i ] === elem ) {
|
||
return i;
|
||
}
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
},
|
||
|
||
merge: function( first, second ) {
|
||
var len = +second.length,
|
||
j = 0,
|
||
i = first.length;
|
||
|
||
while ( j < len ) {
|
||
first[ i++ ] = second[ j++ ];
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
|
||
if ( len !== len ) {
|
||
while ( second[j] !== undefined ) {
|
||
first[ i++ ] = second[ j++ ];
|
||
}
|
||
}
|
||
|
||
first.length = i;
|
||
|
||
return first;
|
||
},
|
||
|
||
grep: function( elems, callback, invert ) {
|
||
var callbackInverse,
|
||
matches = [],
|
||
i = 0,
|
||
length = elems.length,
|
||
callbackExpect = !invert;
|
||
|
||
// Go through the array, only saving the items
|
||
// that pass the validator function
|
||
for ( ; i < length; i++ ) {
|
||
callbackInverse = !callback( elems[ i ], i );
|
||
if ( callbackInverse !== callbackExpect ) {
|
||
matches.push( elems[ i ] );
|
||
}
|
||
}
|
||
|
||
return matches;
|
||
},
|
||
|
||
// arg is for internal usage only
|
||
map: function( elems, callback, arg ) {
|
||
var value,
|
||
i = 0,
|
||
length = elems.length,
|
||
isArray = isArraylike( elems ),
|
||
ret = [];
|
||
|
||
// Go through the array, translating each of the items to their new values
|
||
if ( isArray ) {
|
||
for ( ; i < length; i++ ) {
|
||
value = callback( elems[ i ], i, arg );
|
||
|
||
if ( value != null ) {
|
||
ret.push( value );
|
||
}
|
||
}
|
||
|
||
// Go through every key on the object,
|
||
} else {
|
||
for ( i in elems ) {
|
||
value = callback( elems[ i ], i, arg );
|
||
|
||
if ( value != null ) {
|
||
ret.push( value );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Flatten any nested arrays
|
||
return 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 ) {
|
||
var args, proxy, tmp;
|
||
|
||
if ( typeof context === "string" ) {
|
||
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
|
||
args = slice.call( arguments, 2 );
|
||
proxy = function() {
|
||
return fn.apply( context || this, 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 || jQuery.guid++;
|
||
|
||
return proxy;
|
||
},
|
||
|
||
now: function() {
|
||
return +( new Date() );
|
||
},
|
||
|
||
// jQuery.support is not used in Core but other projects attach their
|
||
// properties to it so it needs to exist.
|
||
support: support
|
||
});
|
||
|
||
// Populate the class2type map
|
||
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
|
||
class2type[ "[object " + name + "]" ] = name.toLowerCase();
|
||
});
|
||
|
||
function isArraylike( obj ) {
|
||
var length = obj.length,
|
||
type = jQuery.type( obj );
|
||
|
||
if ( type === "function" || jQuery.isWindow( obj ) ) {
|
||
return false;
|
||
}
|
||
|
||
if ( obj.nodeType === 1 && length ) {
|
||
return true;
|
||
}
|
||
|
||
return type === "array" || length === 0 ||
|
||
typeof length === "number" && length > 0 && ( length - 1 ) in obj;
|
||
}
|
||
var Sizzle =
|
||
/*!
|
||
* Sizzle CSS Selector Engine v1.10.19
|
||
* http://sizzlejs.com/
|
||
*
|
||
* Copyright 2013 jQuery Foundation, Inc. and other contributors
|
||
* Released under the MIT license
|
||
* http://jquery.org/license
|
||
*
|
||
* Date: 2014-04-18
|
||
*/
|
||
(function( window ) {
|
||
|
||
var i,
|
||
support,
|
||
Expr,
|
||
getText,
|
||
isXML,
|
||
tokenize,
|
||
compile,
|
||
select,
|
||
outermostContext,
|
||
sortInput,
|
||
hasDuplicate,
|
||
|
||
// Local document vars
|
||
setDocument,
|
||
document,
|
||
docElem,
|
||
documentIsHTML,
|
||
rbuggyQSA,
|
||
rbuggyMatches,
|
||
matches,
|
||
contains,
|
||
|
||
// Instance-specific data
|
||
expando = "sizzle" + -(new Date()),
|
||
preferredDoc = window.document,
|
||
dirruns = 0,
|
||
done = 0,
|
||
classCache = createCache(),
|
||
tokenCache = createCache(),
|
||
compilerCache = createCache(),
|
||
sortOrder = function( a, b ) {
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
}
|
||
return 0;
|
||
},
|
||
|
||
// General-purpose constants
|
||
strundefined = typeof undefined,
|
||
MAX_NEGATIVE = 1 << 31,
|
||
|
||
// Instance methods
|
||
hasOwn = ({}).hasOwnProperty,
|
||
arr = [],
|
||
pop = arr.pop,
|
||
push_native = arr.push,
|
||
push = arr.push,
|
||
slice = arr.slice,
|
||
// Use a stripped-down indexOf if we can't use a native one
|
||
indexOf = arr.indexOf || function( elem ) {
|
||
var i = 0,
|
||
len = this.length;
|
||
for ( ; i < len; i++ ) {
|
||
if ( this[i] === elem ) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
},
|
||
|
||
booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
|
||
|
||
// Regular expressions
|
||
|
||
// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
|
||
whitespace = "[\\x20\\t\\r\\n\\f]",
|
||
// http://www.w3.org/TR/css3-syntax/#characters
|
||
characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
|
||
|
||
// Loosely modeled on CSS identifier characters
|
||
// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
|
||
// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
|
||
identifier = characterEncoding.replace( "w", "w#" ),
|
||
|
||
// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
|
||
attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
|
||
// Operator (capture 2)
|
||
"*([*^$|!~]?=)" + whitespace +
|
||
// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
|
||
"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
|
||
"*\\]",
|
||
|
||
pseudos = ":(" + characterEncoding + ")(?:\\((" +
|
||
// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
|
||
// 1. quoted (capture 3; capture 4 or capture 5)
|
||
"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
|
||
// 2. simple (capture 6)
|
||
"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
|
||
// 3. anything else (capture 2)
|
||
".*" +
|
||
")\\)|)",
|
||
|
||
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
|
||
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
|
||
|
||
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
|
||
rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
|
||
|
||
rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
|
||
|
||
rpseudo = new RegExp( pseudos ),
|
||
ridentifier = new RegExp( "^" + identifier + "$" ),
|
||
|
||
matchExpr = {
|
||
"ID": new RegExp( "^#(" + characterEncoding + ")" ),
|
||
"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
|
||
"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
|
||
"ATTR": new RegExp( "^" + attributes ),
|
||
"PSEUDO": new RegExp( "^" + pseudos ),
|
||
"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
|
||
"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
|
||
"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
|
||
"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
|
||
// For use in libraries implementing .is()
|
||
// We use this for POS matching in `select`
|
||
"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
|
||
whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
|
||
},
|
||
|
||
rinputs = /^(?:input|select|textarea|button)$/i,
|
||
rheader = /^h\d$/i,
|
||
|
||
rnative = /^[^{]+\{\s*\[native \w/,
|
||
|
||
// Easily-parseable/retrievable ID or TAG or CLASS selectors
|
||
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
|
||
|
||
rsibling = /[+~]/,
|
||
rescape = /'|\\/g,
|
||
|
||
// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
|
||
runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
|
||
funescape = function( _, escaped, escapedWhitespace ) {
|
||
var high = "0x" + escaped - 0x10000;
|
||
// NaN means non-codepoint
|
||
// Support: Firefox<24
|
||
// Workaround erroneous numeric interpretation of +"0x"
|
||
return high !== high || escapedWhitespace ?
|
||
escaped :
|
||
high < 0 ?
|
||
// BMP codepoint
|
||
String.fromCharCode( high + 0x10000 ) :
|
||
// Supplemental Plane codepoint (surrogate pair)
|
||
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
|
||
};
|
||
|
||
// Optimize for push.apply( _, NodeList )
|
||
try {
|
||
push.apply(
|
||
(arr = slice.call( preferredDoc.childNodes )),
|
||
preferredDoc.childNodes
|
||
);
|
||
// Support: Android<4.0
|
||
// Detect silently failing push.apply
|
||
arr[ preferredDoc.childNodes.length ].nodeType;
|
||
} catch ( e ) {
|
||
push = { apply: arr.length ?
|
||
|
||
// Leverage slice if possible
|
||
function( target, els ) {
|
||
push_native.apply( target, slice.call(els) );
|
||
} :
|
||
|
||
// Support: IE<9
|
||
// Otherwise append directly
|
||
function( target, els ) {
|
||
var j = target.length,
|
||
i = 0;
|
||
// Can't trust NodeList.length
|
||
while ( (target[j++] = els[i++]) ) {}
|
||
target.length = j - 1;
|
||
}
|
||
};
|
||
}
|
||
|
||
function Sizzle( selector, context, results, seed ) {
|
||
var match, elem, m, nodeType,
|
||
// QSA vars
|
||
i, groups, old, nid, newContext, newSelector;
|
||
|
||
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
|
||
setDocument( context );
|
||
}
|
||
|
||
context = context || document;
|
||
results = results || [];
|
||
|
||
if ( !selector || typeof selector !== "string" ) {
|
||
return results;
|
||
}
|
||
|
||
if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
|
||
return [];
|
||
}
|
||
|
||
if ( documentIsHTML && !seed ) {
|
||
|
||
// Shortcuts
|
||
if ( (match = rquickExpr.exec( selector )) ) {
|
||
// Speed-up: Sizzle("#ID")
|
||
if ( (m = match[1]) ) {
|
||
if ( nodeType === 9 ) {
|
||
elem = context.getElementById( m );
|
||
// Check parentNode to catch when Blackberry 4.6 returns
|
||
// nodes that are no longer in the document (jQuery #6963)
|
||
if ( elem && elem.parentNode ) {
|
||
// Handle the case where IE, Opera, and Webkit return items
|
||
// by name instead of ID
|
||
if ( elem.id === m ) {
|
||
results.push( elem );
|
||
return results;
|
||
}
|
||
} else {
|
||
return results;
|
||
}
|
||
} else {
|
||
// Context is not a document
|
||
if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
|
||
contains( context, elem ) && elem.id === m ) {
|
||
results.push( elem );
|
||
return results;
|
||
}
|
||
}
|
||
|
||
// Speed-up: Sizzle("TAG")
|
||
} else if ( match[2] ) {
|
||
push.apply( results, context.getElementsByTagName( selector ) );
|
||
return results;
|
||
|
||
// Speed-up: Sizzle(".CLASS")
|
||
} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
|
||
push.apply( results, context.getElementsByClassName( m ) );
|
||
return results;
|
||
}
|
||
}
|
||
|
||
// QSA path
|
||
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
|
||
nid = old = expando;
|
||
newContext = context;
|
||
newSelector = nodeType === 9 && selector;
|
||
|
||
// 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
|
||
if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
|
||
groups = tokenize( selector );
|
||
|
||
if ( (old = context.getAttribute("id")) ) {
|
||
nid = old.replace( rescape, "\\$&" );
|
||
} else {
|
||
context.setAttribute( "id", nid );
|
||
}
|
||
nid = "[id='" + nid + "'] ";
|
||
|
||
i = groups.length;
|
||
while ( i-- ) {
|
||
groups[i] = nid + toSelector( groups[i] );
|
||
}
|
||
newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
|
||
newSelector = groups.join(",");
|
||
}
|
||
|
||
if ( newSelector ) {
|
||
try {
|
||
push.apply( results,
|
||
newContext.querySelectorAll( newSelector )
|
||
);
|
||
return results;
|
||
} catch(qsaError) {
|
||
} finally {
|
||
if ( !old ) {
|
||
context.removeAttribute("id");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// All others
|
||
return select( selector.replace( rtrim, "$1" ), context, results, seed );
|
||
}
|
||
|
||
/**
|
||
* Create key-value caches of limited size
|
||
* @returns {Function(string, Object)} Returns the Object data after storing it on itself with
|
||
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
|
||
* deleting the oldest entry
|
||
*/
|
||
function createCache() {
|
||
var keys = [];
|
||
|
||
function cache( key, value ) {
|
||
// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
|
||
if ( keys.push( key + " " ) > Expr.cacheLength ) {
|
||
// Only keep the most recent entries
|
||
delete cache[ keys.shift() ];
|
||
}
|
||
return (cache[ key + " " ] = value);
|
||
}
|
||
return cache;
|
||
}
|
||
|
||
/**
|
||
* Mark a function for special use by Sizzle
|
||
* @param {Function} fn The function to mark
|
||
*/
|
||
function markFunction( fn ) {
|
||
fn[ expando ] = true;
|
||
return fn;
|
||
}
|
||
|
||
/**
|
||
* Support testing using an element
|
||
* @param {Function} fn Passed the created div and expects a boolean result
|
||
*/
|
||
function assert( fn ) {
|
||
var div = document.createElement("div");
|
||
|
||
try {
|
||
return !!fn( div );
|
||
} catch (e) {
|
||
return false;
|
||
} finally {
|
||
// Remove from its parent by default
|
||
if ( div.parentNode ) {
|
||
div.parentNode.removeChild( div );
|
||
}
|
||
// release memory in IE
|
||
div = null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Adds the same handler for all of the specified attrs
|
||
* @param {String} attrs Pipe-separated list of attributes
|
||
* @param {Function} handler The method that will be applied
|
||
*/
|
||
function addHandle( attrs, handler ) {
|
||
var arr = attrs.split("|"),
|
||
i = attrs.length;
|
||
|
||
while ( i-- ) {
|
||
Expr.attrHandle[ arr[i] ] = handler;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Checks document order of two siblings
|
||
* @param {Element} a
|
||
* @param {Element} b
|
||
* @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
|
||
*/
|
||
function siblingCheck( a, b ) {
|
||
var cur = b && a,
|
||
diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
|
||
( ~b.sourceIndex || MAX_NEGATIVE ) -
|
||
( ~a.sourceIndex || MAX_NEGATIVE );
|
||
|
||
// Use IE sourceIndex if available on both nodes
|
||
if ( diff ) {
|
||
return diff;
|
||
}
|
||
|
||
// Check if b follows a
|
||
if ( cur ) {
|
||
while ( (cur = cur.nextSibling) ) {
|
||
if ( cur === b ) {
|
||
return -1;
|
||
}
|
||
}
|
||
}
|
||
|
||
return a ? 1 : -1;
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for input types
|
||
* @param {String} type
|
||
*/
|
||
function createInputPseudo( type ) {
|
||
return function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return name === "input" && elem.type === type;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for buttons
|
||
* @param {String} type
|
||
*/
|
||
function createButtonPseudo( type ) {
|
||
return function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return (name === "input" || name === "button") && elem.type === type;
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Returns a function to use in pseudos for positionals
|
||
* @param {Function} fn
|
||
*/
|
||
function createPositionalPseudo( fn ) {
|
||
return markFunction(function( argument ) {
|
||
argument = +argument;
|
||
return markFunction(function( seed, matches ) {
|
||
var j,
|
||
matchIndexes = fn( [], seed.length, argument ),
|
||
i = matchIndexes.length;
|
||
|
||
// Match elements found at the specified indexes
|
||
while ( i-- ) {
|
||
if ( seed[ (j = matchIndexes[i]) ] ) {
|
||
seed[j] = !(matches[j] = seed[j]);
|
||
}
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Checks a node for validity as a Sizzle context
|
||
* @param {Element|Object=} context
|
||
* @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
|
||
*/
|
||
function testContext( context ) {
|
||
return context && typeof context.getElementsByTagName !== strundefined && context;
|
||
}
|
||
|
||
// Expose support vars for convenience
|
||
support = Sizzle.support = {};
|
||
|
||
/**
|
||
* Detects XML nodes
|
||
* @param {Element|Object} elem An element or a document
|
||
* @returns {Boolean} True iff elem is a non-HTML XML node
|
||
*/
|
||
isXML = 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).documentElement;
|
||
return documentElement ? documentElement.nodeName !== "HTML" : false;
|
||
};
|
||
|
||
/**
|
||
* Sets document-related variables once based on the current document
|
||
* @param {Element|Object} [doc] An element or document object to use to set the document
|
||
* @returns {Object} Returns the current document
|
||
*/
|
||
setDocument = Sizzle.setDocument = function( node ) {
|
||
var hasCompare,
|
||
doc = node ? node.ownerDocument || node : preferredDoc,
|
||
parent = doc.defaultView;
|
||
|
||
// If no document and documentElement is available, return
|
||
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
|
||
return document;
|
||
}
|
||
|
||
// Set our document
|
||
document = doc;
|
||
docElem = doc.documentElement;
|
||
|
||
// Support tests
|
||
documentIsHTML = !isXML( doc );
|
||
|
||
// Support: IE>8
|
||
// If iframe document is assigned to "document" variable and if iframe has been reloaded,
|
||
// IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
|
||
// IE6-8 do not support the defaultView property so parent will be undefined
|
||
if ( parent && parent !== parent.top ) {
|
||
// IE11 does not have attachEvent, so all must suffer
|
||
if ( parent.addEventListener ) {
|
||
parent.addEventListener( "unload", function() {
|
||
setDocument();
|
||
}, false );
|
||
} else if ( parent.attachEvent ) {
|
||
parent.attachEvent( "onunload", function() {
|
||
setDocument();
|
||
});
|
||
}
|
||
}
|
||
|
||
/* Attributes
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Support: IE<8
|
||
// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
|
||
support.attributes = assert(function( div ) {
|
||
div.className = "i";
|
||
return !div.getAttribute("className");
|
||
});
|
||
|
||
/* getElement(s)By*
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Check if getElementsByTagName("*") returns only elements
|
||
support.getElementsByTagName = assert(function( div ) {
|
||
div.appendChild( doc.createComment("") );
|
||
return !div.getElementsByTagName("*").length;
|
||
});
|
||
|
||
// Check if getElementsByClassName can be trusted
|
||
support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
|
||
div.innerHTML = "<div class='a'></div><div class='a i'></div>";
|
||
|
||
// Support: Safari<4
|
||
// Catch class over-caching
|
||
div.firstChild.className = "i";
|
||
// Support: Opera<10
|
||
// Catch gEBCN failure to find non-leading classes
|
||
return div.getElementsByClassName("i").length === 2;
|
||
});
|
||
|
||
// Support: IE<10
|
||
// Check if getElementById returns elements by name
|
||
// The broken getElementById methods don't pick up programatically-set names,
|
||
// so use a roundabout getElementsByName test
|
||
support.getById = assert(function( div ) {
|
||
docElem.appendChild( div ).id = expando;
|
||
return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
|
||
});
|
||
|
||
// ID find and filter
|
||
if ( support.getById ) {
|
||
Expr.find["ID"] = function( id, context ) {
|
||
if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
|
||
var m = context.getElementById( id );
|
||
// Check parentNode to catch when Blackberry 4.6 returns
|
||
// nodes that are no longer in the document #6963
|
||
return m && m.parentNode ? [ m ] : [];
|
||
}
|
||
};
|
||
Expr.filter["ID"] = function( id ) {
|
||
var attrId = id.replace( runescape, funescape );
|
||
return function( elem ) {
|
||
return elem.getAttribute("id") === attrId;
|
||
};
|
||
};
|
||
} else {
|
||
// Support: IE6/7
|
||
// getElementById is not reliable as a find shortcut
|
||
delete Expr.find["ID"];
|
||
|
||
Expr.filter["ID"] = function( id ) {
|
||
var attrId = id.replace( runescape, funescape );
|
||
return function( elem ) {
|
||
var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
|
||
return node && node.value === attrId;
|
||
};
|
||
};
|
||
}
|
||
|
||
// Tag
|
||
Expr.find["TAG"] = support.getElementsByTagName ?
|
||
function( tag, context ) {
|
||
if ( typeof context.getElementsByTagName !== strundefined ) {
|
||
return context.getElementsByTagName( tag );
|
||
}
|
||
} :
|
||
function( tag, context ) {
|
||
var elem,
|
||
tmp = [],
|
||
i = 0,
|
||
results = context.getElementsByTagName( tag );
|
||
|
||
// Filter out possible comments
|
||
if ( tag === "*" ) {
|
||
while ( (elem = results[i++]) ) {
|
||
if ( elem.nodeType === 1 ) {
|
||
tmp.push( elem );
|
||
}
|
||
}
|
||
|
||
return tmp;
|
||
}
|
||
return results;
|
||
};
|
||
|
||
// Class
|
||
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
|
||
if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
|
||
return context.getElementsByClassName( className );
|
||
}
|
||
};
|
||
|
||
/* QSA/matchesSelector
|
||
---------------------------------------------------------------------- */
|
||
|
||
// QSA and matchesSelector support
|
||
|
||
// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
|
||
rbuggyMatches = [];
|
||
|
||
// qSa(:focus) reports false when true (Chrome 21)
|
||
// We allow this because of a bug in IE8/9 that throws an error
|
||
// whenever `document.activeElement` is accessed on an iframe
|
||
// So, we allow :focus to pass through QSA all the time to avoid the IE error
|
||
// See http://bugs.jquery.com/ticket/13378
|
||
rbuggyQSA = [];
|
||
|
||
if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
|
||
// Build QSA regex
|
||
// Regex strategy adopted from Diego Perini
|
||
assert(function( div ) {
|
||
// Select is set to empty string on purpose
|
||
// This is to test IE's treatment of not explicitly
|
||
// setting a boolean content attribute,
|
||
// since its presence should be enough
|
||
// http://bugs.jquery.com/ticket/12359
|
||
div.innerHTML = "<select msallowclip=''><option selected=''></option></select>";
|
||
|
||
// Support: IE8, Opera 11-12.16
|
||
// Nothing should be selected when empty strings follow ^= or $= or *=
|
||
// The test attribute must be unknown in Opera but "safe" for WinRT
|
||
// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
|
||
if ( div.querySelectorAll("[msallowclip^='']").length ) {
|
||
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
|
||
}
|
||
|
||
// Support: IE8
|
||
// Boolean attributes and "value" are not treated correctly
|
||
if ( !div.querySelectorAll("[selected]").length ) {
|
||
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
|
||
}
|
||
|
||
// Webkit/Opera - :checked should return selected option elements
|
||
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
|
||
// IE8 throws error here and will not see later tests
|
||
if ( !div.querySelectorAll(":checked").length ) {
|
||
rbuggyQSA.push(":checked");
|
||
}
|
||
});
|
||
|
||
assert(function( div ) {
|
||
// Support: Windows 8 Native Apps
|
||
// The type and name attributes are restricted during .innerHTML assignment
|
||
var input = doc.createElement("input");
|
||
input.setAttribute( "type", "hidden" );
|
||
div.appendChild( input ).setAttribute( "name", "D" );
|
||
|
||
// Support: IE8
|
||
// Enforce case-sensitivity of name attribute
|
||
if ( div.querySelectorAll("[name=d]").length ) {
|
||
rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
|
||
}
|
||
|
||
// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
|
||
// IE8 throws error here and will not see later tests
|
||
if ( !div.querySelectorAll(":enabled").length ) {
|
||
rbuggyQSA.push( ":enabled", ":disabled" );
|
||
}
|
||
|
||
// Opera 10-11 does not throw on post-comma invalid pseudos
|
||
div.querySelectorAll("*,:x");
|
||
rbuggyQSA.push(",.*:");
|
||
});
|
||
}
|
||
|
||
if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
|
||
docElem.webkitMatchesSelector ||
|
||
docElem.mozMatchesSelector ||
|
||
docElem.oMatchesSelector ||
|
||
docElem.msMatchesSelector) )) ) {
|
||
|
||
assert(function( div ) {
|
||
// Check to see if it's possible to do matchesSelector
|
||
// on a disconnected node (IE 9)
|
||
support.disconnectedMatch = matches.call( div, "div" );
|
||
|
||
// This should fail with an exception
|
||
// Gecko does not error, returns false instead
|
||
matches.call( div, "[s!='']:x" );
|
||
rbuggyMatches.push( "!=", pseudos );
|
||
});
|
||
}
|
||
|
||
rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
|
||
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
|
||
|
||
/* Contains
|
||
---------------------------------------------------------------------- */
|
||
hasCompare = rnative.test( docElem.compareDocumentPosition );
|
||
|
||
// Element contains another
|
||
// Purposefully does not implement inclusive descendent
|
||
// As in, an element does not contain itself
|
||
contains = hasCompare || rnative.test( docElem.contains ) ?
|
||
function( a, b ) {
|
||
var adown = a.nodeType === 9 ? a.documentElement : a,
|
||
bup = b && b.parentNode;
|
||
return a === bup || !!( bup && bup.nodeType === 1 && (
|
||
adown.contains ?
|
||
adown.contains( bup ) :
|
||
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
|
||
));
|
||
} :
|
||
function( a, b ) {
|
||
if ( b ) {
|
||
while ( (b = b.parentNode) ) {
|
||
if ( b === a ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
/* Sorting
|
||
---------------------------------------------------------------------- */
|
||
|
||
// Document order sorting
|
||
sortOrder = hasCompare ?
|
||
function( a, b ) {
|
||
|
||
// Flag for duplicate removal
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
return 0;
|
||
}
|
||
|
||
// Sort on method existence if only one input has compareDocumentPosition
|
||
var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
|
||
if ( compare ) {
|
||
return compare;
|
||
}
|
||
|
||
// Calculate position if both inputs belong to the same document
|
||
compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
|
||
a.compareDocumentPosition( b ) :
|
||
|
||
// Otherwise we know they are disconnected
|
||
1;
|
||
|
||
// Disconnected nodes
|
||
if ( compare & 1 ||
|
||
(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
|
||
|
||
// Choose the first element that is related to our preferred document
|
||
if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
|
||
return -1;
|
||
}
|
||
if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
|
||
return 1;
|
||
}
|
||
|
||
// Maintain original order
|
||
return sortInput ?
|
||
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
|
||
0;
|
||
}
|
||
|
||
return compare & 4 ? -1 : 1;
|
||
} :
|
||
function( a, b ) {
|
||
// Exit early if the nodes are identical
|
||
if ( a === b ) {
|
||
hasDuplicate = true;
|
||
return 0;
|
||
}
|
||
|
||
var cur,
|
||
i = 0,
|
||
aup = a.parentNode,
|
||
bup = b.parentNode,
|
||
ap = [ a ],
|
||
bp = [ b ];
|
||
|
||
// Parentless nodes are either documents or disconnected
|
||
if ( !aup || !bup ) {
|
||
return a === doc ? -1 :
|
||
b === doc ? 1 :
|
||
aup ? -1 :
|
||
bup ? 1 :
|
||
sortInput ?
|
||
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
|
||
0;
|
||
|
||
// If the nodes are siblings, we can do a quick check
|
||
} else if ( aup === bup ) {
|
||
return siblingCheck( a, b );
|
||
}
|
||
|
||
// Otherwise we need full lists of their ancestors for comparison
|
||
cur = a;
|
||
while ( (cur = cur.parentNode) ) {
|
||
ap.unshift( cur );
|
||
}
|
||
cur = b;
|
||
while ( (cur = cur.parentNode) ) {
|
||
bp.unshift( cur );
|
||
}
|
||
|
||
// Walk down the tree looking for a discrepancy
|
||
while ( ap[i] === bp[i] ) {
|
||
i++;
|
||
}
|
||
|
||
return i ?
|
||
// Do a sibling check if the nodes have a common ancestor
|
||
siblingCheck( ap[i], bp[i] ) :
|
||
|
||
// Otherwise nodes in our document sort first
|
||
ap[i] === preferredDoc ? -1 :
|
||
bp[i] === preferredDoc ? 1 :
|
||
0;
|
||
};
|
||
|
||
return doc;
|
||
};
|
||
|
||
Sizzle.matches = function( expr, elements ) {
|
||
return Sizzle( expr, null, null, elements );
|
||
};
|
||
|
||
Sizzle.matchesSelector = function( elem, expr ) {
|
||
// Set document vars if needed
|
||
if ( ( elem.ownerDocument || elem ) !== document ) {
|
||
setDocument( elem );
|
||
}
|
||
|
||
// Make sure that attribute selectors are quoted
|
||
expr = expr.replace( rattributeQuotes, "='$1']" );
|
||
|
||
if ( support.matchesSelector && documentIsHTML &&
|
||
( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
|
||
( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
|
||
|
||
try {
|
||
var ret = matches.call( elem, expr );
|
||
|
||
// IE 9's matchesSelector returns false on disconnected nodes
|
||
if ( ret || support.disconnectedMatch ||
|
||
// As well, disconnected nodes are said to be in a document
|
||
// fragment in IE 9
|
||
elem.document && elem.document.nodeType !== 11 ) {
|
||
return ret;
|
||
}
|
||
} catch(e) {}
|
||
}
|
||
|
||
return Sizzle( expr, document, null, [ elem ] ).length > 0;
|
||
};
|
||
|
||
Sizzle.contains = function( context, elem ) {
|
||
// Set document vars if needed
|
||
if ( ( context.ownerDocument || context ) !== document ) {
|
||
setDocument( context );
|
||
}
|
||
return contains( context, elem );
|
||
};
|
||
|
||
Sizzle.attr = function( elem, name ) {
|
||
// Set document vars if needed
|
||
if ( ( elem.ownerDocument || elem ) !== document ) {
|
||
setDocument( elem );
|
||
}
|
||
|
||
var fn = Expr.attrHandle[ name.toLowerCase() ],
|
||
// Don't get fooled by Object.prototype properties (jQuery #13807)
|
||
val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
|
||
fn( elem, name, !documentIsHTML ) :
|
||
undefined;
|
||
|
||
return val !== undefined ?
|
||
val :
|
||
support.attributes || !documentIsHTML ?
|
||
elem.getAttribute( name ) :
|
||
(val = elem.getAttributeNode(name)) && val.specified ?
|
||
val.value :
|
||
null;
|
||
};
|
||
|
||
Sizzle.error = function( msg ) {
|
||
throw new Error( "Syntax error, unrecognized expression: " + msg );
|
||
};
|
||
|
||
/**
|
||
* Document sorting and removing duplicates
|
||
* @param {ArrayLike} results
|
||
*/
|
||
Sizzle.uniqueSort = function( results ) {
|
||
var elem,
|
||
duplicates = [],
|
||
j = 0,
|
||
i = 0;
|
||
|
||
// Unless we *know* we can detect duplicates, assume their presence
|
||
hasDuplicate = !support.detectDuplicates;
|
||
sortInput = !support.sortStable && results.slice( 0 );
|
||
results.sort( sortOrder );
|
||
|
||
if ( hasDuplicate ) {
|
||
while ( (elem = results[i++]) ) {
|
||
if ( elem === results[ i ] ) {
|
||
j = duplicates.push( i );
|
||
}
|
||
}
|
||
while ( j-- ) {
|
||
results.splice( duplicates[ j ], 1 );
|
||
}
|
||
}
|
||
|
||
// Clear input after sorting to release objects
|
||
// See https://github.com/jquery/sizzle/pull/225
|
||
sortInput = null;
|
||
|
||
return results;
|
||
};
|
||
|
||
/**
|
||
* Utility function for retrieving the text value of an array of DOM nodes
|
||
* @param {Array|Element} elem
|
||
*/
|
||
getText = Sizzle.getText = function( elem ) {
|
||
var node,
|
||
ret = "",
|
||
i = 0,
|
||
nodeType = elem.nodeType;
|
||
|
||
if ( !nodeType ) {
|
||
// If no nodeType, this is expected to be an array
|
||
while ( (node = elem[i++]) ) {
|
||
// Do not traverse comment nodes
|
||
ret += getText( node );
|
||
}
|
||
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
|
||
// Use textContent for elements
|
||
// innerText usage removed for consistency of new lines (jQuery #11153)
|
||
if ( typeof elem.textContent === "string" ) {
|
||
return elem.textContent;
|
||
} else {
|
||
// Traverse its children
|
||
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
|
||
ret += getText( elem );
|
||
}
|
||
}
|
||
} else if ( nodeType === 3 || nodeType === 4 ) {
|
||
return elem.nodeValue;
|
||
}
|
||
// Do not include comment or processing instruction nodes
|
||
|
||
return ret;
|
||
};
|
||
|
||
Expr = Sizzle.selectors = {
|
||
|
||
// Can be adjusted by the user
|
||
cacheLength: 50,
|
||
|
||
createPseudo: markFunction,
|
||
|
||
match: matchExpr,
|
||
|
||
attrHandle: {},
|
||
|
||
find: {},
|
||
|
||
relative: {
|
||
">": { dir: "parentNode", first: true },
|
||
" ": { dir: "parentNode" },
|
||
"+": { dir: "previousSibling", first: true },
|
||
"~": { dir: "previousSibling" }
|
||
},
|
||
|
||
preFilter: {
|
||
"ATTR": function( match ) {
|
||
match[1] = match[1].replace( runescape, funescape );
|
||
|
||
// Move the given value to match[3] whether quoted or unquoted
|
||
match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
|
||
|
||
if ( match[2] === "~=" ) {
|
||
match[3] = " " + match[3] + " ";
|
||
}
|
||
|
||
return match.slice( 0, 4 );
|
||
},
|
||
|
||
"CHILD": function( match ) {
|
||
/* matches from matchExpr["CHILD"]
|
||
1 type (only|nth|...)
|
||
2 what (child|of-type)
|
||
3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
|
||
4 xn-component of xn+y argument ([+-]?\d*n|)
|
||
5 sign of xn-component
|
||
6 x of xn-component
|
||
7 sign of y-component
|
||
8 y of y-component
|
||
*/
|
||
match[1] = match[1].toLowerCase();
|
||
|
||
if ( match[1].slice( 0, 3 ) === "nth" ) {
|
||
// nth-* requires argument
|
||
if ( !match[3] ) {
|
||
Sizzle.error( match[0] );
|
||
}
|
||
|
||
// numeric x and y parameters for Expr.filter.CHILD
|
||
// remember that false/true cast respectively to 0/1
|
||
match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
|
||
match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
|
||
|
||
// other types prohibit arguments
|
||
} else if ( match[3] ) {
|
||
Sizzle.error( match[0] );
|
||
}
|
||
|
||
return match;
|
||
},
|
||
|
||
"PSEUDO": function( match ) {
|
||
var excess,
|
||
unquoted = !match[6] && match[2];
|
||
|
||
if ( matchExpr["CHILD"].test( match[0] ) ) {
|
||
return null;
|
||
}
|
||
|
||
// Accept quoted arguments as-is
|
||
if ( match[3] ) {
|
||
match[2] = match[4] || match[5] || "";
|
||
|
||
// Strip excess characters from unquoted arguments
|
||
} else if ( unquoted && rpseudo.test( unquoted ) &&
|
||
// Get excess from tokenize (recursively)
|
||
(excess = tokenize( unquoted, true )) &&
|
||
// advance to the next closing parenthesis
|
||
(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
|
||
|
||
// excess is a negative index
|
||
match[0] = match[0].slice( 0, excess );
|
||
match[2] = unquoted.slice( 0, excess );
|
||
}
|
||
|
||
// Return only captures needed by the pseudo filter method (type and argument)
|
||
return match.slice( 0, 3 );
|
||
}
|
||
},
|
||
|
||
filter: {
|
||
|
||
"TAG": function( nodeNameSelector ) {
|
||
var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
|
||
return nodeNameSelector === "*" ?
|
||
function() { return true; } :
|
||
function( elem ) {
|
||
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
|
||
};
|
||
},
|
||
|
||
"CLASS": function( className ) {
|
||
var pattern = classCache[ className + " " ];
|
||
|
||
return pattern ||
|
||
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
|
||
classCache( className, function( elem ) {
|
||
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
|
||
});
|
||
},
|
||
|
||
"ATTR": function( name, operator, check ) {
|
||
return function( elem ) {
|
||
var result = Sizzle.attr( elem, name );
|
||
|
||
if ( result == null ) {
|
||
return operator === "!=";
|
||
}
|
||
if ( !operator ) {
|
||
return true;
|
||
}
|
||
|
||
result += "";
|
||
|
||
return operator === "=" ? result === check :
|
||
operator === "!=" ? result !== check :
|
||
operator === "^=" ? check && result.indexOf( check ) === 0 :
|
||
operator === "*=" ? check && result.indexOf( check ) > -1 :
|
||
operator === "$=" ? check && result.slice( -check.length ) === check :
|
||
operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
|
||
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
|
||
false;
|
||
};
|
||
},
|
||
|
||
"CHILD": function( type, what, argument, first, last ) {
|
||
var simple = type.slice( 0, 3 ) !== "nth",
|
||
forward = type.slice( -4 ) !== "last",
|
||
ofType = what === "of-type";
|
||
|
||
return first === 1 && last === 0 ?
|
||
|
||
// Shortcut for :nth-*(n)
|
||
function( elem ) {
|
||
return !!elem.parentNode;
|
||
} :
|
||
|
||
function( elem, context, xml ) {
|
||
var cache, outerCache, node, diff, nodeIndex, start,
|
||
dir = simple !== forward ? "nextSibling" : "previousSibling",
|
||
parent = elem.parentNode,
|
||
name = ofType && elem.nodeName.toLowerCase(),
|
||
useCache = !xml && !ofType;
|
||
|
||
if ( parent ) {
|
||
|
||
// :(first|last|only)-(child|of-type)
|
||
if ( simple ) {
|
||
while ( dir ) {
|
||
node = elem;
|
||
while ( (node = node[ dir ]) ) {
|
||
if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
|
||
return false;
|
||
}
|
||
}
|
||
// Reverse direction for :only-* (if we haven't yet done so)
|
||
start = dir = type === "only" && !start && "nextSibling";
|
||
}
|
||
return true;
|
||
}
|
||
|
||
start = [ forward ? parent.firstChild : parent.lastChild ];
|
||
|
||
// non-xml :nth-child(...) stores cache data on `parent`
|
||
if ( forward && useCache ) {
|
||
// Seek `elem` from a previously-cached index
|
||
outerCache = parent[ expando ] || (parent[ expando ] = {});
|
||
cache = outerCache[ type ] || [];
|
||
nodeIndex = cache[0] === dirruns && cache[1];
|
||
diff = cache[0] === dirruns && cache[2];
|
||
node = nodeIndex && parent.childNodes[ nodeIndex ];
|
||
|
||
while ( (node = ++nodeIndex && node && node[ dir ] ||
|
||
|
||
// Fallback to seeking `elem` from the start
|
||
(diff = nodeIndex = 0) || start.pop()) ) {
|
||
|
||
// When found, cache indexes on `parent` and break
|
||
if ( node.nodeType === 1 && ++diff && node === elem ) {
|
||
outerCache[ type ] = [ dirruns, nodeIndex, diff ];
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Use previously-cached element index if available
|
||
} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
|
||
diff = cache[1];
|
||
|
||
// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
|
||
} else {
|
||
// Use the same loop as above to seek `elem` from the start
|
||
while ( (node = ++nodeIndex && node && node[ dir ] ||
|
||
(diff = nodeIndex = 0) || start.pop()) ) {
|
||
|
||
if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
|
||
// Cache the index of each encountered element
|
||
if ( useCache ) {
|
||
(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
|
||
}
|
||
|
||
if ( node === elem ) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Incorporate the offset, then check against cycle size
|
||
diff -= last;
|
||
return diff === first || ( diff % first === 0 && diff / first >= 0 );
|
||
}
|
||
};
|
||
},
|
||
|
||
"PSEUDO": function( pseudo, argument ) {
|
||
// pseudo-class names are case-insensitive
|
||
// http://www.w3.org/TR/selectors/#pseudo-classes
|
||
// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
|
||
// Remember that setFilters inherits from pseudos
|
||
var args,
|
||
fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
|
||
Sizzle.error( "unsupported pseudo: " + pseudo );
|
||
|
||
// The user may use createPseudo to indicate that
|
||
// arguments are needed to create the filter function
|
||
// just as Sizzle does
|
||
if ( fn[ expando ] ) {
|
||
return fn( argument );
|
||
}
|
||
|
||
// But maintain support for old signatures
|
||
if ( fn.length > 1 ) {
|
||
args = [ pseudo, pseudo, "", argument ];
|
||
return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
|
||
markFunction(function( seed, matches ) {
|
||
var idx,
|
||
matched = fn( seed, argument ),
|
||
i = matched.length;
|
||
while ( i-- ) {
|
||
idx = indexOf.call( seed, matched[i] );
|
||
seed[ idx ] = !( matches[ idx ] = matched[i] );
|
||
}
|
||
}) :
|
||
function( elem ) {
|
||
return fn( elem, 0, args );
|
||
};
|
||
}
|
||
|
||
return fn;
|
||
}
|
||
},
|
||
|
||
pseudos: {
|
||
// Potentially complex pseudos
|
||
"not": markFunction(function( selector ) {
|
||
// Trim the selector passed to compile
|
||
// to avoid treating leading and trailing
|
||
// spaces as combinators
|
||
var input = [],
|
||
results = [],
|
||
matcher = compile( selector.replace( rtrim, "$1" ) );
|
||
|
||
return matcher[ expando ] ?
|
||
markFunction(function( seed, matches, context, xml ) {
|
||
var elem,
|
||
unmatched = matcher( seed, null, xml, [] ),
|
||
i = seed.length;
|
||
|
||
// Match elements unmatched by `matcher`
|
||
while ( i-- ) {
|
||
if ( (elem = unmatched[i]) ) {
|
||
seed[i] = !(matches[i] = elem);
|
||
}
|
||
}
|
||
}) :
|
||
function( elem, context, xml ) {
|
||
input[0] = elem;
|
||
matcher( input, null, xml, results );
|
||
return !results.pop();
|
||
};
|
||
}),
|
||
|
||
"has": markFunction(function( selector ) {
|
||
return function( elem ) {
|
||
return Sizzle( selector, elem ).length > 0;
|
||
};
|
||
}),
|
||
|
||
"contains": markFunction(function( text ) {
|
||
return function( elem ) {
|
||
return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
|
||
};
|
||
}),
|
||
|
||
// "Whether an element is represented by a :lang() selector
|
||
// is based solely on the element's language value
|
||
// being equal to the identifier C,
|
||
// or beginning with the identifier C immediately followed by "-".
|
||
// The matching of C against the element's language value is performed case-insensitively.
|
||
// The identifier C does not have to be a valid language name."
|
||
// http://www.w3.org/TR/selectors/#lang-pseudo
|
||
"lang": markFunction( function( lang ) {
|
||
// lang value must be a valid identifier
|
||
if ( !ridentifier.test(lang || "") ) {
|
||
Sizzle.error( "unsupported lang: " + lang );
|
||
}
|
||
lang = lang.replace( runescape, funescape ).toLowerCase();
|
||
return function( elem ) {
|
||
var elemLang;
|
||
do {
|
||
if ( (elemLang = documentIsHTML ?
|
||
elem.lang :
|
||
elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
|
||
|
||
elemLang = elemLang.toLowerCase();
|
||
return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
|
||
}
|
||
} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
|
||
return false;
|
||
};
|
||
}),
|
||
|
||
// Miscellaneous
|
||
"target": function( elem ) {
|
||
var hash = window.location && window.location.hash;
|
||
return hash && hash.slice( 1 ) === elem.id;
|
||
},
|
||
|
||
"root": function( elem ) {
|
||
return elem === docElem;
|
||
},
|
||
|
||
"focus": function( elem ) {
|
||
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
|
||
},
|
||
|
||
// Boolean properties
|
||
"enabled": function( elem ) {
|
||
return elem.disabled === false;
|
||
},
|
||
|
||
"disabled": function( elem ) {
|
||
return elem.disabled === true;
|
||
},
|
||
|
||
"checked": function( elem ) {
|
||
// In CSS3, :checked should return both checked and selected elements
|
||
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
|
||
var nodeName = elem.nodeName.toLowerCase();
|
||
return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
|
||
},
|
||
|
||
"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;
|
||
},
|
||
|
||
// Contents
|
||
"empty": function( elem ) {
|
||
// http://www.w3.org/TR/selectors/#empty-pseudo
|
||
// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
|
||
// but not by others (comment: 8; processing instruction: 7; etc.)
|
||
// nodeType < 6 works because attributes (2) do not appear as children
|
||
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
|
||
if ( elem.nodeType < 6 ) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
},
|
||
|
||
"parent": function( elem ) {
|
||
return !Expr.pseudos["empty"]( elem );
|
||
},
|
||
|
||
// Element/input types
|
||
"header": function( elem ) {
|
||
return rheader.test( elem.nodeName );
|
||
},
|
||
|
||
"input": function( elem ) {
|
||
return rinputs.test( elem.nodeName );
|
||
},
|
||
|
||
"button": function( elem ) {
|
||
var name = elem.nodeName.toLowerCase();
|
||
return name === "input" && elem.type === "button" || name === "button";
|
||
},
|
||
|
||
"text": function( elem ) {
|
||
var attr;
|
||
return elem.nodeName.toLowerCase() === "input" &&
|
||
elem.type === "text" &&
|
||
|
||
// Support: IE<8
|
||
// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
|
||
( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
|
||
},
|
||
|
||
// Position-in-collection
|
||
"first": createPositionalPseudo(function() {
|
||
return [ 0 ];
|
||
}),
|
||
|
||
"last": createPositionalPseudo(function( matchIndexes, length ) {
|
||
return [ length - 1 ];
|
||
}),
|
||
|
||
"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
return [ argument < 0 ? argument + length : argument ];
|
||
}),
|
||
|
||
"even": createPositionalPseudo(function( matchIndexes, length ) {
|
||
var i = 0;
|
||
for ( ; i < length; i += 2 ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"odd": createPositionalPseudo(function( matchIndexes, length ) {
|
||
var i = 1;
|
||
for ( ; i < length; i += 2 ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
var i = argument < 0 ? argument + length : argument;
|
||
for ( ; --i >= 0; ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
}),
|
||
|
||
"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
|
||
var i = argument < 0 ? argument + length : argument;
|
||
for ( ; ++i < length; ) {
|
||
matchIndexes.push( i );
|
||
}
|
||
return matchIndexes;
|
||
})
|
||
}
|
||
};
|
||
|
||
Expr.pseudos["nth"] = Expr.pseudos["eq"];
|
||
|
||
// Add button/input type pseudos
|
||
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
|
||
Expr.pseudos[ i ] = createInputPseudo( i );
|
||
}
|
||
for ( i in { submit: true, reset: true } ) {
|
||
Expr.pseudos[ i ] = createButtonPseudo( i );
|
||
}
|
||
|
||
// Easy API for creating new setFilters
|
||
function setFilters() {}
|
||
setFilters.prototype = Expr.filters = Expr.pseudos;
|
||
Expr.setFilters = new setFilters();
|
||
|
||
tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
|
||
var matched, match, tokens, type,
|
||
soFar, groups, preFilters,
|
||
cached = tokenCache[ selector + " " ];
|
||
|
||
if ( cached ) {
|
||
return parseOnly ? 0 : cached.slice( 0 );
|
||
}
|
||
|
||
soFar = selector;
|
||
groups = [];
|
||
preFilters = Expr.preFilter;
|
||
|
||
while ( soFar ) {
|
||
|
||
// Comma and first run
|
||
if ( !matched || (match = rcomma.exec( soFar )) ) {
|
||
if ( match ) {
|
||
// Don't consume trailing commas as valid
|
||
soFar = soFar.slice( match[0].length ) || soFar;
|
||
}
|
||
groups.push( (tokens = []) );
|
||
}
|
||
|
||
matched = false;
|
||
|
||
// Combinators
|
||
if ( (match = rcombinators.exec( soFar )) ) {
|
||
matched = match.shift();
|
||
tokens.push({
|
||
value: matched,
|
||
// Cast descendant combinators to space
|
||
type: match[0].replace( rtrim, " " )
|
||
});
|
||
soFar = soFar.slice( matched.length );
|
||
}
|
||
|
||
// Filters
|
||
for ( type in Expr.filter ) {
|
||
if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
|
||
(match = preFilters[ type ]( match ))) ) {
|
||
matched = match.shift();
|
||
tokens.push({
|
||
value: matched,
|
||
type: type,
|
||
matches: match
|
||
});
|
||
soFar = soFar.slice( matched.length );
|
||
}
|
||
}
|
||
|
||
if ( !matched ) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Return the length of the invalid excess
|
||
// if we're just parsing
|
||
// Otherwise, throw an error or return tokens
|
||
return parseOnly ?
|
||
soFar.length :
|
||
soFar ?
|
||
Sizzle.error( selector ) :
|
||
// Cache the tokens
|
||
tokenCache( selector, groups ).slice( 0 );
|
||
};
|
||
|
||
function toSelector( tokens ) {
|
||
var i = 0,
|
||
len = tokens.length,
|
||
selector = "";
|
||
for ( ; i < len; i++ ) {
|
||
selector += tokens[i].value;
|
||
}
|
||
return selector;
|
||
}
|
||
|
||
function addCombinator( matcher, combinator, base ) {
|
||
var dir = combinator.dir,
|
||
checkNonElements = base && dir === "parentNode",
|
||
doneName = done++;
|
||
|
||
return combinator.first ?
|
||
// Check against closest ancestor/preceding element
|
||
function( elem, context, xml ) {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
return matcher( elem, context, xml );
|
||
}
|
||
}
|
||
} :
|
||
|
||
// Check against all ancestor/preceding elements
|
||
function( elem, context, xml ) {
|
||
var oldCache, outerCache,
|
||
newCache = [ dirruns, doneName ];
|
||
|
||
// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
|
||
if ( xml ) {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
if ( matcher( elem, context, xml ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
while ( (elem = elem[ dir ]) ) {
|
||
if ( elem.nodeType === 1 || checkNonElements ) {
|
||
outerCache = elem[ expando ] || (elem[ expando ] = {});
|
||
if ( (oldCache = outerCache[ dir ]) &&
|
||
oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
|
||
|
||
// Assign to newCache so results back-propagate to previous elements
|
||
return (newCache[ 2 ] = oldCache[ 2 ]);
|
||
} else {
|
||
// Reuse newcache so results back-propagate to previous elements
|
||
outerCache[ dir ] = newCache;
|
||
|
||
// A match means we're done; a fail means we have to keep checking
|
||
if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
function elementMatcher( matchers ) {
|
||
return matchers.length > 1 ?
|
||
function( elem, context, xml ) {
|
||
var i = matchers.length;
|
||
while ( i-- ) {
|
||
if ( !matchers[i]( elem, context, xml ) ) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
} :
|
||
matchers[0];
|
||
}
|
||
|
||
function multipleContexts( selector, contexts, results ) {
|
||
var i = 0,
|
||
len = contexts.length;
|
||
for ( ; i < len; i++ ) {
|
||
Sizzle( selector, contexts[i], results );
|
||
}
|
||
return results;
|
||
}
|
||
|
||
function condense( unmatched, map, filter, context, xml ) {
|
||
var elem,
|
||
newUnmatched = [],
|
||
i = 0,
|
||
len = unmatched.length,
|
||
mapped = map != null;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
if ( (elem = unmatched[i]) ) {
|
||
if ( !filter || filter( elem, context, xml ) ) {
|
||
newUnmatched.push( elem );
|
||
if ( mapped ) {
|
||
map.push( i );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return newUnmatched;
|
||
}
|
||
|
||
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
|
||
if ( postFilter && !postFilter[ expando ] ) {
|
||
postFilter = setMatcher( postFilter );
|
||
}
|
||
if ( postFinder && !postFinder[ expando ] ) {
|
||
postFinder = setMatcher( postFinder, postSelector );
|
||
}
|
||
return markFunction(function( seed, results, context, xml ) {
|
||
var temp, i, elem,
|
||
preMap = [],
|
||
postMap = [],
|
||
preexisting = results.length,
|
||
|
||
// Get initial elements from seed or context
|
||
elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
|
||
|
||
// Prefilter to get matcher input, preserving a map for seed-results synchronization
|
||
matcherIn = preFilter && ( seed || !selector ) ?
|
||
condense( elems, preMap, preFilter, context, xml ) :
|
||
elems,
|
||
|
||
matcherOut = matcher ?
|
||
// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
|
||
postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
|
||
|
||
// ...intermediate processing is necessary
|
||
[] :
|
||
|
||
// ...otherwise use results directly
|
||
results :
|
||
matcherIn;
|
||
|
||
// Find primary matches
|
||
if ( matcher ) {
|
||
matcher( matcherIn, matcherOut, context, xml );
|
||
}
|
||
|
||
// Apply postFilter
|
||
if ( postFilter ) {
|
||
temp = condense( matcherOut, postMap );
|
||
postFilter( temp, [], context, xml );
|
||
|
||
// Un-match failing elements by moving them back to matcherIn
|
||
i = temp.length;
|
||
while ( i-- ) {
|
||
if ( (elem = temp[i]) ) {
|
||
matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( seed ) {
|
||
if ( postFinder || preFilter ) {
|
||
if ( postFinder ) {
|
||
// Get the final matcherOut by condensing this intermediate into postFinder contexts
|
||
temp = [];
|
||
i = matcherOut.length;
|
||
while ( i-- ) {
|
||
if ( (elem = matcherOut[i]) ) {
|
||
// Restore matcherIn since elem is not yet a final match
|
||
temp.push( (matcherIn[i] = elem) );
|
||
}
|
||
}
|
||
postFinder( null, (matcherOut = []), temp, xml );
|
||
}
|
||
|
||
// Move matched elements from seed to results to keep them synchronized
|
||
i = matcherOut.length;
|
||
while ( i-- ) {
|
||
if ( (elem = matcherOut[i]) &&
|
||
(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
|
||
|
||
seed[temp] = !(results[temp] = elem);
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add elements to results, through postFinder if defined
|
||
} else {
|
||
matcherOut = condense(
|
||
matcherOut === results ?
|
||
matcherOut.splice( preexisting, matcherOut.length ) :
|
||
matcherOut
|
||
);
|
||
if ( postFinder ) {
|
||
postFinder( null, results, matcherOut, xml );
|
||
} else {
|
||
push.apply( results, matcherOut );
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|
||
function matcherFromTokens( tokens ) {
|
||
var checkContext, matcher, j,
|
||
len = tokens.length,
|
||
leadingRelative = Expr.relative[ tokens[0].type ],
|
||
implicitRelative = leadingRelative || Expr.relative[" "],
|
||
i = leadingRelative ? 1 : 0,
|
||
|
||
// The foundational matcher ensures that elements are reachable from top-level context(s)
|
||
matchContext = addCombinator( function( elem ) {
|
||
return elem === checkContext;
|
||
}, implicitRelative, true ),
|
||
matchAnyContext = addCombinator( function( elem ) {
|
||
return indexOf.call( checkContext, elem ) > -1;
|
||
}, implicitRelative, true ),
|
||
matchers = [ function( elem, context, xml ) {
|
||
return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
|
||
(checkContext = context).nodeType ?
|
||
matchContext( elem, context, xml ) :
|
||
matchAnyContext( elem, context, xml ) );
|
||
} ];
|
||
|
||
for ( ; i < len; i++ ) {
|
||
if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
|
||
matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
|
||
} else {
|
||
matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
|
||
|
||
// Return special upon seeing a positional matcher
|
||
if ( matcher[ expando ] ) {
|
||
// Find the next relative operator (if any) for proper handling
|
||
j = ++i;
|
||
for ( ; j < len; j++ ) {
|
||
if ( Expr.relative[ tokens[j].type ] ) {
|
||
break;
|
||
}
|
||
}
|
||
return setMatcher(
|
||
i > 1 && elementMatcher( matchers ),
|
||
i > 1 && toSelector(
|
||
// If the preceding token was a descendant combinator, insert an implicit any-element `*`
|
||
tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
|
||
).replace( rtrim, "$1" ),
|
||
matcher,
|
||
i < j && matcherFromTokens( tokens.slice( i, j ) ),
|
||
j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
|
||
j < len && toSelector( tokens )
|
||
);
|
||
}
|
||
matchers.push( matcher );
|
||
}
|
||
}
|
||
|
||
return elementMatcher( matchers );
|
||
}
|
||
|
||
function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
|
||
var bySet = setMatchers.length > 0,
|
||
byElement = elementMatchers.length > 0,
|
||
superMatcher = function( seed, context, xml, results, outermost ) {
|
||
var elem, j, matcher,
|
||
matchedCount = 0,
|
||
i = "0",
|
||
unmatched = seed && [],
|
||
setMatched = [],
|
||
contextBackup = outermostContext,
|
||
// We must always have either seed elements or outermost context
|
||
elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
|
||
// Use integer dirruns iff this is the outermost matcher
|
||
dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
|
||
len = elems.length;
|
||
|
||
if ( outermost ) {
|
||
outermostContext = context !== document && context;
|
||
}
|
||
|
||
// Add elements passing elementMatchers directly to results
|
||
// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
|
||
// Support: IE<9, Safari
|
||
// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
|
||
for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
|
||
if ( byElement && elem ) {
|
||
j = 0;
|
||
while ( (matcher = elementMatchers[j++]) ) {
|
||
if ( matcher( elem, context, xml ) ) {
|
||
results.push( elem );
|
||
break;
|
||
}
|
||
}
|
||
if ( outermost ) {
|
||
dirruns = dirrunsUnique;
|
||
}
|
||
}
|
||
|
||
// Track unmatched elements for set filters
|
||
if ( bySet ) {
|
||
// They will have gone through all possible matchers
|
||
if ( (elem = !matcher && elem) ) {
|
||
matchedCount--;
|
||
}
|
||
|
||
// Lengthen the array for every element, matched or not
|
||
if ( seed ) {
|
||
unmatched.push( elem );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Apply set filters to unmatched elements
|
||
matchedCount += i;
|
||
if ( bySet && i !== matchedCount ) {
|
||
j = 0;
|
||
while ( (matcher = setMatchers[j++]) ) {
|
||
matcher( unmatched, setMatched, context, xml );
|
||
}
|
||
|
||
if ( seed ) {
|
||
// Reintegrate element matches to eliminate the need for sorting
|
||
if ( matchedCount > 0 ) {
|
||
while ( i-- ) {
|
||
if ( !(unmatched[i] || setMatched[i]) ) {
|
||
setMatched[i] = pop.call( results );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Discard index placeholder values to get only actual matches
|
||
setMatched = condense( setMatched );
|
||
}
|
||
|
||
// Add matches to results
|
||
push.apply( results, setMatched );
|
||
|
||
// Seedless set matches succeeding multiple successful matchers stipulate sorting
|
||
if ( outermost && !seed && setMatched.length > 0 &&
|
||
( matchedCount + setMatchers.length ) > 1 ) {
|
||
|
||
Sizzle.uniqueSort( results );
|
||
}
|
||
}
|
||
|
||
// Override manipulation of globals by nested matchers
|
||
if ( outermost ) {
|
||
dirruns = dirrunsUnique;
|
||
outermostContext = contextBackup;
|
||
}
|
||
|
||
return unmatched;
|
||
};
|
||
|
||
return bySet ?
|
||
markFunction( superMatcher ) :
|
||
superMatcher;
|
||
}
|
||
|
||
compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
|
||
var i,
|
||
setMatchers = [],
|
||
elementMatchers = [],
|
||
cached = compilerCache[ selector + " " ];
|
||
|
||
if ( !cached ) {
|
||
// Generate a function of recursive functions that can be used to check each element
|
||
if ( !match ) {
|
||
match = tokenize( selector );
|
||
}
|
||
i = match.length;
|
||
while ( i-- ) {
|
||
cached = matcherFromTokens( match[i] );
|
||
if ( cached[ expando ] ) {
|
||
setMatchers.push( cached );
|
||
} else {
|
||
elementMatchers.push( cached );
|
||
}
|
||
}
|
||
|
||
// Cache the compiled function
|
||
cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
|
||
|
||
// Save selector and tokenization
|
||
cached.selector = selector;
|
||
}
|
||
return cached;
|
||
};
|
||
|
||
/**
|
||
* A low-level selection function that works with Sizzle's compiled
|
||
* selector functions
|
||
* @param {String|Function} selector A selector or a pre-compiled
|
||
* selector function built with Sizzle.compile
|
||
* @param {Element} context
|
||
* @param {Array} [results]
|
||
* @param {Array} [seed] A set of elements to match against
|
||
*/
|
||
select = Sizzle.select = function( selector, context, results, seed ) {
|
||
var i, tokens, token, type, find,
|
||
compiled = typeof selector === "function" && selector,
|
||
match = !seed && tokenize( (selector = compiled.selector || selector) );
|
||
|
||
results = results || [];
|
||
|
||
// Try to minimize operations if there is no seed and only one group
|
||
if ( match.length === 1 ) {
|
||
|
||
// Take a shortcut and set the context if the root selector is an ID
|
||
tokens = match[0] = match[0].slice( 0 );
|
||
if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
|
||
support.getById && context.nodeType === 9 && documentIsHTML &&
|
||
Expr.relative[ tokens[1].type ] ) {
|
||
|
||
context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
|
||
if ( !context ) {
|
||
return results;
|
||
|
||
// Precompiled matchers will still verify ancestry, so step up a level
|
||
} else if ( compiled ) {
|
||
context = context.parentNode;
|
||
}
|
||
|
||
selector = selector.slice( tokens.shift().value.length );
|
||
}
|
||
|
||
// Fetch a seed set for right-to-left matching
|
||
i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
|
||
while ( i-- ) {
|
||
token = tokens[i];
|
||
|
||
// Abort if we hit a combinator
|
||
if ( Expr.relative[ (type = token.type) ] ) {
|
||
break;
|
||
}
|
||
if ( (find = Expr.find[ type ]) ) {
|
||
// Search, expanding context for leading sibling combinators
|
||
if ( (seed = find(
|
||
token.matches[0].replace( runescape, funescape ),
|
||
rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
|
||
)) ) {
|
||
|
||
// If seed is empty or no tokens remain, we can return early
|
||
tokens.splice( i, 1 );
|
||
selector = seed.length && toSelector( tokens );
|
||
if ( !selector ) {
|
||
push.apply( results, seed );
|
||
return results;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Compile and execute a filtering function if one is not provided
|
||
// Provide `match` to avoid retokenization if we modified the selector above
|
||
( compiled || compile( selector, match ) )(
|
||
seed,
|
||
context,
|
||
!documentIsHTML,
|
||
results,
|
||
rsibling.test( selector ) && testContext( context.parentNode ) || context
|
||
);
|
||
return results;
|
||
};
|
||
|
||
// One-time assignments
|
||
|
||
// Sort stability
|
||
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
|
||
|
||
// Support: Chrome<14
|
||
// Always assume duplicates if they aren't passed to the comparison function
|
||
support.detectDuplicates = !!hasDuplicate;
|
||
|
||
// Initialize against the default document
|
||
setDocument();
|
||
|
||
// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
|
||
// Detached nodes confoundingly follow *each other*
|
||
support.sortDetached = assert(function( div1 ) {
|
||
// Should return 1, but returns 4 (following)
|
||
return div1.compareDocumentPosition( document.createElement("div") ) & 1;
|
||
});
|
||
|
||
// Support: IE<8
|
||
// Prevent attribute/property "interpolation"
|
||
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
|
||
if ( !assert(function( div ) {
|
||
div.innerHTML = "<a href='#'></a>";
|
||
return div.firstChild.getAttribute("href") === "#" ;
|
||
}) ) {
|
||
addHandle( "type|href|height|width", function( elem, name, isXML ) {
|
||
if ( !isXML ) {
|
||
return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
|
||
}
|
||
});
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Use defaultValue in place of getAttribute("value")
|
||
if ( !support.attributes || !assert(function( div ) {
|
||
div.innerHTML = "<input/>";
|
||
div.firstChild.setAttribute( "value", "" );
|
||
return div.firstChild.getAttribute( "value" ) === "";
|
||
}) ) {
|
||
addHandle( "value", function( elem, name, isXML ) {
|
||
if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
|
||
return elem.defaultValue;
|
||
}
|
||
});
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Use getAttributeNode to fetch booleans when getAttribute lies
|
||
if ( !assert(function( div ) {
|
||
return div.getAttribute("disabled") == null;
|
||
}) ) {
|
||
addHandle( booleans, function( elem, name, isXML ) {
|
||
var val;
|
||
if ( !isXML ) {
|
||
return elem[ name ] === true ? name.toLowerCase() :
|
||
(val = elem.getAttributeNode( name )) && val.specified ?
|
||
val.value :
|
||
null;
|
||
}
|
||
});
|
||
}
|
||
|
||
return Sizzle;
|
||
|
||
})( window );
|
||
|
||
|
||
|
||
jQuery.find = Sizzle;
|
||
jQuery.expr = Sizzle.selectors;
|
||
jQuery.expr[":"] = jQuery.expr.pseudos;
|
||
jQuery.unique = Sizzle.uniqueSort;
|
||
jQuery.text = Sizzle.getText;
|
||
jQuery.isXMLDoc = Sizzle.isXML;
|
||
jQuery.contains = Sizzle.contains;
|
||
|
||
|
||
|
||
var rneedsContext = jQuery.expr.match.needsContext;
|
||
|
||
var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
|
||
|
||
|
||
|
||
var risSimple = /^.[^:#\[\.,]*$/;
|
||
|
||
// Implement the identical functionality for filter and not
|
||
function winnow( elements, qualifier, not ) {
|
||
if ( jQuery.isFunction( qualifier ) ) {
|
||
return jQuery.grep( elements, function( elem, i ) {
|
||
/* jshint -W018 */
|
||
return !!qualifier.call( elem, i, elem ) !== not;
|
||
});
|
||
|
||
}
|
||
|
||
if ( qualifier.nodeType ) {
|
||
return jQuery.grep( elements, function( elem ) {
|
||
return ( elem === qualifier ) !== not;
|
||
});
|
||
|
||
}
|
||
|
||
if ( typeof qualifier === "string" ) {
|
||
if ( risSimple.test( qualifier ) ) {
|
||
return jQuery.filter( qualifier, elements, not );
|
||
}
|
||
|
||
qualifier = jQuery.filter( qualifier, elements );
|
||
}
|
||
|
||
return jQuery.grep( elements, function( elem ) {
|
||
return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
|
||
});
|
||
}
|
||
|
||
jQuery.filter = function( expr, elems, not ) {
|
||
var elem = elems[ 0 ];
|
||
|
||
if ( not ) {
|
||
expr = ":not(" + expr + ")";
|
||
}
|
||
|
||
return elems.length === 1 && elem.nodeType === 1 ?
|
||
jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
|
||
jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
|
||
return elem.nodeType === 1;
|
||
}));
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
find: function( selector ) {
|
||
var i,
|
||
ret = [],
|
||
self = this,
|
||
len = self.length;
|
||
|
||
if ( typeof selector !== "string" ) {
|
||
return this.pushStack( jQuery( selector ).filter(function() {
|
||
for ( i = 0; i < len; i++ ) {
|
||
if ( jQuery.contains( self[ i ], this ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
}) );
|
||
}
|
||
|
||
for ( i = 0; i < len; i++ ) {
|
||
jQuery.find( selector, self[ i ], ret );
|
||
}
|
||
|
||
// Needed because $( selector, context ) becomes $( context ).find( selector )
|
||
ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
|
||
ret.selector = this.selector ? this.selector + " " + selector : selector;
|
||
return ret;
|
||
},
|
||
filter: function( selector ) {
|
||
return this.pushStack( winnow(this, selector || [], false) );
|
||
},
|
||
not: function( selector ) {
|
||
return this.pushStack( winnow(this, selector || [], true) );
|
||
},
|
||
is: function( selector ) {
|
||
return !!winnow(
|
||
this,
|
||
|
||
// If this is a positional/relative selector, check membership in the returned set
|
||
// so $("p:first").is("p:last") won't return true for a doc with two "p".
|
||
typeof selector === "string" && rneedsContext.test( selector ) ?
|
||
jQuery( selector ) :
|
||
selector || [],
|
||
false
|
||
).length;
|
||
}
|
||
});
|
||
|
||
|
||
// Initialize a jQuery object
|
||
|
||
|
||
// A central reference to the root jQuery(document)
|
||
var rootjQuery,
|
||
|
||
// Use the correct document accordingly with window argument (sandbox)
|
||
document = window.document,
|
||
|
||
// A simple way to check for HTML strings
|
||
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
|
||
// Strict HTML recognition (#11290: must start with <)
|
||
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
|
||
|
||
init = jQuery.fn.init = function( selector, context ) {
|
||
var match, elem;
|
||
|
||
// HANDLE: $(""), $(null), $(undefined), $(false)
|
||
if ( !selector ) {
|
||
return this;
|
||
}
|
||
|
||
// Handle HTML strings
|
||
if ( typeof selector === "string" ) {
|
||
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 = rquickExpr.exec( selector );
|
||
}
|
||
|
||
// Match html or make sure no context is specified for #id
|
||
if ( match && (match[1] || !context) ) {
|
||
|
||
// HANDLE: $(html) -> $(array)
|
||
if ( match[1] ) {
|
||
context = context instanceof jQuery ? context[0] : context;
|
||
|
||
// scripts is true for back-compat
|
||
// Intentionally let the error be thrown if parseHTML is not present
|
||
jQuery.merge( this, jQuery.parseHTML(
|
||
match[1],
|
||
context && context.nodeType ? context.ownerDocument || context : document,
|
||
true
|
||
) );
|
||
|
||
// HANDLE: $(html, props)
|
||
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
|
||
for ( match in context ) {
|
||
// Properties of context are called as methods if possible
|
||
if ( jQuery.isFunction( this[ match ] ) ) {
|
||
this[ match ]( context[ match ] );
|
||
|
||
// ...and otherwise set as attributes
|
||
} else {
|
||
this.attr( match, context[ match ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
|
||
// 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: $(DOMElement)
|
||
} else if ( selector.nodeType ) {
|
||
this.context = this[0] = selector;
|
||
this.length = 1;
|
||
return this;
|
||
|
||
// HANDLE: $(function)
|
||
// Shortcut for document ready
|
||
} else if ( jQuery.isFunction( selector ) ) {
|
||
return typeof rootjQuery.ready !== "undefined" ?
|
||
rootjQuery.ready( selector ) :
|
||
// Execute immediately if ready is not present
|
||
selector( jQuery );
|
||
}
|
||
|
||
if ( selector.selector !== undefined ) {
|
||
this.selector = selector.selector;
|
||
this.context = selector.context;
|
||
}
|
||
|
||
return jQuery.makeArray( selector, this );
|
||
};
|
||
|
||
// Give the init function the jQuery prototype for later instantiation
|
||
init.prototype = jQuery.fn;
|
||
|
||
// Initialize central reference
|
||
rootjQuery = jQuery( document );
|
||
|
||
|
||
var rparentsprev = /^(?:parents|prev(?:Until|All))/,
|
||
// methods guaranteed to produce a unique set when starting from a unique set
|
||
guaranteedUnique = {
|
||
children: true,
|
||
contents: true,
|
||
next: true,
|
||
prev: true
|
||
};
|
||
|
||
jQuery.extend({
|
||
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;
|
||
},
|
||
|
||
sibling: function( n, elem ) {
|
||
var r = [];
|
||
|
||
for ( ; n; n = n.nextSibling ) {
|
||
if ( n.nodeType === 1 && n !== elem ) {
|
||
r.push( n );
|
||
}
|
||
}
|
||
|
||
return r;
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
has: function( target ) {
|
||
var i,
|
||
targets = jQuery( target, this ),
|
||
len = targets.length;
|
||
|
||
return this.filter(function() {
|
||
for ( i = 0; i < len; i++ ) {
|
||
if ( jQuery.contains( this, targets[i] ) ) {
|
||
return true;
|
||
}
|
||
}
|
||
});
|
||
},
|
||
|
||
closest: function( selectors, context ) {
|
||
var cur,
|
||
i = 0,
|
||
l = this.length,
|
||
matched = [],
|
||
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
|
||
jQuery( selectors, context || this.context ) :
|
||
0;
|
||
|
||
for ( ; i < l; i++ ) {
|
||
for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
|
||
// Always skip document fragments
|
||
if ( cur.nodeType < 11 && (pos ?
|
||
pos.index(cur) > -1 :
|
||
|
||
// Don't pass non-elements to Sizzle
|
||
cur.nodeType === 1 &&
|
||
jQuery.find.matchesSelector(cur, selectors)) ) {
|
||
|
||
matched.push( cur );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
|
||
},
|
||
|
||
// Determine the position of an element within
|
||
// the matched set of elements
|
||
index: function( elem ) {
|
||
|
||
// No argument, return index in parent
|
||
if ( !elem ) {
|
||
return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
|
||
}
|
||
|
||
// index in selector
|
||
if ( typeof elem === "string" ) {
|
||
return jQuery.inArray( this[0], jQuery( elem ) );
|
||
}
|
||
|
||
// 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 ) {
|
||
return this.pushStack(
|
||
jQuery.unique(
|
||
jQuery.merge( this.get(), jQuery( selector, context ) )
|
||
)
|
||
);
|
||
},
|
||
|
||
addBack: function( selector ) {
|
||
return this.add( selector == null ?
|
||
this.prevObject : this.prevObject.filter(selector)
|
||
);
|
||
}
|
||
});
|
||
|
||
function sibling( cur, dir ) {
|
||
do {
|
||
cur = cur[ dir ];
|
||
} while ( cur && cur.nodeType !== 1 );
|
||
|
||
return cur;
|
||
}
|
||
|
||
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 sibling( elem, "nextSibling" );
|
||
},
|
||
prev: function( elem ) {
|
||
return sibling( elem, "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.merge( [], elem.childNodes );
|
||
}
|
||
}, function( name, fn ) {
|
||
jQuery.fn[ name ] = function( until, selector ) {
|
||
var ret = jQuery.map( this, fn, until );
|
||
|
||
if ( name.slice( -5 ) !== "Until" ) {
|
||
selector = until;
|
||
}
|
||
|
||
if ( selector && typeof selector === "string" ) {
|
||
ret = jQuery.filter( selector, ret );
|
||
}
|
||
|
||
if ( this.length > 1 ) {
|
||
// Remove duplicates
|
||
if ( !guaranteedUnique[ name ] ) {
|
||
ret = jQuery.unique( ret );
|
||
}
|
||
|
||
// Reverse order for parents* and prev-derivatives
|
||
if ( rparentsprev.test( name ) ) {
|
||
ret = ret.reverse();
|
||
}
|
||
}
|
||
|
||
return this.pushStack( ret );
|
||
};
|
||
});
|
||
var rnotwhite = (/\S+/g);
|
||
|
||
|
||
|
||
// String to Object options format cache
|
||
var optionsCache = {};
|
||
|
||
// Convert String-formatted options into Object-formatted ones and store in cache
|
||
function createOptions( options ) {
|
||
var object = optionsCache[ options ] = {};
|
||
jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
|
||
object[ flag ] = true;
|
||
});
|
||
return object;
|
||
}
|
||
|
||
/*
|
||
* Create a callback list using the following parameters:
|
||
*
|
||
* options: an optional list of space-separated options that will change how
|
||
* the callback list behaves or a more traditional option object
|
||
*
|
||
* By default a callback list will act like an event callback list and can be
|
||
* "fired" multiple times.
|
||
*
|
||
* Possible options:
|
||
*
|
||
* once: will ensure the callback list can only be fired once (like a Deferred)
|
||
*
|
||
* memory: will keep track of previous values and will call any callback added
|
||
* after the list has been fired right away with the latest "memorized"
|
||
* values (like a Deferred)
|
||
*
|
||
* unique: will ensure a callback can only be added once (no duplicate in the list)
|
||
*
|
||
* stopOnFalse: interrupt callings when a callback returns false
|
||
*
|
||
*/
|
||
jQuery.Callbacks = function( options ) {
|
||
|
||
// Convert options from String-formatted to Object-formatted if needed
|
||
// (we check in cache first)
|
||
options = typeof options === "string" ?
|
||
( optionsCache[ options ] || createOptions( options ) ) :
|
||
jQuery.extend( {}, options );
|
||
|
||
var // Flag to know if list is currently firing
|
||
firing,
|
||
// Last fire value (for non-forgettable lists)
|
||
memory,
|
||
// Flag to know if list was already fired
|
||
fired,
|
||
// End of the loop when firing
|
||
firingLength,
|
||
// Index of currently firing callback (modified by remove if needed)
|
||
firingIndex,
|
||
// First callback to fire (used internally by add and fireWith)
|
||
firingStart,
|
||
// Actual callback list
|
||
list = [],
|
||
// Stack of fire calls for repeatable lists
|
||
stack = !options.once && [],
|
||
// Fire callbacks
|
||
fire = function( data ) {
|
||
memory = options.memory && data;
|
||
fired = true;
|
||
firingIndex = firingStart || 0;
|
||
firingStart = 0;
|
||
firingLength = list.length;
|
||
firing = true;
|
||
for ( ; list && firingIndex < firingLength; firingIndex++ ) {
|
||
if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
|
||
memory = false; // To prevent further calls using add
|
||
break;
|
||
}
|
||
}
|
||
firing = false;
|
||
if ( list ) {
|
||
if ( stack ) {
|
||
if ( stack.length ) {
|
||
fire( stack.shift() );
|
||
}
|
||
} else if ( memory ) {
|
||
list = [];
|
||
} else {
|
||
self.disable();
|
||
}
|
||
}
|
||
},
|
||
// Actual Callbacks object
|
||
self = {
|
||
// Add a callback or a collection of callbacks to the list
|
||
add: function() {
|
||
if ( list ) {
|
||
// First, we save the current length
|
||
var start = list.length;
|
||
(function add( args ) {
|
||
jQuery.each( args, function( _, arg ) {
|
||
var type = jQuery.type( arg );
|
||
if ( type === "function" ) {
|
||
if ( !options.unique || !self.has( arg ) ) {
|
||
list.push( arg );
|
||
}
|
||
} else if ( arg && arg.length && type !== "string" ) {
|
||
// Inspect recursively
|
||
add( arg );
|
||
}
|
||
});
|
||
})( arguments );
|
||
// Do we need to add the callbacks to the
|
||
// current firing batch?
|
||
if ( firing ) {
|
||
firingLength = list.length;
|
||
// With memory, if we're not firing then
|
||
// we should call right away
|
||
} else if ( memory ) {
|
||
firingStart = start;
|
||
fire( memory );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
// Remove a callback from the list
|
||
remove: function() {
|
||
if ( list ) {
|
||
jQuery.each( arguments, function( _, arg ) {
|
||
var index;
|
||
while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
|
||
list.splice( index, 1 );
|
||
// Handle firing indexes
|
||
if ( firing ) {
|
||
if ( index <= firingLength ) {
|
||
firingLength--;
|
||
}
|
||
if ( index <= firingIndex ) {
|
||
firingIndex--;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
return this;
|
||
},
|
||
// Check if a given callback is in the list.
|
||
// If no argument is given, return whether or not list has callbacks attached.
|
||
has: function( fn ) {
|
||
return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
|
||
},
|
||
// Remove all callbacks from the list
|
||
empty: function() {
|
||
list = [];
|
||
firingLength = 0;
|
||
return this;
|
||
},
|
||
// Have the list do nothing anymore
|
||
disable: function() {
|
||
list = stack = memory = undefined;
|
||
return this;
|
||
},
|
||
// Is it disabled?
|
||
disabled: function() {
|
||
return !list;
|
||
},
|
||
// Lock the list in its current state
|
||
lock: function() {
|
||
stack = undefined;
|
||
if ( !memory ) {
|
||
self.disable();
|
||
}
|
||
return this;
|
||
},
|
||
// Is it locked?
|
||
locked: function() {
|
||
return !stack;
|
||
},
|
||
// Call all callbacks with the given context and arguments
|
||
fireWith: function( context, args ) {
|
||
if ( list && ( !fired || stack ) ) {
|
||
args = args || [];
|
||
args = [ context, args.slice ? args.slice() : args ];
|
||
if ( firing ) {
|
||
stack.push( args );
|
||
} else {
|
||
fire( args );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
// Call all the callbacks with the given arguments
|
||
fire: function() {
|
||
self.fireWith( this, arguments );
|
||
return this;
|
||
},
|
||
// To know if the callbacks have already been called at least once
|
||
fired: function() {
|
||
return !!fired;
|
||
}
|
||
};
|
||
|
||
return self;
|
||
};
|
||
|
||
|
||
jQuery.extend({
|
||
|
||
Deferred: function( func ) {
|
||
var tuples = [
|
||
// action, add listener, listener list, final state
|
||
[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
|
||
[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
|
||
[ "notify", "progress", jQuery.Callbacks("memory") ]
|
||
],
|
||
state = "pending",
|
||
promise = {
|
||
state: function() {
|
||
return state;
|
||
},
|
||
always: function() {
|
||
deferred.done( arguments ).fail( arguments );
|
||
return this;
|
||
},
|
||
then: function( /* fnDone, fnFail, fnProgress */ ) {
|
||
var fns = arguments;
|
||
return jQuery.Deferred(function( newDefer ) {
|
||
jQuery.each( tuples, function( i, tuple ) {
|
||
var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
|
||
// deferred[ done | fail | progress ] for forwarding actions to newDefer
|
||
deferred[ tuple[1] ](function() {
|
||
var returned = fn && fn.apply( this, arguments );
|
||
if ( returned && jQuery.isFunction( returned.promise ) ) {
|
||
returned.promise()
|
||
.done( newDefer.resolve )
|
||
.fail( newDefer.reject )
|
||
.progress( newDefer.notify );
|
||
} else {
|
||
newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
|
||
}
|
||
});
|
||
});
|
||
fns = null;
|
||
}).promise();
|
||
},
|
||
// Get a promise for this deferred
|
||
// If obj is provided, the promise aspect is added to the object
|
||
promise: function( obj ) {
|
||
return obj != null ? jQuery.extend( obj, promise ) : promise;
|
||
}
|
||
},
|
||
deferred = {};
|
||
|
||
// Keep pipe for back-compat
|
||
promise.pipe = promise.then;
|
||
|
||
// Add list-specific methods
|
||
jQuery.each( tuples, function( i, tuple ) {
|
||
var list = tuple[ 2 ],
|
||
stateString = tuple[ 3 ];
|
||
|
||
// promise[ done | fail | progress ] = list.add
|
||
promise[ tuple[1] ] = list.add;
|
||
|
||
// Handle state
|
||
if ( stateString ) {
|
||
list.add(function() {
|
||
// state = [ resolved | rejected ]
|
||
state = stateString;
|
||
|
||
// [ reject_list | resolve_list ].disable; progress_list.lock
|
||
}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
|
||
}
|
||
|
||
// deferred[ resolve | reject | notify ]
|
||
deferred[ tuple[0] ] = function() {
|
||
deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
|
||
return this;
|
||
};
|
||
deferred[ tuple[0] + "With" ] = list.fireWith;
|
||
});
|
||
|
||
// Make the deferred a promise
|
||
promise.promise( deferred );
|
||
|
||
// Call given func if any
|
||
if ( func ) {
|
||
func.call( deferred, deferred );
|
||
}
|
||
|
||
// All done!
|
||
return deferred;
|
||
},
|
||
|
||
// Deferred helper
|
||
when: function( subordinate /* , ..., subordinateN */ ) {
|
||
var i = 0,
|
||
resolveValues = slice.call( arguments ),
|
||
length = resolveValues.length,
|
||
|
||
// the count of uncompleted subordinates
|
||
remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
|
||
|
||
// the master Deferred. If resolveValues consist of only a single Deferred, just use that.
|
||
deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
|
||
|
||
// Update function for both resolve and progress values
|
||
updateFunc = function( i, contexts, values ) {
|
||
return function( value ) {
|
||
contexts[ i ] = this;
|
||
values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
|
||
if ( values === progressValues ) {
|
||
deferred.notifyWith( contexts, values );
|
||
|
||
} else if ( !(--remaining) ) {
|
||
deferred.resolveWith( contexts, values );
|
||
}
|
||
};
|
||
},
|
||
|
||
progressValues, progressContexts, resolveContexts;
|
||
|
||
// add listeners to Deferred subordinates; treat others as resolved
|
||
if ( length > 1 ) {
|
||
progressValues = new Array( length );
|
||
progressContexts = new Array( length );
|
||
resolveContexts = new Array( length );
|
||
for ( ; i < length; i++ ) {
|
||
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
|
||
resolveValues[ i ].promise()
|
||
.done( updateFunc( i, resolveContexts, resolveValues ) )
|
||
.fail( deferred.reject )
|
||
.progress( updateFunc( i, progressContexts, progressValues ) );
|
||
} else {
|
||
--remaining;
|
||
}
|
||
}
|
||
}
|
||
|
||
// if we're not waiting on anything, resolve the master
|
||
if ( !remaining ) {
|
||
deferred.resolveWith( resolveContexts, resolveValues );
|
||
}
|
||
|
||
return deferred.promise();
|
||
}
|
||
});
|
||
|
||
|
||
// The deferred used on DOM ready
|
||
var readyList;
|
||
|
||
jQuery.fn.ready = function( fn ) {
|
||
// Add the callback
|
||
jQuery.ready.promise().done( fn );
|
||
|
||
return this;
|
||
};
|
||
|
||
jQuery.extend({
|
||
// 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 ) {
|
||
|
||
// Abort if there are pending holds or we're already ready
|
||
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
|
||
return;
|
||
}
|
||
|
||
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
|
||
if ( !document.body ) {
|
||
return setTimeout( jQuery.ready );
|
||
}
|
||
|
||
// 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.triggerHandler ) {
|
||
jQuery( document ).triggerHandler( "ready" );
|
||
jQuery( document ).off( "ready" );
|
||
}
|
||
}
|
||
});
|
||
|
||
/**
|
||
* Clean-up method for dom ready events
|
||
*/
|
||
function detach() {
|
||
if ( document.addEventListener ) {
|
||
document.removeEventListener( "DOMContentLoaded", completed, false );
|
||
window.removeEventListener( "load", completed, false );
|
||
|
||
} else {
|
||
document.detachEvent( "onreadystatechange", completed );
|
||
window.detachEvent( "onload", completed );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* The ready event handler and self cleanup method
|
||
*/
|
||
function completed() {
|
||
// readyState === "complete" is good enough for us to call the dom ready in oldIE
|
||
if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
|
||
detach();
|
||
jQuery.ready();
|
||
}
|
||
}
|
||
|
||
jQuery.ready.promise = function( obj ) {
|
||
if ( !readyList ) {
|
||
|
||
readyList = jQuery.Deferred();
|
||
|
||
// Catch cases where $(document).ready() is called after the browser event has already occurred.
|
||
// we once tried to use readyState "interactive" here, but it caused issues like the one
|
||
// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
|
||
if ( document.readyState === "complete" ) {
|
||
// Handle it asynchronously to allow scripts the opportunity to delay ready
|
||
setTimeout( jQuery.ready );
|
||
|
||
// Standards-based browsers support DOMContentLoaded
|
||
} else if ( document.addEventListener ) {
|
||
// Use the handy event callback
|
||
document.addEventListener( "DOMContentLoaded", completed, false );
|
||
|
||
// A fallback to window.onload, that will always work
|
||
window.addEventListener( "load", completed, false );
|
||
|
||
// If IE event model is used
|
||
} else {
|
||
// Ensure firing before onload, maybe late but safe also for iframes
|
||
document.attachEvent( "onreadystatechange", completed );
|
||
|
||
// A fallback to window.onload, that will always work
|
||
window.attachEvent( "onload", completed );
|
||
|
||
// If IE and not a frame
|
||
// continually check to see if the document is ready
|
||
var top = false;
|
||
|
||
try {
|
||
top = window.frameElement == null && document.documentElement;
|
||
} catch(e) {}
|
||
|
||
if ( top && top.doScroll ) {
|
||
(function doScrollCheck() {
|
||
if ( !jQuery.isReady ) {
|
||
|
||
try {
|
||
// Use the trick by Diego Perini
|
||
// http://javascript.nwbox.com/IEContentLoaded/
|
||
top.doScroll("left");
|
||
} catch(e) {
|
||
return setTimeout( doScrollCheck, 50 );
|
||
}
|
||
|
||
// detach all dom ready events
|
||
detach();
|
||
|
||
// and execute any waiting functions
|
||
jQuery.ready();
|
||
}
|
||
})();
|
||
}
|
||
}
|
||
}
|
||
return readyList.promise( obj );
|
||
};
|
||
|
||
|
||
var strundefined = typeof undefined;
|
||
|
||
|
||
|
||
// Support: IE<9
|
||
// Iteration over object's inherited properties before its own
|
||
var i;
|
||
for ( i in jQuery( support ) ) {
|
||
break;
|
||
}
|
||
support.ownLast = i !== "0";
|
||
|
||
// Note: most support tests are defined in their respective modules.
|
||
// false until the test is run
|
||
support.inlineBlockNeedsLayout = false;
|
||
|
||
// Execute ASAP in case we need to set body.style.zoom
|
||
jQuery(function() {
|
||
// Minified: var a,b,c,d
|
||
var val, div, body, container;
|
||
|
||
body = document.getElementsByTagName( "body" )[ 0 ];
|
||
if ( !body || !body.style ) {
|
||
// Return for frameset docs that don't have a body
|
||
return;
|
||
}
|
||
|
||
// Setup
|
||
div = document.createElement( "div" );
|
||
container = document.createElement( "div" );
|
||
container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
|
||
body.appendChild( container ).appendChild( div );
|
||
|
||
if ( typeof div.style.zoom !== strundefined ) {
|
||
// Support: IE<8
|
||
// Check if natively block-level elements act like inline-block
|
||
// elements when setting their display to 'inline' and giving
|
||
// them layout
|
||
div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
|
||
|
||
support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
|
||
if ( val ) {
|
||
// Prevent IE 6 from affecting layout for positioned elements #11048
|
||
// Prevent IE from shrinking the body in IE 7 mode #12869
|
||
// Support: IE<8
|
||
body.style.zoom = 1;
|
||
}
|
||
}
|
||
|
||
body.removeChild( container );
|
||
});
|
||
|
||
|
||
|
||
|
||
(function() {
|
||
var div = document.createElement( "div" );
|
||
|
||
// Execute the test only if not already executed in another module.
|
||
if (support.deleteExpando == null) {
|
||
// Support: IE<9
|
||
support.deleteExpando = true;
|
||
try {
|
||
delete div.test;
|
||
} catch( e ) {
|
||
support.deleteExpando = false;
|
||
}
|
||
}
|
||
|
||
// Null elements to avoid leaks in IE.
|
||
div = null;
|
||
})();
|
||
|
||
|
||
/**
|
||
* Determines whether an object can have data
|
||
*/
|
||
jQuery.acceptData = function( elem ) {
|
||
var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ],
|
||
nodeType = +elem.nodeType || 1;
|
||
|
||
// Do not set data on non-element DOM nodes because it will not be cleared (#8335).
|
||
return nodeType !== 1 && nodeType !== 9 ?
|
||
false :
|
||
|
||
// Nodes accept data unless otherwise specified; rejection can be conditional
|
||
!noData || noData !== true && elem.getAttribute("classid") === noData;
|
||
};
|
||
|
||
|
||
var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
|
||
rmultiDash = /([A-Z])/g;
|
||
|
||
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" ).toLowerCase();
|
||
|
||
data = elem.getAttribute( name );
|
||
|
||
if ( typeof data === "string" ) {
|
||
try {
|
||
data = data === "true" ? true :
|
||
data === "false" ? false :
|
||
data === "null" ? null :
|
||
// Only convert to a number if it doesn't change the string
|
||
+data + "" === data ? +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;
|
||
}
|
||
|
||
// checks a cache object for emptiness
|
||
function isEmptyDataObject( obj ) {
|
||
var name;
|
||
for ( name in obj ) {
|
||
|
||
// if the public data object is empty, the private is still empty
|
||
if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
|
||
continue;
|
||
}
|
||
if ( name !== "toJSON" ) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
|
||
if ( !jQuery.acceptData( elem ) ) {
|
||
return;
|
||
}
|
||
|
||
var ret, thisCache,
|
||
internalKey = jQuery.expando,
|
||
|
||
// 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[ internalKey ] : elem[ internalKey ] && internalKey;
|
||
|
||
// 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 || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
|
||
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 ) {
|
||
id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
|
||
} else {
|
||
id = internalKey;
|
||
}
|
||
}
|
||
|
||
if ( !cache[ id ] ) {
|
||
// Avoid exposing jQuery metadata on plain JS objects when the object
|
||
// is serialized using JSON.stringify
|
||
cache[ id ] = isNode ? {} : { 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 ] = jQuery.extend( cache[ id ], name );
|
||
} else {
|
||
cache[ id ].data = jQuery.extend( cache[ id ].data, name );
|
||
}
|
||
}
|
||
|
||
thisCache = cache[ id ];
|
||
|
||
// jQuery data() is stored in a separate object inside the object's internal data
|
||
// cache in order to avoid key collisions between internal data and user-defined
|
||
// data.
|
||
if ( !pvt ) {
|
||
if ( !thisCache.data ) {
|
||
thisCache.data = {};
|
||
}
|
||
|
||
thisCache = thisCache.data;
|
||
}
|
||
|
||
if ( data !== undefined ) {
|
||
thisCache[ jQuery.camelCase( name ) ] = data;
|
||
}
|
||
|
||
// Check for both converted-to-camel and non-converted data property names
|
||
// If a data property was specified
|
||
if ( typeof name === "string" ) {
|
||
|
||
// First Try to find as-is property data
|
||
ret = thisCache[ name ];
|
||
|
||
// Test for null|undefined property data
|
||
if ( ret == null ) {
|
||
|
||
// Try to find the camelCased property
|
||
ret = thisCache[ jQuery.camelCase( name ) ];
|
||
}
|
||
} else {
|
||
ret = thisCache;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
function internalRemoveData( elem, name, pvt ) {
|
||
if ( !jQuery.acceptData( elem ) ) {
|
||
return;
|
||
}
|
||
|
||
var thisCache, i,
|
||
isNode = elem.nodeType,
|
||
|
||
// See jQuery.data for more information
|
||
cache = isNode ? jQuery.cache : elem,
|
||
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 ) {
|
||
|
||
thisCache = pvt ? cache[ id ] : cache[ id ].data;
|
||
|
||
if ( thisCache ) {
|
||
|
||
// Support array or space separated string names for data keys
|
||
if ( !jQuery.isArray( name ) ) {
|
||
|
||
// try the string as a key before any manipulation
|
||
if ( name in thisCache ) {
|
||
name = [ name ];
|
||
} else {
|
||
|
||
// split the camel cased version by spaces unless a key with the spaces exists
|
||
name = jQuery.camelCase( name );
|
||
if ( name in thisCache ) {
|
||
name = [ name ];
|
||
} else {
|
||
name = name.split(" ");
|
||
}
|
||
}
|
||
} else {
|
||
// If "name" is an array of keys...
|
||
// When data is initially created, via ("key", "val") signature,
|
||
// keys will be converted to camelCase.
|
||
// Since there is no way to tell _how_ a key was added, remove
|
||
// both plain key and camelCase key. #12786
|
||
// This will only penalize the array argument path.
|
||
name = name.concat( jQuery.map( name, jQuery.camelCase ) );
|
||
}
|
||
|
||
i = name.length;
|
||
while ( i-- ) {
|
||
delete thisCache[ name[i] ];
|
||
}
|
||
|
||
// If there is no data left in the cache, we want to continue
|
||
// and let the cache object itself get destroyed
|
||
if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
// See jQuery.data for more information
|
||
if ( !pvt ) {
|
||
delete cache[ id ].data;
|
||
|
||
// Don't destroy the parent cache unless the internal data object
|
||
// had been the only thing left in it
|
||
if ( !isEmptyDataObject( cache[ id ] ) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Destroy the cache
|
||
if ( isNode ) {
|
||
jQuery.cleanData( [ elem ], true );
|
||
|
||
// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
|
||
/* jshint eqeqeq: false */
|
||
} else if ( support.deleteExpando || cache != cache.window ) {
|
||
/* jshint eqeqeq: true */
|
||
delete cache[ id ];
|
||
|
||
// When all else fails, null
|
||
} else {
|
||
cache[ id ] = null;
|
||
}
|
||
}
|
||
|
||
jQuery.extend({
|
||
cache: {},
|
||
|
||
// The following elements (space-suffixed to avoid Object.prototype collisions)
|
||
// throw uncatchable exceptions if you attempt to set expando properties
|
||
noData: {
|
||
"applet ": true,
|
||
"embed ": true,
|
||
// ...but Flash objects (which have this classid) *can* handle expandos
|
||
"object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
|
||
},
|
||
|
||
hasData: function( elem ) {
|
||
elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
|
||
return !!elem && !isEmptyDataObject( elem );
|
||
},
|
||
|
||
data: function( elem, name, data ) {
|
||
return internalData( elem, name, data );
|
||
},
|
||
|
||
removeData: function( elem, name ) {
|
||
return internalRemoveData( elem, name );
|
||
},
|
||
|
||
// For internal use only.
|
||
_data: function( elem, name, data ) {
|
||
return internalData( elem, name, data, true );
|
||
},
|
||
|
||
_removeData: function( elem, name ) {
|
||
return internalRemoveData( elem, name, true );
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
data: function( key, value ) {
|
||
var i, name, data,
|
||
elem = this[0],
|
||
attrs = elem && elem.attributes;
|
||
|
||
// Special expections of .data basically thwart jQuery.access,
|
||
// so implement the relevant behavior ourselves
|
||
|
||
// Gets all values
|
||
if ( key === undefined ) {
|
||
if ( this.length ) {
|
||
data = jQuery.data( elem );
|
||
|
||
if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
|
||
i = attrs.length;
|
||
while ( i-- ) {
|
||
|
||
// Support: IE11+
|
||
// The attrs elements can be null (#14894)
|
||
if ( attrs[ i ] ) {
|
||
name = attrs[ i ].name;
|
||
if ( name.indexOf( "data-" ) === 0 ) {
|
||
name = jQuery.camelCase( name.slice(5) );
|
||
dataAttr( elem, name, data[ name ] );
|
||
}
|
||
}
|
||
}
|
||
jQuery._data( elem, "parsedAttrs", true );
|
||
}
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
// Sets multiple values
|
||
if ( typeof key === "object" ) {
|
||
return this.each(function() {
|
||
jQuery.data( this, key );
|
||
});
|
||
}
|
||
|
||
return arguments.length > 1 ?
|
||
|
||
// Sets one value
|
||
this.each(function() {
|
||
jQuery.data( this, key, value );
|
||
}) :
|
||
|
||
// Gets one value
|
||
// Try to fetch any internally stored data first
|
||
elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
|
||
},
|
||
|
||
removeData: function( key ) {
|
||
return this.each(function() {
|
||
jQuery.removeData( this, key );
|
||
});
|
||
}
|
||
});
|
||
|
||
|
||
jQuery.extend({
|
||
queue: function( elem, type, data ) {
|
||
var queue;
|
||
|
||
if ( elem ) {
|
||
type = ( type || "fx" ) + "queue";
|
||
queue = jQuery._data( elem, type );
|
||
|
||
// Speed up dequeue by getting out quickly if this is just a lookup
|
||
if ( data ) {
|
||
if ( !queue || jQuery.isArray(data) ) {
|
||
queue = jQuery._data( elem, type, jQuery.makeArray(data) );
|
||
} else {
|
||
queue.push( data );
|
||
}
|
||
}
|
||
return queue || [];
|
||
}
|
||
},
|
||
|
||
dequeue: function( elem, type ) {
|
||
type = type || "fx";
|
||
|
||
var queue = jQuery.queue( elem, type ),
|
||
startLength = queue.length,
|
||
fn = queue.shift(),
|
||
hooks = jQuery._queueHooks( elem, type ),
|
||
next = function() {
|
||
jQuery.dequeue( elem, type );
|
||
};
|
||
|
||
// If the fx queue is dequeued, always remove the progress sentinel
|
||
if ( fn === "inprogress" ) {
|
||
fn = queue.shift();
|
||
startLength--;
|
||
}
|
||
|
||
if ( fn ) {
|
||
|
||
// Add a progress sentinel to prevent the fx queue from being
|
||
// automatically dequeued
|
||
if ( type === "fx" ) {
|
||
queue.unshift( "inprogress" );
|
||
}
|
||
|
||
// clear up the last queue stop function
|
||
delete hooks.stop;
|
||
fn.call( elem, next, hooks );
|
||
}
|
||
|
||
if ( !startLength && hooks ) {
|
||
hooks.empty.fire();
|
||
}
|
||
},
|
||
|
||
// not intended for public consumption - generates a queueHooks object, or returns the current one
|
||
_queueHooks: function( elem, type ) {
|
||
var key = type + "queueHooks";
|
||
return jQuery._data( elem, key ) || jQuery._data( elem, key, {
|
||
empty: jQuery.Callbacks("once memory").add(function() {
|
||
jQuery._removeData( elem, type + "queue" );
|
||
jQuery._removeData( elem, key );
|
||
})
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
queue: function( type, data ) {
|
||
var setter = 2;
|
||
|
||
if ( typeof type !== "string" ) {
|
||
data = type;
|
||
type = "fx";
|
||
setter--;
|
||
}
|
||
|
||
if ( arguments.length < setter ) {
|
||
return jQuery.queue( this[0], type );
|
||
}
|
||
|
||
return data === undefined ?
|
||
this :
|
||
this.each(function() {
|
||
var queue = jQuery.queue( this, type, data );
|
||
|
||
// ensure a hooks for this queue
|
||
jQuery._queueHooks( this, type );
|
||
|
||
if ( type === "fx" && queue[0] !== "inprogress" ) {
|
||
jQuery.dequeue( this, type );
|
||
}
|
||
});
|
||
},
|
||
dequeue: function( type ) {
|
||
return this.each(function() {
|
||
jQuery.dequeue( this, type );
|
||
});
|
||
},
|
||
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, obj ) {
|
||
var tmp,
|
||
count = 1,
|
||
defer = jQuery.Deferred(),
|
||
elements = this,
|
||
i = this.length,
|
||
resolve = function() {
|
||
if ( !( --count ) ) {
|
||
defer.resolveWith( elements, [ elements ] );
|
||
}
|
||
};
|
||
|
||
if ( typeof type !== "string" ) {
|
||
obj = type;
|
||
type = undefined;
|
||
}
|
||
type = type || "fx";
|
||
|
||
while ( i-- ) {
|
||
tmp = jQuery._data( elements[ i ], type + "queueHooks" );
|
||
if ( tmp && tmp.empty ) {
|
||
count++;
|
||
tmp.empty.add( resolve );
|
||
}
|
||
}
|
||
resolve();
|
||
return defer.promise( obj );
|
||
}
|
||
});
|
||
var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
|
||
|
||
var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
|
||
|
||
var isHidden = function( elem, el ) {
|
||
// isHidden might be called from jQuery#filter function;
|
||
// in that case, element will be second argument
|
||
elem = el || elem;
|
||
return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
|
||
};
|
||
|
||
|
||
|
||
// Multifunctional method to get and set values of a collection
|
||
// The value/s can optionally be executed if it's a function
|
||
var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
|
||
var i = 0,
|
||
length = elems.length,
|
||
bulk = key == null;
|
||
|
||
// Sets many values
|
||
if ( jQuery.type( key ) === "object" ) {
|
||
chainable = true;
|
||
for ( i in key ) {
|
||
jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
|
||
}
|
||
|
||
// Sets one value
|
||
} else if ( value !== undefined ) {
|
||
chainable = true;
|
||
|
||
if ( !jQuery.isFunction( value ) ) {
|
||
raw = true;
|
||
}
|
||
|
||
if ( bulk ) {
|
||
// Bulk operations run against the entire set
|
||
if ( raw ) {
|
||
fn.call( elems, value );
|
||
fn = null;
|
||
|
||
// ...except when executing function values
|
||
} else {
|
||
bulk = fn;
|
||
fn = function( elem, key, value ) {
|
||
return bulk.call( jQuery( elem ), value );
|
||
};
|
||
}
|
||
}
|
||
|
||
if ( fn ) {
|
||
for ( ; i < length; i++ ) {
|
||
fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
return chainable ?
|
||
elems :
|
||
|
||
// Gets
|
||
bulk ?
|
||
fn.call( elems ) :
|
||
length ? fn( elems[0], key ) : emptyGet;
|
||
};
|
||
var rcheckableType = (/^(?:checkbox|radio)$/i);
|
||
|
||
|
||
|
||
(function() {
|
||
// Minified: var a,b,c
|
||
var input = document.createElement( "input" ),
|
||
div = document.createElement( "div" ),
|
||
fragment = document.createDocumentFragment();
|
||
|
||
// Setup
|
||
div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
|
||
|
||
// IE strips leading whitespace when .innerHTML is used
|
||
support.leadingWhitespace = div.firstChild.nodeType === 3;
|
||
|
||
// Make sure that tbody elements aren't automatically inserted
|
||
// IE will insert them into empty tables
|
||
support.tbody = !div.getElementsByTagName( "tbody" ).length;
|
||
|
||
// Make sure that link elements get serialized correctly by innerHTML
|
||
// This requires a wrapper element in IE
|
||
support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
|
||
|
||
// Makes sure cloning an html5 element does not cause problems
|
||
// Where outerHTML is undefined, this still works
|
||
support.html5Clone =
|
||
document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
|
||
|
||
// Check if a disconnected checkbox will retain its checked
|
||
// value of true after appended to the DOM (IE6/7)
|
||
input.type = "checkbox";
|
||
input.checked = true;
|
||
fragment.appendChild( input );
|
||
support.appendChecked = input.checked;
|
||
|
||
// Make sure textarea (and checkbox) defaultValue is properly cloned
|
||
// Support: IE6-IE11+
|
||
div.innerHTML = "<textarea>x</textarea>";
|
||
support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
|
||
|
||
// #11217 - WebKit loses check when the name is after the checked attribute
|
||
fragment.appendChild( div );
|
||
div.innerHTML = "<input type='radio' checked='checked' name='t'/>";
|
||
|
||
// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
|
||
// old WebKit doesn't clone checked state correctly in fragments
|
||
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
|
||
|
||
// Support: IE<9
|
||
// Opera does not clone events (and typeof div.attachEvent === undefined).
|
||
// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
|
||
support.noCloneEvent = true;
|
||
if ( div.attachEvent ) {
|
||
div.attachEvent( "onclick", function() {
|
||
support.noCloneEvent = false;
|
||
});
|
||
|
||
div.cloneNode( true ).click();
|
||
}
|
||
|
||
// Execute the test only if not already executed in another module.
|
||
if (support.deleteExpando == null) {
|
||
// Support: IE<9
|
||
support.deleteExpando = true;
|
||
try {
|
||
delete div.test;
|
||
} catch( e ) {
|
||
support.deleteExpando = false;
|
||
}
|
||
}
|
||
})();
|
||
|
||
|
||
(function() {
|
||
var i, eventName,
|
||
div = document.createElement( "div" );
|
||
|
||
// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)
|
||
for ( i in { submit: true, change: true, focusin: true }) {
|
||
eventName = "on" + i;
|
||
|
||
if ( !(support[ i + "Bubbles" ] = eventName in window) ) {
|
||
// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
|
||
div.setAttribute( eventName, "t" );
|
||
support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false;
|
||
}
|
||
}
|
||
|
||
// Null elements to avoid leaks in IE.
|
||
div = null;
|
||
})();
|
||
|
||
|
||
var rformElems = /^(?:input|select|textarea)$/i,
|
||
rkeyEvent = /^key/,
|
||
rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
|
||
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
|
||
rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
|
||
|
||
function returnTrue() {
|
||
return true;
|
||
}
|
||
|
||
function returnFalse() {
|
||
return false;
|
||
}
|
||
|
||
function safeActiveElement() {
|
||
try {
|
||
return document.activeElement;
|
||
} catch ( err ) { }
|
||
}
|
||
|
||
/*
|
||
* Helper functions for managing events -- not part of the public interface.
|
||
* Props to Dean Edwards' addEvent library for many of the ideas.
|
||
*/
|
||
jQuery.event = {
|
||
|
||
global: {},
|
||
|
||
add: function( elem, types, handler, data, selector ) {
|
||
var tmp, events, t, handleObjIn,
|
||
special, eventHandle, handleObj,
|
||
handlers, type, namespaces, origType,
|
||
elemData = jQuery._data( elem );
|
||
|
||
// Don't attach events to noData or text/comment nodes (but allow plain objects)
|
||
if ( !elemData ) {
|
||
return;
|
||
}
|
||
|
||
// Caller can pass in an object of custom data in lieu of the handler
|
||
if ( handler.handler ) {
|
||
handleObjIn = handler;
|
||
handler = handleObjIn.handler;
|
||
selector = handleObjIn.selector;
|
||
}
|
||
|
||
// Make sure that the handler has a unique ID, used to find/remove it later
|
||
if ( !handler.guid ) {
|
||
handler.guid = jQuery.guid++;
|
||
}
|
||
|
||
// Init the element's event structure and main handler, if this is the first
|
||
if ( !(events = elemData.events) ) {
|
||
events = elemData.events = {};
|
||
}
|
||
if ( !(eventHandle = elemData.handle) ) {
|
||
eventHandle = elemData.handle = 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 !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
|
||
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
|
||
undefined;
|
||
};
|
||
// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
|
||
eventHandle.elem = elem;
|
||
}
|
||
|
||
// Handle multiple events separated by a space
|
||
types = ( types || "" ).match( rnotwhite ) || [ "" ];
|
||
t = types.length;
|
||
while ( t-- ) {
|
||
tmp = rtypenamespace.exec( types[t] ) || [];
|
||
type = origType = tmp[1];
|
||
namespaces = ( tmp[2] || "" ).split( "." ).sort();
|
||
|
||
// There *must* be a type, no attaching namespace-only handlers
|
||
if ( !type ) {
|
||
continue;
|
||
}
|
||
|
||
// If event changes its type, use the special event handlers for the changed type
|
||
special = jQuery.event.special[ type ] || {};
|
||
|
||
// If selector defined, determine special event api type, otherwise given type
|
||
type = ( selector ? special.delegateType : special.bindType ) || type;
|
||
|
||
// Update special based on newly reset type
|
||
special = jQuery.event.special[ type ] || {};
|
||
|
||
// handleObj is passed to all event handlers
|
||
handleObj = jQuery.extend({
|
||
type: type,
|
||
origType: origType,
|
||
data: data,
|
||
handler: handler,
|
||
guid: handler.guid,
|
||
selector: selector,
|
||
needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
|
||
namespace: namespaces.join(".")
|
||
}, handleObjIn );
|
||
|
||
// Init the event handler queue if we're the first
|
||
if ( !(handlers = events[ type ]) ) {
|
||
handlers = events[ type ] = [];
|
||
handlers.delegateCount = 0;
|
||
|
||
// 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 to the element's handler list, delegates in front
|
||
if ( selector ) {
|
||
handlers.splice( handlers.delegateCount++, 0, handleObj );
|
||
} else {
|
||
handlers.push( handleObj );
|
||
}
|
||
|
||
// Keep track of which events have ever been used, for event optimization
|
||
jQuery.event.global[ type ] = true;
|
||
}
|
||
|
||
// Nullify elem to prevent memory leaks in IE
|
||
elem = null;
|
||
},
|
||
|
||
// Detach an event or set of events from an element
|
||
remove: function( elem, types, handler, selector, mappedTypes ) {
|
||
var j, handleObj, tmp,
|
||
origCount, t, events,
|
||
special, handlers, type,
|
||
namespaces, origType,
|
||
elemData = jQuery.hasData( elem ) && jQuery._data( elem );
|
||
|
||
if ( !elemData || !(events = elemData.events) ) {
|
||
return;
|
||
}
|
||
|
||
// Once for each type.namespace in types; type may be omitted
|
||
types = ( types || "" ).match( rnotwhite ) || [ "" ];
|
||
t = types.length;
|
||
while ( t-- ) {
|
||
tmp = rtypenamespace.exec( types[t] ) || [];
|
||
type = origType = tmp[1];
|
||
namespaces = ( tmp[2] || "" ).split( "." ).sort();
|
||
|
||
// Unbind all events (on this namespace, if provided) for the element
|
||
if ( !type ) {
|
||
for ( type in events ) {
|
||
jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
|
||
}
|
||
continue;
|
||
}
|
||
|
||
special = jQuery.event.special[ type ] || {};
|
||
type = ( selector ? special.delegateType : special.bindType ) || type;
|
||
handlers = events[ type ] || [];
|
||
tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
|
||
|
||
// Remove matching events
|
||
origCount = j = handlers.length;
|
||
while ( j-- ) {
|
||
handleObj = handlers[ j ];
|
||
|
||
if ( ( mappedTypes || origType === handleObj.origType ) &&
|
||
( !handler || handler.guid === handleObj.guid ) &&
|
||
( !tmp || tmp.test( handleObj.namespace ) ) &&
|
||
( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
|
||
handlers.splice( j, 1 );
|
||
|
||
if ( handleObj.selector ) {
|
||
handlers.delegateCount--;
|
||
}
|
||
if ( special.remove ) {
|
||
special.remove.call( elem, handleObj );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Remove generic event handler if we removed something and no more handlers exist
|
||
// (avoids potential for endless recursion during removal of special event handlers)
|
||
if ( origCount && !handlers.length ) {
|
||
if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
|
||
jQuery.removeEvent( elem, type, elemData.handle );
|
||
}
|
||
|
||
delete events[ type ];
|
||
}
|
||
}
|
||
|
||
// Remove the expando if it's no longer used
|
||
if ( jQuery.isEmptyObject( events ) ) {
|
||
delete elemData.handle;
|
||
|
||
// removeData also checks for emptiness and clears the expando if empty
|
||
// so use it instead of delete
|
||
jQuery._removeData( elem, "events" );
|
||
}
|
||
},
|
||
|
||
trigger: function( event, data, elem, onlyHandlers ) {
|
||
var handle, ontype, cur,
|
||
bubbleType, special, tmp, i,
|
||
eventPath = [ elem || document ],
|
||
type = hasOwn.call( event, "type" ) ? event.type : event,
|
||
namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
|
||
|
||
cur = tmp = elem = elem || document;
|
||
|
||
// Don't do events on text and comment nodes
|
||
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
|
||
return;
|
||
}
|
||
|
||
// focus/blur morphs to focusin/out; ensure we're not firing them right now
|
||
if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
|
||
return;
|
||
}
|
||
|
||
if ( type.indexOf(".") >= 0 ) {
|
||
// Namespaced trigger; create a regexp to match event type in handle()
|
||
namespaces = type.split(".");
|
||
type = namespaces.shift();
|
||
namespaces.sort();
|
||
}
|
||
ontype = type.indexOf(":") < 0 && "on" + type;
|
||
|
||
// Caller can pass in a jQuery.Event object, Object, or just an event type string
|
||
event = event[ jQuery.expando ] ?
|
||
event :
|
||
new jQuery.Event( type, typeof event === "object" && event );
|
||
|
||
// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
|
||
event.isTrigger = onlyHandlers ? 2 : 3;
|
||
event.namespace = namespaces.join(".");
|
||
event.namespace_re = event.namespace ?
|
||
new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
|
||
null;
|
||
|
||
// Clean up the event in case it is being reused
|
||
event.result = undefined;
|
||
if ( !event.target ) {
|
||
event.target = elem;
|
||
}
|
||
|
||
// Clone any incoming data and prepend the event, creating the handler arg list
|
||
data = data == null ?
|
||
[ event ] :
|
||
jQuery.makeArray( data, [ event ] );
|
||
|
||
// Allow special events to draw outside the lines
|
||
special = jQuery.event.special[ type ] || {};
|
||
if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
|
||
return;
|
||
}
|
||
|
||
// Determine event propagation path in advance, per W3C events spec (#9951)
|
||
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
|
||
if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
|
||
|
||
bubbleType = special.delegateType || type;
|
||
if ( !rfocusMorph.test( bubbleType + type ) ) {
|
||
cur = cur.parentNode;
|
||
}
|
||
for ( ; cur; cur = cur.parentNode ) {
|
||
eventPath.push( cur );
|
||
tmp = cur;
|
||
}
|
||
|
||
// Only add window if we got to document (e.g., not plain obj or detached DOM)
|
||
if ( tmp === (elem.ownerDocument || document) ) {
|
||
eventPath.push( tmp.defaultView || tmp.parentWindow || window );
|
||
}
|
||
}
|
||
|
||
// Fire handlers on the event path
|
||
i = 0;
|
||
while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
|
||
|
||
event.type = i > 1 ?
|
||
bubbleType :
|
||
special.bindType || type;
|
||
|
||
// jQuery handler
|
||
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
|
||
if ( handle ) {
|
||
handle.apply( cur, data );
|
||
}
|
||
|
||
// Native handler
|
||
handle = ontype && cur[ ontype ];
|
||
if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
|
||
event.result = handle.apply( cur, data );
|
||
if ( event.result === false ) {
|
||
event.preventDefault();
|
||
}
|
||
}
|
||
}
|
||
event.type = type;
|
||
|
||
// If nobody prevented the default action, do it now
|
||
if ( !onlyHandlers && !event.isDefaultPrevented() ) {
|
||
|
||
if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
|
||
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.
|
||
// Don't do default actions on window, that's where global variables be (#6170)
|
||
if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
|
||
|
||
// Don't re-trigger an onFOO event when we call its FOO() method
|
||
tmp = elem[ ontype ];
|
||
|
||
if ( tmp ) {
|
||
elem[ ontype ] = null;
|
||
}
|
||
|
||
// Prevent re-triggering of the same event, since we already bubbled it above
|
||
jQuery.event.triggered = type;
|
||
try {
|
||
elem[ type ]();
|
||
} catch ( e ) {
|
||
// IE<9 dies on focus/blur to hidden element (#1486,#12518)
|
||
// only reproducible on winXP IE8 native, not IE9 in IE8 mode
|
||
}
|
||
jQuery.event.triggered = undefined;
|
||
|
||
if ( tmp ) {
|
||
elem[ ontype ] = tmp;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return event.result;
|
||
},
|
||
|
||
dispatch: function( event ) {
|
||
|
||
// Make a writable jQuery.Event from the native event object
|
||
event = jQuery.event.fix( event );
|
||
|
||
var i, ret, handleObj, matched, j,
|
||
handlerQueue = [],
|
||
args = slice.call( arguments ),
|
||
handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
|
||
special = jQuery.event.special[ event.type ] || {};
|
||
|
||
// Use the fix-ed jQuery.Event rather than the (read-only) native event
|
||
args[0] = event;
|
||
event.delegateTarget = this;
|
||
|
||
// Call the preDispatch hook for the mapped type, and let it bail if desired
|
||
if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
|
||
return;
|
||
}
|
||
|
||
// Determine handlers
|
||
handlerQueue = jQuery.event.handlers.call( this, event, handlers );
|
||
|
||
// Run delegates first; they may want to stop propagation beneath us
|
||
i = 0;
|
||
while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
|
||
event.currentTarget = matched.elem;
|
||
|
||
j = 0;
|
||
while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
|
||
|
||
// Triggered event must either 1) have no namespace, or
|
||
// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
|
||
if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
|
||
|
||
event.handleObj = handleObj;
|
||
event.data = handleObj.data;
|
||
|
||
ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
|
||
.apply( matched.elem, args );
|
||
|
||
if ( ret !== undefined ) {
|
||
if ( (event.result = ret) === false ) {
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Call the postDispatch hook for the mapped type
|
||
if ( special.postDispatch ) {
|
||
special.postDispatch.call( this, event );
|
||
}
|
||
|
||
return event.result;
|
||
},
|
||
|
||
handlers: function( event, handlers ) {
|
||
var sel, handleObj, matches, i,
|
||
handlerQueue = [],
|
||
delegateCount = handlers.delegateCount,
|
||
cur = event.target;
|
||
|
||
// Find delegate handlers
|
||
// Black-hole SVG <use> instance trees (#13180)
|
||
// Avoid non-left-click bubbling in Firefox (#3861)
|
||
if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
|
||
|
||
/* jshint eqeqeq: false */
|
||
for ( ; cur != this; cur = cur.parentNode || this ) {
|
||
/* jshint eqeqeq: true */
|
||
|
||
// Don't check non-elements (#13208)
|
||
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
|
||
if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
|
||
matches = [];
|
||
for ( i = 0; i < delegateCount; i++ ) {
|
||
handleObj = handlers[ i ];
|
||
|
||
// Don't conflict with Object.prototype properties (#13203)
|
||
sel = handleObj.selector + " ";
|
||
|
||
if ( matches[ sel ] === undefined ) {
|
||
matches[ sel ] = handleObj.needsContext ?
|
||
jQuery( sel, this ).index( cur ) >= 0 :
|
||
jQuery.find( sel, this, null, [ cur ] ).length;
|
||
}
|
||
if ( matches[ sel ] ) {
|
||
matches.push( handleObj );
|
||
}
|
||
}
|
||
if ( matches.length ) {
|
||
handlerQueue.push({ elem: cur, handlers: matches });
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Add the remaining (directly-bound) handlers
|
||
if ( delegateCount < handlers.length ) {
|
||
handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
|
||
}
|
||
|
||
return handlerQueue;
|
||
},
|
||
|
||
fix: function( event ) {
|
||
if ( event[ jQuery.expando ] ) {
|
||
return event;
|
||
}
|
||
|
||
// Create a writable copy of the event object and normalize some properties
|
||
var i, prop, copy,
|
||
type = event.type,
|
||
originalEvent = event,
|
||
fixHook = this.fixHooks[ type ];
|
||
|
||
if ( !fixHook ) {
|
||
this.fixHooks[ type ] = fixHook =
|
||
rmouseEvent.test( type ) ? this.mouseHooks :
|
||
rkeyEvent.test( type ) ? this.keyHooks :
|
||
{};
|
||
}
|
||
copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
|
||
|
||
event = new jQuery.Event( originalEvent );
|
||
|
||
i = copy.length;
|
||
while ( i-- ) {
|
||
prop = copy[ i ];
|
||
event[ prop ] = originalEvent[ prop ];
|
||
}
|
||
|
||
// Support: IE<9
|
||
// Fix target property (#1925)
|
||
if ( !event.target ) {
|
||
event.target = originalEvent.srcElement || document;
|
||
}
|
||
|
||
// Support: Chrome 23+, Safari?
|
||
// Target should not be a text node (#504, #13143)
|
||
if ( event.target.nodeType === 3 ) {
|
||
event.target = event.target.parentNode;
|
||
}
|
||
|
||
// Support: IE<9
|
||
// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
|
||
event.metaKey = !!event.metaKey;
|
||
|
||
return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
|
||
},
|
||
|
||
// Includes some event props shared by KeyEvent and MouseEvent
|
||
props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
|
||
|
||
fixHooks: {},
|
||
|
||
keyHooks: {
|
||
props: "char charCode key keyCode".split(" "),
|
||
filter: function( event, original ) {
|
||
|
||
// Add which for key events
|
||
if ( event.which == null ) {
|
||
event.which = original.charCode != null ? original.charCode : original.keyCode;
|
||
}
|
||
|
||
return event;
|
||
}
|
||
},
|
||
|
||
mouseHooks: {
|
||
props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
|
||
filter: function( event, original ) {
|
||
var body, eventDoc, doc,
|
||
button = original.button,
|
||
fromElement = original.fromElement;
|
||
|
||
// Calculate pageX/Y if missing and clientX/Y available
|
||
if ( event.pageX == null && original.clientX != null ) {
|
||
eventDoc = event.target.ownerDocument || document;
|
||
doc = eventDoc.documentElement;
|
||
body = eventDoc.body;
|
||
|
||
event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
|
||
event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
|
||
}
|
||
|
||
// Add relatedTarget, if necessary
|
||
if ( !event.relatedTarget && fromElement ) {
|
||
event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
|
||
}
|
||
|
||
// Add which for click: 1 === left; 2 === middle; 3 === right
|
||
// Note: button is not normalized, so don't use it
|
||
if ( !event.which && button !== undefined ) {
|
||
event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
|
||
}
|
||
|
||
return event;
|
||
}
|
||
},
|
||
|
||
special: {
|
||
load: {
|
||
// Prevent triggered image.load events from bubbling to window.load
|
||
noBubble: true
|
||
},
|
||
focus: {
|
||
// Fire native event if possible so blur/focus sequence is correct
|
||
trigger: function() {
|
||
if ( this !== safeActiveElement() && this.focus ) {
|
||
try {
|
||
this.focus();
|
||
return false;
|
||
} catch ( e ) {
|
||
// Support: IE<9
|
||
// If we error on focus to hidden element (#1486, #12518),
|
||
// let .trigger() run the handlers
|
||
}
|
||
}
|
||
},
|
||
delegateType: "focusin"
|
||
},
|
||
blur: {
|
||
trigger: function() {
|
||
if ( this === safeActiveElement() && this.blur ) {
|
||
this.blur();
|
||
return false;
|
||
}
|
||
},
|
||
delegateType: "focusout"
|
||
},
|
||
click: {
|
||
// For checkbox, fire native event so checked state will be right
|
||
trigger: function() {
|
||
if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
|
||
this.click();
|
||
return false;
|
||
}
|
||
},
|
||
|
||
// For cross-browser consistency, don't fire native .click() on links
|
||
_default: function( event ) {
|
||
return jQuery.nodeName( event.target, "a" );
|
||
}
|
||
},
|
||
|
||
beforeunload: {
|
||
postDispatch: function( event ) {
|
||
|
||
// Support: Firefox 20+
|
||
// Firefox doesn't alert if the returnValue field is not set.
|
||
if ( event.result !== undefined && event.originalEvent ) {
|
||
event.originalEvent.returnValue = event.result;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
simulate: function( type, elem, event, bubble ) {
|
||
// 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.
|
||
var e = jQuery.extend(
|
||
new jQuery.Event(),
|
||
event,
|
||
{
|
||
type: type,
|
||
isSimulated: true,
|
||
originalEvent: {}
|
||
}
|
||
);
|
||
if ( bubble ) {
|
||
jQuery.event.trigger( e, null, elem );
|
||
} else {
|
||
jQuery.event.dispatch.call( elem, e );
|
||
}
|
||
if ( e.isDefaultPrevented() ) {
|
||
event.preventDefault();
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.removeEvent = document.removeEventListener ?
|
||
function( elem, type, handle ) {
|
||
if ( elem.removeEventListener ) {
|
||
elem.removeEventListener( type, handle, false );
|
||
}
|
||
} :
|
||
function( elem, type, handle ) {
|
||
var name = "on" + type;
|
||
|
||
if ( elem.detachEvent ) {
|
||
|
||
// #8545, #7054, preventing memory leaks for custom events in IE6-8
|
||
// detachEvent needed property on element, by name of that event, to properly expose it to GC
|
||
if ( typeof elem[ name ] === strundefined ) {
|
||
elem[ name ] = null;
|
||
}
|
||
|
||
elem.detachEvent( name, handle );
|
||
}
|
||
};
|
||
|
||
jQuery.Event = function( src, props ) {
|
||
// Allow instantiation without the 'new' keyword
|
||
if ( !(this instanceof jQuery.Event) ) {
|
||
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.defaultPrevented === undefined &&
|
||
// Support: IE < 9, Android < 4.0
|
||
src.returnValue === false ?
|
||
returnTrue :
|
||
returnFalse;
|
||
|
||
// Event type
|
||
} else {
|
||
this.type = src;
|
||
}
|
||
|
||
// Put explicitly provided properties onto the event object
|
||
if ( props ) {
|
||
jQuery.extend( this, props );
|
||
}
|
||
|
||
// Create a timestamp if incoming event doesn't have one
|
||
this.timeStamp = src && src.timeStamp || jQuery.now();
|
||
|
||
// Mark it as fixed
|
||
this[ jQuery.expando ] = 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 = {
|
||
isDefaultPrevented: returnFalse,
|
||
isPropagationStopped: returnFalse,
|
||
isImmediatePropagationStopped: returnFalse,
|
||
|
||
preventDefault: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isDefaultPrevented = returnTrue;
|
||
if ( !e ) {
|
||
return;
|
||
}
|
||
|
||
// If preventDefault exists, run it on the original event
|
||
if ( e.preventDefault ) {
|
||
e.preventDefault();
|
||
|
||
// Support: IE
|
||
// Otherwise set the returnValue property of the original event to false
|
||
} else {
|
||
e.returnValue = false;
|
||
}
|
||
},
|
||
stopPropagation: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isPropagationStopped = returnTrue;
|
||
if ( !e ) {
|
||
return;
|
||
}
|
||
// If stopPropagation exists, run it on the original event
|
||
if ( e.stopPropagation ) {
|
||
e.stopPropagation();
|
||
}
|
||
|
||
// Support: IE
|
||
// Set the cancelBubble property of the original event to true
|
||
e.cancelBubble = true;
|
||
},
|
||
stopImmediatePropagation: function() {
|
||
var e = this.originalEvent;
|
||
|
||
this.isImmediatePropagationStopped = returnTrue;
|
||
|
||
if ( e && e.stopImmediatePropagation ) {
|
||
e.stopImmediatePropagation();
|
||
}
|
||
|
||
this.stopPropagation();
|
||
}
|
||
};
|
||
|
||
// Create mouseenter/leave events using mouseover/out and event-time checks
|
||
jQuery.each({
|
||
mouseenter: "mouseover",
|
||
mouseleave: "mouseout",
|
||
pointerenter: "pointerover",
|
||
pointerleave: "pointerout"
|
||
}, function( orig, fix ) {
|
||
jQuery.event.special[ orig ] = {
|
||
delegateType: fix,
|
||
bindType: fix,
|
||
|
||
handle: function( event ) {
|
||
var ret,
|
||
target = this,
|
||
related = event.relatedTarget,
|
||
handleObj = event.handleObj;
|
||
|
||
// For mousenter/leave call the handler if related is outside the target.
|
||
// NB: No relatedTarget if the mouse left/entered the browser window
|
||
if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
|
||
event.type = handleObj.origType;
|
||
ret = handleObj.handler.apply( this, arguments );
|
||
event.type = fix;
|
||
}
|
||
return ret;
|
||
}
|
||
};
|
||
});
|
||
|
||
// IE submit delegation
|
||
if ( !support.submitBubbles ) {
|
||
|
||
jQuery.event.special.submit = {
|
||
setup: function() {
|
||
// Only need this for delegated form submit events
|
||
if ( jQuery.nodeName( this, "form" ) ) {
|
||
return false;
|
||
}
|
||
|
||
// Lazy-add a submit handler when a descendant form may potentially be submitted
|
||
jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
|
||
// Node name check avoids a VML-related crash in IE (#9807)
|
||
var elem = e.target,
|
||
form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
|
||
if ( form && !jQuery._data( form, "submitBubbles" ) ) {
|
||
jQuery.event.add( form, "submit._submit", function( event ) {
|
||
event._submit_bubble = true;
|
||
});
|
||
jQuery._data( form, "submitBubbles", true );
|
||
}
|
||
});
|
||
// return undefined since we don't need an event listener
|
||
},
|
||
|
||
postDispatch: function( event ) {
|
||
// If form was submitted by the user, bubble the event up the tree
|
||
if ( event._submit_bubble ) {
|
||
delete event._submit_bubble;
|
||
if ( this.parentNode && !event.isTrigger ) {
|
||
jQuery.event.simulate( "submit", this.parentNode, event, true );
|
||
}
|
||
}
|
||
},
|
||
|
||
teardown: function() {
|
||
// Only need this for delegated form submit events
|
||
if ( jQuery.nodeName( this, "form" ) ) {
|
||
return false;
|
||
}
|
||
|
||
// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
|
||
jQuery.event.remove( this, "._submit" );
|
||
}
|
||
};
|
||
}
|
||
|
||
// IE change delegation and checkbox/radio fix
|
||
if ( !support.changeBubbles ) {
|
||
|
||
jQuery.event.special.change = {
|
||
|
||
setup: function() {
|
||
|
||
if ( rformElems.test( this.nodeName ) ) {
|
||
// IE doesn't fire change on a check/radio until blur; trigger it on click
|
||
// after a propertychange. Eat the blur-change in special.change.handle.
|
||
// This still fires onchange a second time for check/radio after blur.
|
||
if ( this.type === "checkbox" || this.type === "radio" ) {
|
||
jQuery.event.add( this, "propertychange._change", function( event ) {
|
||
if ( event.originalEvent.propertyName === "checked" ) {
|
||
this._just_changed = true;
|
||
}
|
||
});
|
||
jQuery.event.add( this, "click._change", function( event ) {
|
||
if ( this._just_changed && !event.isTrigger ) {
|
||
this._just_changed = false;
|
||
}
|
||
// Allow triggered, simulated change events (#11500)
|
||
jQuery.event.simulate( "change", this, event, true );
|
||
});
|
||
}
|
||
return false;
|
||
}
|
||
// Delegated event; lazy-add a change handler on descendant inputs
|
||
jQuery.event.add( this, "beforeactivate._change", function( e ) {
|
||
var elem = e.target;
|
||
|
||
if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
|
||
jQuery.event.add( elem, "change._change", function( event ) {
|
||
if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
|
||
jQuery.event.simulate( "change", this.parentNode, event, true );
|
||
}
|
||
});
|
||
jQuery._data( elem, "changeBubbles", true );
|
||
}
|
||
});
|
||
},
|
||
|
||
handle: function( event ) {
|
||
var elem = event.target;
|
||
|
||
// Swallow native change events from checkbox/radio, we already triggered them above
|
||
if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
|
||
return event.handleObj.handler.apply( this, arguments );
|
||
}
|
||
},
|
||
|
||
teardown: function() {
|
||
jQuery.event.remove( this, "._change" );
|
||
|
||
return !rformElems.test( this.nodeName );
|
||
}
|
||
};
|
||
}
|
||
|
||
// Create "bubbling" focus and blur events
|
||
if ( !support.focusinBubbles ) {
|
||
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
|
||
|
||
// Attach a single capturing handler on the document while someone wants focusin/focusout
|
||
var handler = function( event ) {
|
||
jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
|
||
};
|
||
|
||
jQuery.event.special[ fix ] = {
|
||
setup: function() {
|
||
var doc = this.ownerDocument || this,
|
||
attaches = jQuery._data( doc, fix );
|
||
|
||
if ( !attaches ) {
|
||
doc.addEventListener( orig, handler, true );
|
||
}
|
||
jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
|
||
},
|
||
teardown: function() {
|
||
var doc = this.ownerDocument || this,
|
||
attaches = jQuery._data( doc, fix ) - 1;
|
||
|
||
if ( !attaches ) {
|
||
doc.removeEventListener( orig, handler, true );
|
||
jQuery._removeData( doc, fix );
|
||
} else {
|
||
jQuery._data( doc, fix, attaches );
|
||
}
|
||
}
|
||
};
|
||
});
|
||
}
|
||
|
||
jQuery.fn.extend({
|
||
|
||
on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
|
||
var type, origFn;
|
||
|
||
// Types can be a map of types/handlers
|
||
if ( typeof types === "object" ) {
|
||
// ( types-Object, selector, data )
|
||
if ( typeof selector !== "string" ) {
|
||
// ( types-Object, data )
|
||
data = data || selector;
|
||
selector = undefined;
|
||
}
|
||
for ( type in types ) {
|
||
this.on( type, selector, data, types[ type ], one );
|
||
}
|
||
return this;
|
||
}
|
||
|
||
if ( data == null && fn == null ) {
|
||
// ( types, fn )
|
||
fn = selector;
|
||
data = selector = undefined;
|
||
} else if ( fn == null ) {
|
||
if ( typeof selector === "string" ) {
|
||
// ( types, selector, fn )
|
||
fn = data;
|
||
data = undefined;
|
||
} else {
|
||
// ( types, data, fn )
|
||
fn = data;
|
||
data = selector;
|
||
selector = undefined;
|
||
}
|
||
}
|
||
if ( fn === false ) {
|
||
fn = returnFalse;
|
||
} else if ( !fn ) {
|
||
return this;
|
||
}
|
||
|
||
if ( one === 1 ) {
|
||
origFn = fn;
|
||
fn = function( event ) {
|
||
// Can use an empty set, since event contains the info
|
||
jQuery().off( event );
|
||
return origFn.apply( this, arguments );
|
||
};
|
||
// Use same guid so caller can remove using origFn
|
||
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
|
||
}
|
||
return this.each( function() {
|
||
jQuery.event.add( this, types, fn, data, selector );
|
||
});
|
||
},
|
||
one: function( types, selector, data, fn ) {
|
||
return this.on( types, selector, data, fn, 1 );
|
||
},
|
||
off: function( types, selector, fn ) {
|
||
var handleObj, type;
|
||
if ( types && types.preventDefault && types.handleObj ) {
|
||
// ( event ) dispatched jQuery.Event
|
||
handleObj = types.handleObj;
|
||
jQuery( types.delegateTarget ).off(
|
||
handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
|
||
handleObj.selector,
|
||
handleObj.handler
|
||
);
|
||
return this;
|
||
}
|
||
if ( typeof types === "object" ) {
|
||
// ( types-object [, selector] )
|
||
for ( type in types ) {
|
||
this.off( type, selector, types[ type ] );
|
||
}
|
||
return this;
|
||
}
|
||
if ( selector === false || typeof selector === "function" ) {
|
||
// ( types [, fn] )
|
||
fn = selector;
|
||
selector = undefined;
|
||
}
|
||
if ( fn === false ) {
|
||
fn = returnFalse;
|
||
}
|
||
return this.each(function() {
|
||
jQuery.event.remove( this, types, fn, selector );
|
||
});
|
||
},
|
||
|
||
trigger: function( type, data ) {
|
||
return this.each(function() {
|
||
jQuery.event.trigger( type, data, this );
|
||
});
|
||
},
|
||
triggerHandler: function( type, data ) {
|
||
var elem = this[0];
|
||
if ( elem ) {
|
||
return jQuery.event.trigger( type, data, elem, true );
|
||
}
|
||
}
|
||
});
|
||
|
||
|
||
function createSafeFragment( document ) {
|
||
var list = nodeNames.split( "|" ),
|
||
safeFrag = document.createDocumentFragment();
|
||
|
||
if ( safeFrag.createElement ) {
|
||
while ( list.length ) {
|
||
safeFrag.createElement(
|
||
list.pop()
|
||
);
|
||
}
|
||
}
|
||
return safeFrag;
|
||
}
|
||
|
||
var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
|
||
"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
|
||
rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
|
||
rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
|
||
rleadingWhitespace = /^\s+/,
|
||
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
|
||
rtagName = /<([\w:]+)/,
|
||
rtbody = /<tbody/i,
|
||
rhtml = /<|&#?\w+;/,
|
||
rnoInnerhtml = /<(?:script|style|link)/i,
|
||
// checked="checked" or checked
|
||
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
|
||
rscriptType = /^$|\/(?:java|ecma)script/i,
|
||
rscriptTypeMasked = /^true\/(.*)/,
|
||
rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
|
||
|
||
// We have to close these tags to support XHTML (#13200)
|
||
wrapMap = {
|
||
option: [ 1, "<select multiple='multiple'>", "</select>" ],
|
||
legend: [ 1, "<fieldset>", "</fieldset>" ],
|
||
area: [ 1, "<map>", "</map>" ],
|
||
param: [ 1, "<object>", "</object>" ],
|
||
thead: [ 1, "<table>", "</table>" ],
|
||
tr: [ 2, "<table><tbody>", "</tbody></table>" ],
|
||
col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
|
||
td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
|
||
|
||
// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
|
||
// unless wrapped in a div with non-breaking characters in front of it.
|
||
_default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
|
||
},
|
||
safeFragment = createSafeFragment( document ),
|
||
fragmentDiv = safeFragment.appendChild( document.createElement("div") );
|
||
|
||
wrapMap.optgroup = wrapMap.option;
|
||
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
|
||
wrapMap.th = wrapMap.td;
|
||
|
||
function getAll( context, tag ) {
|
||
var elems, elem,
|
||
i = 0,
|
||
found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) :
|
||
typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) :
|
||
undefined;
|
||
|
||
if ( !found ) {
|
||
for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
|
||
if ( !tag || jQuery.nodeName( elem, tag ) ) {
|
||
found.push( elem );
|
||
} else {
|
||
jQuery.merge( found, getAll( elem, tag ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
|
||
jQuery.merge( [ context ], found ) :
|
||
found;
|
||
}
|
||
|
||
// Used in buildFragment, fixes the defaultChecked property
|
||
function fixDefaultChecked( elem ) {
|
||
if ( rcheckableType.test( elem.type ) ) {
|
||
elem.defaultChecked = elem.checked;
|
||
}
|
||
}
|
||
|
||
// Support: IE<8
|
||
// Manipulating tables requires a tbody
|
||
function manipulationTarget( elem, content ) {
|
||
return jQuery.nodeName( elem, "table" ) &&
|
||
jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
|
||
|
||
elem.getElementsByTagName("tbody")[0] ||
|
||
elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
|
||
elem;
|
||
}
|
||
|
||
// Replace/restore the type attribute of script elements for safe DOM manipulation
|
||
function disableScript( elem ) {
|
||
elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
|
||
return elem;
|
||
}
|
||
function restoreScript( elem ) {
|
||
var match = rscriptTypeMasked.exec( elem.type );
|
||
if ( match ) {
|
||
elem.type = match[1];
|
||
} else {
|
||
elem.removeAttribute("type");
|
||
}
|
||
return elem;
|
||
}
|
||
|
||
// Mark scripts as having already been evaluated
|
||
function setGlobalEval( elems, refElements ) {
|
||
var elem,
|
||
i = 0;
|
||
for ( ; (elem = elems[i]) != null; i++ ) {
|
||
jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
|
||
}
|
||
}
|
||
|
||
function cloneCopyEvent( src, dest ) {
|
||
|
||
if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
|
||
return;
|
||
}
|
||
|
||
var type, i, l,
|
||
oldData = jQuery._data( src ),
|
||
curData = jQuery._data( dest, oldData ),
|
||
events = oldData.events;
|
||
|
||
if ( events ) {
|
||
delete curData.handle;
|
||
curData.events = {};
|
||
|
||
for ( type in events ) {
|
||
for ( i = 0, l = events[ type ].length; i < l; i++ ) {
|
||
jQuery.event.add( dest, type, events[ type ][ i ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
// make the cloned public data object a copy from the original
|
||
if ( curData.data ) {
|
||
curData.data = jQuery.extend( {}, curData.data );
|
||
}
|
||
}
|
||
|
||
function fixCloneNodeIssues( src, dest ) {
|
||
var nodeName, e, data;
|
||
|
||
// We do not need to do anything for non-Elements
|
||
if ( dest.nodeType !== 1 ) {
|
||
return;
|
||
}
|
||
|
||
nodeName = dest.nodeName.toLowerCase();
|
||
|
||
// IE6-8 copies events bound via attachEvent when using cloneNode.
|
||
if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
|
||
data = jQuery._data( dest );
|
||
|
||
for ( e in data.events ) {
|
||
jQuery.removeEvent( dest, e, data.handle );
|
||
}
|
||
|
||
// Event data gets referenced instead of copied if the expando gets copied too
|
||
dest.removeAttribute( jQuery.expando );
|
||
}
|
||
|
||
// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
|
||
if ( nodeName === "script" && dest.text !== src.text ) {
|
||
disableScript( dest ).text = src.text;
|
||
restoreScript( dest );
|
||
|
||
// IE6-10 improperly clones children of object elements using classid.
|
||
// IE10 throws NoModificationAllowedError if parent is null, #12132.
|
||
} else if ( nodeName === "object" ) {
|
||
if ( dest.parentNode ) {
|
||
dest.outerHTML = src.outerHTML;
|
||
}
|
||
|
||
// This path appears unavoidable for IE9. When cloning an object
|
||
// element in IE9, the outerHTML strategy above is not sufficient.
|
||
// If the src has innerHTML and the destination does not,
|
||
// copy the src.innerHTML into the dest.innerHTML. #10324
|
||
if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
|
||
dest.innerHTML = src.innerHTML;
|
||
}
|
||
|
||
} else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
|
||
// IE6-8 fails to persist the checked state of a cloned checkbox
|
||
// or radio button. Worse, IE6-7 fail to give the cloned element
|
||
// a checked appearance if the defaultChecked value isn't also set
|
||
|
||
dest.defaultChecked = dest.checked = src.checked;
|
||
|
||
// IE6-7 get confused and end up setting the value of a cloned
|
||
// checkbox/radio button to an empty string instead of "on"
|
||
if ( dest.value !== src.value ) {
|
||
dest.value = src.value;
|
||
}
|
||
|
||
// IE6-8 fails to return the selected option to the default selected
|
||
// state when cloning options
|
||
} else if ( nodeName === "option" ) {
|
||
dest.defaultSelected = dest.selected = src.defaultSelected;
|
||
|
||
// IE6-8 fails to set the defaultValue to the correct value when
|
||
// cloning other types of input fields
|
||
} else if ( nodeName === "input" || nodeName === "textarea" ) {
|
||
dest.defaultValue = src.defaultValue;
|
||
}
|
||
}
|
||
|
||
jQuery.extend({
|
||
clone: function( elem, dataAndEvents, deepDataAndEvents ) {
|
||
var destElements, node, clone, i, srcElements,
|
||
inPage = jQuery.contains( elem.ownerDocument, elem );
|
||
|
||
if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
|
||
clone = elem.cloneNode( true );
|
||
|
||
// IE<=8 does not properly clone detached, unknown element nodes
|
||
} else {
|
||
fragmentDiv.innerHTML = elem.outerHTML;
|
||
fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
|
||
}
|
||
|
||
if ( (!support.noCloneEvent || !support.noCloneChecked) &&
|
||
(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
|
||
|
||
// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
|
||
destElements = getAll( clone );
|
||
srcElements = getAll( elem );
|
||
|
||
// Fix all IE cloning issues
|
||
for ( i = 0; (node = srcElements[i]) != null; ++i ) {
|
||
// Ensure that the destination node is not null; Fixes #9587
|
||
if ( destElements[i] ) {
|
||
fixCloneNodeIssues( node, destElements[i] );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Copy the events from the original to the clone
|
||
if ( dataAndEvents ) {
|
||
if ( deepDataAndEvents ) {
|
||
srcElements = srcElements || getAll( elem );
|
||
destElements = destElements || getAll( clone );
|
||
|
||
for ( i = 0; (node = srcElements[i]) != null; i++ ) {
|
||
cloneCopyEvent( node, destElements[i] );
|
||
}
|
||
} else {
|
||
cloneCopyEvent( elem, clone );
|
||
}
|
||
}
|
||
|
||
// Preserve script evaluation history
|
||
destElements = getAll( clone, "script" );
|
||
if ( destElements.length > 0 ) {
|
||
setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
|
||
}
|
||
|
||
destElements = srcElements = node = null;
|
||
|
||
// Return the cloned set
|
||
return clone;
|
||
},
|
||
|
||
buildFragment: function( elems, context, scripts, selection ) {
|
||
var j, elem, contains,
|
||
tmp, tag, tbody, wrap,
|
||
l = elems.length,
|
||
|
||
// Ensure a safe fragment
|
||
safe = createSafeFragment( context ),
|
||
|
||
nodes = [],
|
||
i = 0;
|
||
|
||
for ( ; i < l; i++ ) {
|
||
elem = elems[ i ];
|
||
|
||
if ( elem || elem === 0 ) {
|
||
|
||
// Add nodes directly
|
||
if ( jQuery.type( elem ) === "object" ) {
|
||
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
|
||
|
||
// Convert non-html into a text node
|
||
} else if ( !rhtml.test( elem ) ) {
|
||
nodes.push( context.createTextNode( elem ) );
|
||
|
||
// Convert html into DOM nodes
|
||
} else {
|
||
tmp = tmp || safe.appendChild( context.createElement("div") );
|
||
|
||
// Deserialize a standard representation
|
||
tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase();
|
||
wrap = wrapMap[ tag ] || wrapMap._default;
|
||
|
||
tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
|
||
|
||
// Descend through wrappers to the right content
|
||
j = wrap[0];
|
||
while ( j-- ) {
|
||
tmp = tmp.lastChild;
|
||
}
|
||
|
||
// Manually add leading whitespace removed by IE
|
||
if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
|
||
nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
|
||
}
|
||
|
||
// Remove IE's autoinserted <tbody> from table fragments
|
||
if ( !support.tbody ) {
|
||
|
||
// String was a <table>, *may* have spurious <tbody>
|
||
elem = tag === "table" && !rtbody.test( elem ) ?
|
||
tmp.firstChild :
|
||
|
||
// String was a bare <thead> or <tfoot>
|
||
wrap[1] === "<table>" && !rtbody.test( elem ) ?
|
||
tmp :
|
||
0;
|
||
|
||
j = elem && elem.childNodes.length;
|
||
while ( j-- ) {
|
||
if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
|
||
elem.removeChild( tbody );
|
||
}
|
||
}
|
||
}
|
||
|
||
jQuery.merge( nodes, tmp.childNodes );
|
||
|
||
// Fix #12392 for WebKit and IE > 9
|
||
tmp.textContent = "";
|
||
|
||
// Fix #12392 for oldIE
|
||
while ( tmp.firstChild ) {
|
||
tmp.removeChild( tmp.firstChild );
|
||
}
|
||
|
||
// Remember the top-level container for proper cleanup
|
||
tmp = safe.lastChild;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Fix #11356: Clear elements from fragment
|
||
if ( tmp ) {
|
||
safe.removeChild( tmp );
|
||
}
|
||
|
||
// Reset defaultChecked for any radios and checkboxes
|
||
// about to be appended to the DOM in IE 6/7 (#8060)
|
||
if ( !support.appendChecked ) {
|
||
jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
|
||
}
|
||
|
||
i = 0;
|
||
while ( (elem = nodes[ i++ ]) ) {
|
||
|
||
// #4087 - If origin and destination elements are the same, and this is
|
||
// that element, do not do anything
|
||
if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
|
||
continue;
|
||
}
|
||
|
||
contains = jQuery.contains( elem.ownerDocument, elem );
|
||
|
||
// Append to fragment
|
||
tmp = getAll( safe.appendChild( elem ), "script" );
|
||
|
||
// Preserve script evaluation history
|
||
if ( contains ) {
|
||
setGlobalEval( tmp );
|
||
}
|
||
|
||
// Capture executables
|
||
if ( scripts ) {
|
||
j = 0;
|
||
while ( (elem = tmp[ j++ ]) ) {
|
||
if ( rscriptType.test( elem.type || "" ) ) {
|
||
scripts.push( elem );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
tmp = null;
|
||
|
||
return safe;
|
||
},
|
||
|
||
cleanData: function( elems, /* internal */ acceptData ) {
|
||
var elem, type, id, data,
|
||
i = 0,
|
||
internalKey = jQuery.expando,
|
||
cache = jQuery.cache,
|
||
deleteExpando = support.deleteExpando,
|
||
special = jQuery.event.special;
|
||
|
||
for ( ; (elem = elems[i]) != null; i++ ) {
|
||
if ( acceptData || jQuery.acceptData( elem ) ) {
|
||
|
||
id = elem[ internalKey ];
|
||
data = id && cache[ id ];
|
||
|
||
if ( data ) {
|
||
if ( data.events ) {
|
||
for ( type in data.events ) {
|
||
if ( special[ type ] ) {
|
||
jQuery.event.remove( elem, type );
|
||
|
||
// This is a shortcut to avoid jQuery.event.remove's overhead
|
||
} else {
|
||
jQuery.removeEvent( elem, type, data.handle );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Remove cache only if it was not already removed by jQuery.event.remove
|
||
if ( cache[ id ] ) {
|
||
|
||
delete cache[ id ];
|
||
|
||
// 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 ( deleteExpando ) {
|
||
delete elem[ internalKey ];
|
||
|
||
} else if ( typeof elem.removeAttribute !== strundefined ) {
|
||
elem.removeAttribute( internalKey );
|
||
|
||
} else {
|
||
elem[ internalKey ] = null;
|
||
}
|
||
|
||
deletedIds.push( id );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
text: function( value ) {
|
||
return access( this, function( value ) {
|
||
return value === undefined ?
|
||
jQuery.text( this ) :
|
||
this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
|
||
}, null, value, arguments.length );
|
||
},
|
||
|
||
append: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
||
var target = manipulationTarget( this, elem );
|
||
target.appendChild( elem );
|
||
}
|
||
});
|
||
},
|
||
|
||
prepend: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
|
||
var target = manipulationTarget( this, elem );
|
||
target.insertBefore( elem, target.firstChild );
|
||
}
|
||
});
|
||
},
|
||
|
||
before: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.parentNode ) {
|
||
this.parentNode.insertBefore( elem, this );
|
||
}
|
||
});
|
||
},
|
||
|
||
after: function() {
|
||
return this.domManip( arguments, function( elem ) {
|
||
if ( this.parentNode ) {
|
||
this.parentNode.insertBefore( elem, this.nextSibling );
|
||
}
|
||
});
|
||
},
|
||
|
||
remove: function( selector, keepData /* Internal Use Only */ ) {
|
||
var elem,
|
||
elems = selector ? jQuery.filter( selector, this ) : this,
|
||
i = 0;
|
||
|
||
for ( ; (elem = elems[i]) != null; i++ ) {
|
||
|
||
if ( !keepData && elem.nodeType === 1 ) {
|
||
jQuery.cleanData( getAll( elem ) );
|
||
}
|
||
|
||
if ( elem.parentNode ) {
|
||
if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
|
||
setGlobalEval( getAll( elem, "script" ) );
|
||
}
|
||
elem.parentNode.removeChild( elem );
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
empty: function() {
|
||
var elem,
|
||
i = 0;
|
||
|
||
for ( ; (elem = this[i]) != null; i++ ) {
|
||
// Remove element nodes and prevent memory leaks
|
||
if ( elem.nodeType === 1 ) {
|
||
jQuery.cleanData( getAll( elem, false ) );
|
||
}
|
||
|
||
// Remove any remaining nodes
|
||
while ( elem.firstChild ) {
|
||
elem.removeChild( elem.firstChild );
|
||
}
|
||
|
||
// If this is a select, ensure that it displays empty (#12336)
|
||
// Support: IE<9
|
||
if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
|
||
elem.options.length = 0;
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
clone: function( dataAndEvents, deepDataAndEvents ) {
|
||
dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
|
||
deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
|
||
|
||
return this.map(function() {
|
||
return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
|
||
});
|
||
},
|
||
|
||
html: function( value ) {
|
||
return access( this, function( value ) {
|
||
var elem = this[ 0 ] || {},
|
||
i = 0,
|
||
l = this.length;
|
||
|
||
if ( value === undefined ) {
|
||
return elem.nodeType === 1 ?
|
||
elem.innerHTML.replace( rinlinejQuery, "" ) :
|
||
undefined;
|
||
}
|
||
|
||
// See if we can take a shortcut and just use innerHTML
|
||
if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
|
||
( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
|
||
( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
|
||
!wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
|
||
|
||
value = value.replace( rxhtmlTag, "<$1></$2>" );
|
||
|
||
try {
|
||
for (; i < l; i++ ) {
|
||
// Remove element nodes and prevent memory leaks
|
||
elem = this[i] || {};
|
||
if ( elem.nodeType === 1 ) {
|
||
jQuery.cleanData( getAll( elem, false ) );
|
||
elem.innerHTML = value;
|
||
}
|
||
}
|
||
|
||
elem = 0;
|
||
|
||
// If using innerHTML throws an exception, use the fallback method
|
||
} catch(e) {}
|
||
}
|
||
|
||
if ( elem ) {
|
||
this.empty().append( value );
|
||
}
|
||
}, null, value, arguments.length );
|
||
},
|
||
|
||
replaceWith: function() {
|
||
var arg = arguments[ 0 ];
|
||
|
||
// Make the changes, replacing each context element with the new content
|
||
this.domManip( arguments, function( elem ) {
|
||
arg = this.parentNode;
|
||
|
||
jQuery.cleanData( getAll( this ) );
|
||
|
||
if ( arg ) {
|
||
arg.replaceChild( elem, this );
|
||
}
|
||
});
|
||
|
||
// Force removal if there was no new content (e.g., from empty arguments)
|
||
return arg && (arg.length || arg.nodeType) ? this : this.remove();
|
||
},
|
||
|
||
detach: function( selector ) {
|
||
return this.remove( selector, true );
|
||
},
|
||
|
||
domManip: function( args, callback ) {
|
||
|
||
// Flatten any nested arrays
|
||
args = concat.apply( [], args );
|
||
|
||
var first, node, hasScripts,
|
||
scripts, doc, fragment,
|
||
i = 0,
|
||
l = this.length,
|
||
set = this,
|
||
iNoClone = l - 1,
|
||
value = args[0],
|
||
isFunction = jQuery.isFunction( value );
|
||
|
||
// We can't cloneNode fragments that contain checked, in WebKit
|
||
if ( isFunction ||
|
||
( l > 1 && typeof value === "string" &&
|
||
!support.checkClone && rchecked.test( value ) ) ) {
|
||
return this.each(function( index ) {
|
||
var self = set.eq( index );
|
||
if ( isFunction ) {
|
||
args[0] = value.call( this, index, self.html() );
|
||
}
|
||
self.domManip( args, callback );
|
||
});
|
||
}
|
||
|
||
if ( l ) {
|
||
fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
|
||
first = fragment.firstChild;
|
||
|
||
if ( fragment.childNodes.length === 1 ) {
|
||
fragment = first;
|
||
}
|
||
|
||
if ( first ) {
|
||
scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
|
||
hasScripts = scripts.length;
|
||
|
||
// Use the original fragment for the last item instead of the first because it can end up
|
||
// being emptied incorrectly in certain situations (#8070).
|
||
for ( ; i < l; i++ ) {
|
||
node = fragment;
|
||
|
||
if ( i !== iNoClone ) {
|
||
node = jQuery.clone( node, true, true );
|
||
|
||
// Keep references to cloned scripts for later restoration
|
||
if ( hasScripts ) {
|
||
jQuery.merge( scripts, getAll( node, "script" ) );
|
||
}
|
||
}
|
||
|
||
callback.call( this[i], node, i );
|
||
}
|
||
|
||
if ( hasScripts ) {
|
||
doc = scripts[ scripts.length - 1 ].ownerDocument;
|
||
|
||
// Reenable scripts
|
||
jQuery.map( scripts, restoreScript );
|
||
|
||
// Evaluate executable scripts on first document insertion
|
||
for ( i = 0; i < hasScripts; i++ ) {
|
||
node = scripts[ i ];
|
||
if ( rscriptType.test( node.type || "" ) &&
|
||
!jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
|
||
|
||
if ( node.src ) {
|
||
// Optional AJAX dependency, but won't run scripts if not present
|
||
if ( jQuery._evalUrl ) {
|
||
jQuery._evalUrl( node.src );
|
||
}
|
||
} else {
|
||
jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Fix #11809: Avoid leaking memory
|
||
fragment = first = null;
|
||
}
|
||
}
|
||
|
||
return this;
|
||
}
|
||
});
|
||
|
||
jQuery.each({
|
||
appendTo: "append",
|
||
prependTo: "prepend",
|
||
insertBefore: "before",
|
||
insertAfter: "after",
|
||
replaceAll: "replaceWith"
|
||
}, function( name, original ) {
|
||
jQuery.fn[ name ] = function( selector ) {
|
||
var elems,
|
||
i = 0,
|
||
ret = [],
|
||
insert = jQuery( selector ),
|
||
last = insert.length - 1;
|
||
|
||
for ( ; i <= last; i++ ) {
|
||
elems = i === last ? this : this.clone(true);
|
||
jQuery( insert[i] )[ original ]( elems );
|
||
|
||
// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
|
||
push.apply( ret, elems.get() );
|
||
}
|
||
|
||
return this.pushStack( ret );
|
||
};
|
||
});
|
||
|
||
|
||
var iframe,
|
||
elemdisplay = {};
|
||
|
||
/**
|
||
* Retrieve the actual display of a element
|
||
* @param {String} name nodeName of the element
|
||
* @param {Object} doc Document object
|
||
*/
|
||
// Called only from within defaultDisplay
|
||
function actualDisplay( name, doc ) {
|
||
var style,
|
||
elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
|
||
|
||
// getDefaultComputedStyle might be reliably used only on attached element
|
||
display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
|
||
|
||
// Use of this method is a temporary fix (more like optmization) until something better comes along,
|
||
// since it was removed from specification and supported only in FF
|
||
style.display : jQuery.css( elem[ 0 ], "display" );
|
||
|
||
// We don't have any data stored on the element,
|
||
// so use "detach" method as fast way to get rid of the element
|
||
elem.detach();
|
||
|
||
return display;
|
||
}
|
||
|
||
/**
|
||
* Try to determine the default display value of an element
|
||
* @param {String} nodeName
|
||
*/
|
||
function defaultDisplay( nodeName ) {
|
||
var doc = document,
|
||
display = elemdisplay[ nodeName ];
|
||
|
||
if ( !display ) {
|
||
display = actualDisplay( nodeName, doc );
|
||
|
||
// If the simple way fails, read from inside an iframe
|
||
if ( display === "none" || !display ) {
|
||
|
||
// Use the already-created iframe if possible
|
||
iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
|
||
|
||
// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
|
||
doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
|
||
|
||
// Support: IE
|
||
doc.write();
|
||
doc.close();
|
||
|
||
display = actualDisplay( nodeName, doc );
|
||
iframe.detach();
|
||
}
|
||
|
||
// Store the correct default display
|
||
elemdisplay[ nodeName ] = display;
|
||
}
|
||
|
||
return display;
|
||
}
|
||
|
||
|
||
(function() {
|
||
var shrinkWrapBlocksVal;
|
||
|
||
support.shrinkWrapBlocks = function() {
|
||
if ( shrinkWrapBlocksVal != null ) {
|
||
return shrinkWrapBlocksVal;
|
||
}
|
||
|
||
// Will be changed later if needed.
|
||
shrinkWrapBlocksVal = false;
|
||
|
||
// Minified: var b,c,d
|
||
var div, body, container;
|
||
|
||
body = document.getElementsByTagName( "body" )[ 0 ];
|
||
if ( !body || !body.style ) {
|
||
// Test fired too early or in an unsupported environment, exit.
|
||
return;
|
||
}
|
||
|
||
// Setup
|
||
div = document.createElement( "div" );
|
||
container = document.createElement( "div" );
|
||
container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
|
||
body.appendChild( container ).appendChild( div );
|
||
|
||
// Support: IE6
|
||
// Check if elements with layout shrink-wrap their children
|
||
if ( typeof div.style.zoom !== strundefined ) {
|
||
// Reset CSS: box-sizing; display; margin; border
|
||
div.style.cssText =
|
||
// Support: Firefox<29, Android 2.3
|
||
// Vendor-prefix box-sizing
|
||
"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
|
||
"box-sizing:content-box;display:block;margin:0;border:0;" +
|
||
"padding:1px;width:1px;zoom:1";
|
||
div.appendChild( document.createElement( "div" ) ).style.width = "5px";
|
||
shrinkWrapBlocksVal = div.offsetWidth !== 3;
|
||
}
|
||
|
||
body.removeChild( container );
|
||
|
||
return shrinkWrapBlocksVal;
|
||
};
|
||
|
||
})();
|
||
var rmargin = (/^margin/);
|
||
|
||
var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
|
||
|
||
|
||
|
||
var getStyles, curCSS,
|
||
rposition = /^(top|right|bottom|left)$/;
|
||
|
||
if ( window.getComputedStyle ) {
|
||
getStyles = function( elem ) {
|
||
return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
|
||
};
|
||
|
||
curCSS = function( elem, name, computed ) {
|
||
var width, minWidth, maxWidth, ret,
|
||
style = elem.style;
|
||
|
||
computed = computed || getStyles( elem );
|
||
|
||
// getPropertyValue is only needed for .css('filter') in IE9, see #12537
|
||
ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
|
||
|
||
if ( computed ) {
|
||
|
||
if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
|
||
ret = jQuery.style( elem, name );
|
||
}
|
||
|
||
// A tribute to the "awesome hack by Dean Edwards"
|
||
// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
|
||
// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
|
||
// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
|
||
if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
|
||
|
||
// Remember the original values
|
||
width = style.width;
|
||
minWidth = style.minWidth;
|
||
maxWidth = style.maxWidth;
|
||
|
||
// Put in the new values to get a computed value out
|
||
style.minWidth = style.maxWidth = style.width = ret;
|
||
ret = computed.width;
|
||
|
||
// Revert the changed values
|
||
style.width = width;
|
||
style.minWidth = minWidth;
|
||
style.maxWidth = maxWidth;
|
||
}
|
||
}
|
||
|
||
// Support: IE
|
||
// IE returns zIndex value as an integer.
|
||
return ret === undefined ?
|
||
ret :
|
||
ret + "";
|
||
};
|
||
} else if ( document.documentElement.currentStyle ) {
|
||
getStyles = function( elem ) {
|
||
return elem.currentStyle;
|
||
};
|
||
|
||
curCSS = function( elem, name, computed ) {
|
||
var left, rs, rsLeft, ret,
|
||
style = elem.style;
|
||
|
||
computed = computed || getStyles( elem );
|
||
ret = computed ? computed[ name ] : undefined;
|
||
|
||
// Avoid setting ret to empty string here
|
||
// so we don't default to auto
|
||
if ( ret == null && style && style[ name ] ) {
|
||
ret = style[ name ];
|
||
}
|
||
|
||
// From the awesome hack by Dean Edwards
|
||
// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
|
||
|
||
// If we're not dealing with a regular pixel number
|
||
// but a number that has a weird ending, we need to convert it to pixels
|
||
// but not position css attributes, as those are proportional to the parent element instead
|
||
// and we can't measure the parent instead because it might trigger a "stacking dolls" problem
|
||
if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
|
||
|
||
// Remember the original values
|
||
left = style.left;
|
||
rs = elem.runtimeStyle;
|
||
rsLeft = rs && rs.left;
|
||
|
||
// Put in the new values to get a computed value out
|
||
if ( rsLeft ) {
|
||
rs.left = elem.currentStyle.left;
|
||
}
|
||
style.left = name === "fontSize" ? "1em" : ret;
|
||
ret = style.pixelLeft + "px";
|
||
|
||
// Revert the changed values
|
||
style.left = left;
|
||
if ( rsLeft ) {
|
||
rs.left = rsLeft;
|
||
}
|
||
}
|
||
|
||
// Support: IE
|
||
// IE returns zIndex value as an integer.
|
||
return ret === undefined ?
|
||
ret :
|
||
ret + "" || "auto";
|
||
};
|
||
}
|
||
|
||
|
||
|
||
|
||
function addGetHookIf( conditionFn, hookFn ) {
|
||
// Define the hook, we'll check on the first run if it's really needed.
|
||
return {
|
||
get: function() {
|
||
var condition = conditionFn();
|
||
|
||
if ( condition == null ) {
|
||
// The test was not ready at this point; screw the hook this time
|
||
// but check again when needed next time.
|
||
return;
|
||
}
|
||
|
||
if ( condition ) {
|
||
// Hook not needed (or it's not possible to use it due to missing dependency),
|
||
// remove it.
|
||
// Since there are no other hooks for marginRight, remove the whole object.
|
||
delete this.get;
|
||
return;
|
||
}
|
||
|
||
// Hook needed; redefine it so that the support test is not executed again.
|
||
|
||
return (this.get = hookFn).apply( this, arguments );
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
(function() {
|
||
// Minified: var b,c,d,e,f,g, h,i
|
||
var div, style, a, pixelPositionVal, boxSizingReliableVal,
|
||
reliableHiddenOffsetsVal, reliableMarginRightVal;
|
||
|
||
// Setup
|
||
div = document.createElement( "div" );
|
||
div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
|
||
a = div.getElementsByTagName( "a" )[ 0 ];
|
||
style = a && a.style;
|
||
|
||
// Finish early in limited (non-browser) environments
|
||
if ( !style ) {
|
||
return;
|
||
}
|
||
|
||
style.cssText = "float:left;opacity:.5";
|
||
|
||
// Support: IE<9
|
||
// Make sure that element opacity exists (as opposed to filter)
|
||
support.opacity = style.opacity === "0.5";
|
||
|
||
// Verify style float existence
|
||
// (IE uses styleFloat instead of cssFloat)
|
||
support.cssFloat = !!style.cssFloat;
|
||
|
||
div.style.backgroundClip = "content-box";
|
||
div.cloneNode( true ).style.backgroundClip = "";
|
||
support.clearCloneStyle = div.style.backgroundClip === "content-box";
|
||
|
||
// Support: Firefox<29, Android 2.3
|
||
// Vendor-prefix box-sizing
|
||
support.boxSizing = style.boxSizing === "" || style.MozBoxSizing === "" ||
|
||
style.WebkitBoxSizing === "";
|
||
|
||
jQuery.extend(support, {
|
||
reliableHiddenOffsets: function() {
|
||
if ( reliableHiddenOffsetsVal == null ) {
|
||
computeStyleTests();
|
||
}
|
||
return reliableHiddenOffsetsVal;
|
||
},
|
||
|
||
boxSizingReliable: function() {
|
||
if ( boxSizingReliableVal == null ) {
|
||
computeStyleTests();
|
||
}
|
||
return boxSizingReliableVal;
|
||
},
|
||
|
||
pixelPosition: function() {
|
||
if ( pixelPositionVal == null ) {
|
||
computeStyleTests();
|
||
}
|
||
return pixelPositionVal;
|
||
},
|
||
|
||
// Support: Android 2.3
|
||
reliableMarginRight: function() {
|
||
if ( reliableMarginRightVal == null ) {
|
||
computeStyleTests();
|
||
}
|
||
return reliableMarginRightVal;
|
||
}
|
||
});
|
||
|
||
function computeStyleTests() {
|
||
// Minified: var b,c,d,j
|
||
var div, body, container, contents;
|
||
|
||
body = document.getElementsByTagName( "body" )[ 0 ];
|
||
if ( !body || !body.style ) {
|
||
// Test fired too early or in an unsupported environment, exit.
|
||
return;
|
||
}
|
||
|
||
// Setup
|
||
div = document.createElement( "div" );
|
||
container = document.createElement( "div" );
|
||
container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
|
||
body.appendChild( container ).appendChild( div );
|
||
|
||
div.style.cssText =
|
||
// Support: Firefox<29, Android 2.3
|
||
// Vendor-prefix box-sizing
|
||
"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
|
||
"box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
|
||
"border:1px;padding:1px;width:4px;position:absolute";
|
||
|
||
// Support: IE<9
|
||
// Assume reasonable values in the absence of getComputedStyle
|
||
pixelPositionVal = boxSizingReliableVal = false;
|
||
reliableMarginRightVal = true;
|
||
|
||
// Check for getComputedStyle so that this code is not run in IE<9.
|
||
if ( window.getComputedStyle ) {
|
||
pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
|
||
boxSizingReliableVal =
|
||
( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
|
||
|
||
// Support: Android 2.3
|
||
// Div with explicit width and no margin-right incorrectly
|
||
// gets computed margin-right based on width of container (#3333)
|
||
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
|
||
contents = div.appendChild( document.createElement( "div" ) );
|
||
|
||
// Reset CSS: box-sizing; display; margin; border; padding
|
||
contents.style.cssText = div.style.cssText =
|
||
// Support: Firefox<29, Android 2.3
|
||
// Vendor-prefix box-sizing
|
||
"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
|
||
"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
|
||
contents.style.marginRight = contents.style.width = "0";
|
||
div.style.width = "1px";
|
||
|
||
reliableMarginRightVal =
|
||
!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );
|
||
}
|
||
|
||
// Support: IE8
|
||
// 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).
|
||
div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
|
||
contents = div.getElementsByTagName( "td" );
|
||
contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
|
||
reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
|
||
if ( reliableHiddenOffsetsVal ) {
|
||
contents[ 0 ].style.display = "";
|
||
contents[ 1 ].style.display = "none";
|
||
reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
|
||
}
|
||
|
||
body.removeChild( container );
|
||
}
|
||
|
||
})();
|
||
|
||
|
||
// A method for quickly swapping in/out CSS properties to get correct calculations.
|
||
jQuery.swap = function( elem, options, callback, args ) {
|
||
var ret, name,
|
||
old = {};
|
||
|
||
// Remember the old values, and insert the new ones
|
||
for ( name in options ) {
|
||
old[ name ] = elem.style[ name ];
|
||
elem.style[ name ] = options[ name ];
|
||
}
|
||
|
||
ret = callback.apply( elem, args || [] );
|
||
|
||
// Revert the old values
|
||
for ( name in options ) {
|
||
elem.style[ name ] = old[ name ];
|
||
}
|
||
|
||
return ret;
|
||
};
|
||
|
||
|
||
var
|
||
ralpha = /alpha\([^)]*\)/i,
|
||
ropacity = /opacity\s*=\s*([^)]*)/,
|
||
|
||
// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
|
||
// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
|
||
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
|
||
rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
|
||
rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
|
||
|
||
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
|
||
cssNormalTransform = {
|
||
letterSpacing: "0",
|
||
fontWeight: "400"
|
||
},
|
||
|
||
cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
|
||
|
||
|
||
// return a css property mapped to a potentially vendor prefixed property
|
||
function vendorPropName( style, name ) {
|
||
|
||
// shortcut for names that are not vendor prefixed
|
||
if ( name in style ) {
|
||
return name;
|
||
}
|
||
|
||
// check for vendor prefixed names
|
||
var capName = name.charAt(0).toUpperCase() + name.slice(1),
|
||
origName = name,
|
||
i = cssPrefixes.length;
|
||
|
||
while ( i-- ) {
|
||
name = cssPrefixes[ i ] + capName;
|
||
if ( name in style ) {
|
||
return name;
|
||
}
|
||
}
|
||
|
||
return origName;
|
||
}
|
||
|
||
function showHide( elements, show ) {
|
||
var display, elem, hidden,
|
||
values = [],
|
||
index = 0,
|
||
length = elements.length;
|
||
|
||
for ( ; index < length; index++ ) {
|
||
elem = elements[ index ];
|
||
if ( !elem.style ) {
|
||
continue;
|
||
}
|
||
|
||
values[ index ] = jQuery._data( elem, "olddisplay" );
|
||
display = elem.style.display;
|
||
if ( show ) {
|
||
// Reset the inline display of this element to learn if it is
|
||
// being hidden by cascaded rules or not
|
||
if ( !values[ index ] && display === "none" ) {
|
||
elem.style.display = "";
|
||
}
|
||
|
||
// Set elements which have been overridden with display: none
|
||
// in a stylesheet to whatever the default browser style is
|
||
// for such an element
|
||
if ( elem.style.display === "" && isHidden( elem ) ) {
|
||
values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
|
||
}
|
||
} else {
|
||
hidden = isHidden( elem );
|
||
|
||
if ( display && display !== "none" || !hidden ) {
|
||
jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
// Set the display of most of the elements in a second loop
|
||
// to avoid the constant reflow
|
||
for ( index = 0; index < length; index++ ) {
|
||
elem = elements[ index ];
|
||
if ( !elem.style ) {
|
||
continue;
|
||
}
|
||
if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
|
||
elem.style.display = show ? values[ index ] || "" : "none";
|
||
}
|
||
}
|
||
|
||
return elements;
|
||
}
|
||
|
||
function setPositiveNumber( elem, value, subtract ) {
|
||
var matches = rnumsplit.exec( value );
|
||
return matches ?
|
||
// Guard against undefined "subtract", e.g., when used as in cssHooks
|
||
Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
|
||
value;
|
||
}
|
||
|
||
function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
|
||
var i = extra === ( isBorderBox ? "border" : "content" ) ?
|
||
// If we already have the right measurement, avoid augmentation
|
||
4 :
|
||
// Otherwise initialize for horizontal or vertical properties
|
||
name === "width" ? 1 : 0,
|
||
|
||
val = 0;
|
||
|
||
for ( ; i < 4; i += 2 ) {
|
||
// both box models exclude margin, so add it if we want it
|
||
if ( extra === "margin" ) {
|
||
val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
|
||
}
|
||
|
||
if ( isBorderBox ) {
|
||
// border-box includes padding, so remove it if we want content
|
||
if ( extra === "content" ) {
|
||
val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
|
||
}
|
||
|
||
// at this point, extra isn't border nor margin, so remove border
|
||
if ( extra !== "margin" ) {
|
||
val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
||
}
|
||
} else {
|
||
// at this point, extra isn't content, so add padding
|
||
val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
|
||
|
||
// at this point, extra isn't content nor padding, so add border
|
||
if ( extra !== "padding" ) {
|
||
val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
|
||
}
|
||
}
|
||
}
|
||
|
||
return val;
|
||
}
|
||
|
||
function getWidthOrHeight( elem, name, extra ) {
|
||
|
||
// Start with offset property, which is equivalent to the border-box value
|
||
var valueIsBorderBox = true,
|
||
val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
|
||
styles = getStyles( elem ),
|
||
isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
|
||
|
||
// some non-html elements return undefined for offsetWidth, so check for null/undefined
|
||
// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
|
||
// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
|
||
if ( val <= 0 || val == null ) {
|
||
// Fall back to computed then uncomputed css if necessary
|
||
val = curCSS( elem, name, styles );
|
||
if ( val < 0 || val == null ) {
|
||
val = elem.style[ name ];
|
||
}
|
||
|
||
// Computed unit is not pixels. Stop here and return.
|
||
if ( rnumnonpx.test(val) ) {
|
||
return val;
|
||
}
|
||
|
||
// we need the check for style in case a browser which returns unreliable values
|
||
// for getComputedStyle silently falls back to the reliable elem.style
|
||
valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );
|
||
|
||
// Normalize "", auto, and prepare for extra
|
||
val = parseFloat( val ) || 0;
|
||
}
|
||
|
||
// use the active box-sizing model to add/subtract irrelevant styles
|
||
return ( val +
|
||
augmentWidthOrHeight(
|
||
elem,
|
||
name,
|
||
extra || ( isBorderBox ? "border" : "content" ),
|
||
valueIsBorderBox,
|
||
styles
|
||
)
|
||
) + "px";
|
||
}
|
||
|
||
jQuery.extend({
|
||
// Add in style property hooks for overriding the default
|
||
// behavior of getting and setting a style property
|
||
cssHooks: {
|
||
opacity: {
|
||
get: function( elem, computed ) {
|
||
if ( computed ) {
|
||
// We should always get a number back from opacity
|
||
var ret = curCSS( elem, "opacity" );
|
||
return ret === "" ? "1" : ret;
|
||
}
|
||
}
|
||
}
|
||
},
|
||
|
||
// Don't automatically add "px" to these possibly-unitless properties
|
||
cssNumber: {
|
||
"columnCount": true,
|
||
"fillOpacity": true,
|
||
"flexGrow": true,
|
||
"flexShrink": true,
|
||
"fontWeight": true,
|
||
"lineHeight": true,
|
||
"opacity": true,
|
||
"order": true,
|
||
"orphans": true,
|
||
"widows": true,
|
||
"zIndex": true,
|
||
"zoom": true
|
||
},
|
||
|
||
// Add in properties whose names you wish to fix before
|
||
// setting or getting the value
|
||
cssProps: {
|
||
// normalize float css property
|
||
"float": support.cssFloat ? "cssFloat" : "styleFloat"
|
||
},
|
||
|
||
// Get and set the style property on a DOM Node
|
||
style: function( elem, name, value, extra ) {
|
||
// Don't set styles on text and comment nodes
|
||
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
|
||
return;
|
||
}
|
||
|
||
// Make sure that we're working with the right name
|
||
var ret, type, hooks,
|
||
origName = jQuery.camelCase( name ),
|
||
style = elem.style;
|
||
|
||
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
|
||
|
||
// gets hook for the prefixed version
|
||
// followed by the unprefixed version
|
||
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
||
|
||
// Check if we're setting a value
|
||
if ( value !== undefined ) {
|
||
type = typeof value;
|
||
|
||
// convert relative number strings (+= or -=) to relative numbers. #7345
|
||
if ( type === "string" && (ret = rrelNum.exec( value )) ) {
|
||
value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
|
||
// Fixes bug #9237
|
||
type = "number";
|
||
}
|
||
|
||
// Make sure that null and NaN values aren't set. See: #7116
|
||
if ( value == null || value !== value ) {
|
||
return;
|
||
}
|
||
|
||
// If a number was passed in, add 'px' to the (except for certain CSS properties)
|
||
if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
|
||
value += "px";
|
||
}
|
||
|
||
// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
|
||
// but it would mean to define eight (for every problematic property) identical functions
|
||
if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
|
||
style[ name ] = "inherit";
|
||
}
|
||
|
||
// If a hook was provided, use that value, otherwise just set the specified value
|
||
if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
|
||
|
||
// Support: IE
|
||
// Swallow errors from 'invalid' CSS values (#5509)
|
||
try {
|
||
style[ name ] = value;
|
||
} catch(e) {}
|
||
}
|
||
|
||
} else {
|
||
// If a hook was provided get the non-computed value from there
|
||
if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
|
||
return ret;
|
||
}
|
||
|
||
// Otherwise just get the value from the style object
|
||
return style[ name ];
|
||
}
|
||
},
|
||
|
||
css: function( elem, name, extra, styles ) {
|
||
var num, val, hooks,
|
||
origName = jQuery.camelCase( name );
|
||
|
||
// Make sure that we're working with the right name
|
||
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
|
||
|
||
// gets hook for the prefixed version
|
||
// followed by the unprefixed version
|
||
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
||
|
||
// If a hook was provided get the computed value from there
|
||
if ( hooks && "get" in hooks ) {
|
||
val = hooks.get( elem, true, extra );
|
||
}
|
||
|
||
// Otherwise, if a way to get the computed value exists, use that
|
||
if ( val === undefined ) {
|
||
val = curCSS( elem, name, styles );
|
||
}
|
||
|
||
//convert "normal" to computed value
|
||
if ( val === "normal" && name in cssNormalTransform ) {
|
||
val = cssNormalTransform[ name ];
|
||
}
|
||
|
||
// Return, converting to number if forced or a qualifier was provided and val looks numeric
|
||
if ( extra === "" || extra ) {
|
||
num = parseFloat( val );
|
||
return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
|
||
}
|
||
return val;
|
||
}
|
||
});
|
||
|
||
jQuery.each([ "height", "width" ], function( i, name ) {
|
||
jQuery.cssHooks[ name ] = {
|
||
get: function( elem, computed, extra ) {
|
||
if ( computed ) {
|
||
// certain elements can have dimension info if we invisibly show them
|
||
// however, it must have a current display style that would benefit from this
|
||
return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
|
||
jQuery.swap( elem, cssShow, function() {
|
||
return getWidthOrHeight( elem, name, extra );
|
||
}) :
|
||
getWidthOrHeight( elem, name, extra );
|
||
}
|
||
},
|
||
|
||
set: function( elem, value, extra ) {
|
||
var styles = extra && getStyles( elem );
|
||
return setPositiveNumber( elem, value, extra ?
|
||
augmentWidthOrHeight(
|
||
elem,
|
||
name,
|
||
extra,
|
||
support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
|
||
styles
|
||
) : 0
|
||
);
|
||
}
|
||
};
|
||
});
|
||
|
||
if ( !support.opacity ) {
|
||
jQuery.cssHooks.opacity = {
|
||
get: function( elem, computed ) {
|
||
// IE uses filters for opacity
|
||
return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
|
||
( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
|
||
computed ? "1" : "";
|
||
},
|
||
|
||
set: function( elem, value ) {
|
||
var style = elem.style,
|
||
currentStyle = elem.currentStyle,
|
||
opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
|
||
filter = currentStyle && currentStyle.filter || style.filter || "";
|
||
|
||
// IE has trouble with opacity if it does not have layout
|
||
// Force it by setting the zoom level
|
||
style.zoom = 1;
|
||
|
||
// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
|
||
// if value === "", then remove inline opacity #12685
|
||
if ( ( value >= 1 || value === "" ) &&
|
||
jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
|
||
style.removeAttribute ) {
|
||
|
||
// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
|
||
// if "filter:" is present at all, clearType is disabled, we want to avoid this
|
||
// style.removeAttribute is IE Only, but so apparently is this code path...
|
||
style.removeAttribute( "filter" );
|
||
|
||
// if there is no filter style applied in a css rule or unset inline opacity, we are done
|
||
if ( value === "" || currentStyle && !currentStyle.filter ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
// otherwise, set new filter values
|
||
style.filter = ralpha.test( filter ) ?
|
||
filter.replace( ralpha, opacity ) :
|
||
filter + " " + opacity;
|
||
}
|
||
};
|
||
}
|
||
|
||
jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
|
||
function( elem, computed ) {
|
||
if ( computed ) {
|
||
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
|
||
// Work around by temporarily setting element display to inline-block
|
||
return jQuery.swap( elem, { "display": "inline-block" },
|
||
curCSS, [ elem, "marginRight" ] );
|
||
}
|
||
}
|
||
);
|
||
|
||
// These hooks are used by animate to expand properties
|
||
jQuery.each({
|
||
margin: "",
|
||
padding: "",
|
||
border: "Width"
|
||
}, function( prefix, suffix ) {
|
||
jQuery.cssHooks[ prefix + suffix ] = {
|
||
expand: function( value ) {
|
||
var i = 0,
|
||
expanded = {},
|
||
|
||
// assumes a single number if not a string
|
||
parts = typeof value === "string" ? value.split(" ") : [ value ];
|
||
|
||
for ( ; i < 4; i++ ) {
|
||
expanded[ prefix + cssExpand[ i ] + suffix ] =
|
||
parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
|
||
}
|
||
|
||
return expanded;
|
||
}
|
||
};
|
||
|
||
if ( !rmargin.test( prefix ) ) {
|
||
jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
|
||
}
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
css: function( name, value ) {
|
||
return access( this, function( elem, name, value ) {
|
||
var styles, len,
|
||
map = {},
|
||
i = 0;
|
||
|
||
if ( jQuery.isArray( name ) ) {
|
||
styles = getStyles( elem );
|
||
len = name.length;
|
||
|
||
for ( ; i < len; i++ ) {
|
||
map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
|
||
}
|
||
|
||
return map;
|
||
}
|
||
|
||
return value !== undefined ?
|
||
jQuery.style( elem, name, value ) :
|
||
jQuery.css( elem, name );
|
||
}, name, value, arguments.length > 1 );
|
||
},
|
||
show: function() {
|
||
return showHide( this, true );
|
||
},
|
||
hide: function() {
|
||
return showHide( this );
|
||
},
|
||
toggle: function( state ) {
|
||
if ( typeof state === "boolean" ) {
|
||
return state ? this.show() : this.hide();
|
||
}
|
||
|
||
return this.each(function() {
|
||
if ( isHidden( this ) ) {
|
||
jQuery( this ).show();
|
||
} else {
|
||
jQuery( this ).hide();
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
|
||
function Tween( elem, options, prop, end, easing ) {
|
||
return new Tween.prototype.init( elem, options, prop, end, easing );
|
||
}
|
||
jQuery.Tween = Tween;
|
||
|
||
Tween.prototype = {
|
||
constructor: Tween,
|
||
init: function( elem, options, prop, end, easing, unit ) {
|
||
this.elem = elem;
|
||
this.prop = prop;
|
||
this.easing = easing || "swing";
|
||
this.options = options;
|
||
this.start = this.now = this.cur();
|
||
this.end = end;
|
||
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
|
||
},
|
||
cur: function() {
|
||
var hooks = Tween.propHooks[ this.prop ];
|
||
|
||
return hooks && hooks.get ?
|
||
hooks.get( this ) :
|
||
Tween.propHooks._default.get( this );
|
||
},
|
||
run: function( percent ) {
|
||
var eased,
|
||
hooks = Tween.propHooks[ this.prop ];
|
||
|
||
if ( this.options.duration ) {
|
||
this.pos = eased = jQuery.easing[ this.easing ](
|
||
percent, this.options.duration * percent, 0, 1, this.options.duration
|
||
);
|
||
} else {
|
||
this.pos = eased = percent;
|
||
}
|
||
this.now = ( this.end - this.start ) * eased + this.start;
|
||
|
||
if ( this.options.step ) {
|
||
this.options.step.call( this.elem, this.now, this );
|
||
}
|
||
|
||
if ( hooks && hooks.set ) {
|
||
hooks.set( this );
|
||
} else {
|
||
Tween.propHooks._default.set( this );
|
||
}
|
||
return this;
|
||
}
|
||
};
|
||
|
||
Tween.prototype.init.prototype = Tween.prototype;
|
||
|
||
Tween.propHooks = {
|
||
_default: {
|
||
get: function( tween ) {
|
||
var result;
|
||
|
||
if ( tween.elem[ tween.prop ] != null &&
|
||
(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
|
||
return tween.elem[ tween.prop ];
|
||
}
|
||
|
||
// passing an empty string as a 3rd parameter to .css will automatically
|
||
// attempt a parseFloat and fallback to a string if the parse fails
|
||
// so, simple values such as "10px" are parsed to Float.
|
||
// complex values such as "rotate(1rad)" are returned as is.
|
||
result = jQuery.css( tween.elem, tween.prop, "" );
|
||
// Empty strings, null, undefined and "auto" are converted to 0.
|
||
return !result || result === "auto" ? 0 : result;
|
||
},
|
||
set: function( tween ) {
|
||
// use step hook for back compat - use cssHook if its there - use .style if its
|
||
// available and use plain properties where available
|
||
if ( jQuery.fx.step[ tween.prop ] ) {
|
||
jQuery.fx.step[ tween.prop ]( tween );
|
||
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
|
||
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
|
||
} else {
|
||
tween.elem[ tween.prop ] = tween.now;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
// Support: IE <=9
|
||
// Panic based approach to setting things on disconnected nodes
|
||
|
||
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
|
||
set: function( tween ) {
|
||
if ( tween.elem.nodeType && tween.elem.parentNode ) {
|
||
tween.elem[ tween.prop ] = tween.now;
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.easing = {
|
||
linear: function( p ) {
|
||
return p;
|
||
},
|
||
swing: function( p ) {
|
||
return 0.5 - Math.cos( p * Math.PI ) / 2;
|
||
}
|
||
};
|
||
|
||
jQuery.fx = Tween.prototype.init;
|
||
|
||
// Back Compat <1.8 extension point
|
||
jQuery.fx.step = {};
|
||
|
||
|
||
|
||
|
||
var
|
||
fxNow, timerId,
|
||
rfxtypes = /^(?:toggle|show|hide)$/,
|
||
rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
|
||
rrun = /queueHooks$/,
|
||
animationPrefilters = [ defaultPrefilter ],
|
||
tweeners = {
|
||
"*": [ function( prop, value ) {
|
||
var tween = this.createTween( prop, value ),
|
||
target = tween.cur(),
|
||
parts = rfxnum.exec( value ),
|
||
unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
|
||
|
||
// Starting value computation is required for potential unit mismatches
|
||
start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
|
||
rfxnum.exec( jQuery.css( tween.elem, prop ) ),
|
||
scale = 1,
|
||
maxIterations = 20;
|
||
|
||
if ( start && start[ 3 ] !== unit ) {
|
||
// Trust units reported by jQuery.css
|
||
unit = unit || start[ 3 ];
|
||
|
||
// Make sure we update the tween properties later on
|
||
parts = parts || [];
|
||
|
||
// Iteratively approximate from a nonzero starting point
|
||
start = +target || 1;
|
||
|
||
do {
|
||
// If previous iteration zeroed out, double until we get *something*
|
||
// Use a string for doubling factor so we don't accidentally see scale as unchanged below
|
||
scale = scale || ".5";
|
||
|
||
// Adjust and apply
|
||
start = start / scale;
|
||
jQuery.style( tween.elem, prop, start + unit );
|
||
|
||
// Update scale, tolerating zero or NaN from tween.cur()
|
||
// And breaking the loop if scale is unchanged or perfect, or if we've just had enough
|
||
} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
|
||
}
|
||
|
||
// Update tween properties
|
||
if ( parts ) {
|
||
start = tween.start = +start || +target || 0;
|
||
tween.unit = unit;
|
||
// If a +=/-= token was provided, we're doing a relative animation
|
||
tween.end = parts[ 1 ] ?
|
||
start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
|
||
+parts[ 2 ];
|
||
}
|
||
|
||
return tween;
|
||
} ]
|
||
};
|
||
|
||
// Animations created synchronously will run synchronously
|
||
function createFxNow() {
|
||
setTimeout(function() {
|
||
fxNow = undefined;
|
||
});
|
||
return ( fxNow = jQuery.now() );
|
||
}
|
||
|
||
// Generate parameters to create a standard animation
|
||
function genFx( type, includeWidth ) {
|
||
var which,
|
||
attrs = { height: type },
|
||
i = 0;
|
||
|
||
// if we include width, step value is 1 to do all cssExpand values,
|
||
// if we don't include width, step value is 2 to skip over Left and Right
|
||
includeWidth = includeWidth ? 1 : 0;
|
||
for ( ; i < 4 ; i += 2 - includeWidth ) {
|
||
which = cssExpand[ i ];
|
||
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
|
||
}
|
||
|
||
if ( includeWidth ) {
|
||
attrs.opacity = attrs.width = type;
|
||
}
|
||
|
||
return attrs;
|
||
}
|
||
|
||
function createTween( value, prop, animation ) {
|
||
var tween,
|
||
collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
|
||
index = 0,
|
||
length = collection.length;
|
||
for ( ; index < length; index++ ) {
|
||
if ( (tween = collection[ index ].call( animation, prop, value )) ) {
|
||
|
||
// we're done with this property
|
||
return tween;
|
||
}
|
||
}
|
||
}
|
||
|
||
function defaultPrefilter( elem, props, opts ) {
|
||
/* jshint validthis: true */
|
||
var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
|
||
anim = this,
|
||
orig = {},
|
||
style = elem.style,
|
||
hidden = elem.nodeType && isHidden( elem ),
|
||
dataShow = jQuery._data( elem, "fxshow" );
|
||
|
||
// handle queue: false promises
|
||
if ( !opts.queue ) {
|
||
hooks = jQuery._queueHooks( elem, "fx" );
|
||
if ( hooks.unqueued == null ) {
|
||
hooks.unqueued = 0;
|
||
oldfire = hooks.empty.fire;
|
||
hooks.empty.fire = function() {
|
||
if ( !hooks.unqueued ) {
|
||
oldfire();
|
||
}
|
||
};
|
||
}
|
||
hooks.unqueued++;
|
||
|
||
anim.always(function() {
|
||
// doing this makes sure that the complete handler will be called
|
||
// before this completes
|
||
anim.always(function() {
|
||
hooks.unqueued--;
|
||
if ( !jQuery.queue( elem, "fx" ).length ) {
|
||
hooks.empty.fire();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// height/width overflow pass
|
||
if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
|
||
// Make sure that nothing sneaks out
|
||
// Record all 3 overflow attributes because IE does not
|
||
// change the overflow attribute when overflowX and
|
||
// overflowY are set to the same value
|
||
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
|
||
|
||
// Set display property to inline-block for height/width
|
||
// animations on inline elements that are having width/height animated
|
||
display = jQuery.css( elem, "display" );
|
||
|
||
// Test default display if display is currently "none"
|
||
checkDisplay = display === "none" ?
|
||
jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
|
||
|
||
if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
|
||
|
||
// inline-level elements accept inline-block;
|
||
// block-level elements need to be inline with layout
|
||
if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
|
||
style.display = "inline-block";
|
||
} else {
|
||
style.zoom = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( opts.overflow ) {
|
||
style.overflow = "hidden";
|
||
if ( !support.shrinkWrapBlocks() ) {
|
||
anim.always(function() {
|
||
style.overflow = opts.overflow[ 0 ];
|
||
style.overflowX = opts.overflow[ 1 ];
|
||
style.overflowY = opts.overflow[ 2 ];
|
||
});
|
||
}
|
||
}
|
||
|
||
// show/hide pass
|
||
for ( prop in props ) {
|
||
value = props[ prop ];
|
||
if ( rfxtypes.exec( value ) ) {
|
||
delete props[ prop ];
|
||
toggle = toggle || value === "toggle";
|
||
if ( value === ( hidden ? "hide" : "show" ) ) {
|
||
|
||
// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
|
||
if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
|
||
hidden = true;
|
||
} else {
|
||
continue;
|
||
}
|
||
}
|
||
orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
|
||
|
||
// Any non-fx value stops us from restoring the original display value
|
||
} else {
|
||
display = undefined;
|
||
}
|
||
}
|
||
|
||
if ( !jQuery.isEmptyObject( orig ) ) {
|
||
if ( dataShow ) {
|
||
if ( "hidden" in dataShow ) {
|
||
hidden = dataShow.hidden;
|
||
}
|
||
} else {
|
||
dataShow = jQuery._data( elem, "fxshow", {} );
|
||
}
|
||
|
||
// store state if its toggle - enables .stop().toggle() to "reverse"
|
||
if ( toggle ) {
|
||
dataShow.hidden = !hidden;
|
||
}
|
||
if ( hidden ) {
|
||
jQuery( elem ).show();
|
||
} else {
|
||
anim.done(function() {
|
||
jQuery( elem ).hide();
|
||
});
|
||
}
|
||
anim.done(function() {
|
||
var prop;
|
||
jQuery._removeData( elem, "fxshow" );
|
||
for ( prop in orig ) {
|
||
jQuery.style( elem, prop, orig[ prop ] );
|
||
}
|
||
});
|
||
for ( prop in orig ) {
|
||
tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
|
||
|
||
if ( !( prop in dataShow ) ) {
|
||
dataShow[ prop ] = tween.start;
|
||
if ( hidden ) {
|
||
tween.end = tween.start;
|
||
tween.start = prop === "width" || prop === "height" ? 1 : 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// If this is a noop like .hide().hide(), restore an overwritten display value
|
||
} else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
|
||
style.display = display;
|
||
}
|
||
}
|
||
|
||
function propFilter( props, specialEasing ) {
|
||
var index, name, easing, value, hooks;
|
||
|
||
// camelCase, specialEasing and expand cssHook pass
|
||
for ( index in props ) {
|
||
name = jQuery.camelCase( index );
|
||
easing = specialEasing[ name ];
|
||
value = props[ index ];
|
||
if ( jQuery.isArray( value ) ) {
|
||
easing = value[ 1 ];
|
||
value = props[ index ] = value[ 0 ];
|
||
}
|
||
|
||
if ( index !== name ) {
|
||
props[ name ] = value;
|
||
delete props[ index ];
|
||
}
|
||
|
||
hooks = jQuery.cssHooks[ name ];
|
||
if ( hooks && "expand" in hooks ) {
|
||
value = hooks.expand( value );
|
||
delete props[ name ];
|
||
|
||
// not quite $.extend, this wont overwrite keys already present.
|
||
// also - reusing 'index' from above because we have the correct "name"
|
||
for ( index in value ) {
|
||
if ( !( index in props ) ) {
|
||
props[ index ] = value[ index ];
|
||
specialEasing[ index ] = easing;
|
||
}
|
||
}
|
||
} else {
|
||
specialEasing[ name ] = easing;
|
||
}
|
||
}
|
||
}
|
||
|
||
function Animation( elem, properties, options ) {
|
||
var result,
|
||
stopped,
|
||
index = 0,
|
||
length = animationPrefilters.length,
|
||
deferred = jQuery.Deferred().always( function() {
|
||
// don't match elem in the :animated selector
|
||
delete tick.elem;
|
||
}),
|
||
tick = function() {
|
||
if ( stopped ) {
|
||
return false;
|
||
}
|
||
var currentTime = fxNow || createFxNow(),
|
||
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
|
||
// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
|
||
temp = remaining / animation.duration || 0,
|
||
percent = 1 - temp,
|
||
index = 0,
|
||
length = animation.tweens.length;
|
||
|
||
for ( ; index < length ; index++ ) {
|
||
animation.tweens[ index ].run( percent );
|
||
}
|
||
|
||
deferred.notifyWith( elem, [ animation, percent, remaining ]);
|
||
|
||
if ( percent < 1 && length ) {
|
||
return remaining;
|
||
} else {
|
||
deferred.resolveWith( elem, [ animation ] );
|
||
return false;
|
||
}
|
||
},
|
||
animation = deferred.promise({
|
||
elem: elem,
|
||
props: jQuery.extend( {}, properties ),
|
||
opts: jQuery.extend( true, { specialEasing: {} }, options ),
|
||
originalProperties: properties,
|
||
originalOptions: options,
|
||
startTime: fxNow || createFxNow(),
|
||
duration: options.duration,
|
||
tweens: [],
|
||
createTween: function( prop, end ) {
|
||
var tween = jQuery.Tween( elem, animation.opts, prop, end,
|
||
animation.opts.specialEasing[ prop ] || animation.opts.easing );
|
||
animation.tweens.push( tween );
|
||
return tween;
|
||
},
|
||
stop: function( gotoEnd ) {
|
||
var index = 0,
|
||
// if we are going to the end, we want to run all the tweens
|
||
// otherwise we skip this part
|
||
length = gotoEnd ? animation.tweens.length : 0;
|
||
if ( stopped ) {
|
||
return this;
|
||
}
|
||
stopped = true;
|
||
for ( ; index < length ; index++ ) {
|
||
animation.tweens[ index ].run( 1 );
|
||
}
|
||
|
||
// resolve when we played the last frame
|
||
// otherwise, reject
|
||
if ( gotoEnd ) {
|
||
deferred.resolveWith( elem, [ animation, gotoEnd ] );
|
||
} else {
|
||
deferred.rejectWith( elem, [ animation, gotoEnd ] );
|
||
}
|
||
return this;
|
||
}
|
||
}),
|
||
props = animation.props;
|
||
|
||
propFilter( props, animation.opts.specialEasing );
|
||
|
||
for ( ; index < length ; index++ ) {
|
||
result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
|
||
if ( result ) {
|
||
return result;
|
||
}
|
||
}
|
||
|
||
jQuery.map( props, createTween, animation );
|
||
|
||
if ( jQuery.isFunction( animation.opts.start ) ) {
|
||
animation.opts.start.call( elem, animation );
|
||
}
|
||
|
||
jQuery.fx.timer(
|
||
jQuery.extend( tick, {
|
||
elem: elem,
|
||
anim: animation,
|
||
queue: animation.opts.queue
|
||
})
|
||
);
|
||
|
||
// attach callbacks from options
|
||
return animation.progress( animation.opts.progress )
|
||
.done( animation.opts.done, animation.opts.complete )
|
||
.fail( animation.opts.fail )
|
||
.always( animation.opts.always );
|
||
}
|
||
|
||
jQuery.Animation = jQuery.extend( Animation, {
|
||
tweener: function( props, callback ) {
|
||
if ( jQuery.isFunction( props ) ) {
|
||
callback = props;
|
||
props = [ "*" ];
|
||
} else {
|
||
props = props.split(" ");
|
||
}
|
||
|
||
var prop,
|
||
index = 0,
|
||
length = props.length;
|
||
|
||
for ( ; index < length ; index++ ) {
|
||
prop = props[ index ];
|
||
tweeners[ prop ] = tweeners[ prop ] || [];
|
||
tweeners[ prop ].unshift( callback );
|
||
}
|
||
},
|
||
|
||
prefilter: function( callback, prepend ) {
|
||
if ( prepend ) {
|
||
animationPrefilters.unshift( callback );
|
||
} else {
|
||
animationPrefilters.push( callback );
|
||
}
|
||
}
|
||
});
|
||
|
||
jQuery.speed = function( speed, easing, fn ) {
|
||
var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
|
||
complete: fn || !fn && easing ||
|
||
jQuery.isFunction( speed ) && speed,
|
||
duration: speed,
|
||
easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
|
||
};
|
||
|
||
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
|
||
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
|
||
|
||
// normalize opt.queue - true/undefined/null -> "fx"
|
||
if ( opt.queue == null || opt.queue === true ) {
|
||
opt.queue = "fx";
|
||
}
|
||
|
||
// Queueing
|
||
opt.old = opt.complete;
|
||
|
||
opt.complete = function() {
|
||
if ( jQuery.isFunction( opt.old ) ) {
|
||
opt.old.call( this );
|
||
}
|
||
|
||
if ( opt.queue ) {
|
||
jQuery.dequeue( this, opt.queue );
|
||
}
|
||
};
|
||
|
||
return opt;
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
fadeTo: function( speed, to, easing, callback ) {
|
||
|
||
// show any hidden elements after setting opacity to 0
|
||
return this.filter( isHidden ).css( "opacity", 0 ).show()
|
||
|
||
// animate to the value specified
|
||
.end().animate({ opacity: to }, speed, easing, callback );
|
||
},
|
||
animate: function( prop, speed, easing, callback ) {
|
||
var empty = jQuery.isEmptyObject( prop ),
|
||
optall = jQuery.speed( speed, easing, callback ),
|
||
doAnimation = function() {
|
||
// Operate on a copy of prop so per-property easing won't be lost
|
||
var anim = Animation( this, jQuery.extend( {}, prop ), optall );
|
||
|
||
// Empty animations, or finishing resolves immediately
|
||
if ( empty || jQuery._data( this, "finish" ) ) {
|
||
anim.stop( true );
|
||
}
|
||
};
|
||
doAnimation.finish = doAnimation;
|
||
|
||
return empty || optall.queue === false ?
|
||
this.each( doAnimation ) :
|
||
this.queue( optall.queue, doAnimation );
|
||
},
|
||
stop: function( type, clearQueue, gotoEnd ) {
|
||
var stopQueue = function( hooks ) {
|
||
var stop = hooks.stop;
|
||
delete hooks.stop;
|
||
stop( gotoEnd );
|
||
};
|
||
|
||
if ( typeof type !== "string" ) {
|
||
gotoEnd = clearQueue;
|
||
clearQueue = type;
|
||
type = undefined;
|
||
}
|
||
if ( clearQueue && type !== false ) {
|
||
this.queue( type || "fx", [] );
|
||
}
|
||
|
||
return this.each(function() {
|
||
var dequeue = true,
|
||
index = type != null && type + "queueHooks",
|
||
timers = jQuery.timers,
|
||
data = jQuery._data( this );
|
||
|
||
if ( index ) {
|
||
if ( data[ index ] && data[ index ].stop ) {
|
||
stopQueue( data[ index ] );
|
||
}
|
||
} else {
|
||
for ( index in data ) {
|
||
if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
|
||
stopQueue( data[ index ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
for ( index = timers.length; index--; ) {
|
||
if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
|
||
timers[ index ].anim.stop( gotoEnd );
|
||
dequeue = false;
|
||
timers.splice( index, 1 );
|
||
}
|
||
}
|
||
|
||
// start the next in the queue if the last step wasn't forced
|
||
// timers currently will call their complete callbacks, which will dequeue
|
||
// but only if they were gotoEnd
|
||
if ( dequeue || !gotoEnd ) {
|
||
jQuery.dequeue( this, type );
|
||
}
|
||
});
|
||
},
|
||
finish: function( type ) {
|
||
if ( type !== false ) {
|
||
type = type || "fx";
|
||
}
|
||
return this.each(function() {
|
||
var index,
|
||
data = jQuery._data( this ),
|
||
queue = data[ type + "queue" ],
|
||
hooks = data[ type + "queueHooks" ],
|
||
timers = jQuery.timers,
|
||
length = queue ? queue.length : 0;
|
||
|
||
// enable finishing flag on private data
|
||
data.finish = true;
|
||
|
||
// empty the queue first
|
||
jQuery.queue( this, type, [] );
|
||
|
||
if ( hooks && hooks.stop ) {
|
||
hooks.stop.call( this, true );
|
||
}
|
||
|
||
// look for any active animations, and finish them
|
||
for ( index = timers.length; index--; ) {
|
||
if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
|
||
timers[ index ].anim.stop( true );
|
||
timers.splice( index, 1 );
|
||
}
|
||
}
|
||
|
||
// look for any animations in the old queue and finish them
|
||
for ( index = 0; index < length; index++ ) {
|
||
if ( queue[ index ] && queue[ index ].finish ) {
|
||
queue[ index ].finish.call( this );
|
||
}
|
||
}
|
||
|
||
// turn off finishing flag
|
||
delete data.finish;
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
|
||
var cssFn = jQuery.fn[ name ];
|
||
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
||
return speed == null || typeof speed === "boolean" ?
|
||
cssFn.apply( this, arguments ) :
|
||
this.animate( genFx( name, true ), speed, easing, callback );
|
||
};
|
||
});
|
||
|
||
// Generate shortcuts for custom animations
|
||
jQuery.each({
|
||
slideDown: genFx("show"),
|
||
slideUp: genFx("hide"),
|
||
slideToggle: genFx("toggle"),
|
||
fadeIn: { opacity: "show" },
|
||
fadeOut: { opacity: "hide" },
|
||
fadeToggle: { opacity: "toggle" }
|
||
}, function( name, props ) {
|
||
jQuery.fn[ name ] = function( speed, easing, callback ) {
|
||
return this.animate( props, speed, easing, callback );
|
||
};
|
||
});
|
||
|
||
jQuery.timers = [];
|
||
jQuery.fx.tick = function() {
|
||
var timer,
|
||
timers = jQuery.timers,
|
||
i = 0;
|
||
|
||
fxNow = jQuery.now();
|
||
|
||
for ( ; i < timers.length; i++ ) {
|
||
timer = timers[ i ];
|
||
// Checks the timer has not already been removed
|
||
if ( !timer() && timers[ i ] === timer ) {
|
||
timers.splice( i--, 1 );
|
||
}
|
||
}
|
||
|
||
if ( !timers.length ) {
|
||
jQuery.fx.stop();
|
||
}
|
||
fxNow = undefined;
|
||
};
|
||
|
||
jQuery.fx.timer = function( timer ) {
|
||
jQuery.timers.push( timer );
|
||
if ( timer() ) {
|
||
jQuery.fx.start();
|
||
} else {
|
||
jQuery.timers.pop();
|
||
}
|
||
};
|
||
|
||
jQuery.fx.interval = 13;
|
||
|
||
jQuery.fx.start = function() {
|
||
if ( !timerId ) {
|
||
timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
|
||
}
|
||
};
|
||
|
||
jQuery.fx.stop = function() {
|
||
clearInterval( timerId );
|
||
timerId = null;
|
||
};
|
||
|
||
jQuery.fx.speeds = {
|
||
slow: 600,
|
||
fast: 200,
|
||
// Default speed
|
||
_default: 400
|
||
};
|
||
|
||
|
||
// Based off of the plugin by Clint Helfers, with permission.
|
||
// http://blindsignals.com/index.php/2009/07/jquery-delay/
|
||
jQuery.fn.delay = function( time, type ) {
|
||
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
|
||
type = type || "fx";
|
||
|
||
return this.queue( type, function( next, hooks ) {
|
||
var timeout = setTimeout( next, time );
|
||
hooks.stop = function() {
|
||
clearTimeout( timeout );
|
||
};
|
||
});
|
||
};
|
||
|
||
|
||
(function() {
|
||
// Minified: var a,b,c,d,e
|
||
var input, div, select, a, opt;
|
||
|
||
// Setup
|
||
div = document.createElement( "div" );
|
||
div.setAttribute( "className", "t" );
|
||
div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
|
||
a = div.getElementsByTagName("a")[ 0 ];
|
||
|
||
// First batch of tests.
|
||
select = document.createElement("select");
|
||
opt = select.appendChild( document.createElement("option") );
|
||
input = div.getElementsByTagName("input")[ 0 ];
|
||
|
||
a.style.cssText = "top:1px";
|
||
|
||
// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
|
||
support.getSetAttribute = div.className !== "t";
|
||
|
||
// Get the style information from getAttribute
|
||
// (IE uses .cssText instead)
|
||
support.style = /top/.test( a.getAttribute("style") );
|
||
|
||
// Make sure that URLs aren't manipulated
|
||
// (IE normalizes it by default)
|
||
support.hrefNormalized = a.getAttribute("href") === "/a";
|
||
|
||
// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
|
||
support.checkOn = !!input.value;
|
||
|
||
// 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)
|
||
support.optSelected = opt.selected;
|
||
|
||
// Tests for enctype support on a form (#6743)
|
||
support.enctype = !!document.createElement("form").enctype;
|
||
|
||
// 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;
|
||
|
||
// Support: IE8 only
|
||
// Check if we can trust getAttribute("value")
|
||
input = document.createElement( "input" );
|
||
input.setAttribute( "value", "" );
|
||
support.input = input.getAttribute( "value" ) === "";
|
||
|
||
// Check if an input maintains its value after becoming a radio
|
||
input.value = "t";
|
||
input.setAttribute( "type", "radio" );
|
||
support.radioValue = input.value === "t";
|
||
})();
|
||
|
||
|
||
var rreturn = /\r/g;
|
||
|
||
jQuery.fn.extend({
|
||
val: function( value ) {
|
||
var hooks, ret, isFunction,
|
||
elem = this[0];
|
||
|
||
if ( !arguments.length ) {
|
||
if ( elem ) {
|
||
hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
|
||
|
||
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
|
||
return ret;
|
||
}
|
||
|
||
ret = elem.value;
|
||
|
||
return typeof ret === "string" ?
|
||
// handle most common string cases
|
||
ret.replace(rreturn, "") :
|
||
// handle cases where value is null/undef or number
|
||
ret == null ? "" : ret;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
isFunction = jQuery.isFunction( value );
|
||
|
||
return this.each(function( i ) {
|
||
var val;
|
||
|
||
if ( this.nodeType !== 1 ) {
|
||
return;
|
||
}
|
||
|
||
if ( isFunction ) {
|
||
val = value.call( this, i, jQuery( this ).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.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
|
||
|
||
// 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 ) {
|
||
var val = jQuery.find.attr( elem, "value" );
|
||
return val != null ?
|
||
val :
|
||
// Support: IE10-11+
|
||
// option.text throws exceptions (#14686, #14858)
|
||
jQuery.trim( jQuery.text( elem ) );
|
||
}
|
||
},
|
||
select: {
|
||
get: function( elem ) {
|
||
var value, option,
|
||
options = elem.options,
|
||
index = elem.selectedIndex,
|
||
one = elem.type === "select-one" || index < 0,
|
||
values = one ? null : [],
|
||
max = one ? index + 1 : options.length,
|
||
i = index < 0 ?
|
||
max :
|
||
one ? index : 0;
|
||
|
||
// Loop through all the selected options
|
||
for ( ; i < max; i++ ) {
|
||
option = options[ i ];
|
||
|
||
// oldIE doesn't update selected after form reset (#2551)
|
||
if ( ( option.selected || i === index ) &&
|
||
// Don't return options that are disabled or in a disabled optgroup
|
||
( 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 );
|
||
}
|
||
}
|
||
|
||
return values;
|
||
},
|
||
|
||
set: function( elem, value ) {
|
||
var optionSet, option,
|
||
options = elem.options,
|
||
values = jQuery.makeArray( value ),
|
||
i = options.length;
|
||
|
||
while ( i-- ) {
|
||
option = options[ i ];
|
||
|
||
if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {
|
||
|
||
// Support: IE6
|
||
// When new option element is added to select box we need to
|
||
// force reflow of newly added node in order to workaround delay
|
||
// of initialization properties
|
||
try {
|
||
option.selected = optionSet = true;
|
||
|
||
} catch ( _ ) {
|
||
|
||
// Will be executed only in IE6
|
||
option.scrollHeight;
|
||
}
|
||
|
||
} else {
|
||
option.selected = false;
|
||
}
|
||
}
|
||
|
||
// Force browsers to behave consistently when non-matching value is set
|
||
if ( !optionSet ) {
|
||
elem.selectedIndex = -1;
|
||
}
|
||
|
||
return options;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Radios and checkboxes getter/setter
|
||
jQuery.each([ "radio", "checkbox" ], function() {
|
||
jQuery.valHooks[ this ] = {
|
||
set: function( elem, value ) {
|
||
if ( jQuery.isArray( value ) ) {
|
||
return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
|
||
}
|
||
}
|
||
};
|
||
if ( !support.checkOn ) {
|
||
jQuery.valHooks[ this ].get = function( elem ) {
|
||
// Support: Webkit
|
||
// "" is returned instead of "on" if a value isn't specified
|
||
return elem.getAttribute("value") === null ? "on" : elem.value;
|
||
};
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
var nodeHook, boolHook,
|
||
attrHandle = jQuery.expr.attrHandle,
|
||
ruseDefault = /^(?:checked|selected)$/i,
|
||
getSetAttribute = support.getSetAttribute,
|
||
getSetInput = support.input;
|
||
|
||
jQuery.fn.extend({
|
||
attr: function( name, value ) {
|
||
return access( this, jQuery.attr, name, value, arguments.length > 1 );
|
||
},
|
||
|
||
removeAttr: function( name ) {
|
||
return this.each(function() {
|
||
jQuery.removeAttr( this, name );
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.extend({
|
||
attr: function( elem, name, value ) {
|
||
var hooks, ret,
|
||
nType = elem.nodeType;
|
||
|
||
// don't get/set attributes on text, comment and attribute nodes
|
||
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
|
||
return;
|
||
}
|
||
|
||
// Fallback to prop when attributes are not supported
|
||
if ( typeof elem.getAttribute === strundefined ) {
|
||
return jQuery.prop( elem, name, value );
|
||
}
|
||
|
||
// All attributes are lowercase
|
||
// Grab necessary hook if one is defined
|
||
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
|
||
name = name.toLowerCase();
|
||
hooks = jQuery.attrHooks[ name ] ||
|
||
( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
|
||
}
|
||
|
||
if ( value !== undefined ) {
|
||
|
||
if ( value === null ) {
|
||
jQuery.removeAttr( elem, name );
|
||
|
||
} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
|
||
return ret;
|
||
|
||
} else {
|
||
elem.setAttribute( name, value + "" );
|
||
return value;
|
||
}
|
||
|
||
} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
|
||
return ret;
|
||
|
||
} else {
|
||
ret = jQuery.find.attr( elem, name );
|
||
|
||
// Non-existent attributes return null, we normalize to undefined
|
||
return ret == null ?
|
||
undefined :
|
||
ret;
|
||
}
|
||
},
|
||
|
||
removeAttr: function( elem, value ) {
|
||
var name, propName,
|
||
i = 0,
|
||
attrNames = value && value.match( rnotwhite );
|
||
|
||
if ( attrNames && elem.nodeType === 1 ) {
|
||
while ( (name = attrNames[i++]) ) {
|
||
propName = jQuery.propFix[ name ] || name;
|
||
|
||
// Boolean attributes get special treatment (#10870)
|
||
if ( jQuery.expr.match.bool.test( name ) ) {
|
||
// Set corresponding property to false
|
||
if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
|
||
elem[ propName ] = false;
|
||
// Support: IE<9
|
||
// Also clear defaultChecked/defaultSelected (if appropriate)
|
||
} else {
|
||
elem[ jQuery.camelCase( "default-" + name ) ] =
|
||
elem[ propName ] = false;
|
||
}
|
||
|
||
// See #9699 for explanation of this approach (setting first, then removal)
|
||
} else {
|
||
jQuery.attr( elem, name, "" );
|
||
}
|
||
|
||
elem.removeAttribute( getSetAttribute ? name : propName );
|
||
}
|
||
}
|
||
},
|
||
|
||
attrHooks: {
|
||
type: {
|
||
set: function( elem, value ) {
|
||
if ( !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 default in case type is set after value during creation
|
||
var val = elem.value;
|
||
elem.setAttribute( "type", value );
|
||
if ( val ) {
|
||
elem.value = val;
|
||
}
|
||
return value;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Hook for boolean attributes
|
||
boolHook = {
|
||
set: function( elem, value, name ) {
|
||
if ( value === false ) {
|
||
// Remove boolean attributes when set to false
|
||
jQuery.removeAttr( elem, name );
|
||
} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
|
||
// IE<8 needs the *property* name
|
||
elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
|
||
|
||
// Use defaultChecked and defaultSelected for oldIE
|
||
} else {
|
||
elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
|
||
}
|
||
|
||
return name;
|
||
}
|
||
};
|
||
|
||
// Retrieve booleans specially
|
||
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
|
||
|
||
var getter = attrHandle[ name ] || jQuery.find.attr;
|
||
|
||
attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
|
||
function( elem, name, isXML ) {
|
||
var ret, handle;
|
||
if ( !isXML ) {
|
||
// Avoid an infinite loop by temporarily removing this function from the getter
|
||
handle = attrHandle[ name ];
|
||
attrHandle[ name ] = ret;
|
||
ret = getter( elem, name, isXML ) != null ?
|
||
name.toLowerCase() :
|
||
null;
|
||
attrHandle[ name ] = handle;
|
||
}
|
||
return ret;
|
||
} :
|
||
function( elem, name, isXML ) {
|
||
if ( !isXML ) {
|
||
return elem[ jQuery.camelCase( "default-" + name ) ] ?
|
||
name.toLowerCase() :
|
||
null;
|
||
}
|
||
};
|
||
});
|
||
|
||
// fix oldIE attroperties
|
||
if ( !getSetInput || !getSetAttribute ) {
|
||
jQuery.attrHooks.value = {
|
||
set: function( elem, value, name ) {
|
||
if ( jQuery.nodeName( elem, "input" ) ) {
|
||
// Does not return so that setAttribute is also used
|
||
elem.defaultValue = value;
|
||
} else {
|
||
// Use nodeHook if defined (#1954); otherwise setAttribute is fine
|
||
return nodeHook && nodeHook.set( elem, value, name );
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
// IE6/7 do not support getting/setting some attributes with get/setAttribute
|
||
if ( !getSetAttribute ) {
|
||
|
||
// Use this for any attribute in IE6/7
|
||
// This fixes almost every IE6/7 issue
|
||
nodeHook = {
|
||
set: function( elem, value, name ) {
|
||
// Set the existing or create a new attribute node
|
||
var ret = elem.getAttributeNode( name );
|
||
if ( !ret ) {
|
||
elem.setAttributeNode(
|
||
(ret = elem.ownerDocument.createAttribute( name ))
|
||
);
|
||
}
|
||
|
||
ret.value = value += "";
|
||
|
||
// Break association with cloned elements by also using setAttribute (#9646)
|
||
if ( name === "value" || value === elem.getAttribute( name ) ) {
|
||
return value;
|
||
}
|
||
}
|
||
};
|
||
|
||
// Some attributes are constructed with empty-string values when not defined
|
||
attrHandle.id = attrHandle.name = attrHandle.coords =
|
||
function( elem, name, isXML ) {
|
||
var ret;
|
||
if ( !isXML ) {
|
||
return (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
|
||
ret.value :
|
||
null;
|
||
}
|
||
};
|
||
|
||
// Fixing value retrieval on a button requires this module
|
||
jQuery.valHooks.button = {
|
||
get: function( elem, name ) {
|
||
var ret = elem.getAttributeNode( name );
|
||
if ( ret && ret.specified ) {
|
||
return ret.value;
|
||
}
|
||
},
|
||
set: nodeHook.set
|
||
};
|
||
|
||
// Set contenteditable to false on removals(#10429)
|
||
// Setting to empty string throws an error as an invalid value
|
||
jQuery.attrHooks.contenteditable = {
|
||
set: function( elem, value, name ) {
|
||
nodeHook.set( elem, value === "" ? false : value, name );
|
||
}
|
||
};
|
||
|
||
// 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 ] = {
|
||
set: function( elem, value ) {
|
||
if ( value === "" ) {
|
||
elem.setAttribute( name, "auto" );
|
||
return value;
|
||
}
|
||
}
|
||
};
|
||
});
|
||
}
|
||
|
||
if ( !support.style ) {
|
||
jQuery.attrHooks.style = {
|
||
get: function( elem ) {
|
||
// Return undefined in the case of empty string
|
||
// Note: IE uppercases css property names, but if we were to .toLowerCase()
|
||
// .cssText, that would destroy case senstitivity in URL's, like in "background"
|
||
return elem.style.cssText || undefined;
|
||
},
|
||
set: function( elem, value ) {
|
||
return ( elem.style.cssText = value + "" );
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
|
||
|
||
var rfocusable = /^(?:input|select|textarea|button|object)$/i,
|
||
rclickable = /^(?:a|area)$/i;
|
||
|
||
jQuery.fn.extend({
|
||
prop: function( name, value ) {
|
||
return access( this, jQuery.prop, name, value, arguments.length > 1 );
|
||
},
|
||
|
||
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 ) {}
|
||
});
|
||
}
|
||
});
|
||
|
||
jQuery.extend({
|
||
propFix: {
|
||
"for": "htmlFor",
|
||
"class": "className"
|
||
},
|
||
|
||
prop: function( elem, name, value ) {
|
||
var ret, hooks, notxml,
|
||
nType = elem.nodeType;
|
||
|
||
// don't get/set properties on text, comment and attribute nodes
|
||
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
|
||
return;
|
||
}
|
||
|
||
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
|
||
|
||
if ( notxml ) {
|
||
// Fix name and attach hooks
|
||
name = jQuery.propFix[ name ] || name;
|
||
hooks = jQuery.propHooks[ name ];
|
||
}
|
||
|
||
if ( value !== undefined ) {
|
||
return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
|
||
ret :
|
||
( elem[ name ] = value );
|
||
|
||
} else {
|
||
return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
|
||
ret :
|
||
elem[ name ];
|
||
}
|
||
},
|
||
|
||
propHooks: {
|
||
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/
|
||
// Use proper attribute retrieval(#12072)
|
||
var tabindex = jQuery.find.attr( elem, "tabindex" );
|
||
|
||
return tabindex ?
|
||
parseInt( tabindex, 10 ) :
|
||
rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
|
||
0 :
|
||
-1;
|
||
}
|
||
}
|
||
}
|
||
});
|
||
|
||
// Some attributes require a special call on IE
|
||
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
|
||
if ( !support.hrefNormalized ) {
|
||
// href/src property should get the full normalized URL (#10299/#12915)
|
||
jQuery.each([ "href", "src" ], function( i, name ) {
|
||
jQuery.propHooks[ name ] = {
|
||
get: function( elem ) {
|
||
return elem.getAttribute( name, 4 );
|
||
}
|
||
};
|
||
});
|
||
}
|
||
|
||
// Support: Safari, IE9+
|
||
// mis-reports the default selected property of an option
|
||
// Accessing the parent's selectedIndex property fixes it
|
||
if ( !support.optSelected ) {
|
||
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;
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
};
|
||
}
|
||
|
||
jQuery.each([
|
||
"tabIndex",
|
||
"readOnly",
|
||
"maxLength",
|
||
"cellSpacing",
|
||
"cellPadding",
|
||
"rowSpan",
|
||
"colSpan",
|
||
"useMap",
|
||
"frameBorder",
|
||
"contentEditable"
|
||
], function() {
|
||
jQuery.propFix[ this.toLowerCase() ] = this;
|
||
});
|
||
|
||
// IE6/7 call enctype encoding
|
||
if ( !support.enctype ) {
|
||
jQuery.propFix.enctype = "encoding";
|
||
}
|
||
|
||
|
||
|
||
|
||
var rclass = /[\t\r\n\f]/g;
|
||
|
||
jQuery.fn.extend({
|
||
addClass: function( value ) {
|
||
var classes, elem, cur, clazz, j, finalValue,
|
||
i = 0,
|
||
len = this.length,
|
||
proceed = typeof value === "string" && value;
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each(function( j ) {
|
||
jQuery( this ).addClass( value.call( this, j, this.className ) );
|
||
});
|
||
}
|
||
|
||
if ( proceed ) {
|
||
// The disjunction here is for better compressibility (see removeClass)
|
||
classes = ( value || "" ).match( rnotwhite ) || [];
|
||
|
||
for ( ; i < len; i++ ) {
|
||
elem = this[ i ];
|
||
cur = elem.nodeType === 1 && ( elem.className ?
|
||
( " " + elem.className + " " ).replace( rclass, " " ) :
|
||
" "
|
||
);
|
||
|
||
if ( cur ) {
|
||
j = 0;
|
||
while ( (clazz = classes[j++]) ) {
|
||
if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
|
||
cur += clazz + " ";
|
||
}
|
||
}
|
||
|
||
// only assign if different to avoid unneeded rendering.
|
||
finalValue = jQuery.trim( cur );
|
||
if ( elem.className !== finalValue ) {
|
||
elem.className = finalValue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
removeClass: function( value ) {
|
||
var classes, elem, cur, clazz, j, finalValue,
|
||
i = 0,
|
||
len = this.length,
|
||
proceed = arguments.length === 0 || typeof value === "string" && value;
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each(function( j ) {
|
||
jQuery( this ).removeClass( value.call( this, j, this.className ) );
|
||
});
|
||
}
|
||
if ( proceed ) {
|
||
classes = ( value || "" ).match( rnotwhite ) || [];
|
||
|
||
for ( ; i < len; i++ ) {
|
||
elem = this[ i ];
|
||
// This expression is here for better compressibility (see addClass)
|
||
cur = elem.nodeType === 1 && ( elem.className ?
|
||
( " " + elem.className + " " ).replace( rclass, " " ) :
|
||
""
|
||
);
|
||
|
||
if ( cur ) {
|
||
j = 0;
|
||
while ( (clazz = classes[j++]) ) {
|
||
// Remove *all* instances
|
||
while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
|
||
cur = cur.replace( " " + clazz + " ", " " );
|
||
}
|
||
}
|
||
|
||
// only assign if different to avoid unneeded rendering.
|
||
finalValue = value ? jQuery.trim( cur ) : "";
|
||
if ( elem.className !== finalValue ) {
|
||
elem.className = finalValue;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
toggleClass: function( value, stateVal ) {
|
||
var type = typeof value;
|
||
|
||
if ( typeof stateVal === "boolean" && type === "string" ) {
|
||
return stateVal ? this.addClass( value ) : this.removeClass( value );
|
||
}
|
||
|
||
if ( jQuery.isFunction( value ) ) {
|
||
return this.each(function( i ) {
|
||
jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
|
||
});
|
||
}
|
||
|
||
return this.each(function() {
|
||
if ( type === "string" ) {
|
||
// toggle individual class names
|
||
var className,
|
||
i = 0,
|
||
self = jQuery( this ),
|
||
classNames = value.match( rnotwhite ) || [];
|
||
|
||
while ( (className = classNames[ i++ ]) ) {
|
||
// check each className given, space separated list
|
||
if ( self.hasClass( className ) ) {
|
||
self.removeClass( className );
|
||
} else {
|
||
self.addClass( className );
|
||
}
|
||
}
|
||
|
||
// Toggle whole class name
|
||
} else if ( type === strundefined || type === "boolean" ) {
|
||
if ( this.className ) {
|
||
// store className if set
|
||
jQuery._data( this, "__className__", this.className );
|
||
}
|
||
|
||
// If the element has a class name or if we're passed "false",
|
||
// then remove the whole classname (if there was one, the above saved it).
|
||
// Otherwise bring back whatever was previously saved (if anything),
|
||
// falling back to the empty string if nothing was stored.
|
||
this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
|
||
}
|
||
});
|
||
},
|
||
|
||
hasClass: function( selector ) {
|
||
var className = " " + selector + " ",
|
||
i = 0,
|
||
l = this.length;
|
||
for ( ; i < l; i++ ) {
|
||
if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
// Return jQuery for attributes-only inclusion
|
||
|
||
|
||
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 contextmenu").split(" "), function( i, name ) {
|
||
|
||
// Handle event binding
|
||
jQuery.fn[ name ] = function( data, fn ) {
|
||
return arguments.length > 0 ?
|
||
this.on( name, null, data, fn ) :
|
||
this.trigger( name );
|
||
};
|
||
});
|
||
|
||
jQuery.fn.extend({
|
||
hover: function( fnOver, fnOut ) {
|
||
return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
|
||
},
|
||
|
||
bind: function( types, data, fn ) {
|
||
return this.on( types, null, data, fn );
|
||
},
|
||
unbind: function( types, fn ) {
|
||
return this.off( types, null, fn );
|
||
},
|
||
|
||
delegate: function( selector, types, data, fn ) {
|
||
return this.on( types, selector, data, fn );
|
||
},
|
||
undelegate: function( selector, types, fn ) {
|
||
// ( namespace ) or ( selector, types [, fn] )
|
||
return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
|
||
}
|
||
});
|
||
|
||
|
||
var nonce = jQuery.now();
|
||
|
||
var rquery = (/\?/);
|
||
|
||
|
||
|
||
var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
|
||
|
||
jQuery.parseJSON = function( data ) {
|
||
// Attempt to parse using the native JSON parser first
|
||
if ( window.JSON && window.JSON.parse ) {
|
||
// Support: Android 2.3
|
||
// Workaround failure to string-cast null input
|
||
return window.JSON.parse( data + "" );
|
||
}
|
||
|
||
var requireNonComma,
|
||
depth = null,
|
||
str = jQuery.trim( data + "" );
|
||
|
||
// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
|
||
// after removing valid tokens
|
||
return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
|
||
|
||
// Force termination if we see a misplaced comma
|
||
if ( requireNonComma && comma ) {
|
||
depth = 0;
|
||
}
|
||
|
||
// Perform no more replacements after returning to outermost depth
|
||
if ( depth === 0 ) {
|
||
return token;
|
||
}
|
||
|
||
// Commas must not follow "[", "{", or ","
|
||
requireNonComma = open || comma;
|
||
|
||
// Determine new depth
|
||
// array/object open ("[" or "{"): depth += true - false (increment)
|
||
// array/object close ("]" or "}"): depth += false - true (decrement)
|
||
// other cases ("," or primitive): depth += true - true (numeric cast)
|
||
depth += !close - !open;
|
||
|
||
// Remove this token
|
||
return "";
|
||
}) ) ?
|
||
( Function( "return " + str ) )() :
|
||
jQuery.error( "Invalid JSON: " + data );
|
||
};
|
||
|
||
|
||
// Cross-browser xml parsing
|
||
jQuery.parseXML = function( data ) {
|
||
var xml, tmp;
|
||
if ( !data || typeof data !== "string" ) {
|
||
return null;
|
||
}
|
||
try {
|
||
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 );
|
||
}
|
||
} catch( e ) {
|
||
xml = undefined;
|
||
}
|
||
if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
|
||
jQuery.error( "Invalid XML: " + data );
|
||
}
|
||
return xml;
|
||
};
|
||
|
||
|
||
var
|
||
// Document location
|
||
ajaxLocParts,
|
||
ajaxLocation,
|
||
|
||
rhash = /#.*$/,
|
||
rts = /([?&])_=[^&]*/,
|
||
rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
|
||
// #7653, #8125, #8152: local protocol detection
|
||
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
|
||
rnoContent = /^(?:GET|HEAD)$/,
|
||
rprotocol = /^\/\//,
|
||
rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
|
||
|
||
/* Prefilters
|
||
* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
|
||
* 2) These are called:
|
||
* - BEFORE asking for a transport
|
||
* - AFTER param serialization (s.data is a string if s.processData is true)
|
||
* 3) key is the dataType
|
||
* 4) the catchall symbol "*" can be used
|
||
* 5) execution will start with transport dataType and THEN continue down to "*" if needed
|
||
*/
|
||
prefilters = {},
|
||
|
||
/* Transports bindings
|
||
* 1) key is the dataType
|
||
* 2) the catchall symbol "*" can be used
|
||
* 3) selection will start with transport dataType and THEN go to "*" if needed
|
||
*/
|
||
transports = {},
|
||
|
||
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
|
||
allTypes = "*/".concat("*");
|
||
|
||
// #8138, IE may throw an exception when accessing
|
||
// a field from window.location if document.domain has been set
|
||
try {
|
||
ajaxLocation = location.href;
|
||
} catch( e ) {
|
||
// Use the href attribute of an A element
|
||
// since IE will modify it given document.location
|
||
ajaxLocation = document.createElement( "a" );
|
||
ajaxLocation.href = "";
|
||
ajaxLocation = ajaxLocation.href;
|
||
}
|
||
|
||
// Segment location into parts
|
||
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
|
||
|
||
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
|
||
function addToPrefiltersOrTransports( structure ) {
|
||
|
||
// dataTypeExpression is optional and defaults to "*"
|
||
return function( dataTypeExpression, func ) {
|
||
|
||
if ( typeof dataTypeExpression !== "string" ) {
|
||
func = dataTypeExpression;
|
||
dataTypeExpression = "*";
|
||
}
|
||
|
||
var dataType,
|
||
i = 0,
|
||
dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
|
||
|
||
if ( jQuery.isFunction( func ) ) {
|
||
// For each dataType in the dataTypeExpression
|
||
while ( (dataType = dataTypes[i++]) ) {
|
||
// Prepend if requested
|
||
if ( dataType.charAt( 0 ) === "+" ) {
|
||
dataType = dataType.slice( 1 ) || "*";
|
||
(structure[ dataType ] = structure[ dataType ] || []).unshift( func );
|
||
|
||
// Otherwise append
|
||
} else {
|
||
(structure[ dataType ] = structure[ dataType ] || []).push( func );
|
||
}
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
// Base inspection function for prefilters and transports
|
||
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
|
||
|
||
var inspected = {},
|
||
seekingTransport = ( structure === transports );
|
||
|
||
function inspect( dataType ) {
|
||
var selected;
|
||
inspected[ dataType ] = true;
|
||
jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
|
||
var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
|
||
if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
|
||
options.dataTypes.unshift( dataTypeOrTransport );
|
||
inspect( dataTypeOrTransport );
|
||
return false;
|
||
} else if ( seekingTransport ) {
|
||
return !( selected = dataTypeOrTransport );
|
||
}
|
||
});
|
||
return selected;
|
||
}
|
||
|
||
return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
|
||
}
|
||
|
||
// A special extend for ajax options
|
||
// that takes "flat" options (not to be deep extended)
|
||
// Fixes #9887
|
||
function ajaxExtend( target, src ) {
|
||
var deep, key,
|
||
flatOptions = jQuery.ajaxSettings.flatOptions || {};
|
||
|
||
for ( key in src ) {
|
||
if ( src[ key ] !== undefined ) {
|
||
( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
|
||
}
|
||
}
|
||
if ( deep ) {
|
||
jQuery.extend( true, target, deep );
|
||
}
|
||
|
||
return target;
|
||
}
|
||
|
||
/* Handles responses to an ajax request:
|
||
* - finds the right dataType (mediates between content-type and expected dataType)
|
||
* - returns the corresponding response
|
||
*/
|
||
function ajaxHandleResponses( s, jqXHR, responses ) {
|
||
var firstDataType, ct, finalDataType, type,
|
||
contents = s.contents,
|
||
dataTypes = s.dataTypes;
|
||
|
||
// Remove auto dataType and get content-type in the process
|
||
while ( dataTypes[ 0 ] === "*" ) {
|
||
dataTypes.shift();
|
||
if ( ct === undefined ) {
|
||
ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
|
||
}
|
||
}
|
||
|
||
// Check if we're dealing with a known content-type
|
||
if ( ct ) {
|
||
for ( type in contents ) {
|
||
if ( contents[ type ] && contents[ type ].test( ct ) ) {
|
||
dataTypes.unshift( type );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Check to see if we have a response for the expected dataType
|
||
if ( dataTypes[ 0 ] in responses ) {
|
||
finalDataType = dataTypes[ 0 ];
|
||
} else {
|
||
// Try convertible dataTypes
|
||
for ( type in responses ) {
|
||
if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
|
||
finalDataType = type;
|
||
break;
|
||
}
|
||
if ( !firstDataType ) {
|
||
firstDataType = type;
|
||
}
|
||
}
|
||
// Or just use first one
|
||
finalDataType = finalDataType || firstDataType;
|
||
}
|
||
|
||
// If we found a dataType
|
||
// We add the dataType to the list if needed
|
||
// and return the corresponding response
|
||
if ( finalDataType ) {
|
||
if ( finalDataType !== dataTypes[ 0 ] ) {
|
||
dataTypes.unshift( finalDataType );
|
||
}
|
||
return responses[ finalDataType ];
|
||
}
|
||
}
|
||
|
||
/* Chain conversions given the request and the original response
|
||
* Also sets the responseXXX fields on the jqXHR instance
|
||
*/
|
||
function ajaxConvert( s, response, jqXHR, isSuccess ) {
|
||
var conv2, current, conv, tmp, prev,
|
||
converters = {},
|
||
// Work with a copy of dataTypes in case we need to modify it for conversion
|
||
dataTypes = s.dataTypes.slice();
|
||
|
||
// Create converters map with lowercased keys
|
||
if ( dataTypes[ 1 ] ) {
|
||
for ( conv in s.converters ) {
|
||
converters[ conv.toLowerCase() ] = s.converters[ conv ];
|
||
}
|
||
}
|
||
|
||
current = dataTypes.shift();
|
||
|
||
// Convert to each sequential dataType
|
||
while ( current ) {
|
||
|
||
if ( s.responseFields[ current ] ) {
|
||
jqXHR[ s.responseFields[ current ] ] = response;
|
||
}
|
||
|
||
// Apply the dataFilter if provided
|
||
if ( !prev && isSuccess && s.dataFilter ) {
|
||
response = s.dataFilter( response, s.dataType );
|
||
}
|
||
|
||
prev = current;
|
||
current = dataTypes.shift();
|
||
|
||
if ( current ) {
|
||
|
||
// There's only work to do if current dataType is non-auto
|
||
if ( current === "*" ) {
|
||
|
||
current = prev;
|
||
|
||
// Convert response if prev dataType is non-auto and differs from current
|
||
} else if ( prev !== "*" && prev !== current ) {
|
||
|
||
// Seek a direct converter
|
||
conv = converters[ prev + " " + current ] || converters[ "* " + current ];
|
||
|
||
// If none found, seek a pair
|
||
if ( !conv ) {
|
||
for ( conv2 in converters ) {
|
||
|
||
// If conv2 outputs current
|
||
tmp = conv2.split( " " );
|
||
if ( tmp[ 1 ] === current ) {
|
||
|
||
// If prev can be converted to accepted input
|
||
conv = converters[ prev + " " + tmp[ 0 ] ] ||
|
||
converters[ "* " + tmp[ 0 ] ];
|
||
if ( conv ) {
|
||
// Condense equivalence converters
|
||
if ( conv === true ) {
|
||
conv = converters[ conv2 ];
|
||
|
||
// Otherwise, insert the intermediate dataType
|
||
} else if ( converters[ conv2 ] !== true ) {
|
||
current = tmp[ 0 ];
|
||
dataTypes.unshift( tmp[ 1 ] );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Apply converter (if not an equivalence)
|
||
if ( conv !== true ) {
|
||
|
||
// Unless errors are allowed to bubble, catch and return them
|
||
if ( conv && s[ "throws" ] ) {
|
||
response = conv( response );
|
||
} else {
|
||
try {
|
||
response = conv( response );
|
||
} catch ( e ) {
|
||
return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return { state: "success", data: response };
|
||
}
|
||
|
||
jQuery.extend({
|
||
|
||
// Counter for holding the number of active queries
|
||
active: 0,
|
||
|
||
// Last-Modified header cache for next request
|
||
lastModified: {},
|
||
etag: {},
|
||
|
||
ajaxSettings: {
|
||
url: ajaxLocation,
|
||
type: "GET",
|
||
isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
|
||
global: true,
|
||
processData: true,
|
||
async: true,
|
||
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
|
||
/*
|
||
timeout: 0,
|
||
data: null,
|
||
dataType: null,
|
||
username: null,
|
||
password: null,
|
||
cache: null,
|
||
throws: false,
|
||
traditional: false,
|
||
headers: {},
|
||
*/
|
||
|
||
accepts: {
|
||
"*": allTypes,
|
||
text: "text/plain",
|
||
html: "text/html",
|
||
xml: "application/xml, text/xml",
|
||
json: "application/json, text/javascript"
|
||
},
|
||
|
||
contents: {
|
||
xml: /xml/,
|
||
html: /html/,
|
||
json: /json/
|
||
},
|
||
|
||
responseFields: {
|
||
xml: "responseXML",
|
||
text: "responseText",
|
||
json: "responseJSON"
|
||
},
|
||
|
||
// Data converters
|
||
// Keys separate source (or catchall "*") and destination types with a single space
|
||
converters: {
|
||
|
||
// Convert anything to text
|
||
"* text": String,
|
||
|
||
// Text to html (true = no transformation)
|
||
"text html": true,
|
||
|
||
// Evaluate text as a json expression
|
||
"text json": jQuery.parseJSON,
|
||
|
||
// Parse text as xml
|
||
"text xml": jQuery.parseXML
|
||
},
|
||
|
||
// For options that shouldn't be deep extended:
|
||
// you can add your own custom options here if
|
||
// and when you create one that shouldn't be
|
||
// deep extended (see ajaxExtend)
|
||
flatOptions: {
|
||
url: true,
|
||
context: true
|
||
}
|
||
},
|
||
|
||
// Creates a full fledged settings object into target
|
||
// with both ajaxSettings and settings fields.
|
||
// If target is omitted, writes into ajaxSettings.
|
||
ajaxSetup: function( target, settings ) {
|
||
return settings ?
|
||
|
||
// Building a settings object
|
||
ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
|
||
|
||
// Extending ajaxSettings
|
||
ajaxExtend( jQuery.ajaxSettings, target );
|
||
},
|
||
|
||
ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
|
||
ajaxTransport: addToPrefiltersOrTransports( transports ),
|
||
|
||
// Main method
|
||
ajax: function( url, options ) {
|
||
|
||
// If url is an object, simulate pre-1.5 signature
|
||
if ( typeof url === "object" ) {
|
||
options = url;
|
||
url = undefined;
|
||
}
|
||
|
||
// Force options to be an object
|
||
options = options || {};
|
||
|
||
var // Cross-domain detection vars
|
||
parts,
|
||
// Loop variable
|
||
i,
|
||
// URL without anti-cache param
|
||
cacheURL,
|
||
// Response headers as string
|
||
responseHeadersString,
|
||
// timeout handle
|
||
timeoutTimer,
|
||
|
||
// To know if global events are to be dispatched
|
||
fireGlobals,
|
||
|
||
transport,
|
||
// Response headers
|
||
responseHeaders,
|
||
// Create the final options object
|
||
s = jQuery.ajaxSetup( {}, options ),
|
||
// Callbacks context
|
||
callbackContext = s.context || s,
|
||
// Context for global events is callbackContext if it is a DOM node or jQuery collection
|
||
globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
|
||
jQuery( callbackContext ) :
|
||
jQuery.event,
|
||
// Deferreds
|
||
deferred = jQuery.Deferred(),
|
||
completeDeferred = jQuery.Callbacks("once memory"),
|
||
// Status-dependent callbacks
|
||
statusCode = s.statusCode || {},
|
||
// Headers (they are sent all at once)
|
||
requestHeaders = {},
|
||
requestHeadersNames = {},
|
||
// The jqXHR state
|
||
state = 0,
|
||
// Default abort message
|
||
strAbort = "canceled",
|
||
// Fake xhr
|
||
jqXHR = {
|
||
readyState: 0,
|
||
|
||
// Builds headers hashtable if needed
|
||
getResponseHeader: function( key ) {
|
||
var match;
|
||
if ( state === 2 ) {
|
||
if ( !responseHeaders ) {
|
||
responseHeaders = {};
|
||
while ( (match = rheaders.exec( responseHeadersString )) ) {
|
||
responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
|
||
}
|
||
}
|
||
match = responseHeaders[ key.toLowerCase() ];
|
||
}
|
||
return match == null ? null : match;
|
||
},
|
||
|
||
// Raw string
|
||
getAllResponseHeaders: function() {
|
||
return state === 2 ? responseHeadersString : null;
|
||
},
|
||
|
||
// Caches the header
|
||
setRequestHeader: function( name, value ) {
|
||
var lname = name.toLowerCase();
|
||
if ( !state ) {
|
||
name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
|
||
requestHeaders[ name ] = value;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Overrides response content-type header
|
||
overrideMimeType: function( type ) {
|
||
if ( !state ) {
|
||
s.mimeType = type;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Status-dependent callbacks
|
||
statusCode: function( map ) {
|
||
var code;
|
||
if ( map ) {
|
||
if ( state < 2 ) {
|
||
for ( code in map ) {
|
||
// Lazy-add the new callback in a way that preserves old ones
|
||
statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
|
||
}
|
||
} else {
|
||
// Execute the appropriate callbacks
|
||
jqXHR.always( map[ jqXHR.status ] );
|
||
}
|
||
}
|
||
return this;
|
||
},
|
||
|
||
// Cancel the request
|
||
abort: function( statusText ) {
|
||
var finalText = statusText || strAbort;
|
||
if ( transport ) {
|
||
transport.abort( finalText );
|
||
}
|
||
done( 0, finalText );
|
||
return this;
|
||
}
|
||
};
|
||
|
||
// Attach deferreds
|
||
deferred.promise( jqXHR ).complete = completeDeferred.add;
|
||
jqXHR.success = jqXHR.done;
|
||
jqXHR.error = jqXHR.fail;
|
||
|
||
// Remove hash character (#7531: and string promotion)
|
||
// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
|
||
// Handle falsy url in the settings object (#10093: consistency with old signature)
|
||
// We also use the url parameter if available
|
||
s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
|
||
|
||
// Alias method option to type as per ticket #12004
|
||
s.type = options.method || options.type || s.method || s.type;
|
||
|
||
// Extract dataTypes list
|
||
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
|
||
|
||
// A cross-domain request is in order when we have a protocol:host:port mismatch
|
||
if ( s.crossDomain == null ) {
|
||
parts = rurl.exec( s.url.toLowerCase() );
|
||
s.crossDomain = !!( parts &&
|
||
( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
|
||
( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
|
||
( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
|
||
);
|
||
}
|
||
|
||
// Convert data if not already a string
|
||
if ( s.data && s.processData && typeof s.data !== "string" ) {
|
||
s.data = jQuery.param( s.data, s.traditional );
|
||
}
|
||
|
||
// Apply prefilters
|
||
inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
|
||
|
||
// If request was aborted inside a prefilter, stop there
|
||
if ( state === 2 ) {
|
||
return jqXHR;
|
||
}
|
||
|
||
// We can fire global events as of now if asked to
|
||
fireGlobals = s.global;
|
||
|
||
// Watch for a new set of requests
|
||
if ( fireGlobals && jQuery.active++ === 0 ) {
|
||
jQuery.event.trigger("ajaxStart");
|
||
}
|
||
|
||
// Uppercase the type
|
||
s.type = s.type.toUpperCase();
|
||
|
||
// Determine if request has content
|
||
s.hasContent = !rnoContent.test( s.type );
|
||
|
||
// Save the URL in case we're toying with the If-Modified-Since
|
||
// and/or If-None-Match header later on
|
||
cacheURL = s.url;
|
||
|
||
// More options handling for requests with no content
|
||
if ( !s.hasContent ) {
|
||
|
||
// If data is available, append data to url
|
||
if ( s.data ) {
|
||
cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
|
||
// #9682: remove data so that it's not used in an eventual retry
|
||
delete s.data;
|
||
}
|
||
|
||
// Add anti-cache in url if needed
|
||
if ( s.cache === false ) {
|
||
s.url = rts.test( cacheURL ) ?
|
||
|
||
// If there is already a '_' parameter, set its value
|
||
cacheURL.replace( rts, "$1_=" + nonce++ ) :
|
||
|
||
// Otherwise add one to the end
|
||
cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
|
||
}
|
||
}
|
||
|
||
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
||
if ( s.ifModified ) {
|
||
if ( jQuery.lastModified[ cacheURL ] ) {
|
||
jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
|
||
}
|
||
if ( jQuery.etag[ cacheURL ] ) {
|
||
jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
|
||
}
|
||
}
|
||
|
||
// Set the correct header, if data is being sent
|
||
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
|
||
jqXHR.setRequestHeader( "Content-Type", s.contentType );
|
||
}
|
||
|
||
// Set the Accepts header for the server, depending on the dataType
|
||
jqXHR.setRequestHeader(
|
||
"Accept",
|
||
s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
|
||
s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
|
||
s.accepts[ "*" ]
|
||
);
|
||
|
||
// Check for headers option
|
||
for ( i in s.headers ) {
|
||
jqXHR.setRequestHeader( i, s.headers[ i ] );
|
||
}
|
||
|
||
// Allow custom headers/mimetypes and early abort
|
||
if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
|
||
// Abort if not done already and return
|
||
return jqXHR.abort();
|
||
}
|
||
|
||
// aborting is no longer a cancellation
|
||
strAbort = "abort";
|
||
|
||
// Install callbacks on deferreds
|
||
for ( i in { success: 1, error: 1, complete: 1 } ) {
|
||
jqXHR[ i ]( s[ i ] );
|
||
}
|
||
|
||
// Get transport
|
||
transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
|
||
|
||
// If no transport, we auto-abort
|
||
if ( !transport ) {
|
||
done( -1, "No Transport" );
|
||
} else {
|
||
jqXHR.readyState = 1;
|
||
|
||
// Send global event
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
|
||
}
|
||
// Timeout
|
||
if ( s.async && s.timeout > 0 ) {
|
||
timeoutTimer = setTimeout(function() {
|
||
jqXHR.abort("timeout");
|
||
}, s.timeout );
|
||
}
|
||
|
||
try {
|
||
state = 1;
|
||
transport.send( requestHeaders, done );
|
||
} catch ( e ) {
|
||
// Propagate exception as error if not done
|
||
if ( state < 2 ) {
|
||
done( -1, e );
|
||
// Simply rethrow otherwise
|
||
} else {
|
||
throw e;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Callback for when everything is done
|
||
function done( status, nativeStatusText, responses, headers ) {
|
||
var isSuccess, success, error, response, modified,
|
||
statusText = nativeStatusText;
|
||
|
||
// Called once
|
||
if ( state === 2 ) {
|
||
return;
|
||
}
|
||
|
||
// State is "done" now
|
||
state = 2;
|
||
|
||
// Clear timeout if it exists
|
||
if ( timeoutTimer ) {
|
||
clearTimeout( timeoutTimer );
|
||
}
|
||
|
||
// Dereference transport for early garbage collection
|
||
// (no matter how long the jqXHR object will be used)
|
||
transport = undefined;
|
||
|
||
// Cache response headers
|
||
responseHeadersString = headers || "";
|
||
|
||
// Set readyState
|
||
jqXHR.readyState = status > 0 ? 4 : 0;
|
||
|
||
// Determine if successful
|
||
isSuccess = status >= 200 && status < 300 || status === 304;
|
||
|
||
// Get response data
|
||
if ( responses ) {
|
||
response = ajaxHandleResponses( s, jqXHR, responses );
|
||
}
|
||
|
||
// Convert no matter what (that way responseXXX fields are always set)
|
||
response = ajaxConvert( s, response, jqXHR, isSuccess );
|
||
|
||
// If successful, handle type chaining
|
||
if ( isSuccess ) {
|
||
|
||
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
|
||
if ( s.ifModified ) {
|
||
modified = jqXHR.getResponseHeader("Last-Modified");
|
||
if ( modified ) {
|
||
jQuery.lastModified[ cacheURL ] = modified;
|
||
}
|
||
modified = jqXHR.getResponseHeader("etag");
|
||
if ( modified ) {
|
||
jQuery.etag[ cacheURL ] = modified;
|
||
}
|
||
}
|
||
|
||
// if no content
|
||
if ( status === 204 || s.type === "HEAD" ) {
|
||
statusText = "nocontent";
|
||
|
||
// if not modified
|
||
} else if ( status === 304 ) {
|
||
statusText = "notmodified";
|
||
|
||
// If we have data, let's convert it
|
||
} else {
|
||
statusText = response.state;
|
||
success = response.data;
|
||
error = response.error;
|
||
isSuccess = !error;
|
||
}
|
||
} else {
|
||
// We extract error from statusText
|
||
// then normalize statusText and status for non-aborts
|
||
error = statusText;
|
||
if ( status || !statusText ) {
|
||
statusText = "error";
|
||
if ( status < 0 ) {
|
||
status = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Set data for the fake xhr object
|
||
jqXHR.status = status;
|
||
jqXHR.statusText = ( nativeStatusText || statusText ) + "";
|
||
|
||
// Success/Error
|
||
if ( isSuccess ) {
|
||
deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
|
||
} else {
|
||
deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
|
||
}
|
||
|
||
// Status-dependent callbacks
|
||
jqXHR.statusCode( statusCode );
|
||
statusCode = undefined;
|
||
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
|
||
[ jqXHR, s, isSuccess ? success : error ] );
|
||
}
|
||
|
||
// Complete
|
||
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
|
||
|
||
if ( fireGlobals ) {
|
||
globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
|
||
// Handle the global AJAX counter
|
||
if ( !( --jQuery.active ) ) {
|
||
jQuery.event.trigger("ajaxStop");
|
||
}
|
||
}
|
||
}
|
||
|
||
return jqXHR;
|
||
},
|
||
|
||
getJSON: function( url, data, callback ) {
|
||
return jQuery.get( url, data, callback, "json" );
|
||
},
|
||
|
||
getScript: function( url, callback ) {
|
||
return jQuery.get( url, undefined, callback, "script" );
|
||
}
|
||
});
|
||
|
||
jQuery.each( [ "get", "post" ], function( i, method ) {
|
||
jQuery[ method ] = function( url, data, callback, type ) {
|
||
// shift arguments if data argument was omitted
|
||
if ( jQuery.isFunction( data ) ) {
|
||
type = type || callback;
|
||
callback = data;
|
||
data = undefined;
|
||
}
|
||
|
||
return jQuery.ajax({
|
||
url: url,
|
||
type: method,
|
||
dataType: type,
|
||
data: data,
|
||
success: callback
|
||
});
|
||
};
|
||
});
|
||
|
||
// Attach a bunch of functions for handling common AJAX events
|
||
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
|
||
jQuery.fn[ type ] = function( fn ) {
|
||
return this.on( type, fn );
|
||
};
|
||
});
|
||
|
||
|
||
jQuery._evalUrl = function( url ) {
|
||
return jQuery.ajax({
|
||
url: url,
|
||
type: "GET",
|
||
dataType: "script",
|
||
async: false,
|
||
global: false,
|
||
"throws": true
|
||
});
|
||
};
|
||
|
||
|
||
jQuery.fn.extend({
|
||
wrapAll: function( html ) {
|
||
if ( jQuery.isFunction( html ) ) {
|
||
return this.each(function(i) {
|
||
jQuery(this).wrapAll( html.call(this, i) );
|
||
});
|
||
}
|
||
|
||
if ( this[0] ) {
|
||
// The elements to wrap the target around
|
||
var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
|
||
|
||
if ( this[0].parentNode ) {
|
||
wrap.insertBefore( this[0] );
|
||
}
|
||
|
||
wrap.map(function() {
|
||
var elem = this;
|
||
|
||
while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
|
||
elem = elem.firstChild;
|
||
}
|
||
|
||
return elem;
|
||
}).append( this );
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
wrapInner: function( html ) {
|
||
if ( jQuery.isFunction( html ) ) {
|
||
return this.each(function(i) {
|
||
jQuery(this).wrapInner( html.call(this, i) );
|
||
});
|
||
}
|
||
|
||
return this.each(function() {
|
||
var self = jQuery( this ),
|
||
contents = self.contents();
|
||
|
||
if ( contents.length ) {
|
||
contents.wrapAll( html );
|
||
|
||
} else {
|
||
self.append( html );
|
||
}
|
||
});
|
||
},
|
||
|
||
wrap: function( html ) {
|
||
var isFunction = jQuery.isFunction( html );
|
||
|
||
return this.each(function(i) {
|
||
jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
|
||
});
|
||
},
|
||
|
||
unwrap: function() {
|
||
return this.parent().each(function() {
|
||
if ( !jQuery.nodeName( this, "body" ) ) {
|
||
jQuery( this ).replaceWith( this.childNodes );
|
||
}
|
||
}).end();
|
||
}
|
||
});
|
||
|
||
|
||
jQuery.expr.filters.hidden = function( elem ) {
|
||
// Support: Opera <= 12.12
|
||
// Opera reports offsetWidths and offsetHeights less than zero on some elements
|
||
return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
|
||
(!support.reliableHiddenOffsets() &&
|
||
((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
|
||
};
|
||
|
||
jQuery.expr.filters.visible = function( elem ) {
|
||
return !jQuery.expr.filters.hidden( elem );
|
||
};
|
||
|
||
|
||
|
||
|
||
var r20 = /%20/g,
|
||
rbracket = /\[\]$/,
|
||
rCRLF = /\r?\n/g,
|
||
rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
|
||
rsubmittable = /^(?:input|select|textarea|keygen)/i;
|
||
|
||
function buildParams( prefix, obj, traditional, add ) {
|
||
var name;
|
||
|
||
if ( jQuery.isArray( obj ) ) {
|
||
// Serialize array item.
|
||
jQuery.each( obj, function( i, v ) {
|
||
if ( traditional || rbracket.test( prefix ) ) {
|
||
// Treat each array item as a scalar.
|
||
add( prefix, v );
|
||
|
||
} else {
|
||
// Item is non-scalar (array or object), encode its numeric index.
|
||
buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
|
||
}
|
||
});
|
||
|
||
} else if ( !traditional && jQuery.type( obj ) === "object" ) {
|
||
// Serialize object item.
|
||
for ( name in obj ) {
|
||
buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
|
||
}
|
||
|
||
} else {
|
||
// Serialize scalar item.
|
||
add( prefix, obj );
|
||
}
|
||
}
|
||
|
||
// Serialize an array of form elements or a set of
|
||
// key/values into a query string
|
||
jQuery.param = function( a, traditional ) {
|
||
var prefix,
|
||
s = [],
|
||
add = function( key, value ) {
|
||
// If value is a function, invoke it and return its value
|
||
value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
|
||
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
|
||
};
|
||
|
||
// Set traditional to true for jQuery <= 1.3.2 behavior.
|
||
if ( traditional === undefined ) {
|
||
traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
|
||
}
|
||
|
||
// If an array was passed in, assume that it is an array of form elements.
|
||
if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
|
||
// Serialize the form elements
|
||
jQuery.each( a, function() {
|
||
add( this.name, this.value );
|
||
});
|
||
|
||
} else {
|
||
// If traditional, encode the "old" way (the way 1.3.2 or older
|
||
// did it), otherwise encode params recursively.
|
||
for ( prefix in a ) {
|
||
buildParams( prefix, a[ prefix ], traditional, add );
|
||
}
|
||
}
|
||
|
||
// Return the resulting serialization
|
||
return s.join( "&" ).replace( r20, "+" );
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
serialize: function() {
|
||
return jQuery.param( this.serializeArray() );
|
||
},
|
||
serializeArray: function() {
|
||
return this.map(function() {
|
||
// Can add propHook for "elements" to filter or add form elements
|
||
var elements = jQuery.prop( this, "elements" );
|
||
return elements ? jQuery.makeArray( elements ) : this;
|
||
})
|
||
.filter(function() {
|
||
var type = this.type;
|
||
// Use .is(":disabled") so that fieldset[disabled] works
|
||
return this.name && !jQuery( this ).is( ":disabled" ) &&
|
||
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
|
||
( this.checked || !rcheckableType.test( type ) );
|
||
})
|
||
.map(function( i, elem ) {
|
||
var val = jQuery( this ).val();
|
||
|
||
return val == null ?
|
||
null :
|
||
jQuery.isArray( val ) ?
|
||
jQuery.map( val, function( val ) {
|
||
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
|
||
}) :
|
||
{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
|
||
}).get();
|
||
}
|
||
});
|
||
|
||
|
||
// Create the request object
|
||
// (This is still attached to ajaxSettings for backward compatibility)
|
||
jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
|
||
// Support: IE6+
|
||
function() {
|
||
|
||
// XHR cannot access local files, always use ActiveX for that case
|
||
return !this.isLocal &&
|
||
|
||
// Support: IE7-8
|
||
// oldIE XHR does not support non-RFC2616 methods (#13240)
|
||
// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
|
||
// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
|
||
// Although this check for six methods instead of eight
|
||
// since IE also does not support "trace" and "connect"
|
||
/^(get|post|head|put|delete|options)$/i.test( this.type ) &&
|
||
|
||
createStandardXHR() || createActiveXHR();
|
||
} :
|
||
// For all other browsers, use the standard XMLHttpRequest object
|
||
createStandardXHR;
|
||
|
||
var xhrId = 0,
|
||
xhrCallbacks = {},
|
||
xhrSupported = jQuery.ajaxSettings.xhr();
|
||
|
||
// Support: IE<10
|
||
// Open requests must be manually aborted on unload (#5280)
|
||
if ( window.ActiveXObject ) {
|
||
jQuery( window ).on( "unload", function() {
|
||
for ( var key in xhrCallbacks ) {
|
||
xhrCallbacks[ key ]( undefined, true );
|
||
}
|
||
});
|
||
}
|
||
|
||
// Determine support properties
|
||
support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
|
||
xhrSupported = support.ajax = !!xhrSupported;
|
||
|
||
// Create transport if the browser can provide an xhr
|
||
if ( xhrSupported ) {
|
||
|
||
jQuery.ajaxTransport(function( options ) {
|
||
// Cross domain only allowed if supported through XMLHttpRequest
|
||
if ( !options.crossDomain || support.cors ) {
|
||
|
||
var callback;
|
||
|
||
return {
|
||
send: function( headers, complete ) {
|
||
var i,
|
||
xhr = options.xhr(),
|
||
id = ++xhrId;
|
||
|
||
// Open the socket
|
||
xhr.open( options.type, options.url, options.async, options.username, options.password );
|
||
|
||
// Apply custom fields if provided
|
||
if ( options.xhrFields ) {
|
||
for ( i in options.xhrFields ) {
|
||
xhr[ i ] = options.xhrFields[ i ];
|
||
}
|
||
}
|
||
|
||
// Override mime type if needed
|
||
if ( options.mimeType && xhr.overrideMimeType ) {
|
||
xhr.overrideMimeType( options.mimeType );
|
||
}
|
||
|
||
// X-Requested-With header
|
||
// For cross-domain requests, seeing as conditions for a preflight are
|
||
// akin to a jigsaw puzzle, we simply never set it to be sure.
|
||
// (it can always be set on a per-request basis or even using ajaxSetup)
|
||
// For same-domain requests, won't change header if already provided.
|
||
if ( !options.crossDomain && !headers["X-Requested-With"] ) {
|
||
headers["X-Requested-With"] = "XMLHttpRequest";
|
||
}
|
||
|
||
// Set headers
|
||
for ( i in headers ) {
|
||
// Support: IE<9
|
||
// IE's ActiveXObject throws a 'Type Mismatch' exception when setting
|
||
// request header to a null-value.
|
||
//
|
||
// To keep consistent with other XHR implementations, cast the value
|
||
// to string and ignore `undefined`.
|
||
if ( headers[ i ] !== undefined ) {
|
||
xhr.setRequestHeader( i, headers[ i ] + "" );
|
||
}
|
||
}
|
||
|
||
// Do send the request
|
||
// This may raise an exception which is actually
|
||
// handled in jQuery.ajax (so no try/catch here)
|
||
xhr.send( ( options.hasContent && options.data ) || null );
|
||
|
||
// Listener
|
||
callback = function( _, isAbort ) {
|
||
var status, statusText, responses;
|
||
|
||
// Was never called and is aborted or complete
|
||
if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
|
||
// Clean up
|
||
delete xhrCallbacks[ id ];
|
||
callback = undefined;
|
||
xhr.onreadystatechange = jQuery.noop;
|
||
|
||
// Abort manually if needed
|
||
if ( isAbort ) {
|
||
if ( xhr.readyState !== 4 ) {
|
||
xhr.abort();
|
||
}
|
||
} else {
|
||
responses = {};
|
||
status = xhr.status;
|
||
|
||
// Support: IE<10
|
||
// Accessing binary-data responseText throws an exception
|
||
// (#11426)
|
||
if ( typeof xhr.responseText === "string" ) {
|
||
responses.text = xhr.responseText;
|
||
}
|
||
|
||
// Firefox throws an exception when accessing
|
||
// statusText for faulty cross-domain requests
|
||
try {
|
||
statusText = xhr.statusText;
|
||
} catch( e ) {
|
||
// We normalize with Webkit giving an empty statusText
|
||
statusText = "";
|
||
}
|
||
|
||
// Filter status for non standard behaviors
|
||
|
||
// If the request is local and we have data: assume a success
|
||
// (success with no data won't get notified, that's the best we
|
||
// can do given current implementations)
|
||
if ( !status && options.isLocal && !options.crossDomain ) {
|
||
status = responses.text ? 200 : 404;
|
||
// IE - #1450: sometimes returns 1223 when it should be 204
|
||
} else if ( status === 1223 ) {
|
||
status = 204;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Call complete if needed
|
||
if ( responses ) {
|
||
complete( status, statusText, responses, xhr.getAllResponseHeaders() );
|
||
}
|
||
};
|
||
|
||
if ( !options.async ) {
|
||
// if we're in sync mode we fire the callback
|
||
callback();
|
||
} else if ( xhr.readyState === 4 ) {
|
||
// (IE6 & IE7) if it's in cache and has been
|
||
// retrieved directly we need to fire the callback
|
||
setTimeout( callback );
|
||
} else {
|
||
// Add to the list of active xhr callbacks
|
||
xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
|
||
}
|
||
},
|
||
|
||
abort: function() {
|
||
if ( callback ) {
|
||
callback( undefined, true );
|
||
}
|
||
}
|
||
};
|
||
}
|
||
});
|
||
}
|
||
|
||
// Functions to create xhrs
|
||
function createStandardXHR() {
|
||
try {
|
||
return new window.XMLHttpRequest();
|
||
} catch( e ) {}
|
||
}
|
||
|
||
function createActiveXHR() {
|
||
try {
|
||
return new window.ActiveXObject( "Microsoft.XMLHTTP" );
|
||
} catch( e ) {}
|
||
}
|
||
|
||
|
||
|
||
|
||
// Install script dataType
|
||
jQuery.ajaxSetup({
|
||
accepts: {
|
||
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
|
||
},
|
||
contents: {
|
||
script: /(?:java|ecma)script/
|
||
},
|
||
converters: {
|
||
"text script": function( text ) {
|
||
jQuery.globalEval( text );
|
||
return text;
|
||
}
|
||
}
|
||
});
|
||
|
||
// Handle cache's special case and global
|
||
jQuery.ajaxPrefilter( "script", function( s ) {
|
||
if ( s.cache === undefined ) {
|
||
s.cache = false;
|
||
}
|
||
if ( s.crossDomain ) {
|
||
s.type = "GET";
|
||
s.global = false;
|
||
}
|
||
});
|
||
|
||
// Bind script tag hack transport
|
||
jQuery.ajaxTransport( "script", function(s) {
|
||
|
||
// This transport only deals with cross domain requests
|
||
if ( s.crossDomain ) {
|
||
|
||
var script,
|
||
head = document.head || jQuery("head")[0] || document.documentElement;
|
||
|
||
return {
|
||
|
||
send: function( _, callback ) {
|
||
|
||
script = document.createElement("script");
|
||
|
||
script.async = true;
|
||
|
||
if ( s.scriptCharset ) {
|
||
script.charset = s.scriptCharset;
|
||
}
|
||
|
||
script.src = s.url;
|
||
|
||
// Attach handlers for all browsers
|
||
script.onload = script.onreadystatechange = function( _, isAbort ) {
|
||
|
||
if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
|
||
|
||
// Handle memory leak in IE
|
||
script.onload = script.onreadystatechange = null;
|
||
|
||
// Remove the script
|
||
if ( script.parentNode ) {
|
||
script.parentNode.removeChild( script );
|
||
}
|
||
|
||
// Dereference the script
|
||
script = null;
|
||
|
||
// Callback if not abort
|
||
if ( !isAbort ) {
|
||
callback( 200, "success" );
|
||
}
|
||
}
|
||
};
|
||
|
||
// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
|
||
// Use native DOM manipulation to avoid our domManip AJAX trickery
|
||
head.insertBefore( script, head.firstChild );
|
||
},
|
||
|
||
abort: function() {
|
||
if ( script ) {
|
||
script.onload( undefined, true );
|
||
}
|
||
}
|
||
};
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
var oldCallbacks = [],
|
||
rjsonp = /(=)\?(?=&|$)|\?\?/;
|
||
|
||
// Default jsonp settings
|
||
jQuery.ajaxSetup({
|
||
jsonp: "callback",
|
||
jsonpCallback: function() {
|
||
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
|
||
this[ callback ] = true;
|
||
return callback;
|
||
}
|
||
});
|
||
|
||
// Detect, normalize options and install callbacks for jsonp requests
|
||
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
|
||
|
||
var callbackName, overwritten, responseContainer,
|
||
jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
|
||
"url" :
|
||
typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
|
||
);
|
||
|
||
// Handle iff the expected data type is "jsonp" or we have a parameter to set
|
||
if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
|
||
|
||
// Get callback name, remembering preexisting value associated with it
|
||
callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
|
||
s.jsonpCallback() :
|
||
s.jsonpCallback;
|
||
|
||
// Insert callback into url or form data
|
||
if ( jsonProp ) {
|
||
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
|
||
} else if ( s.jsonp !== false ) {
|
||
s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
|
||
}
|
||
|
||
// Use data converter to retrieve json after script execution
|
||
s.converters["script json"] = function() {
|
||
if ( !responseContainer ) {
|
||
jQuery.error( callbackName + " was not called" );
|
||
}
|
||
return responseContainer[ 0 ];
|
||
};
|
||
|
||
// force json dataType
|
||
s.dataTypes[ 0 ] = "json";
|
||
|
||
// Install callback
|
||
overwritten = window[ callbackName ];
|
||
window[ callbackName ] = function() {
|
||
responseContainer = arguments;
|
||
};
|
||
|
||
// Clean-up function (fires after converters)
|
||
jqXHR.always(function() {
|
||
// Restore preexisting value
|
||
window[ callbackName ] = overwritten;
|
||
|
||
// Save back as free
|
||
if ( s[ callbackName ] ) {
|
||
// make sure that re-using the options doesn't screw things around
|
||
s.jsonpCallback = originalSettings.jsonpCallback;
|
||
|
||
// save the callback name for future use
|
||
oldCallbacks.push( callbackName );
|
||
}
|
||
|
||
// Call if it was a function and we have a response
|
||
if ( responseContainer && jQuery.isFunction( overwritten ) ) {
|
||
overwritten( responseContainer[ 0 ] );
|
||
}
|
||
|
||
responseContainer = overwritten = undefined;
|
||
});
|
||
|
||
// Delegate to script
|
||
return "script";
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
// data: string of html
|
||
// context (optional): If specified, the fragment will be created in this context, defaults to document
|
||
// keepScripts (optional): If true, will include scripts passed in the html string
|
||
jQuery.parseHTML = function( data, context, keepScripts ) {
|
||
if ( !data || typeof data !== "string" ) {
|
||
return null;
|
||
}
|
||
if ( typeof context === "boolean" ) {
|
||
keepScripts = context;
|
||
context = false;
|
||
}
|
||
context = context || document;
|
||
|
||
var parsed = rsingleTag.exec( data ),
|
||
scripts = !keepScripts && [];
|
||
|
||
// Single tag
|
||
if ( parsed ) {
|
||
return [ context.createElement( parsed[1] ) ];
|
||
}
|
||
|
||
parsed = jQuery.buildFragment( [ data ], context, scripts );
|
||
|
||
if ( scripts && scripts.length ) {
|
||
jQuery( scripts ).remove();
|
||
}
|
||
|
||
return jQuery.merge( [], parsed.childNodes );
|
||
};
|
||
|
||
|
||
// Keep a copy of the old load method
|
||
var _load = jQuery.fn.load;
|
||
|
||
/**
|
||
* Load a url into a page
|
||
*/
|
||
jQuery.fn.load = function( url, params, callback ) {
|
||
if ( typeof url !== "string" && _load ) {
|
||
return _load.apply( this, arguments );
|
||
}
|
||
|
||
var selector, response, type,
|
||
self = this,
|
||
off = url.indexOf(" ");
|
||
|
||
if ( off >= 0 ) {
|
||
selector = jQuery.trim( url.slice( off, url.length ) );
|
||
url = url.slice( 0, off );
|
||
}
|
||
|
||
// If it's a function
|
||
if ( jQuery.isFunction( params ) ) {
|
||
|
||
// We assume that it's the callback
|
||
callback = params;
|
||
params = undefined;
|
||
|
||
// Otherwise, build a param string
|
||
} else if ( params && typeof params === "object" ) {
|
||
type = "POST";
|
||
}
|
||
|
||
// If we have elements to modify, make the request
|
||
if ( self.length > 0 ) {
|
||
jQuery.ajax({
|
||
url: url,
|
||
|
||
// if "type" variable is undefined, then "GET" method will be used
|
||
type: type,
|
||
dataType: "html",
|
||
data: params
|
||
}).done(function( responseText ) {
|
||
|
||
// Save response for use in complete callback
|
||
response = arguments;
|
||
|
||
self.html( selector ?
|
||
|
||
// If a selector was specified, locate the right elements in a dummy div
|
||
// Exclude scripts to avoid IE 'Permission Denied' errors
|
||
jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
|
||
|
||
// Otherwise use the full result
|
||
responseText );
|
||
|
||
}).complete( callback && function( jqXHR, status ) {
|
||
self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
|
||
});
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
|
||
|
||
|
||
jQuery.expr.filters.animated = function( elem ) {
|
||
return jQuery.grep(jQuery.timers, function( fn ) {
|
||
return elem === fn.elem;
|
||
}).length;
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
var docElem = window.document.documentElement;
|
||
|
||
/**
|
||
* Gets a window from an element
|
||
*/
|
||
function getWindow( elem ) {
|
||
return jQuery.isWindow( elem ) ?
|
||
elem :
|
||
elem.nodeType === 9 ?
|
||
elem.defaultView || elem.parentWindow :
|
||
false;
|
||
}
|
||
|
||
jQuery.offset = {
|
||
setOffset: function( elem, options, i ) {
|
||
var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
|
||
position = jQuery.css( elem, "position" ),
|
||
curElem = jQuery( elem ),
|
||
props = {};
|
||
|
||
// set position first, in-case top/left are set even on static elem
|
||
if ( position === "static" ) {
|
||
elem.style.position = "relative";
|
||
}
|
||
|
||
curOffset = curElem.offset();
|
||
curCSSTop = jQuery.css( elem, "top" );
|
||
curCSSLeft = jQuery.css( elem, "left" );
|
||
calculatePosition = ( position === "absolute" || position === "fixed" ) &&
|
||
jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
|
||
|
||
// need to be able to calculate position if either top or left is auto and position is either absolute or fixed
|
||
if ( calculatePosition ) {
|
||
curPosition = curElem.position();
|
||
curTop = curPosition.top;
|
||
curLeft = curPosition.left;
|
||
} else {
|
||
curTop = parseFloat( curCSSTop ) || 0;
|
||
curLeft = parseFloat( curCSSLeft ) || 0;
|
||
}
|
||
|
||
if ( jQuery.isFunction( options ) ) {
|
||
options = options.call( elem, i, curOffset );
|
||
}
|
||
|
||
if ( options.top != null ) {
|
||
props.top = ( options.top - curOffset.top ) + curTop;
|
||
}
|
||
if ( options.left != null ) {
|
||
props.left = ( options.left - curOffset.left ) + curLeft;
|
||
}
|
||
|
||
if ( "using" in options ) {
|
||
options.using.call( elem, props );
|
||
} else {
|
||
curElem.css( props );
|
||
}
|
||
}
|
||
};
|
||
|
||
jQuery.fn.extend({
|
||
offset: function( options ) {
|
||
if ( arguments.length ) {
|
||
return options === undefined ?
|
||
this :
|
||
this.each(function( i ) {
|
||
jQuery.offset.setOffset( this, options, i );
|
||
});
|
||
}
|
||
|
||
var docElem, win,
|
||
box = { top: 0, left: 0 },
|
||
elem = this[ 0 ],
|
||
doc = elem && elem.ownerDocument;
|
||
|
||
if ( !doc ) {
|
||
return;
|
||
}
|
||
|
||
docElem = doc.documentElement;
|
||
|
||
// Make sure it's not a disconnected DOM node
|
||
if ( !jQuery.contains( docElem, elem ) ) {
|
||
return box;
|
||
}
|
||
|
||
// If we don't have gBCR, just use 0,0 rather than error
|
||
// BlackBerry 5, iOS 3 (original iPhone)
|
||
if ( typeof elem.getBoundingClientRect !== strundefined ) {
|
||
box = elem.getBoundingClientRect();
|
||
}
|
||
win = getWindow( doc );
|
||
return {
|
||
top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
|
||
left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
|
||
};
|
||
},
|
||
|
||
position: function() {
|
||
if ( !this[ 0 ] ) {
|
||
return;
|
||
}
|
||
|
||
var offsetParent, offset,
|
||
parentOffset = { top: 0, left: 0 },
|
||
elem = this[ 0 ];
|
||
|
||
// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
|
||
if ( jQuery.css( elem, "position" ) === "fixed" ) {
|
||
// we assume that getBoundingClientRect is available when computed position is fixed
|
||
offset = elem.getBoundingClientRect();
|
||
} else {
|
||
// Get *real* offsetParent
|
||
offsetParent = this.offsetParent();
|
||
|
||
// Get correct offsets
|
||
offset = this.offset();
|
||
if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
|
||
parentOffset = offsetParent.offset();
|
||
}
|
||
|
||
// Add offsetParent borders
|
||
parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
|
||
parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
|
||
}
|
||
|
||
// Subtract parent offsets and element margins
|
||
// note: when an element has margin: auto the offsetLeft and marginLeft
|
||
// are the same in Safari causing offset.left to incorrectly be 0
|
||
return {
|
||
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
|
||
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
|
||
};
|
||
},
|
||
|
||
offsetParent: function() {
|
||
return this.map(function() {
|
||
var offsetParent = this.offsetParent || docElem;
|
||
|
||
while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
|
||
offsetParent = offsetParent.offsetParent;
|
||
}
|
||
return offsetParent || docElem;
|
||
});
|
||
}
|
||
});
|
||
|
||
// Create scrollLeft and scrollTop methods
|
||
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
|
||
var top = /Y/.test( prop );
|
||
|
||
jQuery.fn[ method ] = function( val ) {
|
||
return access( this, function( elem, method, val ) {
|
||
var win = getWindow( elem );
|
||
|
||
if ( val === undefined ) {
|
||
return win ? (prop in win) ? win[ prop ] :
|
||
win.document.documentElement[ method ] :
|
||
elem[ method ];
|
||
}
|
||
|
||
if ( win ) {
|
||
win.scrollTo(
|
||
!top ? val : jQuery( win ).scrollLeft(),
|
||
top ? val : jQuery( win ).scrollTop()
|
||
);
|
||
|
||
} else {
|
||
elem[ method ] = val;
|
||
}
|
||
}, method, val, arguments.length, null );
|
||
};
|
||
});
|
||
|
||
// Add the top/left cssHooks using jQuery.fn.position
|
||
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
|
||
// getComputedStyle returns percent when specified for top/left/bottom/right
|
||
// rather than make the css module depend on the offset module, we just check for it here
|
||
jQuery.each( [ "top", "left" ], function( i, prop ) {
|
||
jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
|
||
function( elem, computed ) {
|
||
if ( computed ) {
|
||
computed = curCSS( elem, prop );
|
||
// if curCSS returns percentage, fallback to offset
|
||
return rnumnonpx.test( computed ) ?
|
||
jQuery( elem ).position()[ prop ] + "px" :
|
||
computed;
|
||
}
|
||
}
|
||
);
|
||
});
|
||
|
||
|
||
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
|
||
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
|
||
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
|
||
// margin is only for outerHeight, outerWidth
|
||
jQuery.fn[ funcName ] = function( margin, value ) {
|
||
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
|
||
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
|
||
|
||
return access( this, function( elem, type, value ) {
|
||
var doc;
|
||
|
||
if ( jQuery.isWindow( elem ) ) {
|
||
// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
|
||
// isn't a whole lot we can do. See pull request at this URL for discussion:
|
||
// https://github.com/jquery/jquery/pull/764
|
||
return elem.document.documentElement[ "client" + name ];
|
||
}
|
||
|
||
// Get document width or height
|
||
if ( elem.nodeType === 9 ) {
|
||
doc = elem.documentElement;
|
||
|
||
// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
|
||
// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
|
||
return Math.max(
|
||
elem.body[ "scroll" + name ], doc[ "scroll" + name ],
|
||
elem.body[ "offset" + name ], doc[ "offset" + name ],
|
||
doc[ "client" + name ]
|
||
);
|
||
}
|
||
|
||
return value === undefined ?
|
||
// Get width or height on the element, requesting but not forcing parseFloat
|
||
jQuery.css( elem, type, extra ) :
|
||
|
||
// Set width or height on the element
|
||
jQuery.style( elem, type, value, extra );
|
||
}, type, chainable ? margin : undefined, chainable, null );
|
||
};
|
||
});
|
||
});
|
||
|
||
|
||
// The number of elements contained in the matched element set
|
||
jQuery.fn.size = function() {
|
||
return this.length;
|
||
};
|
||
|
||
jQuery.fn.andSelf = jQuery.fn.addBack;
|
||
|
||
|
||
|
||
|
||
// Register as a named AMD module, since jQuery can be concatenated with other
|
||
// files that may use define, but not via a proper concatenation script that
|
||
// understands anonymous AMD modules. A named AMD is safest and most robust
|
||
// way to register. Lowercase jquery is used because AMD module names are
|
||
// derived from file names, and jQuery is normally delivered in a lowercase
|
||
// file name. Do this after creating the global so that if an AMD module wants
|
||
// to call noConflict to hide this version of jQuery, it will work.
|
||
|
||
// Note that for maximum portability, libraries that are not jQuery should
|
||
// declare themselves as anonymous modules, and avoid setting a global if an
|
||
// AMD loader is present. jQuery is a special case. For more information, see
|
||
// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
|
||
|
||
if ( typeof define === "function" && define.amd ) {
|
||
define( "jquery", [], function() {
|
||
return jQuery;
|
||
});
|
||
}
|
||
|
||
|
||
|
||
|
||
var
|
||
// Map over jQuery in case of overwrite
|
||
_jQuery = window.jQuery,
|
||
|
||
// Map over the $ in case of overwrite
|
||
_$ = window.$;
|
||
|
||
jQuery.noConflict = function( deep ) {
|
||
if ( window.$ === jQuery ) {
|
||
window.$ = _$;
|
||
}
|
||
|
||
if ( deep && window.jQuery === jQuery ) {
|
||
window.jQuery = _jQuery;
|
||
}
|
||
|
||
return jQuery;
|
||
};
|
||
|
||
// Expose jQuery and $ identifiers, even in
|
||
// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
|
||
// and CommonJS for browser emulators (#13566)
|
||
if ( typeof noGlobal === strundefined ) {
|
||
window.jQuery = window.$ = jQuery;
|
||
}
|
||
|
||
|
||
|
||
|
||
return jQuery;
|
||
|
||
}));
|
||
|
||
/*! jQuery UI - v1.10.4 - 2014-04-02
|
||
* http://jqueryui.com
|
||
* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.slider.js, jquery.ui.sortable.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
|
||
* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
|
||
|
||
(function(e,t){function i(t,i){var s,a,o,r=t.nodeName.toLowerCase();return"area"===r?(s=t.parentNode,a=s.name,t.href&&a&&"map"===s.nodeName.toLowerCase()?(o=e("img[usemap=#"+a+"]")[0],!!o&&n(o)):!1):(/input|select|textarea|button|object/.test(r)?!t.disabled:"a"===r?t.href||i:i)&&n(t)}function n(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var s=0,a=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,n){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),n&&n.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var n,s,a=e(this[0]);a.length&&a[0]!==document;){if(n=a.css("position"),("absolute"===n||"relative"===n||"fixed"===n)&&(s=parseInt(a.css("zIndex"),10),!isNaN(s)&&0!==s))return s;a=a.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++s)})},removeUniqueId:function(){return this.each(function(){a.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,n){return!!e.data(t,n[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),s=isNaN(n);return(s||n>=0)&&i(t,!s)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(i,n){function s(t,i,n,s){return e.each(a,function(){i-=parseFloat(e.css(t,"padding"+this))||0,n&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var a="Width"===n?["Left","Right"]:["Top","Bottom"],o=n.toLowerCase(),r={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+n]=function(i){return i===t?r["inner"+n].call(this):this.each(function(){e(this).css(o,s(this,i)+"px")})},e.fn["outer"+n]=function(t,i){return"number"!=typeof t?r["outer"+n].call(this,t):this.each(function(){e(this).css(o,s(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,n){var s,a=e.ui[t].prototype;for(s in n)a.plugins[s]=a.plugins[s]||[],a.plugins[s].push([i,n[s]])},call:function(e,t,i){var n,s=e.plugins[t];if(s&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(n=0;s.length>n;n++)e.options[s[n][0]]&&s[n][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var n=i&&"left"===i?"scrollLeft":"scrollTop",s=!1;return t[n]>0?!0:(t[n]=1,s=t[n]>0,t[n]=0,s)}})})(jQuery);(function(t,e){var i=0,s=Array.prototype.slice,n=t.cleanData;t.cleanData=function(e){for(var i,s=0;null!=(i=e[s]);s++)try{t(i).triggerHandler("remove")}catch(o){}n(e)},t.widget=function(i,s,n){var o,a,r,h,l={},c=i.split(".")[0];i=i.split(".")[1],o=c+"-"+i,n||(n=s,s=t.Widget),t.expr[":"][o.toLowerCase()]=function(e){return!!t.data(e,o)},t[c]=t[c]||{},a=t[c][i],r=t[c][i]=function(t,i){return this._createWidget?(arguments.length&&this._createWidget(t,i),e):new r(t,i)},t.extend(r,a,{version:n.version,_proto:t.extend({},n),_childConstructors:[]}),h=new s,h.options=t.widget.extend({},h.options),t.each(n,function(i,n){return t.isFunction(n)?(l[i]=function(){var t=function(){return s.prototype[i].apply(this,arguments)},e=function(t){return s.prototype[i].apply(this,t)};return function(){var i,s=this._super,o=this._superApply;return this._super=t,this._superApply=e,i=n.apply(this,arguments),this._super=s,this._superApply=o,i}}(),e):(l[i]=n,e)}),r.prototype=t.widget.extend(h,{widgetEventPrefix:a?h.widgetEventPrefix||i:i},l,{constructor:r,namespace:c,widgetName:i,widgetFullName:o}),a?(t.each(a._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,r,i._proto)}),delete a._childConstructors):s._childConstructors.push(r),t.widget.bridge(i,r)},t.widget.extend=function(i){for(var n,o,a=s.call(arguments,1),r=0,h=a.length;h>r;r++)for(n in a[r])o=a[r][n],a[r].hasOwnProperty(n)&&o!==e&&(i[n]=t.isPlainObject(o)?t.isPlainObject(i[n])?t.widget.extend({},i[n],o):t.widget.extend({},o):o);return i},t.widget.bridge=function(i,n){var o=n.prototype.widgetFullName||i;t.fn[i]=function(a){var r="string"==typeof a,h=s.call(arguments,1),l=this;return a=!r&&h.length?t.widget.extend.apply(null,[a].concat(h)):a,r?this.each(function(){var s,n=t.data(this,o);return n?t.isFunction(n[a])&&"_"!==a.charAt(0)?(s=n[a].apply(n,h),s!==n&&s!==e?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):e):t.error("no such method '"+a+"' for "+i+" widget instance"):t.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+a+"'")}):this.each(function(){var e=t.data(this,o);e?e.option(a||{})._init():t.data(this,o,new n(a,this))}),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this.bindings=t(),this.hoverable=t(),this.focusable=t(),s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:t.noop,_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(t.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:t.noop,widget:function(){return this.element},option:function(i,s){var n,o,a,r=i;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof i)if(r={},n=i.split("."),i=n.shift(),n.length){for(o=r[i]=t.widget.extend({},this.options[i]),a=0;n.length-1>a;a++)o[n[a]]=o[n[a]]||{},o=o[n[a]];if(i=n.pop(),1===arguments.length)return o[i]===e?null:o[i];o[i]=s}else{if(1===arguments.length)return this.options[i]===e?null:this.options[i];r[i]=s}return this._setOptions(r),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return this.options[t]=e,"disabled"===t&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!e).attr("aria-disabled",e),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var o,a=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=o=t(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,o=this.widget()),t.each(n,function(n,r){function h(){return i||a.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof r?a[r]:r).apply(a,arguments):e}"string"!=typeof r&&(h.guid=r.guid=r.guid||h.guid||t.guid++);var l=n.match(/^(\w+)\s*(.*)$/),c=l[1]+a.eventNamespace,u=l[2];u?o.delegate(u,c,h):s.bind(c,h)})},_off:function(t,e){e=(e||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,t.unbind(e).undelegate(e)},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){t(e.currentTarget).addClass("ui-state-hover")},mouseleave:function(e){t(e.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){t(e.currentTarget).addClass("ui-state-focus")},focusout:function(e){t(e.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}})})(jQuery);(function(t){var e=!1;t(document).mouseup(function(){e=!1}),t.widget("ui.mouse",{version:"1.10.4",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.bind("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).bind("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!e){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,n=1===i.which,a="string"==typeof this.options.cancel&&i.target.nodeName?t(i.target).closest(this.options.cancel).length:!1;return n&&!a&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===t.data(i.target,this.widgetName+".preventClickEvent")&&t.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return s._mouseMove(t)},this._mouseUpDelegate=function(t){return s._mouseUp(t)},t(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),e=!0,!0)):!0}},_mouseMove:function(e){return t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button?this._mouseUp(e):this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){return t(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),!1},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(t,e){function i(t,e,i){return[parseFloat(t[0])*(p.test(t[0])?e/100:1),parseFloat(t[1])*(p.test(t[1])?i/100:1)]}function s(e,i){return parseInt(t.css(e,i),10)||0}function n(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}t.ui=t.ui||{};var a,o=Math.max,r=Math.abs,l=Math.round,h=/left|center|right/,c=/top|center|bottom/,u=/[\+\-]\d+(\.[\d]+)?%?/,d=/^\w+/,p=/%$/,f=t.fn.position;t.position={scrollbarWidth:function(){if(a!==e)return a;var i,s,n=t("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=n.children()[0];return t("body").append(n),i=o.offsetWidth,n.css("overflow","scroll"),s=o.offsetWidth,i===s&&(s=n[0].clientWidth),n.remove(),a=i-s},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,a="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:a?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType;return{element:i,isWindow:s,isDocument:n,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s?i.width():i.outerWidth(),height:s?i.height():i.outerHeight()}}},t.fn.position=function(e){if(!e||!e.of)return f.apply(this,arguments);e=t.extend({},e);var a,p,g,m,v,_,b=t(e.of),y=t.position.getWithinInfo(e.within),k=t.position.getScrollInfo(y),w=(e.collision||"flip").split(" "),D={};return _=n(b),b[0].preventDefault&&(e.at="left top"),p=_.width,g=_.height,m=_.offset,v=t.extend({},m),t.each(["my","at"],function(){var t,i,s=(e[this]||"").split(" ");1===s.length&&(s=h.test(s[0])?s.concat(["center"]):c.test(s[0])?["center"].concat(s):["center","center"]),s[0]=h.test(s[0])?s[0]:"center",s[1]=c.test(s[1])?s[1]:"center",t=u.exec(s[0]),i=u.exec(s[1]),D[this]=[t?t[0]:0,i?i[0]:0],e[this]=[d.exec(s[0])[0],d.exec(s[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===e.at[0]?v.left+=p:"center"===e.at[0]&&(v.left+=p/2),"bottom"===e.at[1]?v.top+=g:"center"===e.at[1]&&(v.top+=g/2),a=i(D.at,p,g),v.left+=a[0],v.top+=a[1],this.each(function(){var n,h,c=t(this),u=c.outerWidth(),d=c.outerHeight(),f=s(this,"marginLeft"),_=s(this,"marginTop"),x=u+f+s(this,"marginRight")+k.width,C=d+_+s(this,"marginBottom")+k.height,M=t.extend({},v),T=i(D.my,c.outerWidth(),c.outerHeight());"right"===e.my[0]?M.left-=u:"center"===e.my[0]&&(M.left-=u/2),"bottom"===e.my[1]?M.top-=d:"center"===e.my[1]&&(M.top-=d/2),M.left+=T[0],M.top+=T[1],t.support.offsetFractions||(M.left=l(M.left),M.top=l(M.top)),n={marginLeft:f,marginTop:_},t.each(["left","top"],function(i,s){t.ui.position[w[i]]&&t.ui.position[w[i]][s](M,{targetWidth:p,targetHeight:g,elemWidth:u,elemHeight:d,collisionPosition:n,collisionWidth:x,collisionHeight:C,offset:[a[0]+T[0],a[1]+T[1]],my:e.my,at:e.at,within:y,elem:c})}),e.using&&(h=function(t){var i=m.left-M.left,s=i+p-u,n=m.top-M.top,a=n+g-d,l={target:{element:b,left:m.left,top:m.top,width:p,height:g},element:{element:c,left:M.left,top:M.top,width:u,height:d},horizontal:0>s?"left":i>0?"right":"center",vertical:0>a?"top":n>0?"bottom":"middle"};u>p&&p>r(i+s)&&(l.horizontal="center"),d>g&&g>r(n+a)&&(l.vertical="middle"),l.important=o(r(i),r(s))>o(r(n),r(a))?"horizontal":"vertical",e.using.call(this,t,l)}),c.offset(t.extend(M,{using:h}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,l=n-r,h=r+e.collisionWidth-a-n;e.collisionWidth>a?l>0&&0>=h?(i=t.left+l+e.collisionWidth-a-n,t.left+=l-i):t.left=h>0&&0>=l?n:l>h?n+a-e.collisionWidth:n:l>0?t.left+=l:h>0?t.left-=h:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,l=n-r,h=r+e.collisionHeight-a-n;e.collisionHeight>a?l>0&&0>=h?(i=t.top+l+e.collisionHeight-a-n,t.top+=l-i):t.top=h>0&&0>=l?n:l>h?n+a-e.collisionHeight:n:l>0?t.top+=l:h>0?t.top-=h:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,a=n.offset.left+n.scrollLeft,o=n.width,l=n.isWindow?n.scrollLeft:n.offset.left,h=t.left-e.collisionPosition.marginLeft,c=h-l,u=h+e.collisionWidth-o-l,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-o-a,(0>i||r(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-l,(s>0||u>r(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,a=n.offset.top+n.scrollTop,o=n.height,l=n.isWindow?n.scrollTop:n.offset.top,h=t.top-e.collisionPosition.marginTop,c=h-l,u=h+e.collisionHeight-o-l,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-o-a,t.top+p+f+g>c&&(0>s||r(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-l,t.top+p+f+g>u&&(i>0||u>r(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}},function(){var e,i,s,n,a,o=document.getElementsByTagName("body")[0],r=document.createElement("div");e=document.createElement(o?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},o&&t.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(a in s)e.style[a]=s[a];e.appendChild(r),i=o||document.documentElement,i.insertBefore(e,i.firstChild),r.style.cssText="position: absolute; left: 10.7432222px;",n=t(r).offset().left,t.support.offsetFractions=n>10&&11>n,e.innerHTML="",i.removeChild(e)}()})(jQuery);(function(e){var t=0,i={},a={};i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="hide",a.height=a.paddingTop=a.paddingBottom=a.borderTopWidth=a.borderBottomWidth="show",e.widget("ui.accordion",{version:"1.10.4",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var t=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),t.collapsible||t.active!==!1&&null!=t.active||(t.active=0),this._processPanels(),0>t.active&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():e(),content:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("<span>").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),e=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),"content"!==this.options.heightStyle&&e.css("height","")},_setOption:function(e,t){return"active"===e?(this._activate(t),undefined):("event"===e&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),"collapsible"!==e||t||this.options.active!==!1||this._activate(0),"icons"===e&&(this._destroyIcons(),t&&this._createIcons()),"disabled"===e&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t),undefined)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var i=e.ui.keyCode,a=this.headers.length,s=this.headers.index(t.target),n=!1;switch(t.keyCode){case i.RIGHT:case i.DOWN:n=this.headers[(s+1)%a];break;case i.LEFT:case i.UP:n=this.headers[(s-1+a)%a];break;case i.SPACE:case i.ENTER:this._eventHandler(t);break;case i.HOME:n=this.headers[0];break;case i.END:n=this.headers[a-1]}n&&(e(t.target).attr("tabIndex",-1),e(n).attr("tabIndex",0),n.focus(),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t=this.options;this._processPanels(),t.active===!1&&t.collapsible===!0||!this.headers.length?(t.active=!1,this.active=e()):t.active===!1?this._activate(0):this.active.length&&!e.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=e()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var i,a=this.options,s=a.heightStyle,n=this.element.parent(),r=this.accordionId="ui-accordion-"+(this.element.attr("id")||++t);this.active=this._findActive(a.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(t){var i=e(this),a=i.attr("id"),s=i.next(),n=s.attr("id");a||(a=r+"-header-"+t,i.attr("id",a)),n||(n=r+"-panel-"+t,s.attr("id",n)),i.attr("aria-controls",n),s.attr("aria-labelledby",a)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(a.event),"fill"===s?(i=n.height(),this.element.siblings(":visible").each(function(){var t=e(this),a=t.css("position");"absolute"!==a&&"fixed"!==a&&(i-=t.outerHeight(!0))}),this.headers.each(function(){i-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,i-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===s&&(i=0,this.headers.next().each(function(){i=Math.max(i,e(this).css("height","").height())}).height(i))},_activate:function(t){var i=this._findActive(t)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):e()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var i=this.options,a=this.active,s=e(t.currentTarget),n=s[0]===a[0],r=n&&i.collapsible,o=r?e():s.next(),h=a.next(),d={oldHeader:a,oldPanel:h,newHeader:r?e():s,newPanel:o};t.preventDefault(),n&&!i.collapsible||this._trigger("beforeActivate",t,d)===!1||(i.active=r?!1:this.headers.index(s),this.active=n?e():s,this._toggle(d),a.removeClass("ui-accordion-header-active ui-state-active"),i.icons&&a.children(".ui-accordion-header-icon").removeClass(i.icons.activeHeader).addClass(i.icons.header),n||(s.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),i.icons&&s.children(".ui-accordion-header-icon").removeClass(i.icons.header).addClass(i.icons.activeHeader),s.next().addClass("ui-accordion-content-active")))},_toggle:function(t){var i=t.newPanel,a=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=a,this.options.animate?this._animate(i,a,t):(a.hide(),i.show(),this._toggleComplete(t)),a.attr({"aria-hidden":"true"}),a.prev().attr("aria-selected","false"),i.length&&a.length?a.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true",tabIndex:0,"aria-expanded":"true"})},_animate:function(e,t,s){var n,r,o,h=this,d=0,c=e.length&&(!t.length||e.index()<t.index()),l=this.options.animate||{},u=c&&l.down||l,v=function(){h._toggleComplete(s)};return"number"==typeof u&&(o=u),"string"==typeof u&&(r=u),r=r||u.easing||l.easing,o=o||u.duration||l.duration,t.length?e.length?(n=e.show().outerHeight(),t.animate(i,{duration:o,easing:r,step:function(e,t){t.now=Math.round(e)}}),e.hide().animate(a,{duration:o,easing:r,complete:v,step:function(e,i){i.now=Math.round(e),"height"!==i.prop?d+=i.now:"content"!==h.options.heightStyle&&(i.now=Math.round(n-t.outerHeight()-d),d=0)}}),undefined):t.animate(i,o,r,v):e.animate(a,o,r,v)},_toggleComplete:function(e){var t=e.oldPanel;t.removeClass("ui-accordion-content-active").prev().removeClass("ui-corner-top").addClass("ui-corner-all"),t.length&&(t.parent()[0].className=t.parent()[0].className),this._trigger("activate",null,e)}})})(jQuery);(function(e){e.widget("ui.autocomplete",{version:"1.10.4",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var t,i,s,n=this.element[0].nodeName.toLowerCase(),a="textarea"===n,o="input"===n;this.isMultiLine=a?!0:o?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[a||o?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return t=!0,s=!0,i=!0,undefined;t=!1,s=!1,i=!1;var a=e.ui.keyCode;switch(n.keyCode){case a.PAGE_UP:t=!0,this._move("previousPage",n);break;case a.PAGE_DOWN:t=!0,this._move("nextPage",n);break;case a.UP:t=!0,this._keyEvent("previous",n);break;case a.DOWN:t=!0,this._keyEvent("next",n);break;case a.ENTER:case a.NUMPAD_ENTER:this.menu.active&&(t=!0,n.preventDefault(),this.menu.select(n));break;case a.TAB:this.menu.active&&this.menu.select(n);break;case a.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(t)return t=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),undefined;if(!i){var n=e.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(e){return s?(s=!1,e.preventDefault(),undefined):(this._searchTimeout(e),undefined)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){return this.cancelBlur?(delete this.cancelBlur,undefined):(clearTimeout(this.searching),this.close(e),this._change(e),undefined)}}),this._initSource(),this.menu=e("<ul>").addClass("ui-autocomplete ui-front").appendTo(this._appendTo()).menu({role:null}).hide().data("ui-menu"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur});var i=this.menu.element[0];e(t.target).closest(".ui-menu-item").length||this._delay(function(){var t=this;this.document.one("mousedown",function(s){s.target===t.element[0]||s.target===i||e.contains(i,s.target)||t.close()})})},menufocus:function(t,i){if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),this.document.one("mousemove",function(){e(t.target).trigger(t.originalEvent)}),undefined;var s=i.item.data("ui-autocomplete-item");!1!==this._trigger("focus",t,{item:s})?t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value):this.liveRegion.text(s.value)},menuselect:function(e,t){var i=t.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==this.document[0].activeElement&&(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",e,{item:i})&&this._value(i.value),this.term=this._value(),this.close(e),this.selectedItem=i}}),this.liveRegion=e("<span>",{role:"status","aria-live":"polite"}).addClass("ui-helper-hidden-accessible").insertBefore(this.element),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(e,t){this._super(e,t),"source"===e&&this._initSource(),"appendTo"===e&&this.menu.element.appendTo(this._appendTo()),"disabled"===e&&t&&this.xhr&&this.xhr.abort()},_appendTo:function(){var t=this.options.appendTo;return t&&(t=t.jquery||t.nodeType?e(t):this.document.find(t).eq(0)),t||(t=this.element.closest(".ui-front")),t.length||(t=this.document[0].body),t},_initSource:function(){var t,i,s=this;e.isArray(this.options.source)?(t=this.options.source,this.source=function(i,s){s(e.ui.autocomplete.filter(t,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(t,n){s.xhr&&s.xhr.abort(),s.xhr=e.ajax({url:i,data:t,dataType:"json",success:function(e){n(e)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(e){clearTimeout(this.searching),this.searching=this._delay(function(){this.term!==this._value()&&(this.selectedItem=null,this.search(null,e))},this.options.delay)},search:function(e,t){return e=null!=e?e:this._value(),this.term=this._value(),e.length<this.options.minLength?this.close(t):this._trigger("search",t)!==!1?this._search(e):undefined},_search:function(e){this.pending++,this.element.addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:e},this._response())},_response:function(){var t=++this.requestIndex;return e.proxy(function(e){t===this.requestIndex&&this.__response(e),this.pending--,this.pending||this.element.removeClass("ui-autocomplete-loading")},this)},__response:function(e){e&&(e=this._normalize(e)),this._trigger("response",null,{content:e}),!this.options.disabled&&e&&e.length&&!this.cancelSearch?(this._suggest(e),this._trigger("open")):this._close()},close:function(e){this.cancelSearch=!0,this._close(e)},_close:function(e){this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",e))},_change:function(e){this.previous!==this._value()&&this._trigger("change",e,{item:this.selectedItem})},_normalize:function(t){return t.length&&t[0].label&&t[0].value?t:e.map(t,function(t){return"string"==typeof t?{label:t,value:t}:e.extend({label:t.label||t.value,value:t.value||t.label},t)})},_suggest:function(t){var i=this.menu.element.empty();this._renderMenu(i,t),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(e.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next()},_resizeMenu:function(){var e=this.menu.element;e.outerWidth(Math.max(e.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(t,i){var s=this;e.each(i,function(e,i){s._renderItemData(t,i)})},_renderItemData:function(e,t){return this._renderItem(e,t).data("ui-autocomplete-item",t)},_renderItem:function(t,i){return e("<li>").append(e("<a>").text(i.label)).appendTo(t)},_move:function(e,t){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(e)||this.menu.isLastItem()&&/^next/.test(e)?(this._value(this.term),this.menu.blur(),undefined):(this.menu[e](t),undefined):(this.search(null,t),undefined)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(e,t){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(e,t),t.preventDefault())}}),e.extend(e.ui.autocomplete,{escapeRegex:function(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,i){var s=RegExp(e.ui.autocomplete.escapeRegex(i),"i");return e.grep(t,function(e){return s.test(e.label||e.value||e)})}}),e.widget("ui.autocomplete",e.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(e){return e+(e>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var t;this._superApply(arguments),this.options.disabled||this.cancelSearch||(t=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.text(t))}})})(jQuery);(function(e){var t,i="ui-button ui-widget ui-state-default ui-corner-all",n="ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",s=function(){var t=e(this);setTimeout(function(){t.find(":ui-button").button("refresh")},1)},a=function(t){var i=t.name,n=t.form,s=e([]);return i&&(i=i.replace(/'/g,"\\'"),s=n?e(n).find("[name='"+i+"']"):e("[name='"+i+"']",t.ownerDocument).filter(function(){return!this.form})),s};e.widget("ui.button",{version:"1.10.4",defaultElement:"<button>",options:{disabled:null,text:!0,label:null,icons:{primary:null,secondary:null}},_create:function(){this.element.closest("form").unbind("reset"+this.eventNamespace).bind("reset"+this.eventNamespace,s),"boolean"!=typeof this.options.disabled?this.options.disabled=!!this.element.prop("disabled"):this.element.prop("disabled",this.options.disabled),this._determineButtonType(),this.hasTitle=!!this.buttonElement.attr("title");var n=this,o=this.options,r="checkbox"===this.type||"radio"===this.type,h=r?"":"ui-state-active";null===o.label&&(o.label="input"===this.type?this.buttonElement.val():this.buttonElement.html()),this._hoverable(this.buttonElement),this.buttonElement.addClass(i).attr("role","button").bind("mouseenter"+this.eventNamespace,function(){o.disabled||this===t&&e(this).addClass("ui-state-active")}).bind("mouseleave"+this.eventNamespace,function(){o.disabled||e(this).removeClass(h)}).bind("click"+this.eventNamespace,function(e){o.disabled&&(e.preventDefault(),e.stopImmediatePropagation())}),this._on({focus:function(){this.buttonElement.addClass("ui-state-focus")},blur:function(){this.buttonElement.removeClass("ui-state-focus")}}),r&&this.element.bind("change"+this.eventNamespace,function(){n.refresh()}),"checkbox"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){return o.disabled?!1:undefined}):"radio"===this.type?this.buttonElement.bind("click"+this.eventNamespace,function(){if(o.disabled)return!1;e(this).addClass("ui-state-active"),n.buttonElement.attr("aria-pressed","true");var t=n.element[0];a(t).not(t).map(function(){return e(this).button("widget")[0]}).removeClass("ui-state-active").attr("aria-pressed","false")}):(this.buttonElement.bind("mousedown"+this.eventNamespace,function(){return o.disabled?!1:(e(this).addClass("ui-state-active"),t=this,n.document.one("mouseup",function(){t=null}),undefined)}).bind("mouseup"+this.eventNamespace,function(){return o.disabled?!1:(e(this).removeClass("ui-state-active"),undefined)}).bind("keydown"+this.eventNamespace,function(t){return o.disabled?!1:((t.keyCode===e.ui.keyCode.SPACE||t.keyCode===e.ui.keyCode.ENTER)&&e(this).addClass("ui-state-active"),undefined)}).bind("keyup"+this.eventNamespace+" blur"+this.eventNamespace,function(){e(this).removeClass("ui-state-active")}),this.buttonElement.is("a")&&this.buttonElement.keyup(function(t){t.keyCode===e.ui.keyCode.SPACE&&e(this).click()})),this._setOption("disabled",o.disabled),this._resetButton()},_determineButtonType:function(){var e,t,i;this.type=this.element.is("[type=checkbox]")?"checkbox":this.element.is("[type=radio]")?"radio":this.element.is("input")?"input":"button","checkbox"===this.type||"radio"===this.type?(e=this.element.parents().last(),t="label[for='"+this.element.attr("id")+"']",this.buttonElement=e.find(t),this.buttonElement.length||(e=e.length?e.siblings():this.element.siblings(),this.buttonElement=e.filter(t),this.buttonElement.length||(this.buttonElement=e.find(t))),this.element.addClass("ui-helper-hidden-accessible"),i=this.element.is(":checked"),i&&this.buttonElement.addClass("ui-state-active"),this.buttonElement.prop("aria-pressed",i)):this.buttonElement=this.element},widget:function(){return this.buttonElement},_destroy:function(){this.element.removeClass("ui-helper-hidden-accessible"),this.buttonElement.removeClass(i+" ui-state-active "+n).removeAttr("role").removeAttr("aria-pressed").html(this.buttonElement.find(".ui-button-text").html()),this.hasTitle||this.buttonElement.removeAttr("title")},_setOption:function(e,t){return this._super(e,t),"disabled"===e?(this.element.prop("disabled",!!t),t&&this.buttonElement.removeClass("ui-state-focus"),undefined):(this._resetButton(),undefined)},refresh:function(){var t=this.element.is("input, button")?this.element.is(":disabled"):this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOption("disabled",t),"radio"===this.type?a(this.element[0]).each(function(){e(this).is(":checked")?e(this).button("widget").addClass("ui-state-active").attr("aria-pressed","true"):e(this).button("widget").removeClass("ui-state-active").attr("aria-pressed","false")}):"checkbox"===this.type&&(this.element.is(":checked")?this.buttonElement.addClass("ui-state-active").attr("aria-pressed","true"):this.buttonElement.removeClass("ui-state-active").attr("aria-pressed","false"))},_resetButton:function(){if("input"===this.type)return this.options.label&&this.element.val(this.options.label),undefined;var t=this.buttonElement.removeClass(n),i=e("<span></span>",this.document[0]).addClass("ui-button-text").html(this.options.label).appendTo(t.empty()).text(),s=this.options.icons,a=s.primary&&s.secondary,o=[];s.primary||s.secondary?(this.options.text&&o.push("ui-button-text-icon"+(a?"s":s.primary?"-primary":"-secondary")),s.primary&&t.prepend("<span class='ui-button-icon-primary ui-icon "+s.primary+"'></span>"),s.secondary&&t.append("<span class='ui-button-icon-secondary ui-icon "+s.secondary+"'></span>"),this.options.text||(o.push(a?"ui-button-icons-only":"ui-button-icon-only"),this.hasTitle||t.attr("title",e.trim(i)))):o.push("ui-button-text-only"),t.addClass(o.join(" "))}}),e.widget("ui.buttonset",{version:"1.10.4",options:{items:"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(e,t){"disabled"===e&&this.buttons.button("option",e,t),this._super(e,t)},refresh:function(){var t="rtl"===this.element.css("direction");this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(t?"ui-corner-right":"ui-corner-left").end().filter(":last").addClass(t?"ui-corner-left":"ui-corner-right").end().end()},_destroy:function(){this.element.removeClass("ui-buttonset"),this.buttons.map(function(){return e(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy")}})})(jQuery);(function(e,t){function i(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},e.extend(this._defaults,this.regional[""]),this.dpDiv=a(e("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function a(t){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return t.delegate(i,"mouseout",function(){e(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).removeClass("ui-datepicker-next-hover")}).delegate(i,"mouseover",function(){e.datepicker._isDisabledDatepicker(n.inline?t.parent()[0]:n.input[0])||(e(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),e(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&e(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&e(this).addClass("ui-datepicker-next-hover"))})}function s(t,i){e.extend(t,i);for(var a in i)null==i[a]&&(t[a]=i[a]);return t}e.extend(e.ui,{datepicker:{version:"1.10.4"}});var n,r="datepicker";e.extend(i.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(e){return s(this._defaults,e||{}),this},_attachDatepicker:function(t,i){var a,s,n;a=t.nodeName.toLowerCase(),s="div"===a||"span"===a,t.id||(this.uuid+=1,t.id="dp"+this.uuid),n=this._newInst(e(t),s),n.settings=e.extend({},i||{}),"input"===a?this._connectDatepicker(t,n):s&&this._inlineDatepicker(t,n)},_newInst:function(t,i){var s=t[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:s,input:t,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?a(e("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(t,i){var a=e(t);i.append=e([]),i.trigger=e([]),a.hasClass(this.markerClassName)||(this._attachments(a,i),a.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp),this._autoSize(i),e.data(t,r,i),i.settings.disabled&&this._disableDatepicker(t))},_attachments:function(t,i){var a,s,n,r=this._get(i,"appendText"),o=this._get(i,"isRTL");i.append&&i.append.remove(),r&&(i.append=e("<span class='"+this._appendClass+"'>"+r+"</span>"),t[o?"before":"after"](i.append)),t.unbind("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),a=this._get(i,"showOn"),("focus"===a||"both"===a)&&t.focus(this._showDatepicker),("button"===a||"both"===a)&&(s=this._get(i,"buttonText"),n=this._get(i,"buttonImage"),i.trigger=e(this._get(i,"buttonImageOnly")?e("<img/>").addClass(this._triggerClass).attr({src:n,alt:s,title:s}):e("<button type='button'></button>").addClass(this._triggerClass).html(n?e("<img/>").attr({src:n,alt:s,title:s}):s)),t[o?"before":"after"](i.trigger),i.trigger.click(function(){return e.datepicker._datepickerShowing&&e.datepicker._lastInput===t[0]?e.datepicker._hideDatepicker():e.datepicker._datepickerShowing&&e.datepicker._lastInput!==t[0]?(e.datepicker._hideDatepicker(),e.datepicker._showDatepicker(t[0])):e.datepicker._showDatepicker(t[0]),!1}))},_autoSize:function(e){if(this._get(e,"autoSize")&&!e.inline){var t,i,a,s,n=new Date(2009,11,20),r=this._get(e,"dateFormat");r.match(/[DM]/)&&(t=function(e){for(i=0,a=0,s=0;e.length>s;s++)e[s].length>i&&(i=e[s].length,a=s);return a},n.setMonth(t(this._get(e,r.match(/MM/)?"monthNames":"monthNamesShort"))),n.setDate(t(this._get(e,r.match(/DD/)?"dayNames":"dayNamesShort"))+20-n.getDay())),e.input.attr("size",this._formatDate(e,n).length)}},_inlineDatepicker:function(t,i){var a=e(t);a.hasClass(this.markerClassName)||(a.addClass(this.markerClassName).append(i.dpDiv),e.data(t,r,i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(t),i.dpDiv.css("display","block"))},_dialogDatepicker:function(t,i,a,n,o){var u,c,h,l,d,p=this._dialogInst;return p||(this.uuid+=1,u="dp"+this.uuid,this._dialogInput=e("<input type='text' id='"+u+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.keydown(this._doKeyDown),e("body").append(this._dialogInput),p=this._dialogInst=this._newInst(this._dialogInput,!1),p.settings={},e.data(this._dialogInput[0],r,p)),s(p.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(p,i):i,this._dialogInput.val(i),this._pos=o?o.length?o:[o.pageX,o.pageY]:null,this._pos||(c=document.documentElement.clientWidth,h=document.documentElement.clientHeight,l=document.documentElement.scrollLeft||document.body.scrollLeft,d=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[c/2-100+l,h/2-150+d]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),p.settings.onSelect=a,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),e.blockUI&&e.blockUI(this.dpDiv),e.data(this._dialogInput[0],r,p),this},_destroyDatepicker:function(t){var i,a=e(t),s=e.data(t,r);a.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),e.removeData(t,r),"input"===i?(s.append.remove(),s.trigger.remove(),a.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"===i||"span"===i)&&a.removeClass(this.markerClassName).empty())},_enableDatepicker:function(t){var i,a,s=e(t),n=e.data(t,r);s.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!1,n.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(a=s.children("."+this._inlineClass),a.children().removeClass("ui-state-disabled"),a.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}))},_disableDatepicker:function(t){var i,a,s=e(t),n=e.data(t,r);s.hasClass(this.markerClassName)&&(i=t.nodeName.toLowerCase(),"input"===i?(t.disabled=!0,n.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(a=s.children("."+this._inlineClass),a.children().addClass("ui-state-disabled"),a.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=e.map(this._disabledInputs,function(e){return e===t?null:e}),this._disabledInputs[this._disabledInputs.length]=t)},_isDisabledDatepicker:function(e){if(!e)return!1;for(var t=0;this._disabledInputs.length>t;t++)if(this._disabledInputs[t]===e)return!0;return!1},_getInst:function(t){try{return e.data(t,r)}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(i,a,n){var r,o,u,c,h=this._getInst(i);return 2===arguments.length&&"string"==typeof a?"defaults"===a?e.extend({},e.datepicker._defaults):h?"all"===a?e.extend({},h.settings):this._get(h,a):null:(r=a||{},"string"==typeof a&&(r={},r[a]=n),h&&(this._curInst===h&&this._hideDatepicker(),o=this._getDateDatepicker(i,!0),u=this._getMinMaxDate(h,"min"),c=this._getMinMaxDate(h,"max"),s(h.settings,r),null!==u&&r.dateFormat!==t&&r.minDate===t&&(h.settings.minDate=this._formatDate(h,u)),null!==c&&r.dateFormat!==t&&r.maxDate===t&&(h.settings.maxDate=this._formatDate(h,c)),"disabled"in r&&(r.disabled?this._disableDatepicker(i):this._enableDatepicker(i)),this._attachments(e(i),h),this._autoSize(h),this._setDate(h,o),this._updateAlternate(h),this._updateDatepicker(h)),t)},_changeDatepicker:function(e,t,i){this._optionDatepicker(e,t,i)},_refreshDatepicker:function(e){var t=this._getInst(e);t&&this._updateDatepicker(t)},_setDateDatepicker:function(e,t){var i=this._getInst(e);i&&(this._setDate(i,t),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(e,t){var i=this._getInst(e);return i&&!i.inline&&this._setDateFromField(i,t),i?this._getDate(i):null},_doKeyDown:function(t){var i,a,s,n=e.datepicker._getInst(t.target),r=!0,o=n.dpDiv.is(".ui-datepicker-rtl");if(n._keyEvent=!0,e.datepicker._datepickerShowing)switch(t.keyCode){case 9:e.datepicker._hideDatepicker(),r=!1;break;case 13:return s=e("td."+e.datepicker._dayOverClass+":not(."+e.datepicker._currentClass+")",n.dpDiv),s[0]&&e.datepicker._selectDay(t.target,n.selectedMonth,n.selectedYear,s[0]),i=e.datepicker._get(n,"onSelect"),i?(a=e.datepicker._formatDate(n),i.apply(n.input?n.input[0]:null,[a,n])):e.datepicker._hideDatepicker(),!1;case 27:e.datepicker._hideDatepicker();break;case 33:e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(n,"stepBigMonths"):-e.datepicker._get(n,"stepMonths"),"M");break;case 34:e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(n,"stepBigMonths"):+e.datepicker._get(n,"stepMonths"),"M");break;case 35:(t.ctrlKey||t.metaKey)&&e.datepicker._clearDate(t.target),r=t.ctrlKey||t.metaKey;break;case 36:(t.ctrlKey||t.metaKey)&&e.datepicker._gotoToday(t.target),r=t.ctrlKey||t.metaKey;break;case 37:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,o?1:-1,"D"),r=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?-e.datepicker._get(n,"stepBigMonths"):-e.datepicker._get(n,"stepMonths"),"M");break;case 38:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,-7,"D"),r=t.ctrlKey||t.metaKey;break;case 39:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,o?-1:1,"D"),r=t.ctrlKey||t.metaKey,t.originalEvent.altKey&&e.datepicker._adjustDate(t.target,t.ctrlKey?+e.datepicker._get(n,"stepBigMonths"):+e.datepicker._get(n,"stepMonths"),"M");break;case 40:(t.ctrlKey||t.metaKey)&&e.datepicker._adjustDate(t.target,7,"D"),r=t.ctrlKey||t.metaKey;break;default:r=!1}else 36===t.keyCode&&t.ctrlKey?e.datepicker._showDatepicker(this):r=!1;r&&(t.preventDefault(),t.stopPropagation())},_doKeyPress:function(i){var a,s,n=e.datepicker._getInst(i.target);return e.datepicker._get(n,"constrainInput")?(a=e.datepicker._possibleChars(e.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==i.charCode?i.keyCode:i.charCode),i.ctrlKey||i.metaKey||" ">s||!a||a.indexOf(s)>-1):t},_doKeyUp:function(t){var i,a=e.datepicker._getInst(t.target);if(a.input.val()!==a.lastVal)try{i=e.datepicker.parseDate(e.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,e.datepicker._getFormatConfig(a)),i&&(e.datepicker._setDateFromField(a),e.datepicker._updateAlternate(a),e.datepicker._updateDatepicker(a))}catch(s){}return!0},_showDatepicker:function(t){if(t=t.target||t,"input"!==t.nodeName.toLowerCase()&&(t=e("input",t.parentNode)[0]),!e.datepicker._isDisabledDatepicker(t)&&e.datepicker._lastInput!==t){var i,a,n,r,o,u,c;i=e.datepicker._getInst(t),e.datepicker._curInst&&e.datepicker._curInst!==i&&(e.datepicker._curInst.dpDiv.stop(!0,!0),i&&e.datepicker._datepickerShowing&&e.datepicker._hideDatepicker(e.datepicker._curInst.input[0])),a=e.datepicker._get(i,"beforeShow"),n=a?a.apply(t,[t,i]):{},n!==!1&&(s(i.settings,n),i.lastVal=null,e.datepicker._lastInput=t,e.datepicker._setDateFromField(i),e.datepicker._inDialog&&(t.value=""),e.datepicker._pos||(e.datepicker._pos=e.datepicker._findPos(t),e.datepicker._pos[1]+=t.offsetHeight),r=!1,e(t).parents().each(function(){return r|="fixed"===e(this).css("position"),!r}),o={left:e.datepicker._pos[0],top:e.datepicker._pos[1]},e.datepicker._pos=null,i.dpDiv.empty(),i.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),e.datepicker._updateDatepicker(i),o=e.datepicker._checkOffset(i,o,r),i.dpDiv.css({position:e.datepicker._inDialog&&e.blockUI?"static":r?"fixed":"absolute",display:"none",left:o.left+"px",top:o.top+"px"}),i.inline||(u=e.datepicker._get(i,"showAnim"),c=e.datepicker._get(i,"duration"),i.dpDiv.zIndex(e(t).zIndex()+1),e.datepicker._datepickerShowing=!0,e.effects&&e.effects.effect[u]?i.dpDiv.show(u,e.datepicker._get(i,"showOptions"),c):i.dpDiv[u||"show"](u?c:null),e.datepicker._shouldFocusInput(i)&&i.input.focus(),e.datepicker._curInst=i))}},_updateDatepicker:function(t){this.maxRows=4,n=t,t.dpDiv.empty().append(this._generateHTML(t)),this._attachHandlers(t),t.dpDiv.find("."+this._dayOverClass+" a").mouseover();var i,a=this._getNumberOfMonths(t),s=a[1],r=17;t.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),s>1&&t.dpDiv.addClass("ui-datepicker-multi-"+s).css("width",r*s+"em"),t.dpDiv[(1!==a[0]||1!==a[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),t.dpDiv[(this._get(t,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),t===e.datepicker._curInst&&e.datepicker._datepickerShowing&&e.datepicker._shouldFocusInput(t)&&t.input.focus(),t.yearshtml&&(i=t.yearshtml,setTimeout(function(){i===t.yearshtml&&t.yearshtml&&t.dpDiv.find("select.ui-datepicker-year:first").replaceWith(t.yearshtml),i=t.yearshtml=null},0))},_shouldFocusInput:function(e){return e.input&&e.input.is(":visible")&&!e.input.is(":disabled")&&!e.input.is(":focus")},_checkOffset:function(t,i,a){var s=t.dpDiv.outerWidth(),n=t.dpDiv.outerHeight(),r=t.input?t.input.outerWidth():0,o=t.input?t.input.outerHeight():0,u=document.documentElement.clientWidth+(a?0:e(document).scrollLeft()),c=document.documentElement.clientHeight+(a?0:e(document).scrollTop());return i.left-=this._get(t,"isRTL")?s-r:0,i.left-=a&&i.left===t.input.offset().left?e(document).scrollLeft():0,i.top-=a&&i.top===t.input.offset().top+o?e(document).scrollTop():0,i.left-=Math.min(i.left,i.left+s>u&&u>s?Math.abs(i.left+s-u):0),i.top-=Math.min(i.top,i.top+n>c&&c>n?Math.abs(n+o):0),i},_findPos:function(t){for(var i,a=this._getInst(t),s=this._get(a,"isRTL");t&&("hidden"===t.type||1!==t.nodeType||e.expr.filters.hidden(t));)t=t[s?"previousSibling":"nextSibling"];return i=e(t).offset(),[i.left,i.top]},_hideDatepicker:function(t){var i,a,s,n,o=this._curInst;!o||t&&o!==e.data(t,r)||this._datepickerShowing&&(i=this._get(o,"showAnim"),a=this._get(o,"duration"),s=function(){e.datepicker._tidyDialog(o)},e.effects&&(e.effects.effect[i]||e.effects[i])?o.dpDiv.hide(i,e.datepicker._get(o,"showOptions"),a,s):o.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?a:null,s),i||s(),this._datepickerShowing=!1,n=this._get(o,"onClose"),n&&n.apply(o.input?o.input[0]:null,[o.input?o.input.val():"",o]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),e.blockUI&&(e.unblockUI(),e("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(e){e.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(t){if(e.datepicker._curInst){var i=e(t.target),a=e.datepicker._getInst(i[0]);(i[0].id!==e.datepicker._mainDivId&&0===i.parents("#"+e.datepicker._mainDivId).length&&!i.hasClass(e.datepicker.markerClassName)&&!i.closest("."+e.datepicker._triggerClass).length&&e.datepicker._datepickerShowing&&(!e.datepicker._inDialog||!e.blockUI)||i.hasClass(e.datepicker.markerClassName)&&e.datepicker._curInst!==a)&&e.datepicker._hideDatepicker()}},_adjustDate:function(t,i,a){var s=e(t),n=this._getInst(s[0]);this._isDisabledDatepicker(s[0])||(this._adjustInstDate(n,i+("M"===a?this._get(n,"showCurrentAtPos"):0),a),this._updateDatepicker(n))},_gotoToday:function(t){var i,a=e(t),s=this._getInst(a[0]);this._get(s,"gotoCurrent")&&s.currentDay?(s.selectedDay=s.currentDay,s.drawMonth=s.selectedMonth=s.currentMonth,s.drawYear=s.selectedYear=s.currentYear):(i=new Date,s.selectedDay=i.getDate(),s.drawMonth=s.selectedMonth=i.getMonth(),s.drawYear=s.selectedYear=i.getFullYear()),this._notifyChange(s),this._adjustDate(a)},_selectMonthYear:function(t,i,a){var s=e(t),n=this._getInst(s[0]);n["selected"+("M"===a?"Month":"Year")]=n["draw"+("M"===a?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(n),this._adjustDate(s)},_selectDay:function(t,i,a,s){var n,r=e(t);e(s).hasClass(this._unselectableClass)||this._isDisabledDatepicker(r[0])||(n=this._getInst(r[0]),n.selectedDay=n.currentDay=e("a",s).html(),n.selectedMonth=n.currentMonth=i,n.selectedYear=n.currentYear=a,this._selectDate(t,this._formatDate(n,n.currentDay,n.currentMonth,n.currentYear)))},_clearDate:function(t){var i=e(t);this._selectDate(i,"")},_selectDate:function(t,i){var a,s=e(t),n=this._getInst(s[0]);i=null!=i?i:this._formatDate(n),n.input&&n.input.val(i),this._updateAlternate(n),a=this._get(n,"onSelect"),a?a.apply(n.input?n.input[0]:null,[i,n]):n.input&&n.input.trigger("change"),n.inline?this._updateDatepicker(n):(this._hideDatepicker(),this._lastInput=n.input[0],"object"!=typeof n.input[0]&&n.input.focus(),this._lastInput=null)},_updateAlternate:function(t){var i,a,s,n=this._get(t,"altField");n&&(i=this._get(t,"altFormat")||this._get(t,"dateFormat"),a=this._getDate(t),s=this.formatDate(i,a,this._getFormatConfig(t)),e(n).each(function(){e(this).val(s)}))},noWeekends:function(e){var t=e.getDay();return[t>0&&6>t,""]},iso8601Week:function(e){var t,i=new Date(e.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),t=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((t-i)/864e5)/7)+1},parseDate:function(i,a,s){if(null==i||null==a)throw"Invalid arguments";if(a="object"==typeof a?""+a:a+"",""===a)return null;var n,r,o,u,c=0,h=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,l="string"!=typeof h?h:(new Date).getFullYear()%100+parseInt(h,10),d=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,p=(s?s.dayNames:null)||this._defaults.dayNames,g=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,m=(s?s.monthNames:null)||this._defaults.monthNames,f=-1,_=-1,v=-1,k=-1,y=!1,b=function(e){var t=i.length>n+1&&i.charAt(n+1)===e;return t&&n++,t},D=function(e){var t=b(e),i="@"===e?14:"!"===e?20:"y"===e&&t?4:"o"===e?3:2,s=RegExp("^\\d{1,"+i+"}"),n=a.substring(c).match(s);if(!n)throw"Missing number at position "+c;return c+=n[0].length,parseInt(n[0],10)},w=function(i,s,n){var r=-1,o=e.map(b(i)?n:s,function(e,t){return[[t,e]]}).sort(function(e,t){return-(e[1].length-t[1].length)});if(e.each(o,function(e,i){var s=i[1];return a.substr(c,s.length).toLowerCase()===s.toLowerCase()?(r=i[0],c+=s.length,!1):t}),-1!==r)return r+1;throw"Unknown name at position "+c},M=function(){if(a.charAt(c)!==i.charAt(n))throw"Unexpected literal at position "+c;c++};for(n=0;i.length>n;n++)if(y)"'"!==i.charAt(n)||b("'")?M():y=!1;else switch(i.charAt(n)){case"d":v=D("d");break;case"D":w("D",d,p);break;case"o":k=D("o");break;case"m":_=D("m");break;case"M":_=w("M",g,m);break;case"y":f=D("y");break;case"@":u=new Date(D("@")),f=u.getFullYear(),_=u.getMonth()+1,v=u.getDate();break;case"!":u=new Date((D("!")-this._ticksTo1970)/1e4),f=u.getFullYear(),_=u.getMonth()+1,v=u.getDate();break;case"'":b("'")?M():y=!0;break;default:M()}if(a.length>c&&(o=a.substr(c),!/^\s+/.test(o)))throw"Extra/unparsed characters found in date: "+o;if(-1===f?f=(new Date).getFullYear():100>f&&(f+=(new Date).getFullYear()-(new Date).getFullYear()%100+(l>=f?0:-100)),k>-1)for(_=1,v=k;;){if(r=this._getDaysInMonth(f,_-1),r>=v)break;_++,v-=r}if(u=this._daylightSavingAdjust(new Date(f,_-1,v)),u.getFullYear()!==f||u.getMonth()+1!==_||u.getDate()!==v)throw"Invalid date";return u},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(e,t,i){if(!t)return"";var a,s=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,n=(i?i.dayNames:null)||this._defaults.dayNames,r=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,o=(i?i.monthNames:null)||this._defaults.monthNames,u=function(t){var i=e.length>a+1&&e.charAt(a+1)===t;return i&&a++,i},c=function(e,t,i){var a=""+t;if(u(e))for(;i>a.length;)a="0"+a;return a},h=function(e,t,i,a){return u(e)?a[t]:i[t]},l="",d=!1;if(t)for(a=0;e.length>a;a++)if(d)"'"!==e.charAt(a)||u("'")?l+=e.charAt(a):d=!1;else switch(e.charAt(a)){case"d":l+=c("d",t.getDate(),2);break;case"D":l+=h("D",t.getDay(),s,n);break;case"o":l+=c("o",Math.round((new Date(t.getFullYear(),t.getMonth(),t.getDate()).getTime()-new Date(t.getFullYear(),0,0).getTime())/864e5),3);break;case"m":l+=c("m",t.getMonth()+1,2);break;case"M":l+=h("M",t.getMonth(),r,o);break;case"y":l+=u("y")?t.getFullYear():(10>t.getYear()%100?"0":"")+t.getYear()%100;break;case"@":l+=t.getTime();break;case"!":l+=1e4*t.getTime()+this._ticksTo1970;break;case"'":u("'")?l+="'":d=!0;break;default:l+=e.charAt(a)}return l},_possibleChars:function(e){var t,i="",a=!1,s=function(i){var a=e.length>t+1&&e.charAt(t+1)===i;return a&&t++,a};for(t=0;e.length>t;t++)if(a)"'"!==e.charAt(t)||s("'")?i+=e.charAt(t):a=!1;else switch(e.charAt(t)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":s("'")?i+="'":a=!0;break;default:i+=e.charAt(t)}return i},_get:function(e,i){return e.settings[i]!==t?e.settings[i]:this._defaults[i]},_setDateFromField:function(e,t){if(e.input.val()!==e.lastVal){var i=this._get(e,"dateFormat"),a=e.lastVal=e.input?e.input.val():null,s=this._getDefaultDate(e),n=s,r=this._getFormatConfig(e);try{n=this.parseDate(i,a,r)||s}catch(o){a=t?"":a}e.selectedDay=n.getDate(),e.drawMonth=e.selectedMonth=n.getMonth(),e.drawYear=e.selectedYear=n.getFullYear(),e.currentDay=a?n.getDate():0,e.currentMonth=a?n.getMonth():0,e.currentYear=a?n.getFullYear():0,this._adjustInstDate(e)}},_getDefaultDate:function(e){return this._restrictMinMax(e,this._determineDate(e,this._get(e,"defaultDate"),new Date))},_determineDate:function(t,i,a){var s=function(e){var t=new Date;return t.setDate(t.getDate()+e),t},n=function(i){try{return e.datepicker.parseDate(e.datepicker._get(t,"dateFormat"),i,e.datepicker._getFormatConfig(t))}catch(a){}for(var s=(i.toLowerCase().match(/^c/)?e.datepicker._getDate(t):null)||new Date,n=s.getFullYear(),r=s.getMonth(),o=s.getDate(),u=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,c=u.exec(i);c;){switch(c[2]||"d"){case"d":case"D":o+=parseInt(c[1],10);break;case"w":case"W":o+=7*parseInt(c[1],10);break;case"m":case"M":r+=parseInt(c[1],10),o=Math.min(o,e.datepicker._getDaysInMonth(n,r));break;case"y":case"Y":n+=parseInt(c[1],10),o=Math.min(o,e.datepicker._getDaysInMonth(n,r))}c=u.exec(i)}return new Date(n,r,o)},r=null==i||""===i?a:"string"==typeof i?n(i):"number"==typeof i?isNaN(i)?a:s(i):new Date(i.getTime());return r=r&&"Invalid Date"==""+r?a:r,r&&(r.setHours(0),r.setMinutes(0),r.setSeconds(0),r.setMilliseconds(0)),this._daylightSavingAdjust(r)},_daylightSavingAdjust:function(e){return e?(e.setHours(e.getHours()>12?e.getHours()+2:0),e):null},_setDate:function(e,t,i){var a=!t,s=e.selectedMonth,n=e.selectedYear,r=this._restrictMinMax(e,this._determineDate(e,t,new Date));e.selectedDay=e.currentDay=r.getDate(),e.drawMonth=e.selectedMonth=e.currentMonth=r.getMonth(),e.drawYear=e.selectedYear=e.currentYear=r.getFullYear(),s===e.selectedMonth&&n===e.selectedYear||i||this._notifyChange(e),this._adjustInstDate(e),e.input&&e.input.val(a?"":this._formatDate(e))},_getDate:function(e){var t=!e.currentYear||e.input&&""===e.input.val()?null:this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return t},_attachHandlers:function(t){var i=this._get(t,"stepMonths"),a="#"+t.id.replace(/\\\\/g,"\\");t.dpDiv.find("[data-handler]").map(function(){var t={prev:function(){e.datepicker._adjustDate(a,-i,"M")},next:function(){e.datepicker._adjustDate(a,+i,"M")},hide:function(){e.datepicker._hideDatepicker()},today:function(){e.datepicker._gotoToday(a)},selectDay:function(){return e.datepicker._selectDay(a,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return e.datepicker._selectMonthYear(a,this,"M"),!1},selectYear:function(){return e.datepicker._selectMonthYear(a,this,"Y"),!1}};e(this).bind(this.getAttribute("data-event"),t[this.getAttribute("data-handler")])})},_generateHTML:function(e){var t,i,a,s,n,r,o,u,c,h,l,d,p,g,m,f,_,v,k,y,b,D,w,M,C,x,I,N,T,A,E,S,Y,F,P,O,j,K,R,H=new Date,W=this._daylightSavingAdjust(new Date(H.getFullYear(),H.getMonth(),H.getDate())),L=this._get(e,"isRTL"),U=this._get(e,"showButtonPanel"),B=this._get(e,"hideIfNoPrevNext"),z=this._get(e,"navigationAsDateFormat"),q=this._getNumberOfMonths(e),G=this._get(e,"showCurrentAtPos"),J=this._get(e,"stepMonths"),Q=1!==q[0]||1!==q[1],V=this._daylightSavingAdjust(e.currentDay?new Date(e.currentYear,e.currentMonth,e.currentDay):new Date(9999,9,9)),$=this._getMinMaxDate(e,"min"),X=this._getMinMaxDate(e,"max"),Z=e.drawMonth-G,et=e.drawYear;if(0>Z&&(Z+=12,et--),X)for(t=this._daylightSavingAdjust(new Date(X.getFullYear(),X.getMonth()-q[0]*q[1]+1,X.getDate())),t=$&&$>t?$:t;this._daylightSavingAdjust(new Date(et,Z,1))>t;)Z--,0>Z&&(Z=11,et--);for(e.drawMonth=Z,e.drawYear=et,i=this._get(e,"prevText"),i=z?this.formatDate(i,this._daylightSavingAdjust(new Date(et,Z-J,1)),this._getFormatConfig(e)):i,a=this._canAdjustMonth(e,-1,et,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(L?"e":"w")+"'>"+i+"</span></a>":B?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(L?"e":"w")+"'>"+i+"</span></a>",s=this._get(e,"nextText"),s=z?this.formatDate(s,this._daylightSavingAdjust(new Date(et,Z+J,1)),this._getFormatConfig(e)):s,n=this._canAdjustMonth(e,1,et,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+s+"'><span class='ui-icon ui-icon-circle-triangle-"+(L?"w":"e")+"'>"+s+"</span></a>":B?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+s+"'><span class='ui-icon ui-icon-circle-triangle-"+(L?"w":"e")+"'>"+s+"</span></a>",r=this._get(e,"currentText"),o=this._get(e,"gotoCurrent")&&e.currentDay?V:W,r=z?this.formatDate(r,o,this._getFormatConfig(e)):r,u=e.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(e,"closeText")+"</button>",c=U?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(L?u:"")+(this._isInRange(e,o)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+r+"</button>":"")+(L?"":u)+"</div>":"",h=parseInt(this._get(e,"firstDay"),10),h=isNaN(h)?0:h,l=this._get(e,"showWeek"),d=this._get(e,"dayNames"),p=this._get(e,"dayNamesMin"),g=this._get(e,"monthNames"),m=this._get(e,"monthNamesShort"),f=this._get(e,"beforeShowDay"),_=this._get(e,"showOtherMonths"),v=this._get(e,"selectOtherMonths"),k=this._getDefaultDate(e),y="",D=0;q[0]>D;D++){for(w="",this.maxRows=4,M=0;q[1]>M;M++){if(C=this._daylightSavingAdjust(new Date(et,Z,e.selectedDay)),x=" ui-corner-all",I="",Q){if(I+="<div class='ui-datepicker-group",q[1]>1)switch(M){case 0:I+=" ui-datepicker-group-first",x=" ui-corner-"+(L?"right":"left");break;case q[1]-1:I+=" ui-datepicker-group-last",x=" ui-corner-"+(L?"left":"right");break;default:I+=" ui-datepicker-group-middle",x=""}I+="'>"}for(I+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+x+"'>"+(/all|left/.test(x)&&0===D?L?n:a:"")+(/all|right/.test(x)&&0===D?L?a:n:"")+this._generateMonthYearHeader(e,Z,et,$,X,D>0||M>0,g,m)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",N=l?"<th class='ui-datepicker-week-col'>"+this._get(e,"weekHeader")+"</th>":"",b=0;7>b;b++)T=(b+h)%7,N+="<th"+((b+h+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+d[T]+"'>"+p[T]+"</span></th>";for(I+=N+"</tr></thead><tbody>",A=this._getDaysInMonth(et,Z),et===e.selectedYear&&Z===e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,A)),E=(this._getFirstDayOfMonth(et,Z)-h+7)%7,S=Math.ceil((E+A)/7),Y=Q?this.maxRows>S?this.maxRows:S:S,this.maxRows=Y,F=this._daylightSavingAdjust(new Date(et,Z,1-E)),P=0;Y>P;P++){for(I+="<tr>",O=l?"<td class='ui-datepicker-week-col'>"+this._get(e,"calculateWeek")(F)+"</td>":"",b=0;7>b;b++)j=f?f.apply(e.input?e.input[0]:null,[F]):[!0,""],K=F.getMonth()!==Z,R=K&&!v||!j[0]||$&&$>F||X&&F>X,O+="<td class='"+((b+h+6)%7>=5?" ui-datepicker-week-end":"")+(K?" ui-datepicker-other-month":"")+(F.getTime()===C.getTime()&&Z===e.selectedMonth&&e._keyEvent||k.getTime()===F.getTime()&&k.getTime()===C.getTime()?" "+this._dayOverClass:"")+(R?" "+this._unselectableClass+" ui-state-disabled":"")+(K&&!_?"":" "+j[1]+(F.getTime()===V.getTime()?" "+this._currentClass:"")+(F.getTime()===W.getTime()?" ui-datepicker-today":""))+"'"+(K&&!_||!j[2]?"":" title='"+j[2].replace(/'/g,"'")+"'")+(R?"":" data-handler='selectDay' data-event='click' data-month='"+F.getMonth()+"' data-year='"+F.getFullYear()+"'")+">"+(K&&!_?" ":R?"<span class='ui-state-default'>"+F.getDate()+"</span>":"<a class='ui-state-default"+(F.getTime()===W.getTime()?" ui-state-highlight":"")+(F.getTime()===V.getTime()?" ui-state-active":"")+(K?" ui-priority-secondary":"")+"' href='#'>"+F.getDate()+"</a>")+"</td>",F.setDate(F.getDate()+1),F=this._daylightSavingAdjust(F);I+=O+"</tr>"}Z++,Z>11&&(Z=0,et++),I+="</tbody></table>"+(Q?"</div>"+(q[0]>0&&M===q[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),w+=I}y+=w}return y+=c,e._keyEvent=!1,y},_generateMonthYearHeader:function(e,t,i,a,s,n,r,o){var u,c,h,l,d,p,g,m,f=this._get(e,"changeMonth"),_=this._get(e,"changeYear"),v=this._get(e,"showMonthAfterYear"),k="<div class='ui-datepicker-title'>",y="";if(n||!f)y+="<span class='ui-datepicker-month'>"+r[t]+"</span>";else{for(u=a&&a.getFullYear()===i,c=s&&s.getFullYear()===i,y+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",h=0;12>h;h++)(!u||h>=a.getMonth())&&(!c||s.getMonth()>=h)&&(y+="<option value='"+h+"'"+(h===t?" selected='selected'":"")+">"+o[h]+"</option>");y+="</select>"}if(v||(k+=y+(!n&&f&&_?"":" ")),!e.yearshtml)if(e.yearshtml="",n||!_)k+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(l=this._get(e,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(e){var t=e.match(/c[+\-].*/)?i+parseInt(e.substring(1),10):e.match(/[+\-].*/)?d+parseInt(e,10):parseInt(e,10);
|
||
return isNaN(t)?d:t},g=p(l[0]),m=Math.max(g,p(l[1]||"")),g=a?Math.max(g,a.getFullYear()):g,m=s?Math.min(m,s.getFullYear()):m,e.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";m>=g;g++)e.yearshtml+="<option value='"+g+"'"+(g===i?" selected='selected'":"")+">"+g+"</option>";e.yearshtml+="</select>",k+=e.yearshtml,e.yearshtml=null}return k+=this._get(e,"yearSuffix"),v&&(k+=(!n&&f&&_?"":" ")+y),k+="</div>"},_adjustInstDate:function(e,t,i){var a=e.drawYear+("Y"===i?t:0),s=e.drawMonth+("M"===i?t:0),n=Math.min(e.selectedDay,this._getDaysInMonth(a,s))+("D"===i?t:0),r=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(a,s,n)));e.selectedDay=r.getDate(),e.drawMonth=e.selectedMonth=r.getMonth(),e.drawYear=e.selectedYear=r.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(e)},_restrictMinMax:function(e,t){var i=this._getMinMaxDate(e,"min"),a=this._getMinMaxDate(e,"max"),s=i&&i>t?i:t;return a&&s>a?a:s},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return null==t?[1,1]:"number"==typeof t?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return new Date(e,t,1).getDay()},_canAdjustMonth:function(e,t,i,a){var s=this._getNumberOfMonths(e),n=this._daylightSavingAdjust(new Date(i,a+(0>t?t:s[0]*s[1]),1));return 0>t&&n.setDate(this._getDaysInMonth(n.getFullYear(),n.getMonth())),this._isInRange(e,n)},_isInRange:function(e,t){var i,a,s=this._getMinMaxDate(e,"min"),n=this._getMinMaxDate(e,"max"),r=null,o=null,u=this._get(e,"yearRange");return u&&(i=u.split(":"),a=(new Date).getFullYear(),r=parseInt(i[0],10),o=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(r+=a),i[1].match(/[+\-].*/)&&(o+=a)),(!s||t.getTime()>=s.getTime())&&(!n||t.getTime()<=n.getTime())&&(!r||t.getFullYear()>=r)&&(!o||o>=t.getFullYear())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t="string"!=typeof t?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,i,a){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var s=t?"object"==typeof t?t:this._daylightSavingAdjust(new Date(a,i,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),s,this._getFormatConfig(e))}}),e.fn.datepicker=function(t){if(!this.length)return this;e.datepicker.initialized||(e(document).mousedown(e.datepicker._checkExternalClick),e.datepicker.initialized=!0),0===e("#"+e.datepicker._mainDivId).length&&e("body").append(e.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof t||"isDisabled"!==t&&"getDate"!==t&&"widget"!==t?"option"===t&&2===arguments.length&&"string"==typeof arguments[1]?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof t?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this].concat(i)):e.datepicker._attachDatepicker(this,t)}):e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(i))},e.datepicker=new i,e.datepicker.initialized=!1,e.datepicker.uuid=(new Date).getTime(),e.datepicker.version="1.10.4"})(jQuery);(function(e){var t={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.10.4",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var i=e(this).css(t).offset().top;0>i&&e(this).css("top",t.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&e.fn.draggable&&this._makeDraggable(),this.options.resizable&&e.fn.resizable&&this._makeResizable(),this._isOpen=!1},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var t=this.options.appendTo;return t&&(t.jquery||t.nodeType)?e(t):this.document.find(t||"body").eq(0)},_destroy:function(){var e,t=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},disable:e.noop,enable:e.noop,close:function(t){var i,a=this;if(this._isOpen&&this._trigger("beforeClose",t)!==!1){if(this._isOpen=!1,this._destroyOverlay(),!this.opener.filter(":focusable").focus().length)try{i=this.document[0].activeElement,i&&"body"!==i.nodeName.toLowerCase()&&e(i).blur()}catch(s){}this._hide(this.uiDialog,this.options.hide,function(){a._trigger("close",t)})}},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(e,t){var i=!!this.uiDialog.nextAll(":visible").insertBefore(this.uiDialog).length;return i&&!t&&this._trigger("focus",e),i},open:function(){var t=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),undefined):(this._isOpen=!0,this.opener=e(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this._show(this.uiDialog,this.options.show,function(){t._focusTabbable(),t._trigger("focus")}),this._trigger("open"),undefined)},_focusTabbable:function(){var e=this.element.find("[autofocus]");e.length||(e=this.element.find(":tabbable")),e.length||(e=this.uiDialogButtonPane.find(":tabbable")),e.length||(e=this.uiDialogTitlebarClose.filter(":tabbable")),e.length||(e=this.uiDialog),e.eq(0).focus()},_keepFocus:function(t){function i(){var t=this.document[0].activeElement,i=this.uiDialog[0]===t||e.contains(this.uiDialog[0],t);i||this._focusTabbable()}t.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=e("<div>").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(t){if(this.options.closeOnEscape&&!t.isDefaultPrevented()&&t.keyCode&&t.keyCode===e.ui.keyCode.ESCAPE)return t.preventDefault(),this.close(t),undefined;if(t.keyCode===e.ui.keyCode.TAB){var i=this.uiDialog.find(":tabbable"),a=i.filter(":first"),s=i.filter(":last");t.target!==s[0]&&t.target!==this.uiDialog[0]||t.shiftKey?t.target!==a[0]&&t.target!==this.uiDialog[0]||!t.shiftKey||(s.focus(1),t.preventDefault()):(a.focus(1),t.preventDefault())}},mousedown:function(e){this._moveToTop(e)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var t;this.uiDialogTitlebar=e("<div>").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(t){e(t.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=e("<button type='button'></button>").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(e){e.preventDefault(),this.close(e)}}),t=e("<span>").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(t),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(e){this.options.title||e.html(" "),e.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=e("<div>").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=e("<div>").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var t=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),e.isEmptyObject(i)||e.isArray(i)&&!i.length?(this.uiDialog.removeClass("ui-dialog-buttons"),undefined):(e.each(i,function(i,a){var s,n;a=e.isFunction(a)?{click:a,text:i}:a,a=e.extend({type:"button"},a),s=a.click,a.click=function(){s.apply(t.element[0],arguments)},n={icons:a.icons,text:a.showText},delete a.icons,delete a.showText,e("<button></button>",a).button(n).appendTo(t.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),undefined)},_makeDraggable:function(){function t(e){return{position:e.position,offset:e.offset}}var i=this,a=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(a,s){e(this).addClass("ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",a,t(s))},drag:function(e,a){i._trigger("drag",e,t(a))},stop:function(s,n){a.position=[n.position.left-i.document.scrollLeft(),n.position.top-i.document.scrollTop()],e(this).removeClass("ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",s,t(n))}})},_makeResizable:function(){function t(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}var i=this,a=this.options,s=a.resizable,n=this.uiDialog.css("position"),r="string"==typeof s?s:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:a.maxWidth,maxHeight:a.maxHeight,minWidth:a.minWidth,minHeight:this._minHeight(),handles:r,start:function(a,s){e(this).addClass("ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",a,t(s))},resize:function(e,a){i._trigger("resize",e,t(a))},stop:function(s,n){a.height=e(this).height(),a.width=e(this).width(),e(this).removeClass("ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",s,t(n))}}).css("position",n)},_minHeight:function(){var e=this.options;return"auto"===e.height?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(){var e=this.uiDialog.is(":visible");e||this.uiDialog.show(),this.uiDialog.position(this.options.position),e||this.uiDialog.hide()},_setOptions:function(a){var s=this,n=!1,r={};e.each(a,function(e,a){s._setOption(e,a),e in t&&(n=!0),e in i&&(r[e]=a)}),n&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",r)},_setOption:function(e,t){var i,a,s=this.uiDialog;"dialogClass"===e&&s.removeClass(this.options.dialogClass).addClass(t),"disabled"!==e&&(this._super(e,t),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:""+t}),"draggable"===e&&(i=s.is(":data(ui-draggable)"),i&&!t&&s.draggable("destroy"),!i&&t&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(a=s.is(":data(ui-resizable)"),a&&!t&&s.resizable("destroy"),a&&"string"==typeof t&&s.resizable("option","handles",t),a||t===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var e,t,i,a=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),a.minWidth>a.width&&(a.width=a.minWidth),e=this.uiDialog.css({height:"auto",width:a.width}).outerHeight(),t=Math.max(0,a.minHeight-e),i="number"==typeof a.maxHeight?Math.max(0,a.maxHeight-e):"none","auto"===a.height?this.element.css({minHeight:t,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,a.height-e)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=e(this);return e("<div>").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(t){return e(t.target).closest(".ui-dialog").length?!0:!!e(t.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var t=this,i=this.widgetFullName;e.ui.dialog.overlayInstances||this._delay(function(){e.ui.dialog.overlayInstances&&this.document.bind("focusin.dialog",function(a){t._allowInteraction(a)||(a.preventDefault(),e(".ui-dialog:visible:last .ui-dialog-content").data(i)._focusTabbable())})}),this.overlay=e("<div>").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),e.ui.dialog.overlayInstances++}},_destroyOverlay:function(){this.options.modal&&this.overlay&&(e.ui.dialog.overlayInstances--,e.ui.dialog.overlayInstances||this.document.unbind("focusin.dialog"),this.overlay.remove(),this.overlay=null)}}),e.ui.dialog.overlayInstances=0,e.uiBackCompat!==!1&&e.widget("ui.dialog",e.ui.dialog,{_position:function(){var t,i=this.options.position,a=[],s=[0,0];i?(("string"==typeof i||"object"==typeof i&&"0"in i)&&(a=i.split?i.split(" "):[i[0],i[1]],1===a.length&&(a[1]=a[0]),e.each(["left","top"],function(e,t){+a[e]===a[e]&&(s[e]=a[e],a[e]=t)}),i={my:a[0]+(0>s[0]?s[0]:"+"+s[0])+" "+a[1]+(0>s[1]?s[1]:"+"+s[1]),at:a.join(" ")}),i=e.extend({},e.ui.dialog.prototype.options.position,i)):i=e.ui.dialog.prototype.options.position,t=this.uiDialog.is(":visible"),t||this.uiDialog.show(),this.uiDialog.position(i),t||this.uiDialog.hide()}})})(jQuery);(function(t){t.widget("ui.draggable",t.ui.mouse,{version:"1.10.4",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"!==this.options.helper||/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(t(i.iframeFix===!0?"iframe":i.iframeFix).each(function(){t("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(t(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offsetParent=this.helper.offsetParent(),this.offsetParentCssPosition=this.offsetParent.css("position"),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},this.offset.scroll=!1,t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_mouseDrag:function(e,i){if("fixed"===this.offsetParentCssPosition&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp({}),!1;this.position=s.position}return this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"original"!==this.options.helper||t.contains(this.element[0].ownerDocument,this.element[0])?("invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1):!1},_mouseUp:function(e){return t("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return s.parents("body").length||s.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s[0]===this.element[0]||/(fixed|absolute)/.test(s.css("position"))||s.css("position","absolute"),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.element.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;return n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):"document"===n.containment?(this.containment=[0,0,t(document).width()-this.helperProportions.width-this.margins.left,(t(document).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],undefined):n.containment.constructor===Array?(this.containment=n.containment,undefined):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e="hidden"!==i.css("overflow"),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=i),undefined):(this.containment=null,undefined)},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent;return this.offset.scroll||(this.offset.scroll={top:n.scrollTop(),left:n.scrollLeft()}),{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top)*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)*s}},_generatePosition:function(e){var i,s,n,a,o=this.options,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,l=e.pageX,h=e.pageY;return this.offset.scroll||(this.offset.scroll={top:r.scrollTop(),left:r.scrollLeft()}),this.originalPosition&&(this.containment&&(this.relative_container?(s=this.relative_container.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,e.pageX-this.offset.click.left<i[0]&&(l=i[0]+this.offset.click.left),e.pageY-this.offset.click.top<i[1]&&(h=i[1]+this.offset.click.top),e.pageX-this.offset.click.left>i[2]&&(l=i[2]+this.offset.click.left),e.pageY-this.offset.click.top>i[3]&&(h=i[3]+this.offset.click.top)),o.grid&&(n=o.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,h=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-o.grid[1]:n+o.grid[1]:n,a=o.grid[0]?this.originalPageX+Math.round((l-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,l=i?a-this.offset.click.left>=i[0]||a-this.offset.click.left>i[2]?a:a-this.offset.click.left>=i[0]?a-o.grid[0]:a+o.grid[0]:a)),{top:h-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():this.offset.scroll.top),left:l-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():this.offset.scroll.left)}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s]),"drag"===e&&(this.positionAbs=this._convertPositionTo("absolute")),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i){var s=t(this).data("ui-draggable"),n=s.options,a=t.extend({},i,{item:s.element});s.sortables=[],t(n.connectToSortable).each(function(){var i=t.data(this,"ui-sortable");i&&!i.options.disabled&&(s.sortables.push({instance:i,shouldRevert:i.options.revert}),i.refreshPositions(),i._trigger("activate",e,a))})},stop:function(e,i){var s=t(this).data("ui-draggable"),n=t.extend({},i,{item:s.element});t.each(s.sortables,function(){this.instance.isOver?(this.instance.isOver=0,s.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=this.shouldRevert),this.instance._mouseStop(e),this.instance.options.helper=this.instance.options._helper,"original"===s.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",e,n))})},drag:function(e,i){var s=t(this).data("ui-draggable"),n=this;t.each(s.sortables,function(){var a=!1,o=this;this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(a=!0,t.each(s.sortables,function(){return this.instance.positionAbs=s.positionAbs,this.instance.helperProportions=s.helperProportions,this.instance.offset.click=s.offset.click,this!==o&&this.instance._intersectsWith(this.instance.containerCache)&&t.contains(o.instance.element[0],this.instance.element[0])&&(a=!1),a})),a?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=t(n).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return i.helper[0]},e.target=this.instance.currentItem[0],this.instance._mouseCapture(e,!0),this.instance._mouseStart(e,!0,!0),this.instance.offset.click.top=s.offset.click.top,this.instance.offset.click.left=s.offset.click.left,this.instance.offset.parent.left-=s.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=s.offset.parent.top-this.instance.offset.parent.top,s._trigger("toSortable",e),s.dropped=this.instance.element,s.currentItem=s.element,this.instance.fromOutside=s),this.instance.currentItem&&this.instance._mouseDrag(e)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",e,this.instance._uiHash(this.instance)),this.instance._mouseStop(e,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),s._trigger("fromSortable",e),s.dropped=!1)})}}),t.ui.plugin.add("draggable","cursor",{start:function(){var e=t("body"),i=t(this).data("ui-draggable").options;e.css("cursor")&&(i._cursor=e.css("cursor")),e.css("cursor",i.cursor)},stop:function(){var e=t(this).data("ui-draggable").options;e._cursor&&t("body").css("cursor",e._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("opacity")&&(n._opacity=s.css("opacity")),s.css("opacity",n.opacity)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._opacity&&t(i.helper).css("opacity",s._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(){var e=t(this).data("ui-draggable");e.scrollParent[0]!==document&&"HTML"!==e.scrollParent[0].tagName&&(e.overflowOffset=e.scrollParent.offset())},drag:function(e){var i=t(this).data("ui-draggable"),s=i.options,n=!1;i.scrollParent[0]!==document&&"HTML"!==i.scrollParent[0].tagName?(s.axis&&"x"===s.axis||(i.overflowOffset.top+i.scrollParent[0].offsetHeight-e.pageY<s.scrollSensitivity?i.scrollParent[0].scrollTop=n=i.scrollParent[0].scrollTop+s.scrollSpeed:e.pageY-i.overflowOffset.top<s.scrollSensitivity&&(i.scrollParent[0].scrollTop=n=i.scrollParent[0].scrollTop-s.scrollSpeed)),s.axis&&"y"===s.axis||(i.overflowOffset.left+i.scrollParent[0].offsetWidth-e.pageX<s.scrollSensitivity?i.scrollParent[0].scrollLeft=n=i.scrollParent[0].scrollLeft+s.scrollSpeed:e.pageX-i.overflowOffset.left<s.scrollSensitivity&&(i.scrollParent[0].scrollLeft=n=i.scrollParent[0].scrollLeft-s.scrollSpeed))):(s.axis&&"x"===s.axis||(e.pageY-t(document).scrollTop()<s.scrollSensitivity?n=t(document).scrollTop(t(document).scrollTop()-s.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<s.scrollSensitivity&&(n=t(document).scrollTop(t(document).scrollTop()+s.scrollSpeed))),s.axis&&"y"===s.axis||(e.pageX-t(document).scrollLeft()<s.scrollSensitivity?n=t(document).scrollLeft(t(document).scrollLeft()-s.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<s.scrollSensitivity&&(n=t(document).scrollLeft(t(document).scrollLeft()+s.scrollSpeed)))),n!==!1&&t.ui.ddmanager&&!s.dropBehaviour&&t.ui.ddmanager.prepareOffsets(i,e)}}),t.ui.plugin.add("draggable","snap",{start:function(){var e=t(this).data("ui-draggable"),i=e.options;e.snapElements=[],t(i.snap.constructor!==String?i.snap.items||":data(ui-draggable)":i.snap).each(function(){var i=t(this),s=i.offset();this!==e.element[0]&&e.snapElements.push({item:this,width:i.outerWidth(),height:i.outerHeight(),top:s.top,left:s.left})})},drag:function(e,i){var s,n,a,o,r,l,h,c,u,d,p=t(this).data("ui-draggable"),g=p.options,f=g.snapTolerance,m=i.offset.left,_=m+p.helperProportions.width,v=i.offset.top,b=v+p.helperProportions.height;for(u=p.snapElements.length-1;u>=0;u--)r=p.snapElements[u].left,l=r+p.snapElements[u].width,h=p.snapElements[u].top,c=h+p.snapElements[u].height,r-f>_||m>l+f||h-f>b||v>c+f||!t.contains(p.snapElements[u].item.ownerDocument,p.snapElements[u].item)?(p.snapElements[u].snapping&&p.options.snap.release&&p.options.snap.release.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=!1):("inner"!==g.snapMode&&(s=f>=Math.abs(h-b),n=f>=Math.abs(c-v),a=f>=Math.abs(r-_),o=f>=Math.abs(l-m),s&&(i.position.top=p._convertPositionTo("relative",{top:h-p.helperProportions.height,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r-p.helperProportions.width}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:l}).left-p.margins.left)),d=s||n||a||o,"outer"!==g.snapMode&&(s=f>=Math.abs(h-v),n=f>=Math.abs(c-b),a=f>=Math.abs(r-m),o=f>=Math.abs(l-_),s&&(i.position.top=p._convertPositionTo("relative",{top:h,left:0}).top-p.margins.top),n&&(i.position.top=p._convertPositionTo("relative",{top:c-p.helperProportions.height,left:0}).top-p.margins.top),a&&(i.position.left=p._convertPositionTo("relative",{top:0,left:r}).left-p.margins.left),o&&(i.position.left=p._convertPositionTo("relative",{top:0,left:l-p.helperProportions.width}).left-p.margins.left)),!p.snapElements[u].snapping&&(s||n||a||o||d)&&p.options.snap.snap&&p.options.snap.snap.call(p.element,e,t.extend(p._uiHash(),{snapItem:p.snapElements[u].item})),p.snapElements[u].snapping=s||n||a||o||d)}}),t.ui.plugin.add("draggable","stack",{start:function(){var e,i=this.data("ui-draggable").options,s=t.makeArray(t(i.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});s.length&&(e=parseInt(t(s[0]).css("zIndex"),10)||0,t(s).each(function(i){t(this).css("zIndex",e+i)}),this.css("zIndex",e+s.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i){var s=t(i.helper),n=t(this).data("ui-draggable").options;s.css("zIndex")&&(n._zIndex=s.css("zIndex")),s.css("zIndex",n.zIndex)},stop:function(e,i){var s=t(this).data("ui-draggable").options;s._zIndex&&t(i.helper).css("zIndex",s._zIndex)}})})(jQuery);(function(t){function e(t,e,i){return t>e&&e+i>t}t.widget("ui.droppable",{version:"1.10.4",widgetEventPrefix:"drop",options:{accept:"*",activeClass:!1,addClasses:!0,greedy:!1,hoverClass:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(s)?s:function(t){return t.is(s)},this.proportions=function(){return arguments.length?(e=arguments[0],undefined):e?e:e={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},t.ui.ddmanager.droppables[i.scope]=t.ui.ddmanager.droppables[i.scope]||[],t.ui.ddmanager.droppables[i.scope].push(this),i.addClasses&&this.element.addClass("ui-droppable")},_destroy:function(){for(var e=0,i=t.ui.ddmanager.droppables[this.options.scope];i.length>e;e++)i[e]===this&&i.splice(e,1);this.element.removeClass("ui-droppable ui-droppable-disabled")},_setOption:function(e,i){"accept"===e&&(this.accept=t.isFunction(i)?i:function(t){return t.is(i)}),t.Widget.prototype._setOption.apply(this,arguments)},_activate:function(e){var i=t.ui.ddmanager.current;this.options.activeClass&&this.element.addClass(this.options.activeClass),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this.options.activeClass&&this.element.removeClass(this.options.activeClass),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.addClass(this.options.hoverClass),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var e=t.data(this,"ui-droppable");return e.options.greedy&&!e.options.disabled&&e.options.scope===s.options.scope&&e.accept.call(e.element[0],s.currentItem||s.element)&&t.ui.intersect(s,t.extend(e,{offset:e.element.offset()}),e.options.tolerance)?(n=!0,!1):undefined}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this.options.activeClass&&this.element.removeClass(this.options.activeClass),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass),this._trigger("drop",e,this.ui(s)),this.element):!1):!1},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}}}),t.ui.intersect=function(t,i,s){if(!i.offset)return!1;var n,a,o=(t.positionAbs||t.position.absolute).left,r=(t.positionAbs||t.position.absolute).top,l=o+t.helperProportions.width,h=r+t.helperProportions.height,c=i.offset.left,u=i.offset.top,d=c+i.proportions().width,p=u+i.proportions().height;switch(s){case"fit":return o>=c&&d>=l&&r>=u&&p>=h;case"intersect":return o+t.helperProportions.width/2>c&&d>l-t.helperProportions.width/2&&r+t.helperProportions.height/2>u&&p>h-t.helperProportions.height/2;case"pointer":return n=(t.positionAbs||t.position.absolute).left+(t.clickOffset||t.offset.click).left,a=(t.positionAbs||t.position.absolute).top+(t.clickOffset||t.offset.click).top,e(a,u,i.proportions().height)&&e(n,c,i.proportions().width);case"touch":return(r>=u&&p>=r||h>=u&&p>=h||u>r&&h>p)&&(o>=c&&d>=o||l>=c&&d>=l||c>o&&l>d);default:return!1}},t.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,i){var s,n,a=t.ui.ddmanager.droppables[e.options.scope]||[],o=i?i.type:null,r=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;a.length>s;s++)if(!(a[s].options.disabled||e&&!a[s].accept.call(a[s].element[0],e.currentItem||e.element))){for(n=0;r.length>n;n++)if(r[n]===a[s].element[0]){a[s].proportions().height=0;continue t}a[s].visible="none"!==a[s].element.css("display"),a[s].visible&&("mousedown"===o&&a[s]._activate.call(a[s],i),a[s].offset=a[s].element.offset(),a[s].proportions({width:a[s].element[0].offsetWidth,height:a[s].element[0].offsetHeight}))}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&t.ui.intersect(e,this,this.options.tolerance)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").bind("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,a,o=t.ui.intersect(e,this,this.options.tolerance),r=!o&&this.isover?"isout":o&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,a=this.element.parents(":data(ui-droppable)").filter(function(){return t.data(this,"ui-droppable").options.scope===n}),a.length&&(s=t.data(a[0],"ui-droppable"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").unbind("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}}})(jQuery);(function(t,e){var i="ui-effects-";t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=h(),n=s._rgba=[];return i=i.toLowerCase(),f(l,function(t,a){var o,r=a.re.exec(i),l=r&&a.parse(r),h=a.space||"rgba";return l?(o=s[h](l),s[c[h].cache]=o[c[h].cache],n=s._rgba=o._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,a.transparent),s):a[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var a,o="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,l=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],h=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=h.support={},p=t("<p>")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),h.fn=t.extend(h.prototype,{parse:function(n,o,r,l){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(o),o=e);var u=this,d=t.type(n),p=this._rgba=[];return o!==e&&(n=[n,o,r,l],d="array"),"string"===d?this.parse(s(n)||a._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof h?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var a=s.cache;f(s.props,function(t,e){if(!u[a]&&s.to){if("alpha"===t||null==n[t])return;u[a]=s.to(u._rgba)}u[a][e.idx]=i(n[t],e,!0)}),u[a]&&0>t.inArray(null,u[a].slice(0,3))&&(u[a][3]=1,s.from&&(u._rgba=s.from(u[a])))}),this):e},is:function(t){var i=h(t),s=!0,n=this;return f(c,function(t,a){var o,r=i[a.cache];return r&&(o=n[a.cache]||a.to&&a.to(n._rgba)||[],f(a.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===o[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=h(t),n=s._space(),a=c[n],o=0===this.alpha()?h("transparent"):this,r=o[a.cache]||a.to(o._rgba),l=r.slice();return s=s[a.cache],f(a.props,function(t,n){var a=n.idx,o=r[a],h=s[a],c=u[n.type]||{};null!==h&&(null===o?l[a]=h:(c.mod&&(h-o>c.mod/2?o+=c.mod:o-h>c.mod/2&&(o-=c.mod)),l[a]=i((h-o)*e+o,n)))}),this[n](l)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=h(e)._rgba;return h(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),h.fn.parse.prototype=h.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,a=t[2]/255,o=t[3],r=Math.max(s,n,a),l=Math.min(s,n,a),h=r-l,c=r+l,u=.5*c;return e=l===r?0:s===r?60*(n-a)/h+360:n===r?60*(a-s)/h+120:60*(s-n)/h+240,i=0===h?0:.5>=u?h/c:h/(2-c),[Math.round(e)%360,i,u,null==o?1:o]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],a=t[3],o=.5>=s?s*(1+i):s+i-s*i,r=2*s-o;return[Math.round(255*n(r,o,e+1/3)),Math.round(255*n(r,o,e)),Math.round(255*n(r,o,e-1/3)),a]},f(c,function(s,n){var a=n.props,o=n.cache,l=n.to,c=n.from;h.fn[s]=function(s){if(l&&!this[o]&&(this[o]=l(this._rgba)),s===e)return this[o].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[o].slice();return f(a,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=h(c(d)),n[o]=d,n):h(d)},f(a,function(e,i){h.fn[e]||(h.fn[e]=function(n){var a,o=t.type(n),l="alpha"===e?this._hsla?"hsla":"rgba":s,h=this[l](),c=h[i.idx];return"undefined"===o?c:("function"===o&&(n=n.call(this,c),o=t.type(n)),null==n&&i.empty?this:("string"===o&&(a=r.exec(n),a&&(n=c+parseFloat(a[2])*("+"===a[1]?1:-1))),h[i.idx]=n,this[l](h)))})})}),h.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var a,o,r="";if("transparent"!==n&&("string"!==t.type(n)||(a=s(n)))){if(n=h(a||n),!d.rgba&&1!==n._rgba[3]){for(o="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&o&&o.style;)try{r=t.css(o,"backgroundColor"),o=o.parentNode}catch(l){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(l){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=h(e.elem,i),e.end=h(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},h.hook(o),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},a=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,a={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(a[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(a[i]=n[i]);return a}function s(e,i){var s,n,o={};for(s in i)n=i[s],e[s]!==n&&(a[s]||(t.fx.step[s]||!isNaN(parseFloat(n)))&&(o[s]=n));return o}var n=["add","remove","toggle"],a={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(jQuery.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(e,a,o,r){var l=t.speed(a,o,r);return this.queue(function(){var a,o=t(this),r=o.attr("class")||"",h=l.children?o.find("*").addBack():o;h=h.map(function(){var e=t(this);return{el:e,start:i(this)}}),a=function(){t.each(n,function(t,i){e[i]&&o[i+"Class"](e[i])})},a(),h=h.map(function(){return this.end=i(this.el[0]),this.diff=s(this.start,this.end),this}),o.attr("class",r),h=h.map(function(){var e=this,i=t.Deferred(),s=t.extend({},l,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,h.get()).done(function(){a(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),l.complete.call(o[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,a){return s?t.effects.animateClass.call(this,{add:i},s,n,a):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,a){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,a):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(i){return function(s,n,a,o,r){return"boolean"==typeof n||n===e?a?t.effects.animateClass.call(this,n?{add:s}:{remove:s},a,o,r):i.apply(this,arguments):t.effects.animateClass.call(this,{toggle:s},n,a,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,a){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,a)}})}(),function(){function s(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function n(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}t.extend(t.effects,{version:"1.10.4",save:function(t,e){for(var s=0;e.length>s;s++)null!==e[s]&&t.data(i+e[s],t[0].style[e[s]])},restore:function(t,s){var n,a;for(a=0;s.length>a;a++)null!==s[a]&&(n=t.data(i+s[a]),n===e&&(n=""),t.css(s[a],n))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},a=document.activeElement;try{a.id}catch(o){a=document.body}return e.wrap(s),(e[0]===a||t.contains(e[0],a))&&t(a).focus(),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).focus()),e},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var a=e.cssUnit(i);a[0]>0&&(n[i]=a[0]*s+a[1])}),n}}),t.fn.extend({effect:function(){function e(e){function s(){t.isFunction(a)&&a.call(n[0]),t.isFunction(e)&&e()}var n=t(this),a=i.complete,r=i.mode;(n.is(":hidden")?"hide"===r:"show"===r)?(n[r](),s()):o.call(n[0],i,s)}var i=s.apply(this,arguments),n=i.mode,a=i.queue,o=t.effects.effect[i.effect];return t.fx.off||!o?n?this[n](i.duration,i.complete):this.each(function(){i.complete&&i.complete.call(this)}):a===!1?this.each(e):this.queue(a||"fx",e)},show:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="show",this.effect.call(this,i)}}(t.fn.show),hide:function(t){return function(e){if(n(e))return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="hide",this.effect.call(this,i)}}(t.fn.hide),toggle:function(t){return function(e){if(n(e)||"boolean"==typeof e)return t.apply(this,arguments);var i=s.apply(this,arguments);return i.mode="toggle",this.effect.call(this,i)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s}})}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}()})(jQuery);(function(t){var e=/up|down|vertical/,i=/up|left|vertical|horizontal/;t.effects.effect.blind=function(s,n){var a,o,r,l=t(this),h=["position","top","bottom","left","right","height","width"],c=t.effects.setMode(l,s.mode||"hide"),u=s.direction||"up",d=e.test(u),p=d?"height":"width",f=d?"top":"left",g=i.test(u),m={},v="show"===c;l.parent().is(".ui-effects-wrapper")?t.effects.save(l.parent(),h):t.effects.save(l,h),l.show(),a=t.effects.createWrapper(l).css({overflow:"hidden"}),o=a[p](),r=parseFloat(a.css(f))||0,m[p]=v?o:0,g||(l.css(d?"bottom":"right",0).css(d?"top":"left","auto").css({position:"absolute"}),m[f]=v?r:o+r),v&&(a.css(p,0),g||a.css(f,r+o)),a.animate(m,{duration:s.duration,easing:s.easing,queue:!1,complete:function(){"hide"===c&&l.hide(),t.effects.restore(l,h),t.effects.removeWrapper(l),n()}})}})(jQuery);(function(t){t.effects.effect.bounce=function(e,i){var s,n,a,o=t(this),r=["position","top","bottom","left","right","height","width"],l=t.effects.setMode(o,e.mode||"effect"),h="hide"===l,c="show"===l,u=e.direction||"up",d=e.distance,p=e.times||5,f=2*p+(c||h?1:0),g=e.duration/f,m=e.easing,v="up"===u||"down"===u?"top":"left",_="up"===u||"left"===u,b=o.queue(),y=b.length;for((c||h)&&r.push("opacity"),t.effects.save(o,r),o.show(),t.effects.createWrapper(o),d||(d=o["top"===v?"outerHeight":"outerWidth"]()/3),c&&(a={opacity:1},a[v]=0,o.css("opacity",0).css(v,_?2*-d:2*d).animate(a,g,m)),h&&(d/=Math.pow(2,p-1)),a={},a[v]=0,s=0;p>s;s++)n={},n[v]=(_?"-=":"+=")+d,o.animate(n,g,m).animate(a,g,m),d=h?2*d:d/2;h&&(n={opacity:0},n[v]=(_?"-=":"+=")+d,o.animate(n,g,m)),o.queue(function(){h&&o.hide(),t.effects.restore(o,r),t.effects.removeWrapper(o),i()}),y>1&&b.splice.apply(b,[1,0].concat(b.splice(y,f+1))),o.dequeue()}})(jQuery);(function(t){t.effects.effect.clip=function(e,i){var s,n,a,o=t(this),r=["position","top","bottom","left","right","height","width"],l=t.effects.setMode(o,e.mode||"hide"),h="show"===l,c=e.direction||"vertical",u="vertical"===c,d=u?"height":"width",p=u?"top":"left",f={};t.effects.save(o,r),o.show(),s=t.effects.createWrapper(o).css({overflow:"hidden"}),n="IMG"===o[0].tagName?s:o,a=n[d](),h&&(n.css(d,0),n.css(p,a/2)),f[d]=h?a:0,f[p]=h?0:a/2,n.animate(f,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){h||o.hide(),t.effects.restore(o,r),t.effects.removeWrapper(o),i()}})}})(jQuery);(function(t){t.effects.effect.drop=function(e,i){var s,n=t(this),a=["position","top","bottom","left","right","opacity","height","width"],o=t.effects.setMode(n,e.mode||"hide"),r="show"===o,l=e.direction||"left",h="up"===l||"down"===l?"top":"left",c="up"===l||"left"===l?"pos":"neg",u={opacity:r?1:0};t.effects.save(n,a),n.show(),t.effects.createWrapper(n),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0)/2,r&&n.css("opacity",0).css(h,"pos"===c?-s:s),u[h]=(r?"pos"===c?"+=":"-=":"pos"===c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===o&&n.hide(),t.effects.restore(n,a),t.effects.removeWrapper(n),i()}})}})(jQuery);(function(t){t.effects.effect.explode=function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),g||p.hide(),i()}var a,o,r,l,h,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=t.effects.setMode(p,e.mode||"hide"),g="show"===f,m=p.show().css("visibility","hidden").offset(),v=Math.ceil(p.outerWidth()/d),_=Math.ceil(p.outerHeight()/u),b=[];for(a=0;u>a;a++)for(l=m.top+a*_,c=a-(u-1)/2,o=0;d>o;o++)r=m.left+o*v,h=o-(d-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-o*v,top:-a*_}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:v,height:_,left:r+(g?h*v:0),top:l+(g?c*_:0),opacity:g?0:1}).animate({left:r+(g?0:h*v),top:l+(g?0:c*_),opacity:g?1:0},e.duration||500,e.easing,s)}})(jQuery);(function(t){t.effects.effect.fade=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"toggle");s.animate({opacity:n},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}})(jQuery);(function(t){t.effects.effect.fold=function(e,i){var s,n,a=t(this),o=["position","top","bottom","left","right","height","width"],r=t.effects.setMode(a,e.mode||"hide"),l="show"===r,h="hide"===r,c=e.size||15,u=/([0-9]+)%/.exec(c),d=!!e.horizFirst,p=l!==d,f=p?["width","height"]:["height","width"],g=e.duration/2,m={},v={};t.effects.save(a,o),a.show(),s=t.effects.createWrapper(a).css({overflow:"hidden"}),n=p?[s.width(),s.height()]:[s.height(),s.width()],u&&(c=parseInt(u[1],10)/100*n[h?0:1]),l&&s.css(d?{height:0,width:c}:{height:c,width:0}),m[f[0]]=l?n[0]:c,v[f[1]]=l?n[1]:0,s.animate(m,g,e.easing).animate(v,g,e.easing,function(){h&&a.hide(),t.effects.restore(a,o),t.effects.removeWrapper(a),i()})}})(jQuery);(function(t){t.effects.effect.highlight=function(e,i){var s=t(this),n=["backgroundImage","backgroundColor","opacity"],a=t.effects.setMode(s,e.mode||"show"),o={backgroundColor:s.css("backgroundColor")};"hide"===a&&(o.opacity=0),t.effects.save(s,n),s.show().css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(o,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===a&&s.hide(),t.effects.restore(s,n),i()}})}})(jQuery);(function(t){t.effects.effect.pulsate=function(e,i){var s,n=t(this),a=t.effects.setMode(n,e.mode||"show"),o="show"===a,r="hide"===a,l=o||"hide"===a,h=2*(e.times||5)+(l?1:0),c=e.duration/h,u=0,d=n.queue(),p=d.length;for((o||!n.is(":visible"))&&(n.css("opacity",0).show(),u=1),s=1;h>s;s++)n.animate({opacity:u},c,e.easing),u=1-u;n.animate({opacity:u},c,e.easing),n.queue(function(){r&&n.hide(),i()}),p>1&&d.splice.apply(d,[1,0].concat(d.splice(p,h+1))),n.dequeue()}})(jQuery);(function(t){t.effects.effect.puff=function(e,i){var s=t(this),n=t.effects.setMode(s,e.mode||"hide"),a="hide"===n,o=parseInt(e.percent,10)||150,r=o/100,l={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()};t.extend(e,{effect:"scale",queue:!1,fade:!0,mode:n,complete:i,percent:a?o:100,from:a?l:{height:l.height*r,width:l.width*r,outerHeight:l.outerHeight*r,outerWidth:l.outerWidth*r}}),s.effect(e)},t.effects.effect.scale=function(e,i){var s=t(this),n=t.extend(!0,{},e),a=t.effects.setMode(s,e.mode||"effect"),o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"hide"===a?0:100),r=e.direction||"both",l=e.origin,h={height:s.height(),width:s.width(),outerHeight:s.outerHeight(),outerWidth:s.outerWidth()},c={y:"horizontal"!==r?o/100:1,x:"vertical"!==r?o/100:1};n.effect="size",n.queue=!1,n.complete=i,"effect"!==a&&(n.origin=l||["middle","center"],n.restore=!0),n.from=e.from||("show"===a?{height:0,width:0,outerHeight:0,outerWidth:0}:h),n.to={height:h.height*c.y,width:h.width*c.x,outerHeight:h.outerHeight*c.y,outerWidth:h.outerWidth*c.x},n.fade&&("show"===a&&(n.from.opacity=0,n.to.opacity=1),"hide"===a&&(n.from.opacity=1,n.to.opacity=0)),s.effect(n)},t.effects.effect.size=function(e,i){var s,n,a,o=t(this),r=["position","top","bottom","left","right","width","height","overflow","opacity"],l=["position","top","bottom","left","right","overflow","opacity"],h=["width","height","overflow"],c=["fontSize"],u=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],d=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=t.effects.setMode(o,e.mode||"effect"),f=e.restore||"effect"!==p,g=e.scale||"both",m=e.origin||["middle","center"],v=o.css("position"),_=f?r:l,b={height:0,width:0,outerHeight:0,outerWidth:0};"show"===p&&o.show(),s={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},"toggle"===e.mode&&"show"===p?(o.from=e.to||b,o.to=e.from||s):(o.from=e.from||("show"===p?b:s),o.to=e.to||("hide"===p?b:s)),a={from:{y:o.from.height/s.height,x:o.from.width/s.width},to:{y:o.to.height/s.height,x:o.to.width/s.width}},("box"===g||"both"===g)&&(a.from.y!==a.to.y&&(_=_.concat(u),o.from=t.effects.setTransition(o,u,a.from.y,o.from),o.to=t.effects.setTransition(o,u,a.to.y,o.to)),a.from.x!==a.to.x&&(_=_.concat(d),o.from=t.effects.setTransition(o,d,a.from.x,o.from),o.to=t.effects.setTransition(o,d,a.to.x,o.to))),("content"===g||"both"===g)&&a.from.y!==a.to.y&&(_=_.concat(c).concat(h),o.from=t.effects.setTransition(o,c,a.from.y,o.from),o.to=t.effects.setTransition(o,c,a.to.y,o.to)),t.effects.save(o,_),o.show(),t.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),m&&(n=t.effects.getBaseline(m,s),o.from.top=(s.outerHeight-o.outerHeight())*n.y,o.from.left=(s.outerWidth-o.outerWidth())*n.x,o.to.top=(s.outerHeight-o.to.outerHeight)*n.y,o.to.left=(s.outerWidth-o.to.outerWidth)*n.x),o.css(o.from),("content"===g||"both"===g)&&(u=u.concat(["marginTop","marginBottom"]).concat(c),d=d.concat(["marginLeft","marginRight"]),h=r.concat(u).concat(d),o.find("*[width]").each(function(){var i=t(this),s={height:i.height(),width:i.width(),outerHeight:i.outerHeight(),outerWidth:i.outerWidth()};f&&t.effects.save(i,h),i.from={height:s.height*a.from.y,width:s.width*a.from.x,outerHeight:s.outerHeight*a.from.y,outerWidth:s.outerWidth*a.from.x},i.to={height:s.height*a.to.y,width:s.width*a.to.x,outerHeight:s.height*a.to.y,outerWidth:s.width*a.to.x},a.from.y!==a.to.y&&(i.from=t.effects.setTransition(i,u,a.from.y,i.from),i.to=t.effects.setTransition(i,u,a.to.y,i.to)),a.from.x!==a.to.x&&(i.from=t.effects.setTransition(i,d,a.from.x,i.from),i.to=t.effects.setTransition(i,d,a.to.x,i.to)),i.css(i.from),i.animate(i.to,e.duration,e.easing,function(){f&&t.effects.restore(i,h)})})),o.animate(o.to,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){0===o.to.opacity&&o.css("opacity",o.from.opacity),"hide"===p&&o.hide(),t.effects.restore(o,_),f||("static"===v?o.css({position:"relative",top:o.to.top,left:o.to.left}):t.each(["top","left"],function(t,e){o.css(e,function(e,i){var s=parseInt(i,10),n=t?o.to.left:o.to.top;return"auto"===i?n+"px":s+n+"px"})})),t.effects.removeWrapper(o),i()}})}})(jQuery);(function(t){t.effects.effect.shake=function(e,i){var s,n=t(this),a=["position","top","bottom","left","right","height","width"],o=t.effects.setMode(n,e.mode||"effect"),r=e.direction||"left",l=e.distance||20,h=e.times||3,c=2*h+1,u=Math.round(e.duration/c),d="up"===r||"down"===r?"top":"left",p="up"===r||"left"===r,f={},g={},m={},v=n.queue(),_=v.length;for(t.effects.save(n,a),n.show(),t.effects.createWrapper(n),f[d]=(p?"-=":"+=")+l,g[d]=(p?"+=":"-=")+2*l,m[d]=(p?"-=":"+=")+2*l,n.animate(f,u,e.easing),s=1;h>s;s++)n.animate(g,u,e.easing).animate(m,u,e.easing);n.animate(g,u,e.easing).animate(f,u/2,e.easing).queue(function(){"hide"===o&&n.hide(),t.effects.restore(n,a),t.effects.removeWrapper(n),i()}),_>1&&v.splice.apply(v,[1,0].concat(v.splice(_,c+1))),n.dequeue()}})(jQuery);(function(t){t.effects.effect.slide=function(e,i){var s,n=t(this),a=["position","top","bottom","left","right","width","height"],o=t.effects.setMode(n,e.mode||"show"),r="show"===o,l=e.direction||"left",h="up"===l||"down"===l?"top":"left",c="up"===l||"left"===l,u={};t.effects.save(n,a),n.show(),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0),t.effects.createWrapper(n).css({overflow:"hidden"}),r&&n.css(h,c?isNaN(s)?"-"+s:-s:s),u[h]=(r?c?"+=":"-=":c?"-=":"+=")+s,n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){"hide"===o&&n.hide(),t.effects.restore(n,a),t.effects.removeWrapper(n),i()}})}})(jQuery);(function(t){t.effects.effect.transfer=function(e,i){var s=t(this),n=t(e.to),a="fixed"===n.css("position"),o=t("body"),r=a?o.scrollTop():0,l=a?o.scrollLeft():0,h=n.offset(),c={top:h.top-r,left:h.left-l,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("<div class='ui-effects-transfer'></div>").appendTo(document.body).addClass(e.className).css({top:u.top-r,left:u.left-l,height:s.innerHeight(),width:s.innerWidth(),position:a?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),i()})}})(jQuery);(function(t){t.widget("ui.menu",{version:"1.10.4",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,t.proxy(function(t){this.options.disabled&&t.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(t){t.preventDefault()},"click .ui-state-disabled > a":function(t){t.preventDefault()},"click .ui-menu-item:has(a)":function(e){var i=t(e.target).closest(".ui-menu-item");!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&t(this.document[0].activeElement).closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){var i=t(e.currentTarget);i.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(e,i)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.children(".ui-menu-item").eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){t.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(e){t(e.target).closest(".ui-menu").length||this.collapseAll(e),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var e=t(this);e.data("ui-menu-submenu-carat")&&e.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(e){function i(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var s,n,a,o,r,l=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:l=!1,n=this.previousFilter||"",a=String.fromCharCode(e.keyCode),o=!1,clearTimeout(this.filterTimer),a===n?o=!0:a=n+a,r=RegExp("^"+i(a),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return r.test(t(this).children("a").text())}),s=o&&-1!==s.index(this.active.next())?this.active.nextAll(".ui-menu-item"):s,s.length||(a=String.fromCharCode(e.keyCode),r=RegExp("^"+i(a),"i"),s=this.activeMenu.children(".ui-menu-item").filter(function(){return r.test(t(this).children("a").text())})),s.length?(this.focus(e,s),s.length>1?(this.previousFilter=a,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}l&&e.preventDefault()},_activate:function(t){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i=this.options.icons.submenu,s=this.element.find(this.options.menus);this.element.toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length),s.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),s=e.prev("a"),n=t("<span>").addClass("ui-menu-icon ui-icon "+i).data("ui-menu-submenu-carat",!0);s.attr("aria-haspopup","true").prepend(n),e.attr("aria-labelledby",s.attr("id"))}),e=s.add(this.element),e.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),e.children(":not(.ui-menu-item)").each(function(){var e=t(this);/[^\-\u2014\u2013\s]/.test(e.text())||e.addClass("ui-widget-content ui-menu-divider")}),e.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){"icons"===t&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(e.submenu),this._super(t,e)},focus:function(t,e){var i,s;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,a,o,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,a=this.activeMenu.scrollTop(),o=this.activeMenu.height(),r=e.height(),0>n?this.activeMenu.scrollTop(a+n):n+r>o&&this.activeMenu.scrollTop(a+n-o+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",t,{item:this.active}))},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.children(".ui-menu-item")[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())),undefined):(this.next(e),undefined)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.children(".ui-menu-item").first())),undefined):(this.next(e),undefined)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(e){this.active=this.active||t(e.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(e,!0),this._trigger("select",e,i)}})})(jQuery);(function(t,e){t.widget("ui.progressbar",{version:"1.10.4",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=t("<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(t){return t===e?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),e)},_constrainedValue:function(t){return t===e&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(i.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("<div class='ui-progressbar-overlay'></div>").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}})})(jQuery);(function(t){function e(t){return parseInt(t,10)||0}function i(t){return!isNaN(parseInt(t,10))}t.widget("ui.resizable",t.ui.mouse,{version:"1.10.4",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_create:function(){var e,i,s,n,a,o=this,r=this.options;if(this.element.addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!r.aspectRatio,aspectRatio:r.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:r.helper||r.ghost||r.animate?r.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=r.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),e=this.handles.split(","),this.handles={},i=0;e.length>i;i++)s=t.trim(e[i]),a="ui-resizable-"+s,n=t("<div class='ui-resizable-handle "+a+"'></div>"),n.css({zIndex:r.zIndex}),"se"===s&&n.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(n);this._renderAxis=function(e){var i,s,n,a;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String&&(this.handles[i]=t(this.handles[i],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(s=t(this.handles[i],this.element),a=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,a),this._proportionallyResize()),t(this.handles[i]).length},this._renderAxis(this.element),this._handles=t(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=n&&n[1]?n[1]:"se")}),r.autoHide&&(this._handles.hide(),t(this.element).addClass("ui-resizable-autohide").mouseenter(function(){r.disabled||(t(this).removeClass("ui-resizable-autohide"),o._handles.show())}).mouseleave(function(){r.disabled||o.resizing||(t(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(i){var s,n,a,o=this.options,r=this.element.position(),h=this.element;return this.resizing=!0,/absolute/.test(h.css("position"))?h.css({position:"absolute",top:h.css("top"),left:h.css("left")}):h.is(".ui-draggable")&&h.css({position:"absolute",top:r.top,left:r.left}),this._renderProxy(),s=e(this.helper.css("left")),n=e(this.helper.css("top")),o.containment&&(s+=t(o.containment).scrollLeft()||0,n+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:s,top:n},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:h.width(),height:h.height()},this.originalSize=this._helper?{width:h.outerWidth(),height:h.outerHeight()}:{width:h.width(),height:h.height()},this.originalPosition={left:s,top:n},this.sizeDiff={width:h.outerWidth()-h.width(),height:h.outerHeight()-h.height()},this.originalMousePosition={left:i.pageX,top:i.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,a=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===a?this.axis+"-resize":a),h.addClass("ui-resizable-resizing"),this._propagate("start",i),!0},_mouseDrag:function(e){var i,s=this.helper,n={},a=this.originalMousePosition,o=this.axis,r=this.position.top,h=this.position.left,l=this.size.width,c=this.size.height,u=e.pageX-a.left||0,d=e.pageY-a.top||0,p=this._change[o];return p?(i=p.apply(this,[e,u,d]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),this.position.top!==r&&(n.top=this.position.top+"px"),this.position.left!==h&&(n.left=this.position.left+"px"),this.size.width!==l&&(n.width=this.size.width+"px"),this.size.height!==c&&(n.height=this.size.height+"px"),s.css(n),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(n)||this._trigger("resize",e,this.ui()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,a,o,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&t.ui.hasScroll(i[0],"left")?0:c.sizeDiff.height,a=s?0:c.sizeDiff.width,o={width:c.helper.width()-a,height:c.helper.height()-n},r=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null,h=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(o,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(t){var e,s,n,a,o,r=this.options;o={minWidth:i(r.minWidth)?r.minWidth:0,maxWidth:i(r.maxWidth)?r.maxWidth:1/0,minHeight:i(r.minHeight)?r.minHeight:0,maxHeight:i(r.maxHeight)?r.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,n=o.minWidth/this.aspectRatio,s=o.maxHeight*this.aspectRatio,a=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),n>o.minHeight&&(o.minHeight=n),o.maxWidth>s&&(o.maxWidth=s),o.maxHeight>a&&(o.maxHeight=a)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),i(t.left)&&(this.position.left=t.left),i(t.top)&&(this.position.top=t.top),i(t.height)&&(this.size.height=t.height),i(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,s=this.size,n=this.axis;return i(t.height)?t.width=t.height*this.aspectRatio:i(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===n&&(t.left=e.left+(s.width-t.width),t.top=null),"nw"===n&&(t.top=e.top+(s.height-t.height),t.left=e.left+(s.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,s=this.axis,n=i(t.width)&&e.maxWidth&&e.maxWidth<t.width,a=i(t.height)&&e.maxHeight&&e.maxHeight<t.height,o=i(t.width)&&e.minWidth&&e.minWidth>t.width,r=i(t.height)&&e.minHeight&&e.minHeight>t.height,h=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,c=/sw|nw|w/.test(s),u=/nw|ne|n/.test(s);return o&&(t.width=e.minWidth),r&&(t.height=e.minHeight),n&&(t.width=e.maxWidth),a&&(t.height=e.maxHeight),o&&c&&(t.left=h-e.minWidth),n&&c&&(t.left=h-e.maxWidth),r&&u&&(t.top=l-e.minHeight),a&&u&&(t.top=l-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_proportionallyResize:function(){if(this._proportionallyResizeElements.length){var t,e,i,s,n,a=this.helper||this.element;for(t=0;this._proportionallyResizeElements.length>t;t++){if(n=this._proportionallyResizeElements[t],!this.borderDif)for(this.borderDif=[],i=[n.css("borderTopWidth"),n.css("borderRightWidth"),n.css("borderBottomWidth"),n.css("borderLeftWidth")],s=[n.css("paddingTop"),n.css("paddingRight"),n.css("paddingBottom"),n.css("paddingLeft")],e=0;i.length>e;e++)this.borderDif[e]=(parseInt(i[e],10)||0)+(parseInt(s[e],10)||0);n.css({height:a.height()-this.borderDif[0]-this.borderDif[2]||0,width:a.width()-this.borderDif[1]-this.borderDif[3]||0})}}},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).data("ui-resizable"),s=i.options,n=i._proportionallyResizeElements,a=n.length&&/textarea/i.test(n[0].nodeName),o=a&&t.ui.hasScroll(n[0],"left")?0:i.sizeDiff.height,r=a?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-o},l=parseInt(i.element.css("left"),10)+(i.position.left-i.originalPosition.left)||null,c=parseInt(i.element.css("top"),10)+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseInt(i.element.css("width"),10),height:parseInt(i.element.css("height"),10),top:parseInt(i.element.css("top"),10),left:parseInt(i.element.css("left"),10)};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var i,s,n,a,o,r,h,l=t(this).data("ui-resizable"),c=l.options,u=l.element,d=c.containment,p=d instanceof t?d.get(0):/parent/.test(d)?u.parent().get(0):d;p&&(l.containerElement=t(p),/document/.test(d)||d===document?(l.containerOffset={left:0,top:0},l.containerPosition={left:0,top:0},l.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(i=t(p),s=[],t(["Top","Right","Left","Bottom"]).each(function(t,n){s[t]=e(i.css("padding"+n))}),l.containerOffset=i.offset(),l.containerPosition=i.position(),l.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},n=l.containerOffset,a=l.containerSize.height,o=l.containerSize.width,r=t.ui.hasScroll(p,"left")?p.scrollWidth:o,h=t.ui.hasScroll(p)?p.scrollHeight:a,l.parentData={element:p,left:n.left,top:n.top,width:r,height:h}))},resize:function(e){var i,s,n,a,o=t(this).data("ui-resizable"),r=o.options,h=o.containerOffset,l=o.position,c=o._aspectRatio||e.shiftKey,u={top:0,left:0},d=o.containerElement;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(o._helper?h.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-h.left:o.position.left-u.left),c&&(o.size.height=o.size.width/o.aspectRatio),o.position.left=r.helper?h.left:0),l.top<(o._helper?h.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-h.top:o.position.top),c&&(o.size.width=o.size.height*o.aspectRatio),o.position.top=o._helper?h.top:0),o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top,i=Math.abs((o._helper?o.offset.left-u.left:o.offset.left-u.left)+o.sizeDiff.width),s=Math.abs((o._helper?o.offset.top-u.top:o.offset.top-h.top)+o.sizeDiff.height),n=o.containerElement.get(0)===o.element.parent().get(0),a=/relative|absolute/.test(o.containerElement.css("position")),n&&a&&(i-=Math.abs(o.parentData.left)),i+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-i,c&&(o.size.height=o.size.width/o.aspectRatio)),s+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-s,c&&(o.size.width=o.size.height*o.aspectRatio))},stop:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.containerOffset,n=e.containerPosition,a=e.containerElement,o=t(e.helper),r=o.offset(),h=o.outerWidth()-e.sizeDiff.width,l=o.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(a.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(a.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=function(e){t(e).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseInt(e.width(),10),height:parseInt(e.height(),10),left:parseInt(e.css("left"),10),top:parseInt(e.css("top"),10)})})};"object"!=typeof i.alsoResize||i.alsoResize.parentNode?s(i.alsoResize):i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):t.each(i.alsoResize,function(t){s(t)})},resize:function(e,i){var s=t(this).data("ui-resizable"),n=s.options,a=s.originalSize,o=s.originalPosition,r={height:s.size.height-a.height||0,width:s.size.width-a.width||0,top:s.position.top-o.top||0,left:s.position.left-o.left||0},h=function(e,s){t(e).each(function(){var e=t(this),n=t(this).data("ui-resizable-alsoresize"),a={},o=s&&s.length?s:e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(n[e]||0)+(r[e]||0);i&&i>=0&&(a[e]=i||null)}),e.css(a)})};"object"!=typeof n.alsoResize||n.alsoResize.nodeType?h(n.alsoResize):t.each(n.alsoResize,function(t,e){h(t,e)})},stop:function(){t(this).removeData("resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof i.ghost?i.ghost:""),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).data("ui-resizable");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).data("ui-resizable");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e=t(this).data("ui-resizable"),i=e.options,s=e.size,n=e.originalSize,a=e.originalPosition,o=e.axis,r="number"==typeof i.grid?[i.grid,i.grid]:i.grid,h=r[0]||1,l=r[1]||1,c=Math.round((s.width-n.width)/h)*h,u=Math.round((s.height-n.height)/l)*l,d=n.width+c,p=n.height+u,f=i.maxWidth&&d>i.maxWidth,g=i.maxHeight&&p>i.maxHeight,m=i.minWidth&&i.minWidth>d,v=i.minHeight&&i.minHeight>p;i.grid=r,m&&(d+=h),v&&(p+=l),f&&(d-=h),g&&(p-=l),/^(se|s|e)$/.test(o)?(e.size.width=d,e.size.height=p):/^(ne)$/.test(o)?(e.size.width=d,e.size.height=p,e.position.top=a.top-u):/^(sw)$/.test(o)?(e.size.width=d,e.size.height=p,e.position.left=a.left-c):(p-l>0?(e.size.height=p,e.position.top=a.top-u):(e.size.height=l,e.position.top=a.top+n.height-l),d-h>0?(e.size.width=d,e.position.left=a.left-c):(e.size.width=h,e.position.left=a.left+n.width-h))}})})(jQuery);(function(t){t.widget("ui.selectable",t.ui.mouse,{version:"1.10.4",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e,i=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e=t(i.options.filter,i.element[0]),e.addClass("ui-selectee"),e.each(function(){var e=t(this),i=e.offset();t.data(this,"selectable-item",{element:this,$element:e,left:i.left,top:i.top,right:i.left+e.outerWidth(),bottom:i.top+e.outerHeight(),startselected:!1,selected:e.hasClass("ui-selected"),selecting:e.hasClass("ui-selecting"),unselecting:e.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=e.addClass("ui-selectee"),this._mouseInit(),this.helper=t("<div class='ui-selectable-helper'></div>")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(s.$element.removeClass("ui-selected"),s.selected=!1,s.$element.addClass("ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,n=t.data(this,"selectable-item");return n?(s=!e.metaKey&&!e.ctrlKey||!n.$element.hasClass("ui-selected"),n.$element.removeClass(s?"ui-unselecting":"ui-selected").addClass(s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",e,{selecting:n.element}):i._trigger("unselecting",e,{unselecting:n.element}),!1):undefined}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,a=this.opos[0],o=this.opos[1],r=e.pageX,l=e.pageY;return a>r&&(i=r,r=a,a=i),o>l&&(i=l,l=o,o=i),this.helper.css({left:a,top:o,width:r-a,height:l-o}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),h=!1;i&&i.element!==s.element[0]&&("touch"===n.tolerance?h=!(i.left>r||a>i.right||i.top>l||o>i.bottom):"fit"===n.tolerance&&(h=i.left>a&&r>i.right&&i.top>o&&l>i.bottom),h?(i.selected&&(i.$element.removeClass("ui-selected"),i.selected=!1),i.unselecting&&(i.$element.removeClass("ui-unselecting"),i.unselecting=!1),i.selecting||(i.$element.addClass("ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.$element.addClass("ui-selected"),i.selected=!0):(i.$element.removeClass("ui-selecting"),i.selecting=!1,i.startselected&&(i.$element.addClass("ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(i.$element.removeClass("ui-selected"),i.selected=!1,i.$element.addClass("ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");s.$element.removeClass("ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");s.$element.removeClass("ui-selecting").addClass("ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}})})(jQuery);(function(t){var e=5;t.widget("ui.slider",t.ui.mouse,{version:"1.10.4",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),a="<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",o=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)o.push(a);this.handles=n.add(t(o.join("")).appendTo(this.element)),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e)})},_createRange:function(){var e=this.options,i="";e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}):(this.range=t("<div></div>").appendTo(this.element),i="ui-slider-range ui-widget-header ui-corner-all"),this.range.addClass(i+("min"===e.range||"max"===e.range?" ui-slider-range-"+e.range:""))):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){var t=this.handles.add(this.range).filter("a");this._off(t),this._on(t,this._handleEvents),this._hoverable(t),this._focusable(t)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,a,o,r,l,h,u=this,c=this.options;return c.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-u.values(e));(n>i||n===i&&(e===u._lastChangedValue||u.values(e)===c.min))&&(n=i,a=t(this),o=e)}),r=this._start(e,o),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,a.addClass("ui-state-active").focus(),l=a.offset(),h=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=h?{left:0,top:0}:{left:e.pageX-l.left-a.width()/2,top:e.pageY-l.top-a.height()/2-(parseInt(a.css("borderTopWidth"),10)||0)-(parseInt(a.css("borderBottomWidth"),10)||0)+(parseInt(a.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,o,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,a;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),a=this._valueMin()+s*n,this._trimAlignValue(a)},_start:function(t,e){var i={handle:this.handles[e],value:this.value()};return this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._trigger("start",t,i)},_slide:function(t,e,i){var s,n,a;this.options.values&&this.options.values.length?(s=this.values(e?0:1),2===this.options.values.length&&this.options.range===!0&&(0===e&&i>s||1===e&&s>i)&&(i=s),i!==this.values(e)&&(n=this.values(),n[e]=i,a=this._trigger("slide",t,{handle:this.handles[e],value:i,values:n}),s=this.values(e?0:1),a!==!1&&this.values(e,i))):i!==this.value()&&(a=this._trigger("slide",t,{handle:this.handles[e],value:i}),a!==!1&&this.value(i))},_stop:function(t,e){var i={handle:this.handles[e],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._trigger("stop",t,i)},_change:function(t,e){if(!this._keySliding&&!this._mouseSliding){var i={handle:this.handles[e],value:this.value()};this.options.values&&this.options.values.length&&(i.value=this.values(e),i.values=this.values()),this._lastChangedValue=e,this._trigger("change",t,i)}},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),undefined):this._value()},values:function(e,i){var s,n,a;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),undefined;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(e):this.value();for(s=this.options.values,n=arguments[0],a=0;s.length>a;a+=1)s[a]=this._trimAlignValue(n[a]),this._change(null,a);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),t.Widget.prototype._setOption.apply(this,arguments),e){case"orientation":this._detectOrientation(),this.element.removeClass("ui-slider-horizontal ui-slider-vertical").addClass("ui-slider-"+this.orientation),this._refreshValue();break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=0;n>s;s+=1)this._change(null,s);this._animateOff=!1;break;case"min":case"max":this._animateOff=!0,this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this.options.values&&this.options.values.length){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var e,i,s,n,a,o=this.options.range,r=this.options,l=this,h=this._animateOff?!1:r.animate,u={};this.options.values&&this.options.values.length?this.handles.each(function(s){i=100*((l.values(s)-l._valueMin())/(l._valueMax()-l._valueMin())),u["horizontal"===l.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[h?"animate":"css"](u,r.animate),l.options.range===!0&&("horizontal"===l.orientation?(0===s&&l.range.stop(1,1)[h?"animate":"css"]({left:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&l.range.stop(1,1)[h?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),a=this._valueMax(),i=a!==n?100*((s-n)/(a-n)):0,u["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[h?"animate":"css"](u,r.animate),"min"===o&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:i+"%"},r.animate),"max"===o&&"horizontal"===this.orientation&&this.range[h?"animate":"css"]({width:100-i+"%"},{queue:!1,duration:r.animate}),"min"===o&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:i+"%"},r.animate),"max"===o&&"vertical"===this.orientation&&this.range[h?"animate":"css"]({height:100-i+"%"},{queue:!1,duration:r.animate}))},_handleEvents:{keydown:function(i){var s,n,a,o,r=t(i.target).data("ui-slider-handle-index");switch(i.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(i.preventDefault(),!this._keySliding&&(this._keySliding=!0,t(i.target).addClass("ui-state-active"),s=this._start(i,r),s===!1))return}switch(o=this.options.step,n=a=this.options.values&&this.options.values.length?this.values(r):this.value(),i.keyCode){case t.ui.keyCode.HOME:a=this._valueMin();break;case t.ui.keyCode.END:a=this._valueMax();break;case t.ui.keyCode.PAGE_UP:a=this._trimAlignValue(n+(this._valueMax()-this._valueMin())/e);break;case t.ui.keyCode.PAGE_DOWN:a=this._trimAlignValue(n-(this._valueMax()-this._valueMin())/e);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(n===this._valueMax())return;a=this._trimAlignValue(n+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(n===this._valueMin())return;a=this._trimAlignValue(n-o)}this._slide(i,r,a)},click:function(t){t.preventDefault()},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),t(e.target).removeClass("ui-state-active"))}}})})(jQuery);(function(t){function e(t,e,i){return t>e&&e+i>t}function i(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))}t.widget("ui.sortable",t.ui.mouse,{version:"1.10.4",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var t=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===t.axis||i(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_setOption:function(e,i){"disabled"===e?(this.options[e]=i,this.widget().toggleClass("ui-sortable-disabled",!!i)):t.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):undefined}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("<style>*{ cursor: "+a.cursor+" !important; }</style>").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<a.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+a.scrollSpeed:e.pageY-this.overflowOffset.top<a.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-a.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<a.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+a.scrollSpeed:e.pageX-this.overflowOffset.left<a.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-a.scrollSpeed)):(e.pageY-t(document).scrollTop()<a.scrollSensitivity?r=t(document).scrollTop(t(document).scrollTop()-a.scrollSpeed):t(window).height()-(e.pageY-t(document).scrollTop())<a.scrollSensitivity&&(r=t(document).scrollTop(t(document).scrollTop()+a.scrollSpeed)),e.pageX-t(document).scrollLeft()<a.scrollSensitivity?r=t(document).scrollLeft(t(document).scrollLeft()-a.scrollSpeed):t(window).width()-(e.pageX-t(document).scrollLeft())<a.scrollSensitivity&&(r=t(document).scrollLeft(t(document).scrollLeft()+a.scrollSpeed))),r!==!1&&t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var i="x"===this.options.axis||e(this.positionAbs.top+this.offset.click.top,t.top,t.height),s="y"===this.options.axis||e(this.positionAbs.left+this.offset.click.left,t.left,t.width),n=i&&s,o=this._getDragVerticalDirection(),a=this._getDragHorizontalDirection();return n?this.floating?a&&"right"===a||"down"===o?2:1:o&&("down"===o?2:1):!1},_intersectsWithSides:function(t){var i=e(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),s=e(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),n=this._getDragVerticalDirection(),o=this._getDragHorizontalDirection();return this.floating&&o?"right"===o&&s||"left"===o&&!s:n&&("down"===n&&i||"up"===n&&!i)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],h=[],l=this._connectWith();if(l&&e)for(s=l.length-1;s>=0;s--)for(o=t(l[s]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&h.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(h.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]).addClass(i||e.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?e.currentItem.children().each(function(){t("<td> </td>",e.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(n)}):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_contactContainers:function(s){var n,o,a,r,h,l,c,u,d,p,f=null,g=null;for(n=this.containers.length-1;n>=0;n--)if(!t.contains(this.currentItem[0],this.containers[n].element[0]))if(this._intersectsWith(this.containers[n].containerCache)){if(f&&t.contains(this.containers[n].element[0],f.element[0]))continue;f=this.containers[n],g=n}else this.containers[n].containerCache.over&&(this.containers[n]._trigger("out",s,this._uiHash(this)),this.containers[n].containerCache.over=0);if(f)if(1===this.containers.length)this.containers[g].containerCache.over||(this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1);else{for(a=1e4,r=null,p=f.floating||i(this.currentItem),h=p?"left":"top",l=p?"width":"height",c=this.positionAbs[h]+this.offset.click[h],o=this.items.length-1;o>=0;o--)t.contains(this.containers[g].element[0],this.items[o].item[0])&&this.items[o].item[0]!==this.currentItem[0]&&(!p||e(this.positionAbs.top+this.offset.click.top,this.items[o].top,this.items[o].height))&&(u=this.items[o].item.offset()[h],d=!1,Math.abs(u-c)>Math.abs(u+this.items[o][l]-c)&&(d=!0,u+=this.items[o][l]),a>Math.abs(u-c)&&(a=Math.abs(u-c),r=this.items[o],this.direction=d?"up":"down"));if(!r&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[g])return;r?this._rearrange(s,r,null,!0):this._rearrange(s,null,this.containers[g].element,!0),this._trigger("change",s,this._uiHash()),this.containers[g]._trigger("change",s,this._uiHash(this)),this.currentContainer=this.containers[g],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[g]._trigger("over",s,this._uiHash(this)),this.containers[g].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,t("document"===n.containment?document:window).width()-this.helperProportions.width-this.margins.left,(t("document"===n.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(o=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(a=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!e){for(this._trigger("beforeStop",t,this._uiHash()),s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!1}if(e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}})})(jQuery);(function(t){function e(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.widget("ui.spinner",{version:"1.10.4",defaultElement:"<input>",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e={},i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);void 0!==n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var t=this.element[0]===this.document[0].activeElement;t||(this.element.focus(),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var t=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=t.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(.5*t.height())&&t.height()>0&&t.height(t.height()),this.options.disabled&&this.disable()},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_uiSpinnerHtml:function(){return"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>"},_buttonHtml:function(){return"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'><span class='ui-icon "+this.options.icons.up+"'>▲</span>"+"</a>"+"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>"+"<span class='ui-icon "+this.options.icons.down+"'>▼</span>"+"</a>"},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){if("culture"===t||"numberFormat"===t){var i=this._parse(this.element.val());return this.options[t]=e,this.element.val(this._format(i)),void 0}("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(this.buttons.first().find(".ui-icon").removeClass(this.options.icons.up).addClass(e.up),this.buttons.last().find(".ui-icon").removeClass(this.options.icons.down).addClass(e.down)),this._super(t,e),"disabled"===t&&(e?(this.element.prop("disabled",!0),this.buttons.button("disable")):(this.element.prop("disabled",!1),this.buttons.button("enable")))},_setOptions:e(function(t){this._super(t),this._value(this.element.val())}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.removeClass("ui-spinner-input").prop("disabled",!1).removeAttr("autocomplete").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:e(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:e(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:e(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:e(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(e(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}})})(jQuery);(function(t,e){function i(){return++n}function s(t){return t=t.cloneNode(!1),t.hash.length>1&&decodeURIComponent(t.href.replace(a,""))===decodeURIComponent(location.href.replace(a,""))}var n=0,a=/#.*$/;t.widget("ui.tabs",{version:"1.10.4",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var e=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var i=this.options.active,s=this.options.collapsible,n=location.hash.substring(1);return null===i&&(n&&this.tabs.each(function(s,a){return t(a).attr("aria-controls")===n?(i=s,!1):e}),null===i&&(i=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===i||-1===i)&&(i=this.tabs.length?0:!1)),i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),-1===i&&(i=s?!1:0)),!s&&i===!1&&this.anchors.length&&(i=0),i},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(i){var s=t(this.document[0].activeElement).closest("li"),n=this.tabs.index(s),a=!0;if(!this._handlePageNav(i)){switch(i.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:n++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:a=!1,n--;break;case t.ui.keyCode.END:n=this.anchors.length-1;break;case t.ui.keyCode.HOME:n=0;break;case t.ui.keyCode.SPACE:return i.preventDefault(),clearTimeout(this.activating),this._activate(n),e;case t.ui.keyCode.ENTER:return i.preventDefault(),clearTimeout(this.activating),this._activate(n===this.options.active?!1:n),e;default:return}i.preventDefault(),clearTimeout(this.activating),n=this._focusNextTab(n,a),i.ctrlKey||(s.attr("aria-selected","false"),this.tabs.eq(n).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",n)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.focus())},_handlePageNav:function(i){return i.altKey&&i.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):i.altKey&&i.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):e},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).focus(),t},_setOption:function(t,i){return"active"===t?(this._activate(i),e):"disabled"===t?(this._setupDisabled(i),e):(this._super(t,i),"collapsible"===t&&(this.element.toggleClass("ui-tabs-collapsible",i),i||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(i),"heightStyle"===t&&this._setupHeightStyle(i),e)},_tabId:function(t){return t.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=t(),this.anchors.each(function(i,n){var a,o,r,h=t(n).uniqueId().attr("id"),l=t(n).closest("li"),c=l.attr("aria-controls");s(n)?(a=n.hash,o=e.element.find(e._sanitizeSelector(a))):(r=e._tabId(l),a="#"+r,o=e.element.find(a),o.length||(o=e._createPanel(r),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),c&&l.data("ui-tabs-aria-controls",c),l.attr({"aria-controls":a.substring(1),"aria-labelledby":h}),o.attr("aria-labelledby",h)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.tablist||this.element.find("ol,ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(e){t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1);for(var i,s=0;i=this.tabs[s];s++)e===!0||-1!==t.inArray(s,e)?t(i).addClass("ui-state-disabled").attr("aria-disabled","true"):t(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=e},_setupEvents:function(e){var i={click:function(t){t.preventDefault()}};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),a=n.closest("li"),o=a[0]===s[0],r=o&&i.collapsible,h=r?t():this._getPanelForTab(a),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():a,newPanel:h};e.preventDefault(),a.hasClass("ui-state-disabled")||a.hasClass("ui-tabs-loading")||this.running||o&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(a),this.active=o?t():a,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(a),e),this._toggle(e,c))},_toggle:function(e,i){function s(){a.running=!1,a._trigger("activate",e,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),o.length&&a.options.show?a._show(o,a.options.show,s):(o.show(),s())}var a=this,o=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr({"aria-expanded":"false","aria-hidden":"true"}),i.oldTab.attr("aria-selected","false"),o.length&&r.length?i.oldTab.attr("tabIndex",-1):o.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),o.attr({"aria-expanded":"true","aria-hidden":"false"}),i.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(t){return"string"==typeof t&&(t=this.anchors.index(this.anchors.filter("[href$='"+t+"']"))),t},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var s=this.options.disabled;s!==!1&&(i===e?s=!1:(i=this._getIndex(i),s=t.isArray(s)?t.map(s,function(t){return t!==i?t:null}):t.map(this.tabs,function(t,e){return e!==i?e:null})),this._setupDisabled(s))},disable:function(i){var s=this.options.disabled;if(s!==!0){if(i===e)s=!0;else{if(i=this._getIndex(i),-1!==t.inArray(i,s))return;s=t.isArray(s)?t.merge([i],s).sort():[i]}this._setupDisabled(s)}},load:function(e,i){e=this._getIndex(e);var n=this,a=this.tabs.eq(e),o=a.find(".ui-tabs-anchor"),r=this._getPanelForTab(a),h={tab:a,panel:r};s(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,h)),this.xhr&&"canceled"!==this.xhr.statusText&&(a.addClass("ui-tabs-loading"),r.attr("aria-busy","true"),this.xhr.success(function(t){setTimeout(function(){r.html(t),n._trigger("load",i,h)},1)}).complete(function(t,e){setTimeout(function(){"abort"===e&&n.panels.stop(!1,!0),a.removeClass("ui-tabs-loading"),r.removeAttr("aria-busy"),t===n.xhr&&delete n.xhr},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href"),beforeSend:function(e,a){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:a},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})})(jQuery);(function(t){function e(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))}function i(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")}var s=0;t.widget("ui.tooltip",{version:"1.10.4",options:{content:function(){var e=t(this).attr("title")||"";return t("<a>").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(e,i){var s=this;return"disabled"===e?(this[i?"_disable":"_enable"](),this.options[e]=i,void 0):(this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e)}),void 0)},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0)}),this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.is("[title]")&&e.data("ui-tooltip-title",e.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))})},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s?this._open(e,t,s):(i=s.call(t[0],function(i){t.data("ui-tooltip-open")&&n._delay(function(){e&&(e.type=o),this._open(e,t,i)})}),i&&this._open(e,t,i),void 0)},_open:function(i,s,n){function o(t){l.of=t,a.is(":hidden")||a.position(l)}var a,r,h,l=t.extend({},this.options.position);if(n){if(a=this._find(s),a.length)return a.find(".ui-tooltip-content").html(n),void 0;s.is("[title]")&&(i&&"mouseover"===i.type?s.attr("title",""):s.removeAttr("title")),a=this._tooltip(s),e(s,a.attr("id")),a.find(".ui-tooltip-content").html(n),this.options.track&&i&&/^mouse/.test(i.type)?(this._on(this.document,{mousemove:o}),o(i)):a.position(t.extend({of:s},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.show&&this.options.show.delay&&(h=this.delayedShow=setInterval(function(){a.is(":visible")&&(o(l.of),clearInterval(h))},t.fx.interval)),this._trigger("open",i,{tooltip:a}),r={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var i=t.Event(e);i.currentTarget=s[0],this.close(i,!0)}},remove:function(){this._removeTooltip(a)}},i&&"mouseover"!==i.type||(r.mouseleave="close"),i&&"focusin"!==i.type||(r.focusout="close"),this._on(!0,s,r)}},close:function(e){var s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);this.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&n.attr("title",n.data("ui-tooltip-title")),i(n),o.stop(!0),this._hide(o,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]}),this.closing=!0,this._trigger("close",e,{tooltip:o}),this.closing=!1)},_tooltip:function(e){var i="ui-tooltip-"+s++,n=t("<div>").attr({id:i,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return t("<div>").addClass("ui-tooltip-content").appendTo(n),n.appendTo(this.document[0].body),this.tooltips[i]=e,n},_find:function(e){var i=e.data("ui-tooltip-id");return i?t("#"+i):t()},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s[0],e.close(n,!0),t("#"+i).remove(),s.data("ui-tooltip-title")&&(s.attr("title",s.data("ui-tooltip-title")),s.removeData("ui-tooltip-title"))})}})})(jQuery);
|
||
/*!
|
||
* Bootstrap v3.1.1 (http://getbootstrap.com)
|
||
* Copyright 2011-2014 Twitter, Inc.
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||
*/
|
||
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one(a.support.transition.end,function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b()})}(jQuery),+function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function c(){f.trigger("closed.bs.alert").remove()}var d=a(this),e=d.attr("data-target");e||(e=d.attr("href"),e=e&&e.replace(/.*(?=#[^\s]*$)/,""));var f=a(e);b&&b.preventDefault(),f.length||(f=d.hasClass("alert")?d:d.parent()),f.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one(a.support.transition.end,c).emulateTransitionEnd(150):c())};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),"string"==typeof b&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.isLoading=!1};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",f.resetText||d.data("resetText",d[e]()),d[e](f[b]||this.options[b]),setTimeout(a.proxy(function(){"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},b.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}a&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof c&&c;e||d.data("bs.button",e=new b(this,f)),"toggle"==c?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){"use strict";var b=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,"hover"==this.options.pause&&this.$element.on("mouseenter",a.proxy(this.pause,this)).on("mouseleave",a.proxy(this.cycle,this))};b.DEFAULTS={interval:5e3,pause:"hover",wrap:!0},b.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},b.prototype.getActiveIndex=function(){return this.$active=this.$element.find(".item.active"),this.$items=this.$active.parent().children(),this.$items.index(this.$active)},b.prototype.to=function(b){var c=this,d=this.getActiveIndex();return b>this.$items.length-1||0>b?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){c.to(b)}):d==b?this.pause().cycle():this.slide(b>d?"next":"prev",a(this.$items[b]))},b.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},b.prototype.next=function(){return this.sliding?void 0:this.slide("next")},b.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},b.prototype.slide=function(b,c){var d=this.$element.find(".item.active"),e=c||d[b](),f=this.interval,g="next"==b?"left":"right",h="next"==b?"first":"last",i=this;if(!e.length){if(!this.options.wrap)return;e=this.$element.find(".item")[h]()}if(e.hasClass("active"))return this.sliding=!1;var j=a.Event("slide.bs.carousel",{relatedTarget:e[0],direction:g});return this.$element.trigger(j),j.isDefaultPrevented()?void 0:(this.sliding=!0,f&&this.pause(),this.$indicators.length&&(this.$indicators.find(".active").removeClass("active"),this.$element.one("slid.bs.carousel",function(){var b=a(i.$indicators.children()[i.getActiveIndex()]);b&&b.addClass("active")})),a.support.transition&&this.$element.hasClass("slide")?(e.addClass(b),e[0].offsetWidth,d.addClass(g),e.addClass(g),d.one(a.support.transition.end,function(){e.removeClass([b,g].join(" ")).addClass("active"),d.removeClass(["active",g].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger("slid.bs.carousel")},0)}).emulateTransitionEnd(1e3*d.css("transition-duration").slice(0,-1))):(d.removeClass("active"),e.addClass("active"),this.sliding=!1,this.$element.trigger("slid.bs.carousel")),f&&this.cycle(),this)};var c=a.fn.carousel;a.fn.carousel=function(c){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c),g="string"==typeof c?c:f.slide;e||d.data("bs.carousel",e=new b(this,f)),"number"==typeof c?e.to(c):g?e[g]():f.interval&&e.pause().cycle()})},a.fn.carousel.Constructor=b,a.fn.carousel.noConflict=function(){return a.fn.carousel=c,this},a(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",function(b){var c,d=a(this),e=a(d.attr("data-target")||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"")),f=a.extend({},e.data(),d.data()),g=d.attr("data-slide-to");g&&(f.interval=!1),e.carousel(f),(g=d.attr("data-slide-to"))&&e.data("bs.carousel").to(g),b.preventDefault()}),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var b=a(this);b.carousel(b.data())})})}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d),this.transitioning=null,this.options.parent&&(this.$parent=a(this.options.parent)),this.options.toggle&&this.toggle()};b.DEFAULTS={toggle:!0},b.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},b.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b=a.Event("show.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.$parent&&this.$parent.find("> .panel > .in");if(c&&c.length){var d=c.data("bs.collapse");if(d&&d.transitioning)return;c.collapse("hide"),d||c.data("bs.collapse",null)}var e=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[e](0),this.transitioning=1;var f=function(){this.$element.removeClass("collapsing").addClass("collapse in")[e]("auto"),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return f.call(this);var g=a.camelCase(["scroll",e].join("-"));this.$element.one(a.support.transition.end,a.proxy(f,this)).emulateTransitionEnd(350)[e](this.$element[0][g])}}},b.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse").removeClass("in"),this.transitioning=1;var d=function(){this.transitioning=0,this.$element.trigger("hidden.bs.collapse").removeClass("collapsing").addClass("collapse")};return a.support.transition?void this.$element[c](0).one(a.support.transition.end,a.proxy(d,this)).emulateTransitionEnd(350):d.call(this)}}},b.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};var c=a.fn.collapse;a.fn.collapse=function(c){return this.each(function(){var d=a(this),e=d.data("bs.collapse"),f=a.extend({},b.DEFAULTS,d.data(),"object"==typeof c&&c);!e&&f.toggle&&"show"==c&&(c=!c),e||d.data("bs.collapse",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.collapse.Constructor=b,a.fn.collapse.noConflict=function(){return a.fn.collapse=c,this},a(document).on("click.bs.collapse.data-api","[data-toggle=collapse]",function(b){var c,d=a(this),e=d.attr("data-target")||b.preventDefault()||(c=d.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,""),f=a(e),g=f.data("bs.collapse"),h=g?"toggle":d.data(),i=d.attr("data-parent"),j=i&&a(i);g&&g.transitioning||(j&&j.find('[data-toggle=collapse][data-parent="'+i+'"]').not(d).addClass("collapsed"),d[f.hasClass("in")?"addClass":"removeClass"]("collapsed")),f.collapse(h)})}(jQuery),+function(a){"use strict";function b(b){a(d).remove(),a(e).each(function(){var d=c(a(this)),e={relatedTarget:this};d.hasClass("open")&&(d.trigger(b=a.Event("hide.bs.dropdown",e)),b.isDefaultPrevented()||d.removeClass("open").trigger("hidden.bs.dropdown",e))})}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}var d=".dropdown-backdrop",e="[data-toggle=dropdown]",f=function(b){a(b).on("click.bs.dropdown",this.toggle)};f.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;f.toggleClass("open").trigger("shown.bs.dropdown",h),e.focus()}return!1}},f.prototype.keydown=function(b){if(/(38|40|27)/.test(b.keyCode)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var f=c(d),g=f.hasClass("open");if(!g||g&&27==b.keyCode)return 27==b.which&&f.find(e).focus(),d.click();var h=" li:not(.divider):visible a",i=f.find("[role=menu]"+h+", [role=listbox]"+h);if(i.length){var j=i.index(i.filter(":focus"));38==b.keyCode&&j>0&&j--,40==b.keyCode&&j<i.length-1&&j++,~j||(j=0),i.eq(j).focus()}}}};var g=a.fn.dropdown;a.fn.dropdown=function(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new f(this)),"string"==typeof b&&d[b].call(c)})},a.fn.dropdown.Constructor=f,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=g,this},a(document).on("click.bs.dropdown.data-api",b).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",e,f.prototype.toggle).on("keydown.bs.dropdown.data-api",e+", [role=menu], [role=listbox]",f.prototype.keydown)}(jQuery),+function(a){"use strict";var b=function(b,c){this.options=c,this.$element=a(b),this.$backdrop=this.isShown=null,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};b.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},b.prototype.toggle=function(a){return this[this.isShown?"hide":"show"](a)},b.prototype.show=function(b){var c=this,d=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(d),this.isShown||d.isDefaultPrevented()||(this.isShown=!0,this.escape(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var d=a.support.transition&&c.$element.hasClass("fade");c.$element.parent().length||c.$element.appendTo(document.body),c.$element.show().scrollTop(0),d&&c.$element[0].offsetWidth,c.$element.addClass("in").attr("aria-hidden",!1),c.enforceFocus();var e=a.Event("shown.bs.modal",{relatedTarget:b});d?c.$element.find(".modal-dialog").one(a.support.transition.end,function(){c.$element.focus().trigger(e)}).emulateTransitionEnd(300):c.$element.focus().trigger(e)}))},b.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one(a.support.transition.end,a.proxy(this.hideModal,this)).emulateTransitionEnd(300):this.hideModal())},b.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.focus()},this))},b.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keyup.dismiss.bs.modal")},b.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.removeBackdrop(),a.$element.trigger("hidden.bs.modal")})},b.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},b.prototype.backdrop=function(b){var c=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var d=a.support.transition&&c;if(this.$backdrop=a('<div class="modal-backdrop '+c+'" />').appendTo(document.body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),d&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;d?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()):b&&b()};var c=a.fn.modal;a.fn.modal=function(c,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},b.DEFAULTS,e.data(),"object"==typeof c&&c);f||e.data("bs.modal",f=new b(this,g)),"string"==typeof c?f[c](d):g.show&&f.show(d)})},a.fn.modal.Constructor=b,a.fn.modal.noConflict=function(){return a.fn.modal=c,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d=c.attr("href"),e=a(c.attr("data-target")||d&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(d)&&d},e.data(),c.data());c.is("a")&&b.preventDefault(),e.modal(f,this).one("hide",function(){c.is(":visible")&&c.focus()})}),a(document).on("show.bs.modal",".modal",function(){a(document.body).addClass("modal-open")}).on("hidden.bs.modal",".modal",function(){a(document.body).removeClass("modal-open")})}(jQuery),+function(a){"use strict";var b=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};b.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},b.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},b.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},b.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show()},b.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},b.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){if(this.$element.trigger(b),b.isDefaultPrevented())return;var c=this,d=this.tip();this.setContent(),this.options.animation&&d.addClass("fade");var e="function"==typeof this.options.placement?this.options.placement.call(this,d[0],this.$element[0]):this.options.placement,f=/\s?auto?\s?/i,g=f.test(e);g&&(e=e.replace(f,"")||"top"),d.detach().css({top:0,left:0,display:"block"}).addClass(e),this.options.container?d.appendTo(this.options.container):d.insertAfter(this.$element);var h=this.getPosition(),i=d[0].offsetWidth,j=d[0].offsetHeight;if(g){var k=this.$element.parent(),l=e,m=document.documentElement.scrollTop||document.body.scrollTop,n="body"==this.options.container?window.innerWidth:k.outerWidth(),o="body"==this.options.container?window.innerHeight:k.outerHeight(),p="body"==this.options.container?0:k.offset().left;e="bottom"==e&&h.top+h.height+j-m>o?"top":"top"==e&&h.top-m-j<0?"bottom":"right"==e&&h.right+i>n?"left":"left"==e&&h.left-i<p?"right":e,d.removeClass(l).addClass(e)}var q=this.getCalculatedOffset(e,h,i,j);this.applyPlacement(q,e),this.hoverState=null;var r=function(){c.$element.trigger("shown.bs."+c.type)};a.support.transition&&this.$tip.hasClass("fade")?d.one(a.support.transition.end,r).emulateTransitionEnd(150):r()}},b.prototype.applyPlacement=function(b,c){var d,e=this.tip(),f=e[0].offsetWidth,g=e[0].offsetHeight,h=parseInt(e.css("margin-top"),10),i=parseInt(e.css("margin-left"),10);isNaN(h)&&(h=0),isNaN(i)&&(i=0),b.top=b.top+h,b.left=b.left+i,a.offset.setOffset(e[0],a.extend({using:function(a){e.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),e.addClass("in");var j=e[0].offsetWidth,k=e[0].offsetHeight;if("top"==c&&k!=g&&(d=!0,b.top=b.top+g-k),/bottom|top/.test(c)){var l=0;b.left<0&&(l=-2*b.left,b.left=0,e.offset(b),j=e[0].offsetWidth,k=e[0].offsetHeight),this.replaceArrow(l-f+j,j,"left")}else this.replaceArrow(k-g,k,"top");d&&e.offset(b)},b.prototype.replaceArrow=function(a,b,c){this.arrow().css(c,a?50*(1-a/b)+"%":"")},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},b.prototype.hide=function(){function b(){"in"!=c.hoverState&&d.detach(),c.$element.trigger("hidden.bs."+c.type)}var c=this,d=this.tip(),e=a.Event("hide.bs."+this.type);return this.$element.trigger(e),e.isDefaultPrevented()?void 0:(d.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?d.one(a.support.transition.end,b).emulateTransitionEnd(150):b(),this.hoverState=null,this)},b.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},b.prototype.hasContent=function(){return this.getTitle()},b.prototype.getPosition=function(){var b=this.$element[0];return a.extend({},"function"==typeof b.getBoundingClientRect?b.getBoundingClientRect():{width:b.offsetWidth,height:b.offsetHeight},this.$element.offset())},b.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},b.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},b.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},b.prototype.validate=function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},b.prototype.enable=function(){this.enabled=!0},b.prototype.disable=function(){this.enabled=!1},b.prototype.toggleEnabled=function(){this.enabled=!this.enabled},b.prototype.toggle=function(b){var c=b?a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type):this;c.tip().hasClass("in")?c.leave(c):c.enter(c)},b.prototype.destroy=function(){clearTimeout(this.timeout),this.hide().$element.off("."+this.type).removeData("bs."+this.type)};var c=a.fn.tooltip;a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.tooltip",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.tooltip.Constructor=b,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=c,this}}(jQuery),+function(a){"use strict";var b=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");b.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof c&&c;(e||"destroy"!=c)&&(e||d.data("bs.popover",e=new b(this,f)),"string"==typeof c&&e[c]())})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";function b(c,d){var e,f=a.proxy(this.process,this);this.$element=a(a(c).is("body")?window:c),this.$body=a("body"),this.$scrollElement=this.$element.on("scroll.bs.scroll-spy.data-api",f),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||(e=a(c).attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.offsets=a([]),this.targets=a([]),this.activeTarget=null,this.refresh(),this.process()}b.DEFAULTS={offset:10},b.prototype.refresh=function(){var b=this.$element[0]==window?"offset":"position";this.offsets=a([]),this.targets=a([]);{var c=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+(!a.isWindow(c.$scrollElement.get(0))&&c.$scrollElement.scrollTop()),e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){c.offsets.push(this[0]),c.targets.push(this[1])})}},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,d=c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(b>=d)return g!=(a=f.last()[0])&&this.activate(a);if(g&&b<=e[0])return g!=(a=f[0])&&this.activate(a);for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,a(this.selector).parentsUntil(this.options.target,".active").removeClass("active");var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")};var c=a.fn.scrollspy;a.fn.scrollspy=function(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=c,this},a(window).on("load",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);b.scrollspy(b.data())})})}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});if(b.trigger(f),!f.isDefaultPrevented()){var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})}}},b.prototype.activate=function(b,c,d){function e(){f.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),g?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var f=c.find("> .active"),g=d&&a.support.transition&&f.hasClass("fade");g?f.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),f.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),"string"==typeof c&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery),+function(a){"use strict";var b=function(c,d){this.options=a.extend({},b.DEFAULTS,d),this.$window=a(window).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(c),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};b.RESET="affix affix-top affix-bottom",b.DEFAULTS={offset:0},b.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(b.RESET).addClass("affix");var a=this.$window.scrollTop(),c=this.$element.offset();return this.pinnedOffset=c.top-a},b.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},b.prototype.checkPosition=function(){if(this.$element.is(":visible")){var c=a(document).height(),d=this.$window.scrollTop(),e=this.$element.offset(),f=this.options.offset,g=f.top,h=f.bottom;"top"==this.affixed&&(e.top+=d),"object"!=typeof f&&(h=g=f),"function"==typeof g&&(g=f.top(this.$element)),"function"==typeof h&&(h=f.bottom(this.$element));var i=null!=this.unpin&&d+this.unpin<=e.top?!1:null!=h&&e.top+this.$element.height()>=c-h?"bottom":null!=g&&g>=d?"top":!1;if(this.affixed!==i){this.unpin&&this.$element.css("top","");var j="affix"+(i?"-"+i:""),k=a.Event(j+".bs.affix");this.$element.trigger(k),k.isDefaultPrevented()||(this.affixed=i,this.unpin="bottom"==i?this.getPinnedOffset():null,this.$element.removeClass(b.RESET).addClass(j).trigger(a.Event(j.replace("affix","affixed"))),"bottom"==i&&this.$element.offset({top:c-h-this.$element.height()}))}}};var c=a.fn.affix;a.fn.affix=function(c){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof c&&c;e||d.data("bs.affix",e=new b(this,f)),"string"==typeof c&&e[c]()})},a.fn.affix.Constructor=b,a.fn.affix.noConflict=function(){return a.fn.affix=c,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var b=a(this),c=b.data();c.offset=c.offset||{},c.offsetBottom&&(c.offset.bottom=c.offsetBottom),c.offsetTop&&(c.offset.top=c.offsetTop),b.affix(c)})})}(jQuery);
|
||
/*! DataTables 1.10.0
|
||
* ©2008-2014 SpryMedia Ltd - datatables.net/license
|
||
*/
|
||
|
||
/**
|
||
* @summary DataTables
|
||
* @description Paginate, search and order HTML tables
|
||
* @version 1.10.0
|
||
* @file jquery.dataTables.js
|
||
* @author SpryMedia Ltd (www.sprymedia.co.uk)
|
||
* @contact www.sprymedia.co.uk/contact
|
||
* @copyright Copyright 2008-2014 SpryMedia Ltd.
|
||
*
|
||
* This source file is free software, available under the following license:
|
||
* MIT license - http://datatables.net/license
|
||
*
|
||
* This source file is distributed in the hope that it will be useful, but
|
||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
|
||
*
|
||
* For details please refer to: http://www.datatables.net
|
||
*/
|
||
|
||
/*jslint evil: true, undef: true, browser: true */
|
||
/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidateRow,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnScrollBarWidth,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/
|
||
|
||
(/** @lends <global> */function( window, document, undefined ) {
|
||
|
||
(function( factory ) {
|
||
"use strict";
|
||
|
||
if ( typeof define === 'function' && define.amd ) {
|
||
// Define as an AMD module if possible
|
||
define( 'datatables', ['jquery'], factory );
|
||
}
|
||
else if ( typeof exports === 'object' ) {
|
||
// Node/CommonJS
|
||
factory( require( 'jquery' ) );
|
||
}
|
||
else if ( jQuery && !jQuery.fn.dataTable ) {
|
||
// Define using browser globals otherwise
|
||
// Prevent multiple instantiations if the script is loaded twice
|
||
factory( jQuery );
|
||
}
|
||
}
|
||
(/** @lends <global> */function( $ ) {
|
||
"use strict";
|
||
|
||
/**
|
||
* DataTables is a plug-in for the jQuery Javascript library. It is a highly
|
||
* flexible tool, based upon the foundations of progressive enhancement,
|
||
* which will add advanced interaction controls to any HTML table. For a
|
||
* full list of features please refer to
|
||
* [DataTables.net](href="http://datatables.net).
|
||
*
|
||
* Note that the `DataTable` object is not a global variable but is aliased
|
||
* to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may
|
||
* be accessed.
|
||
*
|
||
* @class
|
||
* @param {object} [init={}] Configuration object for DataTables. Options
|
||
* are defined by {@link DataTable.defaults}
|
||
* @requires jQuery 1.7+
|
||
*
|
||
* @example
|
||
* // Basic initialisation
|
||
* $(document).ready( function {
|
||
* $('#example').dataTable();
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Initialisation with configuration options - in this case, disable
|
||
* // pagination and sorting.
|
||
* $(document).ready( function {
|
||
* $('#example').dataTable( {
|
||
* "paginate": false,
|
||
* "sort": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
var DataTable;
|
||
|
||
|
||
/*
|
||
* It is useful to have variables which are scoped locally so only the
|
||
* DataTables functions can access them and they don't leak into global space.
|
||
* At the same time these functions are often useful over multiple files in the
|
||
* core and API, so we list, or at least document, all variables which are used
|
||
* by DataTables as private variables here. This also ensures that there is no
|
||
* clashing of variable names and that they can easily referenced for reuse.
|
||
*/
|
||
|
||
|
||
// Defined else where
|
||
// _selector_run
|
||
// _selector_opts
|
||
// _selector_first
|
||
// _selector_row_indexes
|
||
|
||
var _ext; // DataTable.ext
|
||
var _Api; // DataTable.Api
|
||
var _api_register; // DataTable.Api.register
|
||
var _api_registerPlural; // DataTable.Api.registerPlural
|
||
|
||
var _re_dic = {};
|
||
var _re_new_lines = /[\r\n]/g;
|
||
var _re_html = /<.*?>/g;
|
||
var _re_date_start = /^[\d\+\-a-zA-Z]/;
|
||
|
||
// Escape regular expression special characters
|
||
var _re_escape_regex = new RegExp( '(\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ].join('|\\') + ')', 'g' );
|
||
|
||
// U+2009 is thin space and U+202F is narrow no-break space, both used in many
|
||
// standards as thousands separators
|
||
var _re_formatted_numeric = /[',$£€¥%\u2009\u202F]/g;
|
||
|
||
|
||
var _empty = function ( d ) {
|
||
return !d || d === '-' ? true : false;
|
||
};
|
||
|
||
|
||
var _intVal = function ( s ) {
|
||
var integer = parseInt( s, 10 );
|
||
return !isNaN(integer) && isFinite(s) ? integer : null;
|
||
};
|
||
|
||
// Convert from a formatted number with characters other than `.` as the
|
||
// decimal place, to a Javascript number
|
||
var _numToDecimal = function ( num, decimalPoint ) {
|
||
// Cache created regular expressions for speed as this function is called often
|
||
if ( ! _re_dic[ decimalPoint ] ) {
|
||
_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );
|
||
}
|
||
return typeof num === 'string' ?
|
||
num.replace( /\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :
|
||
num;
|
||
};
|
||
|
||
|
||
var _isNumber = function ( d, decimalPoint, formatted ) {
|
||
var strType = typeof d === 'string';
|
||
|
||
if ( decimalPoint && strType ) {
|
||
d = _numToDecimal( d, decimalPoint );
|
||
}
|
||
|
||
if ( formatted && strType ) {
|
||
d = d.replace( _re_formatted_numeric, '' );
|
||
}
|
||
|
||
return !d || d==='-' || (!isNaN( parseFloat(d) ) && isFinite( d ));
|
||
};
|
||
|
||
|
||
// A string without HTML in it can be considered to be HTML still
|
||
var _isHtml = function ( d ) {
|
||
return !d || typeof d === 'string';
|
||
};
|
||
|
||
|
||
var _htmlNumeric = function ( d, decimalPoint, formatted ) {
|
||
if ( _empty( d ) ) {
|
||
return true;
|
||
}
|
||
|
||
var html = _isHtml( d );
|
||
return ! html ?
|
||
null :
|
||
_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?
|
||
true :
|
||
null;
|
||
};
|
||
|
||
|
||
var _pluck = function ( a, prop, prop2 ) {
|
||
var out = [];
|
||
var i=0, ien=a.length;
|
||
|
||
// Could have the test in the loop for slightly smaller code, but speed
|
||
// is essential here
|
||
if ( prop2 !== undefined ) {
|
||
for ( ; i<ien ; i++ ) {
|
||
if ( a[i] && a[i][ prop ] ) {
|
||
out.push( a[i][ prop ][ prop2 ] );
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
for ( ; i<ien ; i++ ) {
|
||
if ( a[i] ) {
|
||
out.push( a[i][ prop ] );
|
||
}
|
||
}
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
// Basically the same as _pluck, but rather than looping over `a` we use `order`
|
||
// as the indexes to pick from `a`
|
||
var _pluck_order = function ( a, order, prop, prop2 )
|
||
{
|
||
var out = [];
|
||
var i=0, ien=order.length;
|
||
|
||
// Could have the test in the loop for slightly smaller code, but speed
|
||
// is essential here
|
||
if ( prop2 !== undefined ) {
|
||
for ( ; i<ien ; i++ ) {
|
||
out.push( a[ order[i] ][ prop ][ prop2 ] );
|
||
}
|
||
}
|
||
else {
|
||
for ( ; i<ien ; i++ ) {
|
||
out.push( a[ order[i] ][ prop ] );
|
||
}
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
var _range = function ( len, start )
|
||
{
|
||
var out = [];
|
||
var end;
|
||
|
||
if ( start === undefined ) {
|
||
start = 0;
|
||
end = len;
|
||
}
|
||
else {
|
||
end = start;
|
||
start = len;
|
||
}
|
||
|
||
for ( var i=start ; i<end ; i++ ) {
|
||
out.push( i );
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
var _stripHtml = function ( d ) {
|
||
return d.replace( _re_html, '' );
|
||
};
|
||
|
||
|
||
/**
|
||
* Find the unique elements in a source array.
|
||
*
|
||
* @param {array} src Source array
|
||
* @return {array} Array of unique items
|
||
* @ignore
|
||
*/
|
||
var _unique = function ( src )
|
||
{
|
||
// A faster unique method is to use object keys to identify used values,
|
||
// but this doesn't work with arrays or objects, which we must also
|
||
// consider. See jsperf.com/compare-array-unique-versions/4 for more
|
||
// information.
|
||
var
|
||
out = [],
|
||
val,
|
||
i, ien=src.length,
|
||
j, k=0;
|
||
|
||
again: for ( i=0 ; i<ien ; i++ ) {
|
||
val = src[i];
|
||
|
||
for ( j=0 ; j<k ; j++ ) {
|
||
if ( out[j] === val ) {
|
||
continue again;
|
||
}
|
||
}
|
||
|
||
out.push( val );
|
||
k++;
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* Create a mapping object that allows camel case parameters to be looked up
|
||
* for their Hungarian counterparts. The mapping is stored in a private
|
||
* parameter called `_hungarianMap` which can be accessed on the source object.
|
||
* @param {object} o
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnHungarianMap ( o )
|
||
{
|
||
var
|
||
hungarian = 'a aa ai ao as b fn i m o s ',
|
||
match,
|
||
newKey,
|
||
map = {};
|
||
|
||
$.each( o, function (key, val) {
|
||
match = key.match(/^([^A-Z]+?)([A-Z])/);
|
||
|
||
if ( match && hungarian.indexOf(match[1]+' ') !== -1 )
|
||
{
|
||
newKey = key.replace( match[0], match[2].toLowerCase() );
|
||
map[ newKey ] = key;
|
||
|
||
//console.log( key, match );
|
||
if ( match[1] === 'o' )
|
||
{
|
||
_fnHungarianMap( o[key] );
|
||
}
|
||
}
|
||
} );
|
||
|
||
o._hungarianMap = map;
|
||
}
|
||
|
||
|
||
/**
|
||
* Convert from camel case parameters to Hungarian, based on a Hungarian map
|
||
* created by _fnHungarianMap.
|
||
* @param {object} src The model object which holds all parameters that can be
|
||
* mapped.
|
||
* @param {object} user The object to convert from camel case to Hungarian.
|
||
* @param {boolean} force When set to `true`, properties which already have a
|
||
* Hungarian value in the `user` object will be overwritten. Otherwise they
|
||
* won't be.
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnCamelToHungarian ( src, user, force )
|
||
{
|
||
if ( ! src._hungarianMap ) {
|
||
_fnHungarianMap( src );
|
||
}
|
||
|
||
var hungarianKey;
|
||
|
||
$.each( user, function (key, val) {
|
||
hungarianKey = src._hungarianMap[ key ];
|
||
|
||
if ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )
|
||
{
|
||
// For objects, we need to buzz down into the object to copy parameters
|
||
if ( hungarianKey.charAt(0) === 'o' )
|
||
{
|
||
// Copy the camelCase options over to the hungarian
|
||
if ( ! user[ hungarianKey ] ) {
|
||
user[ hungarianKey ] = {};
|
||
}
|
||
$.extend( true, user[hungarianKey], user[key] );
|
||
|
||
_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );
|
||
}
|
||
else {
|
||
user[hungarianKey] = user[ key ];
|
||
}
|
||
}
|
||
} );
|
||
}
|
||
|
||
|
||
/**
|
||
* Language compatibility - when certain options are given, and others aren't, we
|
||
* need to duplicate the values over, in order to provide backwards compatibility
|
||
* with older language files.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnLanguageCompat( lang )
|
||
{
|
||
var defaults = DataTable.defaults.oLanguage;
|
||
var zeroRecords = lang.sZeroRecords;
|
||
|
||
/* Backwards compatibility - if there is no sEmptyTable given, then use the same as
|
||
* sZeroRecords - assuming that is given.
|
||
*/
|
||
if ( ! lang.sEmptyTable && zeroRecords &&
|
||
defaults.sEmptyTable === "No data available in table" )
|
||
{
|
||
_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );
|
||
}
|
||
|
||
/* Likewise with loading records */
|
||
if ( ! lang.sLoadingRecords && zeroRecords &&
|
||
defaults.sLoadingRecords === "Loading..." )
|
||
{
|
||
_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );
|
||
}
|
||
|
||
// Old parameter name of the thousands separator mapped onto the new
|
||
if ( lang.sInfoThousands ) {
|
||
lang.sThousands = lang.sInfoThousands;
|
||
}
|
||
|
||
var decimal = lang.sDecimal;
|
||
if ( decimal ) {
|
||
_addNumericSort( decimal );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Map one parameter onto another
|
||
* @param {object} o Object to map
|
||
* @param {*} knew The new parameter name
|
||
* @param {*} old The old parameter name
|
||
*/
|
||
var _fnCompatMap = function ( o, knew, old ) {
|
||
if ( o[ knew ] !== undefined ) {
|
||
o[ old ] = o[ knew ];
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Provide backwards compatibility for the main DT options. Note that the new
|
||
* options are mapped onto the old parameters, so this is an external interface
|
||
* change only.
|
||
* @param {object} init Object to map
|
||
*/
|
||
function _fnCompatOpts ( init )
|
||
{
|
||
_fnCompatMap( init, 'ordering', 'bSort' );
|
||
_fnCompatMap( init, 'orderMulti', 'bSortMulti' );
|
||
_fnCompatMap( init, 'orderClasses', 'bSortClasses' );
|
||
_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );
|
||
_fnCompatMap( init, 'order', 'aaSorting' );
|
||
_fnCompatMap( init, 'orderFixed', 'aaSortingFixed' );
|
||
_fnCompatMap( init, 'paging', 'bPaginate' );
|
||
_fnCompatMap( init, 'pagingType', 'sPaginationType' );
|
||
_fnCompatMap( init, 'pageLength', 'iDisplayLength' );
|
||
_fnCompatMap( init, 'searching', 'bFilter' );
|
||
}
|
||
|
||
|
||
/**
|
||
* Provide backwards compatibility for column options. Note that the new options
|
||
* are mapped onto the old parameters, so this is an external interface change
|
||
* only.
|
||
* @param {object} init Object to map
|
||
*/
|
||
function _fnCompatCols ( init )
|
||
{
|
||
_fnCompatMap( init, 'orderable', 'bSortable' );
|
||
_fnCompatMap( init, 'orderData', 'aDataSort' );
|
||
_fnCompatMap( init, 'orderSequence', 'asSorting' );
|
||
_fnCompatMap( init, 'orderDataType', 'sortDataType' );
|
||
}
|
||
|
||
|
||
/**
|
||
* Browser feature detection for capabilities, quirks
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnBrowserDetect( settings )
|
||
{
|
||
var browser = settings.oBrowser;
|
||
|
||
// Scrolling feature / quirks detection
|
||
var n = $('<div/>')
|
||
.css( {
|
||
position: 'absolute',
|
||
top: 0,
|
||
left: 0,
|
||
height: 1,
|
||
width: 1,
|
||
overflow: 'hidden'
|
||
} )
|
||
.append(
|
||
$('<div/>')
|
||
.css( {
|
||
position: 'absolute',
|
||
top: 1,
|
||
left: 1,
|
||
width: 100,
|
||
overflow: 'scroll'
|
||
} )
|
||
.append(
|
||
$('<div class="test"/>')
|
||
.css( {
|
||
width: '100%',
|
||
height: 10
|
||
} )
|
||
)
|
||
)
|
||
.appendTo( 'body' );
|
||
|
||
var test = n.find('.test');
|
||
|
||
// IE6/7 will oversize a width 100% element inside a scrolling element, to
|
||
// include the width of the scrollbar, while other browsers ensure the inner
|
||
// element is contained without forcing scrolling
|
||
browser.bScrollOversize = test[0].offsetWidth === 100;
|
||
|
||
// In rtl text layout, some browsers (most, but not all) will place the
|
||
// scrollbar on the left, rather than the right.
|
||
browser.bScrollbarLeft = test.offset().left !== 1;
|
||
|
||
n.remove();
|
||
}
|
||
|
||
|
||
/**
|
||
* Array.prototype reduce[Right] method, used for browsers which don't support
|
||
* JS 1.6. Done this way to reduce code size, since we iterate either way
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnReduce ( that, fn, init, start, end, inc )
|
||
{
|
||
var
|
||
i = start,
|
||
value,
|
||
isSet = false;
|
||
|
||
if ( init !== undefined ) {
|
||
value = init;
|
||
isSet = true;
|
||
}
|
||
|
||
while ( i !== end ) {
|
||
if ( ! that.hasOwnProperty(i) ) {
|
||
continue;
|
||
}
|
||
|
||
value = isSet ?
|
||
fn( value, that[i], i, that ) :
|
||
that[i];
|
||
|
||
isSet = true;
|
||
i += inc;
|
||
}
|
||
|
||
return value;
|
||
}
|
||
|
||
/**
|
||
* Add a column to the list used for the table with default values
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {node} nTh The th element for this column
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAddColumn( oSettings, nTh )
|
||
{
|
||
// Add column to aoColumns array
|
||
var oDefaults = DataTable.defaults.column;
|
||
var iCol = oSettings.aoColumns.length;
|
||
var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {
|
||
"nTh": nTh ? nTh : document.createElement('th'),
|
||
"sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '',
|
||
"aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],
|
||
"mData": oDefaults.mData ? oDefaults.mData : iCol,
|
||
idx: iCol
|
||
} );
|
||
oSettings.aoColumns.push( oCol );
|
||
|
||
// Add search object for column specific search. Note that the `searchCols[ iCol ]`
|
||
// passed into extend can be undefined. This allows the user to give a default
|
||
// with only some of the parameters defined, and also not give a default
|
||
var searchCols = oSettings.aoPreSearchCols;
|
||
searchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );
|
||
|
||
// Use the default column options function to initialise classes etc
|
||
_fnColumnOptions( oSettings, iCol, null );
|
||
}
|
||
|
||
|
||
/**
|
||
* Apply options for a column
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iCol column index to consider
|
||
* @param {object} oOptions object with sType, bVisible and bSearchable etc
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnColumnOptions( oSettings, iCol, oOptions )
|
||
{
|
||
var oCol = oSettings.aoColumns[ iCol ];
|
||
var oClasses = oSettings.oClasses;
|
||
var th = $(oCol.nTh);
|
||
|
||
// Try to get width information from the DOM. We can't get it from CSS
|
||
// as we'd need to parse the CSS stylesheet. `width` option can override
|
||
if ( ! oCol.sWidthOrig ) {
|
||
// Width attribute
|
||
oCol.sWidthOrig = th.attr('width') || null;
|
||
|
||
// Style attribute
|
||
var t = (th.attr('style') || '').match(/width:\s*(\d+[pxem%])/);
|
||
if ( t ) {
|
||
oCol.sWidthOrig = t[1];
|
||
}
|
||
}
|
||
|
||
/* User specified column options */
|
||
if ( oOptions !== undefined && oOptions !== null )
|
||
{
|
||
// Backwards compatibility
|
||
_fnCompatCols( oOptions );
|
||
|
||
// Map camel case parameters to their Hungarian counterparts
|
||
_fnCamelToHungarian( DataTable.defaults.column, oOptions );
|
||
|
||
/* Backwards compatibility for mDataProp */
|
||
if ( oOptions.mDataProp !== undefined && !oOptions.mData )
|
||
{
|
||
oOptions.mData = oOptions.mDataProp;
|
||
}
|
||
|
||
if ( oOptions.sType )
|
||
{
|
||
oCol._sManualType = oOptions.sType;
|
||
}
|
||
|
||
// `class` is a reserved word in Javascript, so we need to provide
|
||
// the ability to use a valid name for the camel case input
|
||
if ( oOptions.className && ! oOptions.sClass )
|
||
{
|
||
oOptions.sClass = oOptions.className;
|
||
}
|
||
|
||
$.extend( oCol, oOptions );
|
||
_fnMap( oCol, oOptions, "sWidth", "sWidthOrig" );
|
||
|
||
/* iDataSort to be applied (backwards compatibility), but aDataSort will take
|
||
* priority if defined
|
||
*/
|
||
if ( typeof oOptions.iDataSort === 'number' )
|
||
{
|
||
oCol.aDataSort = [ oOptions.iDataSort ];
|
||
}
|
||
_fnMap( oCol, oOptions, "aDataSort" );
|
||
}
|
||
|
||
/* Cache the data get and set functions for speed */
|
||
var mDataSrc = oCol.mData;
|
||
var mData = _fnGetObjectDataFn( mDataSrc );
|
||
var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;
|
||
|
||
var attrTest = function( src ) {
|
||
return typeof src === 'string' && src.indexOf('@') !== -1;
|
||
};
|
||
oCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (
|
||
attrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)
|
||
);
|
||
|
||
oCol.fnGetData = function (oData, sSpecific) {
|
||
var innerData = mData( oData, sSpecific );
|
||
|
||
if ( oCol.mRender && (sSpecific && sSpecific !== '') )
|
||
{
|
||
return mRender( innerData, sSpecific, oData );
|
||
}
|
||
return innerData;
|
||
};
|
||
oCol.fnSetData = _fnSetObjectDataFn( mDataSrc );
|
||
|
||
/* Feature sorting overrides column specific when off */
|
||
if ( !oSettings.oFeatures.bSort )
|
||
{
|
||
oCol.bSortable = false;
|
||
th.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called
|
||
}
|
||
|
||
/* Check that the class assignment is correct for sorting */
|
||
var bAsc = $.inArray('asc', oCol.asSorting) !== -1;
|
||
var bDesc = $.inArray('desc', oCol.asSorting) !== -1;
|
||
if ( !oCol.bSortable || (!bAsc && !bDesc) )
|
||
{
|
||
oCol.sSortingClass = oClasses.sSortableNone;
|
||
oCol.sSortingClassJUI = "";
|
||
}
|
||
else if ( bAsc && !bDesc )
|
||
{
|
||
oCol.sSortingClass = oClasses.sSortableAsc;
|
||
oCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;
|
||
}
|
||
else if ( !bAsc && bDesc )
|
||
{
|
||
oCol.sSortingClass = oClasses.sSortableDesc;
|
||
oCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;
|
||
}
|
||
else
|
||
{
|
||
oCol.sSortingClass = oClasses.sSortable;
|
||
oCol.sSortingClassJUI = oClasses.sSortJUI;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Adjust the table column widths for new data. Note: you would probably want to
|
||
* do a redraw after calling this function!
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAdjustColumnSizing ( settings )
|
||
{
|
||
/* Not interested in doing column width calculation if auto-width is disabled */
|
||
if ( settings.oFeatures.bAutoWidth !== false )
|
||
{
|
||
var columns = settings.aoColumns;
|
||
|
||
_fnCalculateColumnWidths( settings );
|
||
for ( var i=0 , iLen=columns.length ; i<iLen ; i++ )
|
||
{
|
||
columns[i].nTh.style.width = columns[i].sWidth;
|
||
}
|
||
}
|
||
|
||
var scroll = settings.oScroll;
|
||
if ( scroll.sY !== '' || scroll.sX !== '')
|
||
{
|
||
_fnScrollDraw( settings );
|
||
}
|
||
|
||
_fnCallbackFire( settings, null, 'column-sizing', [settings] );
|
||
}
|
||
|
||
|
||
/**
|
||
* Covert the index of a visible column to the index in the data array (take account
|
||
* of hidden columns)
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iMatch Visible column index to lookup
|
||
* @returns {int} i the data index
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnVisibleToColumnIndex( oSettings, iMatch )
|
||
{
|
||
var aiVis = _fnGetColumns( oSettings, 'bVisible' );
|
||
|
||
return typeof aiVis[iMatch] === 'number' ?
|
||
aiVis[iMatch] :
|
||
null;
|
||
}
|
||
|
||
|
||
/**
|
||
* Covert the index of an index in the data array and convert it to the visible
|
||
* column index (take account of hidden columns)
|
||
* @param {int} iMatch Column index to lookup
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {int} i the data index
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnColumnIndexToVisible( oSettings, iMatch )
|
||
{
|
||
var aiVis = _fnGetColumns( oSettings, 'bVisible' );
|
||
var iPos = $.inArray( iMatch, aiVis );
|
||
|
||
return iPos !== -1 ? iPos : null;
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the number of visible columns
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {int} i the number of visible columns
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnVisbleColumns( oSettings )
|
||
{
|
||
return _fnGetColumns( oSettings, 'bVisible' ).length;
|
||
}
|
||
|
||
|
||
/**
|
||
* Get an array of column indexes that match a given property
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {string} sParam Parameter in aoColumns to look for - typically
|
||
* bVisible or bSearchable
|
||
* @returns {array} Array of indexes with matched properties
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetColumns( oSettings, sParam )
|
||
{
|
||
var a = [];
|
||
|
||
$.map( oSettings.aoColumns, function(val, i) {
|
||
if ( val[sParam] ) {
|
||
a.push( i );
|
||
}
|
||
} );
|
||
|
||
return a;
|
||
}
|
||
|
||
|
||
/**
|
||
* Calculate the 'type' of a column
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnColumnTypes ( settings )
|
||
{
|
||
var columns = settings.aoColumns;
|
||
var data = settings.aoData;
|
||
var types = DataTable.ext.type.detect;
|
||
var i, ien, j, jen, k, ken;
|
||
var col, cell, detectedType, cache;
|
||
|
||
// For each column, spin over the
|
||
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
||
col = columns[i];
|
||
cache = [];
|
||
|
||
if ( ! col.sType && col._sManualType ) {
|
||
col.sType = col._sManualType;
|
||
}
|
||
else if ( ! col.sType ) {
|
||
for ( j=0, jen=types.length ; j<jen ; j++ ) {
|
||
for ( k=0, ken=data.length ; k<ken ; k++ ) {
|
||
// Use a cache array so we only need to get the type data
|
||
// from the formatter once (when using multiple detectors)
|
||
if ( cache[k] === undefined ) {
|
||
cache[k] = _fnGetCellData( settings, k, i, 'type' );
|
||
}
|
||
|
||
detectedType = types[j]( cache[k], settings );
|
||
|
||
// Doesn't match, so break early, since this type can't
|
||
// apply to this column. Also, HTML is a special case since
|
||
// it is so similar to `string`. Just a single match is
|
||
// needed for a column to be html type
|
||
if ( ! detectedType || detectedType === 'html' ) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Type is valid for all data points in the column - use this
|
||
// type
|
||
if ( detectedType ) {
|
||
col.sType = detectedType;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Fall back - if no type was detected, always use string
|
||
if ( ! col.sType ) {
|
||
col.sType = 'string';
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Take the column definitions and static columns arrays and calculate how
|
||
* they relate to column indexes. The callback function will then apply the
|
||
* definition found for a column to a suitable configuration object.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {array} aoColDefs The aoColumnDefs array that is to be applied
|
||
* @param {array} aoCols The aoColumns array that defines columns individually
|
||
* @param {function} fn Callback function - takes two parameters, the calculated
|
||
* column index and the definition for that column.
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )
|
||
{
|
||
var i, iLen, j, jLen, k, kLen, def;
|
||
var columns = oSettings.aoColumns;
|
||
|
||
// Column definitions with aTargets
|
||
if ( aoColDefs )
|
||
{
|
||
/* Loop over the definitions array - loop in reverse so first instance has priority */
|
||
for ( i=aoColDefs.length-1 ; i>=0 ; i-- )
|
||
{
|
||
def = aoColDefs[i];
|
||
|
||
/* Each definition can target multiple columns, as it is an array */
|
||
var aTargets = def.targets !== undefined ?
|
||
def.targets :
|
||
def.aTargets;
|
||
|
||
if ( ! $.isArray( aTargets ) )
|
||
{
|
||
aTargets = [ aTargets ];
|
||
}
|
||
|
||
for ( j=0, jLen=aTargets.length ; j<jLen ; j++ )
|
||
{
|
||
if ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )
|
||
{
|
||
/* Add columns that we don't yet know about */
|
||
while( columns.length <= aTargets[j] )
|
||
{
|
||
_fnAddColumn( oSettings );
|
||
}
|
||
|
||
/* Integer, basic index */
|
||
fn( aTargets[j], def );
|
||
}
|
||
else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
|
||
{
|
||
/* Negative integer, right to left column counting */
|
||
fn( columns.length+aTargets[j], def );
|
||
}
|
||
else if ( typeof aTargets[j] === 'string' )
|
||
{
|
||
/* Class name matching on TH element */
|
||
for ( k=0, kLen=columns.length ; k<kLen ; k++ )
|
||
{
|
||
if ( aTargets[j] == "_all" ||
|
||
$(columns[k].nTh).hasClass( aTargets[j] ) )
|
||
{
|
||
fn( k, def );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Statically defined columns array
|
||
if ( aoCols )
|
||
{
|
||
for ( i=0, iLen=aoCols.length ; i<iLen ; i++ )
|
||
{
|
||
fn( i, aoCols[i] );
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Add a data array to the table, creating DOM node etc. This is the parallel to
|
||
* _fnGatherData, but for adding rows from a Javascript source, rather than a
|
||
* DOM source.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {array} aData data array to be added
|
||
* @param {node} [nTr] TR element to add to the table - optional. If not given,
|
||
* DataTables will create a row automatically
|
||
* @param {array} [anTds] Array of TD|TH elements for the row - must be given
|
||
* if nTr is.
|
||
* @returns {int} >=0 if successful (index of new aoData entry), -1 if failed
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAddData ( oSettings, aDataIn, nTr, anTds )
|
||
{
|
||
/* Create the object for storing information about this new row */
|
||
var iRow = oSettings.aoData.length;
|
||
var oData = $.extend( true, {}, DataTable.models.oRow, {
|
||
src: nTr ? 'dom' : 'data'
|
||
} );
|
||
|
||
oData._aData = aDataIn;
|
||
oSettings.aoData.push( oData );
|
||
|
||
/* Create the cells */
|
||
var nTd, sThisType;
|
||
var columns = oSettings.aoColumns;
|
||
for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
|
||
{
|
||
// When working with a row, the data source object must be populated. In
|
||
// all other cases, the data source object is already populated, so we
|
||
// don't overwrite it, which might break bindings etc
|
||
if ( nTr ) {
|
||
_fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) );
|
||
}
|
||
columns[i].sType = null;
|
||
}
|
||
|
||
/* Add to the display array */
|
||
oSettings.aiDisplayMaster.push( iRow );
|
||
|
||
/* Create the DOM information */
|
||
if ( !oSettings.oFeatures.bDeferRender )
|
||
{
|
||
_fnCreateTr( oSettings, iRow, nTr, anTds );
|
||
}
|
||
|
||
return iRow;
|
||
}
|
||
|
||
|
||
/**
|
||
* Add one or more TR elements to the table. Generally we'd expect to
|
||
* use this for reading data from a DOM sourced table, but it could be
|
||
* used for an TR element. Note that if a TR is given, it is used (i.e.
|
||
* it is not cloned).
|
||
* @param {object} settings dataTables settings object
|
||
* @param {array|node|jQuery} trs The TR element(s) to add to the table
|
||
* @returns {array} Array of indexes for the added rows
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAddTr( settings, trs )
|
||
{
|
||
var row;
|
||
|
||
// Allow an individual node to be passed in
|
||
if ( ! (trs instanceof $) ) {
|
||
trs = $(trs);
|
||
}
|
||
|
||
return trs.map( function (i, el) {
|
||
row = _fnGetRowElements( settings, el );
|
||
return _fnAddData( settings, row.data, el, row.cells );
|
||
} );
|
||
}
|
||
|
||
|
||
/**
|
||
* Take a TR element and convert it to an index in aoData
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {node} n the TR element to find
|
||
* @returns {int} index if the node is found, null if not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnNodeToDataIndex( oSettings, n )
|
||
{
|
||
return (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;
|
||
}
|
||
|
||
|
||
/**
|
||
* Take a TD element and convert it into a column data index (not the visible index)
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iRow The row number the TD/TH can be found in
|
||
* @param {node} n The TD/TH element to find
|
||
* @returns {int} index if the node is found, -1 if not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnNodeToColumnIndex( oSettings, iRow, n )
|
||
{
|
||
return $.inArray( n, oSettings.aoData[ iRow ].anCells );
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the data for a given cell from the internal cache, taking into account data mapping
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iRow aoData row id
|
||
* @param {int} iCol Column index
|
||
* @param {string} sSpecific data get type ('display', 'type' 'filter' 'sort')
|
||
* @returns {*} Cell data
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetCellData( oSettings, iRow, iCol, sSpecific )
|
||
{
|
||
var oCol = oSettings.aoColumns[iCol];
|
||
var oData = oSettings.aoData[iRow]._aData;
|
||
var sData = oCol.fnGetData( oData, sSpecific );
|
||
|
||
if ( sData === undefined )
|
||
{
|
||
if ( oSettings.iDrawError != oSettings.iDraw && oCol.sDefaultContent === null )
|
||
{
|
||
_fnLog( oSettings, 0, "Requested unknown parameter "+
|
||
(typeof oCol.mData=='function' ? '{function}' : "'"+oCol.mData+"'")+
|
||
" for row "+iRow, 4 );
|
||
oSettings.iDrawError = oSettings.iDraw;
|
||
}
|
||
return oCol.sDefaultContent;
|
||
}
|
||
|
||
/* When the data source is null, we can use default column data */
|
||
if ( (sData === oData || sData === null) && oCol.sDefaultContent !== null )
|
||
{
|
||
sData = oCol.sDefaultContent;
|
||
}
|
||
else if ( typeof sData === 'function' )
|
||
{
|
||
// If the data source is a function, then we run it and use the return
|
||
return sData();
|
||
}
|
||
|
||
if ( sData === null && sSpecific == 'display' )
|
||
{
|
||
return '';
|
||
}
|
||
return sData;
|
||
}
|
||
|
||
|
||
/**
|
||
* Set the value for a specific cell, into the internal data cache
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iRow aoData row id
|
||
* @param {int} iCol Column index
|
||
* @param {*} val Value to set
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSetCellData( oSettings, iRow, iCol, val )
|
||
{
|
||
var oCol = oSettings.aoColumns[iCol];
|
||
var oData = oSettings.aoData[iRow]._aData;
|
||
|
||
oCol.fnSetData( oData, val );
|
||
}
|
||
|
||
|
||
// Private variable that is used to match action syntax in the data property object
|
||
var __reArray = /\[.*?\]$/;
|
||
var __reFn = /\(\)$/;
|
||
|
||
/**
|
||
* Split string on periods, taking into account escaped periods
|
||
* @param {string} str String to split
|
||
* @return {array} Split string
|
||
*/
|
||
function _fnSplitObjNotation( str )
|
||
{
|
||
return $.map( str.match(/(\\.|[^\.])+/g), function ( s ) {
|
||
return s.replace('\\.', '.');
|
||
} );
|
||
}
|
||
|
||
|
||
/**
|
||
* Return a function that can be used to get data from a source object, taking
|
||
* into account the ability to use nested objects as a source
|
||
* @param {string|int|function} mSource The data source for the object
|
||
* @returns {function} Data get function
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetObjectDataFn( mSource )
|
||
{
|
||
if ( $.isPlainObject( mSource ) )
|
||
{
|
||
/* Build an object of get functions, and wrap them in a single call */
|
||
var o = {};
|
||
$.each( mSource, function (key, val) {
|
||
if ( val ) {
|
||
o[key] = _fnGetObjectDataFn( val );
|
||
}
|
||
} );
|
||
|
||
return function (data, type, extra) {
|
||
var t = o[type] || o._;
|
||
return t !== undefined ?
|
||
t(data, type, extra) :
|
||
data;
|
||
};
|
||
}
|
||
else if ( mSource === null )
|
||
{
|
||
/* Give an empty string for rendering / sorting etc */
|
||
return function (data, type) {
|
||
return data;
|
||
};
|
||
}
|
||
else if ( typeof mSource === 'function' )
|
||
{
|
||
return function (data, type, extra) {
|
||
return mSource( data, type, extra );
|
||
};
|
||
}
|
||
else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
|
||
mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
|
||
{
|
||
/* If there is a . in the source string then the data source is in a
|
||
* nested object so we loop over the data for each level to get the next
|
||
* level down. On each loop we test for undefined, and if found immediately
|
||
* return. This allows entire objects to be missing and sDefaultContent to
|
||
* be used if defined, rather than throwing an error
|
||
*/
|
||
var fetchData = function (data, type, src) {
|
||
var arrayNotation, funcNotation, out, innerSrc;
|
||
|
||
if ( src !== "" )
|
||
{
|
||
var a = _fnSplitObjNotation( src );
|
||
|
||
for ( var i=0, iLen=a.length ; i<iLen ; i++ )
|
||
{
|
||
// Check if we are dealing with special notation
|
||
arrayNotation = a[i].match(__reArray);
|
||
funcNotation = a[i].match(__reFn);
|
||
|
||
if ( arrayNotation )
|
||
{
|
||
// Array notation
|
||
a[i] = a[i].replace(__reArray, '');
|
||
|
||
// Condition allows simply [] to be passed in
|
||
if ( a[i] !== "" ) {
|
||
data = data[ a[i] ];
|
||
}
|
||
out = [];
|
||
|
||
// Get the remainder of the nested object to get
|
||
a.splice( 0, i+1 );
|
||
innerSrc = a.join('.');
|
||
|
||
// Traverse each entry in the array getting the properties requested
|
||
for ( var j=0, jLen=data.length ; j<jLen ; j++ ) {
|
||
out.push( fetchData( data[j], type, innerSrc ) );
|
||
}
|
||
|
||
// If a string is given in between the array notation indicators, that
|
||
// is used to join the strings together, otherwise an array is returned
|
||
var join = arrayNotation[0].substring(1, arrayNotation[0].length-1);
|
||
data = (join==="") ? out : out.join(join);
|
||
|
||
// The inner call to fetchData has already traversed through the remainder
|
||
// of the source requested, so we exit from the loop
|
||
break;
|
||
}
|
||
else if ( funcNotation )
|
||
{
|
||
// Function call
|
||
a[i] = a[i].replace(__reFn, '');
|
||
data = data[ a[i] ]();
|
||
continue;
|
||
}
|
||
|
||
if ( data === null || data[ a[i] ] === undefined )
|
||
{
|
||
return undefined;
|
||
}
|
||
data = data[ a[i] ];
|
||
}
|
||
}
|
||
|
||
return data;
|
||
};
|
||
|
||
return function (data, type) {
|
||
return fetchData( data, type, mSource );
|
||
};
|
||
}
|
||
else
|
||
{
|
||
/* Array or flat object mapping */
|
||
return function (data, type) {
|
||
return data[mSource];
|
||
};
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Return a function that can be used to set data from a source object, taking
|
||
* into account the ability to use nested objects as a source
|
||
* @param {string|int|function} mSource The data source for the object
|
||
* @returns {function} Data set function
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSetObjectDataFn( mSource )
|
||
{
|
||
if ( $.isPlainObject( mSource ) )
|
||
{
|
||
/* Unlike get, only the underscore (global) option is used for for
|
||
* setting data since we don't know the type here. This is why an object
|
||
* option is not documented for `mData` (which is read/write), but it is
|
||
* for `mRender` which is read only.
|
||
*/
|
||
return _fnSetObjectDataFn( mSource._ );
|
||
}
|
||
else if ( mSource === null )
|
||
{
|
||
/* Nothing to do when the data source is null */
|
||
return function (data, val) {};
|
||
}
|
||
else if ( typeof mSource === 'function' )
|
||
{
|
||
return function (data, val) {
|
||
mSource( data, 'set', val );
|
||
};
|
||
}
|
||
else if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||
|
||
mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )
|
||
{
|
||
/* Like the get, we need to get data from a nested object */
|
||
var setData = function (data, val, src) {
|
||
var a = _fnSplitObjNotation( src ), b;
|
||
var aLast = a[a.length-1];
|
||
var arrayNotation, funcNotation, o, innerSrc;
|
||
|
||
for ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )
|
||
{
|
||
// Check if we are dealing with an array notation request
|
||
arrayNotation = a[i].match(__reArray);
|
||
funcNotation = a[i].match(__reFn);
|
||
|
||
if ( arrayNotation )
|
||
{
|
||
a[i] = a[i].replace(__reArray, '');
|
||
data[ a[i] ] = [];
|
||
|
||
// Get the remainder of the nested object to set so we can recurse
|
||
b = a.slice();
|
||
b.splice( 0, i+1 );
|
||
innerSrc = b.join('.');
|
||
|
||
// Traverse each entry in the array setting the properties requested
|
||
for ( var j=0, jLen=val.length ; j<jLen ; j++ )
|
||
{
|
||
o = {};
|
||
setData( o, val[j], innerSrc );
|
||
data[ a[i] ].push( o );
|
||
}
|
||
|
||
// The inner call to setData has already traversed through the remainder
|
||
// of the source and has set the data, thus we can exit here
|
||
return;
|
||
}
|
||
else if ( funcNotation )
|
||
{
|
||
// Function call
|
||
a[i] = a[i].replace(__reFn, '');
|
||
data = data[ a[i] ]( val );
|
||
}
|
||
|
||
// If the nested object doesn't currently exist - since we are
|
||
// trying to set the value - create it
|
||
if ( data[ a[i] ] === null || data[ a[i] ] === undefined )
|
||
{
|
||
data[ a[i] ] = {};
|
||
}
|
||
data = data[ a[i] ];
|
||
}
|
||
|
||
// Last item in the input - i.e, the actual set
|
||
if ( aLast.match(__reFn ) )
|
||
{
|
||
// Function call
|
||
data = data[ aLast.replace(__reFn, '') ]( val );
|
||
}
|
||
else
|
||
{
|
||
// If array notation is used, we just want to strip it and use the property name
|
||
// and assign the value. If it isn't used, then we get the result we want anyway
|
||
data[ aLast.replace(__reArray, '') ] = val;
|
||
}
|
||
};
|
||
|
||
return function (data, val) {
|
||
return setData( data, val, mSource );
|
||
};
|
||
}
|
||
else
|
||
{
|
||
/* Array or flat object mapping */
|
||
return function (data, val) {
|
||
data[mSource] = val;
|
||
};
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Return an array with the full table data
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns array {array} aData Master data array
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetDataMaster ( settings )
|
||
{
|
||
return _pluck( settings.aoData, '_aData' );
|
||
}
|
||
|
||
|
||
/**
|
||
* Nuke the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnClearTable( settings )
|
||
{
|
||
settings.aoData.length = 0;
|
||
settings.aiDisplayMaster.length = 0;
|
||
settings.aiDisplay.length = 0;
|
||
}
|
||
|
||
|
||
/**
|
||
* Take an array of integers (index array) and remove a target integer (value - not
|
||
* the key!)
|
||
* @param {array} a Index array to target
|
||
* @param {int} iTarget value to find
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnDeleteIndex( a, iTarget, splice )
|
||
{
|
||
var iTargetIndex = -1;
|
||
|
||
for ( var i=0, iLen=a.length ; i<iLen ; i++ )
|
||
{
|
||
if ( a[i] == iTarget )
|
||
{
|
||
iTargetIndex = i;
|
||
}
|
||
else if ( a[i] > iTarget )
|
||
{
|
||
a[i]--;
|
||
}
|
||
}
|
||
|
||
if ( iTargetIndex != -1 && splice === undefined )
|
||
{
|
||
a.splice( iTargetIndex, 1 );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Mark cached data as invalid such that a re-read of the data will occur when
|
||
* the cached data is next requested. Also update from the data source object.
|
||
*
|
||
* @param {object} settings DataTables settings object
|
||
* @param {int} rowIdx Row index to invalidate
|
||
* @memberof DataTable#oApi
|
||
*
|
||
* @todo For the modularisation of v1.11 this will need to become a callback, so
|
||
* the sort and filter methods can subscribe to it. That will required
|
||
* initialisation options for sorting, which is why it is not already baked in
|
||
*/
|
||
function _fnInvalidateRow( settings, rowIdx, src, column )
|
||
{
|
||
var row = settings.aoData[ rowIdx ];
|
||
var i, ien;
|
||
|
||
// Are we reading last data from DOM or the data object?
|
||
if ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {
|
||
// Read the data from the DOM
|
||
row._aData = _fnGetRowElements( settings, row ).data;
|
||
}
|
||
else {
|
||
// Reading from data object, update the DOM
|
||
var cells = row.anCells;
|
||
|
||
if ( cells ) {
|
||
for ( i=0, ien=cells.length ; i<ien ; i++ ) {
|
||
cells[i].innerHTML = _fnGetCellData( settings, rowIdx, i, 'display' );
|
||
}
|
||
}
|
||
}
|
||
|
||
row._aSortData = null;
|
||
row._aFilterData = null;
|
||
|
||
// Invalidate the type for a specific column (if given) or all columns since
|
||
// the data might have changed
|
||
var cols = settings.aoColumns;
|
||
if ( column !== undefined ) {
|
||
cols[ column ].sType = null;
|
||
}
|
||
else {
|
||
for ( i=0, ien=cols.length ; i<ien ; i++ ) {
|
||
cols[i].sType = null;
|
||
}
|
||
}
|
||
|
||
// Update DataTables special `DT_*` attributes for the row
|
||
_fnRowAttributes( row );
|
||
}
|
||
|
||
|
||
/**
|
||
* Build a data source object from an HTML row, reading the contents of the
|
||
* cells that are in the row.
|
||
*
|
||
* @param {object} settings DataTables settings object
|
||
* @param {node|object} TR element from which to read data or existing row
|
||
* object from which to re-read the data from the cells
|
||
* @returns {object} Object with two parameters: `data` the data read, in
|
||
* document order, and `cells` and array of nodes (they can be useful to the
|
||
* caller, so rather than needing a second traversal to get them, just return
|
||
* them from here).
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetRowElements( settings, row )
|
||
{
|
||
var
|
||
d = [],
|
||
tds = [],
|
||
td = row.firstChild,
|
||
name, col, o, i=0, contents,
|
||
columns = settings.aoColumns;
|
||
|
||
var attr = function ( str, data, td ) {
|
||
if ( typeof str === 'string' ) {
|
||
var idx = str.indexOf('@');
|
||
|
||
if ( idx !== -1 ) {
|
||
var src = str.substring( idx+1 );
|
||
o[ '@'+src ] = td.getAttribute( src );
|
||
}
|
||
}
|
||
};
|
||
|
||
var cellProcess = function ( cell ) {
|
||
col = columns[i];
|
||
contents = $.trim(cell.innerHTML);
|
||
|
||
if ( col && col._bAttrSrc ) {
|
||
o = {
|
||
display: contents
|
||
};
|
||
|
||
attr( col.mData.sort, o, cell );
|
||
attr( col.mData.type, o, cell );
|
||
attr( col.mData.filter, o, cell );
|
||
|
||
d.push( o );
|
||
}
|
||
else {
|
||
d.push( contents );
|
||
}
|
||
|
||
tds.push( cell );
|
||
i++;
|
||
};
|
||
|
||
if ( td ) {
|
||
// `tr` element passed in
|
||
while ( td ) {
|
||
name = td.nodeName.toUpperCase();
|
||
|
||
if ( name == "TD" || name == "TH" ) {
|
||
cellProcess( td );
|
||
}
|
||
|
||
td = td.nextSibling;
|
||
}
|
||
}
|
||
else {
|
||
// Existing row object passed in
|
||
tds = row.anCells;
|
||
|
||
for ( var j=0, jen=tds.length ; j<jen ; j++ ) {
|
||
cellProcess( tds[j] );
|
||
}
|
||
}
|
||
|
||
return {
|
||
data: d,
|
||
cells: tds
|
||
};
|
||
}
|
||
/**
|
||
* Create a new TR element (and it's TD children) for a row
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {int} iRow Row to consider
|
||
* @param {node} [nTrIn] TR element to add to the table - optional. If not given,
|
||
* DataTables will create a row automatically
|
||
* @param {array} [anTds] Array of TD|TH elements for the row - must be given
|
||
* if nTr is.
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnCreateTr ( oSettings, iRow, nTrIn, anTds )
|
||
{
|
||
var
|
||
row = oSettings.aoData[iRow],
|
||
rowData = row._aData,
|
||
cells = [],
|
||
nTr, nTd, oCol,
|
||
i, iLen;
|
||
|
||
if ( row.nTr === null )
|
||
{
|
||
nTr = nTrIn || document.createElement('tr');
|
||
|
||
row.nTr = nTr;
|
||
row.anCells = cells;
|
||
|
||
/* Use a private property on the node to allow reserve mapping from the node
|
||
* to the aoData array for fast look up
|
||
*/
|
||
nTr._DT_RowIndex = iRow;
|
||
|
||
/* Special parameters can be given by the data source to be used on the row */
|
||
_fnRowAttributes( row );
|
||
|
||
/* Process each column */
|
||
for ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )
|
||
{
|
||
oCol = oSettings.aoColumns[i];
|
||
|
||
nTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );
|
||
cells.push( nTd );
|
||
|
||
// Need to create the HTML if new, or if a rendering function is defined
|
||
if ( !nTrIn || oCol.mRender || oCol.mData !== i )
|
||
{
|
||
nTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );
|
||
}
|
||
|
||
/* Add user defined class */
|
||
if ( oCol.sClass )
|
||
{
|
||
nTd.className += ' '+oCol.sClass;
|
||
}
|
||
|
||
// Visibility - add or remove as required
|
||
if ( oCol.bVisible && ! nTrIn )
|
||
{
|
||
nTr.appendChild( nTd );
|
||
}
|
||
else if ( ! oCol.bVisible && nTrIn )
|
||
{
|
||
nTd.parentNode.removeChild( nTd );
|
||
}
|
||
|
||
if ( oCol.fnCreatedCell )
|
||
{
|
||
oCol.fnCreatedCell.call( oSettings.oInstance,
|
||
nTd, _fnGetCellData( oSettings, iRow, i, 'display' ), rowData, iRow, i
|
||
);
|
||
}
|
||
}
|
||
|
||
_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );
|
||
}
|
||
|
||
// Remove once webkit bug 131819 and Chromium bug 365619 have been resolved
|
||
// and deployed
|
||
row.nTr.setAttribute( 'role', 'row' );
|
||
}
|
||
|
||
|
||
/**
|
||
* Add attributes to a row based on the special `DT_*` parameters in a data
|
||
* source object.
|
||
* @param {object} DataTables row object for the row to be modified
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnRowAttributes( row )
|
||
{
|
||
var tr = row.nTr;
|
||
var data = row._aData;
|
||
|
||
if ( tr ) {
|
||
if ( data.DT_RowId ) {
|
||
tr.id = data.DT_RowId;
|
||
}
|
||
|
||
if ( data.DT_RowClass ) {
|
||
// Remove any classes added by DT_RowClass before
|
||
var a = data.DT_RowClass.split(' ');
|
||
row.__rowc = row.__rowc ?
|
||
_unique( row.__rowc.concat( a ) ) :
|
||
a;
|
||
|
||
$(tr)
|
||
.removeClass( row.__rowc.join(' ') )
|
||
.addClass( data.DT_RowClass );
|
||
}
|
||
|
||
if ( data.DT_RowData ) {
|
||
$(tr).data( data.DT_RowData );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Create the HTML header for the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnBuildHead( oSettings )
|
||
{
|
||
var i, ien, cell, row, column;
|
||
var thead = oSettings.nTHead;
|
||
var tfoot = oSettings.nTFoot;
|
||
var createHeader = $('th, td', thead).length === 0;
|
||
var classes = oSettings.oClasses;
|
||
var columns = oSettings.aoColumns;
|
||
|
||
if ( createHeader ) {
|
||
row = $('<tr/>').appendTo( thead );
|
||
}
|
||
|
||
for ( i=0, ien=columns.length ; i<ien ; i++ ) {
|
||
column = columns[i];
|
||
cell = $( column.nTh ).addClass( column.sClass );
|
||
|
||
if ( createHeader ) {
|
||
cell.appendTo( row );
|
||
}
|
||
|
||
// 1.11 move into sorting
|
||
if ( oSettings.oFeatures.bSort ) {
|
||
cell.addClass( column.sSortingClass );
|
||
|
||
if ( column.bSortable !== false ) {
|
||
cell
|
||
.attr( 'tabindex', oSettings.iTabIndex )
|
||
.attr( 'aria-controls', oSettings.sTableId );
|
||
|
||
_fnSortAttachListener( oSettings, column.nTh, i );
|
||
}
|
||
}
|
||
|
||
if ( column.sTitle != cell.html() ) {
|
||
cell.html( column.sTitle );
|
||
}
|
||
|
||
_fnRenderer( oSettings, 'header' )(
|
||
oSettings, cell, column, classes
|
||
);
|
||
}
|
||
|
||
if ( createHeader ) {
|
||
_fnDetectHeader( oSettings.aoHeader, thead );
|
||
}
|
||
|
||
/* ARIA role for the rows */
|
||
$(thead).find('>tr').attr('role', 'row');
|
||
|
||
/* Deal with the footer - add classes if required */
|
||
$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );
|
||
$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );
|
||
|
||
// Cache the footer cells. Note that we only take the cells from the first
|
||
// row in the footer. If there is more than one row the user wants to
|
||
// interact with, they need to use the table().foot() method. Note also this
|
||
// allows cells to be used for multiple columns using colspan
|
||
if ( tfoot !== null ) {
|
||
var cells = oSettings.aoFooter[0];
|
||
|
||
for ( i=0, ien=cells.length ; i<ien ; i++ ) {
|
||
column = columns[i];
|
||
column.nTf = cells[i].cell;
|
||
|
||
if ( column.sClass ) {
|
||
$(column.nTf).addClass( column.sClass );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Draw the header (or footer) element based on the column visibility states. The
|
||
* methodology here is to use the layout array from _fnDetectHeader, modified for
|
||
* the instantaneous column visibility, to construct the new layout. The grid is
|
||
* traversed over cell at a time in a rows x columns grid fashion, although each
|
||
* cell insert can cover multiple elements in the grid - which is tracks using the
|
||
* aApplied array. Cell inserts in the grid will only occur where there isn't
|
||
* already a cell in that position.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param array {objects} aoSource Layout array from _fnDetectHeader
|
||
* @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnDrawHead( oSettings, aoSource, bIncludeHidden )
|
||
{
|
||
var i, iLen, j, jLen, k, kLen, n, nLocalTr;
|
||
var aoLocal = [];
|
||
var aApplied = [];
|
||
var iColumns = oSettings.aoColumns.length;
|
||
var iRowspan, iColspan;
|
||
|
||
if ( ! aoSource )
|
||
{
|
||
return;
|
||
}
|
||
|
||
if ( bIncludeHidden === undefined )
|
||
{
|
||
bIncludeHidden = false;
|
||
}
|
||
|
||
/* Make a copy of the master layout array, but without the visible columns in it */
|
||
for ( i=0, iLen=aoSource.length ; i<iLen ; i++ )
|
||
{
|
||
aoLocal[i] = aoSource[i].slice();
|
||
aoLocal[i].nTr = aoSource[i].nTr;
|
||
|
||
/* Remove any columns which are currently hidden */
|
||
for ( j=iColumns-1 ; j>=0 ; j-- )
|
||
{
|
||
if ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )
|
||
{
|
||
aoLocal[i].splice( j, 1 );
|
||
}
|
||
}
|
||
|
||
/* Prep the applied array - it needs an element for each row */
|
||
aApplied.push( [] );
|
||
}
|
||
|
||
for ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )
|
||
{
|
||
nLocalTr = aoLocal[i].nTr;
|
||
|
||
/* All cells are going to be replaced, so empty out the row */
|
||
if ( nLocalTr )
|
||
{
|
||
while( (n = nLocalTr.firstChild) )
|
||
{
|
||
nLocalTr.removeChild( n );
|
||
}
|
||
}
|
||
|
||
for ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )
|
||
{
|
||
iRowspan = 1;
|
||
iColspan = 1;
|
||
|
||
/* Check to see if there is already a cell (row/colspan) covering our target
|
||
* insert point. If there is, then there is nothing to do.
|
||
*/
|
||
if ( aApplied[i][j] === undefined )
|
||
{
|
||
nLocalTr.appendChild( aoLocal[i][j].cell );
|
||
aApplied[i][j] = 1;
|
||
|
||
/* Expand the cell to cover as many rows as needed */
|
||
while ( aoLocal[i+iRowspan] !== undefined &&
|
||
aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )
|
||
{
|
||
aApplied[i+iRowspan][j] = 1;
|
||
iRowspan++;
|
||
}
|
||
|
||
/* Expand the cell to cover as many columns as needed */
|
||
while ( aoLocal[i][j+iColspan] !== undefined &&
|
||
aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )
|
||
{
|
||
/* Must update the applied array over the rows for the columns */
|
||
for ( k=0 ; k<iRowspan ; k++ )
|
||
{
|
||
aApplied[i+k][j+iColspan] = 1;
|
||
}
|
||
iColspan++;
|
||
}
|
||
|
||
/* Do the actual expansion in the DOM */
|
||
$(aoLocal[i][j].cell)
|
||
.attr('rowspan', iRowspan)
|
||
.attr('colspan', iColspan);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Insert the required TR nodes into the table for display
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnDraw( oSettings )
|
||
{
|
||
/* Provide a pre-callback function which can be used to cancel the draw is false is returned */
|
||
var aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );
|
||
if ( $.inArray( false, aPreDraw ) !== -1 )
|
||
{
|
||
_fnProcessingDisplay( oSettings, false );
|
||
return;
|
||
}
|
||
|
||
var i, iLen, n;
|
||
var anRows = [];
|
||
var iRowCount = 0;
|
||
var asStripeClasses = oSettings.asStripeClasses;
|
||
var iStripes = asStripeClasses.length;
|
||
var iOpenRows = oSettings.aoOpenRows.length;
|
||
var oLang = oSettings.oLanguage;
|
||
var iInitDisplayStart = oSettings.iInitDisplayStart;
|
||
var bServerSide = _fnDataSource( oSettings ) == 'ssp';
|
||
var aiDisplay = oSettings.aiDisplay;
|
||
|
||
oSettings.bDrawing = true;
|
||
|
||
/* Check and see if we have an initial draw position from state saving */
|
||
if ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )
|
||
{
|
||
oSettings._iDisplayStart = bServerSide ?
|
||
iInitDisplayStart :
|
||
iInitDisplayStart >= oSettings.fnRecordsDisplay() ?
|
||
0 :
|
||
iInitDisplayStart;
|
||
|
||
oSettings.iInitDisplayStart = -1;
|
||
}
|
||
|
||
var iDisplayStart = oSettings._iDisplayStart;
|
||
var iDisplayEnd = oSettings.fnDisplayEnd();
|
||
|
||
/* Server-side processing draw intercept */
|
||
if ( oSettings.bDeferLoading )
|
||
{
|
||
oSettings.bDeferLoading = false;
|
||
oSettings.iDraw++;
|
||
_fnProcessingDisplay( oSettings, false );
|
||
}
|
||
else if ( !bServerSide )
|
||
{
|
||
oSettings.iDraw++;
|
||
}
|
||
else if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )
|
||
{
|
||
return;
|
||
}
|
||
|
||
if ( aiDisplay.length !== 0 )
|
||
{
|
||
var iStart = bServerSide ? 0 : iDisplayStart;
|
||
var iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;
|
||
|
||
for ( var j=iStart ; j<iEnd ; j++ )
|
||
{
|
||
var iDataIndex = aiDisplay[j];
|
||
var aoData = oSettings.aoData[ iDataIndex ];
|
||
if ( aoData.nTr === null )
|
||
{
|
||
_fnCreateTr( oSettings, iDataIndex );
|
||
}
|
||
|
||
var nRow = aoData.nTr;
|
||
|
||
/* Remove the old striping classes and then add the new one */
|
||
if ( iStripes !== 0 )
|
||
{
|
||
var sStripe = asStripeClasses[ iRowCount % iStripes ];
|
||
if ( aoData._sRowStripe != sStripe )
|
||
{
|
||
$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );
|
||
aoData._sRowStripe = sStripe;
|
||
}
|
||
}
|
||
|
||
/* Row callback functions - might want to manipulate the row */
|
||
_fnCallbackFire( oSettings, 'aoRowCallback', null,
|
||
[nRow, aoData._aData, iRowCount, j] );
|
||
|
||
anRows.push( nRow );
|
||
iRowCount++;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/* Table is empty - create a row with an empty message in it */
|
||
var sZero = oLang.sZeroRecords;
|
||
if ( oSettings.iDraw == 1 && _fnDataSource( oSettings ) == 'ajax' )
|
||
{
|
||
sZero = oLang.sLoadingRecords;
|
||
}
|
||
else if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )
|
||
{
|
||
sZero = oLang.sEmptyTable;
|
||
}
|
||
|
||
anRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )
|
||
.append( $('<td />', {
|
||
'valign': 'top',
|
||
'colSpan': _fnVisbleColumns( oSettings ),
|
||
'class': oSettings.oClasses.sRowEmpty
|
||
} ).html( sZero ) )[0];
|
||
}
|
||
|
||
/* Header and footer callbacks */
|
||
_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],
|
||
_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
|
||
|
||
_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],
|
||
_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );
|
||
|
||
var body = $(oSettings.nTBody);
|
||
|
||
body.children().detach();
|
||
body.append( $(anRows) );
|
||
|
||
/* Call all required callback functions for the end of a draw */
|
||
_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
|
||
|
||
/* Draw is complete, sorting and filtering must be as well */
|
||
oSettings.bSorted = false;
|
||
oSettings.bFiltered = false;
|
||
oSettings.bDrawing = false;
|
||
}
|
||
|
||
|
||
/**
|
||
* Redraw the table - taking account of the various features which are enabled
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {boolean} [holdPosition] Keep the current paging position. By default
|
||
* the paging is reset to the first page
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnReDraw( settings, holdPosition )
|
||
{
|
||
var
|
||
features = settings.oFeatures,
|
||
sort = features.bSort,
|
||
filter = features.bFilter;
|
||
|
||
if ( sort ) {
|
||
_fnSort( settings );
|
||
}
|
||
|
||
if ( filter ) {
|
||
_fnFilterComplete( settings, settings.oPreviousSearch );
|
||
}
|
||
else {
|
||
// No filtering, so we want to just use the display master
|
||
settings.aiDisplay = settings.aiDisplayMaster.slice();
|
||
}
|
||
|
||
if ( holdPosition !== true ) {
|
||
settings._iDisplayStart = 0;
|
||
}
|
||
|
||
_fnDraw( settings );
|
||
}
|
||
|
||
|
||
/**
|
||
* Add the options to the page HTML for the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAddOptionsHtml ( oSettings )
|
||
{
|
||
var classes = oSettings.oClasses;
|
||
var table = $(oSettings.nTable);
|
||
var holding = $('<div/>').insertBefore( table ); // Holding element for speed
|
||
var features = oSettings.oFeatures;
|
||
|
||
// All DataTables are wrapped in a div
|
||
var insert = $('<div/>', {
|
||
id: oSettings.sTableId+'_wrapper',
|
||
'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)
|
||
} );
|
||
|
||
oSettings.nHolding = holding[0];
|
||
oSettings.nTableWrapper = insert[0];
|
||
oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
|
||
|
||
/* Loop over the user set positioning and place the elements as needed */
|
||
var aDom = oSettings.sDom.split('');
|
||
var featureNode, cOption, nNewNode, cNext, sAttr, j;
|
||
for ( var i=0 ; i<aDom.length ; i++ )
|
||
{
|
||
featureNode = null;
|
||
cOption = aDom[i];
|
||
|
||
if ( cOption == '<' )
|
||
{
|
||
/* New container div */
|
||
nNewNode = $('<div/>')[0];
|
||
|
||
/* Check to see if we should append an id and/or a class name to the container */
|
||
cNext = aDom[i+1];
|
||
if ( cNext == "'" || cNext == '"' )
|
||
{
|
||
sAttr = "";
|
||
j = 2;
|
||
while ( aDom[i+j] != cNext )
|
||
{
|
||
sAttr += aDom[i+j];
|
||
j++;
|
||
}
|
||
|
||
/* Replace jQuery UI constants @todo depreciated */
|
||
if ( sAttr == "H" )
|
||
{
|
||
sAttr = classes.sJUIHeader;
|
||
}
|
||
else if ( sAttr == "F" )
|
||
{
|
||
sAttr = classes.sJUIFooter;
|
||
}
|
||
|
||
/* The attribute can be in the format of "#id.class", "#id" or "class" This logic
|
||
* breaks the string into parts and applies them as needed
|
||
*/
|
||
if ( sAttr.indexOf('.') != -1 )
|
||
{
|
||
var aSplit = sAttr.split('.');
|
||
nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
|
||
nNewNode.className = aSplit[1];
|
||
}
|
||
else if ( sAttr.charAt(0) == "#" )
|
||
{
|
||
nNewNode.id = sAttr.substr(1, sAttr.length-1);
|
||
}
|
||
else
|
||
{
|
||
nNewNode.className = sAttr;
|
||
}
|
||
|
||
i += j; /* Move along the position array */
|
||
}
|
||
|
||
insert.append( nNewNode );
|
||
insert = $(nNewNode);
|
||
}
|
||
else if ( cOption == '>' )
|
||
{
|
||
/* End container div */
|
||
insert = insert.parent();
|
||
}
|
||
// @todo Move options into their own plugins?
|
||
else if ( cOption == 'l' && features.bPaginate && features.bLengthChange )
|
||
{
|
||
/* Length */
|
||
featureNode = _fnFeatureHtmlLength( oSettings );
|
||
}
|
||
else if ( cOption == 'f' && features.bFilter )
|
||
{
|
||
/* Filter */
|
||
featureNode = _fnFeatureHtmlFilter( oSettings );
|
||
}
|
||
else if ( cOption == 'r' && features.bProcessing )
|
||
{
|
||
/* pRocessing */
|
||
featureNode = _fnFeatureHtmlProcessing( oSettings );
|
||
}
|
||
else if ( cOption == 't' )
|
||
{
|
||
/* Table */
|
||
featureNode = _fnFeatureHtmlTable( oSettings );
|
||
}
|
||
else if ( cOption == 'i' && features.bInfo )
|
||
{
|
||
/* Info */
|
||
featureNode = _fnFeatureHtmlInfo( oSettings );
|
||
}
|
||
else if ( cOption == 'p' && features.bPaginate )
|
||
{
|
||
/* Pagination */
|
||
featureNode = _fnFeatureHtmlPaginate( oSettings );
|
||
}
|
||
else if ( DataTable.ext.feature.length !== 0 )
|
||
{
|
||
/* Plug-in features */
|
||
var aoFeatures = DataTable.ext.feature;
|
||
for ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )
|
||
{
|
||
if ( cOption == aoFeatures[k].cFeature )
|
||
{
|
||
featureNode = aoFeatures[k].fnInit( oSettings );
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Add to the 2D features array */
|
||
if ( featureNode )
|
||
{
|
||
var aanFeatures = oSettings.aanFeatures;
|
||
|
||
if ( ! aanFeatures[cOption] )
|
||
{
|
||
aanFeatures[cOption] = [];
|
||
}
|
||
|
||
aanFeatures[cOption].push( featureNode );
|
||
insert.append( featureNode );
|
||
}
|
||
}
|
||
|
||
/* Built our DOM structure - replace the holding div with what we want */
|
||
holding.replaceWith( insert );
|
||
}
|
||
|
||
|
||
/**
|
||
* Use the DOM source to create up an array of header cells. The idea here is to
|
||
* create a layout grid (array) of rows x columns, which contains a reference
|
||
* to the cell that that point in the grid (regardless of col/rowspan), such that
|
||
* any column / row could be removed and the new grid constructed
|
||
* @param array {object} aLayout Array to store the calculated layout in
|
||
* @param {node} nThead The header/footer element for the table
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnDetectHeader ( aLayout, nThead )
|
||
{
|
||
var nTrs = $(nThead).children('tr');
|
||
var nTr, nCell;
|
||
var i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;
|
||
var bUnique;
|
||
var fnShiftCol = function ( a, i, j ) {
|
||
var k = a[i];
|
||
while ( k[j] ) {
|
||
j++;
|
||
}
|
||
return j;
|
||
};
|
||
|
||
aLayout.splice( 0, aLayout.length );
|
||
|
||
/* We know how many rows there are in the layout - so prep it */
|
||
for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
|
||
{
|
||
aLayout.push( [] );
|
||
}
|
||
|
||
/* Calculate a layout array */
|
||
for ( i=0, iLen=nTrs.length ; i<iLen ; i++ )
|
||
{
|
||
nTr = nTrs[i];
|
||
iColumn = 0;
|
||
|
||
/* For every cell in the row... */
|
||
nCell = nTr.firstChild;
|
||
while ( nCell ) {
|
||
if ( nCell.nodeName.toUpperCase() == "TD" ||
|
||
nCell.nodeName.toUpperCase() == "TH" )
|
||
{
|
||
/* Get the col and rowspan attributes from the DOM and sanitise them */
|
||
iColspan = nCell.getAttribute('colspan') * 1;
|
||
iRowspan = nCell.getAttribute('rowspan') * 1;
|
||
iColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;
|
||
iRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;
|
||
|
||
/* There might be colspan cells already in this row, so shift our target
|
||
* accordingly
|
||
*/
|
||
iColShifted = fnShiftCol( aLayout, i, iColumn );
|
||
|
||
/* Cache calculation for unique columns */
|
||
bUnique = iColspan === 1 ? true : false;
|
||
|
||
/* If there is col / rowspan, copy the information into the layout grid */
|
||
for ( l=0 ; l<iColspan ; l++ )
|
||
{
|
||
for ( k=0 ; k<iRowspan ; k++ )
|
||
{
|
||
aLayout[i+k][iColShifted+l] = {
|
||
"cell": nCell,
|
||
"unique": bUnique
|
||
};
|
||
aLayout[i+k].nTr = nTr;
|
||
}
|
||
}
|
||
}
|
||
nCell = nCell.nextSibling;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Get an array of unique th elements, one for each column
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {node} nHeader automatically detect the layout from this node - optional
|
||
* @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional
|
||
* @returns array {node} aReturn list of unique th's
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetUniqueThs ( oSettings, nHeader, aLayout )
|
||
{
|
||
var aReturn = [];
|
||
if ( !aLayout )
|
||
{
|
||
aLayout = oSettings.aoHeader;
|
||
if ( nHeader )
|
||
{
|
||
aLayout = [];
|
||
_fnDetectHeader( aLayout, nHeader );
|
||
}
|
||
}
|
||
|
||
for ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )
|
||
{
|
||
for ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )
|
||
{
|
||
if ( aLayout[i][j].unique &&
|
||
(!aReturn[j] || !oSettings.bSortCellsTop) )
|
||
{
|
||
aReturn[j] = aLayout[i][j].cell;
|
||
}
|
||
}
|
||
}
|
||
|
||
return aReturn;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Create an Ajax call based on the table's settings, taking into account that
|
||
* parameters can have multiple forms, and backwards compatibility.
|
||
*
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {array} data Data to send to the server, required by
|
||
* DataTables - may be augmented by developer callbacks
|
||
* @param {function} fn Callback function to run when data is obtained
|
||
*/
|
||
function _fnBuildAjax( oSettings, data, fn )
|
||
{
|
||
// Compatibility with 1.9-, allow fnServerData and event to manipulate
|
||
_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );
|
||
|
||
// Convert to object based for 1.10+ if using the old array scheme which can
|
||
// come from server-side processing or serverParams
|
||
if ( data && $.isArray(data) ) {
|
||
var tmp = {};
|
||
var rbracket = /(.*?)\[\]$/;
|
||
|
||
$.each( data, function (key, val) {
|
||
var match = val.name.match(rbracket);
|
||
|
||
if ( match ) {
|
||
// Support for arrays
|
||
var name = match[0];
|
||
|
||
if ( ! tmp[ name ] ) {
|
||
tmp[ name ] = [];
|
||
}
|
||
tmp[ name ].push( val.value );
|
||
}
|
||
else {
|
||
tmp[val.name] = val.value;
|
||
}
|
||
} );
|
||
data = tmp;
|
||
}
|
||
|
||
var ajaxData;
|
||
var ajax = oSettings.ajax;
|
||
var instance = oSettings.oInstance;
|
||
|
||
if ( $.isPlainObject( ajax ) && ajax.data )
|
||
{
|
||
ajaxData = ajax.data;
|
||
|
||
var newData = $.isFunction( ajaxData ) ?
|
||
ajaxData( data ) : // fn can manipulate data or return an object
|
||
ajaxData; // object or array to merge
|
||
|
||
// If the function returned an object, use that alone
|
||
data = $.isFunction( ajaxData ) && newData ?
|
||
newData :
|
||
$.extend( true, data, newData );
|
||
|
||
// Remove the data property as we've resolved it already and don't want
|
||
// jQuery to do it again (it is restored at the end of the function)
|
||
delete ajax.data;
|
||
}
|
||
|
||
var baseAjax = {
|
||
"data": data,
|
||
"success": function (json) {
|
||
var error = json.error || json.sError;
|
||
if ( error ) {
|
||
oSettings.oApi._fnLog( oSettings, 0, error );
|
||
}
|
||
|
||
oSettings.json = json;
|
||
_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json] );
|
||
fn( json );
|
||
},
|
||
"dataType": "json",
|
||
"cache": false,
|
||
"type": oSettings.sServerMethod,
|
||
"error": function (xhr, error, thrown) {
|
||
var log = oSettings.oApi._fnLog;
|
||
|
||
if ( error == "parsererror" ) {
|
||
log( oSettings, 0, 'Invalid JSON response', 1 );
|
||
}
|
||
else if ( xhr.readyState === 4 ) {
|
||
log( oSettings, 0, 'Ajax error', 7 );
|
||
}
|
||
|
||
_fnProcessingDisplay( oSettings, false );
|
||
}
|
||
};
|
||
|
||
// Store the data submitted for the API
|
||
oSettings.oAjaxData = data;
|
||
|
||
// Allow plug-ins and external processes to modify the data
|
||
_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );
|
||
|
||
if ( oSettings.fnServerData )
|
||
{
|
||
// DataTables 1.9- compatibility
|
||
oSettings.fnServerData.call( instance,
|
||
oSettings.sAjaxSource,
|
||
$.map( data, function (val, key) { // Need to convert back to 1.9 trad format
|
||
return { name: key, value: val };
|
||
} ),
|
||
fn,
|
||
oSettings
|
||
);
|
||
}
|
||
else if ( oSettings.sAjaxSource || typeof ajax === 'string' )
|
||
{
|
||
// DataTables 1.9- compatibility
|
||
oSettings.jqXHR = $.ajax( $.extend( baseAjax, {
|
||
url: ajax || oSettings.sAjaxSource
|
||
} ) );
|
||
}
|
||
else if ( $.isFunction( ajax ) )
|
||
{
|
||
// Is a function - let the caller define what needs to be done
|
||
oSettings.jqXHR = ajax.call( instance, data, fn, oSettings );
|
||
}
|
||
else
|
||
{
|
||
// Object to extend the base settings
|
||
oSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );
|
||
|
||
// Restore for next time around
|
||
ajax.data = ajaxData;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Update the table using an Ajax call
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {boolean} Block the table drawing or not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAjaxUpdate( oSettings )
|
||
{
|
||
if ( oSettings.bAjaxDataGet )
|
||
{
|
||
oSettings.iDraw++;
|
||
_fnProcessingDisplay( oSettings, true );
|
||
var iColumns = oSettings.aoColumns.length;
|
||
var aoData = _fnAjaxParameters( oSettings );
|
||
|
||
_fnBuildAjax( oSettings, aoData, function(json) {
|
||
_fnAjaxUpdateDraw( oSettings, json );
|
||
}, oSettings );
|
||
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
|
||
/**
|
||
* Build up the parameters in an object needed for a server-side processing
|
||
* request. Note that this is basically done twice, is different ways - a modern
|
||
* method which is used by default in DataTables 1.10 which uses objects and
|
||
* arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if
|
||
* the sAjaxSource option is used in the initialisation, or the legacyAjax
|
||
* option is set.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {bool} block the table drawing or not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAjaxParameters( settings )
|
||
{
|
||
var
|
||
columns = settings.aoColumns,
|
||
columnCount = columns.length,
|
||
features = settings.oFeatures,
|
||
preSearch = settings.oPreviousSearch,
|
||
preColSearch = settings.aoPreSearchCols,
|
||
i, data = [], dataProp, column, columnSearch,
|
||
sort = _fnSortFlatten( settings ),
|
||
displayStart = settings._iDisplayStart,
|
||
displayLength = features.bPaginate !== false ?
|
||
settings._iDisplayLength :
|
||
-1;
|
||
|
||
var param = function ( name, value ) {
|
||
data.push( { 'name': name, 'value': value } );
|
||
};
|
||
|
||
// DataTables 1.9- compatible method
|
||
param( 'sEcho', settings.iDraw );
|
||
param( 'iColumns', columnCount );
|
||
param( 'sColumns', _pluck( columns, 'sName' ).join(',') );
|
||
param( 'iDisplayStart', displayStart );
|
||
param( 'iDisplayLength', displayLength );
|
||
|
||
// DataTables 1.10+ method
|
||
var d = {
|
||
draw: settings.iDraw,
|
||
columns: [],
|
||
order: [],
|
||
start: displayStart,
|
||
length: displayLength,
|
||
search: {
|
||
value: preSearch.sSearch,
|
||
regex: preSearch.bRegex
|
||
}
|
||
};
|
||
|
||
for ( i=0 ; i<columnCount ; i++ ) {
|
||
column = columns[i];
|
||
columnSearch = preColSearch[i];
|
||
dataProp = typeof column.mData=="function" ? 'function' : column.mData ;
|
||
|
||
d.columns.push( {
|
||
data: dataProp,
|
||
name: column.sName,
|
||
searchable: column.bSearchable,
|
||
orderable: column.bSortable,
|
||
search: {
|
||
value: columnSearch.sSearch,
|
||
regex: columnSearch.bRegex
|
||
}
|
||
} );
|
||
|
||
param( "mDataProp_"+i, dataProp );
|
||
|
||
if ( features.bFilter ) {
|
||
param( 'sSearch_'+i, columnSearch.sSearch );
|
||
param( 'bRegex_'+i, columnSearch.bRegex );
|
||
param( 'bSearchable_'+i, column.bSearchable );
|
||
}
|
||
|
||
if ( features.bSort ) {
|
||
param( 'bSortable_'+i, column.bSortable );
|
||
}
|
||
}
|
||
|
||
if ( features.bFilter ) {
|
||
param( 'sSearch', preSearch.sSearch );
|
||
param( 'bRegex', preSearch.bRegex );
|
||
}
|
||
|
||
if ( features.bSort ) {
|
||
$.each( sort, function ( i, val ) {
|
||
d.order.push( { column: val.col, dir: val.dir } );
|
||
|
||
param( 'iSortCol_'+i, val.col );
|
||
param( 'sSortDir_'+i, val.dir );
|
||
} );
|
||
|
||
param( 'iSortingCols', sort.length );
|
||
}
|
||
|
||
// If the legacy.ajax parameter is null, then we automatically decide which
|
||
// form to use, based on sAjaxSource
|
||
var legacy = DataTable.ext.legacy.ajax;
|
||
if ( legacy === null ) {
|
||
return settings.sAjaxSource ? data : d;
|
||
}
|
||
|
||
// Otherwise, if legacy has been specified then we use that to decide on the
|
||
// form
|
||
return legacy ? data : d;
|
||
}
|
||
|
||
|
||
/**
|
||
* Data the data from the server (nuking the old) and redraw the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {object} json json data return from the server.
|
||
* @param {string} json.sEcho Tracking flag for DataTables to match requests
|
||
* @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering
|
||
* @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering
|
||
* @param {array} json.aaData The data to display on this page
|
||
* @param {string} [json.sColumns] Column ordering (sName, comma separated)
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnAjaxUpdateDraw ( settings, json )
|
||
{
|
||
// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.
|
||
// Support both
|
||
var compat = function ( old, modern ) {
|
||
return json[old] !== undefined ? json[old] : json[modern];
|
||
};
|
||
|
||
var draw = compat( 'sEcho', 'draw' );
|
||
var recordsTotal = compat( 'iTotalRecords', 'recordsTotal' );
|
||
var rocordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );
|
||
|
||
if ( draw ) {
|
||
// Protect against out of sequence returns
|
||
if ( draw*1 < settings.iDraw ) {
|
||
return;
|
||
}
|
||
settings.iDraw = draw * 1;
|
||
}
|
||
|
||
_fnClearTable( settings );
|
||
settings._iRecordsTotal = parseInt(recordsTotal, 10);
|
||
settings._iRecordsDisplay = parseInt(rocordsFiltered, 10);
|
||
|
||
var data = _fnAjaxDataSrc( settings, json );
|
||
for ( var i=0, ien=data.length ; i<ien ; i++ ) {
|
||
_fnAddData( settings, data[i] );
|
||
}
|
||
settings.aiDisplay = settings.aiDisplayMaster.slice();
|
||
|
||
settings.bAjaxDataGet = false;
|
||
_fnDraw( settings );
|
||
|
||
if ( ! settings._bInitComplete ) {
|
||
_fnInitComplete( settings, json );
|
||
}
|
||
|
||
settings.bAjaxDataGet = true;
|
||
_fnProcessingDisplay( settings, false );
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the data from the JSON data source to use for drawing a table. Using
|
||
* `_fnGetObjectDataFn` allows the data to be sourced from a property of the
|
||
* source object, or from a processing function.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {object} json Data source object / array from the server
|
||
* @return {array} Array of data to use
|
||
*/
|
||
function _fnAjaxDataSrc ( oSettings, json )
|
||
{
|
||
var dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?
|
||
oSettings.ajax.dataSrc :
|
||
oSettings.sAjaxDataProp; // Compatibility with 1.9-.
|
||
|
||
// Compatibility with 1.9-. In order to read from aaData, check if the
|
||
// default has been changed, if not, check for aaData
|
||
if ( dataSrc === 'data' ) {
|
||
return json.aaData || json[dataSrc];
|
||
}
|
||
|
||
return dataSrc !== "" ?
|
||
_fnGetObjectDataFn( dataSrc )( json ) :
|
||
json;
|
||
}
|
||
|
||
|
||
/**
|
||
* Generate the node required for filtering text
|
||
* @returns {node} Filter control element
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlFilter ( settings )
|
||
{
|
||
var classes = settings.oClasses;
|
||
var tableId = settings.sTableId;
|
||
var previousSearch = settings.oPreviousSearch;
|
||
var features = settings.aanFeatures;
|
||
var input = '<input type="search" class="'+classes.sFilterInput+'"/>';
|
||
|
||
var str = settings.oLanguage.sSearch;
|
||
str = str.match(/_INPUT_/) ?
|
||
str.replace('_INPUT_', input) :
|
||
str+input;
|
||
|
||
var filter = $('<div/>', {
|
||
'id': ! features.f ? tableId+'_filter' : null,
|
||
'class': classes.sFilter
|
||
} )
|
||
.append( $('<label/>' ).append( str ) );
|
||
|
||
var searchFn = function() {
|
||
/* Update all other filter input elements for the new display */
|
||
var n = features.f;
|
||
var val = !this.value ? "" : this.value; // mental IE8 fix :-(
|
||
|
||
/* Now do the filter */
|
||
if ( val != previousSearch.sSearch ) {
|
||
_fnFilterComplete( settings, {
|
||
"sSearch": val,
|
||
"bRegex": previousSearch.bRegex,
|
||
"bSmart": previousSearch.bSmart ,
|
||
"bCaseInsensitive": previousSearch.bCaseInsensitive
|
||
} );
|
||
|
||
// Need to redraw, without resorting
|
||
settings._iDisplayStart = 0;
|
||
_fnDraw( settings );
|
||
}
|
||
};
|
||
var jqFilter = $('input', filter)
|
||
.val( previousSearch.sSearch.replace('"','"') )
|
||
.bind(
|
||
'keyup.DT search.DT input.DT paste.DT cut.DT',
|
||
_fnDataSource( settings ) === 'ssp' ?
|
||
_fnThrottle( searchFn, 400 ):
|
||
searchFn
|
||
)
|
||
.bind( 'keypress.DT', function(e) {
|
||
/* Prevent form submission */
|
||
if ( e.keyCode == 13 ) {
|
||
return false;
|
||
}
|
||
} )
|
||
.attr('aria-controls', tableId);
|
||
|
||
// Update the input elements whenever the table is filtered
|
||
$(settings.nTable).on( 'filter.DT', function () {
|
||
// IE9 throws an 'unknown error' if document.activeElement is used
|
||
// inside an iframe or frame...
|
||
try {
|
||
if ( jqFilter[0] !== document.activeElement ) {
|
||
jqFilter.val( previousSearch.sSearch );
|
||
}
|
||
}
|
||
catch ( e ) {}
|
||
} );
|
||
|
||
return filter[0];
|
||
}
|
||
|
||
|
||
/**
|
||
* Filter the table using both the global filter and column based filtering
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {object} oSearch search information
|
||
* @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFilterComplete ( oSettings, oInput, iForce )
|
||
{
|
||
var oPrevSearch = oSettings.oPreviousSearch;
|
||
var aoPrevSearch = oSettings.aoPreSearchCols;
|
||
var fnSaveFilter = function ( oFilter ) {
|
||
/* Save the filtering values */
|
||
oPrevSearch.sSearch = oFilter.sSearch;
|
||
oPrevSearch.bRegex = oFilter.bRegex;
|
||
oPrevSearch.bSmart = oFilter.bSmart;
|
||
oPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;
|
||
};
|
||
var fnRegex = function ( o ) {
|
||
// Backwards compatibility with the bEscapeRegex option
|
||
return o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;
|
||
};
|
||
|
||
// Resolve any column types that are unknown due to addition or invalidation
|
||
// @todo As per sort - can this be moved into an event handler?
|
||
_fnColumnTypes( oSettings );
|
||
|
||
/* In server-side processing all filtering is done by the server, so no point hanging around here */
|
||
if ( _fnDataSource( oSettings ) != 'ssp' )
|
||
{
|
||
/* Global filter */
|
||
_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );
|
||
fnSaveFilter( oInput );
|
||
|
||
/* Now do the individual column filter */
|
||
for ( var i=0 ; i<aoPrevSearch.length ; i++ )
|
||
{
|
||
_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),
|
||
aoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );
|
||
}
|
||
|
||
/* Custom filtering */
|
||
_fnFilterCustom( oSettings );
|
||
}
|
||
else
|
||
{
|
||
fnSaveFilter( oInput );
|
||
}
|
||
|
||
/* Tell the draw function we have been filtering */
|
||
oSettings.bFiltered = true;
|
||
_fnCallbackFire( oSettings, null, 'search', [oSettings] );
|
||
}
|
||
|
||
|
||
/**
|
||
* Apply custom filtering functions
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFilterCustom( settings )
|
||
{
|
||
var filters = DataTable.ext.search;
|
||
var displayRows = settings.aiDisplay;
|
||
var row, rowIdx;
|
||
|
||
for ( var i=0, iLen=filters.length ; i<iLen ; i++ ) {
|
||
for ( var j=displayRows.length-1 ; j>=0 ; j-- ) {
|
||
rowIdx = displayRows[ j ];
|
||
row = settings.aoData[ rowIdx ];
|
||
|
||
if ( ! filters[i]( settings, row._aFilterData, rowIdx, row._aData ) ) {
|
||
displayRows.splice( j, 1 );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Filter the table on a per-column basis
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {string} sInput string to filter on
|
||
* @param {int} iColumn column to filter
|
||
* @param {bool} bRegex treat search string as a regular expression or not
|
||
* @param {bool} bSmart use smart filtering or not
|
||
* @param {bool} bCaseInsensitive Do case insenstive matching or not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )
|
||
{
|
||
if ( searchStr === '' ) {
|
||
return;
|
||
}
|
||
|
||
var data;
|
||
var display = settings.aiDisplay;
|
||
var rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );
|
||
|
||
for ( var i=display.length-1 ; i>=0 ; i-- ) {
|
||
data = settings.aoData[ display[i] ]._aFilterData[ colIdx ];
|
||
|
||
if ( ! rpSearch.test( data ) ) {
|
||
display.splice( i, 1 );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Filter the data table based on user input and draw the table
|
||
* @param {object} settings dataTables settings object
|
||
* @param {string} input string to filter on
|
||
* @param {int} force optional - force a research of the master array (1) or not (undefined or 0)
|
||
* @param {bool} regex treat as a regular expression or not
|
||
* @param {bool} smart perform smart filtering or not
|
||
* @param {bool} caseInsensitive Do case insenstive matching or not
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFilter( settings, input, force, regex, smart, caseInsensitive )
|
||
{
|
||
var rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );
|
||
var prevSearch = settings.oPreviousSearch.sSearch;
|
||
var displayMaster = settings.aiDisplayMaster;
|
||
var display, invalidated, i;
|
||
|
||
// Need to take account of custom filtering functions - always filter
|
||
if ( DataTable.ext.search.length !== 0 ) {
|
||
force = true;
|
||
}
|
||
|
||
// Check if any of the rows were invalidated
|
||
invalidated = _fnFilterData( settings );
|
||
|
||
// If the input is blank - we just want the full data set
|
||
if ( input.length <= 0 ) {
|
||
settings.aiDisplay = displayMaster.slice();
|
||
}
|
||
else {
|
||
// New search - start from the master array
|
||
if ( invalidated ||
|
||
force ||
|
||
prevSearch.length > input.length ||
|
||
input.indexOf(prevSearch) !== 0 ||
|
||
settings.bSorted // On resort, the display master needs to be
|
||
// re-filtered since indexes will have changed
|
||
) {
|
||
settings.aiDisplay = displayMaster.slice();
|
||
}
|
||
|
||
// Search the display array
|
||
display = settings.aiDisplay;
|
||
|
||
for ( i=display.length-1 ; i>=0 ; i-- ) {
|
||
if ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {
|
||
display.splice( i, 1 );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Build a regular expression object suitable for searching a table
|
||
* @param {string} sSearch string to search for
|
||
* @param {bool} bRegex treat as a regular expression or not
|
||
* @param {bool} bSmart perform smart filtering or not
|
||
* @param {bool} bCaseInsensitive Do case insensitive matching or not
|
||
* @returns {RegExp} constructed object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFilterCreateSearch( search, regex, smart, caseInsensitive )
|
||
{
|
||
search = regex ?
|
||
search :
|
||
_fnEscapeRegex( search );
|
||
|
||
if ( smart ) {
|
||
/* For smart filtering we want to allow the search to work regardless of
|
||
* word order. We also want double quoted text to be preserved, so word
|
||
* order is important - a la google. So this is what we want to
|
||
* generate:
|
||
*
|
||
* ^(?=.*?\bone\b)(?=.*?\btwo three\b)(?=.*?\bfour\b).*$
|
||
*/
|
||
var a = $.map( search.match( /"[^"]+"|[^ ]+/g ) || '', function ( word ) {
|
||
return word.charAt(0) === '"' ?
|
||
word.match( /^"(.*)"$/ )[1] :
|
||
word;
|
||
} );
|
||
|
||
search = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';
|
||
}
|
||
|
||
return new RegExp( search, caseInsensitive ? 'i' : '' );
|
||
}
|
||
|
||
|
||
/**
|
||
* scape a string such that it can be used in a regular expression
|
||
* @param {string} sVal string to escape
|
||
* @returns {string} escaped string
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnEscapeRegex ( sVal )
|
||
{
|
||
return sVal.replace( _re_escape_regex, '\\$1' );
|
||
}
|
||
|
||
|
||
|
||
var __filter_div = $('<div>')[0];
|
||
var __filter_div_textContent = __filter_div.textContent !== undefined;
|
||
|
||
// Update the filtering data for each row if needed (by invalidation or first run)
|
||
function _fnFilterData ( settings )
|
||
{
|
||
var columns = settings.aoColumns;
|
||
var column;
|
||
var i, j, ien, jen, filterData, cellData, row;
|
||
var fomatters = DataTable.ext.type.search;
|
||
var wasInvalidated = false;
|
||
|
||
for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||
row = settings.aoData[i];
|
||
|
||
if ( ! row._aFilterData ) {
|
||
filterData = [];
|
||
|
||
for ( j=0, jen=columns.length ; j<jen ; j++ ) {
|
||
column = columns[j];
|
||
|
||
if ( column.bSearchable ) {
|
||
cellData = _fnGetCellData( settings, i, j, 'filter' );
|
||
|
||
cellData = fomatters[ column.sType ] ?
|
||
fomatters[ column.sType ]( cellData ) :
|
||
cellData !== null ?
|
||
cellData :
|
||
'';
|
||
}
|
||
else {
|
||
cellData = '';
|
||
}
|
||
|
||
// If it looks like there is an HTML entity in the string,
|
||
// attempt to decode it so sorting works as expected. Note that
|
||
// we could use a single line of jQuery to do this, but the DOM
|
||
// method used here is much faster http://jsperf.com/html-decode
|
||
if ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {
|
||
__filter_div.innerHTML = cellData;
|
||
cellData = __filter_div_textContent ?
|
||
__filter_div.textContent :
|
||
__filter_div.innerText;
|
||
}
|
||
|
||
if ( cellData.replace ) {
|
||
cellData = cellData.replace(/[\r\n]/g, '');
|
||
}
|
||
|
||
filterData.push( cellData );
|
||
}
|
||
|
||
row._aFilterData = filterData;
|
||
row._sFilterRow = filterData.join(' ');
|
||
wasInvalidated = true;
|
||
}
|
||
}
|
||
|
||
return wasInvalidated;
|
||
}
|
||
|
||
/**
|
||
* Generate the node required for the info display
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {node} Information element
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlInfo ( settings )
|
||
{
|
||
var
|
||
tid = settings.sTableId,
|
||
nodes = settings.aanFeatures.i,
|
||
n = $('<div/>', {
|
||
'class': settings.oClasses.sInfo,
|
||
'id': ! nodes ? tid+'_info' : null
|
||
} );
|
||
|
||
if ( ! nodes ) {
|
||
// Update display on each draw
|
||
settings.aoDrawCallback.push( {
|
||
"fn": _fnUpdateInfo,
|
||
"sName": "information"
|
||
} );
|
||
|
||
n
|
||
.attr( 'role', 'status' )
|
||
.attr( 'aria-live', 'polite' );
|
||
|
||
// Table is described by our info div
|
||
$(settings.nTable).attr( 'aria-describedby', tid+'_info' );
|
||
}
|
||
|
||
return n[0];
|
||
}
|
||
|
||
|
||
/**
|
||
* Update the information elements in the display
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnUpdateInfo ( settings )
|
||
{
|
||
/* Show information about the table */
|
||
var nodes = settings.aanFeatures.i;
|
||
if ( nodes.length === 0 ) {
|
||
return;
|
||
}
|
||
|
||
var
|
||
lang = settings.oLanguage,
|
||
start = settings._iDisplayStart+1,
|
||
end = settings.fnDisplayEnd(),
|
||
max = settings.fnRecordsTotal(),
|
||
total = settings.fnRecordsDisplay(),
|
||
out = total ?
|
||
lang.sInfo :
|
||
lang.sInfoEmpty;
|
||
|
||
if ( total !== max ) {
|
||
/* Record set after filtering */
|
||
out += ' ' + lang.sInfoFiltered;
|
||
}
|
||
|
||
// Convert the macros
|
||
out += lang.sInfoPostFix;
|
||
out = _fnInfoMacros( settings, out );
|
||
|
||
var callback = lang.fnInfoCallback;
|
||
if ( callback !== null ) {
|
||
out = callback.call( settings.oInstance,
|
||
settings, start, end, max, total, out
|
||
);
|
||
}
|
||
|
||
$(nodes).html( out );
|
||
}
|
||
|
||
|
||
function _fnInfoMacros ( settings, str )
|
||
{
|
||
// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
|
||
// internally
|
||
var
|
||
formatter = settings.fnFormatNumber,
|
||
start = settings._iDisplayStart+1,
|
||
len = settings._iDisplayLength,
|
||
vis = settings.fnRecordsDisplay(),
|
||
all = len === -1;
|
||
|
||
return str.
|
||
replace(/_START_/g, formatter.call( settings, start ) ).
|
||
replace(/_END_/g, formatter.call( settings, settings.fnDisplayEnd() ) ).
|
||
replace(/_MAX_/g, formatter.call( settings, settings.fnRecordsTotal() ) ).
|
||
replace(/_TOTAL_/g, formatter.call( settings, vis ) ).
|
||
replace(/_PAGE_/g, formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).
|
||
replace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Draw the table for the first time, adding all required features
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnInitialise ( settings )
|
||
{
|
||
var i, iLen, iAjaxStart=settings.iInitDisplayStart;
|
||
var columns = settings.aoColumns, column;
|
||
var features = settings.oFeatures;
|
||
|
||
/* Ensure that the table data is fully initialised */
|
||
if ( ! settings.bInitialised ) {
|
||
setTimeout( function(){ _fnInitialise( settings ); }, 200 );
|
||
return;
|
||
}
|
||
|
||
/* Show the display HTML options */
|
||
_fnAddOptionsHtml( settings );
|
||
|
||
/* Build and draw the header / footer for the table */
|
||
_fnBuildHead( settings );
|
||
_fnDrawHead( settings, settings.aoHeader );
|
||
_fnDrawHead( settings, settings.aoFooter );
|
||
|
||
/* Okay to show that something is going on now */
|
||
_fnProcessingDisplay( settings, true );
|
||
|
||
/* Calculate sizes for columns */
|
||
if ( features.bAutoWidth ) {
|
||
_fnCalculateColumnWidths( settings );
|
||
}
|
||
|
||
for ( i=0, iLen=columns.length ; i<iLen ; i++ ) {
|
||
column = columns[i];
|
||
|
||
if ( column.sWidth ) {
|
||
column.nTh.style.width = _fnStringToCss( column.sWidth );
|
||
}
|
||
}
|
||
|
||
// If there is default sorting required - let's do it. The sort function
|
||
// will do the drawing for us. Otherwise we draw the table regardless of the
|
||
// Ajax source - this allows the table to look initialised for Ajax sourcing
|
||
// data (show 'loading' message possibly)
|
||
_fnReDraw( settings );
|
||
|
||
// Server-side processing init complete is done by _fnAjaxUpdateDraw
|
||
var dataSrc = _fnDataSource( settings );
|
||
if ( dataSrc != 'ssp' ) {
|
||
// if there is an ajax source load the data
|
||
if ( dataSrc == 'ajax' ) {
|
||
_fnBuildAjax( settings, [], function(json) {
|
||
var aData = _fnAjaxDataSrc( settings, json );
|
||
|
||
// Got the data - add it to the table
|
||
for ( i=0 ; i<aData.length ; i++ ) {
|
||
_fnAddData( settings, aData[i] );
|
||
}
|
||
|
||
// Reset the init display for cookie saving. We've already done
|
||
// a filter, and therefore cleared it before. So we need to make
|
||
// it appear 'fresh'
|
||
settings.iInitDisplayStart = iAjaxStart;
|
||
|
||
_fnReDraw( settings );
|
||
|
||
_fnProcessingDisplay( settings, false );
|
||
_fnInitComplete( settings, json );
|
||
}, settings );
|
||
}
|
||
else {
|
||
_fnProcessingDisplay( settings, false );
|
||
_fnInitComplete( settings );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Draw the table for the first time, adding all required features
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {object} [json] JSON from the server that completed the table, if using Ajax source
|
||
* with client-side processing (optional)
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnInitComplete ( settings, json )
|
||
{
|
||
settings._bInitComplete = true;
|
||
|
||
// On an Ajax load we now have data and therefore want to apply the column
|
||
// sizing
|
||
if ( json ) {
|
||
_fnAdjustColumnSizing( settings );
|
||
}
|
||
|
||
_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );
|
||
}
|
||
|
||
|
||
function _fnLengthChange ( settings, val )
|
||
{
|
||
var len = parseInt( val, 10 );
|
||
settings._iDisplayLength = len;
|
||
|
||
_fnLengthOverflow( settings );
|
||
|
||
// Fire length change event
|
||
_fnCallbackFire( settings, null, 'length', [settings, len] );
|
||
}
|
||
|
||
|
||
/**
|
||
* Generate the node required for user display length changing
|
||
* @param {object} settings dataTables settings object
|
||
* @returns {node} Display length feature node
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlLength ( settings )
|
||
{
|
||
var
|
||
classes = settings.oClasses,
|
||
tableId = settings.sTableId,
|
||
menu = settings.aLengthMenu,
|
||
d2 = $.isArray( menu[0] ),
|
||
lengths = d2 ? menu[0] : menu,
|
||
language = d2 ? menu[1] : menu;
|
||
|
||
var select = $('<select/>', {
|
||
'name': tableId+'_length',
|
||
'aria-controls': tableId,
|
||
'class': classes.sLengthSelect
|
||
} );
|
||
|
||
for ( var i=0, ien=lengths.length ; i<ien ; i++ ) {
|
||
select[0][ i ] = new Option( language[i], lengths[i] );
|
||
}
|
||
|
||
var div = $('<div><label/></div>').addClass( classes.sLength );
|
||
if ( ! settings.aanFeatures.l ) {
|
||
div[0].id = tableId+'_length';
|
||
}
|
||
|
||
var a = settings.oLanguage.sLengthMenu.split(/(_MENU_)/);
|
||
div.children().append( a.length > 1 ?
|
||
[ a[0], select, a[2] ] :
|
||
a[0]
|
||
);
|
||
|
||
// Can't use `select` variable, as user might provide their own select menu
|
||
$('select', div)
|
||
.val( settings._iDisplayLength )
|
||
.bind( 'change.DT', function(e) {
|
||
_fnLengthChange( settings, $(this).val() );
|
||
_fnDraw( settings );
|
||
} );
|
||
|
||
// Update node value whenever anything changes the table's length
|
||
$(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {
|
||
$('select', div).val( len );
|
||
} );
|
||
|
||
return div[0];
|
||
}
|
||
|
||
|
||
|
||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Note that most of the paging logic is done in
|
||
* DataTable.ext.pager
|
||
*/
|
||
|
||
/**
|
||
* Generate the node required for default pagination
|
||
* @param {object} oSettings dataTables settings object
|
||
* @returns {node} Pagination feature node
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlPaginate ( settings )
|
||
{
|
||
var
|
||
type = settings.sPaginationType,
|
||
plugin = DataTable.ext.pager[ type ],
|
||
modern = typeof plugin === 'function',
|
||
redraw = function( settings ) {
|
||
_fnDraw( settings );
|
||
},
|
||
node = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],
|
||
features = settings.aanFeatures;
|
||
|
||
if ( ! modern ) {
|
||
plugin.fnInit( settings, node, redraw );
|
||
}
|
||
|
||
/* Add a draw callback for the pagination on first instance, to update the paging display */
|
||
if ( ! features.p )
|
||
{
|
||
node.id = settings.sTableId+'_paginate';
|
||
|
||
settings.aoDrawCallback.push( {
|
||
"fn": function( settings ) {
|
||
if ( modern ) {
|
||
var
|
||
start = settings._iDisplayStart,
|
||
len = settings._iDisplayLength,
|
||
visRecords = settings.fnRecordsDisplay(),
|
||
all = len === -1,
|
||
page = all ? 0 : Math.ceil( start / len ),
|
||
pages = all ? 1 : Math.ceil( visRecords / len ),
|
||
buttons = plugin(page, pages),
|
||
i, ien;
|
||
|
||
for ( i=0, ien=features.p.length ; i<ien ; i++ ) {
|
||
_fnRenderer( settings, 'pageButton' )(
|
||
settings, features.p[i], i, buttons, page, pages
|
||
);
|
||
}
|
||
}
|
||
else {
|
||
plugin.fnUpdate( settings, redraw );
|
||
}
|
||
},
|
||
"sName": "pagination"
|
||
} );
|
||
}
|
||
|
||
return node;
|
||
}
|
||
|
||
|
||
/**
|
||
* Alter the display settings to change the page
|
||
* @param {object} settings DataTables settings object
|
||
* @param {string|int} action Paging action to take: "first", "previous",
|
||
* "next" or "last" or page number to jump to (integer)
|
||
* @param [bool] redraw Automatically draw the update or not
|
||
* @returns {bool} true page has changed, false - no change
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnPageChange ( settings, action, redraw )
|
||
{
|
||
var
|
||
start = settings._iDisplayStart,
|
||
len = settings._iDisplayLength,
|
||
records = settings.fnRecordsDisplay();
|
||
|
||
if ( records === 0 || len === -1 )
|
||
{
|
||
start = 0;
|
||
}
|
||
else if ( typeof action === "number" )
|
||
{
|
||
start = action * len;
|
||
|
||
if ( start > records )
|
||
{
|
||
start = 0;
|
||
}
|
||
}
|
||
else if ( action == "first" )
|
||
{
|
||
start = 0;
|
||
}
|
||
else if ( action == "previous" )
|
||
{
|
||
start = len >= 0 ?
|
||
start - len :
|
||
0;
|
||
|
||
if ( start < 0 )
|
||
{
|
||
start = 0;
|
||
}
|
||
}
|
||
else if ( action == "next" )
|
||
{
|
||
if ( start + len < records )
|
||
{
|
||
start += len;
|
||
}
|
||
}
|
||
else if ( action == "last" )
|
||
{
|
||
start = Math.floor( (records-1) / len) * len;
|
||
}
|
||
else
|
||
{
|
||
_fnLog( settings, 0, "Unknown paging action: "+action, 5 );
|
||
}
|
||
|
||
var changed = settings._iDisplayStart !== start;
|
||
settings._iDisplayStart = start;
|
||
|
||
if ( changed ) {
|
||
_fnCallbackFire( settings, null, 'page', [settings] );
|
||
|
||
if ( redraw ) {
|
||
_fnDraw( settings );
|
||
}
|
||
}
|
||
|
||
return changed;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Generate the node required for the processing node
|
||
* @param {object} settings dataTables settings object
|
||
* @returns {node} Processing element
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlProcessing ( settings )
|
||
{
|
||
return $('<div/>', {
|
||
'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,
|
||
'class': settings.oClasses.sProcessing
|
||
} )
|
||
.html( settings.oLanguage.sProcessing )
|
||
.insertBefore( settings.nTable )[0];
|
||
}
|
||
|
||
|
||
/**
|
||
* Display or hide the processing indicator
|
||
* @param {object} settings dataTables settings object
|
||
* @param {bool} show Show the processing indicator (true) or not (false)
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnProcessingDisplay ( settings, show )
|
||
{
|
||
if ( settings.oFeatures.bProcessing ) {
|
||
$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );
|
||
}
|
||
|
||
_fnCallbackFire( settings, null, 'processing', [settings, show] );
|
||
}
|
||
|
||
/**
|
||
* Add any control elements for the table - specifically scrolling
|
||
* @param {object} settings dataTables settings object
|
||
* @returns {node} Node to add to the DOM
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnFeatureHtmlTable ( settings )
|
||
{
|
||
var table = $(settings.nTable);
|
||
|
||
// Add the ARIA grid role to the table
|
||
table.attr( 'role', 'grid' );
|
||
|
||
// Scrolling from here on in
|
||
var scroll = settings.oScroll;
|
||
|
||
if ( scroll.sX === '' && scroll.sY === '' ) {
|
||
return settings.nTable;
|
||
}
|
||
|
||
var scrollX = scroll.sX;
|
||
var scrollY = scroll.sY;
|
||
var classes = settings.oClasses;
|
||
var caption = table.children('caption');
|
||
var captionSide = caption.length ? caption[0]._captionSide : null;
|
||
var headerClone = $( table[0].cloneNode(false) );
|
||
var footerClone = $( table[0].cloneNode(false) );
|
||
var footer = table.children('tfoot');
|
||
var _div = '<div/>';
|
||
var size = function ( s ) {
|
||
return !s ? null : _fnStringToCss( s );
|
||
};
|
||
|
||
// This is fairly messy, but with x scrolling enabled, if the table has a
|
||
// width attribute, regardless of any width applied using the column width
|
||
// options, the browser will shrink or grow the table as needed to fit into
|
||
// that 100%. That would make the width options useless. So we remove it.
|
||
// This is okay, under the assumption that width:100% is applied to the
|
||
// table in CSS (it is in the default stylesheet) which will set the table
|
||
// width as appropriate (the attribute and css behave differently...)
|
||
if ( scroll.sX && table.attr('width') === '100%' ) {
|
||
table.removeAttr('width');
|
||
}
|
||
|
||
if ( ! footer.length ) {
|
||
footer = null;
|
||
}
|
||
|
||
/*
|
||
* The HTML structure that we want to generate in this function is:
|
||
* div - scroller
|
||
* div - scroll head
|
||
* div - scroll head inner
|
||
* table - scroll head table
|
||
* thead - thead
|
||
* div - scroll body
|
||
* table - table (master table)
|
||
* thead - thead clone for sizing
|
||
* tbody - tbody
|
||
* div - scroll foot
|
||
* div - scroll foot inner
|
||
* table - scroll foot table
|
||
* tfoot - tfoot
|
||
*/
|
||
var scroller = $( _div, { 'class': classes.sScrollWrapper } )
|
||
.append(
|
||
$(_div, { 'class': classes.sScrollHead } )
|
||
.css( {
|
||
overflow: 'hidden',
|
||
position: 'relative',
|
||
border: 0,
|
||
width: scrollX ? size(scrollX) : '100%'
|
||
} )
|
||
.append(
|
||
$(_div, { 'class': classes.sScrollHeadInner } )
|
||
.css( {
|
||
'box-sizing': 'content-box',
|
||
width: scroll.sXInner || '100%'
|
||
} )
|
||
.append(
|
||
headerClone
|
||
.removeAttr('id')
|
||
.css( 'margin-left', 0 )
|
||
.append(
|
||
table.children('thead')
|
||
)
|
||
)
|
||
)
|
||
.append( captionSide === 'top' ? caption : null )
|
||
)
|
||
.append(
|
||
$(_div, { 'class': classes.sScrollBody } )
|
||
.css( {
|
||
overflow: 'auto',
|
||
height: size( scrollY ),
|
||
width: size( scrollX )
|
||
} )
|
||
.append( table )
|
||
);
|
||
|
||
if ( footer ) {
|
||
scroller.append(
|
||
$(_div, { 'class': classes.sScrollFoot } )
|
||
.css( {
|
||
overflow: 'hidden',
|
||
border: 0,
|
||
width: scrollX ? size(scrollX) : '100%'
|
||
} )
|
||
.append(
|
||
$(_div, { 'class': classes.sScrollFootInner } )
|
||
.append(
|
||
footerClone
|
||
.removeAttr('id')
|
||
.css( 'margin-left', 0 )
|
||
.append(
|
||
table.children('tfoot')
|
||
)
|
||
)
|
||
)
|
||
.append( captionSide === 'bottom' ? caption : null )
|
||
);
|
||
}
|
||
|
||
var children = scroller.children();
|
||
var scrollHead = children[0];
|
||
var scrollBody = children[1];
|
||
var scrollFoot = footer ? children[2] : null;
|
||
|
||
// When the body is scrolled, then we also want to scroll the headers
|
||
if ( scrollX ) {
|
||
$(scrollBody).scroll( function (e) {
|
||
var scrollLeft = this.scrollLeft;
|
||
|
||
scrollHead.scrollLeft = scrollLeft;
|
||
|
||
if ( footer ) {
|
||
scrollFoot.scrollLeft = scrollLeft;
|
||
}
|
||
} );
|
||
}
|
||
|
||
settings.nScrollHead = scrollHead;
|
||
settings.nScrollBody = scrollBody;
|
||
settings.nScrollFoot = scrollFoot;
|
||
|
||
// On redraw - align columns
|
||
settings.aoDrawCallback.push( {
|
||
"fn": _fnScrollDraw,
|
||
"sName": "scrolling"
|
||
} );
|
||
|
||
return scroller[0];
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Update the header, footer and body tables for resizing - i.e. column
|
||
* alignment.
|
||
*
|
||
* Welcome to the most horrible function DataTables. The process that this
|
||
* function follows is basically:
|
||
* 1. Re-create the table inside the scrolling div
|
||
* 2. Take live measurements from the DOM
|
||
* 3. Apply the measurements to align the columns
|
||
* 4. Clean up
|
||
*
|
||
* @param {object} settings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnScrollDraw ( settings )
|
||
{
|
||
// Given that this is such a monster function, a lot of variables are use
|
||
// to try and keep the minimised size as small as possible
|
||
var
|
||
scroll = settings.oScroll,
|
||
scrollX = scroll.sX,
|
||
scrollXInner = scroll.sXInner,
|
||
scrollY = scroll.sY,
|
||
barWidth = scroll.iBarWidth,
|
||
divHeader = $(settings.nScrollHead),
|
||
divHeaderStyle = divHeader[0].style,
|
||
divHeaderInner = divHeader.children('div'),
|
||
divHeaderInnerStyle = divHeaderInner[0].style,
|
||
divHeaderTable = divHeaderInner.children('table'),
|
||
divBodyEl = settings.nScrollBody,
|
||
divBody = $(divBodyEl),
|
||
divBodyStyle = divBodyEl.style,
|
||
divFooter = $(settings.nScrollFoot),
|
||
divFooterInner = divFooter.children('div'),
|
||
divFooterTable = divFooterInner.children('table'),
|
||
header = $(settings.nTHead),
|
||
table = $(settings.nTable),
|
||
tableEl = table[0],
|
||
tableStyle = tableEl.style,
|
||
footer = settings.nTFoot ? $(settings.nTFoot) : null,
|
||
browser = settings.oBrowser,
|
||
ie67 = browser.bScrollOversize,
|
||
headerTrgEls, footerTrgEls,
|
||
headerSrcEls, footerSrcEls,
|
||
headerCopy, footerCopy,
|
||
headerWidths=[], footerWidths=[],
|
||
headerContent=[],
|
||
idx, correction, sanityWidth,
|
||
zeroOut = function(nSizer) {
|
||
var style = nSizer.style;
|
||
style.paddingTop = "0";
|
||
style.paddingBottom = "0";
|
||
style.borderTopWidth = "0";
|
||
style.borderBottomWidth = "0";
|
||
style.height = 0;
|
||
};
|
||
|
||
/*
|
||
* 1. Re-create the table inside the scrolling div
|
||
*/
|
||
|
||
// Remove the old minimised thead and tfoot elements in the inner table
|
||
table.children('thead, tfoot').remove();
|
||
|
||
// Clone the current header and footer elements and then place it into the inner table
|
||
headerCopy = header.clone().prependTo( table );
|
||
headerTrgEls = header.find('tr'); // original header is in its own table
|
||
headerSrcEls = headerCopy.find('tr');
|
||
headerCopy.find('th, td').removeAttr('tabindex');
|
||
|
||
if ( footer ) {
|
||
footerCopy = footer.clone().prependTo( table );
|
||
footerTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized
|
||
footerSrcEls = footerCopy.find('tr');
|
||
}
|
||
|
||
|
||
/*
|
||
* 2. Take live measurements from the DOM - do not alter the DOM itself!
|
||
*/
|
||
|
||
// Remove old sizing and apply the calculated column widths
|
||
// Get the unique column headers in the newly created (cloned) header. We want to apply the
|
||
// calculated sizes to this header
|
||
if ( ! scrollX )
|
||
{
|
||
divBodyStyle.width = '100%';
|
||
divHeader[0].style.width = '100%';
|
||
}
|
||
|
||
$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {
|
||
idx = _fnVisibleToColumnIndex( settings, i );
|
||
el.style.width = settings.aoColumns[idx].sWidth;
|
||
} );
|
||
|
||
if ( footer ) {
|
||
_fnApplyToChildren( function(n) {
|
||
n.style.width = "";
|
||
}, footerSrcEls );
|
||
}
|
||
|
||
// If scroll collapse is enabled, when we put the headers back into the body for sizing, we
|
||
// will end up forcing the scrollbar to appear, making our measurements wrong for when we
|
||
// then hide it (end of this function), so add the header height to the body scroller.
|
||
if ( scroll.bCollapse && scrollY !== "" ) {
|
||
divBodyStyle.height = (divBody[0].offsetHeight + header[0].offsetHeight)+"px";
|
||
}
|
||
|
||
// Size the table as a whole
|
||
sanityWidth = table.outerWidth();
|
||
if ( scrollX === "" ) {
|
||
// No x scrolling
|
||
tableStyle.width = "100%";
|
||
|
||
// IE7 will make the width of the table when 100% include the scrollbar
|
||
// - which is shouldn't. When there is a scrollbar we need to take this
|
||
// into account.
|
||
if ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||
|
||
divBody.css('overflow-y') == "scroll")
|
||
) {
|
||
tableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// x scrolling
|
||
if ( scrollXInner !== "" ) {
|
||
// x scroll inner has been given - use it
|
||
tableStyle.width = _fnStringToCss(scrollXInner);
|
||
}
|
||
else if ( sanityWidth == divBody.width() && divBody.height() < table.height() ) {
|
||
// There is y-scrolling - try to take account of the y scroll bar
|
||
tableStyle.width = _fnStringToCss( sanityWidth-barWidth );
|
||
if ( table.outerWidth() > sanityWidth-barWidth ) {
|
||
// Not possible to take account of it
|
||
tableStyle.width = _fnStringToCss( sanityWidth );
|
||
}
|
||
}
|
||
else {
|
||
// When all else fails
|
||
tableStyle.width = _fnStringToCss( sanityWidth );
|
||
}
|
||
}
|
||
|
||
// Recalculate the sanity width - now that we've applied the required width,
|
||
// before it was a temporary variable. This is required because the column
|
||
// width calculation is done before this table DOM is created.
|
||
sanityWidth = table.outerWidth();
|
||
|
||
// Hidden header should have zero height, so remove padding and borders. Then
|
||
// set the width based on the real headers
|
||
|
||
// Apply all styles in one pass
|
||
_fnApplyToChildren( zeroOut, headerSrcEls );
|
||
|
||
// Read all widths in next pass
|
||
_fnApplyToChildren( function(nSizer) {
|
||
headerContent.push( nSizer.innerHTML );
|
||
headerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
|
||
}, headerSrcEls );
|
||
|
||
// Apply all widths in final pass
|
||
_fnApplyToChildren( function(nToSize, i) {
|
||
nToSize.style.width = headerWidths[i];
|
||
}, headerTrgEls );
|
||
|
||
$(headerSrcEls).height(0);
|
||
|
||
/* Same again with the footer if we have one */
|
||
if ( footer )
|
||
{
|
||
_fnApplyToChildren( zeroOut, footerSrcEls );
|
||
|
||
_fnApplyToChildren( function(nSizer) {
|
||
footerWidths.push( _fnStringToCss( $(nSizer).css('width') ) );
|
||
}, footerSrcEls );
|
||
|
||
_fnApplyToChildren( function(nToSize, i) {
|
||
nToSize.style.width = footerWidths[i];
|
||
}, footerTrgEls );
|
||
|
||
$(footerSrcEls).height(0);
|
||
}
|
||
|
||
|
||
/*
|
||
* 3. Apply the measurements
|
||
*/
|
||
|
||
// "Hide" the header and footer that we used for the sizing. We need to keep
|
||
// the content of the cell so that the width applied to the header and body
|
||
// both match, but we want to hide it completely. We want to also fix their
|
||
// width to what they currently are
|
||
_fnApplyToChildren( function(nSizer, i) {
|
||
nSizer.innerHTML = '<div class="dataTables_sizing" style="height:0;overflow:hidden;">'+headerContent[i]+'</div>';
|
||
nSizer.style.width = headerWidths[i];
|
||
}, headerSrcEls );
|
||
|
||
if ( footer )
|
||
{
|
||
_fnApplyToChildren( function(nSizer, i) {
|
||
nSizer.innerHTML = "";
|
||
nSizer.style.width = footerWidths[i];
|
||
}, footerSrcEls );
|
||
}
|
||
|
||
// Sanity check that the table is of a sensible width. If not then we are going to get
|
||
// misalignment - try to prevent this by not allowing the table to shrink below its min width
|
||
if ( table.outerWidth() < sanityWidth )
|
||
{
|
||
// The min width depends upon if we have a vertical scrollbar visible or not */
|
||
correction = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||
|
||
divBody.css('overflow-y') == "scroll")) ?
|
||
sanityWidth+barWidth :
|
||
sanityWidth;
|
||
|
||
// IE6/7 are a law unto themselves...
|
||
if ( ie67 && (divBodyEl.scrollHeight >
|
||
divBodyEl.offsetHeight || divBody.css('overflow-y') == "scroll")
|
||
) {
|
||
tableStyle.width = _fnStringToCss( correction-barWidth );
|
||
}
|
||
|
||
// And give the user a warning that we've stopped the table getting too small
|
||
if ( scrollX === "" || scrollXInner !== "" ) {
|
||
_fnLog( settings, 1, 'Possible column misalignment', 6 );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
correction = '100%';
|
||
}
|
||
|
||
// Apply to the container elements
|
||
divBodyStyle.width = _fnStringToCss( correction );
|
||
divHeaderStyle.width = _fnStringToCss( correction );
|
||
|
||
if ( footer ) {
|
||
settings.nScrollFoot.style.width = _fnStringToCss( correction );
|
||
}
|
||
|
||
|
||
/*
|
||
* 4. Clean up
|
||
*/
|
||
if ( ! scrollY ) {
|
||
/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
|
||
* the scrollbar height from the visible display, rather than adding it on. We need to
|
||
* set the height in order to sort this. Don't want to do it in any other browsers.
|
||
*/
|
||
if ( ie67 ) {
|
||
divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );
|
||
}
|
||
}
|
||
|
||
if ( scrollY && scroll.bCollapse ) {
|
||
divBodyStyle.height = _fnStringToCss( scrollY );
|
||
|
||
var iExtra = (scrollX && tableEl.offsetWidth > divBodyEl.offsetWidth) ?
|
||
barWidth :
|
||
0;
|
||
|
||
if ( tableEl.offsetHeight < divBodyEl.offsetHeight ) {
|
||
divBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+iExtra );
|
||
}
|
||
}
|
||
|
||
/* Finally set the width's of the header and footer tables */
|
||
var iOuterWidth = table.outerWidth();
|
||
divHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );
|
||
divHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );
|
||
|
||
// Figure out if there are scrollbar present - if so then we need a the header and footer to
|
||
// provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar)
|
||
var bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == "scroll";
|
||
var padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );
|
||
divHeaderInnerStyle[ padding ] = bScrolling ? barWidth+"px" : "0px";
|
||
|
||
if ( footer ) {
|
||
divFooterTable[0].style.width = _fnStringToCss( iOuterWidth );
|
||
divFooterInner[0].style.width = _fnStringToCss( iOuterWidth );
|
||
divFooterInner[0].style[padding] = bScrolling ? barWidth+"px" : "0px";
|
||
}
|
||
|
||
/* Adjust the position of the header in case we loose the y-scrollbar */
|
||
divBody.scroll();
|
||
|
||
/* If sorting or filtering has occurred, jump the scrolling back to the top */
|
||
if ( settings.bSorted || settings.bFiltered ) {
|
||
divBodyEl.scrollTop = 0;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Apply a given function to the display child nodes of an element array (typically
|
||
* TD children of TR rows
|
||
* @param {function} fn Method to apply to the objects
|
||
* @param array {nodes} an1 List of elements to look through for display children
|
||
* @param array {nodes} an2 Another list (identical structure to the first) - optional
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnApplyToChildren( fn, an1, an2 )
|
||
{
|
||
var index=0, i=0, iLen=an1.length;
|
||
var nNode1, nNode2;
|
||
|
||
while ( i < iLen ) {
|
||
nNode1 = an1[i].firstChild;
|
||
nNode2 = an2 ? an2[i].firstChild : null;
|
||
|
||
while ( nNode1 ) {
|
||
if ( nNode1.nodeType === 1 ) {
|
||
if ( an2 ) {
|
||
fn( nNode1, nNode2, index );
|
||
}
|
||
else {
|
||
fn( nNode1, index );
|
||
}
|
||
|
||
index++;
|
||
}
|
||
|
||
nNode1 = nNode1.nextSibling;
|
||
nNode2 = an2 ? nNode2.nextSibling : null;
|
||
}
|
||
|
||
i++;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
var __re_html_remove = /<.*?>/g;
|
||
|
||
|
||
/**
|
||
* Calculate the width of columns for the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnCalculateColumnWidths ( oSettings )
|
||
{
|
||
var
|
||
table = oSettings.nTable,
|
||
columns = oSettings.aoColumns,
|
||
scroll = oSettings.oScroll,
|
||
scrollY = scroll.sY,
|
||
scrollX = scroll.sX,
|
||
scrollXInner = scroll.sXInner,
|
||
columnCount = columns.length,
|
||
visibleColumns = _fnGetColumns( oSettings, 'bVisible' ),
|
||
headerCells = $('th', oSettings.nTHead),
|
||
tableWidthAttr = table.getAttribute('width'),
|
||
tableContainer = table.parentNode,
|
||
userInputs = false,
|
||
i, column, columnIdx, width, outerWidth;
|
||
|
||
/* Convert any user input sizes into pixel sizes */
|
||
for ( i=0 ; i<visibleColumns.length ; i++ ) {
|
||
column = columns[ visibleColumns[i] ];
|
||
|
||
if ( column.sWidth !== null ) {
|
||
column.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );
|
||
|
||
userInputs = true;
|
||
}
|
||
}
|
||
|
||
/* If the number of columns in the DOM equals the number that we have to
|
||
* process in DataTables, then we can use the offsets that are created by
|
||
* the web- browser. No custom sizes can be set in order for this to happen,
|
||
* nor scrolling used
|
||
*/
|
||
if ( ! userInputs && ! scrollX && ! scrollY &&
|
||
columnCount == _fnVisbleColumns( oSettings ) &&
|
||
columnCount == headerCells.length
|
||
) {
|
||
for ( i=0 ; i<columnCount ; i++ ) {
|
||
columns[i].sWidth = _fnStringToCss( headerCells.eq(i).width() );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Otherwise construct a single row table with the widest node in the
|
||
// data, assign any user defined widths, then insert it into the DOM and
|
||
// allow the browser to do all the hard work of calculating table widths
|
||
var tmpTable = $( table.cloneNode( false ) )
|
||
.css( 'visibility', 'hidden' )
|
||
.removeAttr( 'id' )
|
||
.append( $(oSettings.nTHead).clone( false ) )
|
||
.append( $(oSettings.nTFoot).clone( false ) )
|
||
.append( $('<tbody><tr/></tbody>') );
|
||
|
||
// Remove any assigned widths from the footer (from scrolling)
|
||
tmpTable.find('tfoot th, tfoot td').css('width', '');
|
||
|
||
var tr = tmpTable.find( 'tbody tr' );
|
||
|
||
// Apply custom sizing to the cloned header
|
||
headerCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );
|
||
|
||
for ( i=0 ; i<visibleColumns.length ; i++ ) {
|
||
column = columns[ visibleColumns[i] ];
|
||
|
||
headerCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?
|
||
_fnStringToCss( column.sWidthOrig ) :
|
||
'';
|
||
}
|
||
|
||
// Find the widest cell for each column and put it into the table
|
||
if ( oSettings.aoData.length ) {
|
||
for ( i=0 ; i<visibleColumns.length ; i++ ) {
|
||
columnIdx = visibleColumns[i];
|
||
column = columns[ columnIdx ];
|
||
|
||
$( _fnGetWidestNode( oSettings, columnIdx ) )
|
||
.clone( false )
|
||
.append( column.sContentPadding )
|
||
.appendTo( tr );
|
||
}
|
||
}
|
||
|
||
// Table has been built, attach to the document so we can work with it
|
||
tmpTable.appendTo( tableContainer );
|
||
|
||
// When scrolling (X or Y) we want to set the width of the table as
|
||
// appropriate. However, when not scrolling leave the table width as it
|
||
// is. This results in slightly different, but I think correct behaviour
|
||
if ( scrollX && scrollXInner ) {
|
||
tmpTable.width( scrollXInner );
|
||
}
|
||
else if ( scrollX ) {
|
||
tmpTable.css( 'width', 'auto' );
|
||
|
||
if ( tmpTable.width() < tableContainer.offsetWidth ) {
|
||
tmpTable.width( tableContainer.offsetWidth );
|
||
}
|
||
}
|
||
else if ( scrollY ) {
|
||
tmpTable.width( tableContainer.offsetWidth );
|
||
}
|
||
else if ( tableWidthAttr ) {
|
||
tmpTable.width( tableWidthAttr );
|
||
}
|
||
|
||
// Take into account the y scrollbar
|
||
_fnScrollingWidthAdjust( oSettings, tmpTable[0] );
|
||
|
||
// Browsers need a bit of a hand when a width is assigned to any columns
|
||
// when x-scrolling as they tend to collapse the table to the min-width,
|
||
// even if we sent the column widths. So we need to keep track of what
|
||
// the table width should be by summing the user given values, and the
|
||
// automatic values
|
||
if ( scrollX )
|
||
{
|
||
var total = 0;
|
||
|
||
for ( i=0 ; i<visibleColumns.length ; i++ ) {
|
||
column = columns[ visibleColumns[i] ];
|
||
outerWidth = $(headerCells[i]).outerWidth();
|
||
|
||
total += column.sWidthOrig === null ?
|
||
outerWidth :
|
||
parseInt( column.sWidth, 10 ) + outerWidth - $(headerCells[i]).width();
|
||
}
|
||
|
||
tmpTable.width( _fnStringToCss( total ) );
|
||
table.style.width = _fnStringToCss( total );
|
||
}
|
||
|
||
// Get the width of each column in the constructed table
|
||
for ( i=0 ; i<visibleColumns.length ; i++ ) {
|
||
column = columns[ visibleColumns[i] ];
|
||
width = $(headerCells[i]).width();
|
||
|
||
if ( width ) {
|
||
column.sWidth = _fnStringToCss( width );
|
||
}
|
||
}
|
||
|
||
table.style.width = _fnStringToCss( tmpTable.css('width') );
|
||
|
||
// Finished with the table - ditch it
|
||
tmpTable.remove();
|
||
}
|
||
|
||
// If there is a width attr, we want to attach an event listener which
|
||
// allows the table sizing to automatically adjust when the window is
|
||
// resized. Use the width attr rather than CSS, since we can't know if the
|
||
// CSS is a relative value or absolute - DOM read is always px.
|
||
if ( tableWidthAttr ) {
|
||
table.style.width = _fnStringToCss( tableWidthAttr );
|
||
}
|
||
|
||
if ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {
|
||
$(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {
|
||
_fnAdjustColumnSizing( oSettings );
|
||
} ) );
|
||
|
||
oSettings._reszEvt = true;
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Throttle the calls to a function. Arguments and context are maintained for
|
||
* the throttled function
|
||
* @param {function} fn Function to be called
|
||
* @param {int} [freq=200] call frequency in mS
|
||
* @returns {function} wrapped function
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnThrottle( fn, freq ) {
|
||
var
|
||
frequency = freq || 200,
|
||
last,
|
||
timer;
|
||
|
||
return function () {
|
||
var
|
||
that = this,
|
||
now = +new Date(),
|
||
args = arguments;
|
||
|
||
if ( last && now < last + frequency ) {
|
||
clearTimeout( timer );
|
||
|
||
timer = setTimeout( function () {
|
||
last = undefined;
|
||
fn.apply( that, args );
|
||
}, frequency );
|
||
}
|
||
else if ( last ) {
|
||
last = now;
|
||
fn.apply( that, args );
|
||
}
|
||
else {
|
||
last = now;
|
||
}
|
||
};
|
||
}
|
||
|
||
|
||
/**
|
||
* Convert a CSS unit width to pixels (e.g. 2em)
|
||
* @param {string} width width to be converted
|
||
* @param {node} parent parent to get the with for (required for relative widths) - optional
|
||
* @returns {int} width in pixels
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnConvertToWidth ( width, parent )
|
||
{
|
||
if ( ! width ) {
|
||
return 0;
|
||
}
|
||
|
||
var n = $('<div/>')
|
||
.css( 'width', _fnStringToCss( width ) )
|
||
.appendTo( parent || document.body );
|
||
|
||
var val = n[0].offsetWidth;
|
||
n.remove();
|
||
|
||
return val;
|
||
}
|
||
|
||
|
||
/**
|
||
* Adjust a table's width to take account of vertical scroll bar
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {node} n table node
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
|
||
function _fnScrollingWidthAdjust ( settings, n )
|
||
{
|
||
var scroll = settings.oScroll;
|
||
|
||
if ( scroll.sX || scroll.sY ) {
|
||
// When y-scrolling only, we want to remove the width of the scroll bar
|
||
// so the table + scroll bar will fit into the area available, otherwise
|
||
// we fix the table at its current size with no adjustment
|
||
var correction = ! scroll.sX ? scroll.iBarWidth : 0;
|
||
n.style.width = _fnStringToCss( $(n).outerWidth() - correction );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the widest node
|
||
* @param {object} settings dataTables settings object
|
||
* @param {int} colIdx column of interest
|
||
* @returns {node} widest table node
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetWidestNode( settings, colIdx )
|
||
{
|
||
var idx = _fnGetMaxLenString( settings, colIdx );
|
||
if ( idx < 0 ) {
|
||
return null;
|
||
}
|
||
|
||
var data = settings.aoData[ idx ];
|
||
return ! data.nTr ? // Might not have been created when deferred rendering
|
||
$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :
|
||
data.anCells[ colIdx ];
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the maximum strlen for each data column
|
||
* @param {object} settings dataTables settings object
|
||
* @param {int} colIdx column of interest
|
||
* @returns {string} max string length for each column
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnGetMaxLenString( settings, colIdx )
|
||
{
|
||
var s, max=-1, maxIdx = -1;
|
||
|
||
for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||
s = _fnGetCellData( settings, i, colIdx, 'display' )+'';
|
||
s = s.replace( __re_html_remove, '' );
|
||
|
||
if ( s.length > max ) {
|
||
max = s.length;
|
||
maxIdx = i;
|
||
}
|
||
}
|
||
|
||
return maxIdx;
|
||
}
|
||
|
||
|
||
/**
|
||
* Append a CSS unit (only if required) to a string
|
||
* @param {string} value to css-ify
|
||
* @returns {string} value with css unit
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnStringToCss( s )
|
||
{
|
||
if ( s === null ) {
|
||
return '0px';
|
||
}
|
||
|
||
if ( typeof s == 'number' ) {
|
||
return s < 0 ?
|
||
'0px' :
|
||
s+'px';
|
||
}
|
||
|
||
// Check it has a unit character already
|
||
return s.match(/\d$/) ?
|
||
s+'px' :
|
||
s;
|
||
}
|
||
|
||
|
||
/**
|
||
* Get the width of a scroll bar in this browser being used
|
||
* @returns {int} width in pixels
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnScrollBarWidth ()
|
||
{
|
||
// On first run a static variable is set, since this is only needed once.
|
||
// Subsequent runs will just use the previously calculated value
|
||
if ( ! DataTable.__scrollbarWidth ) {
|
||
var inner = $('<p/>').css( {
|
||
width: '100%',
|
||
height: 200,
|
||
padding: 0
|
||
} )[0];
|
||
|
||
var outer = $('<div/>')
|
||
.css( {
|
||
position: 'absolute',
|
||
top: 0,
|
||
left: 0,
|
||
width: 200,
|
||
height: 150,
|
||
padding: 0,
|
||
overflow: 'hidden',
|
||
visibility: 'hidden'
|
||
} )
|
||
.append( inner )
|
||
.appendTo( 'body' );
|
||
|
||
var w1 = inner.offsetWidth;
|
||
outer.css( 'overflow', 'scroll' );
|
||
var w2 = inner.offsetWidth;
|
||
|
||
if ( w1 === w2 ) {
|
||
w2 = outer[0].clientWidth;
|
||
}
|
||
|
||
outer.remove();
|
||
|
||
DataTable.__scrollbarWidth = w1 - w2;
|
||
}
|
||
|
||
return DataTable.__scrollbarWidth;
|
||
}
|
||
|
||
|
||
|
||
function _fnSortFlatten ( settings )
|
||
{
|
||
var
|
||
i, iLen, k, kLen,
|
||
aSort = [],
|
||
aiOrig = [],
|
||
aoColumns = settings.aoColumns,
|
||
aDataSort, iCol, sType, srcCol,
|
||
fixed = settings.aaSortingFixed,
|
||
fixedObj = $.isPlainObject( fixed ),
|
||
nestedSort = [],
|
||
add = function ( a ) {
|
||
if ( a.length && ! $.isArray( a[0] ) ) {
|
||
// 1D array
|
||
nestedSort.push( a );
|
||
}
|
||
else {
|
||
// 2D array
|
||
nestedSort.push.apply( nestedSort, a );
|
||
}
|
||
};
|
||
|
||
// Build the sort array, with pre-fix and post-fix options if they have been
|
||
// specified
|
||
if ( $.isArray( fixed ) ) {
|
||
add( fixed );
|
||
}
|
||
|
||
if ( fixedObj && fixed.pre ) {
|
||
add( fixed.pre );
|
||
}
|
||
|
||
add( settings.aaSorting );
|
||
|
||
if (fixedObj && fixed.post ) {
|
||
add( fixed.post );
|
||
}
|
||
|
||
for ( i=0 ; i<nestedSort.length ; i++ )
|
||
{
|
||
srcCol = nestedSort[i][0];
|
||
aDataSort = aoColumns[ srcCol ].aDataSort;
|
||
|
||
for ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )
|
||
{
|
||
iCol = aDataSort[k];
|
||
sType = aoColumns[ iCol ].sType || 'string';
|
||
|
||
aSort.push( {
|
||
src: srcCol,
|
||
col: iCol,
|
||
dir: nestedSort[i][1],
|
||
index: nestedSort[i][2],
|
||
type: sType,
|
||
formatter: DataTable.ext.type.order[ sType+"-pre" ]
|
||
} );
|
||
}
|
||
}
|
||
|
||
return aSort;
|
||
}
|
||
|
||
/**
|
||
* Change the order of the table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
* @todo This really needs split up!
|
||
*/
|
||
function _fnSort ( oSettings )
|
||
{
|
||
var
|
||
i, ien, iLen, j, jLen, k, kLen,
|
||
sDataType, nTh,
|
||
aiOrig = [],
|
||
oExtSort = DataTable.ext.type.order,
|
||
aoData = oSettings.aoData,
|
||
aoColumns = oSettings.aoColumns,
|
||
aDataSort, data, iCol, sType, oSort,
|
||
formatters = 0,
|
||
sortCol,
|
||
displayMaster = oSettings.aiDisplayMaster,
|
||
aSort;
|
||
|
||
// Resolve any column types that are unknown due to addition or invalidation
|
||
// @todo Can this be moved into a 'data-ready' handler which is called when
|
||
// data is going to be used in the table?
|
||
_fnColumnTypes( oSettings );
|
||
|
||
aSort = _fnSortFlatten( oSettings );
|
||
|
||
for ( i=0, ien=aSort.length ; i<ien ; i++ ) {
|
||
sortCol = aSort[i];
|
||
|
||
// Track if we can use the fast sort algorithm
|
||
if ( sortCol.formatter ) {
|
||
formatters++;
|
||
}
|
||
|
||
// Load the data needed for the sort, for each cell
|
||
_fnSortData( oSettings, sortCol.col );
|
||
}
|
||
|
||
/* No sorting required if server-side or no sorting array */
|
||
if ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )
|
||
{
|
||
// Create a value - key array of the current row positions such that we can use their
|
||
// current position during the sort, if values match, in order to perform stable sorting
|
||
for ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {
|
||
aiOrig[ displayMaster[i] ] = i;
|
||
}
|
||
|
||
/* Do the sort - here we want multi-column sorting based on a given data source (column)
|
||
* and sorting function (from oSort) in a certain direction. It's reasonably complex to
|
||
* follow on it's own, but this is what we want (example two column sorting):
|
||
* fnLocalSorting = function(a,b){
|
||
* var iTest;
|
||
* iTest = oSort['string-asc']('data11', 'data12');
|
||
* if (iTest !== 0)
|
||
* return iTest;
|
||
* iTest = oSort['numeric-desc']('data21', 'data22');
|
||
* if (iTest !== 0)
|
||
* return iTest;
|
||
* return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );
|
||
* }
|
||
* Basically we have a test for each sorting column, if the data in that column is equal,
|
||
* test the next column. If all columns match, then we use a numeric sort on the row
|
||
* positions in the original data array to provide a stable sort.
|
||
*
|
||
* Note - I know it seems excessive to have two sorting methods, but the first is around
|
||
* 15% faster, so the second is only maintained for backwards compatibility with sorting
|
||
* methods which do not have a pre-sort formatting function.
|
||
*/
|
||
if ( formatters === aSort.length ) {
|
||
// All sort types have formatting functions
|
||
displayMaster.sort( function ( a, b ) {
|
||
var
|
||
x, y, k, test, sort,
|
||
len=aSort.length,
|
||
dataA = aoData[a]._aSortData,
|
||
dataB = aoData[b]._aSortData;
|
||
|
||
for ( k=0 ; k<len ; k++ ) {
|
||
sort = aSort[k];
|
||
|
||
x = dataA[ sort.col ];
|
||
y = dataB[ sort.col ];
|
||
|
||
test = x<y ? -1 : x>y ? 1 : 0;
|
||
if ( test !== 0 ) {
|
||
return sort.dir === 'asc' ? test : -test;
|
||
}
|
||
}
|
||
|
||
x = aiOrig[a];
|
||
y = aiOrig[b];
|
||
return x<y ? -1 : x>y ? 1 : 0;
|
||
} );
|
||
}
|
||
else {
|
||
// Depreciated - remove in 1.11 (providing a plug-in option)
|
||
// Not all sort types have formatting methods, so we have to call their sorting
|
||
// methods.
|
||
displayMaster.sort( function ( a, b ) {
|
||
var
|
||
x, y, k, l, test, sort, fn,
|
||
len=aSort.length,
|
||
dataA = aoData[a]._aSortData,
|
||
dataB = aoData[b]._aSortData;
|
||
|
||
for ( k=0 ; k<len ; k++ ) {
|
||
sort = aSort[k];
|
||
|
||
x = dataA[ sort.col ];
|
||
y = dataB[ sort.col ];
|
||
|
||
fn = oExtSort[ sort.type+"-"+sort.dir ] || oExtSort[ "string-"+sort.dir ];
|
||
test = fn( x, y );
|
||
if ( test !== 0 ) {
|
||
return test;
|
||
}
|
||
}
|
||
|
||
x = aiOrig[a];
|
||
y = aiOrig[b];
|
||
return x<y ? -1 : x>y ? 1 : 0;
|
||
} );
|
||
}
|
||
}
|
||
|
||
/* Tell the draw function that we have sorted the data */
|
||
oSettings.bSorted = true;
|
||
}
|
||
|
||
|
||
function _fnSortAria ( settings )
|
||
{
|
||
var label;
|
||
var nextSort;
|
||
var columns = settings.aoColumns;
|
||
var aSort = _fnSortFlatten( settings );
|
||
var oAria = settings.oLanguage.oAria;
|
||
|
||
// ARIA attributes - need to loop all columns, to update all (removing old
|
||
// attributes as needed)
|
||
for ( var i=0, iLen=columns.length ; i<iLen ; i++ )
|
||
{
|
||
var col = columns[i];
|
||
var asSorting = col.asSorting;
|
||
var sTitle = col.sTitle.replace( /<.*?>/g, "" );
|
||
var th = col.nTh;
|
||
|
||
// IE7 is throwing an error when setting these properties with jQuery's
|
||
// attr() and removeAttr() methods...
|
||
th.removeAttribute('aria-sort');
|
||
|
||
/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */
|
||
if ( col.bSortable ) {
|
||
if ( aSort.length > 0 && aSort[0].col == i ) {
|
||
th.setAttribute('aria-sort', aSort[0].dir=="asc" ? "ascending" : "descending" );
|
||
nextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];
|
||
}
|
||
else {
|
||
nextSort = asSorting[0];
|
||
}
|
||
|
||
label = sTitle + ( nextSort === "asc" ?
|
||
oAria.sSortAscending :
|
||
oAria.sSortDescending
|
||
);
|
||
}
|
||
else {
|
||
label = sTitle;
|
||
}
|
||
|
||
th.setAttribute('aria-label', label);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Function to run on user sort request
|
||
* @param {object} settings dataTables settings object
|
||
* @param {node} attachTo node to attach the handler to
|
||
* @param {int} colIdx column sorting index
|
||
* @param {boolean} [append=false] Append the requested sort to the existing
|
||
* sort if true (i.e. multi-column sort)
|
||
* @param {function} [callback] callback function
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSortListener ( settings, colIdx, append, callback )
|
||
{
|
||
var col = settings.aoColumns[ colIdx ];
|
||
var sorting = settings.aaSorting;
|
||
var asSorting = col.asSorting;
|
||
var nextSortIdx;
|
||
var next = function ( a ) {
|
||
var idx = a._idx;
|
||
if ( idx === undefined ) {
|
||
idx = $.inArray( a[1], asSorting );
|
||
}
|
||
|
||
return idx+1 >= asSorting.length ? 0 : idx+1;
|
||
};
|
||
|
||
// If appending the sort then we are multi-column sorting
|
||
if ( append && settings.oFeatures.bSortMulti ) {
|
||
// Are we already doing some kind of sort on this column?
|
||
var sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );
|
||
|
||
if ( sortIdx !== -1 ) {
|
||
// Yes, modify the sort
|
||
nextSortIdx = next( sorting[sortIdx] );
|
||
|
||
sorting[sortIdx][1] = asSorting[ nextSortIdx ];
|
||
sorting[sortIdx]._idx = nextSortIdx;
|
||
}
|
||
else {
|
||
// No sort on this column yet
|
||
sorting.push( [ colIdx, asSorting[0], 0 ] );
|
||
sorting[sorting.length-1]._idx = 0;
|
||
}
|
||
}
|
||
else if ( sorting.length && sorting[0][0] == colIdx ) {
|
||
// Single column - already sorting on this column, modify the sort
|
||
nextSortIdx = next( sorting[0] );
|
||
|
||
sorting.length = 1;
|
||
sorting[0][1] = asSorting[ nextSortIdx ];
|
||
sorting[0]._idx = nextSortIdx;
|
||
}
|
||
else {
|
||
// Single column - sort only on this column
|
||
sorting.length = 0;
|
||
sorting.push( [ colIdx, asSorting[0] ] );
|
||
sorting[0]._idx = 0;
|
||
}
|
||
|
||
// Run the sort by calling a full redraw
|
||
_fnReDraw( settings );
|
||
|
||
// callback used for async user interaction
|
||
if ( typeof callback == 'function' ) {
|
||
callback( settings );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Attach a sort handler (click) to a node
|
||
* @param {object} settings dataTables settings object
|
||
* @param {node} attachTo node to attach the handler to
|
||
* @param {int} colIdx column sorting index
|
||
* @param {function} [callback] callback function
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSortAttachListener ( settings, attachTo, colIdx, callback )
|
||
{
|
||
var col = settings.aoColumns[ colIdx ];
|
||
|
||
_fnBindAction( attachTo, {}, function (e) {
|
||
/* If the column is not sortable - don't to anything */
|
||
if ( col.bSortable === false ) {
|
||
return;
|
||
}
|
||
|
||
// If processing is enabled use a timeout to allow the processing
|
||
// display to be shown - otherwise to it synchronously
|
||
if ( settings.oFeatures.bProcessing ) {
|
||
_fnProcessingDisplay( settings, true );
|
||
|
||
setTimeout( function() {
|
||
_fnSortListener( settings, colIdx, e.shiftKey, callback );
|
||
|
||
// In server-side processing, the draw callback will remove the
|
||
// processing display
|
||
if ( _fnDataSource( settings ) !== 'ssp' ) {
|
||
_fnProcessingDisplay( settings, false );
|
||
}
|
||
}, 0 );
|
||
}
|
||
else {
|
||
_fnSortListener( settings, colIdx, e.shiftKey, callback );
|
||
}
|
||
} );
|
||
}
|
||
|
||
|
||
/**
|
||
* Set the sorting classes on table's body, Note: it is safe to call this function
|
||
* when bSort and bSortClasses are false
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSortingClasses( settings )
|
||
{
|
||
var oldSort = settings.aLastSort;
|
||
var sortClass = settings.oClasses.sSortColumn;
|
||
var sort = _fnSortFlatten( settings );
|
||
var features = settings.oFeatures;
|
||
var i, ien, colIdx;
|
||
|
||
if ( features.bSort && features.bSortClasses ) {
|
||
// Remove old sorting classes
|
||
for ( i=0, ien=oldSort.length ; i<ien ; i++ ) {
|
||
colIdx = oldSort[i].src;
|
||
|
||
// Remove column sorting
|
||
$( _pluck( settings.aoData, 'anCells', colIdx ) )
|
||
.removeClass( sortClass + (i<2 ? i+1 : 3) );
|
||
}
|
||
|
||
// Add new column sorting
|
||
for ( i=0, ien=sort.length ; i<ien ; i++ ) {
|
||
colIdx = sort[i].src;
|
||
|
||
$( _pluck( settings.aoData, 'anCells', colIdx ) )
|
||
.addClass( sortClass + (i<2 ? i+1 : 3) );
|
||
}
|
||
}
|
||
|
||
settings.aLastSort = sort;
|
||
}
|
||
|
||
|
||
// Get the data to sort a column, be it from cache, fresh (populating the
|
||
// cache), or from a sort formatter
|
||
function _fnSortData( settings, idx )
|
||
{
|
||
// Custom sorting function - provided by the sort data type
|
||
var column = settings.aoColumns[ idx ];
|
||
var customSort = DataTable.ext.order[ column.sSortDataType ];
|
||
var customData;
|
||
|
||
if ( customSort ) {
|
||
customData = customSort.call( settings.oInstance, settings, idx,
|
||
_fnColumnIndexToVisible( settings, idx )
|
||
);
|
||
}
|
||
|
||
// Use / populate cache
|
||
var row, cellData;
|
||
var formatter = DataTable.ext.type.order[ column.sType+"-pre" ];
|
||
|
||
for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||
row = settings.aoData[i];
|
||
|
||
if ( ! row._aSortData ) {
|
||
row._aSortData = [];
|
||
}
|
||
|
||
if ( ! row._aSortData[idx] || customSort ) {
|
||
cellData = customSort ?
|
||
customData[i] : // If there was a custom sort function, use data from there
|
||
_fnGetCellData( settings, i, idx, 'sort' );
|
||
|
||
row._aSortData[ idx ] = formatter ?
|
||
formatter( cellData ) :
|
||
cellData;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Save the state of a table
|
||
* @param {object} oSettings dataTables settings object
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSaveState ( oSettings )
|
||
{
|
||
if ( !oSettings.oFeatures.bStateSave || oSettings.bDestroying )
|
||
{
|
||
return;
|
||
}
|
||
|
||
/* Store the interesting variables */
|
||
var i, iLen;
|
||
var oState = {
|
||
"iCreate": +new Date(),
|
||
"iStart": oSettings._iDisplayStart,
|
||
"iLength": oSettings._iDisplayLength,
|
||
"aaSorting": $.extend( true, [], oSettings.aaSorting ),
|
||
"oSearch": $.extend( true, {}, oSettings.oPreviousSearch ),
|
||
"aoSearchCols": $.extend( true, [], oSettings.aoPreSearchCols ),
|
||
"abVisCols": _pluck( oSettings.aoColumns, 'bVisible' )
|
||
};
|
||
|
||
_fnCallbackFire( oSettings, "aoStateSaveParams", 'stateSaveParams', [oSettings, oState] );
|
||
|
||
oSettings.fnStateSaveCallback.call( oSettings.oInstance, oSettings, oState );
|
||
}
|
||
|
||
|
||
/**
|
||
* Attempt to load a saved table state
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {object} oInit DataTables init object so we can override settings
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnLoadState ( oSettings, oInit )
|
||
{
|
||
var i, ien;
|
||
var columns = oSettings.aoColumns;
|
||
|
||
if ( ! oSettings.oFeatures.bStateSave ) {
|
||
return;
|
||
}
|
||
|
||
var oData = oSettings.fnStateLoadCallback.call( oSettings.oInstance, oSettings );
|
||
if ( !oData ) {
|
||
return;
|
||
}
|
||
|
||
/* Allow custom and plug-in manipulation functions to alter the saved data set and
|
||
* cancelling of loading by returning false
|
||
*/
|
||
var abStateLoad = _fnCallbackFire( oSettings, 'aoStateLoadParams', 'stateLoadParams', [oSettings, oData] );
|
||
if ( $.inArray( false, abStateLoad ) !== -1 ) {
|
||
return;
|
||
}
|
||
|
||
/* Reject old data */
|
||
var duration = oSettings.iStateDuration;
|
||
if ( duration > 0 && oData.iCreate < +new Date() - (duration*1000) ) {
|
||
return;
|
||
}
|
||
|
||
// Number of columns have changed - all bets are off, no restore of settings
|
||
if ( columns.length !== oData.aoSearchCols.length ) {
|
||
return;
|
||
}
|
||
|
||
/* Store the saved state so it might be accessed at any time */
|
||
oSettings.oLoadedState = $.extend( true, {}, oData );
|
||
|
||
/* Restore key features */
|
||
oSettings._iDisplayStart = oData.iStart;
|
||
oSettings.iInitDisplayStart = oData.iStart;
|
||
oSettings._iDisplayLength = oData.iLength;
|
||
oSettings.aaSorting = $.map( oData.aaSorting, function ( col, i ) {
|
||
return col[0] >= columns.length ?
|
||
[ 0, col[1] ] :
|
||
col;
|
||
} );
|
||
|
||
/* Search filtering */
|
||
$.extend( oSettings.oPreviousSearch, oData.oSearch );
|
||
$.extend( true, oSettings.aoPreSearchCols, oData.aoSearchCols );
|
||
|
||
/* Column visibility state */
|
||
var visColumns = oData.abVisCols;
|
||
for ( i=0, ien=visColumns.length ; i<ien ; i++ ) {
|
||
columns[i].bVisible = visColumns[i];
|
||
}
|
||
|
||
_fnCallbackFire( oSettings, 'aoStateLoaded', 'stateLoaded', [oSettings, oData] );
|
||
}
|
||
|
||
|
||
/**
|
||
* Return the settings object for a particular table
|
||
* @param {node} table table we are using as a dataTable
|
||
* @returns {object} Settings object - or null if not found
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnSettingsFromNode ( table )
|
||
{
|
||
var settings = DataTable.settings;
|
||
var idx = $.inArray( table, _pluck( settings, 'nTable' ) );
|
||
|
||
return idx !== -1 ?
|
||
settings[ idx ] :
|
||
null;
|
||
}
|
||
|
||
|
||
/**
|
||
* Log an error message
|
||
* @param {object} settings dataTables settings object
|
||
* @param {int} level log error messages, or display them to the user
|
||
* @param {string} msg error message
|
||
* @param {int} tn Technical note id to get more information about the error.
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnLog( settings, level, msg, tn )
|
||
{
|
||
msg = 'DataTables warning: '+
|
||
(settings!==null ? 'table id='+settings.sTableId+' - ' : '')+msg;
|
||
|
||
if ( tn ) {
|
||
msg += '. For more information about this error, please see '+
|
||
'http://datatables.net/tn/'+tn;
|
||
}
|
||
|
||
if ( ! level ) {
|
||
// Backwards compatibility pre 1.10
|
||
var ext = DataTable.ext;
|
||
var type = ext.sErrMode || ext.errMode;
|
||
|
||
if ( type == 'alert' ) {
|
||
alert( msg );
|
||
}
|
||
else {
|
||
throw new Error(msg);
|
||
}
|
||
}
|
||
else if ( window.console && console.log ) {
|
||
console.log( msg );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* See if a property is defined on one object, if so assign it to the other object
|
||
* @param {object} ret target object
|
||
* @param {object} src source object
|
||
* @param {string} name property
|
||
* @param {string} [mappedName] name to map too - optional, name used if not given
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnMap( ret, src, name, mappedName )
|
||
{
|
||
if ( $.isArray( name ) ) {
|
||
$.each( name, function (i, val) {
|
||
if ( $.isArray( val ) ) {
|
||
_fnMap( ret, src, val[0], val[1] );
|
||
}
|
||
else {
|
||
_fnMap( ret, src, val );
|
||
}
|
||
} );
|
||
|
||
return;
|
||
}
|
||
|
||
if ( mappedName === undefined ) {
|
||
mappedName = name;
|
||
}
|
||
|
||
if ( src[name] !== undefined ) {
|
||
ret[mappedName] = src[name];
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Extend objects - very similar to jQuery.extend, but deep copy objects, and
|
||
* shallow copy arrays. The reason we need to do this, is that we don't want to
|
||
* deep copy array init values (such as aaSorting) since the dev wouldn't be
|
||
* able to override them, but we do want to deep copy arrays.
|
||
* @param {object} out Object to extend
|
||
* @param {object} extender Object from which the properties will be applied to
|
||
* out
|
||
* @param {boolean} breakRefs If true, then arrays will be sliced to take an
|
||
* independent copy with the exception of the `data` or `aaData` parameters
|
||
* if they are present. This is so you can pass in a collection to
|
||
* DataTables and have that used as your data source without breaking the
|
||
* references
|
||
* @returns {object} out Reference, just for convenience - out === the return.
|
||
* @memberof DataTable#oApi
|
||
* @todo This doesn't take account of arrays inside the deep copied objects.
|
||
*/
|
||
function _fnExtend( out, extender, breakRefs )
|
||
{
|
||
var val;
|
||
|
||
for ( var prop in extender ) {
|
||
if ( extender.hasOwnProperty(prop) ) {
|
||
val = extender[prop];
|
||
|
||
if ( $.isPlainObject( val ) ) {
|
||
if ( ! $.isPlainObject( out[prop] ) ) {
|
||
out[prop] = {};
|
||
}
|
||
$.extend( true, out[prop], val );
|
||
}
|
||
else if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {
|
||
out[prop] = val.slice();
|
||
}
|
||
else {
|
||
out[prop] = val;
|
||
}
|
||
}
|
||
}
|
||
|
||
return out;
|
||
}
|
||
|
||
|
||
/**
|
||
* Bind an event handers to allow a click or return key to activate the callback.
|
||
* This is good for accessibility since a return on the keyboard will have the
|
||
* same effect as a click, if the element has focus.
|
||
* @param {element} n Element to bind the action to
|
||
* @param {object} oData Data object to pass to the triggered function
|
||
* @param {function} fn Callback function for when the event is triggered
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnBindAction( n, oData, fn )
|
||
{
|
||
$(n)
|
||
.bind( 'click.DT', oData, function (e) {
|
||
n.blur(); // Remove focus outline for mouse users
|
||
fn(e);
|
||
} )
|
||
.bind( 'keypress.DT', oData, function (e){
|
||
if ( e.which === 13 ) {
|
||
e.preventDefault();
|
||
fn(e);
|
||
}
|
||
} )
|
||
.bind( 'selectstart.DT', function () {
|
||
/* Take the brutal approach to cancelling text selection */
|
||
return false;
|
||
} );
|
||
}
|
||
|
||
|
||
/**
|
||
* Register a callback function. Easily allows a callback function to be added to
|
||
* an array store of callback functions that can then all be called together.
|
||
* @param {object} oSettings dataTables settings object
|
||
* @param {string} sStore Name of the array storage for the callbacks in oSettings
|
||
* @param {function} fn Function to be called back
|
||
* @param {string} sName Identifying name for the callback (i.e. a label)
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnCallbackReg( oSettings, sStore, fn, sName )
|
||
{
|
||
if ( fn )
|
||
{
|
||
oSettings[sStore].push( {
|
||
"fn": fn,
|
||
"sName": sName
|
||
} );
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* Fire callback functions and trigger events. Note that the loop over the
|
||
* callback array store is done backwards! Further note that you do not want to
|
||
* fire off triggers in time sensitive applications (for example cell creation)
|
||
* as its slow.
|
||
* @param {object} settings dataTables settings object
|
||
* @param {string} callbackArr Name of the array storage for the callbacks in
|
||
* oSettings
|
||
* @param {string} event Name of the jQuery custom event to trigger. If null no
|
||
* trigger is fired
|
||
* @param {array} args Array of arguments to pass to the callback function /
|
||
* trigger
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnCallbackFire( settings, callbackArr, event, args )
|
||
{
|
||
var ret = [];
|
||
|
||
if ( callbackArr ) {
|
||
ret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {
|
||
return val.fn.apply( settings.oInstance, args );
|
||
} );
|
||
}
|
||
|
||
if ( event !== null ) {
|
||
$(settings.nTable).trigger( event+'.dt', args );
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
|
||
function _fnLengthOverflow ( settings )
|
||
{
|
||
var
|
||
start = settings._iDisplayStart,
|
||
end = settings.fnDisplayEnd(),
|
||
len = settings._iDisplayLength;
|
||
|
||
/* If we have space to show extra rows (backing up from the end point - then do so */
|
||
if ( end === settings.fnRecordsDisplay() )
|
||
{
|
||
start = end - len;
|
||
}
|
||
|
||
if ( len === -1 || start < 0 )
|
||
{
|
||
start = 0;
|
||
}
|
||
|
||
settings._iDisplayStart = start;
|
||
}
|
||
|
||
|
||
function _fnRenderer( settings, type )
|
||
{
|
||
var renderer = settings.renderer;
|
||
var host = DataTable.ext.renderer[type];
|
||
|
||
if ( $.isPlainObject( renderer ) && renderer[type] ) {
|
||
// Specific renderer for this type. If available use it, otherwise use
|
||
// the default.
|
||
return host[renderer[type]] || host._;
|
||
}
|
||
else if ( typeof renderer === 'string' ) {
|
||
// Common renderer - if there is one available for this type use it,
|
||
// otherwise use the default
|
||
return host[renderer] || host._;
|
||
}
|
||
|
||
// Use the default
|
||
return host._;
|
||
}
|
||
|
||
|
||
/**
|
||
* Detect the data source being used for the table. Used to simplify the code
|
||
* a little (ajax) and to make it compress a little smaller.
|
||
*
|
||
* @param {object} settings dataTables settings object
|
||
* @returns {string} Data source
|
||
* @memberof DataTable#oApi
|
||
*/
|
||
function _fnDataSource ( settings )
|
||
{
|
||
if ( settings.oFeatures.bServerSide ) {
|
||
return 'ssp';
|
||
}
|
||
else if ( settings.ajax || settings.sAjaxSource ) {
|
||
return 'ajax';
|
||
}
|
||
return 'dom';
|
||
}
|
||
|
||
|
||
DataTable = function( options )
|
||
{
|
||
/**
|
||
* Perform a jQuery selector action on the table's TR elements (from the tbody) and
|
||
* return the resulting jQuery object.
|
||
* @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
|
||
* @param {object} [oOpts] Optional parameters for modifying the rows to be included
|
||
* @param {string} [oOpts.filter=none] Select TR elements that meet the current filter
|
||
* criterion ("applied") or all TR elements (i.e. no filter).
|
||
* @param {string} [oOpts.order=current] Order of the TR elements in the processed array.
|
||
* Can be either 'current', whereby the current sorting of the table is used, or
|
||
* 'original' whereby the original order the data was read into the table is used.
|
||
* @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
|
||
* ("current") or not ("all"). If 'current' is given, then order is assumed to be
|
||
* 'current' and filter is 'applied', regardless of what they might be given as.
|
||
* @returns {object} jQuery object, filtered by the given selector.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Highlight every second row
|
||
* oTable.$('tr:odd').css('backgroundColor', 'blue');
|
||
* } );
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Filter to rows with 'Webkit' in them, add a background colour and then
|
||
* // remove the filter, thus highlighting the 'Webkit' rows only.
|
||
* oTable.fnFilter('Webkit');
|
||
* oTable.$('tr', {"search": "applied"}).css('backgroundColor', 'blue');
|
||
* oTable.fnFilter('');
|
||
* } );
|
||
*/
|
||
this.$ = function ( sSelector, oOpts )
|
||
{
|
||
return this.api(true).$( sSelector, oOpts );
|
||
};
|
||
|
||
|
||
/**
|
||
* Almost identical to $ in operation, but in this case returns the data for the matched
|
||
* rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes
|
||
* rather than any descendants, so the data can be obtained for the row/cell. If matching
|
||
* rows are found, the data returned is the original data array/object that was used to
|
||
* create the row (or a generated array if from a DOM source).
|
||
*
|
||
* This method is often useful in-combination with $ where both functions are given the
|
||
* same parameters and the array indexes will match identically.
|
||
* @param {string|node|jQuery} sSelector jQuery selector or node collection to act on
|
||
* @param {object} [oOpts] Optional parameters for modifying the rows to be included
|
||
* @param {string} [oOpts.filter=none] Select elements that meet the current filter
|
||
* criterion ("applied") or all elements (i.e. no filter).
|
||
* @param {string} [oOpts.order=current] Order of the data in the processed array.
|
||
* Can be either 'current', whereby the current sorting of the table is used, or
|
||
* 'original' whereby the original order the data was read into the table is used.
|
||
* @param {string} [oOpts.page=all] Limit the selection to the currently displayed page
|
||
* ("current") or not ("all"). If 'current' is given, then order is assumed to be
|
||
* 'current' and filter is 'applied', regardless of what they might be given as.
|
||
* @returns {array} Data for the matched elements. If any elements, as a result of the
|
||
* selector, were not TR, TD or TH elements in the DataTable, they will have a null
|
||
* entry in the array.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Get the data from the first row in the table
|
||
* var data = oTable._('tr:first');
|
||
*
|
||
* // Do something useful with the data
|
||
* alert( "First cell is: "+data[0] );
|
||
* } );
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Filter to 'Webkit' and get all data for
|
||
* oTable.fnFilter('Webkit');
|
||
* var data = oTable._('tr', {"search": "applied"});
|
||
*
|
||
* // Do something with the data
|
||
* alert( data.length+" rows matched the search" );
|
||
* } );
|
||
*/
|
||
this._ = function ( sSelector, oOpts )
|
||
{
|
||
return this.api(true).rows( sSelector, oOpts ).data();
|
||
};
|
||
|
||
|
||
/**
|
||
* Create a DataTables Api instance, with the currently selected tables for
|
||
* the Api's context.
|
||
* @param {boolean} [traditional=false] Set the API instance's context to be
|
||
* only the table referred to by the `DataTable.ext.iApiIndex` option, as was
|
||
* used in the API presented by DataTables 1.9- (i.e. the traditional mode),
|
||
* or if all tables captured in the jQuery object should be used.
|
||
* @return {DataTables.Api}
|
||
*/
|
||
this.api = function ( traditional )
|
||
{
|
||
return traditional ?
|
||
new _Api(
|
||
_fnSettingsFromNode( this[ _ext.iApiIndex ] )
|
||
) :
|
||
new _Api( this );
|
||
};
|
||
|
||
|
||
/**
|
||
* Add a single new row or multiple rows of data to the table. Please note
|
||
* that this is suitable for client-side processing only - if you are using
|
||
* server-side processing (i.e. "bServerSide": true), then to add data, you
|
||
* must add it to the data source, i.e. the server-side, through an Ajax call.
|
||
* @param {array|object} data The data to be added to the table. This can be:
|
||
* <ul>
|
||
* <li>1D array of data - add a single row with the data provided</li>
|
||
* <li>2D array of arrays - add multiple rows in a single call</li>
|
||
* <li>object - data object when using <i>mData</i></li>
|
||
* <li>array of objects - multiple data objects when using <i>mData</i></li>
|
||
* </ul>
|
||
* @param {bool} [redraw=true] redraw the table or not
|
||
* @returns {array} An array of integers, representing the list of indexes in
|
||
* <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to
|
||
* the table.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* // Global var for counter
|
||
* var giCount = 2;
|
||
*
|
||
* $(document).ready(function() {
|
||
* $('#example').dataTable();
|
||
* } );
|
||
*
|
||
* function fnClickAddRow() {
|
||
* $('#example').dataTable().fnAddData( [
|
||
* giCount+".1",
|
||
* giCount+".2",
|
||
* giCount+".3",
|
||
* giCount+".4" ]
|
||
* );
|
||
*
|
||
* giCount++;
|
||
* }
|
||
*/
|
||
this.fnAddData = function( data, redraw )
|
||
{
|
||
var api = this.api( true );
|
||
|
||
/* Check if we want to add multiple rows or not */
|
||
var rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?
|
||
api.rows.add( data ) :
|
||
api.row.add( data );
|
||
|
||
if ( redraw === undefined || redraw ) {
|
||
api.draw();
|
||
}
|
||
|
||
return rows.flatten().toArray();
|
||
};
|
||
|
||
|
||
/**
|
||
* This function will make DataTables recalculate the column sizes, based on the data
|
||
* contained in the table and the sizes applied to the columns (in the DOM, CSS or
|
||
* through the sWidth parameter). This can be useful when the width of the table's
|
||
* parent element changes (for example a window resize).
|
||
* @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable( {
|
||
* "sScrollY": "200px",
|
||
* "bPaginate": false
|
||
* } );
|
||
*
|
||
* $(window).bind('resize', function () {
|
||
* oTable.fnAdjustColumnSizing();
|
||
* } );
|
||
* } );
|
||
*/
|
||
this.fnAdjustColumnSizing = function ( bRedraw )
|
||
{
|
||
var api = this.api( true ).columns.adjust();
|
||
var settings = api.settings()[0];
|
||
var scroll = settings.oScroll;
|
||
|
||
if ( bRedraw === undefined || bRedraw ) {
|
||
api.draw( false );
|
||
}
|
||
else if ( scroll.sX !== "" || scroll.sY !== "" ) {
|
||
/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */
|
||
_fnScrollDraw( settings );
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Quickly and simply clear a table
|
||
* @param {bool} [bRedraw=true] redraw the table or not
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)
|
||
* oTable.fnClearTable();
|
||
* } );
|
||
*/
|
||
this.fnClearTable = function( bRedraw )
|
||
{
|
||
var api = this.api( true ).clear();
|
||
|
||
if ( bRedraw === undefined || bRedraw ) {
|
||
api.draw();
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* The exact opposite of 'opening' a row, this function will close any rows which
|
||
* are currently 'open'.
|
||
* @param {node} nTr the table row to 'close'
|
||
* @returns {int} 0 on success, or 1 if failed (can't find the row)
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable;
|
||
*
|
||
* // 'open' an information row when a row is clicked on
|
||
* $('#example tbody tr').click( function () {
|
||
* if ( oTable.fnIsOpen(this) ) {
|
||
* oTable.fnClose( this );
|
||
* } else {
|
||
* oTable.fnOpen( this, "Temporary row opened", "info_row" );
|
||
* }
|
||
* } );
|
||
*
|
||
* oTable = $('#example').dataTable();
|
||
* } );
|
||
*/
|
||
this.fnClose = function( nTr )
|
||
{
|
||
this.api( true ).row( nTr ).child.hide();
|
||
};
|
||
|
||
|
||
/**
|
||
* Remove a row for the table
|
||
* @param {mixed} target The index of the row from aoData to be deleted, or
|
||
* the TR element you want to delete
|
||
* @param {function|null} [callBack] Callback function
|
||
* @param {bool} [redraw=true] Redraw the table or not
|
||
* @returns {array} The row that was deleted
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Immediately remove the first row
|
||
* oTable.fnDeleteRow( 0 );
|
||
* } );
|
||
*/
|
||
this.fnDeleteRow = function( target, callback, redraw )
|
||
{
|
||
var api = this.api( true );
|
||
var rows = api.rows( target );
|
||
var settings = rows.settings()[0];
|
||
var data = settings.aoData[ rows[0][0] ];
|
||
|
||
rows.remove();
|
||
|
||
if ( callback ) {
|
||
callback.call( this, settings, data );
|
||
}
|
||
|
||
if ( redraw === undefined || redraw ) {
|
||
api.draw();
|
||
}
|
||
|
||
return data;
|
||
};
|
||
|
||
|
||
/**
|
||
* Restore the table to it's original state in the DOM by removing all of DataTables
|
||
* enhancements, alterations to the DOM structure of the table and event listeners.
|
||
* @param {boolean} [remove=false] Completely remove the table from the DOM
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* // This example is fairly pointless in reality, but shows how fnDestroy can be used
|
||
* var oTable = $('#example').dataTable();
|
||
* oTable.fnDestroy();
|
||
* } );
|
||
*/
|
||
this.fnDestroy = function ( remove )
|
||
{
|
||
this.api( true ).destroy( remove );
|
||
};
|
||
|
||
|
||
/**
|
||
* Redraw the table
|
||
* @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Re-draw the table - you wouldn't want to do it here, but it's an example :-)
|
||
* oTable.fnDraw();
|
||
* } );
|
||
*/
|
||
this.fnDraw = function( complete )
|
||
{
|
||
// Note that this isn't an exact match to the old call to _fnDraw - it takes
|
||
// into account the new data, but can old position.
|
||
this.api( true ).draw( ! complete );
|
||
};
|
||
|
||
|
||
/**
|
||
* Filter the input based on data
|
||
* @param {string} sInput String to filter the table on
|
||
* @param {int|null} [iColumn] Column to limit filtering to
|
||
* @param {bool} [bRegex=false] Treat as regular expression or not
|
||
* @param {bool} [bSmart=true] Perform smart filtering or not
|
||
* @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)
|
||
* @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Sometime later - filter...
|
||
* oTable.fnFilter( 'test string' );
|
||
* } );
|
||
*/
|
||
this.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )
|
||
{
|
||
var api = this.api( true );
|
||
|
||
if ( iColumn === null || iColumn === undefined ) {
|
||
api.search( sInput, bRegex, bSmart, bCaseInsensitive );
|
||
}
|
||
else {
|
||
api.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );
|
||
}
|
||
|
||
api.draw();
|
||
};
|
||
|
||
|
||
/**
|
||
* Get the data for the whole table, an individual row or an individual cell based on the
|
||
* provided parameters.
|
||
* @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as
|
||
* a TR node then the data source for the whole row will be returned. If given as a
|
||
* TD/TH cell node then iCol will be automatically calculated and the data for the
|
||
* cell returned. If given as an integer, then this is treated as the aoData internal
|
||
* data index for the row (see fnGetPosition) and the data for that row used.
|
||
* @param {int} [col] Optional column index that you want the data of.
|
||
* @returns {array|object|string} If mRow is undefined, then the data for all rows is
|
||
* returned. If mRow is defined, just data for that row, and is iCol is
|
||
* defined, only data for the designated cell is returned.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* // Row data
|
||
* $(document).ready(function() {
|
||
* oTable = $('#example').dataTable();
|
||
*
|
||
* oTable.$('tr').click( function () {
|
||
* var data = oTable.fnGetData( this );
|
||
* // ... do something with the array / object of data for the row
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Individual cell data
|
||
* $(document).ready(function() {
|
||
* oTable = $('#example').dataTable();
|
||
*
|
||
* oTable.$('td').click( function () {
|
||
* var sData = oTable.fnGetData( this );
|
||
* alert( 'The cell clicked on had the value of '+sData );
|
||
* } );
|
||
* } );
|
||
*/
|
||
this.fnGetData = function( src, col )
|
||
{
|
||
var api = this.api( true );
|
||
|
||
if ( src !== undefined ) {
|
||
var type = src.nodeName ? src.nodeName.toLowerCase() : '';
|
||
|
||
return col !== undefined || type == 'td' || type == 'th' ?
|
||
api.cell( src, col ).data() :
|
||
api.row( src ).data() || null;
|
||
}
|
||
|
||
return api.data().toArray();
|
||
};
|
||
|
||
|
||
/**
|
||
* Get an array of the TR nodes that are used in the table's body. Note that you will
|
||
* typically want to use the '$' API method in preference to this as it is more
|
||
* flexible.
|
||
* @param {int} [iRow] Optional row index for the TR element you want
|
||
* @returns {array|node} If iRow is undefined, returns an array of all TR elements
|
||
* in the table's body, or iRow is defined, just the TR element requested.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Get the nodes from the table
|
||
* var nNodes = oTable.fnGetNodes( );
|
||
* } );
|
||
*/
|
||
this.fnGetNodes = function( iRow )
|
||
{
|
||
var api = this.api( true );
|
||
|
||
return iRow !== undefined ?
|
||
api.row( iRow ).node() :
|
||
api.rows().nodes().flatten().toArray();
|
||
};
|
||
|
||
|
||
/**
|
||
* Get the array indexes of a particular cell from it's DOM element
|
||
* and column index including hidden columns
|
||
* @param {node} node this can either be a TR, TD or TH in the table's body
|
||
* @returns {int} If nNode is given as a TR, then a single index is returned, or
|
||
* if given as a cell, an array of [row index, column index (visible),
|
||
* column index (all)] is given.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* $('#example tbody td').click( function () {
|
||
* // Get the position of the current data from the node
|
||
* var aPos = oTable.fnGetPosition( this );
|
||
*
|
||
* // Get the data array for this row
|
||
* var aData = oTable.fnGetData( aPos[0] );
|
||
*
|
||
* // Update the data array and return the value
|
||
* aData[ aPos[1] ] = 'clicked';
|
||
* this.innerHTML = 'clicked';
|
||
* } );
|
||
*
|
||
* // Init DataTables
|
||
* oTable = $('#example').dataTable();
|
||
* } );
|
||
*/
|
||
this.fnGetPosition = function( node )
|
||
{
|
||
var api = this.api( true );
|
||
var nodeName = node.nodeName.toUpperCase();
|
||
|
||
if ( nodeName == 'TR' ) {
|
||
return api.row( node ).index();
|
||
}
|
||
else if ( nodeName == 'TD' || nodeName == 'TH' ) {
|
||
var cell = api.cell( node ).index();
|
||
|
||
return [
|
||
cell.row,
|
||
cell.columnVisible,
|
||
cell.column
|
||
];
|
||
}
|
||
return null;
|
||
};
|
||
|
||
|
||
/**
|
||
* Check to see if a row is 'open' or not.
|
||
* @param {node} nTr the table row to check
|
||
* @returns {boolean} true if the row is currently open, false otherwise
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable;
|
||
*
|
||
* // 'open' an information row when a row is clicked on
|
||
* $('#example tbody tr').click( function () {
|
||
* if ( oTable.fnIsOpen(this) ) {
|
||
* oTable.fnClose( this );
|
||
* } else {
|
||
* oTable.fnOpen( this, "Temporary row opened", "info_row" );
|
||
* }
|
||
* } );
|
||
*
|
||
* oTable = $('#example').dataTable();
|
||
* } );
|
||
*/
|
||
this.fnIsOpen = function( nTr )
|
||
{
|
||
return this.api( true ).row( nTr ).child.isShown();
|
||
};
|
||
|
||
|
||
/**
|
||
* This function will place a new row directly after a row which is currently
|
||
* on display on the page, with the HTML contents that is passed into the
|
||
* function. This can be used, for example, to ask for confirmation that a
|
||
* particular record should be deleted.
|
||
* @param {node} nTr The table row to 'open'
|
||
* @param {string|node|jQuery} mHtml The HTML to put into the row
|
||
* @param {string} sClass Class to give the new TD cell
|
||
* @returns {node} The row opened. Note that if the table row passed in as the
|
||
* first parameter, is not found in the table, this method will silently
|
||
* return.
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable;
|
||
*
|
||
* // 'open' an information row when a row is clicked on
|
||
* $('#example tbody tr').click( function () {
|
||
* if ( oTable.fnIsOpen(this) ) {
|
||
* oTable.fnClose( this );
|
||
* } else {
|
||
* oTable.fnOpen( this, "Temporary row opened", "info_row" );
|
||
* }
|
||
* } );
|
||
*
|
||
* oTable = $('#example').dataTable();
|
||
* } );
|
||
*/
|
||
this.fnOpen = function( nTr, mHtml, sClass )
|
||
{
|
||
return this.api( true )
|
||
.row( nTr )
|
||
.child( mHtml, sClass )
|
||
.show()
|
||
.child()[0];
|
||
};
|
||
|
||
|
||
/**
|
||
* Change the pagination - provides the internal logic for pagination in a simple API
|
||
* function. With this function you can have a DataTables table go to the next,
|
||
* previous, first or last pages.
|
||
* @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
|
||
* or page number to jump to (integer), note that page 0 is the first page.
|
||
* @param {bool} [bRedraw=true] Redraw the table or not
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
* oTable.fnPageChange( 'next' );
|
||
* } );
|
||
*/
|
||
this.fnPageChange = function ( mAction, bRedraw )
|
||
{
|
||
var api = this.api( true ).page( mAction );
|
||
|
||
if ( bRedraw === undefined || bRedraw ) {
|
||
api.draw(false);
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Show a particular column
|
||
* @param {int} iCol The column whose display should be changed
|
||
* @param {bool} bShow Show (true) or hide (false) the column
|
||
* @param {bool} [bRedraw=true] Redraw the table or not
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Hide the second column after initialisation
|
||
* oTable.fnSetColumnVis( 1, false );
|
||
* } );
|
||
*/
|
||
this.fnSetColumnVis = function ( iCol, bShow, bRedraw )
|
||
{
|
||
var api = this.api( true ).column( iCol ).visible( bShow );
|
||
|
||
if ( bRedraw === undefined || bRedraw ) {
|
||
api.columns.adjust().draw();
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Get the settings for a particular table for external manipulation
|
||
* @returns {object} DataTables settings object. See
|
||
* {@link DataTable.models.oSettings}
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
* var oSettings = oTable.fnSettings();
|
||
*
|
||
* // Show an example parameter from the settings
|
||
* alert( oSettings._iDisplayStart );
|
||
* } );
|
||
*/
|
||
this.fnSettings = function()
|
||
{
|
||
return _fnSettingsFromNode( this[_ext.iApiIndex] );
|
||
};
|
||
|
||
|
||
/**
|
||
* Sort the table by a particular column
|
||
* @param {int} iCol the data index to sort on. Note that this will not match the
|
||
* 'display index' if you have hidden data entries
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Sort immediately with columns 0 and 1
|
||
* oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );
|
||
* } );
|
||
*/
|
||
this.fnSort = function( aaSort )
|
||
{
|
||
this.api( true ).order( aaSort ).draw();
|
||
};
|
||
|
||
|
||
/**
|
||
* Attach a sort listener to an element for a given column
|
||
* @param {node} nNode the element to attach the sort listener to
|
||
* @param {int} iColumn the column that a click on this node will sort on
|
||
* @param {function} [fnCallback] callback function when sort is run
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
*
|
||
* // Sort on column 1, when 'sorter' is clicked on
|
||
* oTable.fnSortListener( document.getElementById('sorter'), 1 );
|
||
* } );
|
||
*/
|
||
this.fnSortListener = function( nNode, iColumn, fnCallback )
|
||
{
|
||
this.api( true ).order.listener( nNode, iColumn, fnCallback );
|
||
};
|
||
|
||
|
||
/**
|
||
* Update a table cell or row - this method will accept either a single value to
|
||
* update the cell with, an array of values with one element for each column or
|
||
* an object in the same format as the original data source. The function is
|
||
* self-referencing in order to make the multi column updates easier.
|
||
* @param {object|array|string} mData Data to update the cell/row with
|
||
* @param {node|int} mRow TR element you want to update or the aoData index
|
||
* @param {int} [iColumn] The column to update, give as null or undefined to
|
||
* update a whole row.
|
||
* @param {bool} [bRedraw=true] Redraw the table or not
|
||
* @param {bool} [bAction=true] Perform pre-draw actions or not
|
||
* @returns {int} 0 on success, 1 on error
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
* oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell
|
||
* oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row
|
||
* } );
|
||
*/
|
||
this.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )
|
||
{
|
||
var api = this.api( true );
|
||
|
||
if ( iColumn === undefined || iColumn === null ) {
|
||
api.row( mRow ).data( mData );
|
||
}
|
||
else {
|
||
api.cell( mRow, iColumn ).data( mData );
|
||
}
|
||
|
||
if ( bAction === undefined || bAction ) {
|
||
api.columns.adjust();
|
||
}
|
||
|
||
if ( bRedraw === undefined || bRedraw ) {
|
||
api.draw();
|
||
}
|
||
return 0;
|
||
};
|
||
|
||
|
||
/**
|
||
* Provide a common method for plug-ins to check the version of DataTables being used, in order
|
||
* to ensure compatibility.
|
||
* @param {string} sVersion Version string to check for, in the format "X.Y.Z". Note that the
|
||
* formats "X" and "X.Y" are also acceptable.
|
||
* @returns {boolean} true if this version of DataTables is greater or equal to the required
|
||
* version, or false if this version of DataTales is not suitable
|
||
* @method
|
||
* @dtopt API
|
||
* @deprecated Since v1.10
|
||
*
|
||
* @example
|
||
* $(document).ready(function() {
|
||
* var oTable = $('#example').dataTable();
|
||
* alert( oTable.fnVersionCheck( '1.9.0' ) );
|
||
* } );
|
||
*/
|
||
this.fnVersionCheck = _ext.fnVersionCheck;
|
||
|
||
|
||
var _that = this;
|
||
var emptyInit = options === undefined;
|
||
var len = this.length;
|
||
|
||
if ( emptyInit ) {
|
||
options = {};
|
||
}
|
||
|
||
this.oApi = this.internal = _ext.internal;
|
||
|
||
// Extend with old style plug-in API methods
|
||
for ( var fn in DataTable.ext.internal ) {
|
||
if ( fn ) {
|
||
this[fn] = _fnExternApiFunc(fn);
|
||
}
|
||
}
|
||
|
||
this.each(function() {
|
||
// For each initialisation we want to give it a clean initialisation
|
||
// object that can be bashed around
|
||
var o = {};
|
||
var oInit = len > 1 ? // optimisation for single table case
|
||
_fnExtend( o, options, true ) :
|
||
options;
|
||
|
||
/*global oInit,_that,emptyInit*/
|
||
var i=0, iLen, j, jLen, k, kLen;
|
||
var sId = this.getAttribute( 'id' );
|
||
var bInitHandedOff = false;
|
||
var defaults = DataTable.defaults;
|
||
|
||
|
||
/* Sanity check */
|
||
if ( this.nodeName.toLowerCase() != 'table' )
|
||
{
|
||
_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );
|
||
return;
|
||
}
|
||
|
||
/* Backwards compatibility for the defaults */
|
||
_fnCompatOpts( defaults );
|
||
_fnCompatCols( defaults.column );
|
||
|
||
/* Convert the camel-case defaults to Hungarian */
|
||
_fnCamelToHungarian( defaults, defaults, true );
|
||
_fnCamelToHungarian( defaults.column, defaults.column, true );
|
||
|
||
/* Setting up the initialisation object */
|
||
_fnCamelToHungarian( defaults, oInit );
|
||
|
||
/* Check to see if we are re-initialising a table */
|
||
var allSettings = DataTable.settings;
|
||
for ( i=0, iLen=allSettings.length ; i<iLen ; i++ )
|
||
{
|
||
/* Base check on table node */
|
||
if ( allSettings[i].nTable == this )
|
||
{
|
||
var bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;
|
||
var bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;
|
||
|
||
if ( emptyInit || bRetrieve )
|
||
{
|
||
return allSettings[i].oInstance;
|
||
}
|
||
else if ( bDestroy )
|
||
{
|
||
allSettings[i].oInstance.fnDestroy();
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
_fnLog( allSettings[i], 0, 'Cannot reinitialise DataTable', 3 );
|
||
return;
|
||
}
|
||
}
|
||
|
||
/* If the element we are initialising has the same ID as a table which was previously
|
||
* initialised, but the table nodes don't match (from before) then we destroy the old
|
||
* instance by simply deleting it. This is under the assumption that the table has been
|
||
* destroyed by other methods. Anyone using non-id selectors will need to do this manually
|
||
*/
|
||
if ( allSettings[i].sTableId == this.id )
|
||
{
|
||
allSettings.splice( i, 1 );
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* Ensure the table has an ID - required for accessibility */
|
||
if ( sId === null || sId === "" )
|
||
{
|
||
sId = "DataTables_Table_"+(DataTable.ext._unique++);
|
||
this.id = sId;
|
||
}
|
||
|
||
/* Create the settings object for this table and set some of the default parameters */
|
||
var oSettings = $.extend( true, {}, DataTable.models.oSettings, {
|
||
"nTable": this,
|
||
"oApi": _that.internal,
|
||
"oInit": oInit,
|
||
"sDestroyWidth": $(this)[0].style.width,
|
||
"sInstance": sId,
|
||
"sTableId": sId
|
||
} );
|
||
allSettings.push( oSettings );
|
||
|
||
// Need to add the instance after the instance after the settings object has been added
|
||
// to the settings array, so we can self reference the table instance if more than one
|
||
oSettings.oInstance = (_that.length===1) ? _that : $(this).dataTable();
|
||
|
||
// Backwards compatibility, before we apply all the defaults
|
||
_fnCompatOpts( oInit );
|
||
|
||
if ( oInit.oLanguage )
|
||
{
|
||
_fnLanguageCompat( oInit.oLanguage );
|
||
}
|
||
|
||
// If the length menu is given, but the init display length is not, use the length menu
|
||
if ( oInit.aLengthMenu && ! oInit.iDisplayLength )
|
||
{
|
||
oInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?
|
||
oInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];
|
||
}
|
||
|
||
// Apply the defaults and init options to make a single init object will all
|
||
// options defined from defaults and instance options.
|
||
oInit = _fnExtend( $.extend( true, {}, defaults ), oInit );
|
||
|
||
|
||
// Map the initialisation options onto the settings object
|
||
_fnMap( oSettings.oFeatures, oInit, [
|
||
"bPaginate",
|
||
"bLengthChange",
|
||
"bFilter",
|
||
"bSort",
|
||
"bSortMulti",
|
||
"bInfo",
|
||
"bProcessing",
|
||
"bAutoWidth",
|
||
"bSortClasses",
|
||
"bServerSide",
|
||
"bDeferRender"
|
||
] );
|
||
_fnMap( oSettings, oInit, [
|
||
"asStripeClasses",
|
||
"ajax",
|
||
"fnServerData",
|
||
"fnFormatNumber",
|
||
"sServerMethod",
|
||
"aaSorting",
|
||
"aaSortingFixed",
|
||
"aLengthMenu",
|
||
"sPaginationType",
|
||
"sAjaxSource",
|
||
"sAjaxDataProp",
|
||
"iStateDuration",
|
||
"sDom",
|
||
"bSortCellsTop",
|
||
"iTabIndex",
|
||
"fnStateLoadCallback",
|
||
"fnStateSaveCallback",
|
||
"renderer",
|
||
[ "iCookieDuration", "iStateDuration" ], // backwards compat
|
||
[ "oSearch", "oPreviousSearch" ],
|
||
[ "aoSearchCols", "aoPreSearchCols" ],
|
||
[ "iDisplayLength", "_iDisplayLength" ],
|
||
[ "bJQueryUI", "bJUI" ]
|
||
] );
|
||
_fnMap( oSettings.oScroll, oInit, [
|
||
[ "sScrollX", "sX" ],
|
||
[ "sScrollXInner", "sXInner" ],
|
||
[ "sScrollY", "sY" ],
|
||
[ "bScrollCollapse", "bCollapse" ]
|
||
] );
|
||
_fnMap( oSettings.oLanguage, oInit, "fnInfoCallback" );
|
||
|
||
/* Callback functions which are array driven */
|
||
_fnCallbackReg( oSettings, 'aoDrawCallback', oInit.fnDrawCallback, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoServerParams', oInit.fnServerParams, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoStateSaveParams', oInit.fnStateSaveParams, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoStateLoadParams', oInit.fnStateLoadParams, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoStateLoaded', oInit.fnStateLoaded, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoRowCallback', oInit.fnRowCallback, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoHeaderCallback', oInit.fnHeaderCallback, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoFooterCallback', oInit.fnFooterCallback, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoInitComplete', oInit.fnInitComplete, 'user' );
|
||
_fnCallbackReg( oSettings, 'aoPreDrawCallback', oInit.fnPreDrawCallback, 'user' );
|
||
|
||
var oClasses = oSettings.oClasses;
|
||
|
||
// @todo Remove in 1.11
|
||
if ( oInit.bJQueryUI )
|
||
{
|
||
/* Use the JUI classes object for display. You could clone the oStdClasses object if
|
||
* you want to have multiple tables with multiple independent classes
|
||
*/
|
||
$.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );
|
||
|
||
if ( oInit.sDom === defaults.sDom && defaults.sDom === "lfrtip" )
|
||
{
|
||
/* Set the DOM to use a layout suitable for jQuery UI's theming */
|
||
oSettings.sDom = '<"H"lfr>t<"F"ip>';
|
||
}
|
||
|
||
if ( ! oSettings.renderer ) {
|
||
oSettings.renderer = 'jqueryui';
|
||
}
|
||
else if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {
|
||
oSettings.renderer.header = 'jqueryui';
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );
|
||
}
|
||
$(this).addClass( oClasses.sTable );
|
||
|
||
/* Calculate the scroll bar width and cache it for use later on */
|
||
if ( oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "" )
|
||
{
|
||
oSettings.oScroll.iBarWidth = _fnScrollBarWidth();
|
||
}
|
||
if ( oSettings.oScroll.sX === true ) { // Easy initialisation of x-scrolling
|
||
oSettings.oScroll.sX = '100%';
|
||
}
|
||
|
||
if ( oSettings.iInitDisplayStart === undefined )
|
||
{
|
||
/* Display start point, taking into account the save saving */
|
||
oSettings.iInitDisplayStart = oInit.iDisplayStart;
|
||
oSettings._iDisplayStart = oInit.iDisplayStart;
|
||
}
|
||
|
||
if ( oInit.iDeferLoading !== null )
|
||
{
|
||
oSettings.bDeferLoading = true;
|
||
var tmp = $.isArray( oInit.iDeferLoading );
|
||
oSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;
|
||
oSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;
|
||
}
|
||
|
||
/* Language definitions */
|
||
if ( oInit.oLanguage.sUrl !== "" )
|
||
{
|
||
/* Get the language definitions from a file - because this Ajax call makes the language
|
||
* get async to the remainder of this function we use bInitHandedOff to indicate that
|
||
* _fnInitialise will be fired by the returned Ajax handler, rather than the constructor
|
||
*/
|
||
oSettings.oLanguage.sUrl = oInit.oLanguage.sUrl;
|
||
$.getJSON( oSettings.oLanguage.sUrl, null, function( json ) {
|
||
_fnLanguageCompat( json );
|
||
_fnCamelToHungarian( defaults.oLanguage, json );
|
||
$.extend( true, oSettings.oLanguage, oInit.oLanguage, json );
|
||
_fnInitialise( oSettings );
|
||
} );
|
||
bInitHandedOff = true;
|
||
}
|
||
else
|
||
{
|
||
$.extend( true, oSettings.oLanguage, oInit.oLanguage );
|
||
}
|
||
|
||
|
||
/*
|
||
* Stripes
|
||
*/
|
||
if ( oInit.asStripeClasses === null )
|
||
{
|
||
oSettings.asStripeClasses =[
|
||
oClasses.sStripeOdd,
|
||
oClasses.sStripeEven
|
||
];
|
||
}
|
||
|
||
/* Remove row stripe classes if they are already on the table row */
|
||
var stripeClasses = oSettings.asStripeClasses;
|
||
var rowOne = $('tbody tr:eq(0)', this);
|
||
if ( $.inArray( true, $.map( stripeClasses, function(el, i) {
|
||
return rowOne.hasClass(el);
|
||
} ) ) !== -1 ) {
|
||
$('tbody tr', this).removeClass( stripeClasses.join(' ') );
|
||
oSettings.asDestroyStripes = stripeClasses.slice();
|
||
}
|
||
|
||
/*
|
||
* Columns
|
||
* See if we should load columns automatically or use defined ones
|
||
*/
|
||
var anThs = [];
|
||
var aoColumnsInit;
|
||
var nThead = this.getElementsByTagName('thead');
|
||
if ( nThead.length !== 0 )
|
||
{
|
||
_fnDetectHeader( oSettings.aoHeader, nThead[0] );
|
||
anThs = _fnGetUniqueThs( oSettings );
|
||
}
|
||
|
||
/* If not given a column array, generate one with nulls */
|
||
if ( oInit.aoColumns === null )
|
||
{
|
||
aoColumnsInit = [];
|
||
for ( i=0, iLen=anThs.length ; i<iLen ; i++ )
|
||
{
|
||
aoColumnsInit.push( null );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
aoColumnsInit = oInit.aoColumns;
|
||
}
|
||
|
||
/* Add the columns */
|
||
for ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )
|
||
{
|
||
_fnAddColumn( oSettings, anThs ? anThs[i] : null );
|
||
}
|
||
|
||
/* Apply the column definitions */
|
||
_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {
|
||
_fnColumnOptions( oSettings, iCol, oDef );
|
||
} );
|
||
|
||
/* HTML5 attribute detection - build an mData object automatically if the
|
||
* attributes are found
|
||
*/
|
||
if ( rowOne.length ) {
|
||
var a = function ( cell, name ) {
|
||
return cell.getAttribute( 'data-'+name ) ? name : null;
|
||
};
|
||
|
||
$.each( _fnGetRowElements( oSettings, rowOne[0] ).cells, function (i, cell) {
|
||
var col = oSettings.aoColumns[i];
|
||
|
||
if ( col.mData === i ) {
|
||
var sort = a( cell, 'sort' ) || a( cell, 'order' );
|
||
var filter = a( cell, 'filter' ) || a( cell, 'search' );
|
||
|
||
if ( sort !== null || filter !== null ) {
|
||
col.mData = {
|
||
_: i+'.display',
|
||
sort: sort !== null ? i+'.@data-'+sort : undefined,
|
||
type: sort !== null ? i+'.@data-'+sort : undefined,
|
||
filter: filter !== null ? i+'.@data-'+filter : undefined
|
||
};
|
||
|
||
_fnColumnOptions( oSettings, i );
|
||
}
|
||
}
|
||
} );
|
||
}
|
||
|
||
var features = oSettings.oFeatures;
|
||
|
||
/* Must be done after everything which can be overridden by the state saving! */
|
||
if ( oInit.bStateSave )
|
||
{
|
||
features.bStateSave = true;
|
||
_fnLoadState( oSettings, oInit );
|
||
_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );
|
||
}
|
||
|
||
|
||
/*
|
||
* Sorting
|
||
* @todo For modularisation (1.11) this needs to do into a sort start up handler
|
||
*/
|
||
|
||
// If aaSorting is not defined, then we use the first indicator in asSorting
|
||
// in case that has been altered, so the default sort reflects that option
|
||
if ( oInit.aaSorting === undefined )
|
||
{
|
||
var sorting = oSettings.aaSorting;
|
||
for ( i=0, iLen=sorting.length ; i<iLen ; i++ )
|
||
{
|
||
sorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];
|
||
}
|
||
}
|
||
|
||
/* Do a first pass on the sorting classes (allows any size changes to be taken into
|
||
* account, and also will apply sorting disabled classes if disabled
|
||
*/
|
||
_fnSortingClasses( oSettings );
|
||
|
||
if ( features.bSort )
|
||
{
|
||
_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
|
||
if ( oSettings.bSorted ) {
|
||
var aSort = _fnSortFlatten( oSettings );
|
||
var sortedColumns = {};
|
||
|
||
$.each( aSort, function (i, val) {
|
||
sortedColumns[ val.src ] = val.dir;
|
||
} );
|
||
|
||
_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );
|
||
_fnSortAria( oSettings );
|
||
}
|
||
} );
|
||
}
|
||
|
||
_fnCallbackReg( oSettings, 'aoDrawCallback', function () {
|
||
if ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {
|
||
_fnSortingClasses( oSettings );
|
||
}
|
||
}, 'sc' );
|
||
|
||
|
||
/*
|
||
* Final init
|
||
* Cache the header, body and footer as required, creating them if needed
|
||
*/
|
||
|
||
/* Browser support detection */
|
||
_fnBrowserDetect( oSettings );
|
||
|
||
// Work around for Webkit bug 83867 - store the caption-side before removing from doc
|
||
var captions = $(this).children('caption').each( function () {
|
||
this._captionSide = $(this).css('caption-side');
|
||
} );
|
||
|
||
var thead = $(this).children('thead');
|
||
if ( thead.length === 0 )
|
||
{
|
||
thead = $('<thead/>').appendTo(this);
|
||
}
|
||
oSettings.nTHead = thead[0];
|
||
|
||
var tbody = $(this).children('tbody');
|
||
if ( tbody.length === 0 )
|
||
{
|
||
tbody = $('<tbody/>').appendTo(this);
|
||
}
|
||
oSettings.nTBody = tbody[0];
|
||
|
||
var tfoot = $(this).children('tfoot');
|
||
if ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== "" || oSettings.oScroll.sY !== "") )
|
||
{
|
||
// If we are a scrolling table, and no footer has been given, then we need to create
|
||
// a tfoot element for the caption element to be appended to
|
||
tfoot = $('<tfoot/>').appendTo(this);
|
||
}
|
||
|
||
if ( tfoot.length === 0 || tfoot.children().length === 0 ) {
|
||
$(this).addClass( oClasses.sNoFooter );
|
||
}
|
||
else if ( tfoot.length > 0 ) {
|
||
oSettings.nTFoot = tfoot[0];
|
||
_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );
|
||
}
|
||
|
||
/* Check if there is data passing into the constructor */
|
||
if ( oInit.aaData )
|
||
{
|
||
for ( i=0 ; i<oInit.aaData.length ; i++ )
|
||
{
|
||
_fnAddData( oSettings, oInit.aaData[ i ] );
|
||
}
|
||
}
|
||
else if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )
|
||
{
|
||
/* Grab the data from the page - only do this when deferred loading or no Ajax
|
||
* source since there is no point in reading the DOM data if we are then going
|
||
* to replace it with Ajax data
|
||
*/
|
||
_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );
|
||
}
|
||
|
||
/* Copy the data index array */
|
||
oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
|
||
|
||
/* Initialisation complete - table can be drawn */
|
||
oSettings.bInitialised = true;
|
||
|
||
/* Check if we need to initialise the table (it might not have been handed off to the
|
||
* language processor)
|
||
*/
|
||
if ( bInitHandedOff === false )
|
||
{
|
||
_fnInitialise( oSettings );
|
||
}
|
||
} );
|
||
_that = null;
|
||
return this;
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* Computed structure of the DataTables API, defined by the options passed to
|
||
* `DataTable.Api.register()` when building the API.
|
||
*
|
||
* The structure is built in order to speed creation and extension of the Api
|
||
* objects since the extensions are effectively pre-parsed.
|
||
*
|
||
* The array is an array of objects with the following structure, where this
|
||
* base array represents the Api prototype base:
|
||
*
|
||
* [
|
||
* {
|
||
* name: 'data' -- string - Property name
|
||
* val: function () {}, -- function - Api method (or undefined if just an object
|
||
* methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
|
||
* propExt: [ ... ] -- array - Array of Api object definitions to extend the property
|
||
* },
|
||
* {
|
||
* name: 'row'
|
||
* val: {},
|
||
* methodExt: [ ... ],
|
||
* propExt: [
|
||
* {
|
||
* name: 'data'
|
||
* val: function () {},
|
||
* methodExt: [ ... ],
|
||
* propExt: [ ... ]
|
||
* },
|
||
* ...
|
||
* ]
|
||
* }
|
||
* ]
|
||
*
|
||
* @type {Array}
|
||
* @ignore
|
||
*/
|
||
var __apiStruct = [];
|
||
|
||
|
||
/**
|
||
* `Array.prototype` reference.
|
||
*
|
||
* @type object
|
||
* @ignore
|
||
*/
|
||
var __arrayProto = Array.prototype;
|
||
|
||
|
||
/**
|
||
* Abstraction for `context` parameter of the `Api` constructor to allow it to
|
||
* take several different forms for ease of use.
|
||
*
|
||
* Each of the input parameter types will be converted to a DataTables settings
|
||
* object where possible.
|
||
*
|
||
* @param {string|node|jQuery|object} mixed DataTable identifier. Can be one
|
||
* of:
|
||
*
|
||
* * `string` - jQuery selector. Any DataTables' matching the given selector
|
||
* with be found and used.
|
||
* * `node` - `TABLE` node which has already been formed into a DataTable.
|
||
* * `jQuery` - A jQuery object of `TABLE` nodes.
|
||
* * `object` - DataTables settings object
|
||
* * `DataTables.Api` - API instance
|
||
* @return {array|null} Matching DataTables settings objects. `null` or
|
||
* `undefined` is returned if no matching DataTable is found.
|
||
* @ignore
|
||
*/
|
||
var _toSettings = function ( mixed )
|
||
{
|
||
var idx, jq;
|
||
var settings = DataTable.settings;
|
||
var tables = $.map( settings, function (el, i) {
|
||
return el.nTable;
|
||
} );
|
||
|
||
if ( ! mixed ) {
|
||
return [];
|
||
}
|
||
else if ( mixed.nTable && mixed.oApi ) {
|
||
// DataTables settings object
|
||
return [ mixed ];
|
||
}
|
||
else if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {
|
||
// Table node
|
||
idx = $.inArray( mixed, tables );
|
||
return idx !== -1 ? [ settings[idx] ] : null;
|
||
}
|
||
else if ( mixed && typeof mixed.settings === 'function' ) {
|
||
return mixed.settings().toArray();
|
||
}
|
||
else if ( typeof mixed === 'string' ) {
|
||
// jQuery selector
|
||
jq = $(mixed);
|
||
}
|
||
else if ( mixed instanceof $ ) {
|
||
// jQuery object (also DataTables instance)
|
||
jq = mixed;
|
||
}
|
||
|
||
if ( jq ) {
|
||
return jq.map( function(i) {
|
||
idx = $.inArray( this, tables );
|
||
return idx !== -1 ? settings[idx] : null;
|
||
} ).toArray();
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* DataTables API class - used to control and interface with one or more
|
||
* DataTables enhanced tables.
|
||
*
|
||
* The API class is heavily based on jQuery, presenting a chainable interface
|
||
* that you can use to interact with tables. Each instance of the API class has
|
||
* a "context" - i.e. the tables that it will operate on. This could be a single
|
||
* table, all tables on a page or a sub-set thereof.
|
||
*
|
||
* Additionally the API is designed to allow you to easily work with the data in
|
||
* the tables, retrieving and manipulating it as required. This is done by
|
||
* presenting the API class as an array like interface. The contents of the
|
||
* array depend upon the actions requested by each method (for example
|
||
* `rows().nodes()` will return an array of nodes, while `rows().data()` will
|
||
* return an array of objects or arrays depending upon your table's
|
||
* configuration). The API object has a number of array like methods (`push`,
|
||
* `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,
|
||
* `unique` etc) to assist your working with the data held in a table.
|
||
*
|
||
* Most methods (those which return an Api instance) are chainable, which means
|
||
* the return from a method call also has all of the methods available that the
|
||
* top level object had. For example, these two calls are equivalent:
|
||
*
|
||
* // Not chained
|
||
* api.row.add( {...} );
|
||
* api.draw();
|
||
*
|
||
* // Chained
|
||
* api.row.add( {...} ).draw();
|
||
*
|
||
* @class DataTable.Api
|
||
* @param {array|object|string|jQuery} context DataTable identifier. This is
|
||
* used to define which DataTables enhanced tables this API will operate on.
|
||
* Can be one of:
|
||
*
|
||
* * `string` - jQuery selector. Any DataTables' matching the given selector
|
||
* with be found and used.
|
||
* * `node` - `TABLE` node which has already been formed into a DataTable.
|
||
* * `jQuery` - A jQuery object of `TABLE` nodes.
|
||
* * `object` - DataTables settings object
|
||
* @param {array} [data] Data to initialise the Api instance with.
|
||
*
|
||
* @example
|
||
* // Direct initialisation during DataTables construction
|
||
* var api = $('#example').DataTable();
|
||
*
|
||
* @example
|
||
* // Initialisation using a DataTables jQuery object
|
||
* var api = $('#example').dataTable().api();
|
||
*
|
||
* @example
|
||
* // Initialisation as a constructor
|
||
* var api = new $.fn.DataTable.Api( 'table.dataTable' );
|
||
*/
|
||
DataTable.Api = _Api = function ( context, data )
|
||
{
|
||
if ( ! this instanceof _Api ) {
|
||
throw 'DT API must be constructed as a new object';
|
||
// or should it do the 'new' for the caller?
|
||
// return new _Api.apply( this, arguments );
|
||
}
|
||
|
||
var settings = [];
|
||
var ctxSettings = function ( o ) {
|
||
var a = _toSettings( o );
|
||
if ( a ) {
|
||
settings.push.apply( settings, a );
|
||
}
|
||
};
|
||
|
||
if ( $.isArray( context ) ) {
|
||
for ( var i=0, ien=context.length ; i<ien ; i++ ) {
|
||
ctxSettings( context[i] );
|
||
}
|
||
}
|
||
else {
|
||
ctxSettings( context );
|
||
}
|
||
|
||
// Remove duplicates
|
||
this.context = _unique( settings );
|
||
|
||
// Initial data
|
||
if ( data ) {
|
||
this.push.apply( this, data.toArray ? data.toArray() : data );
|
||
}
|
||
|
||
// selector
|
||
this.selector = {
|
||
rows: null,
|
||
cols: null,
|
||
opts: null
|
||
};
|
||
|
||
_Api.extend( this, this, __apiStruct );
|
||
};
|
||
|
||
|
||
_Api.prototype = /** @lends DataTables.Api */{
|
||
/**
|
||
* Return a new Api instance, comprised of the data held in the current
|
||
* instance, join with the other array(s) and/or value(s).
|
||
*
|
||
* An alias for `Array.prototype.concat`.
|
||
*
|
||
* @type method
|
||
* @param {*} value1 Arrays and/or values to concatenate.
|
||
* @param {*} [...] Additional arrays and/or values to concatenate.
|
||
* @returns {DataTables.Api} New API instance, comprising of the combined
|
||
* array.
|
||
*/
|
||
concat: __arrayProto.concat,
|
||
|
||
|
||
context: [], // array of table settings objects
|
||
|
||
|
||
each: function ( fn )
|
||
{
|
||
if ( __arrayProto.forEach ) {
|
||
// Where possible, use the built-in forEach
|
||
__arrayProto.forEach.call( this, fn, this );
|
||
}
|
||
else {
|
||
// Compatibility for browsers without EMCA-252-5 (JS 1.6)
|
||
for ( var i=0, ien=this.length ; i<ien; i++ ) {
|
||
// In strict mode the execution scope is the passed value
|
||
fn.call( this, this[i], i, this );
|
||
}
|
||
}
|
||
|
||
return this;
|
||
},
|
||
|
||
|
||
eq: function ( idx )
|
||
{
|
||
var ctx = this.context;
|
||
|
||
return ctx.length > idx ?
|
||
new _Api( ctx[idx], this[idx] ) :
|
||
null;
|
||
},
|
||
|
||
|
||
filter: function ( fn )
|
||
{
|
||
var a = [];
|
||
|
||
if ( __arrayProto.filter ) {
|
||
a = __arrayProto.filter.call( this, fn, this );
|
||
}
|
||
else {
|
||
// Compatibility for browsers without EMCA-252-5 (JS 1.6)
|
||
for ( var i=0, ien=this.length ; i<ien ; i++ ) {
|
||
if ( fn.call( this, this[i], i, this ) ) {
|
||
a.push( this[i] );
|
||
}
|
||
}
|
||
}
|
||
|
||
return new _Api( this.context, a );
|
||
},
|
||
|
||
|
||
flatten: function ()
|
||
{
|
||
var a = [];
|
||
return new _Api( this.context, a.concat.apply( a, this.toArray() ) );
|
||
},
|
||
|
||
|
||
join: __arrayProto.join,
|
||
|
||
|
||
indexOf: __arrayProto.indexOf || function (obj, start)
|
||
{
|
||
for ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {
|
||
if ( this[i] === obj ) {
|
||
return i;
|
||
}
|
||
}
|
||
return -1;
|
||
},
|
||
|
||
// Internal only at the moment - relax?
|
||
iterator: function ( flatten, type, fn ) {
|
||
var
|
||
a = [], ret,
|
||
i, ien, j, jen,
|
||
context = this.context,
|
||
rows, items, item,
|
||
selector = this.selector;
|
||
|
||
// Argument shifting
|
||
if ( typeof flatten === 'string' ) {
|
||
fn = type;
|
||
type = flatten;
|
||
flatten = false;
|
||
}
|
||
|
||
for ( i=0, ien=context.length ; i<ien ; i++ ) {
|
||
if ( type === 'table' ) {
|
||
ret = fn( context[i], i );
|
||
|
||
if ( ret !== undefined ) {
|
||
a.push( ret );
|
||
}
|
||
}
|
||
else if ( type === 'columns' || type === 'rows' ) {
|
||
// this has same length as context - one entry for each table
|
||
ret = fn( context[i], this[i], i );
|
||
|
||
if ( ret !== undefined ) {
|
||
a.push( ret );
|
||
}
|
||
}
|
||
else if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {
|
||
// columns and rows share the same structure.
|
||
// 'this' is an array of column indexes for each context
|
||
items = this[i];
|
||
|
||
if ( type === 'column-rows' ) {
|
||
rows = _selector_row_indexes( context[i], selector.opts );
|
||
}
|
||
|
||
for ( j=0, jen=items.length ; j<jen ; j++ ) {
|
||
item = items[j];
|
||
|
||
if ( type === 'cell' ) {
|
||
ret = fn( context[i], item.row, item.column, i, j );
|
||
}
|
||
else {
|
||
ret = fn( context[i], item, i, j, rows );
|
||
}
|
||
|
||
if ( ret !== undefined ) {
|
||
a.push( ret );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if ( a.length ) {
|
||
var api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );
|
||
var apiSelector = api.selector;
|
||
apiSelector.rows = selector.rows;
|
||
apiSelector.cols = selector.cols;
|
||
apiSelector.opts = selector.opts;
|
||
return api;
|
||
}
|
||
return this;
|
||
},
|
||
|
||
|
||
lastIndexOf: __arrayProto.lastIndexOf || function (obj, start)
|
||
{
|
||
// Bit cheeky...
|
||
return this.indexOf.apply( this.toArray.reverse(), arguments );
|
||
},
|
||
|
||
|
||
length: 0,
|
||
|
||
|
||
map: function ( fn )
|
||
{
|
||
var a = [];
|
||
|
||
if ( __arrayProto.map ) {
|
||
a = __arrayProto.map.call( this, fn, this );
|
||
}
|
||
else {
|
||
// Compatibility for browsers without EMCA-252-5 (JS 1.6)
|
||
for ( var i=0, ien=this.length ; i<ien ; i++ ) {
|
||
a.push( fn.call( this, this[i], i ) );
|
||
}
|
||
}
|
||
|
||
return new _Api( this.context, a );
|
||
},
|
||
|
||
|
||
pluck: function ( prop )
|
||
{
|
||
return this.map( function ( el ) {
|
||
return el[ prop ];
|
||
} );
|
||
},
|
||
|
||
pop: __arrayProto.pop,
|
||
|
||
|
||
push: __arrayProto.push,
|
||
|
||
|
||
// Does not return an API instance
|
||
reduce: __arrayProto.reduce || function ( fn, init )
|
||
{
|
||
return _fnReduce( this, fn, init, 0, this.length, 1 );
|
||
},
|
||
|
||
|
||
reduceRight: __arrayProto.reduceRight || function ( fn, init )
|
||
{
|
||
return _fnReduce( this, fn, init, this.length-1, -1, -1 );
|
||
},
|
||
|
||
|
||
reverse: __arrayProto.reverse,
|
||
|
||
|
||
// Object with rows, columns and opts
|
||
selector: null,
|
||
|
||
|
||
shift: __arrayProto.shift,
|
||
|
||
|
||
sort: __arrayProto.sort, // ? name - order?
|
||
|
||
|
||
splice: __arrayProto.splice,
|
||
|
||
|
||
toArray: function ()
|
||
{
|
||
return __arrayProto.slice.call( this );
|
||
},
|
||
|
||
|
||
to$: function ()
|
||
{
|
||
return $( this );
|
||
},
|
||
|
||
|
||
toJQuery: function ()
|
||
{
|
||
return $( this );
|
||
},
|
||
|
||
|
||
unique: function ()
|
||
{
|
||
return new _Api( this.context, _unique(this) );
|
||
},
|
||
|
||
|
||
unshift: __arrayProto.unshift
|
||
};
|
||
|
||
|
||
_Api.extend = function ( scope, obj, ext )
|
||
{
|
||
// Only extend API instances and static properties of the API
|
||
if ( ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {
|
||
return;
|
||
}
|
||
|
||
var
|
||
i, ien,
|
||
j, jen,
|
||
struct, inner,
|
||
methodScoping = function ( fn, struc ) {
|
||
return function () {
|
||
var ret = fn.apply( scope, arguments );
|
||
|
||
// Method extension
|
||
_Api.extend( ret, ret, struc.methodExt );
|
||
return ret;
|
||
};
|
||
};
|
||
|
||
for ( i=0, ien=ext.length ; i<ien ; i++ ) {
|
||
struct = ext[i];
|
||
|
||
// Value
|
||
obj[ struct.name ] = typeof struct.val === 'function' ?
|
||
methodScoping( struct.val, struct ) :
|
||
$.isPlainObject( struct.val ) ?
|
||
{} :
|
||
struct.val;
|
||
|
||
obj[ struct.name ].__dt_wrapper = true;
|
||
|
||
// Property extension
|
||
_Api.extend( scope, obj[ struct.name ], struct.propExt );
|
||
}
|
||
};
|
||
|
||
|
||
// @todo - Is there need for an augment function?
|
||
// _Api.augment = function ( inst, name )
|
||
// {
|
||
// // Find src object in the structure from the name
|
||
// var parts = name.split('.');
|
||
|
||
// _Api.extend( inst, obj );
|
||
// };
|
||
|
||
|
||
// [
|
||
// {
|
||
// name: 'data' -- string - Property name
|
||
// val: function () {}, -- function - Api method (or undefined if just an object
|
||
// methodExt: [ ... ], -- array - Array of Api object definitions to extend the method result
|
||
// propExt: [ ... ] -- array - Array of Api object definitions to extend the property
|
||
// },
|
||
// {
|
||
// name: 'row'
|
||
// val: {},
|
||
// methodExt: [ ... ],
|
||
// propExt: [
|
||
// {
|
||
// name: 'data'
|
||
// val: function () {},
|
||
// methodExt: [ ... ],
|
||
// propExt: [ ... ]
|
||
// },
|
||
// ...
|
||
// ]
|
||
// }
|
||
// ]
|
||
|
||
_Api.register = _api_register = function ( name, val )
|
||
{
|
||
if ( $.isArray( name ) ) {
|
||
for ( var j=0, jen=name.length ; j<jen ; j++ ) {
|
||
_Api.register( name[j], val );
|
||
}
|
||
return;
|
||
}
|
||
|
||
var
|
||
i, ien,
|
||
heir = name.split('.'),
|
||
struct = __apiStruct,
|
||
key, method;
|
||
|
||
var find = function ( src, name ) {
|
||
for ( var i=0, ien=src.length ; i<ien ; i++ ) {
|
||
if ( src[i].name === name ) {
|
||
return src[i];
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
|
||
for ( i=0, ien=heir.length ; i<ien ; i++ ) {
|
||
method = heir[i].indexOf('()') !== -1;
|
||
key = method ?
|
||
heir[i].replace('()', '') :
|
||
heir[i];
|
||
|
||
var src = find( struct, key );
|
||
if ( ! src ) {
|
||
src = {
|
||
name: key,
|
||
val: {},
|
||
methodExt: [],
|
||
propExt: []
|
||
};
|
||
struct.push( src );
|
||
}
|
||
|
||
if ( i === ien-1 ) {
|
||
src.val = val;
|
||
}
|
||
else {
|
||
struct = method ?
|
||
src.methodExt :
|
||
src.propExt;
|
||
}
|
||
}
|
||
|
||
// Rebuild the API with the new construct
|
||
if ( _Api.ready ) {
|
||
DataTable.api.build();
|
||
}
|
||
};
|
||
|
||
|
||
_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {
|
||
_Api.register( pluralName, val );
|
||
|
||
_Api.register( singularName, function () {
|
||
var ret = val.apply( this, arguments );
|
||
|
||
if ( ret === this ) {
|
||
// Returned item is the API instance that was passed in, return it
|
||
return this;
|
||
}
|
||
else if ( ret instanceof _Api ) {
|
||
// New API instance returned, want the value from the first item
|
||
// in the returned array for the singular result.
|
||
return ret.length ?
|
||
$.isArray( ret[0] ) ?
|
||
new _Api( ret.context, ret[0] ) : // Array results are 'enhanced'
|
||
ret[0] :
|
||
undefined;
|
||
}
|
||
|
||
// Non-API return - just fire it back
|
||
return ret;
|
||
} );
|
||
};
|
||
|
||
|
||
/**
|
||
* Selector for HTML tables. Apply the given selector to the give array of
|
||
* DataTables settings objects.
|
||
*
|
||
* @param {string|integer} [selector] jQuery selector string or integer
|
||
* @param {array} Array of DataTables settings objects to be filtered
|
||
* @return {array}
|
||
* @ignore
|
||
*/
|
||
var __table_selector = function ( selector, a )
|
||
{
|
||
// Integer is used to pick out a table by index
|
||
if ( typeof selector === 'number' ) {
|
||
return [ a[ selector ] ];
|
||
}
|
||
|
||
// Perform a jQuery selector on the table nodes
|
||
var nodes = $.map( a, function (el, i) {
|
||
return el.nTable;
|
||
} );
|
||
|
||
return $(nodes)
|
||
.filter( selector )
|
||
.map( function (i) {
|
||
// Need to translate back from the table node to the settings
|
||
var idx = $.inArray( this, nodes );
|
||
return a[ idx ];
|
||
} )
|
||
.toArray();
|
||
};
|
||
|
||
|
||
|
||
/**
|
||
* Context selector for the API's context (i.e. the tables the API instance
|
||
* refers to.
|
||
*
|
||
* @name DataTable.Api#tables
|
||
* @param {string|integer} [selector] Selector to pick which tables the iterator
|
||
* should operate on. If not given, all tables in the current context are
|
||
* used. This can be given as a jQuery selector (for example `':gt(0)'`) to
|
||
* select multiple tables or as an integer to select a single table.
|
||
* @returns {DataTable.Api} Returns a new API instance if a selector is given.
|
||
*/
|
||
_api_register( 'tables()', function ( selector ) {
|
||
// A new instance is created if there was a selector specified
|
||
return selector ?
|
||
new _Api( __table_selector( selector, this.context ) ) :
|
||
this;
|
||
} );
|
||
|
||
|
||
_api_register( 'table()', function ( selector ) {
|
||
var tables = this.tables( selector );
|
||
var ctx = tables.context;
|
||
|
||
// Truncate to the first matched table
|
||
return ctx.length ?
|
||
new _Api( ctx[0] ) :
|
||
tables;
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {
|
||
return this.iterator( 'table', function ( ctx ) {
|
||
return ctx.nTable;
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'tables().body()', 'table().body()' , function () {
|
||
return this.iterator( 'table', function ( ctx ) {
|
||
return ctx.nTBody;
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'tables().header()', 'table().header()' , function () {
|
||
return this.iterator( 'table', function ( ctx ) {
|
||
return ctx.nTHead;
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {
|
||
return this.iterator( 'table', function ( ctx ) {
|
||
return ctx.nTFoot;
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
/**
|
||
* Redraw the tables in the current context.
|
||
*
|
||
* @param {boolean} [reset=true] Reset (default) or hold the current paging
|
||
* position. A full re-sort and re-filter is performed when this method is
|
||
* called, which is why the pagination reset is the default action.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'draw()', function ( resetPaging ) {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnReDraw( settings, resetPaging===false );
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
/**
|
||
* Get the current page index.
|
||
*
|
||
* @return {integer} Current page index (zero based)
|
||
*//**
|
||
* Set the current page.
|
||
*
|
||
* Note that if you attempt to show a page which does not exist, DataTables will
|
||
* not throw an error, but rather reset the paging.
|
||
*
|
||
* @param {integer|string} action The paging action to take. This can be one of:
|
||
* * `integer` - The page index to jump to
|
||
* * `string` - An action to take:
|
||
* * `first` - Jump to first page.
|
||
* * `next` - Jump to the next page
|
||
* * `previous` - Jump to previous page
|
||
* * `last` - Jump to the last page.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'page()', function ( action ) {
|
||
if ( action === undefined ) {
|
||
return this.page.info().page; // not an expensive call
|
||
}
|
||
|
||
// else, have an action to take on all tables
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnPageChange( settings, action );
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
* Paging information for the first table in the current context.
|
||
*
|
||
* If you require paging information for another table, use the `table()` method
|
||
* with a suitable selector.
|
||
*
|
||
* @return {object} Object with the following properties set:
|
||
* * `page` - Current page index (zero based - i.e. the first page is `0`)
|
||
* * `pages` - Total number of pages
|
||
* * `start` - Display index for the first record shown on the current page
|
||
* * `end` - Display index for the last record shown on the current page
|
||
* * `length` - Display length (number of records). Note that generally `start
|
||
* + length = end`, but this is not always true, for example if there are
|
||
* only 2 records to show on the final page, with a length of 10.
|
||
* * `recordsTotal` - Full data set length
|
||
* * `recordsDisplay` - Data set length once the current filtering criterion
|
||
* are applied.
|
||
*/
|
||
_api_register( 'page.info()', function ( action ) {
|
||
if ( this.context.length === 0 ) {
|
||
return undefined;
|
||
}
|
||
|
||
var
|
||
settings = this.context[0],
|
||
start = settings._iDisplayStart,
|
||
len = settings._iDisplayLength,
|
||
visRecords = settings.fnRecordsDisplay(),
|
||
all = len === -1;
|
||
|
||
return {
|
||
"page": all ? 0 : Math.floor( start / len ),
|
||
"pages": all ? 1 : Math.ceil( visRecords / len ),
|
||
"start": start,
|
||
"end": settings.fnDisplayEnd(),
|
||
"length": len,
|
||
"recordsTotal": settings.fnRecordsTotal(),
|
||
"recordsDisplay": visRecords
|
||
};
|
||
} );
|
||
|
||
|
||
/**
|
||
* Get the current page length.
|
||
*
|
||
* @return {integer} Current page length. Note `-1` indicates that all records
|
||
* are to be shown.
|
||
*//**
|
||
* Set the current page length.
|
||
*
|
||
* @param {integer} Page length to set. Use `-1` to show all records.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'page.len()', function ( len ) {
|
||
// Note that we can't call this function 'length()' because `length`
|
||
// is a Javascript property of functions which defines how many arguments
|
||
// the function expects.
|
||
if ( len === undefined ) {
|
||
return this.context.length !== 0 ?
|
||
this.context[0]._iDisplayLength :
|
||
undefined;
|
||
}
|
||
|
||
// else, set the page length
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnLengthChange( settings, len );
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
var __reload = function ( settings, holdPosition, callback ) {
|
||
if ( _fnDataSource( settings ) == 'ssp' ) {
|
||
_fnReDraw( settings, holdPosition );
|
||
}
|
||
else {
|
||
// Trigger xhr
|
||
_fnProcessingDisplay( settings, true );
|
||
|
||
_fnBuildAjax( settings, [], function( json ) {
|
||
_fnClearTable( settings );
|
||
|
||
var data = _fnAjaxDataSrc( settings, json );
|
||
for ( var i=0, ien=data.length ; i<ien ; i++ ) {
|
||
_fnAddData( settings, data[i] );
|
||
}
|
||
|
||
_fnReDraw( settings, holdPosition );
|
||
_fnProcessingDisplay( settings, false );
|
||
} );
|
||
}
|
||
|
||
// Use the draw event to trigger a callback, regardless of if it is an async
|
||
// or sync draw
|
||
if ( callback ) {
|
||
var api = new _Api( settings );
|
||
|
||
api.one( 'draw', function () {
|
||
callback( api.ajax.json() );
|
||
} );
|
||
}
|
||
};
|
||
|
||
|
||
/**
|
||
* Get the JSON response from the last Ajax request that DataTables made to the
|
||
* server. Note that this returns the JSON from the first table in the current
|
||
* context.
|
||
*
|
||
* @return {object} JSON received from the server.
|
||
*/
|
||
_api_register( 'ajax.json()', function () {
|
||
var ctx = this.context;
|
||
|
||
if ( ctx.length > 0 ) {
|
||
return ctx[0].json;
|
||
}
|
||
|
||
// else return undefined;
|
||
} );
|
||
|
||
|
||
/**
|
||
* Get the data submitted in the last Ajax request
|
||
*/
|
||
_api_register( 'ajax.params()', function () {
|
||
var ctx = this.context;
|
||
|
||
if ( ctx.length > 0 ) {
|
||
return ctx[0].oAjaxData;
|
||
}
|
||
|
||
// else return undefined;
|
||
} );
|
||
|
||
|
||
/**
|
||
* Reload tables from the Ajax data source. Note that this function will
|
||
* automatically re-draw the table when the remote data has been loaded.
|
||
*
|
||
* @param {boolean} [reset=true] Reset (default) or hold the current paging
|
||
* position. A full re-sort and re-filter is performed when this method is
|
||
* called, which is why the pagination reset is the default action.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'ajax.reload()', function ( callback, resetPaging ) {
|
||
return this.iterator( 'table', function (settings) {
|
||
__reload( settings, resetPaging===false, callback );
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
* Get the current Ajax URL. Note that this returns the URL from the first
|
||
* table in the current context.
|
||
*
|
||
* @return {string} Current Ajax source URL
|
||
*//**
|
||
* Set the Ajax URL. Note that this will set the URL for all tables in the
|
||
* current context.
|
||
*
|
||
* @param {string} url URL to set.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'ajax.url()', function ( url ) {
|
||
var ctx = this.context;
|
||
|
||
if ( url === undefined ) {
|
||
// get
|
||
if ( ctx.length === 0 ) {
|
||
return undefined;
|
||
}
|
||
ctx = ctx[0];
|
||
|
||
return ctx.ajax ?
|
||
$.isPlainObject( ctx.ajax ) ?
|
||
ctx.ajax.url :
|
||
ctx.ajax :
|
||
ctx.sAjaxSource;
|
||
}
|
||
|
||
// set
|
||
return this.iterator( 'table', function ( settings ) {
|
||
if ( $.isPlainObject( settings.ajax ) ) {
|
||
settings.ajax.url = url;
|
||
}
|
||
else {
|
||
settings.ajax = url;
|
||
}
|
||
// No need to consider sAjaxSource here since DataTables gives priority
|
||
// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any
|
||
// value of `sAjaxSource` redundant.
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
* Load data from the newly set Ajax URL. Note that this method is only
|
||
* available when `ajax.url()` is used to set a URL. Additionally, this method
|
||
* has the same effect as calling `ajax.reload()` but is provided for
|
||
* convenience when setting a new URL. Like `ajax.reload()` it will
|
||
* automatically redraw the table once the remote data has been loaded.
|
||
*
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {
|
||
// Same as a reload, but makes sense to present it for easy access after a
|
||
// url change
|
||
return this.iterator( 'table', function ( ctx ) {
|
||
__reload( ctx, resetPaging===false, callback );
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
|
||
var _selector_run = function ( selector, select )
|
||
{
|
||
var
|
||
out = [], res,
|
||
a, i, ien, j, jen;
|
||
|
||
// Can't just check for isArray here, as an API or jQuery instance might be
|
||
// given with their array like look
|
||
if ( ! selector || typeof selector === 'string' || selector.length === undefined ) {
|
||
selector = [ selector ];
|
||
}
|
||
|
||
for ( i=0, ien=selector.length ; i<ien ; i++ ) {
|
||
a = selector[i] && selector[i].split ?
|
||
selector[i].split(',') :
|
||
[ selector[i] ];
|
||
|
||
for ( j=0, jen=a.length ; j<jen ; j++ ) {
|
||
res = select( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );
|
||
|
||
if ( res && res.length ) {
|
||
out.push.apply( out, res );
|
||
}
|
||
}
|
||
}
|
||
|
||
return out;
|
||
};
|
||
|
||
|
||
var _selector_opts = function ( opts )
|
||
{
|
||
if ( ! opts ) {
|
||
opts = {};
|
||
}
|
||
|
||
// Backwards compatibility for 1.9- which used the terminology filter rather
|
||
// than search
|
||
if ( opts.filter && ! opts.search ) {
|
||
opts.search = opts.filter;
|
||
}
|
||
|
||
return {
|
||
search: opts.search || 'none',
|
||
order: opts.order || 'current',
|
||
page: opts.page || 'all'
|
||
};
|
||
};
|
||
|
||
|
||
var _selector_first = function ( inst )
|
||
{
|
||
// Reduce the API instance to the first item found
|
||
for ( var i=0, ien=inst.length ; i<ien ; i++ ) {
|
||
if ( inst[i].length > 0 ) {
|
||
// Assign the first element to the first item in the instance
|
||
// and truncate the instance and context
|
||
inst[0] = inst[i];
|
||
inst.length = 1;
|
||
inst.context = [ inst.context[i] ];
|
||
|
||
return inst;
|
||
}
|
||
}
|
||
|
||
// Not found - return an empty instance
|
||
inst.length = 0;
|
||
return inst;
|
||
};
|
||
|
||
|
||
var _selector_row_indexes = function ( settings, opts )
|
||
{
|
||
var
|
||
i, ien, tmp, a=[],
|
||
displayFiltered = settings.aiDisplay,
|
||
displayMaster = settings.aiDisplayMaster;
|
||
|
||
var
|
||
search = opts.search, // none, applied, removed
|
||
order = opts.order, // applied, current, index (original - compatibility with 1.9)
|
||
page = opts.page; // all, current
|
||
|
||
if ( _fnDataSource( settings ) == 'ssp' ) {
|
||
// In server-side processing mode, most options are irrelevant since
|
||
// rows not shown don't exist and the index order is the applied order
|
||
// Removed is a special case - for consistency just return an empty
|
||
// array
|
||
return search === 'removed' ?
|
||
[] :
|
||
_range( 0, displayMaster.length );
|
||
}
|
||
else if ( page == 'current' ) {
|
||
// Current page implies that order=current and fitler=applied, since it is
|
||
// fairly senseless otherwise, regardless of what order and search actually
|
||
// are
|
||
for ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {
|
||
a.push( displayFiltered[i] );
|
||
}
|
||
}
|
||
else if ( order == 'current' || order == 'applied' ) {
|
||
a = search == 'none' ?
|
||
displayMaster.slice() : // no search
|
||
search == 'applied' ?
|
||
displayFiltered.slice() : // applied search
|
||
$.map( displayMaster, function (el, i) { // removed search
|
||
return $.inArray( el, displayFiltered ) === -1 ? el : null;
|
||
} );
|
||
}
|
||
else if ( order == 'index' || order == 'original' ) {
|
||
for ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||
if ( search == 'none' ) {
|
||
a.push( i );
|
||
}
|
||
else { // applied | removed
|
||
tmp = $.inArray( i, displayFiltered );
|
||
|
||
if ((tmp === -1 && search == 'removed') ||
|
||
(tmp === 1 && search == 'applied') )
|
||
{
|
||
a.push( i );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return a;
|
||
};
|
||
|
||
|
||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Rows
|
||
*
|
||
* {} - no selector - use all available rows
|
||
* {integer} - row aoData index
|
||
* {node} - TR node
|
||
* {string} - jQuery selector to apply to the TR elements
|
||
* {array} - jQuery array of nodes, or simply an array of TR nodes
|
||
*
|
||
*/
|
||
|
||
|
||
var __row_selector = function ( settings, selector, opts )
|
||
{
|
||
return _selector_run( selector, function ( sel ) {
|
||
var selInt = _intVal( sel );
|
||
|
||
// Short cut - selector is a number and no options provided (default is
|
||
// all records, so no need to check if the index is in there, since it
|
||
// must be - dev error if the index doesn't exist).
|
||
if ( selInt !== null && ! opts ) {
|
||
return [ selInt ];
|
||
}
|
||
|
||
var rows = _selector_row_indexes( settings, opts );
|
||
|
||
if ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {
|
||
// Selector - integer
|
||
return [ selInt ];
|
||
}
|
||
else if ( ! sel ) {
|
||
// Selector - none
|
||
return rows;
|
||
}
|
||
|
||
// Get nodes in the order from the `rows` array (can't use `pluck`) @todo - use pluck_order
|
||
var nodes = [];
|
||
for ( var i=0, ien=rows.length ; i<ien ; i++ ) {
|
||
nodes.push( settings.aoData[ rows[i] ].nTr );
|
||
}
|
||
|
||
if ( sel.nodeName ) {
|
||
// Selector - node
|
||
if ( $.inArray( sel, nodes ) !== -1 ) {
|
||
return [ sel._DT_RowIndex ];// sel is a TR node that is in the table
|
||
// and DataTables adds a prop for fast lookup
|
||
}
|
||
}
|
||
|
||
// Selector - jQuery selector string, array of nodes or jQuery object/
|
||
// As jQuery's .filter() allows jQuery objects to be passed in filter,
|
||
// it also allows arrays, so this will cope with all three options
|
||
return $(nodes)
|
||
.filter( sel )
|
||
.map( function () {
|
||
return this._DT_RowIndex;
|
||
} )
|
||
.toArray();
|
||
} );
|
||
};
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_register( 'rows()', function ( selector, opts ) {
|
||
// argument shifting
|
||
if ( selector === undefined ) {
|
||
selector = '';
|
||
}
|
||
else if ( $.isPlainObject( selector ) ) {
|
||
opts = selector;
|
||
selector = '';
|
||
}
|
||
|
||
opts = _selector_opts( opts );
|
||
|
||
var inst = this.iterator( 'table', function ( settings ) {
|
||
return __row_selector( settings, selector, opts );
|
||
} );
|
||
|
||
// Want argument shifting here and in __row_selector?
|
||
inst.selector.rows = selector;
|
||
inst.selector.opts = opts;
|
||
|
||
return inst;
|
||
} );
|
||
|
||
|
||
_api_register( 'rows().nodes()', function () {
|
||
return this.iterator( 'row', function ( settings, row ) {
|
||
return settings.aoData[ row ].nTr || undefined;
|
||
} );
|
||
} );
|
||
|
||
_api_register( 'rows().data()', function () {
|
||
return this.iterator( true, 'rows', function ( settings, rows ) {
|
||
return _pluck_order( settings.aoData, rows, '_aData' );
|
||
} );
|
||
} );
|
||
|
||
_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {
|
||
return this.iterator( 'row', function ( settings, row ) {
|
||
var r = settings.aoData[ row ];
|
||
return type === 'search' ? r._aFilterData : r._aSortData;
|
||
} );
|
||
} );
|
||
|
||
_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
|
||
return this.iterator( 'row', function ( settings, row ) {
|
||
_fnInvalidateRow( settings, row, src );
|
||
} );
|
||
} );
|
||
|
||
_api_registerPlural( 'rows().indexes()', 'row().index()', function () {
|
||
return this.iterator( 'row', function ( settings, row ) {
|
||
return row;
|
||
} );
|
||
} );
|
||
|
||
_api_registerPlural( 'rows().remove()', 'row().remove()', function () {
|
||
var that = this;
|
||
|
||
return this.iterator( 'row', function ( settings, row, thatIdx ) {
|
||
var data = settings.aoData;
|
||
|
||
data.splice( row, 1 );
|
||
|
||
// Update the _DT_RowIndex parameter on all rows in the table
|
||
for ( var i=0, ien=data.length ; i<ien ; i++ ) {
|
||
if ( data[i].nTr !== null ) {
|
||
data[i].nTr._DT_RowIndex = i;
|
||
}
|
||
}
|
||
|
||
// Remove the target row from the search array
|
||
var displayIndex = $.inArray( row, settings.aiDisplay );
|
||
|
||
// Delete from the display arrays
|
||
_fnDeleteIndex( settings.aiDisplayMaster, row );
|
||
_fnDeleteIndex( settings.aiDisplay, row );
|
||
_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes
|
||
|
||
// Check for an 'overflow' they case for displaying the table
|
||
_fnLengthOverflow( settings );
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( 'rows.add()', function ( rows ) {
|
||
var newRows = this.iterator( 'table', function ( settings ) {
|
||
var row, i, ien;
|
||
var out = [];
|
||
|
||
for ( i=0, ien=rows.length ; i<ien ; i++ ) {
|
||
row = rows[i];
|
||
|
||
if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
|
||
out.push( _fnAddTr( settings, row )[0] );
|
||
}
|
||
else {
|
||
out.push( _fnAddData( settings, row ) );
|
||
}
|
||
}
|
||
|
||
return out;
|
||
} );
|
||
|
||
// Return an Api.rows() extended instance, so rows().nodes() etc can be used
|
||
var modRows = this.rows( -1 );
|
||
modRows.pop();
|
||
modRows.push.apply( modRows, newRows.toArray() );
|
||
|
||
return modRows;
|
||
} );
|
||
|
||
|
||
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_register( 'row()', function ( selector, opts ) {
|
||
return _selector_first( this.rows( selector, opts ) );
|
||
} );
|
||
|
||
|
||
_api_register( 'row().data()', function ( data ) {
|
||
var ctx = this.context;
|
||
|
||
if ( data === undefined ) {
|
||
// Get
|
||
return ctx.length && this.length ?
|
||
ctx[0].aoData[ this[0] ]._aData :
|
||
undefined;
|
||
}
|
||
|
||
// Set
|
||
ctx[0].aoData[ this[0] ]._aData = data;
|
||
|
||
// Automatically invalidate
|
||
_fnInvalidateRow( ctx[0], this[0], 'data' );
|
||
|
||
return this;
|
||
} );
|
||
|
||
|
||
_api_register( 'row().node()', function () {
|
||
var ctx = this.context;
|
||
|
||
return ctx.length && this.length ?
|
||
ctx[0].aoData[ this[0] ].nTr || null :
|
||
null;
|
||
} );
|
||
|
||
|
||
_api_register( 'row.add()', function ( row ) {
|
||
// Allow a jQuery object to be passed in - only a single row is added from
|
||
// it though - the first element in the set
|
||
if ( row instanceof $ && row.length ) {
|
||
row = row[0];
|
||
}
|
||
|
||
var rows = this.iterator( 'table', function ( settings ) {
|
||
if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
|
||
return _fnAddTr( settings, row )[0];
|
||
}
|
||
return _fnAddData( settings, row );
|
||
} );
|
||
|
||
// Return an Api.rows() extended instance, with the newly added row selected
|
||
return this.row( rows[0] );
|
||
} );
|
||
|
||
|
||
|
||
var __details_add = function ( ctx, row, data, klass )
|
||
{
|
||
// Convert to array of TR elements
|
||
var rows = [];
|
||
var addRow = function ( r, k ) {
|
||
// If we get a TR element, then just add it directly - up to the dev
|
||
// to add the correct number of columns etc
|
||
if ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {
|
||
rows.push( r );
|
||
}
|
||
else {
|
||
// Otherwise create a row with a wrapper
|
||
var created = $('<tr><td/></tr>');
|
||
$('td', created)
|
||
.addClass( k )
|
||
.html( r )
|
||
[0].colSpan = _fnVisbleColumns( ctx );
|
||
|
||
rows.push( created[0] );
|
||
}
|
||
};
|
||
|
||
if ( $.isArray( data ) || data instanceof $ ) {
|
||
for ( var i=0, ien=data.length ; i<ien ; i++ ) {
|
||
addRow( data[i], klass );
|
||
}
|
||
}
|
||
else {
|
||
addRow( data, klass );
|
||
}
|
||
|
||
if ( row._details ) {
|
||
row._details.remove();
|
||
}
|
||
|
||
row._details = $(rows);
|
||
|
||
// If the children were already shown, that state should be retained
|
||
if ( row._detailsShow ) {
|
||
row._details.insertAfter( row.nTr );
|
||
}
|
||
};
|
||
|
||
|
||
var __details_display = function ( show ) {
|
||
var ctx = this.context;
|
||
|
||
if ( ctx.length && this.length ) {
|
||
var row = ctx[0].aoData[ this[0] ];
|
||
|
||
if ( row._details ) {
|
||
row._detailsShow = show;
|
||
if ( show ) {
|
||
row._details.insertAfter( row.nTr );
|
||
}
|
||
else {
|
||
row._details.remove();
|
||
}
|
||
|
||
__details_events( ctx[0] );
|
||
}
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
|
||
var __details_events = function ( settings )
|
||
{
|
||
var api = new _Api( settings );
|
||
var namespace = '.dt.DT_details';
|
||
var drawEvent = 'draw'+namespace;
|
||
var colvisEvent = 'column-visibility'+namespace;
|
||
|
||
api.off( drawEvent +' '+ colvisEvent );
|
||
|
||
if ( _pluck( settings.aoData, '_details' ).length > 0 ) {
|
||
// On each draw, insert the required elements into the document
|
||
api.on( drawEvent, function () {
|
||
api.rows( {page:'current'} ).eq(0).each( function (idx) {
|
||
// Internal data grab
|
||
var row = settings.aoData[ idx ];
|
||
|
||
if ( row._detailsShow ) {
|
||
row._details.insertAfter( row.nTr );
|
||
}
|
||
} );
|
||
} );
|
||
|
||
// Column visibility change - update the colspan
|
||
api.on( colvisEvent, function ( e, settings, idx, vis ) {
|
||
// Update the colspan for the details rows (note, only if it already has
|
||
// a colspan)
|
||
var row, visible = _fnVisbleColumns( settings );
|
||
|
||
for ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {
|
||
row = settings.aoData[i];
|
||
|
||
if ( row._details ) {
|
||
row._details.children('td[colspan]').attr('colspan', visible );
|
||
}
|
||
}
|
||
} );
|
||
}
|
||
};
|
||
|
||
// data can be:
|
||
// tr
|
||
// string
|
||
// jQuery or array of any of the above
|
||
_api_register( 'row().child()', function ( data, klass ) {
|
||
var ctx = this.context;
|
||
|
||
if ( data === undefined ) {
|
||
// get
|
||
return ctx.length && this.length ?
|
||
ctx[0].aoData[ this[0] ]._details :
|
||
undefined;
|
||
}
|
||
else if ( ctx.length && this.length ) {
|
||
// set
|
||
__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );
|
||
}
|
||
|
||
return this;
|
||
} );
|
||
|
||
_api_register( [
|
||
'row().child.show()',
|
||
'row().child().show()'
|
||
], function () {
|
||
__details_display.call( this, true );
|
||
return this;
|
||
} );
|
||
|
||
_api_register( [
|
||
'row().child.hide()',
|
||
'row().child().hide()'
|
||
], function () {
|
||
__details_display.call( this, false );
|
||
return this;
|
||
} );
|
||
|
||
_api_register( 'row().child.isShown()', function () {
|
||
var ctx = this.context;
|
||
|
||
if ( ctx.length && this.length ) {
|
||
// _detailsShown as false or undefined will fall through to return false
|
||
return ctx[0].aoData[ this[0] ]._detailsShow || false;
|
||
}
|
||
return false;
|
||
} );
|
||
|
||
|
||
|
||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||
* Columns
|
||
*
|
||
* {integer} - column index (>=0 count from left, <0 count from right)
|
||
* "{integer}:visIdx" - visible column index (i.e. translate to column index) (>=0 count from left, <0 count from right)
|
||
* "{integer}:visible" - alias for {integer}:visIdx (>=0 count from left, <0 count from right)
|
||
* "{string}:name" - column name
|
||
* "{string}" - jQuery selector on column header nodes
|
||
*
|
||
*/
|
||
|
||
// can be an array of these items, comma separated list, or an array of comma
|
||
// separated lists
|
||
|
||
var __re_column_selector = /^(.*):(name|visIdx|visible)$/;
|
||
|
||
var __column_selector = function ( settings, selector, opts )
|
||
{
|
||
var
|
||
columns = settings.aoColumns,
|
||
names = _pluck( columns, 'sName' ),
|
||
nodes = _pluck( columns, 'nTh' );
|
||
|
||
return _selector_run( selector, function ( s ) {
|
||
var selInt = _intVal( s );
|
||
|
||
if ( s === '' ) {
|
||
// All columns
|
||
return _range( columns.length );
|
||
}
|
||
else if ( selInt !== null ) {
|
||
// Integer selector
|
||
return [ selInt >= 0 ?
|
||
selInt : // Count from left
|
||
columns.length + selInt // Count from right (+ because its a negative value)
|
||
];
|
||
}
|
||
else {
|
||
var match = typeof s === 'string' ?
|
||
s.match( __re_column_selector ) :
|
||
'';
|
||
|
||
if ( match ) {
|
||
switch( match[2] ) {
|
||
case 'visIdx':
|
||
case 'visible':
|
||
var idx = parseInt( match[1], 10 );
|
||
// Visible index given, convert to column index
|
||
if ( idx < 0 ) {
|
||
// Counting from the right
|
||
var visColumns = $.map( columns, function (col,i) {
|
||
return col.bVisible ? i : null;
|
||
} );
|
||
return [ visColumns[ visColumns.length + idx ] ];
|
||
}
|
||
// Counting from the left
|
||
return [ _fnVisibleToColumnIndex( settings, idx ) ];
|
||
|
||
case 'name':
|
||
// match by name. `names` is column index complete and in order
|
||
return $.map( names, function (name, i) {
|
||
return name === match[1] ? i : null;
|
||
} );
|
||
}
|
||
}
|
||
else {
|
||
// jQuery selector on the TH elements for the columns
|
||
return $( nodes )
|
||
.filter( s )
|
||
.map( function () {
|
||
return $.inArray( this, nodes ); // `nodes` is column index complete and in order
|
||
} )
|
||
.toArray();
|
||
}
|
||
}
|
||
} );
|
||
};
|
||
|
||
|
||
|
||
|
||
|
||
var __setColumnVis = function ( settings, column, vis ) {
|
||
var
|
||
cols = settings.aoColumns,
|
||
col = cols[ column ],
|
||
data = settings.aoData,
|
||
row, cells, i, ien, tr;
|
||
|
||
// Get
|
||
if ( vis === undefined ) {
|
||
return col.bVisible;
|
||
}
|
||
|
||
// Set
|
||
// No change
|
||
if ( col.bVisible === vis ) {
|
||
return;
|
||
}
|
||
|
||
if ( vis ) {
|
||
// Insert column
|
||
// Need to decide if we should use appendChild or insertBefore
|
||
var insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );
|
||
|
||
for ( i=0, ien=data.length ; i<ien ; i++ ) {
|
||
tr = data[i].nTr;
|
||
cells = data[i].anCells;
|
||
|
||
if ( tr ) {
|
||
// insertBefore can act like appendChild if 2nd arg is null
|
||
tr.insertBefore( cells[ column ], cells[ insertBefore ] || null );
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
// Remove column
|
||
$( _pluck( settings.aoData, 'anCells', column ) ).detach();
|
||
|
||
col.bVisible = false;
|
||
_fnDrawHead( settings, settings.aoHeader );
|
||
_fnDrawHead( settings, settings.aoFooter );
|
||
|
||
_fnSaveState( settings );
|
||
}
|
||
|
||
// Common actions
|
||
col.bVisible = vis;
|
||
_fnDrawHead( settings, settings.aoHeader );
|
||
_fnDrawHead( settings, settings.aoFooter );
|
||
|
||
// Automatically adjust column sizing
|
||
_fnAdjustColumnSizing( settings );
|
||
|
||
// Realign columns for scrolling
|
||
if ( settings.oScroll.sX || settings.oScroll.sY ) {
|
||
_fnScrollDraw( settings );
|
||
}
|
||
|
||
_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis] );
|
||
|
||
_fnSaveState( settings );
|
||
};
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_register( 'columns()', function ( selector, opts ) {
|
||
// argument shifting
|
||
if ( selector === undefined ) {
|
||
selector = '';
|
||
}
|
||
else if ( $.isPlainObject( selector ) ) {
|
||
opts = selector;
|
||
selector = '';
|
||
}
|
||
|
||
opts = _selector_opts( opts );
|
||
|
||
var inst = this.iterator( 'table', function ( settings ) {
|
||
return __column_selector( settings, selector, opts );
|
||
} );
|
||
|
||
// Want argument shifting here and in _row_selector?
|
||
inst.selector.cols = selector;
|
||
inst.selector.opts = opts;
|
||
|
||
return inst;
|
||
} );
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {
|
||
return this.iterator( 'column', function ( settings, column ) {
|
||
return settings.aoColumns[column].nTh;
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {
|
||
return this.iterator( 'column', function ( settings, column ) {
|
||
return settings.aoColumns[column].nTf;
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_registerPlural( 'columns().data()', 'column().data()', function () {
|
||
return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
|
||
var a = [];
|
||
for ( var row=0, ien=rows.length ; row<ien ; row++ ) {
|
||
a.push( _fnGetCellData( settings, rows[row], column, '' ) );
|
||
}
|
||
return a;
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {
|
||
return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
|
||
return _pluck_order( settings.aoData, rows,
|
||
type === 'search' ? '_aFilterData' : '_aSortData', column
|
||
);
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {
|
||
return this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {
|
||
return _pluck_order( settings.aoData, rows, 'anCells', column ) ;
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis ) {
|
||
return this.iterator( 'column', function ( settings, column ) {
|
||
return vis === undefined ?
|
||
settings.aoColumns[ column ].bVisible :
|
||
__setColumnVis( settings, column, vis );
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {
|
||
return this.iterator( 'column', function ( settings, column ) {
|
||
return type === 'visible' ?
|
||
_fnColumnIndexToVisible( settings, column ) :
|
||
column;
|
||
} );
|
||
} );
|
||
|
||
|
||
// _api_register( 'columns().show()', function () {
|
||
// var selector = this.selector;
|
||
// return this.columns( selector.cols, selector.opts ).visible( true );
|
||
// } );
|
||
|
||
|
||
// _api_register( 'columns().hide()', function () {
|
||
// var selector = this.selector;
|
||
// return this.columns( selector.cols, selector.opts ).visible( false );
|
||
// } );
|
||
|
||
|
||
|
||
_api_register( 'columns.adjust()', function () {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnAdjustColumnSizing( settings );
|
||
} );
|
||
} );
|
||
|
||
|
||
// Convert from one column index type, to another type
|
||
_api_register( 'column.index()', function ( type, idx ) {
|
||
if ( this.context.length !== 0 ) {
|
||
var ctx = this.context[0];
|
||
|
||
if ( type === 'fromVisible' || type === 'toData' ) {
|
||
return _fnVisibleToColumnIndex( ctx, idx );
|
||
}
|
||
else if ( type === 'fromData' || type === 'toVisible' ) {
|
||
return _fnColumnIndexToVisible( ctx, idx );
|
||
}
|
||
}
|
||
} );
|
||
|
||
|
||
_api_register( 'column()', function ( selector, opts ) {
|
||
return _selector_first( this.columns( selector, opts ) );
|
||
} );
|
||
|
||
|
||
|
||
|
||
var __cell_selector = function ( settings, selector, opts )
|
||
{
|
||
var data = settings.aoData;
|
||
var rows = _selector_row_indexes( settings, opts );
|
||
var cells = _pluck_order( data, rows, 'anCells' );
|
||
var allCells = $( [].concat.apply([], cells) );
|
||
var row;
|
||
var columns = settings.aoColumns.length;
|
||
var a, i, ien, j;
|
||
|
||
return _selector_run( selector, function ( s ) {
|
||
if ( ! s ) {
|
||
// All cells
|
||
a = [];
|
||
|
||
for ( i=0, ien=rows.length ; i<ien ; i++ ) {
|
||
row = rows[i];
|
||
|
||
for ( j=0 ; j<columns ; j++ ) {
|
||
a.push( {
|
||
row: row,
|
||
column: j
|
||
} );
|
||
}
|
||
}
|
||
|
||
return a;
|
||
}
|
||
else if ( $.isPlainObject( s ) ) {
|
||
return [s];
|
||
}
|
||
|
||
// jQuery filtered cells
|
||
return allCells
|
||
.filter( s )
|
||
.map( function (i, el) {
|
||
row = el.parentNode._DT_RowIndex;
|
||
|
||
return {
|
||
row: row,
|
||
column: $.inArray( el, data[ row ].anCells )
|
||
};
|
||
} )
|
||
.toArray();
|
||
} );
|
||
};
|
||
|
||
|
||
|
||
|
||
_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {
|
||
// Argument shifting
|
||
if ( $.isPlainObject( rowSelector ) ) {
|
||
// If passing in a cell index
|
||
if ( rowSelector.row ) {
|
||
opts = columnSelector;
|
||
columnSelector = null;
|
||
}
|
||
else {
|
||
opts = rowSelector;
|
||
rowSelector = null;
|
||
}
|
||
}
|
||
if ( $.isPlainObject( columnSelector ) ) {
|
||
opts = columnSelector;
|
||
columnSelector = null;
|
||
}
|
||
|
||
// Cell selector
|
||
if ( columnSelector === null || columnSelector === undefined ) {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
return __cell_selector( settings, rowSelector, _selector_opts( opts ) );
|
||
} );
|
||
}
|
||
|
||
// Row + column selector
|
||
var columns = this.columns( columnSelector, opts );
|
||
var rows = this.rows( rowSelector, opts );
|
||
var a, i, ien, j, jen;
|
||
|
||
var cells = this.iterator( 'table', function ( settings, idx ) {
|
||
a = [];
|
||
|
||
for ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {
|
||
for ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {
|
||
a.push( {
|
||
row: rows[idx][i],
|
||
column: columns[idx][j]
|
||
} );
|
||
}
|
||
}
|
||
|
||
return a;
|
||
} );
|
||
|
||
$.extend( cells.selector, {
|
||
cols: columnSelector,
|
||
rows: rowSelector,
|
||
opts: opts
|
||
} );
|
||
|
||
return cells;
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {
|
||
return this.iterator( 'cell', function ( settings, row, column ) {
|
||
return settings.aoData[ row ].anCells[ column ];
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( 'cells().data()', function () {
|
||
return this.iterator( 'cell', function ( settings, row, column ) {
|
||
return _fnGetCellData( settings, row, column );
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {
|
||
type = type === 'search' ? '_aFilterData' : '_aSortData';
|
||
|
||
return this.iterator( 'cell', function ( settings, row, column ) {
|
||
return settings.aoData[ row ][ type ][ column ];
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {
|
||
return this.iterator( 'cell', function ( settings, row, column ) {
|
||
return {
|
||
row: row,
|
||
column: column,
|
||
columnVisible: _fnColumnIndexToVisible( settings, column )
|
||
};
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( [
|
||
'cells().invalidate()',
|
||
'cell().invalidate()'
|
||
], function ( src ) {
|
||
var selector = this.selector;
|
||
|
||
// Use the rows method of the instance to perform the invalidation, rather
|
||
// than doing it here. This avoids needing to handle duplicate rows from
|
||
// the cells.
|
||
this.rows( selector.rows, selector.opts ).invalidate( src );
|
||
|
||
return this;
|
||
} );
|
||
|
||
|
||
|
||
|
||
_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {
|
||
return _selector_first( this.cells( rowSelector, columnSelector, opts ) );
|
||
} );
|
||
|
||
|
||
|
||
_api_register( 'cell().data()', function ( data ) {
|
||
var ctx = this.context;
|
||
var cell = this[0];
|
||
|
||
if ( data === undefined ) {
|
||
// Get
|
||
return ctx.length && cell.length ?
|
||
_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :
|
||
undefined;
|
||
}
|
||
|
||
// Set
|
||
_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );
|
||
_fnInvalidateRow( ctx[0], cell[0].row, 'data', cell[0].column );
|
||
|
||
return this;
|
||
} );
|
||
|
||
|
||
|
||
/**
|
||
* Get current ordering (sorting) that has been applied to the table.
|
||
*
|
||
* @returns {array} 2D array containing the sorting information for the first
|
||
* table in the current context. Each element in the parent array represents
|
||
* a column being sorted upon (i.e. multi-sorting with two columns would have
|
||
* 2 inner arrays). The inner arrays may have 2 or 3 elements. The first is
|
||
* the column index that the sorting condition applies to, the second is the
|
||
* direction of the sort (`desc` or `asc`) and, optionally, the third is the
|
||
* index of the sorting order from the `column.sorting` initialisation array.
|
||
*//**
|
||
* Set the ordering for the table.
|
||
*
|
||
* @param {integer} order Column index to sort upon.
|
||
* @param {string} direction Direction of the sort to be applied (`asc` or `desc`)
|
||
* @returns {DataTables.Api} this
|
||
*//**
|
||
* Set the ordering for the table.
|
||
*
|
||
* @param {array} order 1D array of sorting information to be applied.
|
||
* @param {array} [...] Optional additional sorting conditions
|
||
* @returns {DataTables.Api} this
|
||
*//**
|
||
* Set the ordering for the table.
|
||
*
|
||
* @param {array} order 2D array of sorting information to be applied.
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'order()', function ( order, dir ) {
|
||
var ctx = this.context;
|
||
|
||
if ( order === undefined ) {
|
||
// get
|
||
return ctx.length !== 0 ?
|
||
ctx[0].aaSorting :
|
||
undefined;
|
||
}
|
||
|
||
// set
|
||
if ( typeof order === 'number' ) {
|
||
// Simple column / direction passed in
|
||
order = [ [ order, dir ] ];
|
||
}
|
||
else if ( ! $.isArray( order[0] ) ) {
|
||
// Arguments passed in (list of 1D arrays)
|
||
order = Array.prototype.slice.call( arguments );
|
||
}
|
||
// otherwise a 2D array was passed in
|
||
|
||
return this.iterator( 'table', function ( settings ) {
|
||
settings.aaSorting = order.slice();
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
* Attach a sort listener to an element for a given column
|
||
*
|
||
* @param {node|jQuery|string} node Identifier for the element(s) to attach the
|
||
* listener to. This can take the form of a single DOM node, a jQuery
|
||
* collection of nodes or a jQuery selector which will identify the node(s).
|
||
* @param {integer} column the column that a click on this node will sort on
|
||
* @param {function} [callback] callback function when sort is run
|
||
* @returns {DataTables.Api} this
|
||
*/
|
||
_api_register( 'order.listener()', function ( node, column, callback ) {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnSortAttachListener( settings, node, column, callback );
|
||
} );
|
||
} );
|
||
|
||
|
||
// Order by the selected column(s)
|
||
_api_register( [
|
||
'columns().order()',
|
||
'column().order()'
|
||
], function ( dir ) {
|
||
var that = this;
|
||
|
||
return this.iterator( 'table', function ( settings, i ) {
|
||
var sort = [];
|
||
|
||
$.each( that[i], function (j, col) {
|
||
sort.push( [ col, dir ] );
|
||
} );
|
||
|
||
settings.aaSorting = sort;
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
_api_register( 'search()', function ( input, regex, smart, caseInsen ) {
|
||
var ctx = this.context;
|
||
|
||
if ( input === undefined ) {
|
||
// get
|
||
return ctx.length !== 0 ?
|
||
ctx[0].oPreviousSearch.sSearch :
|
||
undefined;
|
||
}
|
||
|
||
// set
|
||
return this.iterator( 'table', function ( settings ) {
|
||
if ( ! settings.oFeatures.bFilter ) {
|
||
return;
|
||
}
|
||
|
||
_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {
|
||
"sSearch": input+"",
|
||
"bRegex": regex === null ? false : regex,
|
||
"bSmart": smart === null ? true : smart,
|
||
"bCaseInsensitive": caseInsen === null ? true : caseInsen
|
||
} ), 1 );
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( [
|
||
'columns().search()',
|
||
'column().search()'
|
||
], function ( input, regex, smart, caseInsen ) {
|
||
return this.iterator( 'column', function ( settings, column ) {
|
||
var preSearch = settings.aoPreSearchCols;
|
||
|
||
if ( input === undefined ) {
|
||
// get
|
||
return preSearch[ column ].sSearch;
|
||
}
|
||
|
||
// set
|
||
if ( ! settings.oFeatures.bFilter ) {
|
||
return;
|
||
}
|
||
|
||
$.extend( preSearch[ column ], {
|
||
"sSearch": input+"",
|
||
"bRegex": regex === null ? false : regex,
|
||
"bSmart": smart === null ? true : smart,
|
||
"bCaseInsensitive": caseInsen === null ? true : caseInsen
|
||
} );
|
||
|
||
_fnFilterComplete( settings, settings.oPreviousSearch, 1 );
|
||
} );
|
||
} );
|
||
|
||
|
||
|
||
/**
|
||
* Provide a common method for plug-ins to check the version of DataTables being
|
||
* used, in order to ensure compatibility.
|
||
*
|
||
* @param {string} version Version string to check for, in the format "X.Y.Z".
|
||
* Note that the formats "X" and "X.Y" are also acceptable.
|
||
* @returns {boolean} true if this version of DataTables is greater or equal to
|
||
* the required version, or false if this version of DataTales is not
|
||
* suitable
|
||
* @static
|
||
* @dtopt API-Static
|
||
*
|
||
* @example
|
||
* alert( $.fn.dataTable.versionCheck( '1.9.0' ) );
|
||
*/
|
||
DataTable.versionCheck = DataTable.fnVersionCheck = function( version )
|
||
{
|
||
var aThis = DataTable.version.split('.');
|
||
var aThat = version.split('.');
|
||
var iThis, iThat;
|
||
|
||
for ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {
|
||
iThis = parseInt( aThis[i], 10 ) || 0;
|
||
iThat = parseInt( aThat[i], 10 ) || 0;
|
||
|
||
// Parts are the same, keep comparing
|
||
if (iThis === iThat) {
|
||
continue;
|
||
}
|
||
|
||
// Parts are different, return immediately
|
||
return iThis > iThat;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
|
||
/**
|
||
* Check if a `<table>` node is a DataTable table already or not.
|
||
*
|
||
* @param {node|jquery|string} table Table node, jQuery object or jQuery
|
||
* selector for the table to test. Note that if more than more than one
|
||
* table is passed on, only the first will be checked
|
||
* @returns {boolean} true the table given is a DataTable, or false otherwise
|
||
* @static
|
||
* @dtopt API-Static
|
||
*
|
||
* @example
|
||
* if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {
|
||
* $('#example').dataTable();
|
||
* }
|
||
*/
|
||
DataTable.isDataTable = DataTable.fnIsDataTable = function ( table )
|
||
{
|
||
var t = $(table).get(0);
|
||
var is = false;
|
||
|
||
$.each( DataTable.settings, function (i, o) {
|
||
if ( o.nTable === t || o.nScrollHead === t || o.nScrollFoot === t ) {
|
||
is = true;
|
||
}
|
||
} );
|
||
|
||
return is;
|
||
};
|
||
|
||
|
||
/**
|
||
* Get all DataTable tables that have been initialised - optionally you can
|
||
* select to get only currently visible tables.
|
||
*
|
||
* @param {boolean} [visible=false] Flag to indicate if you want all (default)
|
||
* or visible tables only.
|
||
* @returns {array} Array of `table` nodes (not DataTable instances) which are
|
||
* DataTables
|
||
* @static
|
||
* @dtopt API-Static
|
||
*
|
||
* @example
|
||
* $.each( $.fn.dataTable.tables(true), function () {
|
||
* $(table).DataTable().columns.adjust();
|
||
* } );
|
||
*/
|
||
DataTable.tables = DataTable.fnTables = function ( visible )
|
||
{
|
||
return jQuery.map( DataTable.settings, function (o) {
|
||
if ( !visible || (visible && $(o.nTable).is(':visible')) ) {
|
||
return o.nTable;
|
||
}
|
||
} );
|
||
};
|
||
|
||
|
||
/**
|
||
* Convert from camel case parameters to Hungarian notation. This is made public
|
||
* for the extensions to provide the same ability as DataTables core to accept
|
||
* either the 1.9 style Hungarian notation, or the 1.10+ style camelCase
|
||
* parameters.
|
||
*
|
||
* @param {object} src The model object which holds all parameters that can be
|
||
* mapped.
|
||
* @param {object} user The object to convert from camel case to Hungarian.
|
||
* @param {boolean} force When set to `true`, properties which already have a
|
||
* Hungarian value in the `user` object will be overwritten. Otherwise they
|
||
* won't be.
|
||
*/
|
||
DataTable.camelToHungarian = _fnCamelToHungarian;
|
||
|
||
|
||
|
||
/**
|
||
*
|
||
*/
|
||
_api_register( '$()', function ( selector, opts ) {
|
||
var
|
||
rows = this.rows( opts ).nodes(), // Get all rows
|
||
jqRows = $(rows);
|
||
|
||
return $( [].concat(
|
||
jqRows.filter( selector ).toArray(),
|
||
jqRows.find( selector ).toArray()
|
||
) );
|
||
} );
|
||
|
||
|
||
// jQuery functions to operate on the tables
|
||
$.each( [ 'on', 'one', 'off' ], function (i, key) {
|
||
_api_register( key+'()', function ( /* event, handler */ ) {
|
||
var args = Array.prototype.slice.call(arguments);
|
||
|
||
// Add the `dt` namespace automatically if it isn't already present
|
||
if ( args[0].indexOf( '.dt' ) === -1 ) {
|
||
args[0] += '.dt';
|
||
}
|
||
|
||
var inst = $( this.tables().nodes() );
|
||
inst[key].apply( inst, args );
|
||
return this;
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( 'clear()', function () {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
_fnClearTable( settings );
|
||
} );
|
||
} );
|
||
|
||
|
||
_api_register( 'settings()', function () {
|
||
return new _Api( this.context, this.context );
|
||
} );
|
||
|
||
|
||
_api_register( 'data()', function () {
|
||
return this.iterator( 'table', function ( settings ) {
|
||
return _pluck( settings.aoData, '_aData' );
|
||
} ).flatten();
|
||
} );
|
||
|
||
|
||
_api_register( 'destroy()', function ( remove ) {
|
||
remove = remove || false;
|
||
|
||
return this.iterator( 'table', function ( settings ) {
|
||
var orig = settings.nTableWrapper.parentNode;
|
||
var classes = settings.oClasses;
|
||
var table = settings.nTable;
|
||
var tbody = settings.nTBody;
|
||
var thead = settings.nTHead;
|
||
var tfoot = settings.nTFoot;
|
||
var jqTable = $(table);
|
||
var jqTbody = $(tbody);
|
||
var jqWrapper = $(settings.nTableWrapper);
|
||
var rows = $.map( settings.aoData, function (r) { return r.nTr; } );
|
||
var i, ien;
|
||
|
||
// Flag to note that the table is currently being destroyed - no action
|
||
// should be taken
|
||
settings.bDestroying = true;
|
||
|
||
// Fire off the destroy callbacks for plug-ins etc
|
||
_fnCallbackFire( settings, "aoDestroyCallback", "destroy", [settings] );
|
||
|
||
// If not being removed from the document, make all columns visible
|
||
if ( ! remove ) {
|
||
new _Api( settings ).columns().visible( true );
|
||
}
|
||
|
||
// Blitz all `DT` namespaced events (these are internal events, the
|
||
// lowercase, `dt` events are user subscribed and they are responsible
|
||
// for removing them
|
||
jqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');
|
||
$(window).unbind('.DT-'+settings.sInstance);
|
||
|
||
// When scrolling we had to break the table up - restore it
|
||
if ( table != thead.parentNode ) {
|
||
jqTable.children('thead').detach();
|
||
jqTable.append( thead );
|
||
}
|
||
|
||
if ( tfoot && table != tfoot.parentNode ) {
|
||
jqTable.children('tfoot').detach();
|
||
jqTable.append( tfoot );
|
||
}
|
||
|
||
// Remove the DataTables generated nodes, events and classes
|
||
jqTable.detach();
|
||
jqWrapper.detach();
|
||
|
||
settings.aaSorting = [];
|
||
settings.aaSortingFixed = [];
|
||
_fnSortingClasses( settings );
|
||
|
||
$( rows ).removeClass( settings.asStripeClasses.join(' ') );
|
||
|
||
$('th, td', thead).removeClass( classes.sSortable+' '+
|
||
classes.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone
|
||
);
|
||
|
||
if ( settings.bJUI ) {
|
||
$('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();
|
||
$('th, td', thead).each( function () {
|
||
var wrapper = $('div.'+classes.sSortJUIWrapper, this);
|
||
$(this).append( wrapper.contents() );
|
||
wrapper.detach();
|
||
} );
|
||
}
|
||
|
||
if ( ! remove && orig ) {
|
||
// insertBefore acts like appendChild if !arg[1]
|
||
orig.insertBefore( table, settings.nTableReinsertBefore );
|
||
}
|
||
|
||
// Add the TR elements back into the table in their original order
|
||
jqTbody.children().detach();
|
||
jqTbody.append( rows );
|
||
|
||
// Restore the width of the original table - was read from the style property,
|
||
// so we can restore directly to that
|
||
jqTable
|
||
.css( 'width', settings.sDestroyWidth )
|
||
.removeClass( classes.sTable );
|
||
|
||
// If the were originally stripe classes - then we add them back here.
|
||
// Note this is not fool proof (for example if not all rows had stripe
|
||
// classes - but it's a good effort without getting carried away
|
||
ien = settings.asDestroyStripes.length;
|
||
|
||
if ( ien ) {
|
||
jqTbody.children().each( function (i) {
|
||
$(this).addClass( settings.asDestroyStripes[i % ien] );
|
||
} );
|
||
}
|
||
|
||
/* Remove the settings object from the settings array */
|
||
var idx = $.inArray( settings, DataTable.settings );
|
||
if ( idx !== -1 ) {
|
||
DataTable.settings.splice( idx, 1 );
|
||
}
|
||
} );
|
||
} );
|
||
|
||
|
||
/**
|
||
* Version string for plug-ins to check compatibility. Allowed format is
|
||
* `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used
|
||
* only for non-release builds. See http://semver.org/ for more information.
|
||
* @member
|
||
* @type string
|
||
* @default Version number
|
||
*/
|
||
DataTable.version = "1.10.0";
|
||
|
||
/**
|
||
* Private data store, containing all of the settings objects that are
|
||
* created for the tables on a given page.
|
||
*
|
||
* Note that the `DataTable.settings` object is aliased to
|
||
* `jQuery.fn.dataTableExt` through which it may be accessed and
|
||
* manipulated, or `jQuery.fn.dataTable.settings`.
|
||
* @member
|
||
* @type array
|
||
* @default []
|
||
* @private
|
||
*/
|
||
DataTable.settings = [];
|
||
|
||
/**
|
||
* Object models container, for the various models that DataTables has
|
||
* available to it. These models define the objects that are used to hold
|
||
* the active state and configuration of the table.
|
||
* @namespace
|
||
*/
|
||
DataTable.models = {};
|
||
|
||
|
||
|
||
/**
|
||
* Template object for the way in which DataTables holds information about
|
||
* search information for the global filter and individual column filters.
|
||
* @namespace
|
||
*/
|
||
DataTable.models.oSearch = {
|
||
/**
|
||
* Flag to indicate if the filtering should be case insensitive or not
|
||
* @type boolean
|
||
* @default true
|
||
*/
|
||
"bCaseInsensitive": true,
|
||
|
||
/**
|
||
* Applied search term
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
*/
|
||
"sSearch": "",
|
||
|
||
/**
|
||
* Flag to indicate if the search term should be interpreted as a
|
||
* regular expression (true) or not (false) and therefore and special
|
||
* regex characters escaped.
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bRegex": false,
|
||
|
||
/**
|
||
* Flag to indicate if DataTables is to use its smart filtering or not.
|
||
* @type boolean
|
||
* @default true
|
||
*/
|
||
"bSmart": true
|
||
};
|
||
|
||
|
||
|
||
|
||
/**
|
||
* Template object for the way in which DataTables holds information about
|
||
* each individual row. This is the object format used for the settings
|
||
* aoData array.
|
||
* @namespace
|
||
*/
|
||
DataTable.models.oRow = {
|
||
/**
|
||
* TR element for the row
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTr": null,
|
||
|
||
/**
|
||
* Array of TD elements for each row. This is null until the row has been
|
||
* created.
|
||
* @type array nodes
|
||
* @default []
|
||
*/
|
||
"anCells": null,
|
||
|
||
/**
|
||
* Data object from the original data source for the row. This is either
|
||
* an array if using the traditional form of DataTables, or an object if
|
||
* using mData options. The exact type will depend on the passed in
|
||
* data from the data source, or will be an array if using DOM a data
|
||
* source.
|
||
* @type array|object
|
||
* @default []
|
||
*/
|
||
"_aData": [],
|
||
|
||
/**
|
||
* Sorting data cache - this array is ostensibly the same length as the
|
||
* number of columns (although each index is generated only as it is
|
||
* needed), and holds the data that is used for sorting each column in the
|
||
* row. We do this cache generation at the start of the sort in order that
|
||
* the formatting of the sort data need be done only once for each cell
|
||
* per sort. This array should not be read from or written to by anything
|
||
* other than the master sorting methods.
|
||
* @type array
|
||
* @default null
|
||
* @private
|
||
*/
|
||
"_aSortData": null,
|
||
|
||
/**
|
||
* Per cell filtering data cache. As per the sort data cache, used to
|
||
* increase the performance of the filtering in DataTables
|
||
* @type array
|
||
* @default null
|
||
* @private
|
||
*/
|
||
"_aFilterData": null,
|
||
|
||
/**
|
||
* Filtering data cache. This is the same as the cell filtering cache, but
|
||
* in this case a string rather than an array. This is easily computed with
|
||
* a join on `_aFilterData`, but is provided as a cache so the join isn't
|
||
* needed on every search (memory traded for performance)
|
||
* @type array
|
||
* @default null
|
||
* @private
|
||
*/
|
||
"_sFilterRow": null,
|
||
|
||
/**
|
||
* Cache of the class name that DataTables has applied to the row, so we
|
||
* can quickly look at this variable rather than needing to do a DOM check
|
||
* on className for the nTr property.
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
* @private
|
||
*/
|
||
"_sRowStripe": "",
|
||
|
||
/**
|
||
* Denote if the original data source was from the DOM, or the data source
|
||
* object. This is used for invalidating data, so DataTables can
|
||
* automatically read data from the original source, unless uninstructed
|
||
* otherwise.
|
||
* @type string
|
||
* @default null
|
||
* @private
|
||
*/
|
||
"src": null
|
||
};
|
||
|
||
|
||
/**
|
||
* Template object for the column information object in DataTables. This object
|
||
* is held in the settings aoColumns array and contains all the information that
|
||
* DataTables needs about each individual column.
|
||
*
|
||
* Note that this object is related to {@link DataTable.defaults.column}
|
||
* but this one is the internal data store for DataTables's cache of columns.
|
||
* It should NOT be manipulated outside of DataTables. Any configuration should
|
||
* be done through the initialisation options.
|
||
* @namespace
|
||
*/
|
||
DataTable.models.oColumn = {
|
||
/**
|
||
* Column index. This could be worked out on-the-fly with $.inArray, but it
|
||
* is faster to just hold it as a variable
|
||
* @type integer
|
||
* @default null
|
||
*/
|
||
"idx": null,
|
||
|
||
/**
|
||
* A list of the columns that sorting should occur on when this column
|
||
* is sorted. That this property is an array allows multi-column sorting
|
||
* to be defined for a column (for example first name / last name columns
|
||
* would benefit from this). The values are integers pointing to the
|
||
* columns to be sorted on (typically it will be a single integer pointing
|
||
* at itself, but that doesn't need to be the case).
|
||
* @type array
|
||
*/
|
||
"aDataSort": null,
|
||
|
||
/**
|
||
* Define the sorting directions that are applied to the column, in sequence
|
||
* as the column is repeatedly sorted upon - i.e. the first value is used
|
||
* as the sorting direction when the column if first sorted (clicked on).
|
||
* Sort it again (click again) and it will move on to the next index.
|
||
* Repeat until loop.
|
||
* @type array
|
||
*/
|
||
"asSorting": null,
|
||
|
||
/**
|
||
* Flag to indicate if the column is searchable, and thus should be included
|
||
* in the filtering or not.
|
||
* @type boolean
|
||
*/
|
||
"bSearchable": null,
|
||
|
||
/**
|
||
* Flag to indicate if the column is sortable or not.
|
||
* @type boolean
|
||
*/
|
||
"bSortable": null,
|
||
|
||
/**
|
||
* Flag to indicate if the column is currently visible in the table or not
|
||
* @type boolean
|
||
*/
|
||
"bVisible": null,
|
||
|
||
/**
|
||
* Store for manual type assignment using the `column.type` option. This
|
||
* is held in store so we can manipulate the column's `sType` property.
|
||
* @type string
|
||
* @default null
|
||
* @private
|
||
*/
|
||
"_sManualType": null,
|
||
|
||
/**
|
||
* Flag to indicate if HTML5 data attributes should be used as the data
|
||
* source for filtering or sorting. True is either are.
|
||
* @type boolean
|
||
* @default false
|
||
* @private
|
||
*/
|
||
"_bAttrSrc": false,
|
||
|
||
/**
|
||
* Developer definable function that is called whenever a cell is created (Ajax source,
|
||
* etc) or processed for input (DOM source). This can be used as a compliment to mRender
|
||
* allowing you to modify the DOM element (add background colour for example) when the
|
||
* element is available.
|
||
* @type function
|
||
* @param {element} nTd The TD node that has been created
|
||
* @param {*} sData The Data for the cell
|
||
* @param {array|object} oData The data for the whole row
|
||
* @param {int} iRow The row index for the aoData data store
|
||
* @default null
|
||
*/
|
||
"fnCreatedCell": null,
|
||
|
||
/**
|
||
* Function to get data from a cell in a column. You should <b>never</b>
|
||
* access data directly through _aData internally in DataTables - always use
|
||
* the method attached to this property. It allows mData to function as
|
||
* required. This function is automatically assigned by the column
|
||
* initialisation method
|
||
* @type function
|
||
* @param {array|object} oData The data array/object for the array
|
||
* (i.e. aoData[]._aData)
|
||
* @param {string} sSpecific The specific data type you want to get -
|
||
* 'display', 'type' 'filter' 'sort'
|
||
* @returns {*} The data for the cell from the given row's data
|
||
* @default null
|
||
*/
|
||
"fnGetData": null,
|
||
|
||
/**
|
||
* Function to set data for a cell in the column. You should <b>never</b>
|
||
* set the data directly to _aData internally in DataTables - always use
|
||
* this method. It allows mData to function as required. This function
|
||
* is automatically assigned by the column initialisation method
|
||
* @type function
|
||
* @param {array|object} oData The data array/object for the array
|
||
* (i.e. aoData[]._aData)
|
||
* @param {*} sValue Value to set
|
||
* @default null
|
||
*/
|
||
"fnSetData": null,
|
||
|
||
/**
|
||
* Property to read the value for the cells in the column from the data
|
||
* source array / object. If null, then the default content is used, if a
|
||
* function is given then the return from the function is used.
|
||
* @type function|int|string|null
|
||
* @default null
|
||
*/
|
||
"mData": null,
|
||
|
||
/**
|
||
* Partner property to mData which is used (only when defined) to get
|
||
* the data - i.e. it is basically the same as mData, but without the
|
||
* 'set' option, and also the data fed to it is the result from mData.
|
||
* This is the rendering method to match the data method of mData.
|
||
* @type function|int|string|null
|
||
* @default null
|
||
*/
|
||
"mRender": null,
|
||
|
||
/**
|
||
* Unique header TH/TD element for this column - this is what the sorting
|
||
* listener is attached to (if sorting is enabled.)
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTh": null,
|
||
|
||
/**
|
||
* Unique footer TH/TD element for this column (if there is one). Not used
|
||
* in DataTables as such, but can be used for plug-ins to reference the
|
||
* footer for each column.
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTf": null,
|
||
|
||
/**
|
||
* The class to apply to all TD elements in the table's TBODY for the column
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sClass": null,
|
||
|
||
/**
|
||
* When DataTables calculates the column widths to assign to each column,
|
||
* it finds the longest string in each column and then constructs a
|
||
* temporary table and reads the widths from that. The problem with this
|
||
* is that "mmm" is much wider then "iiii", but the latter is a longer
|
||
* string - thus the calculation can go wrong (doing it properly and putting
|
||
* it into an DOM object and measuring that is horribly(!) slow). Thus as
|
||
* a "work around" we provide this option. It will append its value to the
|
||
* text that is found to be the longest string for the column - i.e. padding.
|
||
* @type string
|
||
*/
|
||
"sContentPadding": null,
|
||
|
||
/**
|
||
* Allows a default value to be given for a column's data, and will be used
|
||
* whenever a null data source is encountered (this can be because mData
|
||
* is set to null, or because the data source itself is null).
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sDefaultContent": null,
|
||
|
||
/**
|
||
* Name for the column, allowing reference to the column by name as well as
|
||
* by index (needs a lookup to work by name).
|
||
* @type string
|
||
*/
|
||
"sName": null,
|
||
|
||
/**
|
||
* Custom sorting data type - defines which of the available plug-ins in
|
||
* afnSortData the custom sorting will use - if any is defined.
|
||
* @type string
|
||
* @default std
|
||
*/
|
||
"sSortDataType": 'std',
|
||
|
||
/**
|
||
* Class to be applied to the header element when sorting on this column
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sSortingClass": null,
|
||
|
||
/**
|
||
* Class to be applied to the header element when sorting on this column -
|
||
* when jQuery UI theming is used.
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sSortingClassJUI": null,
|
||
|
||
/**
|
||
* Title of the column - what is seen in the TH element (nTh).
|
||
* @type string
|
||
*/
|
||
"sTitle": null,
|
||
|
||
/**
|
||
* Column sorting and filtering type
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sType": null,
|
||
|
||
/**
|
||
* Width of the column
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sWidth": null,
|
||
|
||
/**
|
||
* Width of the column when it was first "encountered"
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sWidthOrig": null
|
||
};
|
||
|
||
|
||
/*
|
||
* Developer note: The properties of the object below are given in Hungarian
|
||
* notation, that was used as the interface for DataTables prior to v1.10, however
|
||
* from v1.10 onwards the primary interface is camel case. In order to avoid
|
||
* breaking backwards compatibility utterly with this change, the Hungarian
|
||
* version is still, internally the primary interface, but is is not documented
|
||
* - hence the @name tags in each doc comment. This allows a Javascript function
|
||
* to create a map from Hungarian notation to camel case (going the other direction
|
||
* would require each property to be listed, which would at around 3K to the size
|
||
* of DataTables, while this method is about a 0.5K hit.
|
||
*
|
||
* Ultimately this does pave the way for Hungarian notation to be dropped
|
||
* completely, but that is a massive amount of work and will break current
|
||
* installs (therefore is on-hold until v2).
|
||
*/
|
||
|
||
/**
|
||
* Initialisation options that can be given to DataTables at initialisation
|
||
* time.
|
||
* @namespace
|
||
*/
|
||
DataTable.defaults = {
|
||
/**
|
||
* An array of data to use for the table, passed in at initialisation which
|
||
* will be used in preference to any data which is already in the DOM. This is
|
||
* particularly useful for constructing tables purely in Javascript, for
|
||
* example with a custom Ajax call.
|
||
* @type array
|
||
* @default null
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.data
|
||
*
|
||
* @example
|
||
* // Using a 2D array data source
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "data": [
|
||
* ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
|
||
* ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
|
||
* ],
|
||
* "columns": [
|
||
* { "title": "Engine" },
|
||
* { "title": "Browser" },
|
||
* { "title": "Platform" },
|
||
* { "title": "Version" },
|
||
* { "title": "Grade" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using an array of objects as a data source (`data`)
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "data": [
|
||
* {
|
||
* "engine": "Trident",
|
||
* "browser": "Internet Explorer 4.0",
|
||
* "platform": "Win 95+",
|
||
* "version": 4,
|
||
* "grade": "X"
|
||
* },
|
||
* {
|
||
* "engine": "Trident",
|
||
* "browser": "Internet Explorer 5.0",
|
||
* "platform": "Win 95+",
|
||
* "version": 5,
|
||
* "grade": "C"
|
||
* }
|
||
* ],
|
||
* "columns": [
|
||
* { "title": "Engine", "data": "engine" },
|
||
* { "title": "Browser", "data": "browser" },
|
||
* { "title": "Platform", "data": "platform" },
|
||
* { "title": "Version", "data": "version" },
|
||
* { "title": "Grade", "data": "grade" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"aaData": null,
|
||
|
||
|
||
/**
|
||
* If ordering is enabled, then DataTables will perform a first pass sort on
|
||
* initialisation. You can define which column(s) the sort is performed
|
||
* upon, and the sorting direction, with this variable. The `sorting` array
|
||
* should contain an array for each column to be sorted initially containing
|
||
* the column's index and a direction string ('asc' or 'desc').
|
||
* @type array
|
||
* @default [[0,'asc']]
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.order
|
||
*
|
||
* @example
|
||
* // Sort by 3rd column first, and then 4th column
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "order": [[2,'asc'], [3,'desc']]
|
||
* } );
|
||
* } );
|
||
*
|
||
* // No initial sorting
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "order": []
|
||
* } );
|
||
* } );
|
||
*/
|
||
"aaSorting": [[0,'asc']],
|
||
|
||
|
||
/**
|
||
* This parameter is basically identical to the `sorting` parameter, but
|
||
* cannot be overridden by user interaction with the table. What this means
|
||
* is that you could have a column (visible or hidden) which the sorting
|
||
* will always be forced on first - any sorting after that (from the user)
|
||
* will then be performed as required. This can be useful for grouping rows
|
||
* together.
|
||
* @type array
|
||
* @default null
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.orderFixed
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "orderFixed": [[0,'asc']]
|
||
* } );
|
||
* } )
|
||
*/
|
||
"aaSortingFixed": [],
|
||
|
||
|
||
/**
|
||
* DataTables can be instructed to load data to display in the table from a
|
||
* Ajax source. This option defines how that Ajax call is made and where to.
|
||
*
|
||
* The `ajax` property has three different modes of operation, depending on
|
||
* how it is defined. These are:
|
||
*
|
||
* * `string` - Set the URL from where the data should be loaded from.
|
||
* * `object` - Define properties for `jQuery.ajax`.
|
||
* * `function` - Custom data get function
|
||
*
|
||
* `string`
|
||
* --------
|
||
*
|
||
* As a string, the `ajax` property simply defines the URL from which
|
||
* DataTables will load data.
|
||
*
|
||
* `object`
|
||
* --------
|
||
*
|
||
* As an object, the parameters in the object are passed to
|
||
* [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control
|
||
* of the Ajax request. DataTables has a number of default parameters which
|
||
* you can override using this option. Please refer to the jQuery
|
||
* documentation for a full description of the options available, although
|
||
* the following parameters provide additional options in DataTables or
|
||
* require special consideration:
|
||
*
|
||
* * `data` - As with jQuery, `data` can be provided as an object, but it
|
||
* can also be used as a function to manipulate the data DataTables sends
|
||
* to the server. The function takes a single parameter, an object of
|
||
* parameters with the values that DataTables has readied for sending. An
|
||
* object may be returned which will be merged into the DataTables
|
||
* defaults, or you can add the items to the object that was passed in and
|
||
* not return anything from the function. This supersedes `fnServerParams`
|
||
* from DataTables 1.9-.
|
||
*
|
||
* * `dataSrc` - By default DataTables will look for the property `data` (or
|
||
* `aaData` for compatibility with DataTables 1.9-) when obtaining data
|
||
* from an Ajax source or for server-side processing - this parameter
|
||
* allows that property to be changed. You can use Javascript dotted
|
||
* object notation to get a data source for multiple levels of nesting, or
|
||
* it my be used as a function. As a function it takes a single parameter,
|
||
* the JSON returned from the server, which can be manipulated as
|
||
* required, with the returned value being that used by DataTables as the
|
||
* data source for the table. This supersedes `sAjaxDataProp` from
|
||
* DataTables 1.9-.
|
||
*
|
||
* * `success` - Should not be overridden it is used internally in
|
||
* DataTables. To manipulate / transform the data returned by the server
|
||
* use `ajax.dataSrc`, or use `ajax` as a function (see below).
|
||
*
|
||
* `function`
|
||
* ----------
|
||
*
|
||
* As a function, making the Ajax call is left up to yourself allowing
|
||
* complete control of the Ajax request. Indeed, if desired, a method other
|
||
* than Ajax could be used to obtain the required data, such as Web storage
|
||
* or an AIR database.
|
||
*
|
||
* The function is given four parameters and no return is required. The
|
||
* parameters are:
|
||
*
|
||
* 1. _object_ - Data to send to the server
|
||
* 2. _function_ - Callback function that must be executed when the required
|
||
* data has been obtained. That data should be passed into the callback
|
||
* as the only parameter
|
||
* 3. _object_ - DataTables settings object for the table
|
||
*
|
||
* Note that this supersedes `fnServerData` from DataTables 1.9-.
|
||
*
|
||
* @type string|object|function
|
||
* @default null
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.ajax
|
||
* @since 1.10.0
|
||
*
|
||
* @example
|
||
* // Get JSON data from a file via Ajax.
|
||
* // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).
|
||
* $('#example').dataTable( {
|
||
* "ajax": "data.json"
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Get JSON data from a file via Ajax, using `dataSrc` to change
|
||
* // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)
|
||
* $('#example').dataTable( {
|
||
* "ajax": {
|
||
* "url": "data.json",
|
||
* "dataSrc": "tableData"
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Get JSON data from a file via Ajax, using `dataSrc` to read data
|
||
* // from a plain array rather than an array in an object
|
||
* $('#example').dataTable( {
|
||
* "ajax": {
|
||
* "url": "data.json",
|
||
* "dataSrc": ""
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Manipulate the data returned from the server - add a link to data
|
||
* // (note this can, should, be done using `render` for the column - this
|
||
* // is just a simple example of how the data can be manipulated).
|
||
* $('#example').dataTable( {
|
||
* "ajax": {
|
||
* "url": "data.json",
|
||
* "dataSrc": function ( json ) {
|
||
* for ( var i=0, ien=json.length ; i<ien ; i++ ) {
|
||
* json[i][0] = '<a href="/message/'+json[i][0]+'>View message</a>';
|
||
* }
|
||
* return json;
|
||
* }
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Add data to the request
|
||
* $('#example').dataTable( {
|
||
* "ajax": {
|
||
* "url": "data.json",
|
||
* "data": function ( d ) {
|
||
* return {
|
||
* "extra_search": $('#extra').val()
|
||
* };
|
||
* }
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Send request as POST
|
||
* $('#example').dataTable( {
|
||
* "ajax": {
|
||
* "url": "data.json",
|
||
* "type": "POST"
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Get the data from localStorage (could interface with a form for
|
||
* // adding, editing and removing rows).
|
||
* $('#example').dataTable( {
|
||
* "ajax": function (data, callback, settings) {
|
||
* callback(
|
||
* JSON.parse( localStorage.getItem('dataTablesData') )
|
||
* );
|
||
* }
|
||
* } );
|
||
*/
|
||
"ajax": null,
|
||
|
||
|
||
/**
|
||
* This parameter allows you to readily specify the entries in the length drop
|
||
* down menu that DataTables shows when pagination is enabled. It can be
|
||
* either a 1D array of options which will be used for both the displayed
|
||
* option and the value, or a 2D array which will use the array in the first
|
||
* position as the value, and the array in the second position as the
|
||
* displayed options (useful for language strings such as 'All').
|
||
*
|
||
* Note that the `pageLength` property will be automatically set to the
|
||
* first value given in this array, unless `pageLength` is also provided.
|
||
* @type array
|
||
* @default [ 10, 25, 50, 100 ]
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.lengthMenu
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"aLengthMenu": [ 10, 25, 50, 100 ],
|
||
|
||
|
||
/**
|
||
* The `columns` option in the initialisation parameter allows you to define
|
||
* details about the way individual columns behave. For a full list of
|
||
* column options that can be set, please see
|
||
* {@link DataTable.defaults.column}. Note that if you use `columns` to
|
||
* define your columns, you must have an entry in the array for every single
|
||
* column that you have in your table (these can be null if you don't which
|
||
* to specify any options).
|
||
* @member
|
||
*
|
||
* @name DataTable.defaults.column
|
||
*/
|
||
"aoColumns": null,
|
||
|
||
/**
|
||
* Very similar to `columns`, `columnDefs` allows you to target a specific
|
||
* column, multiple columns, or all columns, using the `targets` property of
|
||
* each object in the array. This allows great flexibility when creating
|
||
* tables, as the `columnDefs` arrays can be of any length, targeting the
|
||
* columns you specifically want. `columnDefs` may use any of the column
|
||
* options available: {@link DataTable.defaults.column}, but it _must_
|
||
* have `targets` defined in each object in the array. Values in the `targets`
|
||
* array may be:
|
||
* <ul>
|
||
* <li>a string - class name will be matched on the TH for the column</li>
|
||
* <li>0 or a positive integer - column index counting from the left</li>
|
||
* <li>a negative integer - column index counting from the right</li>
|
||
* <li>the string "_all" - all columns (i.e. assign a default)</li>
|
||
* </ul>
|
||
* @member
|
||
*
|
||
* @name DataTable.defaults.columnDefs
|
||
*/
|
||
"aoColumnDefs": null,
|
||
|
||
|
||
/**
|
||
* Basically the same as `search`, this parameter defines the individual column
|
||
* filtering state at initialisation time. The array must be of the same size
|
||
* as the number of columns, and each element be an object with the parameters
|
||
* `search` and `escapeRegex` (the latter is optional). 'null' is also
|
||
* accepted and the default will be used.
|
||
* @type array
|
||
* @default []
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.searchCols
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "searchCols": [
|
||
* null,
|
||
* { "search": "My filter" },
|
||
* null,
|
||
* { "search": "^[0-9]", "escapeRegex": false }
|
||
* ]
|
||
* } );
|
||
* } )
|
||
*/
|
||
"aoSearchCols": [],
|
||
|
||
|
||
/**
|
||
* An array of CSS classes that should be applied to displayed rows. This
|
||
* array may be of any length, and DataTables will apply each class
|
||
* sequentially, looping when required.
|
||
* @type array
|
||
* @default null <i>Will take the values determined by the `oClasses.stripe*`
|
||
* options</i>
|
||
*
|
||
* @dtopt Option
|
||
* @name DataTable.defaults.stripeClasses
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stripeClasses": [ 'strip1', 'strip2', 'strip3' ]
|
||
* } );
|
||
* } )
|
||
*/
|
||
"asStripeClasses": null,
|
||
|
||
|
||
/**
|
||
* Enable or disable automatic column width calculation. This can be disabled
|
||
* as an optimisation (it takes some time to calculate the widths) if the
|
||
* tables widths are passed in using `columns`.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.autoWidth
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "autoWidth": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bAutoWidth": true,
|
||
|
||
|
||
/**
|
||
* Deferred rendering can provide DataTables with a huge speed boost when you
|
||
* are using an Ajax or JS data source for the table. This option, when set to
|
||
* true, will cause DataTables to defer the creation of the table elements for
|
||
* each row until they are needed for a draw - saving a significant amount of
|
||
* time.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.deferRender
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "ajax": "sources/arrays.txt",
|
||
* "deferRender": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bDeferRender": false,
|
||
|
||
|
||
/**
|
||
* Replace a DataTable which matches the given selector and replace it with
|
||
* one which has the properties of the new initialisation object passed. If no
|
||
* table matches the selector, then the new DataTable will be constructed as
|
||
* per normal.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.destroy
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "srollY": "200px",
|
||
* "paginate": false
|
||
* } );
|
||
*
|
||
* // Some time later....
|
||
* $('#example').dataTable( {
|
||
* "filter": false,
|
||
* "destroy": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bDestroy": false,
|
||
|
||
|
||
/**
|
||
* Enable or disable filtering of data. Filtering in DataTables is "smart" in
|
||
* that it allows the end user to input multiple words (space separated) and
|
||
* will match a row containing those words, even if not in the order that was
|
||
* specified (this allow matching across multiple columns). Note that if you
|
||
* wish to use filtering in DataTables this must remain 'true' - to remove the
|
||
* default filtering input box and retain filtering abilities, please use
|
||
* {@link DataTable.defaults.dom}.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.searching
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "searching": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bFilter": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable the table information display. This shows information
|
||
* about the data that is currently visible on the page, including information
|
||
* about filtered data if that action is being performed.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.info
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "info": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bInfo": true,
|
||
|
||
|
||
/**
|
||
* Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
|
||
* slightly different and additional mark-up from what DataTables has
|
||
* traditionally used).
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.jQueryUI
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "jQueryUI": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bJQueryUI": false,
|
||
|
||
|
||
/**
|
||
* Allows the end user to select the size of a formatted page from a select
|
||
* menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.lengthChange
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "lengthChange": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bLengthChange": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable pagination.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.paging
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "paging": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bPaginate": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable the display of a 'processing' indicator when the table is
|
||
* being processed (e.g. a sort). This is particularly useful for tables with
|
||
* large amounts of data where it can take a noticeable amount of time to sort
|
||
* the entries.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.processing
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "processing": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bProcessing": false,
|
||
|
||
|
||
/**
|
||
* Retrieve the DataTables object for the given selector. Note that if the
|
||
* table has already been initialised, this parameter will cause DataTables
|
||
* to simply return the object that has already been set up - it will not take
|
||
* account of any changes you might have made to the initialisation object
|
||
* passed to DataTables (setting this parameter to true is an acknowledgement
|
||
* that you understand this). `destroy` can be used to reinitialise a table if
|
||
* you need.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.retrieve
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* initTable();
|
||
* tableActions();
|
||
* } );
|
||
*
|
||
* function initTable ()
|
||
* {
|
||
* return $('#example').dataTable( {
|
||
* "scrollY": "200px",
|
||
* "paginate": false,
|
||
* "retrieve": true
|
||
* } );
|
||
* }
|
||
*
|
||
* function tableActions ()
|
||
* {
|
||
* var table = initTable();
|
||
* // perform API operations with oTable
|
||
* }
|
||
*/
|
||
"bRetrieve": false,
|
||
|
||
|
||
/**
|
||
* When vertical (y) scrolling is enabled, DataTables will force the height of
|
||
* the table's viewport to the given height at all times (useful for layout).
|
||
* However, this can look odd when filtering data down to a small data set,
|
||
* and the footer is left "floating" further down. This parameter (when
|
||
* enabled) will cause DataTables to collapse the table's viewport down when
|
||
* the result set will fit within the given Y height.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.scrollCollapse
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "scrollY": "200",
|
||
* "scrollCollapse": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bScrollCollapse": false,
|
||
|
||
|
||
/**
|
||
* Configure DataTables to use server-side processing. Note that the
|
||
* `ajax` parameter must also be given in order to give DataTables a
|
||
* source to obtain the required data for each draw.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Features
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.serverSide
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "serverSide": true,
|
||
* "ajax": "xhr.php"
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bServerSide": false,
|
||
|
||
|
||
/**
|
||
* Enable or disable sorting of columns. Sorting of individual columns can be
|
||
* disabled by the `sortable` option for each column.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.ordering
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "ordering": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bSort": true,
|
||
|
||
|
||
/**
|
||
* Enable or display DataTables' ability to sort multiple columns at the
|
||
* same time (activated by shift-click by the user).
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.orderMulti
|
||
*
|
||
* @example
|
||
* // Disable multiple column sorting ability
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "orderMulti": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bSortMulti": true,
|
||
|
||
|
||
/**
|
||
* Allows control over whether DataTables should use the top (true) unique
|
||
* cell that is found for a single column, or the bottom (false - default).
|
||
* This is useful when using complex headers.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.orderCellsTop
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "orderCellsTop": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bSortCellsTop": false,
|
||
|
||
|
||
/**
|
||
* Enable or disable the addition of the classes `sorting\_1`, `sorting\_2` and
|
||
* `sorting\_3` to the columns which are currently being sorted on. This is
|
||
* presented as a feature switch as it can increase processing time (while
|
||
* classes are removed and added) so for large data sets you might want to
|
||
* turn this off.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.orderClasses
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "orderClasses": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bSortClasses": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable state saving. When enabled HTML5 `localStorage` will be
|
||
* used to save table display information such as pagination information,
|
||
* display length, filtering and sorting. As such when the end user reloads
|
||
* the page the display display will match what thy had previously set up.
|
||
*
|
||
* Due to the use of `localStorage` the default state saving is not supported
|
||
* in IE6 or 7. If state saving is required in those browsers, use
|
||
* `stateSaveCallback` to provide a storage solution such as cookies.
|
||
* @type boolean
|
||
* @default false
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.stateSave
|
||
*
|
||
* @example
|
||
* $(document).ready( function () {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"bStateSave": false,
|
||
|
||
|
||
/**
|
||
* This function is called when a TR element is created (and all TD child
|
||
* elements have been inserted), or registered if using a DOM source, allowing
|
||
* manipulation of the TR element (adding classes etc).
|
||
* @type function
|
||
* @param {node} row "TR" element for the current row
|
||
* @param {array} data Raw data array for this row
|
||
* @param {int} dataIndex The index of this row in the internal aoData array
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.createdRow
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "createdRow": function( row, data, dataIndex ) {
|
||
* // Bold the grade for all 'A' grade browsers
|
||
* if ( data[4] == "A" )
|
||
* {
|
||
* $('td:eq(4)', row).html( '<b>A</b>' );
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnCreatedRow": null,
|
||
|
||
|
||
/**
|
||
* This function is called on every 'draw' event, and allows you to
|
||
* dynamically modify any aspect you want about the created DOM.
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.drawCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "drawCallback": function( settings ) {
|
||
* alert( 'DataTables has redrawn the table' );
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnDrawCallback": null,
|
||
|
||
|
||
/**
|
||
* Identical to fnHeaderCallback() but for the table footer this function
|
||
* allows you to modify the table footer on every 'draw' event.
|
||
* @type function
|
||
* @param {node} foot "TR" element for the footer
|
||
* @param {array} data Full table data (as derived from the original HTML)
|
||
* @param {int} start Index for the current display starting point in the
|
||
* display array
|
||
* @param {int} end Index for the current display ending point in the
|
||
* display array
|
||
* @param {array int} display Index array to translate the visual position
|
||
* to the full data array
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.footerCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "footerCallback": function( tfoot, data, start, end, display ) {
|
||
* tfoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+start;
|
||
* }
|
||
* } );
|
||
* } )
|
||
*/
|
||
"fnFooterCallback": null,
|
||
|
||
|
||
/**
|
||
* When rendering large numbers in the information element for the table
|
||
* (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
|
||
* to have a comma separator for the 'thousands' units (e.g. 1 million is
|
||
* rendered as "1,000,000") to help readability for the end user. This
|
||
* function will override the default method DataTables uses.
|
||
* @type function
|
||
* @member
|
||
* @param {int} toFormat number to be formatted
|
||
* @returns {string} formatted string for DataTables to show the number
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.formatNumber
|
||
*
|
||
* @example
|
||
* // Format a number using a single quote for the separator (note that
|
||
* // this can also be done with the language.thousands option)
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "formatNumber": function ( toFormat ) {
|
||
* return toFormat.toString().replace(
|
||
* /\B(?=(\d{3})+(?!\d))/g, "'"
|
||
* );
|
||
* };
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnFormatNumber": function ( toFormat ) {
|
||
return toFormat.toString().replace(
|
||
/\B(?=(\d{3})+(?!\d))/g,
|
||
this.oLanguage.sThousands
|
||
);
|
||
},
|
||
|
||
|
||
/**
|
||
* This function is called on every 'draw' event, and allows you to
|
||
* dynamically modify the header row. This can be used to calculate and
|
||
* display useful information about the table.
|
||
* @type function
|
||
* @param {node} head "TR" element for the header
|
||
* @param {array} data Full table data (as derived from the original HTML)
|
||
* @param {int} start Index for the current display starting point in the
|
||
* display array
|
||
* @param {int} end Index for the current display ending point in the
|
||
* display array
|
||
* @param {array int} display Index array to translate the visual position
|
||
* to the full data array
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.headerCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "fheaderCallback": function( head, data, start, end, display ) {
|
||
* head.getElementsByTagName('th')[0].innerHTML = "Displaying "+(end-start)+" records";
|
||
* }
|
||
* } );
|
||
* } )
|
||
*/
|
||
"fnHeaderCallback": null,
|
||
|
||
|
||
/**
|
||
* The information element can be used to convey information about the current
|
||
* state of the table. Although the internationalisation options presented by
|
||
* DataTables are quite capable of dealing with most customisations, there may
|
||
* be times where you wish to customise the string further. This callback
|
||
* allows you to do exactly that.
|
||
* @type function
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {int} start Starting position in data for the draw
|
||
* @param {int} end End position in data for the draw
|
||
* @param {int} max Total number of rows in the table (regardless of
|
||
* filtering)
|
||
* @param {int} total Total number of rows in the data set, after filtering
|
||
* @param {string} pre The string that DataTables has formatted using it's
|
||
* own rules
|
||
* @returns {string} The string to be displayed in the information element.
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.infoCallback
|
||
*
|
||
* @example
|
||
* $('#example').dataTable( {
|
||
* "infoCallback": function( settings, start, end, max, total, pre ) {
|
||
* return start +" to "+ end;
|
||
* }
|
||
* } );
|
||
*/
|
||
"fnInfoCallback": null,
|
||
|
||
|
||
/**
|
||
* Called when the table has been initialised. Normally DataTables will
|
||
* initialise sequentially and there will be no need for this function,
|
||
* however, this does not hold true when using external language information
|
||
* since that is obtained using an async XHR call.
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
* @param {object} json The JSON object request from the server - only
|
||
* present if client-side Ajax sourced data is used
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.initComplete
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "initComplete": function(settings, json) {
|
||
* alert( 'DataTables has finished its initialisation.' );
|
||
* }
|
||
* } );
|
||
* } )
|
||
*/
|
||
"fnInitComplete": null,
|
||
|
||
|
||
/**
|
||
* Called at the very start of each table draw and can be used to cancel the
|
||
* draw by returning false, any other return (including undefined) results in
|
||
* the full draw occurring).
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
* @returns {boolean} False will cancel the draw, anything else (including no
|
||
* return) will allow it to complete.
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.preDrawCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "preDrawCallback": function( settings ) {
|
||
* if ( $('#test').val() == 1 ) {
|
||
* return false;
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnPreDrawCallback": null,
|
||
|
||
|
||
/**
|
||
* This function allows you to 'post process' each row after it have been
|
||
* generated for each table draw, but before it is rendered on screen. This
|
||
* function might be used for setting the row class name etc.
|
||
* @type function
|
||
* @param {node} row "TR" element for the current row
|
||
* @param {array} data Raw data array for this row
|
||
* @param {int} displayIndex The display index for the current table draw
|
||
* @param {int} displayIndexFull The index of the data in the full list of
|
||
* rows (after filtering)
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.rowCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "rowCallback": function( row, data, displayIndex, displayIndexFull ) {
|
||
* // Bold the grade for all 'A' grade browsers
|
||
* if ( data[4] == "A" ) {
|
||
* $('td:eq(4)', row).html( '<b>A</b>' );
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnRowCallback": null,
|
||
|
||
|
||
/**
|
||
* __Deprecated__ The functionality provided by this parameter has now been
|
||
* superseded by that provided through `ajax`, which should be used instead.
|
||
*
|
||
* This parameter allows you to override the default function which obtains
|
||
* the data from the server so something more suitable for your application.
|
||
* For example you could use POST data, or pull information from a Gears or
|
||
* AIR database.
|
||
* @type function
|
||
* @member
|
||
* @param {string} source HTTP source to obtain the data from (`ajax`)
|
||
* @param {array} data A key/value pair object containing the data to send
|
||
* to the server
|
||
* @param {function} callback to be called on completion of the data get
|
||
* process that will draw the data on the page.
|
||
* @param {object} settings DataTables settings object
|
||
*
|
||
* @dtopt Callbacks
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.serverData
|
||
*
|
||
* @deprecated 1.10. Please use `ajax` for this functionality now.
|
||
*/
|
||
"fnServerData": null,
|
||
|
||
|
||
/**
|
||
* __Deprecated__ The functionality provided by this parameter has now been
|
||
* superseded by that provided through `ajax`, which should be used instead.
|
||
*
|
||
* It is often useful to send extra data to the server when making an Ajax
|
||
* request - for example custom filtering information, and this callback
|
||
* function makes it trivial to send extra information to the server. The
|
||
* passed in parameter is the data set that has been constructed by
|
||
* DataTables, and you can add to this or modify it as you require.
|
||
* @type function
|
||
* @param {array} data Data array (array of objects which are name/value
|
||
* pairs) that has been constructed by DataTables and will be sent to the
|
||
* server. In the case of Ajax sourced data with server-side processing
|
||
* this will be an empty array, for server-side processing there will be a
|
||
* significant number of parameters!
|
||
* @returns {undefined} Ensure that you modify the data array passed in,
|
||
* as this is passed by reference.
|
||
*
|
||
* @dtopt Callbacks
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.serverParams
|
||
*
|
||
* @deprecated 1.10. Please use `ajax` for this functionality now.
|
||
*/
|
||
"fnServerParams": null,
|
||
|
||
|
||
/**
|
||
* Load the table state. With this function you can define from where, and how, the
|
||
* state of a table is loaded. By default DataTables will load from `localStorage`
|
||
* but you might wish to use a server-side database or cookies.
|
||
* @type function
|
||
* @member
|
||
* @param {object} settings DataTables settings object
|
||
* @return {object} The DataTables state object to be loaded
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.stateLoadCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateLoadCallback": function (settings) {
|
||
* var o;
|
||
*
|
||
* // Send an Ajax request to the server to get the data. Note that
|
||
* // this is a synchronous request.
|
||
* $.ajax( {
|
||
* "url": "/state_load",
|
||
* "async": false,
|
||
* "dataType": "json",
|
||
* "success": function (json) {
|
||
* o = json;
|
||
* }
|
||
* } );
|
||
*
|
||
* return o;
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnStateLoadCallback": function ( settings ) {
|
||
try {
|
||
return JSON.parse(
|
||
(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(
|
||
'DataTables_'+settings.sInstance+'_'+location.pathname
|
||
)
|
||
);
|
||
} catch (e) {}
|
||
},
|
||
|
||
|
||
/**
|
||
* Callback which allows modification of the saved state prior to loading that state.
|
||
* This callback is called when the table is loading state from the stored data, but
|
||
* prior to the settings object being modified by the saved state. Note that for
|
||
* plug-in authors, you should use the `stateLoadParams` event to load parameters for
|
||
* a plug-in.
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
* @param {object} data The state object that is to be loaded
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.stateLoadParams
|
||
*
|
||
* @example
|
||
* // Remove a saved filter, so filtering is never loaded
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateLoadParams": function (settings, data) {
|
||
* data.oSearch.sSearch = "";
|
||
* }
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Disallow state loading by returning false
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateLoadParams": function (settings, data) {
|
||
* return false;
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnStateLoadParams": null,
|
||
|
||
|
||
/**
|
||
* Callback that is called when the state has been loaded from the state saving method
|
||
* and the DataTables settings object has been modified as a result of the loaded state.
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
* @param {object} data The state object that was loaded
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.stateLoaded
|
||
*
|
||
* @example
|
||
* // Show an alert with the filtering value that was saved
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateLoaded": function (settings, data) {
|
||
* alert( 'Saved filter was: '+data.oSearch.sSearch );
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnStateLoaded": null,
|
||
|
||
|
||
/**
|
||
* Save the table state. This function allows you to define where and how the state
|
||
* information for the table is stored By default DataTables will use `localStorage`
|
||
* but you might wish to use a server-side database or cookies.
|
||
* @type function
|
||
* @member
|
||
* @param {object} settings DataTables settings object
|
||
* @param {object} data The state object to be saved
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.stateSaveCallback
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateSaveCallback": function (settings, data) {
|
||
* // Send an Ajax request to the server with the state object
|
||
* $.ajax( {
|
||
* "url": "/state_save",
|
||
* "data": data,
|
||
* "dataType": "json",
|
||
* "method": "POST"
|
||
* "success": function () {}
|
||
* } );
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnStateSaveCallback": function ( settings, data ) {
|
||
try {
|
||
(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(
|
||
'DataTables_'+settings.sInstance+'_'+location.pathname,
|
||
JSON.stringify( data )
|
||
);
|
||
} catch (e) {}
|
||
},
|
||
|
||
|
||
/**
|
||
* Callback which allows modification of the state to be saved. Called when the table
|
||
* has changed state a new state save is required. This method allows modification of
|
||
* the state saving object prior to actually doing the save, including addition or
|
||
* other state properties or modification. Note that for plug-in authors, you should
|
||
* use the `stateSaveParams` event to save parameters for a plug-in.
|
||
* @type function
|
||
* @param {object} settings DataTables settings object
|
||
* @param {object} data The state object to be saved
|
||
*
|
||
* @dtopt Callbacks
|
||
* @name DataTable.defaults.stateSaveParams
|
||
*
|
||
* @example
|
||
* // Remove a saved filter, so filtering is never saved
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateSave": true,
|
||
* "stateSaveParams": function (settings, data) {
|
||
* data.oSearch.sSearch = "";
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"fnStateSaveParams": null,
|
||
|
||
|
||
/**
|
||
* Duration for which the saved state information is considered valid. After this period
|
||
* has elapsed the state will be returned to the default.
|
||
* Value is given in seconds.
|
||
* @type int
|
||
* @default 7200 <i>(2 hours)</i>
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.stateDuration
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "stateDuration": 60*60*24; // 1 day
|
||
* } );
|
||
* } )
|
||
*/
|
||
"iStateDuration": 7200,
|
||
|
||
|
||
/**
|
||
* When enabled DataTables will not make a request to the server for the first
|
||
* page draw - rather it will use the data already on the page (no sorting etc
|
||
* will be applied to it), thus saving on an XHR at load time. `deferLoading`
|
||
* is used to indicate that deferred loading is required, but it is also used
|
||
* to tell DataTables how many records there are in the full table (allowing
|
||
* the information element and pagination to be displayed correctly). In the case
|
||
* where a filtering is applied to the table on initial load, this can be
|
||
* indicated by giving the parameter as an array, where the first element is
|
||
* the number of records available after filtering and the second element is the
|
||
* number of records without filtering (allowing the table information element
|
||
* to be shown correctly).
|
||
* @type int | array
|
||
* @default null
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.deferLoading
|
||
*
|
||
* @example
|
||
* // 57 records available in the table, no filtering applied
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "serverSide": true,
|
||
* "ajax": "scripts/server_processing.php",
|
||
* "deferLoading": 57
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // 57 records after filtering, 100 without filtering (an initial filter applied)
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "serverSide": true,
|
||
* "ajax": "scripts/server_processing.php",
|
||
* "deferLoading": [ 57, 100 ],
|
||
* "search": {
|
||
* "search": "my_filter"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"iDeferLoading": null,
|
||
|
||
|
||
/**
|
||
* Number of rows to display on a single page when using pagination. If
|
||
* feature enabled (`lengthChange`) then the end user will be able to override
|
||
* this to a custom setting using a pop-up menu.
|
||
* @type int
|
||
* @default 10
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.pageLength
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "pageLength": 50
|
||
* } );
|
||
* } )
|
||
*/
|
||
"iDisplayLength": 10,
|
||
|
||
|
||
/**
|
||
* Define the starting point for data display when using DataTables with
|
||
* pagination. Note that this parameter is the number of records, rather than
|
||
* the page number, so if you have 10 records per page and want to start on
|
||
* the third page, it should be "20".
|
||
* @type int
|
||
* @default 0
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.displayStart
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "displayStart": 20
|
||
* } );
|
||
* } )
|
||
*/
|
||
"iDisplayStart": 0,
|
||
|
||
|
||
/**
|
||
* By default DataTables allows keyboard navigation of the table (sorting, paging,
|
||
* and filtering) by adding a `tabindex` attribute to the required elements. This
|
||
* allows you to tab through the controls and press the enter key to activate them.
|
||
* The tabindex is default 0, meaning that the tab follows the flow of the document.
|
||
* You can overrule this using this parameter if you wish. Use a value of -1 to
|
||
* disable built-in keyboard navigation.
|
||
* @type int
|
||
* @default 0
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.tabIndex
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "tabIndex": 1
|
||
* } );
|
||
* } );
|
||
*/
|
||
"iTabIndex": 0,
|
||
|
||
|
||
/**
|
||
* Classes that DataTables assigns to the various components and features
|
||
* that it adds to the HTML table. This allows classes to be configured
|
||
* during initialisation in addition to through the static
|
||
* {@link DataTable.ext.oStdClasses} object).
|
||
* @namespace
|
||
* @name DataTable.defaults.classes
|
||
*/
|
||
"oClasses": {},
|
||
|
||
|
||
/**
|
||
* All strings that DataTables uses in the user interface that it creates
|
||
* are defined in this object, allowing you to modified them individually or
|
||
* completely replace them all as required.
|
||
* @namespace
|
||
* @name DataTable.defaults.language
|
||
*/
|
||
"oLanguage": {
|
||
/**
|
||
* Strings that are used for WAI-ARIA labels and controls only (these are not
|
||
* actually visible on the page, but will be read by screenreaders, and thus
|
||
* must be internationalised as well).
|
||
* @namespace
|
||
* @name DataTable.defaults.language.aria
|
||
*/
|
||
"oAria": {
|
||
/**
|
||
* ARIA label that is added to the table headers when the column may be
|
||
* sorted ascending by activing the column (click or return when focused).
|
||
* Note that the column header is prefixed to this string.
|
||
* @type string
|
||
* @default : activate to sort column ascending
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.aria.sortAscending
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "aria": {
|
||
* "sortAscending": " - click/return to sort ascending"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sSortAscending": ": activate to sort column ascending",
|
||
|
||
/**
|
||
* ARIA label that is added to the table headers when the column may be
|
||
* sorted descending by activing the column (click or return when focused).
|
||
* Note that the column header is prefixed to this string.
|
||
* @type string
|
||
* @default : activate to sort column ascending
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.aria.sortDescending
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "aria": {
|
||
* "sortDescending": " - click/return to sort descending"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sSortDescending": ": activate to sort column descending"
|
||
},
|
||
|
||
/**
|
||
* Pagination string used by DataTables for the built-in pagination
|
||
* control types.
|
||
* @namespace
|
||
* @name DataTable.defaults.language.paginate
|
||
*/
|
||
"oPaginate": {
|
||
/**
|
||
* Text to use when using the 'full_numbers' type of pagination for the
|
||
* button to take the user to the first page.
|
||
* @type string
|
||
* @default First
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.paginate.first
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "paginate": {
|
||
* "first": "First page"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sFirst": "First",
|
||
|
||
|
||
/**
|
||
* Text to use when using the 'full_numbers' type of pagination for the
|
||
* button to take the user to the last page.
|
||
* @type string
|
||
* @default Last
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.paginate.last
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "paginate": {
|
||
* "last": "Last page"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sLast": "Last",
|
||
|
||
|
||
/**
|
||
* Text to use for the 'next' pagination button (to take the user to the
|
||
* next page).
|
||
* @type string
|
||
* @default Next
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.paginate.next
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "paginate": {
|
||
* "next": "Next page"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sNext": "Next",
|
||
|
||
|
||
/**
|
||
* Text to use for the 'previous' pagination button (to take the user to
|
||
* the previous page).
|
||
* @type string
|
||
* @default Previous
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.paginate.previous
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "paginate": {
|
||
* "previous": "Previous page"
|
||
* }
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sPrevious": "Previous"
|
||
},
|
||
|
||
/**
|
||
* This string is shown in preference to `zeroRecords` when the table is
|
||
* empty of data (regardless of filtering). Note that this is an optional
|
||
* parameter - if it is not given, the value of `zeroRecords` will be used
|
||
* instead (either the default or given value).
|
||
* @type string
|
||
* @default No data available in table
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.emptyTable
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "emptyTable": "No data available in table"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sEmptyTable": "No data available in table",
|
||
|
||
|
||
/**
|
||
* This string gives information to the end user about the information
|
||
* that is current on display on the page. The following tokens can be
|
||
* used in the string and will be dynamically replaced as the table
|
||
* display updates. This tokens can be placed anywhere in the string, or
|
||
* removed as needed by the language requires:
|
||
*
|
||
* * `\_START\_` - Display index of the first record on the current page
|
||
* * `\_END\_` - Display index of the last record on the current page
|
||
* * `\_TOTAL\_` - Number of records in the table after filtering
|
||
* * `\_MAX\_` - Number of records in the table without filtering
|
||
* * `\_PAGE\_` - Current page number
|
||
* * `\_PAGES\_` - Total number of pages of data in the table
|
||
*
|
||
* @type string
|
||
* @default Showing _START_ to _END_ of _TOTAL_ entries
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.info
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "info": "Showing page _PAGE_ of _PAGES_"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
|
||
|
||
|
||
/**
|
||
* Display information string for when the table is empty. Typically the
|
||
* format of this string should match `info`.
|
||
* @type string
|
||
* @default Showing 0 to 0 of 0 entries
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.infoEmpty
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "infoEmpty": "No entries to show"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sInfoEmpty": "Showing 0 to 0 of 0 entries",
|
||
|
||
|
||
/**
|
||
* When a user filters the information in a table, this string is appended
|
||
* to the information (`info`) to give an idea of how strong the filtering
|
||
* is. The variable _MAX_ is dynamically updated.
|
||
* @type string
|
||
* @default (filtered from _MAX_ total entries)
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.infoFiltered
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "infoFiltered": " - filtering from _MAX_ records"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sInfoFiltered": "(filtered from _MAX_ total entries)",
|
||
|
||
|
||
/**
|
||
* If can be useful to append extra information to the info string at times,
|
||
* and this variable does exactly that. This information will be appended to
|
||
* the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are
|
||
* being used) at all times.
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.infoPostFix
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "infoPostFix": "All records shown are derived from real information."
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sInfoPostFix": "",
|
||
|
||
|
||
/**
|
||
* This decimal place operator is a little different from the other
|
||
* language options since DataTables doesn't output floating point
|
||
* numbers, so it won't ever use this for display of a number. Rather,
|
||
* what this parameter does is modify the sort methods of the table so
|
||
* that numbers which are in a format which has a character other than
|
||
* a period (`.`) as a decimal place will be sorted numerically.
|
||
*
|
||
* Note that numbers with different decimal places cannot be shown in
|
||
* the same table and still be sortable, the table must be consistent.
|
||
* However, multiple different tables on the page can use different
|
||
* decimal place characters.
|
||
* @type string
|
||
* @default
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.decimal
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "decimal": ","
|
||
* "thousands": "."
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sDecimal": "",
|
||
|
||
|
||
/**
|
||
* DataTables has a build in number formatter (`formatNumber`) which is
|
||
* used to format large numbers that are used in the table information.
|
||
* By default a comma is used, but this can be trivially changed to any
|
||
* character you wish with this parameter.
|
||
* @type string
|
||
* @default ,
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.thousands
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "thousands": "'"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sThousands": ",",
|
||
|
||
|
||
/**
|
||
* Detail the action that will be taken when the drop down menu for the
|
||
* pagination length option is changed. The '_MENU_' variable is replaced
|
||
* with a default select list of 10, 25, 50 and 100, and can be replaced
|
||
* with a custom select box if required.
|
||
* @type string
|
||
* @default Show _MENU_ entries
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.lengthMenu
|
||
*
|
||
* @example
|
||
* // Language change only
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "lengthMenu": "Display _MENU_ records"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Language and options change
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "lengthMenu": 'Display <select>'+
|
||
* '<option value="10">10</option>'+
|
||
* '<option value="20">20</option>'+
|
||
* '<option value="30">30</option>'+
|
||
* '<option value="40">40</option>'+
|
||
* '<option value="50">50</option>'+
|
||
* '<option value="-1">All</option>'+
|
||
* '</select> records'
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sLengthMenu": "Show _MENU_ entries",
|
||
|
||
|
||
/**
|
||
* When using Ajax sourced data and during the first draw when DataTables is
|
||
* gathering the data, this message is shown in an empty row in the table to
|
||
* indicate to the end user the the data is being loaded. Note that this
|
||
* parameter is not used when loading data by server-side processing, just
|
||
* Ajax sourced data with client-side processing.
|
||
* @type string
|
||
* @default Loading...
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.loadingRecords
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "loadingRecords": "Please wait - loading..."
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sLoadingRecords": "Loading...",
|
||
|
||
|
||
/**
|
||
* Text which is displayed when the table is processing a user action
|
||
* (usually a sort command or similar).
|
||
* @type string
|
||
* @default Processing...
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.processing
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "processing": "DataTables is currently busy"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sProcessing": "Processing...",
|
||
|
||
|
||
/**
|
||
* Details the actions that will be taken when the user types into the
|
||
* filtering input text box. The variable "_INPUT_", if used in the string,
|
||
* is replaced with the HTML text box for the filtering input allowing
|
||
* control over where it appears in the string. If "_INPUT_" is not given
|
||
* then the input box is appended to the string automatically.
|
||
* @type string
|
||
* @default Search:
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.search
|
||
*
|
||
* @example
|
||
* // Input text box will be appended at the end automatically
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "search": "Filter records:"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Specify where the filter should appear
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "search": "Apply filter _INPUT_ to table"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sSearch": "Search:",
|
||
|
||
|
||
/**
|
||
* All of the language information can be stored in a file on the
|
||
* server-side, which DataTables will look up if this parameter is passed.
|
||
* It must store the URL of the language file, which is in a JSON format,
|
||
* and the object has the same properties as the oLanguage object in the
|
||
* initialiser object (i.e. the above parameters). Please refer to one of
|
||
* the example language files to see how this works in action.
|
||
* @type string
|
||
* @default <i>Empty string - i.e. disabled</i>
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.url
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "url": "http://www.sprymedia.co.uk/dataTables/lang.txt"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sUrl": "",
|
||
|
||
|
||
/**
|
||
* Text shown inside the table records when the is no information to be
|
||
* displayed after filtering. `emptyTable` is shown when there is simply no
|
||
* information in the table at all (regardless of filtering).
|
||
* @type string
|
||
* @default No matching records found
|
||
*
|
||
* @dtopt Language
|
||
* @name DataTable.defaults.language.zeroRecords
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "language": {
|
||
* "zeroRecords": "No records to display"
|
||
* }
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sZeroRecords": "No matching records found"
|
||
},
|
||
|
||
|
||
/**
|
||
* This parameter allows you to have define the global filtering state at
|
||
* initialisation time. As an object the `search` parameter must be
|
||
* defined, but all other parameters are optional. When `regex` is true,
|
||
* the search string will be treated as a regular expression, when false
|
||
* (default) it will be treated as a straight string. When `smart`
|
||
* DataTables will use it's smart filtering methods (to word match at
|
||
* any point in the data), when false this will not be done.
|
||
* @namespace
|
||
* @extends DataTable.models.oSearch
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.search
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "search": {"search": "Initial search"}
|
||
* } );
|
||
* } )
|
||
*/
|
||
"oSearch": $.extend( {}, DataTable.models.oSearch ),
|
||
|
||
|
||
/**
|
||
* __Deprecated__ The functionality provided by this parameter has now been
|
||
* superseded by that provided through `ajax`, which should be used instead.
|
||
*
|
||
* By default DataTables will look for the property `data` (or `aaData` for
|
||
* compatibility with DataTables 1.9-) when obtaining data from an Ajax
|
||
* source or for server-side processing - this parameter allows that
|
||
* property to be changed. You can use Javascript dotted object notation to
|
||
* get a data source for multiple levels of nesting.
|
||
* @type string
|
||
* @default data
|
||
*
|
||
* @dtopt Options
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.ajaxDataProp
|
||
*
|
||
* @deprecated 1.10. Please use `ajax` for this functionality now.
|
||
*/
|
||
"sAjaxDataProp": "data",
|
||
|
||
|
||
/**
|
||
* __Deprecated__ The functionality provided by this parameter has now been
|
||
* superseded by that provided through `ajax`, which should be used instead.
|
||
*
|
||
* You can instruct DataTables to load data from an external
|
||
* source using this parameter (use aData if you want to pass data in you
|
||
* already have). Simply provide a url a JSON object can be obtained from.
|
||
* @type string
|
||
* @default null
|
||
*
|
||
* @dtopt Options
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.ajaxSource
|
||
*
|
||
* @deprecated 1.10. Please use `ajax` for this functionality now.
|
||
*/
|
||
"sAjaxSource": null,
|
||
|
||
|
||
/**
|
||
* This initialisation variable allows you to specify exactly where in the
|
||
* DOM you want DataTables to inject the various controls it adds to the page
|
||
* (for example you might want the pagination controls at the top of the
|
||
* table). DIV elements (with or without a custom class) can also be added to
|
||
* aid styling. The follow syntax is used:
|
||
* <ul>
|
||
* <li>The following options are allowed:
|
||
* <ul>
|
||
* <li>'l' - Length changing</li>
|
||
* <li>'f' - Filtering input</li>
|
||
* <li>'t' - The table!</li>
|
||
* <li>'i' - Information</li>
|
||
* <li>'p' - Pagination</li>
|
||
* <li>'r' - pRocessing</li>
|
||
* </ul>
|
||
* </li>
|
||
* <li>The following constants are allowed:
|
||
* <ul>
|
||
* <li>'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>
|
||
* <li>'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>
|
||
* </ul>
|
||
* </li>
|
||
* <li>The following syntax is expected:
|
||
* <ul>
|
||
* <li>'<' and '>' - div elements</li>
|
||
* <li>'<"class" and '>' - div with a class</li>
|
||
* <li>'<"#id" and '>' - div with an ID</li>
|
||
* </ul>
|
||
* </li>
|
||
* <li>Examples:
|
||
* <ul>
|
||
* <li>'<"wrapper"flipt>'</li>
|
||
* <li>'<lf<t>ip>'</li>
|
||
* </ul>
|
||
* </li>
|
||
* </ul>
|
||
* @type string
|
||
* @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>
|
||
* <"H"lfr>t<"F"ip> <i>(when `jQueryUI` is true)</i>
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.dom
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "dom": '<"top"i>rt<"bottom"flp><"clear">'
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sDom": "lfrtip",
|
||
|
||
|
||
/**
|
||
* DataTables features four different built-in options for the buttons to
|
||
* display for pagination control:
|
||
*
|
||
* * `simple` - 'Previous' and 'Next' buttons only
|
||
* * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers
|
||
* * `full` - 'First', 'Previous', 'Next' and 'Last' buttons
|
||
* * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus
|
||
* page numbers
|
||
*
|
||
* Further methods can be added using {@link DataTable.ext.oPagination}.
|
||
* @type string
|
||
* @default simple_numbers
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.pagingType
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "pagingType": "full_numbers"
|
||
* } );
|
||
* } )
|
||
*/
|
||
"sPaginationType": "simple_numbers",
|
||
|
||
|
||
/**
|
||
* Enable horizontal scrolling. When a table is too wide to fit into a
|
||
* certain layout, or you have a large number of columns in the table, you
|
||
* can enable x-scrolling to show the table in a viewport, which can be
|
||
* scrolled. This property can be `true` which will allow the table to
|
||
* scroll horizontally when needed, or any CSS unit, or a number (in which
|
||
* case it will be treated as a pixel measurement). Setting as simply `true`
|
||
* is recommended.
|
||
* @type boolean|string
|
||
* @default <i>blank string - i.e. disabled</i>
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.scrollX
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "scrollX": true,
|
||
* "scrollCollapse": true
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sScrollX": "",
|
||
|
||
|
||
/**
|
||
* This property can be used to force a DataTable to use more width than it
|
||
* might otherwise do when x-scrolling is enabled. For example if you have a
|
||
* table which requires to be well spaced, this parameter is useful for
|
||
* "over-sizing" the table, and thus forcing scrolling. This property can by
|
||
* any CSS unit, or a number (in which case it will be treated as a pixel
|
||
* measurement).
|
||
* @type string
|
||
* @default <i>blank string - i.e. disabled</i>
|
||
*
|
||
* @dtopt Options
|
||
* @name DataTable.defaults.scrollXInner
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "scrollX": "100%",
|
||
* "scrollXInner": "110%"
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sScrollXInner": "",
|
||
|
||
|
||
/**
|
||
* Enable vertical scrolling. Vertical scrolling will constrain the DataTable
|
||
* to the given height, and enable scrolling for any data which overflows the
|
||
* current viewport. This can be used as an alternative to paging to display
|
||
* a lot of data in a small area (although paging and scrolling can both be
|
||
* enabled at the same time). This property can be any CSS unit, or a number
|
||
* (in which case it will be treated as a pixel measurement).
|
||
* @type string
|
||
* @default <i>blank string - i.e. disabled</i>
|
||
*
|
||
* @dtopt Features
|
||
* @name DataTable.defaults.scrollY
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "scrollY": "200px",
|
||
* "paginate": false
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sScrollY": "",
|
||
|
||
|
||
/**
|
||
* __Deprecated__ The functionality provided by this parameter has now been
|
||
* superseded by that provided through `ajax`, which should be used instead.
|
||
*
|
||
* Set the HTTP method that is used to make the Ajax call for server-side
|
||
* processing or Ajax sourced data.
|
||
* @type string
|
||
* @default GET
|
||
*
|
||
* @dtopt Options
|
||
* @dtopt Server-side
|
||
* @name DataTable.defaults.serverMethod
|
||
*
|
||
* @deprecated 1.10. Please use `ajax` for this functionality now.
|
||
*/
|
||
"sServerMethod": "GET",
|
||
|
||
|
||
/**
|
||
* DataTables makes use of renderers when displaying HTML elements for
|
||
* a table. These renderers can be added or modified by plug-ins to
|
||
* generate suitable mark-up for a site. For example the Bootstrap
|
||
* integration plug-in for DataTables uses a paging button renderer to
|
||
* display pagination buttons in the mark-up required by Bootstrap.
|
||
*
|
||
* For further information about the renderers available see
|
||
* DataTable.ext.renderer
|
||
* @type string|object
|
||
* @default null
|
||
*
|
||
* @name DataTable.defaults.renderer
|
||
*
|
||
*/
|
||
"renderer": null
|
||
};
|
||
|
||
_fnHungarianMap( DataTable.defaults );
|
||
|
||
|
||
|
||
/*
|
||
* Developer note - See note in model.defaults.js about the use of Hungarian
|
||
* notation and camel case.
|
||
*/
|
||
|
||
/**
|
||
* Column options that can be given to DataTables at initialisation time.
|
||
* @namespace
|
||
*/
|
||
DataTable.defaults.column = {
|
||
/**
|
||
* Define which column(s) an order will occur on for this column. This
|
||
* allows a column's ordering to take multiple columns into account when
|
||
* doing a sort or use the data from a different column. For example first
|
||
* name / last name columns make sense to do a multi-column sort over the
|
||
* two columns.
|
||
* @type array|int
|
||
* @default null <i>Takes the value of the column index automatically</i>
|
||
*
|
||
* @name DataTable.defaults.column.orderData
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "orderData": [ 0, 1 ], "targets": [ 0 ] },
|
||
* { "orderData": [ 1, 0 ], "targets": [ 1 ] },
|
||
* { "orderData": 2, "targets": [ 2 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "orderData": [ 0, 1 ] },
|
||
* { "orderData": [ 1, 0 ] },
|
||
* { "orderData": 2 },
|
||
* null,
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"aDataSort": null,
|
||
"iDataSort": -1,
|
||
|
||
|
||
/**
|
||
* You can control the default ordering direction, and even alter the
|
||
* behaviour of the sort handler (i.e. only allow ascending ordering etc)
|
||
* using this parameter.
|
||
* @type array
|
||
* @default [ 'asc', 'desc' ]
|
||
*
|
||
* @name DataTable.defaults.column.orderSequence
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "orderSequence": [ "asc" ], "targets": [ 1 ] },
|
||
* { "orderSequence": [ "desc", "asc", "asc" ], "targets": [ 2 ] },
|
||
* { "orderSequence": [ "desc" ], "targets": [ 3 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* null,
|
||
* { "orderSequence": [ "asc" ] },
|
||
* { "orderSequence": [ "desc", "asc", "asc" ] },
|
||
* { "orderSequence": [ "desc" ] },
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"asSorting": [ 'asc', 'desc' ],
|
||
|
||
|
||
/**
|
||
* Enable or disable filtering on the data in this column.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @name DataTable.defaults.column.searchable
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "searchable": false, "targets": [ 0 ] }
|
||
* ] } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "searchable": false },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ] } );
|
||
* } );
|
||
*/
|
||
"bSearchable": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable ordering on this column.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @name DataTable.defaults.column.orderable
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "orderable": false, "targets": [ 0 ] }
|
||
* ] } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "orderable": false },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ] } );
|
||
* } );
|
||
*/
|
||
"bSortable": true,
|
||
|
||
|
||
/**
|
||
* Enable or disable the display of this column.
|
||
* @type boolean
|
||
* @default true
|
||
*
|
||
* @name DataTable.defaults.column.visible
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "visible": false, "targets": [ 0 ] }
|
||
* ] } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "visible": false },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ] } );
|
||
* } );
|
||
*/
|
||
"bVisible": true,
|
||
|
||
|
||
/**
|
||
* Developer definable function that is called whenever a cell is created (Ajax source,
|
||
* etc) or processed for input (DOM source). This can be used as a compliment to mRender
|
||
* allowing you to modify the DOM element (add background colour for example) when the
|
||
* element is available.
|
||
* @type function
|
||
* @param {element} td The TD node that has been created
|
||
* @param {*} cellData The Data for the cell
|
||
* @param {array|object} rowData The data for the whole row
|
||
* @param {int} row The row index for the aoData data store
|
||
* @param {int} col The column index for aoColumns
|
||
*
|
||
* @name DataTable.defaults.column.createdCell
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [3],
|
||
* "createdCell": function (td, cellData, rowData, row, col) {
|
||
* if ( cellData == "1.7" ) {
|
||
* $(td).css('color', 'blue')
|
||
* }
|
||
* }
|
||
* } ]
|
||
* });
|
||
* } );
|
||
*/
|
||
"fnCreatedCell": null,
|
||
|
||
|
||
/**
|
||
* This parameter has been replaced by `data` in DataTables to ensure naming
|
||
* consistency. `dataProp` can still be used, as there is backwards
|
||
* compatibility in DataTables for this option, but it is strongly
|
||
* recommended that you use `data` in preference to `dataProp`.
|
||
* @name DataTable.defaults.column.dataProp
|
||
*/
|
||
|
||
|
||
/**
|
||
* This property can be used to read data from any data source property,
|
||
* including deeply nested objects / properties. `data` can be given in a
|
||
* number of different ways which effect its behaviour:
|
||
*
|
||
* * `integer` - treated as an array index for the data source. This is the
|
||
* default that DataTables uses (incrementally increased for each column).
|
||
* * `string` - read an object property from the data source. There are
|
||
* three 'special' options that can be used in the string to alter how
|
||
* DataTables reads the data from the source object:
|
||
* * `.` - Dotted Javascript notation. Just as you use a `.` in
|
||
* Javascript to read from nested objects, so to can the options
|
||
* specified in `data`. For example: `browser.version` or
|
||
* `browser.name`. If your object parameter name contains a period, use
|
||
* `\\` to escape it - i.e. `first\\.name`.
|
||
* * `[]` - Array notation. DataTables can automatically combine data
|
||
* from and array source, joining the data with the characters provided
|
||
* between the two brackets. For example: `name[, ]` would provide a
|
||
* comma-space separated list from the source array. If no characters
|
||
* are provided between the brackets, the original array source is
|
||
* returned.
|
||
* * `()` - Function notation. Adding `()` to the end of a parameter will
|
||
* execute a function of the name given. For example: `browser()` for a
|
||
* simple function on the data source, `browser.version()` for a
|
||
* function in a nested property or even `browser().version` to get an
|
||
* object property if the function called returns an object. Note that
|
||
* function notation is recommended for use in `render` rather than
|
||
* `data` as it is much simpler to use as a renderer.
|
||
* * `null` - use the original data source for the row rather than plucking
|
||
* data directly from it. This action has effects on two other
|
||
* initialisation options:
|
||
* * `defaultContent` - When null is given as the `data` option and
|
||
* `defaultContent` is specified for the column, the value defined by
|
||
* `defaultContent` will be used for the cell.
|
||
* * `render` - When null is used for the `data` option and the `render`
|
||
* option is specified for the column, the whole data source for the
|
||
* row is used for the renderer.
|
||
* * `function` - the function given will be executed whenever DataTables
|
||
* needs to set or get the data for a cell in the column. The function
|
||
* takes three parameters:
|
||
* * Parameters:
|
||
* * `{array|object}` The data source for the row
|
||
* * `{string}` The type call data requested - this will be 'set' when
|
||
* setting data or 'filter', 'display', 'type', 'sort' or undefined
|
||
* when gathering data. Note that when `undefined` is given for the
|
||
* type DataTables expects to get the raw data for the object back<
|
||
* * `{*}` Data to set when the second parameter is 'set'.
|
||
* * Return:
|
||
* * The return value from the function is not required when 'set' is
|
||
* the type of call, but otherwise the return is what will be used
|
||
* for the data requested.
|
||
*
|
||
* Note that `data` is a getter and setter option. If you just require
|
||
* formatting of data for output, you will likely want to use `render` which
|
||
* is simply a getter and thus simpler to use.
|
||
*
|
||
* Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The
|
||
* name change reflects the flexibility of this property and is consistent
|
||
* with the naming of mRender. If 'mDataProp' is given, then it will still
|
||
* be used by DataTables, as it automatically maps the old name to the new
|
||
* if required.
|
||
*
|
||
* @type string|int|function|null
|
||
* @default null <i>Use automatically calculated column index</i>
|
||
*
|
||
* @name DataTable.defaults.column.data
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Read table data from objects
|
||
* // JSON structure for each row:
|
||
* // {
|
||
* // "engine": {value},
|
||
* // "browser": {value},
|
||
* // "platform": {value},
|
||
* // "version": {value},
|
||
* // "grade": {value}
|
||
* // }
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "ajaxSource": "sources/objects.txt",
|
||
* "columns": [
|
||
* { "data": "engine" },
|
||
* { "data": "browser" },
|
||
* { "data": "platform" },
|
||
* { "data": "version" },
|
||
* { "data": "grade" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Read information from deeply nested objects
|
||
* // JSON structure for each row:
|
||
* // {
|
||
* // "engine": {value},
|
||
* // "browser": {value},
|
||
* // "platform": {
|
||
* // "inner": {value}
|
||
* // },
|
||
* // "details": [
|
||
* // {value}, {value}
|
||
* // ]
|
||
* // }
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "ajaxSource": "sources/deep.txt",
|
||
* "columns": [
|
||
* { "data": "engine" },
|
||
* { "data": "browser" },
|
||
* { "data": "platform.inner" },
|
||
* { "data": "platform.details.0" },
|
||
* { "data": "platform.details.1" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `data` as a function to provide different information for
|
||
* // sorting, filtering and display. In this case, currency (price)
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": function ( source, type, val ) {
|
||
* if (type === 'set') {
|
||
* source.price = val;
|
||
* // Store the computed dislay and filter values for efficiency
|
||
* source.price_display = val=="" ? "" : "$"+numberFormat(val);
|
||
* source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
|
||
* return;
|
||
* }
|
||
* else if (type === 'display') {
|
||
* return source.price_display;
|
||
* }
|
||
* else if (type === 'filter') {
|
||
* return source.price_filter;
|
||
* }
|
||
* // 'sort', 'type' and undefined all just use the integer
|
||
* return source.price;
|
||
* }
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using default content
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": null,
|
||
* "defaultContent": "Click to edit"
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using array notation - outputting a list from an array
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": "name[, ]"
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*
|
||
*/
|
||
"mData": null,
|
||
|
||
|
||
/**
|
||
* This property is the rendering partner to `data` and it is suggested that
|
||
* when you want to manipulate data for display (including filtering,
|
||
* sorting etc) without altering the underlying data for the table, use this
|
||
* property. `render` can be considered to be the the read only companion to
|
||
* `data` which is read / write (then as such more complex). Like `data`
|
||
* this option can be given in a number of different ways to effect its
|
||
* behaviour:
|
||
*
|
||
* * `integer` - treated as an array index for the data source. This is the
|
||
* default that DataTables uses (incrementally increased for each column).
|
||
* * `string` - read an object property from the data source. There are
|
||
* three 'special' options that can be used in the string to alter how
|
||
* DataTables reads the data from the source object:
|
||
* * `.` - Dotted Javascript notation. Just as you use a `.` in
|
||
* Javascript to read from nested objects, so to can the options
|
||
* specified in `data`. For example: `browser.version` or
|
||
* `browser.name`. If your object parameter name contains a period, use
|
||
* `\\` to escape it - i.e. `first\\.name`.
|
||
* * `[]` - Array notation. DataTables can automatically combine data
|
||
* from and array source, joining the data with the characters provided
|
||
* between the two brackets. For example: `name[, ]` would provide a
|
||
* comma-space separated list from the source array. If no characters
|
||
* are provided between the brackets, the original array source is
|
||
* returned.
|
||
* * `()` - Function notation. Adding `()` to the end of a parameter will
|
||
* execute a function of the name given. For example: `browser()` for a
|
||
* simple function on the data source, `browser.version()` for a
|
||
* function in a nested property or even `browser().version` to get an
|
||
* object property if the function called returns an object.
|
||
* * `object` - use different data for the different data types requested by
|
||
* DataTables ('filter', 'display', 'type' or 'sort'). The property names
|
||
* of the object is the data type the property refers to and the value can
|
||
* defined using an integer, string or function using the same rules as
|
||
* `render` normally does. Note that an `_` option _must_ be specified.
|
||
* This is the default value to use if you haven't specified a value for
|
||
* the data type requested by DataTables.
|
||
* * `function` - the function given will be executed whenever DataTables
|
||
* needs to set or get the data for a cell in the column. The function
|
||
* takes three parameters:
|
||
* * Parameters:
|
||
* * {array|object} The data source for the row (based on `data`)
|
||
* * {string} The type call data requested - this will be 'filter',
|
||
* 'display', 'type' or 'sort'.
|
||
* * {array|object} The full data source for the row (not based on
|
||
* `data`)
|
||
* * Return:
|
||
* * The return value from the function is what will be used for the
|
||
* data requested.
|
||
*
|
||
* @type string|int|function|object|null
|
||
* @default null Use the data source value.
|
||
*
|
||
* @name DataTable.defaults.column.render
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Create a comma separated list from an array of objects
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "ajaxSource": "sources/deep.txt",
|
||
* "columns": [
|
||
* { "data": "engine" },
|
||
* { "data": "browser" },
|
||
* {
|
||
* "data": "platform",
|
||
* "render": "[, ].name"
|
||
* }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Execute a function to obtain data
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": null, // Use the full data source object for the renderer's source
|
||
* "render": "browserName()"
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // As an object, extracting different data for the different types
|
||
* // This would be used with a data source such as:
|
||
* // { "phone": 5552368, "phone_filter": "5552368 555-2368", "phone_display": "555-2368" }
|
||
* // Here the `phone` integer is used for sorting and type detection, while `phone_filter`
|
||
* // (which has both forms) is used for filtering for if a user inputs either format, while
|
||
* // the formatted phone number is the one that is shown in the table.
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": null, // Use the full data source object for the renderer's source
|
||
* "render": {
|
||
* "_": "phone",
|
||
* "filter": "phone_filter",
|
||
* "display": "phone_display"
|
||
* }
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Use as a function to create a link from the data source
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "data": "download_link",
|
||
* "render": function ( data, type, full ) {
|
||
* return '<a href="'+data+'">Download</a>';
|
||
* }
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"mRender": null,
|
||
|
||
|
||
/**
|
||
* Change the cell type created for the column - either TD cells or TH cells. This
|
||
* can be useful as TH cells have semantic meaning in the table body, allowing them
|
||
* to act as a header for a row (you may wish to add scope='row' to the TH elements).
|
||
* @type string
|
||
* @default td
|
||
*
|
||
* @name DataTable.defaults.column.cellType
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Make the first column use TH cells
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [ {
|
||
* "targets": [ 0 ],
|
||
* "cellType": "th"
|
||
* } ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sCellType": "td",
|
||
|
||
|
||
/**
|
||
* Class to give to each cell in this column.
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
*
|
||
* @name DataTable.defaults.column.class
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "class": "my_class", "targets": [ 0 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "class": "my_class" },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sClass": "",
|
||
|
||
/**
|
||
* When DataTables calculates the column widths to assign to each column,
|
||
* it finds the longest string in each column and then constructs a
|
||
* temporary table and reads the widths from that. The problem with this
|
||
* is that "mmm" is much wider then "iiii", but the latter is a longer
|
||
* string - thus the calculation can go wrong (doing it properly and putting
|
||
* it into an DOM object and measuring that is horribly(!) slow). Thus as
|
||
* a "work around" we provide this option. It will append its value to the
|
||
* text that is found to be the longest string for the column - i.e. padding.
|
||
* Generally you shouldn't need this!
|
||
* @type string
|
||
* @default <i>Empty string<i>
|
||
*
|
||
* @name DataTable.defaults.column.contentPadding
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* {
|
||
* "contentPadding": "mmm"
|
||
* }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sContentPadding": "",
|
||
|
||
|
||
/**
|
||
* Allows a default value to be given for a column's data, and will be used
|
||
* whenever a null data source is encountered (this can be because `data`
|
||
* is set to null, or because the data source itself is null).
|
||
* @type string
|
||
* @default null
|
||
*
|
||
* @name DataTable.defaults.column.defaultContent
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* {
|
||
* "data": null,
|
||
* "defaultContent": "Edit",
|
||
* "targets": [ -1 ]
|
||
* }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* {
|
||
* "data": null,
|
||
* "defaultContent": "Edit"
|
||
* }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sDefaultContent": null,
|
||
|
||
|
||
/**
|
||
* This parameter is only used in DataTables' server-side processing. It can
|
||
* be exceptionally useful to know what columns are being displayed on the
|
||
* client side, and to map these to database fields. When defined, the names
|
||
* also allow DataTables to reorder information from the server if it comes
|
||
* back in an unexpected order (i.e. if you switch your columns around on the
|
||
* client-side, your server-side code does not also need updating).
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
*
|
||
* @name DataTable.defaults.column.name
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "name": "engine", "targets": [ 0 ] },
|
||
* { "name": "browser", "targets": [ 1 ] },
|
||
* { "name": "platform", "targets": [ 2 ] },
|
||
* { "name": "version", "targets": [ 3 ] },
|
||
* { "name": "grade", "targets": [ 4 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "name": "engine" },
|
||
* { "name": "browser" },
|
||
* { "name": "platform" },
|
||
* { "name": "version" },
|
||
* { "name": "grade" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sName": "",
|
||
|
||
|
||
/**
|
||
* Defines a data source type for the ordering which can be used to read
|
||
* real-time information from the table (updating the internally cached
|
||
* version) prior to ordering. This allows ordering to occur on user
|
||
* editable elements such as form inputs.
|
||
* @type string
|
||
* @default std
|
||
*
|
||
* @name DataTable.defaults.column.orderDataType
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "orderDataType": "dom-text", "targets": [ 2, 3 ] },
|
||
* { "type": "numeric", "targets": [ 3 ] },
|
||
* { "orderDataType": "dom-select", "targets": [ 4 ] },
|
||
* { "orderDataType": "dom-checkbox", "targets": [ 5 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* null,
|
||
* null,
|
||
* { "orderDataType": "dom-text" },
|
||
* { "orderDataType": "dom-text", "type": "numeric" },
|
||
* { "orderDataType": "dom-select" },
|
||
* { "orderDataType": "dom-checkbox" }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sSortDataType": "std",
|
||
|
||
|
||
/**
|
||
* The title of this column.
|
||
* @type string
|
||
* @default null <i>Derived from the 'TH' value for this column in the
|
||
* original HTML table.</i>
|
||
*
|
||
* @name DataTable.defaults.column.title
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "title": "My column title", "targets": [ 0 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "title": "My column title" },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sTitle": null,
|
||
|
||
|
||
/**
|
||
* The type allows you to specify how the data for this column will be
|
||
* ordered. Four types (string, numeric, date and html (which will strip
|
||
* HTML tags before ordering)) are currently available. Note that only date
|
||
* formats understood by Javascript's Date() object will be accepted as type
|
||
* date. For example: "Mar 26, 2008 5:03 PM". May take the values: 'string',
|
||
* 'numeric', 'date' or 'html' (by default). Further types can be adding
|
||
* through plug-ins.
|
||
* @type string
|
||
* @default null <i>Auto-detected from raw data</i>
|
||
*
|
||
* @name DataTable.defaults.column.type
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "type": "html", "targets": [ 0 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "type": "html" },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sType": null,
|
||
|
||
|
||
/**
|
||
* Defining the width of the column, this parameter may take any CSS value
|
||
* (3em, 20px etc). DataTables applies 'smart' widths to columns which have not
|
||
* been given a specific width through this interface ensuring that the table
|
||
* remains readable.
|
||
* @type string
|
||
* @default null <i>Automatic</i>
|
||
*
|
||
* @name DataTable.defaults.column.width
|
||
* @dtopt Columns
|
||
*
|
||
* @example
|
||
* // Using `columnDefs`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columnDefs": [
|
||
* { "width": "20%", "targets": [ 0 ] }
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Using `columns`
|
||
* $(document).ready( function() {
|
||
* $('#example').dataTable( {
|
||
* "columns": [
|
||
* { "width": "20%" },
|
||
* null,
|
||
* null,
|
||
* null,
|
||
* null
|
||
* ]
|
||
* } );
|
||
* } );
|
||
*/
|
||
"sWidth": null
|
||
};
|
||
|
||
_fnHungarianMap( DataTable.defaults.column );
|
||
|
||
|
||
|
||
/**
|
||
* DataTables settings object - this holds all the information needed for a
|
||
* given table, including configuration, data and current application of the
|
||
* table options. DataTables does not have a single instance for each DataTable
|
||
* with the settings attached to that instance, but rather instances of the
|
||
* DataTable "class" are created on-the-fly as needed (typically by a
|
||
* $().dataTable() call) and the settings object is then applied to that
|
||
* instance.
|
||
*
|
||
* Note that this object is related to {@link DataTable.defaults} but this
|
||
* one is the internal data store for DataTables's cache of columns. It should
|
||
* NOT be manipulated outside of DataTables. Any configuration should be done
|
||
* through the initialisation options.
|
||
* @namespace
|
||
* @todo Really should attach the settings object to individual instances so we
|
||
* don't need to create new instances on each $().dataTable() call (if the
|
||
* table already exists). It would also save passing oSettings around and
|
||
* into every single function. However, this is a very significant
|
||
* architecture change for DataTables and will almost certainly break
|
||
* backwards compatibility with older installations. This is something that
|
||
* will be done in 2.0.
|
||
*/
|
||
DataTable.models.oSettings = {
|
||
/**
|
||
* Primary features of DataTables and their enablement state.
|
||
* @namespace
|
||
*/
|
||
"oFeatures": {
|
||
|
||
/**
|
||
* Flag to say if DataTables should automatically try to calculate the
|
||
* optimum table and columns widths (true) or not (false).
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bAutoWidth": null,
|
||
|
||
/**
|
||
* Delay the creation of TR and TD elements until they are actually
|
||
* needed by a driven page draw. This can give a significant speed
|
||
* increase for Ajax source and Javascript source data, but makes no
|
||
* difference at all fro DOM and server-side processing tables.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bDeferRender": null,
|
||
|
||
/**
|
||
* Enable filtering on the table or not. Note that if this is disabled
|
||
* then there is no filtering at all on the table, including fnFilter.
|
||
* To just remove the filtering input use sDom and remove the 'f' option.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bFilter": null,
|
||
|
||
/**
|
||
* Table information element (the 'Showing x of y records' div) enable
|
||
* flag.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bInfo": null,
|
||
|
||
/**
|
||
* Present a user control allowing the end user to change the page size
|
||
* when pagination is enabled.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bLengthChange": null,
|
||
|
||
/**
|
||
* Pagination enabled or not. Note that if this is disabled then length
|
||
* changing must also be disabled.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bPaginate": null,
|
||
|
||
/**
|
||
* Processing indicator enable flag whenever DataTables is enacting a
|
||
* user request - typically an Ajax request for server-side processing.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bProcessing": null,
|
||
|
||
/**
|
||
* Server-side processing enabled flag - when enabled DataTables will
|
||
* get all data from the server for every draw - there is no filtering,
|
||
* sorting or paging done on the client-side.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bServerSide": null,
|
||
|
||
/**
|
||
* Sorting enablement flag.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bSort": null,
|
||
|
||
/**
|
||
* Multi-column sorting
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bSortMulti": null,
|
||
|
||
/**
|
||
* Apply a class to the columns which are being sorted to provide a
|
||
* visual highlight or not. This can slow things down when enabled since
|
||
* there is a lot of DOM interaction.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bSortClasses": null,
|
||
|
||
/**
|
||
* State saving enablement flag.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bStateSave": null
|
||
},
|
||
|
||
|
||
/**
|
||
* Scrolling settings for a table.
|
||
* @namespace
|
||
*/
|
||
"oScroll": {
|
||
/**
|
||
* When the table is shorter in height than sScrollY, collapse the
|
||
* table container down to the height of the table (when true).
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bCollapse": null,
|
||
|
||
/**
|
||
* Width of the scrollbar for the web-browser's platform. Calculated
|
||
* during table initialisation.
|
||
* @type int
|
||
* @default 0
|
||
*/
|
||
"iBarWidth": 0,
|
||
|
||
/**
|
||
* Viewport width for horizontal scrolling. Horizontal scrolling is
|
||
* disabled if an empty string.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
*/
|
||
"sX": null,
|
||
|
||
/**
|
||
* Width to expand the table to when using x-scrolling. Typically you
|
||
* should not need to use this.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
* @deprecated
|
||
*/
|
||
"sXInner": null,
|
||
|
||
/**
|
||
* Viewport height for vertical scrolling. Vertical scrolling is disabled
|
||
* if an empty string.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
*/
|
||
"sY": null
|
||
},
|
||
|
||
/**
|
||
* Language information for the table.
|
||
* @namespace
|
||
* @extends DataTable.defaults.oLanguage
|
||
*/
|
||
"oLanguage": {
|
||
/**
|
||
* Information callback function. See
|
||
* {@link DataTable.defaults.fnInfoCallback}
|
||
* @type function
|
||
* @default null
|
||
*/
|
||
"fnInfoCallback": null
|
||
},
|
||
|
||
/**
|
||
* Browser support parameters
|
||
* @namespace
|
||
*/
|
||
"oBrowser": {
|
||
/**
|
||
* Indicate if the browser incorrectly calculates width:100% inside a
|
||
* scrolling element (IE6/7)
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bScrollOversize": false,
|
||
|
||
/**
|
||
* Determine if the vertical scrollbar is on the right or left of the
|
||
* scrolling container - needed for rtl language layout, although not
|
||
* all browsers move the scrollbar (Safari).
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bScrollbarLeft": false
|
||
},
|
||
|
||
|
||
"ajax": null,
|
||
|
||
|
||
/**
|
||
* Array referencing the nodes which are used for the features. The
|
||
* parameters of this object match what is allowed by sDom - i.e.
|
||
* <ul>
|
||
* <li>'l' - Length changing</li>
|
||
* <li>'f' - Filtering input</li>
|
||
* <li>'t' - The table!</li>
|
||
* <li>'i' - Information</li>
|
||
* <li>'p' - Pagination</li>
|
||
* <li>'r' - pRocessing</li>
|
||
* </ul>
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aanFeatures": [],
|
||
|
||
/**
|
||
* Store data information - see {@link DataTable.models.oRow} for detailed
|
||
* information.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoData": [],
|
||
|
||
/**
|
||
* Array of indexes which are in the current display (after filtering etc)
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aiDisplay": [],
|
||
|
||
/**
|
||
* Array of indexes for display - no filtering
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aiDisplayMaster": [],
|
||
|
||
/**
|
||
* Store information about each column that is in use
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoColumns": [],
|
||
|
||
/**
|
||
* Store information about the table's header
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoHeader": [],
|
||
|
||
/**
|
||
* Store information about the table's footer
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoFooter": [],
|
||
|
||
/**
|
||
* Store the applied global search information in case we want to force a
|
||
* research or compare the old search to a new one.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @namespace
|
||
* @extends DataTable.models.oSearch
|
||
*/
|
||
"oPreviousSearch": {},
|
||
|
||
/**
|
||
* Store the applied search for each column - see
|
||
* {@link DataTable.models.oSearch} for the format that is used for the
|
||
* filtering information for each column.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoPreSearchCols": [],
|
||
|
||
/**
|
||
* Sorting that is applied to the table. Note that the inner arrays are
|
||
* used in the following manner:
|
||
* <ul>
|
||
* <li>Index 0 - column number</li>
|
||
* <li>Index 1 - current sorting direction</li>
|
||
* </ul>
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type array
|
||
* @todo These inner arrays should really be objects
|
||
*/
|
||
"aaSorting": null,
|
||
|
||
/**
|
||
* Sorting that is always applied to the table (i.e. prefixed in front of
|
||
* aaSorting).
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aaSortingFixed": [],
|
||
|
||
/**
|
||
* Classes to use for the striping of a table.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"asStripeClasses": null,
|
||
|
||
/**
|
||
* If restoring a table - we should restore its striping classes as well
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"asDestroyStripes": [],
|
||
|
||
/**
|
||
* If restoring a table - we should restore its width
|
||
* @type int
|
||
* @default 0
|
||
*/
|
||
"sDestroyWidth": 0,
|
||
|
||
/**
|
||
* Callback functions array for every time a row is inserted (i.e. on a draw).
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoRowCallback": [],
|
||
|
||
/**
|
||
* Callback functions for the header on each draw.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoHeaderCallback": [],
|
||
|
||
/**
|
||
* Callback function for the footer on each draw.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoFooterCallback": [],
|
||
|
||
/**
|
||
* Array of callback functions for draw callback functions
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoDrawCallback": [],
|
||
|
||
/**
|
||
* Array of callback functions for row created function
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoRowCreatedCallback": [],
|
||
|
||
/**
|
||
* Callback functions for just before the table is redrawn. A return of
|
||
* false will be used to cancel the draw.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoPreDrawCallback": [],
|
||
|
||
/**
|
||
* Callback functions for when the table has been initialised.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoInitComplete": [],
|
||
|
||
|
||
/**
|
||
* Callbacks for modifying the settings to be stored for state saving, prior to
|
||
* saving state.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoStateSaveParams": [],
|
||
|
||
/**
|
||
* Callbacks for modifying the settings that have been stored for state saving
|
||
* prior to using the stored values to restore the state.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoStateLoadParams": [],
|
||
|
||
/**
|
||
* Callbacks for operating on the settings object once the saved state has been
|
||
* loaded
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoStateLoaded": [],
|
||
|
||
/**
|
||
* Cache the table ID for quick access
|
||
* @type string
|
||
* @default <i>Empty string</i>
|
||
*/
|
||
"sTableId": "",
|
||
|
||
/**
|
||
* The TABLE node for the main table
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTable": null,
|
||
|
||
/**
|
||
* Permanent ref to the thead element
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTHead": null,
|
||
|
||
/**
|
||
* Permanent ref to the tfoot element - if it exists
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTFoot": null,
|
||
|
||
/**
|
||
* Permanent ref to the tbody element
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTBody": null,
|
||
|
||
/**
|
||
* Cache the wrapper node (contains all DataTables controlled elements)
|
||
* @type node
|
||
* @default null
|
||
*/
|
||
"nTableWrapper": null,
|
||
|
||
/**
|
||
* Indicate if when using server-side processing the loading of data
|
||
* should be deferred until the second draw.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bDeferLoading": false,
|
||
|
||
/**
|
||
* Indicate if all required information has been read in
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bInitialised": false,
|
||
|
||
/**
|
||
* Information about open rows. Each object in the array has the parameters
|
||
* 'nTr' and 'nParent'
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoOpenRows": [],
|
||
|
||
/**
|
||
* Dictate the positioning of DataTables' control elements - see
|
||
* {@link DataTable.model.oInit.sDom}.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sDom": null,
|
||
|
||
/**
|
||
* Which type of pagination should be used.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
* @default two_button
|
||
*/
|
||
"sPaginationType": "two_button",
|
||
|
||
/**
|
||
* The state duration (for `stateSave`) in seconds.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type int
|
||
* @default 0
|
||
*/
|
||
"iStateDuration": 0,
|
||
|
||
/**
|
||
* Array of callback functions for state saving. Each array element is an
|
||
* object with the following parameters:
|
||
* <ul>
|
||
* <li>function:fn - function to call. Takes two parameters, oSettings
|
||
* and the JSON string to save that has been thus far created. Returns
|
||
* a JSON string to be inserted into a json object
|
||
* (i.e. '"param": [ 0, 1, 2]')</li>
|
||
* <li>string:sName - name of callback</li>
|
||
* </ul>
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoStateSave": [],
|
||
|
||
/**
|
||
* Array of callback functions for state loading. Each array element is an
|
||
* object with the following parameters:
|
||
* <ul>
|
||
* <li>function:fn - function to call. Takes two parameters, oSettings
|
||
* and the object stored. May return false to cancel state loading</li>
|
||
* <li>string:sName - name of callback</li>
|
||
* </ul>
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoStateLoad": [],
|
||
|
||
/**
|
||
* State that was loaded. Useful for back reference
|
||
* @type object
|
||
* @default null
|
||
*/
|
||
"oLoadedState": null,
|
||
|
||
/**
|
||
* Source url for AJAX data for the table.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sAjaxSource": null,
|
||
|
||
/**
|
||
* Property from a given object from which to read the table data from. This
|
||
* can be an empty string (when not server-side processing), in which case
|
||
* it is assumed an an array is given directly.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
*/
|
||
"sAjaxDataProp": null,
|
||
|
||
/**
|
||
* Note if draw should be blocked while getting data
|
||
* @type boolean
|
||
* @default true
|
||
*/
|
||
"bAjaxDataGet": true,
|
||
|
||
/**
|
||
* The last jQuery XHR object that was used for server-side data gathering.
|
||
* This can be used for working with the XHR information in one of the
|
||
* callbacks
|
||
* @type object
|
||
* @default null
|
||
*/
|
||
"jqXHR": null,
|
||
|
||
/**
|
||
* JSON returned from the server in the last Ajax request
|
||
* @type object
|
||
* @default undefined
|
||
*/
|
||
"json": undefined,
|
||
|
||
/**
|
||
* Data submitted as part of the last Ajax request
|
||
* @type object
|
||
* @default undefined
|
||
*/
|
||
"oAjaxData": undefined,
|
||
|
||
/**
|
||
* Function to get the server-side data.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type function
|
||
*/
|
||
"fnServerData": null,
|
||
|
||
/**
|
||
* Functions which are called prior to sending an Ajax request so extra
|
||
* parameters can easily be sent to the server
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoServerParams": [],
|
||
|
||
/**
|
||
* Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
|
||
* required).
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type string
|
||
*/
|
||
"sServerMethod": null,
|
||
|
||
/**
|
||
* Format numbers for display.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type function
|
||
*/
|
||
"fnFormatNumber": null,
|
||
|
||
/**
|
||
* List of options that can be used for the user selectable length menu.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aLengthMenu": null,
|
||
|
||
/**
|
||
* Counter for the draws that the table does. Also used as a tracker for
|
||
* server-side processing
|
||
* @type int
|
||
* @default 0
|
||
*/
|
||
"iDraw": 0,
|
||
|
||
/**
|
||
* Indicate if a redraw is being done - useful for Ajax
|
||
* @type boolean
|
||
* @default false
|
||
*/
|
||
"bDrawing": false,
|
||
|
||
/**
|
||
* Draw index (iDraw) of the last error when parsing the returned data
|
||
* @type int
|
||
* @default -1
|
||
*/
|
||
"iDrawError": -1,
|
||
|
||
/**
|
||
* Paging display length
|
||
* @type int
|
||
* @default 10
|
||
*/
|
||
"_iDisplayLength": 10,
|
||
|
||
/**
|
||
* Paging start point - aiDisplay index
|
||
* @type int
|
||
* @default 0
|
||
*/
|
||
"_iDisplayStart": 0,
|
||
|
||
/**
|
||
* Server-side processing - number of records in the result set
|
||
* (i.e. before filtering), Use fnRecordsTotal rather than
|
||
* this property to get the value of the number of records, regardless of
|
||
* the server-side processing setting.
|
||
* @type int
|
||
* @default 0
|
||
* @private
|
||
*/
|
||
"_iRecordsTotal": 0,
|
||
|
||
/**
|
||
* Server-side processing - number of records in the current display set
|
||
* (i.e. after filtering). Use fnRecordsDisplay rather than
|
||
* this property to get the value of the number of records, regardless of
|
||
* the server-side processing setting.
|
||
* @type boolean
|
||
* @default 0
|
||
* @private
|
||
*/
|
||
"_iRecordsDisplay": 0,
|
||
|
||
/**
|
||
* Flag to indicate if jQuery UI marking and classes should be used.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bJUI": null,
|
||
|
||
/**
|
||
* The classes to use for the table
|
||
* @type object
|
||
* @default {}
|
||
*/
|
||
"oClasses": {},
|
||
|
||
/**
|
||
* Flag attached to the settings object so you can check in the draw
|
||
* callback if filtering has been done in the draw. Deprecated in favour of
|
||
* events.
|
||
* @type boolean
|
||
* @default false
|
||
* @deprecated
|
||
*/
|
||
"bFiltered": false,
|
||
|
||
/**
|
||
* Flag attached to the settings object so you can check in the draw
|
||
* callback if sorting has been done in the draw. Deprecated in favour of
|
||
* events.
|
||
* @type boolean
|
||
* @default false
|
||
* @deprecated
|
||
*/
|
||
"bSorted": false,
|
||
|
||
/**
|
||
* Indicate that if multiple rows are in the header and there is more than
|
||
* one unique cell per column, if the top one (true) or bottom one (false)
|
||
* should be used for sorting / title by DataTables.
|
||
* Note that this parameter will be set by the initialisation routine. To
|
||
* set a default use {@link DataTable.defaults}.
|
||
* @type boolean
|
||
*/
|
||
"bSortCellsTop": null,
|
||
|
||
/**
|
||
* Initialisation object that is used for the table
|
||
* @type object
|
||
* @default null
|
||
*/
|
||
"oInit": null,
|
||
|
||
/**
|
||
* Destroy callback functions - for plug-ins to attach themselves to the
|
||
* destroy so they can clean up markup and events.
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aoDestroyCallback": [],
|
||
|
||
|
||
/**
|
||
* Get the number of records in the current record set, before filtering
|
||
* @type function
|
||
*/
|
||
"fnRecordsTotal": function ()
|
||
{
|
||
return _fnDataSource( this ) == 'ssp' ?
|
||
this._iRecordsTotal * 1 :
|
||
this.aiDisplayMaster.length;
|
||
},
|
||
|
||
/**
|
||
* Get the number of records in the current record set, after filtering
|
||
* @type function
|
||
*/
|
||
"fnRecordsDisplay": function ()
|
||
{
|
||
return _fnDataSource( this ) == 'ssp' ?
|
||
this._iRecordsDisplay * 1 :
|
||
this.aiDisplay.length;
|
||
},
|
||
|
||
/**
|
||
* Get the display end point - aiDisplay index
|
||
* @type function
|
||
*/
|
||
"fnDisplayEnd": function ()
|
||
{
|
||
var
|
||
len = this._iDisplayLength,
|
||
start = this._iDisplayStart,
|
||
calc = start + len,
|
||
records = this.aiDisplay.length,
|
||
features = this.oFeatures,
|
||
paginate = features.bPaginate;
|
||
|
||
if ( features.bServerSide ) {
|
||
return paginate === false || len === -1 ?
|
||
start + records :
|
||
Math.min( start+len, this._iRecordsDisplay );
|
||
}
|
||
else {
|
||
return ! paginate || calc>records || len===-1 ?
|
||
records :
|
||
calc;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* The DataTables object for this table
|
||
* @type object
|
||
* @default null
|
||
*/
|
||
"oInstance": null,
|
||
|
||
/**
|
||
* Unique identifier for each instance of the DataTables object. If there
|
||
* is an ID on the table node, then it takes that value, otherwise an
|
||
* incrementing internal counter is used.
|
||
* @type string
|
||
* @default null
|
||
*/
|
||
"sInstance": null,
|
||
|
||
/**
|
||
* tabindex attribute value that is added to DataTables control elements, allowing
|
||
* keyboard navigation of the table and its controls.
|
||
*/
|
||
"iTabIndex": 0,
|
||
|
||
/**
|
||
* DIV container for the footer scrolling table if scrolling
|
||
*/
|
||
"nScrollHead": null,
|
||
|
||
/**
|
||
* DIV container for the footer scrolling table if scrolling
|
||
*/
|
||
"nScrollFoot": null,
|
||
|
||
/**
|
||
* Last applied sort
|
||
* @type array
|
||
* @default []
|
||
*/
|
||
"aLastSort": [],
|
||
|
||
/**
|
||
* Stored plug-in instances
|
||
* @type object
|
||
* @default {}
|
||
*/
|
||
"oPlugins": {}
|
||
};
|
||
|
||
/**
|
||
* Extension object for DataTables that is used to provide all extension
|
||
* options.
|
||
*
|
||
* Note that the `DataTable.ext` object is available through
|
||
* `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is
|
||
* also aliased to `jQuery.fn.dataTableExt` for historic reasons.
|
||
* @namespace
|
||
* @extends DataTable.models.ext
|
||
*/
|
||
|
||
|
||
/**
|
||
* DataTables extensions
|
||
*
|
||
* This namespace acts as a collection area for plug-ins that can be used to
|
||
* extend DataTables capabilities. Indeed many of the build in methods
|
||
* use this method to provide their own capabilities (sorting methods for
|
||
* example).
|
||
*
|
||
* Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy
|
||
* reasons
|
||
*
|
||
* @namespace
|
||
*/
|
||
DataTable.ext = _ext = {
|
||
/**
|
||
* Element class names
|
||
*
|
||
* @type object
|
||
* @default {}
|
||
*/
|
||
classes: {},
|
||
|
||
|
||
/**
|
||
* Error reporting.
|
||
*
|
||
* How should DataTables report an error. Can take the value 'alert' or
|
||
* 'throw'
|
||
*
|
||
* @type string
|
||
* @default alert
|
||
*/
|
||
errMode: "alert",
|
||
|
||
|
||
/**
|
||
* Feature plug-ins.
|
||
*
|
||
* This is an array of objects which describe the feature plug-ins that are
|
||
* available to DataTables. These feature plug-ins are then available for
|
||
* use through the `dom` initialisation option.
|
||
*
|
||
* Each feature plug-in is described by an object which must have the
|
||
* following properties:
|
||
*
|
||
* * `fnInit` - function that is used to initialise the plug-in,
|
||
* * `cFeature` - a character so the feature can be enabled by the `dom`
|
||
* instillation option. This is case sensitive.
|
||
*
|
||
* The `fnInit` function has the following input parameters:
|
||
*
|
||
* 1. `{object}` DataTables settings object: see
|
||
* {@link DataTable.models.oSettings}
|
||
*
|
||
* And the following return is expected:
|
||
*
|
||
* * {node|null} The element which contains your feature. Note that the
|
||
* return may also be void if your plug-in does not require to inject any
|
||
* DOM elements into DataTables control (`dom`) - for example this might
|
||
* be useful when developing a plug-in which allows table control via
|
||
* keyboard entry
|
||
*
|
||
* @type array
|
||
*
|
||
* @example
|
||
* $.fn.dataTable.ext.features.push( {
|
||
* "fnInit": function( oSettings ) {
|
||
* return new TableTools( { "oDTSettings": oSettings } );
|
||
* },
|
||
* "cFeature": "T"
|
||
* } );
|
||
*/
|
||
feature: [],
|
||
|
||
|
||
/**
|
||
* Row searching.
|
||
*
|
||
* This method of searching is complimentary to the default type based
|
||
* searching, and a lot more comprehensive as it allows you complete control
|
||
* over the searching logic. Each element in this array is a function
|
||
* (parameters described below) that is called for every row in the table,
|
||
* and your logic decides if it should be included in the searching data set
|
||
* or not.
|
||
*
|
||
* Searching functions have the following input parameters:
|
||
*
|
||
* 1. `{object}` DataTables settings object: see
|
||
* {@link DataTable.models.oSettings}
|
||
* 2. `{array|object}` Data for the row to be processed (same as the
|
||
* original format that was passed in as the data source, or an array
|
||
* from a DOM data source
|
||
* 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which
|
||
* can be useful to retrieve the `TR` element if you need DOM interaction.
|
||
*
|
||
* And the following return is expected:
|
||
*
|
||
* * {boolean} Include the row in the searched result set (true) or not
|
||
* (false)
|
||
*
|
||
* Note that as with the main search ability in DataTables, technically this
|
||
* is "filtering", since it is subtractive. However, for consistency in
|
||
* naming we call it searching here.
|
||
*
|
||
* @type array
|
||
* @default []
|
||
*
|
||
* @example
|
||
* // The following example shows custom search being applied to the
|
||
* // fourth column (i.e. the data[3] index) based on two input values
|
||
* // from the end-user, matching the data in a certain range.
|
||
* $.fn.dataTable.ext.search.push(
|
||
* function( settings, data, dataIndex ) {
|
||
* var min = document.getElementById('min').value * 1;
|
||
* var max = document.getElementById('max').value * 1;
|
||
* var version = data[3] == "-" ? 0 : data[3]*1;
|
||
*
|
||
* if ( min == "" && max == "" ) {
|
||
* return true;
|
||
* }
|
||
* else if ( min == "" && version < max ) {
|
||
* return true;
|
||
* }
|
||
* else if ( min < version && "" == max ) {
|
||
* return true;
|
||
* }
|
||
* else if ( min < version && version < max ) {
|
||
* return true;
|
||
* }
|
||
* return false;
|
||
* }
|
||
* );
|
||
*/
|
||
search: [],
|
||
|
||
|
||
/**
|
||
* Internal functions, exposed for used in plug-ins.
|
||
*
|
||
* Please note that you should not need to use the internal methods for
|
||
* anything other than a plug-in (and even then, try to avoid if possible).
|
||
* The internal function may change between releases.
|
||
*
|
||
* @type object
|
||
* @default {}
|
||
*/
|
||
internal: {},
|
||
|
||
|
||
/**
|
||
* Legacy configuration options. Enable and disable legacy options that
|
||
* are available in DataTables.
|
||
*
|
||
* @type object
|
||
*/
|
||
legacy: {
|
||
/**
|
||
* Enable / disable DataTables 1.9 compatible server-side processing
|
||
* requests
|
||
*
|
||
* @type boolean
|
||
* @default null
|
||
*/
|
||
ajax: null
|
||
},
|
||
|
||
|
||
/**
|
||
* Pagination plug-in methods.
|
||
*
|
||
* Each entry in this object is a function and defines which buttons should
|
||
* be shown by the pagination rendering method that is used for the table:
|
||
* {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the
|
||
* buttons are displayed in the document, while the functions here tell it
|
||
* what buttons to display. This is done by returning an array of button
|
||
* descriptions (what each button will do).
|
||
*
|
||
* Pagination types (the four built in options and any additional plug-in
|
||
* options defined here) can be used through the `paginationType`
|
||
* initialisation parameter.
|
||
*
|
||
* The functions defined take two parameters:
|
||
*
|
||
* 1. `{int} page` The current page index
|
||
* 2. `{int} pages` The number of pages in the table
|
||
*
|
||
* Each function is expected to return an array where each element of the
|
||
* array can be one of:
|
||
*
|
||
* * `first` - Jump to first page when activated
|
||
* * `last` - Jump to last page when activated
|
||
* * `previous` - Show previous page when activated
|
||
* * `next` - Show next page when activated
|
||
* * `{int}` - Show page of the index given
|
||
* * `{array}` - A nested array containing the above elements to add a
|
||
* containing 'DIV' element (might be useful for styling).
|
||
*
|
||
* Note that DataTables v1.9- used this object slightly differently whereby
|
||
* an object with two functions would be defined for each plug-in. That
|
||
* ability is still supported by DataTables 1.10+ to provide backwards
|
||
* compatibility, but this option of use is now decremented and no longer
|
||
* documented in DataTables 1.10+.
|
||
*
|
||
* @type object
|
||
* @default {}
|
||
*
|
||
* @example
|
||
* // Show previous, next and current page buttons only
|
||
* $.fn.dataTableExt.oPagination.current = function ( page, pages ) {
|
||
* return [ 'previous', page, 'next' ];
|
||
* };
|
||
*/
|
||
pager: {},
|
||
|
||
|
||
renderer: {
|
||
pageButton: {},
|
||
header: {}
|
||
},
|
||
|
||
|
||
/**
|
||
* Ordering plug-ins - custom data source
|
||
*
|
||
* The extension options for ordering of data available here is complimentary
|
||
* to the default type based ordering that DataTables typically uses. It
|
||
* allows much greater control over the the data that is being used to
|
||
* order a column, but is necessarily therefore more complex.
|
||
*
|
||
* This type of ordering is useful if you want to do ordering based on data
|
||
* live from the DOM (for example the contents of an 'input' element) rather
|
||
* than just the static string that DataTables knows of.
|
||
*
|
||
* The way these plug-ins work is that you create an array of the values you
|
||
* wish to be ordering for the column in question and then return that
|
||
* array. The data in the array much be in the index order of the rows in
|
||
* the table (not the currently ordering order!). Which order data gathering
|
||
* function is run here depends on the `dt-init columns.orderDataType`
|
||
* parameter that is used for the column (if any).
|
||
*
|
||
* The functions defined take two parameters:
|
||
*
|
||
* 1. `{object}` DataTables settings object: see
|
||
* {@link DataTable.models.oSettings}
|
||
* 2. `{int}` Target column index
|
||
*
|
||
* Each function is expected to return an array:
|
||
*
|
||
* * `{array}` Data for the column to be ordering upon
|
||
*
|
||
* @type array
|
||
*
|
||
* @example
|
||
* // Ordering using `input` node values
|
||
* $.fn.dataTable.ext.order['dom-text'] = function ( settings, col )
|
||
* {
|
||
* return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {
|
||
* return $('input', td).val();
|
||
* } );
|
||
* }
|
||
*/
|
||
order: {},
|
||
|
||
|
||
/**
|
||
* Type based plug-ins.
|
||
*
|
||
* Each column in DataTables has a type assigned to it, either by automatic
|
||
* detection or by direct assignment using the `type` option for the column.
|
||
* The type of a column will effect how it is ordering and search (plug-ins
|
||
* can also make use of the column type if required).
|
||
*
|
||
* @namespace
|
||
*/
|
||
type: {
|
||
/**
|
||
* Type detection functions.
|
||
*
|
||
* The functions defined in this object are used to automatically detect
|
||
* a column's type, making initialisation of DataTables super easy, even
|
||
* when complex data is in the table.
|
||
*
|
||
* The functions defined take two parameters:
|
||
*
|
||
* 1. `{*}` Data from the column cell to be analysed
|
||
* 2. `{settings}` DataTables settings object. This can be used to
|
||
* perform context specific type detection - for example detection
|
||
* based on language settings such as using a comma for a decimal
|
||
* place. Generally speaking the options from the settings will not
|
||
* be required
|
||
*
|
||
* Each function is expected to return:
|
||
*
|
||
* * `{string|null}` Data type detected, or null if unknown (and thus
|
||
* pass it on to the other type detection functions.
|
||
*
|
||
* @type array
|
||
*
|
||
* @example
|
||
* // Currency type detection plug-in:
|
||
* $.fn.dataTable.ext.type.detect.push(
|
||
* function ( data, settings ) {
|
||
* // Check the numeric part
|
||
* if ( ! $.isNumeric( data.substring(1) ) ) {
|
||
* return null;
|
||
* }
|
||
*
|
||
* // Check prefixed by currency
|
||
* if ( data.charAt(0) == '$' || data.charAt(0) == '£' ) {
|
||
* return 'currency';
|
||
* }
|
||
* return null;
|
||
* }
|
||
* );
|
||
*/
|
||
detect: [],
|
||
|
||
|
||
/**
|
||
* Type based search formatting.
|
||
*
|
||
* The type based searching functions can be used to pre-format the
|
||
* data to be search on. For example, it can be used to strip HTML
|
||
* tags or to de-format telephone numbers for numeric only searching.
|
||
*
|
||
* Note that is a search is not defined for a column of a given type,
|
||
* no search formatting will be performed.
|
||
*
|
||
* Pre-processing of searching data plug-ins - When you assign the sType
|
||
* for a column (or have it automatically detected for you by DataTables
|
||
* or a type detection plug-in), you will typically be using this for
|
||
* custom sorting, but it can also be used to provide custom searching
|
||
* by allowing you to pre-processing the data and returning the data in
|
||
* the format that should be searched upon. This is done by adding
|
||
* functions this object with a parameter name which matches the sType
|
||
* for that target column. This is the corollary of <i>afnSortData</i>
|
||
* for searching data.
|
||
*
|
||
* The functions defined take a single parameter:
|
||
*
|
||
* 1. `{*}` Data from the column cell to be prepared for searching
|
||
*
|
||
* Each function is expected to return:
|
||
*
|
||
* * `{string|null}` Formatted string that will be used for the searching.
|
||
*
|
||
* @type object
|
||
* @default {}
|
||
*
|
||
* @example
|
||
* $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {
|
||
* return d.replace(/\n/g," ").replace( /<.*?>/g, "" );
|
||
* }
|
||
*/
|
||
search: {},
|
||
|
||
|
||
/**
|
||
* Type based ordering.
|
||
*
|
||
* The column type tells DataTables what ordering to apply to the table
|
||
* when a column is sorted upon. The order for each type that is defined,
|
||
* is defined by the functions available in this object.
|
||
*
|
||
* Each ordering option can be described by three properties added to
|
||
* this object:
|
||
*
|
||
* * `{type}-pre` - Pre-formatting function
|
||
* * `{type}-asc` - Ascending order function
|
||
* * `{type}-desc` - Descending order function
|
||
*
|
||
* All three can be used together, only `{type}-pre` or only
|
||
* `{type}-asc` and `{type}-desc` together. It is generally recommended
|
||
* that only `{type}-pre` is used, as this provides the optimal
|
||
* implementation in terms of speed, although the others are provided
|
||
* for compatibility with existing Javascript sort functions.
|
||
*
|
||
* `{type}-pre`: Functions defined take a single parameter:
|
||
*
|
||
* 1. `{*}` Data from the column cell to be prepared for ordering
|
||
*
|
||
* And return:
|
||
*
|
||
* * `{*}` Data to be sorted upon
|
||
*
|
||
* `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort
|
||
* functions, taking two parameters:
|
||
*
|
||
* 1. `{*}` Data to compare to the second parameter
|
||
* 2. `{*}` Data to compare to the first parameter
|
||
*
|
||
* And returning:
|
||
*
|
||
* * `{*}` Ordering match: <0 if first parameter should be sorted lower
|
||
* than the second parameter, ===0 if the two parameters are equal and
|
||
* >0 if the first parameter should be sorted height than the second
|
||
* parameter.
|
||
*
|
||
* @type object
|
||
* @default {}
|
||
*
|
||
* @example
|
||
* // Numeric ordering of formatted numbers with a pre-formatter
|
||
* $.extend( $.fn.dataTable.ext.type.order, {
|
||
* "string-pre": function(x) {
|
||
* a = (a === "-" || a === "") ? 0 : a.replace( /[^\d\-\.]/g, "" );
|
||
* return parseFloat( a );
|
||
* }
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Case-sensitive string ordering, with no pre-formatting method
|
||
* $.extend( $.fn.dataTable.ext.order, {
|
||
* "string-case-asc": function(x,y) {
|
||
* return ((x < y) ? -1 : ((x > y) ? 1 : 0));
|
||
* },
|
||
* "string-case-desc": function(x,y) {
|
||
* return ((x < y) ? 1 : ((x > y) ? -1 : 0));
|
||
* }
|
||
* } );
|
||
*/
|
||
order: {}
|
||
},
|
||
|
||
/**
|
||
* Unique DataTables instance counter
|
||
*
|
||
* @type int
|
||
* @private
|
||
*/
|
||
_unique: 0,
|
||
|
||
|
||
//
|
||
// Depreciated
|
||
// The following properties are retained for backwards compatiblity only.
|
||
// The should not be used in new projects and will be removed in a future
|
||
// version
|
||
//
|
||
|
||
/**
|
||
* Version check function.
|
||
* @type function
|
||
* @depreciated Since 1.10
|
||
*/
|
||
fnVersionCheck: DataTable.fnVersionCheck,
|
||
|
||
|
||
/**
|
||
* Index for what 'this' index API functions should use
|
||
* @type int
|
||
* @deprecated Since v1.10
|
||
*/
|
||
iApiIndex: 0,
|
||
|
||
|
||
/**
|
||
* jQuery UI class container
|
||
* @type object
|
||
* @deprecated Since v1.10
|
||
*/
|
||
oJUIClasses: {},
|
||
|
||
|
||
/**
|
||
* Software version
|
||
* @type string
|
||
* @deprecated Since v1.10
|
||
*/
|
||
sVersion: DataTable.version
|
||
};
|
||
|
||
|
||
//
|
||
// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts
|
||
//
|
||
$.extend( _ext, {
|
||
afnFiltering: _ext.search,
|
||
aTypes: _ext.type.detect,
|
||
ofnSearch: _ext.type.search,
|
||
oSort: _ext.type.order,
|
||
afnSortData: _ext.order,
|
||
aoFeatures: _ext.feature,
|
||
oApi: _ext.internal,
|
||
oStdClasses: _ext.classes,
|
||
oPagination: _ext.pager
|
||
} );
|
||
|
||
|
||
$.extend( DataTable.ext.classes, {
|
||
"sTable": "dataTable",
|
||
"sNoFooter": "no-footer",
|
||
|
||
/* Paging buttons */
|
||
"sPageButton": "paginate_button",
|
||
"sPageButtonActive": "current",
|
||
"sPageButtonDisabled": "disabled",
|
||
|
||
/* Striping classes */
|
||
"sStripeOdd": "odd",
|
||
"sStripeEven": "even",
|
||
|
||
/* Empty row */
|
||
"sRowEmpty": "dataTables_empty",
|
||
|
||
/* Features */
|
||
"sWrapper": "dataTables_wrapper",
|
||
"sFilter": "dataTables_filter",
|
||
"sInfo": "dataTables_info",
|
||
"sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
|
||
"sLength": "dataTables_length",
|
||
"sProcessing": "dataTables_processing",
|
||
|
||
/* Sorting */
|
||
"sSortAsc": "sorting_asc",
|
||
"sSortDesc": "sorting_desc",
|
||
"sSortable": "sorting", /* Sortable in both directions */
|
||
"sSortableAsc": "sorting_asc_disabled",
|
||
"sSortableDesc": "sorting_desc_disabled",
|
||
"sSortableNone": "sorting_disabled",
|
||
"sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
|
||
|
||
/* Filtering */
|
||
"sFilterInput": "",
|
||
|
||
/* Page length */
|
||
"sLengthSelect": "",
|
||
|
||
/* Scrolling */
|
||
"sScrollWrapper": "dataTables_scroll",
|
||
"sScrollHead": "dataTables_scrollHead",
|
||
"sScrollHeadInner": "dataTables_scrollHeadInner",
|
||
"sScrollBody": "dataTables_scrollBody",
|
||
"sScrollFoot": "dataTables_scrollFoot",
|
||
"sScrollFootInner": "dataTables_scrollFootInner",
|
||
|
||
/* Misc */
|
||
"sHeaderTH": "",
|
||
"sFooterTH": "",
|
||
|
||
// Deprecated
|
||
"sSortJUIAsc": "",
|
||
"sSortJUIDesc": "",
|
||
"sSortJUI": "",
|
||
"sSortJUIAscAllowed": "",
|
||
"sSortJUIDescAllowed": "",
|
||
"sSortJUIWrapper": "",
|
||
"sSortIcon": "",
|
||
"sJUIHeader": "",
|
||
"sJUIFooter": ""
|
||
} );
|
||
|
||
|
||
(function() {
|
||
|
||
// Reused strings for better compression. Closure compiler appears to have a
|
||
// weird edge case where it is trying to expand strings rather than use the
|
||
// variable version. This results in about 200 bytes being added, for very
|
||
// little preference benefit since it this run on script load only.
|
||
var _empty = '';
|
||
_empty = '';
|
||
|
||
var _stateDefault = _empty + 'ui-state-default';
|
||
var _sortIcon = _empty + 'css_right ui-icon ui-icon-';
|
||
var _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';
|
||
|
||
$.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {
|
||
/* Full numbers paging buttons */
|
||
"sPageButton": "fg-button ui-button "+_stateDefault,
|
||
"sPageButtonActive": "ui-state-disabled",
|
||
"sPageButtonDisabled": "ui-state-disabled",
|
||
|
||
/* Features */
|
||
"sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
|
||
"ui-buttonset-multi paging_", /* Note that the type is postfixed */
|
||
|
||
/* Sorting */
|
||
"sSortAsc": _stateDefault+" sorting_asc",
|
||
"sSortDesc": _stateDefault+" sorting_desc",
|
||
"sSortable": _stateDefault+" sorting",
|
||
"sSortableAsc": _stateDefault+" sorting_asc_disabled",
|
||
"sSortableDesc": _stateDefault+" sorting_desc_disabled",
|
||
"sSortableNone": _stateDefault+" sorting_disabled",
|
||
"sSortJUIAsc": _sortIcon+"triangle-1-n",
|
||
"sSortJUIDesc": _sortIcon+"triangle-1-s",
|
||
"sSortJUI": _sortIcon+"carat-2-n-s",
|
||
"sSortJUIAscAllowed": _sortIcon+"carat-1-n",
|
||
"sSortJUIDescAllowed": _sortIcon+"carat-1-s",
|
||
"sSortJUIWrapper": "DataTables_sort_wrapper",
|
||
"sSortIcon": "DataTables_sort_icon",
|
||
|
||
/* Scrolling */
|
||
"sScrollHead": "dataTables_scrollHead "+_stateDefault,
|
||
"sScrollFoot": "dataTables_scrollFoot "+_stateDefault,
|
||
|
||
/* Misc */
|
||
"sHeaderTH": _stateDefault,
|
||
"sFooterTH": _stateDefault,
|
||
"sJUIHeader": _headerFooter+" ui-corner-tl ui-corner-tr",
|
||
"sJUIFooter": _headerFooter+" ui-corner-bl ui-corner-br"
|
||
} );
|
||
|
||
}());
|
||
|
||
|
||
|
||
var extPagination = DataTable.ext.pager;
|
||
|
||
function _numbers ( page, pages ) {
|
||
var
|
||
numbers = [],
|
||
buttons = extPagination.numbers_length,
|
||
half = Math.floor( buttons / 2 ),
|
||
i = 1;
|
||
|
||
if ( pages <= buttons ) {
|
||
numbers = _range( 0, pages );
|
||
}
|
||
else if ( page <= half ) {
|
||
numbers = _range( 0, buttons-2 );
|
||
numbers.push( 'ellipsis' );
|
||
numbers.push( pages-1 );
|
||
}
|
||
else if ( page >= pages - 1 - half ) {
|
||
numbers = _range( pages-(buttons-2), pages );
|
||
numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
|
||
numbers.splice( 0, 0, 0 );
|
||
}
|
||
else {
|
||
numbers = _range( page-1, page+2 );
|
||
numbers.push( 'ellipsis' );
|
||
numbers.push( pages-1 );
|
||
numbers.splice( 0, 0, 'ellipsis' );
|
||
numbers.splice( 0, 0, 0 );
|
||
}
|
||
|
||
numbers.DT_el = 'span';
|
||
return numbers;
|
||
}
|
||
|
||
|
||
$.extend( extPagination, {
|
||
simple: function ( page, pages ) {
|
||
return [ 'previous', 'next' ];
|
||
},
|
||
|
||
full: function ( page, pages ) {
|
||
return [ 'first', 'previous', 'next', 'last' ];
|
||
},
|
||
|
||
simple_numbers: function ( page, pages ) {
|
||
return [ 'previous', _numbers(page, pages), 'next' ];
|
||
},
|
||
|
||
full_numbers: function ( page, pages ) {
|
||
return [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];
|
||
},
|
||
|
||
// For testing and plug-ins to use
|
||
_numbers: _numbers,
|
||
numbers_length: 7
|
||
} );
|
||
|
||
|
||
$.extend( true, DataTable.ext.renderer, {
|
||
pageButton: {
|
||
_: function ( settings, host, idx, buttons, page, pages ) {
|
||
var classes = settings.oClasses;
|
||
var lang = settings.oLanguage.oPaginate;
|
||
var btnDisplay, btnClass, counter=0;
|
||
|
||
var attach = function( container, buttons ) {
|
||
var i, ien, node, button;
|
||
var clickHandler = function ( e ) {
|
||
_fnPageChange( settings, e.data.action, true );
|
||
};
|
||
|
||
for ( i=0, ien=buttons.length ; i<ien ; i++ ) {
|
||
button = buttons[i];
|
||
|
||
if ( $.isArray( button ) ) {
|
||
var inner = $( '<'+(button.DT_el || 'div')+'/>' )
|
||
.appendTo( container );
|
||
attach( inner, button );
|
||
}
|
||
else {
|
||
btnDisplay = '';
|
||
btnClass = '';
|
||
|
||
switch ( button ) {
|
||
case 'ellipsis':
|
||
container.append('<span>…</span>');
|
||
break;
|
||
|
||
case 'first':
|
||
btnDisplay = lang.sFirst;
|
||
btnClass = button + (page > 0 ?
|
||
'' : ' '+classes.sPageButtonDisabled);
|
||
break;
|
||
|
||
case 'previous':
|
||
btnDisplay = lang.sPrevious;
|
||
btnClass = button + (page > 0 ?
|
||
'' : ' '+classes.sPageButtonDisabled);
|
||
break;
|
||
|
||
case 'next':
|
||
btnDisplay = lang.sNext;
|
||
btnClass = button + (page < pages-1 ?
|
||
'' : ' '+classes.sPageButtonDisabled);
|
||
break;
|
||
|
||
case 'last':
|
||
btnDisplay = lang.sLast;
|
||
btnClass = button + (page < pages-1 ?
|
||
'' : ' '+classes.sPageButtonDisabled);
|
||
break;
|
||
|
||
default:
|
||
btnDisplay = button + 1;
|
||
btnClass = page === button ?
|
||
classes.sPageButtonActive : '';
|
||
break;
|
||
}
|
||
|
||
if ( btnDisplay ) {
|
||
node = $('<a>', {
|
||
'class': classes.sPageButton+' '+btnClass,
|
||
'aria-controls': settings.sTableId,
|
||
'data-dt-idx': counter,
|
||
'tabindex': settings.iTabIndex,
|
||
'id': idx === 0 && typeof button === 'string' ?
|
||
settings.sTableId +'_'+ button :
|
||
null
|
||
} )
|
||
.html( btnDisplay )
|
||
.appendTo( container );
|
||
|
||
_fnBindAction(
|
||
node, {action: button}, clickHandler
|
||
);
|
||
|
||
counter++;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
// Because this approach is destroying and recreating the paging
|
||
// elements, focus is lost on the select button which is bad for
|
||
// accessibility. So we want to restore focus once the draw has
|
||
// completed
|
||
var activeEl = $(document.activeElement).data('dt-idx');
|
||
|
||
attach( $(host).empty(), buttons );
|
||
|
||
if ( activeEl !== null ) {
|
||
$(host).find( '[data-dt-idx='+activeEl+']' ).focus();
|
||
}
|
||
}
|
||
}
|
||
} );
|
||
|
||
|
||
|
||
var __numericReplace = function ( d, decimalPlace, re1, re2 ) {
|
||
if ( !d || d === '-' ) {
|
||
return -Infinity;
|
||
}
|
||
|
||
// If a decimal place other than `.` is used, it needs to be given to the
|
||
// function so we can detect it and replace with a `.` which is the only
|
||
// decimal place Javascript recognises - it is not locale aware.
|
||
if ( decimalPlace ) {
|
||
d = _numToDecimal( d, decimalPlace );
|
||
}
|
||
|
||
if ( d.replace ) {
|
||
if ( re1 ) {
|
||
d = d.replace( re1, '' );
|
||
}
|
||
|
||
if ( re2 ) {
|
||
d = d.replace( re2, '' );
|
||
}
|
||
}
|
||
|
||
return d * 1;
|
||
};
|
||
|
||
|
||
// Add the numeric 'deformatting' functions for sorting. This is done in a
|
||
// function to provide an easy ability for the language options to add
|
||
// additional methods if a non-period decimal place is used.
|
||
function _addNumericSort ( decimalPlace ) {
|
||
$.each(
|
||
{
|
||
// Plain numbers
|
||
"num": function ( d ) {
|
||
return __numericReplace( d, decimalPlace );
|
||
},
|
||
|
||
// Formatted numbers
|
||
"num-fmt": function ( d ) {
|
||
return __numericReplace( d, decimalPlace, _re_formatted_numeric );
|
||
},
|
||
|
||
// HTML numeric
|
||
"html-num": function ( d ) {
|
||
return __numericReplace( d, decimalPlace, _re_html );
|
||
},
|
||
|
||
// HTML numeric, formatted
|
||
"html-num-fmt": function ( d ) {
|
||
return __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );
|
||
}
|
||
},
|
||
function ( key, fn ) {
|
||
_ext.type.order[ key+decimalPlace+'-pre' ] = fn;
|
||
}
|
||
);
|
||
}
|
||
|
||
|
||
// Default sort methods
|
||
$.extend( _ext.type.order, {
|
||
// Dates
|
||
"date-pre": function ( d ) {
|
||
return Date.parse( d ) || 0;
|
||
},
|
||
|
||
// html
|
||
"html-pre": function ( a ) {
|
||
return ! a ?
|
||
'' :
|
||
a.replace ?
|
||
a.replace( /<.*?>/g, "" ).toLowerCase() :
|
||
a+'';
|
||
},
|
||
|
||
// string
|
||
"string-pre": function ( a ) {
|
||
return typeof a === 'string' ?
|
||
a.toLowerCase() :
|
||
! a || ! a.toString ?
|
||
'' :
|
||
a.toString();
|
||
},
|
||
|
||
// string-asc and -desc are retained only for compatibility with the old
|
||
// sort methods
|
||
"string-asc": function ( x, y ) {
|
||
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
|
||
},
|
||
|
||
"string-desc": function ( x, y ) {
|
||
return ((x < y) ? 1 : ((x > y) ? -1 : 0));
|
||
}
|
||
} );
|
||
|
||
|
||
// Numeric sorting types - order doesn't matter here
|
||
_addNumericSort( '' );
|
||
|
||
|
||
// Built in type detection. See model.ext.aTypes for information about
|
||
// what is required from this methods.
|
||
$.extend( DataTable.ext.type.detect, [
|
||
// Plain numbers - first since V8 detects some plain numbers as dates
|
||
// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).
|
||
function ( d, settings )
|
||
{
|
||
var decimal = settings.oLanguage.sDecimal;
|
||
return _isNumber( d, decimal ) ? 'num'+decimal : null;
|
||
},
|
||
|
||
// Dates (only those recognised by the browser's Date.parse)
|
||
function ( d, settings )
|
||
{
|
||
// V8 will remove any unknown characters at the start of the expression,
|
||
// leading to false matches such as `$245.12` being a valid date. See
|
||
// forum thread 18941 for detail.
|
||
if ( d && ! _re_date_start.test(d) ) {
|
||
return null;
|
||
}
|
||
var parsed = Date.parse(d);
|
||
return (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;
|
||
},
|
||
|
||
// Formatted numbers
|
||
function ( d, settings )
|
||
{
|
||
var decimal = settings.oLanguage.sDecimal;
|
||
return _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;
|
||
},
|
||
|
||
// HTML numeric
|
||
function ( d, settings )
|
||
{
|
||
var decimal = settings.oLanguage.sDecimal;
|
||
return _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;
|
||
},
|
||
|
||
// HTML numeric, formatted
|
||
function ( d, settings )
|
||
{
|
||
var decimal = settings.oLanguage.sDecimal;
|
||
return _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;
|
||
},
|
||
|
||
// HTML (this is strict checking - there must be html)
|
||
function ( d, settings )
|
||
{
|
||
return _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?
|
||
'html' : null;
|
||
}
|
||
] );
|
||
|
||
|
||
|
||
// Filter formatting functions. See model.ext.ofnSearch for information about
|
||
// what is required from these methods.
|
||
|
||
|
||
$.extend( DataTable.ext.type.search, {
|
||
html: function ( data ) {
|
||
return _empty(data) ?
|
||
'' :
|
||
typeof data === 'string' ?
|
||
data
|
||
.replace( _re_new_lines, " " )
|
||
.replace( _re_html, "" ) :
|
||
'';
|
||
},
|
||
|
||
string: function ( data ) {
|
||
return _empty(data) ?
|
||
'' :
|
||
typeof data === 'string' ?
|
||
data.replace( _re_new_lines, " " ) :
|
||
data;
|
||
}
|
||
} );
|
||
|
||
|
||
|
||
$.extend( true, DataTable.ext.renderer, {
|
||
header: {
|
||
_: function ( settings, cell, column, classes ) {
|
||
// No additional mark-up required
|
||
// Attach a sort listener to update on sort - note that using the
|
||
// `DT` namespace will allow the event to be removed automatically
|
||
// on destroy, while the `dt` namespaced event is the one we are
|
||
// listening for
|
||
$(settings.nTable).on( 'order.dt.DT', function ( e, settings, sorting, columns ) {
|
||
var colIdx = column.idx;
|
||
|
||
cell
|
||
.removeClass(
|
||
column.sSortingClass +' '+
|
||
classes.sSortAsc +' '+
|
||
classes.sSortDesc
|
||
)
|
||
.addClass( columns[ colIdx ] == 'asc' ?
|
||
classes.sSortAsc : columns[ colIdx ] == 'desc' ?
|
||
classes.sSortDesc :
|
||
column.sSortingClass
|
||
);
|
||
} );
|
||
},
|
||
|
||
jqueryui: function ( settings, cell, column, classes ) {
|
||
var colIdx = column.idx;
|
||
|
||
$('<div/>')
|
||
.addClass( classes.sSortJUIWrapper )
|
||
.append( cell.contents() )
|
||
.append( $('<span/>')
|
||
.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )
|
||
)
|
||
.appendTo( cell );
|
||
|
||
// Attach a sort listener to update on sort
|
||
$(settings.nTable).on( 'order.dt.DT', function ( e, settings, sorting, columns ) {
|
||
cell
|
||
.removeClass( classes.sSortAsc +" "+classes.sSortDesc )
|
||
.addClass( columns[ colIdx ] == 'asc' ?
|
||
classes.sSortAsc : columns[ colIdx ] == 'desc' ?
|
||
classes.sSortDesc :
|
||
column.sSortingClass
|
||
);
|
||
|
||
cell
|
||
.find( 'span.'+classes.sSortIcon )
|
||
.removeClass(
|
||
classes.sSortJUIAsc +" "+
|
||
classes.sSortJUIDesc +" "+
|
||
classes.sSortJUI +" "+
|
||
classes.sSortJUIAscAllowed +" "+
|
||
classes.sSortJUIDescAllowed
|
||
)
|
||
.addClass( columns[ colIdx ] == 'asc' ?
|
||
classes.sSortJUIAsc : columns[ colIdx ] == 'desc' ?
|
||
classes.sSortJUIDesc :
|
||
column.sSortingClassJUI
|
||
);
|
||
} );
|
||
}
|
||
}
|
||
} );
|
||
|
||
/*
|
||
* Public helper functions. These aren't used internally by DataTables, or
|
||
* called by any of the options passed into DataTables, but they can be used
|
||
* externally by developers working with DataTables. They are helper functions
|
||
* to make working with DataTables a little bit easier.
|
||
*/
|
||
|
||
/**
|
||
* Helpers for `columns.render`.
|
||
*
|
||
* The options defined here can be used with the `columns.render` initialisation
|
||
* option to provide a display renderer. The following functions are defined:
|
||
*
|
||
* * `number` - Will format numeric data (defined by `columns.data`) for
|
||
* display, retaining the original unformatted data for sorting and filtering.
|
||
* It takes 4 parameters:
|
||
* * `string` - Thousands grouping separator
|
||
* * `string` - Decimal point indicator
|
||
* * `integer` - Number of decimal points to show
|
||
* * `string` (optional) - Prefix.
|
||
*
|
||
* @example
|
||
* // Column definition using the number renderer
|
||
* {
|
||
* data: "salary",
|
||
* render: $.fn.dataTable.render.number( '\'', '.', 0, '$' )
|
||
* }
|
||
*
|
||
* @namespace
|
||
*/
|
||
DataTable.render = {
|
||
number: function ( thousands, decimal, precision, prefix ) {
|
||
return {
|
||
display: function ( d ) {
|
||
d = parseFloat( d );
|
||
var intPart = parseInt( d, 10 );
|
||
var floatPart = precision ?
|
||
(decimal+(d - intPart).toFixed( precision )).substring( 2 ):
|
||
'';
|
||
|
||
return (prefix||'') +
|
||
intPart.toString().replace(
|
||
/\B(?=(\d{3})+(?!\d))/g, thousands
|
||
) +
|
||
floatPart;
|
||
}
|
||
};
|
||
}
|
||
};
|
||
|
||
|
||
/*
|
||
* This is really a good bit rubbish this method of exposing the internal methods
|
||
* publicly... - To be fixed in 2.0 using methods on the prototype
|
||
*/
|
||
|
||
|
||
/**
|
||
* Create a wrapper function for exporting an internal functions to an external API.
|
||
* @param {string} fn API function name
|
||
* @returns {function} wrapped function
|
||
* @memberof DataTable#internal
|
||
*/
|
||
function _fnExternApiFunc (fn)
|
||
{
|
||
return function() {
|
||
var args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(
|
||
Array.prototype.slice.call(arguments)
|
||
);
|
||
return DataTable.ext.internal[fn].apply( this, args );
|
||
};
|
||
}
|
||
|
||
|
||
/**
|
||
* Reference to internal functions for use by plug-in developers. Note that
|
||
* these methods are references to internal functions and are considered to be
|
||
* private. If you use these methods, be aware that they are liable to change
|
||
* between versions.
|
||
* @namespace
|
||
*/
|
||
$.extend( DataTable.ext.internal, {
|
||
_fnExternApiFunc: _fnExternApiFunc,
|
||
_fnBuildAjax: _fnBuildAjax,
|
||
_fnAjaxUpdate: _fnAjaxUpdate,
|
||
_fnAjaxParameters: _fnAjaxParameters,
|
||
_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,
|
||
_fnAjaxDataSrc: _fnAjaxDataSrc,
|
||
_fnAddColumn: _fnAddColumn,
|
||
_fnColumnOptions: _fnColumnOptions,
|
||
_fnAdjustColumnSizing: _fnAdjustColumnSizing,
|
||
_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,
|
||
_fnColumnIndexToVisible: _fnColumnIndexToVisible,
|
||
_fnVisbleColumns: _fnVisbleColumns,
|
||
_fnGetColumns: _fnGetColumns,
|
||
_fnColumnTypes: _fnColumnTypes,
|
||
_fnApplyColumnDefs: _fnApplyColumnDefs,
|
||
_fnHungarianMap: _fnHungarianMap,
|
||
_fnCamelToHungarian: _fnCamelToHungarian,
|
||
_fnLanguageCompat: _fnLanguageCompat,
|
||
_fnBrowserDetect: _fnBrowserDetect,
|
||
_fnAddData: _fnAddData,
|
||
_fnAddTr: _fnAddTr,
|
||
_fnNodeToDataIndex: _fnNodeToDataIndex,
|
||
_fnNodeToColumnIndex: _fnNodeToColumnIndex,
|
||
_fnGetCellData: _fnGetCellData,
|
||
_fnSetCellData: _fnSetCellData,
|
||
_fnSplitObjNotation: _fnSplitObjNotation,
|
||
_fnGetObjectDataFn: _fnGetObjectDataFn,
|
||
_fnSetObjectDataFn: _fnSetObjectDataFn,
|
||
_fnGetDataMaster: _fnGetDataMaster,
|
||
_fnClearTable: _fnClearTable,
|
||
_fnDeleteIndex: _fnDeleteIndex,
|
||
_fnInvalidateRow: _fnInvalidateRow,
|
||
_fnGetRowElements: _fnGetRowElements,
|
||
_fnCreateTr: _fnCreateTr,
|
||
_fnBuildHead: _fnBuildHead,
|
||
_fnDrawHead: _fnDrawHead,
|
||
_fnDraw: _fnDraw,
|
||
_fnReDraw: _fnReDraw,
|
||
_fnAddOptionsHtml: _fnAddOptionsHtml,
|
||
_fnDetectHeader: _fnDetectHeader,
|
||
_fnGetUniqueThs: _fnGetUniqueThs,
|
||
_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,
|
||
_fnFilterComplete: _fnFilterComplete,
|
||
_fnFilterCustom: _fnFilterCustom,
|
||
_fnFilterColumn: _fnFilterColumn,
|
||
_fnFilter: _fnFilter,
|
||
_fnFilterCreateSearch: _fnFilterCreateSearch,
|
||
_fnEscapeRegex: _fnEscapeRegex,
|
||
_fnFilterData: _fnFilterData,
|
||
_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,
|
||
_fnUpdateInfo: _fnUpdateInfo,
|
||
_fnInfoMacros: _fnInfoMacros,
|
||
_fnInitialise: _fnInitialise,
|
||
_fnInitComplete: _fnInitComplete,
|
||
_fnLengthChange: _fnLengthChange,
|
||
_fnFeatureHtmlLength: _fnFeatureHtmlLength,
|
||
_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,
|
||
_fnPageChange: _fnPageChange,
|
||
_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,
|
||
_fnProcessingDisplay: _fnProcessingDisplay,
|
||
_fnFeatureHtmlTable: _fnFeatureHtmlTable,
|
||
_fnScrollDraw: _fnScrollDraw,
|
||
_fnApplyToChildren: _fnApplyToChildren,
|
||
_fnCalculateColumnWidths: _fnCalculateColumnWidths,
|
||
_fnThrottle: _fnThrottle,
|
||
_fnConvertToWidth: _fnConvertToWidth,
|
||
_fnScrollingWidthAdjust: _fnScrollingWidthAdjust,
|
||
_fnGetWidestNode: _fnGetWidestNode,
|
||
_fnGetMaxLenString: _fnGetMaxLenString,
|
||
_fnStringToCss: _fnStringToCss,
|
||
_fnScrollBarWidth: _fnScrollBarWidth,
|
||
_fnSortFlatten: _fnSortFlatten,
|
||
_fnSort: _fnSort,
|
||
_fnSortAria: _fnSortAria,
|
||
_fnSortListener: _fnSortListener,
|
||
_fnSortAttachListener: _fnSortAttachListener,
|
||
_fnSortingClasses: _fnSortingClasses,
|
||
_fnSortData: _fnSortData,
|
||
_fnSaveState: _fnSaveState,
|
||
_fnLoadState: _fnLoadState,
|
||
_fnSettingsFromNode: _fnSettingsFromNode,
|
||
_fnLog: _fnLog,
|
||
_fnMap: _fnMap,
|
||
_fnBindAction: _fnBindAction,
|
||
_fnCallbackReg: _fnCallbackReg,
|
||
_fnCallbackFire: _fnCallbackFire,
|
||
_fnLengthOverflow: _fnLengthOverflow,
|
||
_fnRenderer: _fnRenderer,
|
||
_fnDataSource: _fnDataSource,
|
||
_fnRowAttributes: _fnRowAttributes,
|
||
_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant
|
||
// in 1.10, so this dead-end function is
|
||
// added to prevent errors
|
||
} );
|
||
|
||
|
||
// jQuery access
|
||
$.fn.dataTable = DataTable;
|
||
|
||
// Legacy aliases
|
||
$.fn.dataTableSettings = DataTable.settings;
|
||
$.fn.dataTableExt = DataTable.ext;
|
||
|
||
// With a capital `D` we return a DataTables API instance rather than a
|
||
// jQuery object
|
||
$.fn.DataTable = function ( opts ) {
|
||
return $(this).dataTable( opts ).api();
|
||
};
|
||
|
||
// All properties that are available to $.fn.dataTable should also be
|
||
// available on $.fn.DataTable
|
||
$.each( DataTable, function ( prop, val ) {
|
||
$.fn.DataTable[ prop ] = val;
|
||
} );
|
||
|
||
|
||
// Information about events fired by DataTables - for documentation.
|
||
/**
|
||
* Draw event, fired whenever the table is redrawn on the page, at the same
|
||
* point as fnDrawCallback. This may be useful for binding events or
|
||
* performing calculations when the table is altered at all.
|
||
* @name DataTable#draw.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* Search event, fired when the searching applied to the table (using the
|
||
* built-in global search, or column filters) is altered.
|
||
* @name DataTable#search.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* Page change event, fired when the paging of the table is altered.
|
||
* @name DataTable#page.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* Order event, fired when the ordering applied to the table is altered.
|
||
* @name DataTable#order.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* DataTables initialisation complete event, fired when the table is fully
|
||
* drawn, including Ajax data loaded, if Ajax data is required.
|
||
* @name DataTable#init.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {object} json The JSON object request from the server - only
|
||
* present if client-side Ajax sourced data is used</li></ol>
|
||
*/
|
||
|
||
/**
|
||
* State save event, fired when the table has changed state a new state save
|
||
* is required. This event allows modification of the state saving object
|
||
* prior to actually doing the save, including addition or other state
|
||
* properties (for plug-ins) or modification of a DataTables core property.
|
||
* @name DataTable#stateSaveParams.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {object} json The state information to be saved
|
||
*/
|
||
|
||
/**
|
||
* State load event, fired when the table is loading state from the stored
|
||
* data, but prior to the settings object being modified by the saved state
|
||
* - allowing modification of the saved state is required or loading of
|
||
* state for a plug-in.
|
||
* @name DataTable#stateLoadParams.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {object} json The saved state information
|
||
*/
|
||
|
||
/**
|
||
* State loaded event, fired when state has been loaded from stored data and
|
||
* the settings object has been modified by the loaded data.
|
||
* @name DataTable#stateLoaded.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {object} json The saved state information
|
||
*/
|
||
|
||
/**
|
||
* Processing event, fired when DataTables is doing some kind of processing
|
||
* (be it, order, searcg or anything else). It can be used to indicate to
|
||
* the end user that there is something happening, or that something has
|
||
* finished.
|
||
* @name DataTable#processing.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} oSettings DataTables settings object
|
||
* @param {boolean} bShow Flag for if DataTables is doing processing or not
|
||
*/
|
||
|
||
/**
|
||
* Ajax (XHR) event, fired whenever an Ajax request is completed from a
|
||
* request to made to the server for new data. This event is called before
|
||
* DataTables processed the returned data, so it can also be used to pre-
|
||
* process the data returned from the server, if needed.
|
||
*
|
||
* Note that this trigger is called in `fnServerData`, if you override
|
||
* `fnServerData` and which to use this event, you need to trigger it in you
|
||
* success function.
|
||
* @name DataTable#xhr.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
* @param {object} json JSON returned from the server
|
||
*
|
||
* @example
|
||
* // Use a custom property returned from the server in another DOM element
|
||
* $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
|
||
* $('#status').html( json.status );
|
||
* } );
|
||
*
|
||
* @example
|
||
* // Pre-process the data returned from the server
|
||
* $('#table').dataTable().on('xhr.dt', function (e, settings, json) {
|
||
* for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {
|
||
* json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;
|
||
* }
|
||
* // Note no return - manipulate the data directly in the JSON object.
|
||
* } );
|
||
*/
|
||
|
||
/**
|
||
* Destroy event, fired when the DataTable is destroyed by calling fnDestroy
|
||
* or passing the bDestroy:true parameter in the initialisation object. This
|
||
* can be used to remove bound events, added DOM nodes, etc.
|
||
* @name DataTable#destroy.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* Page length change event, fired when number of records to show on each
|
||
* page (the length) is changed.
|
||
* @name DataTable#length.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
* @param {integer} len New length
|
||
*/
|
||
|
||
/**
|
||
* Column sizing has changed.
|
||
* @name DataTable#column-sizing.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
*/
|
||
|
||
/**
|
||
* Column visibility has changed.
|
||
* @name DataTable#column-visibility.dt
|
||
* @event
|
||
* @param {event} e jQuery event object
|
||
* @param {object} o DataTables settings object {@link DataTable.models.oSettings}
|
||
* @param {int} column Column index
|
||
* @param {bool} vis `false` if column now hidden, or `true` if visible
|
||
*/
|
||
|
||
return $.fn.dataTable;
|
||
}));
|
||
|
||
}(window, document));
|
||
|
||
|
||
(function (factory) {
|
||
if (typeof define === 'function' && define.amd) {
|
||
define(['jquery','datatables'], factory);
|
||
}
|
||
else {
|
||
factory(jQuery);
|
||
}
|
||
}(function ($) {
|
||
/* Set the defaults for DataTables initialisation */
|
||
$.extend( true, $.fn.dataTable.defaults, {
|
||
"sDom": "<'row'<'col-sm-12'<'pull-right'f><'pull-left'l>r<'clearfix'>>>t<'row'<'col-sm-12'<'pull-left'i><'pull-right'p><'clearfix'>>>",
|
||
"sPaginationType": "bs_normal",
|
||
"oLanguage": {
|
||
"sLengthMenu": "Show _MENU_ Rows",
|
||
"sSearch": ""
|
||
}
|
||
} );
|
||
|
||
/* Default class modification */
|
||
$.extend( $.fn.dataTableExt.oStdClasses, {
|
||
"sWrapper": "dataTables_wrapper form-inline"
|
||
} );
|
||
|
||
/* API method to get paging information */
|
||
$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
|
||
{
|
||
return {
|
||
"iStart": oSettings._iDisplayStart,
|
||
"iEnd": oSettings.fnDisplayEnd(),
|
||
"iLength": oSettings._iDisplayLength,
|
||
"iTotal": oSettings.fnRecordsTotal(),
|
||
"iFilteredTotal": oSettings.fnRecordsDisplay(),
|
||
"iPage": oSettings._iDisplayLength === -1 ?
|
||
0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
|
||
"iTotalPages": oSettings._iDisplayLength === -1 ?
|
||
0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
|
||
};
|
||
};
|
||
|
||
/* Bootstrap style pagination control */
|
||
$.extend( $.fn.dataTableExt.oPagination, {
|
||
"bs_normal": {
|
||
"fnInit": function( oSettings, nPaging, fnDraw ) {
|
||
var oLang = oSettings.oLanguage.oPaginate;
|
||
var fnClickHandler = function ( e ) {
|
||
e.preventDefault();
|
||
if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) {
|
||
fnDraw( oSettings );
|
||
}
|
||
};
|
||
$(nPaging).append(
|
||
'<ul class="pagination">'+
|
||
'<li class="prev disabled"><a href="#"><span class="glyphicon glyphicon-chevron-left"></span> '+oLang.sPrevious+'</a></li>'+
|
||
'<li class="next disabled"><a href="#">'+oLang.sNext+' <span class="glyphicon glyphicon-chevron-right"></span></a></li>'+
|
||
'</ul>'
|
||
);
|
||
var els = $('a', nPaging);
|
||
$(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler );
|
||
$(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler );
|
||
},
|
||
"fnUpdate": function ( oSettings, fnDraw ) {
|
||
var iListLength = 5;
|
||
var oPaging = oSettings.oInstance.fnPagingInfo();
|
||
var an = oSettings.aanFeatures.p;
|
||
var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);
|
||
if ( oPaging.iTotalPages < iListLength) {
|
||
iStart = 1;
|
||
iEnd = oPaging.iTotalPages;
|
||
}
|
||
else if ( oPaging.iPage <= iHalf ) {
|
||
iStart = 1;
|
||
iEnd = iListLength;
|
||
} else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) {
|
||
iStart = oPaging.iTotalPages - iListLength + 1;
|
||
iEnd = oPaging.iTotalPages;
|
||
} else {
|
||
iStart = oPaging.iPage - iHalf + 1;
|
||
iEnd = iStart + iListLength - 1;
|
||
}
|
||
for ( i=0, ien=an.length ; i<ien ; i++ ) {
|
||
$('li:gt(0)', an[i]).filter(':not(:last)').remove();
|
||
for ( j=iStart ; j<=iEnd ; j++ ) {
|
||
sClass = (j==oPaging.iPage+1) ? 'class="active"' : '';
|
||
$('<li '+sClass+'><a href="#">'+j+'</a></li>')
|
||
.insertBefore( $('li:last', an[i])[0] )
|
||
.bind('click', function (e) {
|
||
e.preventDefault();
|
||
if ( oSettings.oApi._fnPageChange(oSettings, parseInt($('a', this).text(),10)-1) ) {
|
||
fnDraw( oSettings );
|
||
}
|
||
} );
|
||
}
|
||
if ( oPaging.iPage === 0 ) {
|
||
$('li:first', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:first', an[i]).removeClass('disabled');
|
||
}
|
||
|
||
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
|
||
$('li:last', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:last', an[i]).removeClass('disabled');
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"bs_two_button": {
|
||
"fnInit": function ( oSettings, nPaging, fnCallbackDraw )
|
||
{
|
||
var oLang = oSettings.oLanguage.oPaginate;
|
||
var oClasses = oSettings.oClasses;
|
||
var fnClickHandler = function ( e ) {
|
||
if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
|
||
{
|
||
fnCallbackDraw( oSettings );
|
||
}
|
||
};
|
||
var sAppend = '<ul class="pagination">'+
|
||
'<li class="prev"><a class="'+oSettings.oClasses.sPagePrevDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button"><span class="glyphicon glyphicon-chevron-left"></span> '+oLang.sPrevious+'</a></li>'+
|
||
'<li class="next"><a class="'+oSettings.oClasses.sPageNextDisabled+'" tabindex="'+oSettings.iTabIndex+'" role="button">'+oLang.sNext+' <span class="glyphicon glyphicon-chevron-right"></span></a></li>'+
|
||
'</ul>';
|
||
$(nPaging).append( sAppend );
|
||
var els = $('a', nPaging);
|
||
var nPrevious = els[0],
|
||
nNext = els[1];
|
||
oSettings.oApi._fnBindAction( nPrevious, {action: "previous"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
nPaging.id = oSettings.sTableId+'_paginate';
|
||
nPrevious.id = oSettings.sTableId+'_previous';
|
||
nNext.id = oSettings.sTableId+'_next';
|
||
nPrevious.setAttribute('aria-controls', oSettings.sTableId);
|
||
nNext.setAttribute('aria-controls', oSettings.sTableId);
|
||
}
|
||
},
|
||
"fnUpdate": function ( oSettings, fnCallbackDraw )
|
||
{
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
return;
|
||
}
|
||
var oPaging = oSettings.oInstance.fnPagingInfo();
|
||
var oClasses = oSettings.oClasses;
|
||
var an = oSettings.aanFeatures.p;
|
||
var nNode;
|
||
for ( var i=0, iLen=an.length ; i<iLen ; i++ )
|
||
{
|
||
if ( oPaging.iPage === 0 ) {
|
||
$('li:first', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:first', an[i]).removeClass('disabled');
|
||
}
|
||
|
||
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
|
||
$('li:last', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:last', an[i]).removeClass('disabled');
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"bs_four_button": {
|
||
"fnInit": function ( oSettings, nPaging, fnCallbackDraw )
|
||
{
|
||
var oLang = oSettings.oLanguage.oPaginate;
|
||
var oClasses = oSettings.oClasses;
|
||
var fnClickHandler = function ( e ) {
|
||
e.preventDefault()
|
||
if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
|
||
{
|
||
fnCallbackDraw( oSettings );
|
||
}
|
||
};
|
||
$(nPaging).append(
|
||
'<ul class="pagination">'+
|
||
'<li class="disabled"><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageFirst+'"><span class="glyphicon glyphicon-backward"></span> '+oLang.sFirst+'</a></li>'+
|
||
'<li class="disabled"><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPagePrevious+'"><span class="glyphicon glyphicon-chevron-left"></span> '+oLang.sPrevious+'</a></li>'+
|
||
'<li><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageNext+'">'+oLang.sNext+' <span class="glyphicon glyphicon-chevron-right"></span></a></li>'+
|
||
'<li><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageLast+'">'+oLang.sLast+' <span class="glyphicon glyphicon-forward"></span></a></li>'+
|
||
'</ul>'
|
||
);
|
||
var els = $('a', nPaging);
|
||
var nFirst = els[0],
|
||
nPrev = els[1],
|
||
nNext = els[2],
|
||
nLast = els[3];
|
||
oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler );
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
nPaging.id = oSettings.sTableId+'_paginate';
|
||
nFirst.id =oSettings.sTableId+'_first';
|
||
nPrev.id =oSettings.sTableId+'_previous';
|
||
nNext.id =oSettings.sTableId+'_next';
|
||
nLast.id =oSettings.sTableId+'_last';
|
||
}
|
||
},
|
||
"fnUpdate": function ( oSettings, fnCallbackDraw )
|
||
{
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
return;
|
||
}
|
||
var oPaging = oSettings.oInstance.fnPagingInfo();
|
||
var oClasses = oSettings.oClasses;
|
||
var an = oSettings.aanFeatures.p;
|
||
var nNode;
|
||
for ( var i=0, iLen=an.length ; i<iLen ; i++ )
|
||
{
|
||
if ( oPaging.iPage === 0 ) {
|
||
$('li:eq(0)', an[i]).addClass('disabled');
|
||
$('li:eq(1)', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:eq(0)', an[i]).removeClass('disabled');
|
||
$('li:eq(1)', an[i]).removeClass('disabled');
|
||
}
|
||
|
||
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
|
||
$('li:eq(2)', an[i]).addClass('disabled');
|
||
$('li:eq(3)', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:eq(2)', an[i]).removeClass('disabled');
|
||
$('li:eq(3)', an[i]).removeClass('disabled');
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"bs_full": {
|
||
"fnInit": function ( oSettings, nPaging, fnCallbackDraw )
|
||
{
|
||
var oLang = oSettings.oLanguage.oPaginate;
|
||
var oClasses = oSettings.oClasses;
|
||
var fnClickHandler = function ( e ) {
|
||
if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
|
||
{
|
||
fnCallbackDraw( oSettings );
|
||
}
|
||
};
|
||
$(nPaging).append(
|
||
'<ul class="pagination">'+
|
||
'<li class="disabled"><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageFirst+'">'+oLang.sFirst+'</a></li>'+
|
||
'<li class="disabled"><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPagePrevious+'">'+oLang.sPrevious+'</a></li>'+
|
||
'<li><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageNext+'">'+oLang.sNext+'</a></li>'+
|
||
'<li><a tabindex="'+oSettings.iTabIndex+'" class="'+oClasses.sPageButton+" "+oClasses.sPageLast+'">'+oLang.sLast+'</a></li>'+
|
||
'</ul>'
|
||
);
|
||
var els = $('a', nPaging);
|
||
var nFirst = els[0],
|
||
nPrev = els[1],
|
||
nNext = els[2],
|
||
nLast = els[3];
|
||
oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
|
||
oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler );
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
nPaging.id = oSettings.sTableId+'_paginate';
|
||
nFirst.id =oSettings.sTableId+'_first';
|
||
nPrev.id =oSettings.sTableId+'_previous';
|
||
nNext.id =oSettings.sTableId+'_next';
|
||
nLast.id =oSettings.sTableId+'_last';
|
||
}
|
||
},
|
||
"fnUpdate": function ( oSettings, fnCallbackDraw )
|
||
{
|
||
if ( !oSettings.aanFeatures.p )
|
||
{
|
||
return;
|
||
}
|
||
var oPaging = oSettings.oInstance.fnPagingInfo();
|
||
var iPageCount = $.fn.dataTableExt.oPagination.iFullNumbersShowPages;
|
||
var iPageCountHalf = Math.floor(iPageCount / 2);
|
||
var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);
|
||
var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
|
||
var sList = "";
|
||
var iStartButton, iEndButton, i, iLen;
|
||
var oClasses = oSettings.oClasses;
|
||
var anButtons, anStatic, nPaginateList, nNode;
|
||
var an = oSettings.aanFeatures.p;
|
||
var fnBind = function (j) {
|
||
oSettings.oApi._fnBindAction( this, {"page": j+iStartButton-1}, function(e) {
|
||
if( oSettings.oApi._fnPageChange( oSettings, e.data.page ) ){
|
||
fnCallbackDraw( oSettings );
|
||
}
|
||
e.preventDefault();
|
||
} );
|
||
};
|
||
if ( oSettings._iDisplayLength === -1 )
|
||
{
|
||
iStartButton = 1;
|
||
iEndButton = 1;
|
||
iCurrentPage = 1;
|
||
}
|
||
else if (iPages < iPageCount)
|
||
{
|
||
iStartButton = 1;
|
||
iEndButton = iPages;
|
||
}
|
||
else if (iCurrentPage <= iPageCountHalf)
|
||
{
|
||
iStartButton = 1;
|
||
iEndButton = iPageCount;
|
||
}
|
||
else if (iCurrentPage >= (iPages - iPageCountHalf))
|
||
{
|
||
iStartButton = iPages - iPageCount + 1;
|
||
iEndButton = iPages;
|
||
}
|
||
else
|
||
{
|
||
iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1;
|
||
iEndButton = iStartButton + iPageCount - 1;
|
||
}
|
||
for ( i=iStartButton ; i<=iEndButton ; i++ )
|
||
{
|
||
sList += (iCurrentPage !== i) ?
|
||
'<li><a tabindex="'+oSettings.iTabIndex+'">'+oSettings.fnFormatNumber(i)+'</a></li>' :
|
||
'<li class="active"><a tabindex="'+oSettings.iTabIndex+'">'+oSettings.fnFormatNumber(i)+'</a></li>';
|
||
}
|
||
for ( i=0, iLen=an.length ; i<iLen ; i++ )
|
||
{
|
||
nNode = an[i];
|
||
if ( !nNode.hasChildNodes() )
|
||
{
|
||
continue;
|
||
}
|
||
$('li:gt(1)', an[i]).filter(':not(li:eq(-2))').filter(':not(li:eq(-1))').remove();
|
||
if ( oPaging.iPage === 0 ) {
|
||
$('li:eq(0)', an[i]).addClass('disabled');
|
||
$('li:eq(1)', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:eq(0)', an[i]).removeClass('disabled');
|
||
$('li:eq(1)', an[i]).removeClass('disabled');
|
||
}
|
||
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
|
||
$('li:eq(-1)', an[i]).addClass('disabled');
|
||
$('li:eq(-2)', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:eq(-1)', an[i]).removeClass('disabled');
|
||
$('li:eq(-2)', an[i]).removeClass('disabled');
|
||
}
|
||
$(sList)
|
||
.insertBefore($('li:eq(-2)', an[i]))
|
||
.bind('click', function (e) {
|
||
e.preventDefault();
|
||
if ( oSettings.oApi._fnPageChange(oSettings, parseInt($('a', this).text(),10)-1) ) {
|
||
fnCallbackDraw( oSettings );
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
} );
|
||
|
||
|
||
/*
|
||
* TableTools Bootstrap compatibility
|
||
* Required TableTools 2.1+
|
||
*/
|
||
if ( $.fn.DataTable.TableTools ) {
|
||
// Set the classes that TableTools uses to something suitable for Bootstrap
|
||
$.extend( true, $.fn.DataTable.TableTools.classes, {
|
||
"container": "DTTT btn-group",
|
||
"buttons": {
|
||
"normal": "btn",
|
||
"disabled": "disabled"
|
||
},
|
||
"collection": {
|
||
"container": "DTTT_dropdown dropdown-menu",
|
||
"buttons": {
|
||
"normal": "",
|
||
"disabled": "disabled"
|
||
}
|
||
},
|
||
"print": {
|
||
"info": "DTTT_print_info modal"
|
||
},
|
||
"select": {
|
||
"row": "active"
|
||
}
|
||
} );
|
||
|
||
// Have the collection use a bootstrap compatible dropdown
|
||
$.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
|
||
"collection": {
|
||
"container": "ul",
|
||
"button": "li",
|
||
"liner": "a"
|
||
}
|
||
} );
|
||
}
|
||
}));
|
||
|
||
|
||
|
||
|
||
|
||
// Knockout JavaScript library v3.0.0
|
||
// (c) Steven Sanderson - http://knockoutjs.com/
|
||
// License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
||
|
||
(function() {(function(q){var y=this||(0,eval)("this"),w=y.document,K=y.navigator,u=y.jQuery,B=y.JSON;(function(q){"function"===typeof require&&"object"===typeof exports&&"object"===typeof module?q(module.exports||exports):"function"===typeof define&&define.amd?define(["exports"],q):q(y.ko={})})(function(F){function G(a,c){return null===a||typeof a in N?a===c:!1}function H(b,c,d,e){a.d[b]={init:function(b){a.a.f.set(b,L,{});return{controlsDescendantBindings:!0}},update:function(b,h,k,m,f){k=a.a.f.get(b,L);h=a.a.c(h());
|
||
m=!d!==!h;var p=!k.ob;if(p||c||m!==k.Db)p&&(k.ob=a.a.Ya(a.e.childNodes(b),!0)),m?(p||a.e.S(b,a.a.Ya(k.ob)),a.Ta(e?e(f,h):f,b)):a.e.Z(b),k.Db=m}};a.g.Y[b]=!1;a.e.P[b]=!0}var a="undefined"!==typeof F?F:{};a.b=function(b,c){for(var d=b.split("."),e=a,g=0;g<d.length-1;g++)e=e[d[g]];e[d[d.length-1]]=c};a.s=function(a,c,d){a[c]=d};a.version="3.0.0";a.b("version",a.version);a.a=function(){function b(a,b){for(var f in a)a.hasOwnProperty(f)&&b(f,a[f])}function c(k,b){if("input"!==a.a.v(k)||!k.type||"click"!=
|
||
b.toLowerCase())return!1;var f=k.type;return"checkbox"==f||"radio"==f}var d={},e={};d[K&&/Firefox\/2/i.test(K.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"];d.MouseEvents="click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave".split(" ");b(d,function(a,b){if(b.length)for(var f=0,c=b.length;f<c;f++)e[b[f]]=a});var g={propertychange:!0},h=w&&function(){for(var a=3,b=w.createElement("div"),f=b.getElementsByTagName("i");b.innerHTML="\x3c!--[if gt IE "+
|
||
++a+"]><i></i><![endif]--\x3e",f[0];);return 4<a?a:q}();return{$a:["authenticity_token",/^__RequestVerificationToken(_.*)?$/],n:function(a,b){for(var f=0,c=a.length;f<c;f++)b(a[f])},l:function(a,b){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(a,b);for(var f=0,c=a.length;f<c;f++)if(a[f]===b)return f;return-1},Ua:function(a,b,f){for(var c=0,d=a.length;c<d;c++)if(b.call(f,a[c]))return a[c];return null},ia:function(b,c){var f=a.a.l(b,c);0<=f&&b.splice(f,1)},Va:function(b){b=
|
||
b||[];for(var c=[],f=0,d=b.length;f<d;f++)0>a.a.l(c,b[f])&&c.push(b[f]);return c},ha:function(a,b){a=a||[];for(var f=[],c=0,d=a.length;c<d;c++)f.push(b(a[c]));return f},ga:function(a,b){a=a||[];for(var f=[],c=0,d=a.length;c<d;c++)b(a[c])&&f.push(a[c]);return f},X:function(a,b){if(b instanceof Array)a.push.apply(a,b);else for(var f=0,c=b.length;f<c;f++)a.push(b[f]);return a},V:function(b,c,f){var d=a.a.l(a.a.Ha(b),c);0>d?f&&b.push(c):f||b.splice(d,1)},extend:function(a,b){if(b)for(var f in b)b.hasOwnProperty(f)&&
|
||
(a[f]=b[f]);return a},K:b,Da:function(a,b){if(!a)return a;var f={},c;for(c in a)a.hasOwnProperty(c)&&(f[c]=b(a[c],c,a));return f},wa:function(b){for(;b.firstChild;)a.removeNode(b.firstChild)},Vb:function(b){b=a.a.Q(b);for(var c=w.createElement("div"),f=0,d=b.length;f<d;f++)c.appendChild(a.L(b[f]));return c},Ya:function(b,c){for(var f=0,d=b.length,e=[];f<d;f++){var g=b[f].cloneNode(!0);e.push(c?a.L(g):g)}return e},S:function(b,c){a.a.wa(b);if(c)for(var f=0,d=c.length;f<d;f++)b.appendChild(c[f])},nb:function(b,
|
||
c){var f=b.nodeType?[b]:b;if(0<f.length){for(var d=f[0],e=d.parentNode,g=0,n=c.length;g<n;g++)e.insertBefore(c[g],d);g=0;for(n=f.length;g<n;g++)a.removeNode(f[g])}},$:function(a,b){if(a.length){for(b=8===b.nodeType&&b.parentNode||b;a.length&&a[0].parentNode!==b;)a.splice(0,1);if(1<a.length){var f=a[0],c=a[a.length-1];for(a.length=0;f!==c;)if(a.push(f),f=f.nextSibling,!f)return;a.push(c)}}return a},qb:function(a,b){7>h?a.setAttribute("selected",b):a.selected=b},la:function(a){return null===a||a===
|
||
q?"":a.trim?a.trim():a.toString().replace(/^[\s\xa0]+|[\s\xa0]+$/g,"")},ec:function(b,c){for(var f=[],d=(b||"").split(c),e=0,g=d.length;e<g;e++){var n=a.a.la(d[e]);""!==n&&f.push(n)}return f},ac:function(a,b){a=a||"";return b.length>a.length?!1:a.substring(0,b.length)===b},Gb:function(a,b){if(a===b)return!0;if(11===a.nodeType)return!1;if(b.contains)return b.contains(3===a.nodeType?a.parentNode:a);if(b.compareDocumentPosition)return 16==(b.compareDocumentPosition(a)&16);for(;a&&a!=b;)a=a.parentNode;
|
||
return!!a},va:function(b){return a.a.Gb(b,b.ownerDocument.documentElement)},Ra:function(b){return!!a.a.Ua(b,a.a.va)},v:function(a){return a&&a.tagName&&a.tagName.toLowerCase()},r:function(b,d,f){var e=h&&g[d];if(e||"undefined"==typeof u)if(e||"function"!=typeof b.addEventListener)if("undefined"!=typeof b.attachEvent){var s=function(a){f.call(b,a)},l="on"+d;b.attachEvent(l,s);a.a.C.ea(b,function(){b.detachEvent(l,s)})}else throw Error("Browser doesn't support addEventListener or attachEvent");else b.addEventListener(d,
|
||
f,!1);else{if(c(b,d)){var n=f;f=function(a,b){var f=this.checked;b&&(this.checked=!0!==b.Ab);n.call(this,a);this.checked=f}}u(b).bind(d,f)}},da:function(a,b){if(!a||!a.nodeType)throw Error("element must be a DOM node when calling triggerEvent");if("undefined"!=typeof u){var f=[];c(a,b)&&f.push({Ab:a.checked});u(a).trigger(b,f)}else if("function"==typeof w.createEvent)if("function"==typeof a.dispatchEvent)f=w.createEvent(e[b]||"HTMLEvents"),f.initEvent(b,!0,!0,y,0,0,0,0,0,!1,!1,!1,!1,0,a),a.dispatchEvent(f);
|
||
else throw Error("The supplied element doesn't support dispatchEvent");else if("undefined"!=typeof a.fireEvent)c(a,b)&&(a.checked=!0!==a.checked),a.fireEvent("on"+b);else throw Error("Browser doesn't support triggering events");},c:function(b){return a.M(b)?b():b},Ha:function(b){return a.M(b)?b.t():b},ma:function(b,c,f){if(c){var d=/\S+/g,e=b.className.match(d)||[];a.a.n(c.match(d),function(b){a.a.V(e,b,f)});b.className=e.join(" ")}},Ma:function(b,c){var f=a.a.c(c);if(null===f||f===q)f="";var d=a.e.firstChild(b);
|
||
!d||3!=d.nodeType||a.e.nextSibling(d)?a.e.S(b,[w.createTextNode(f)]):d.data=f;a.a.Jb(b)},pb:function(a,b){a.name=b;if(7>=h)try{a.mergeAttributes(w.createElement("<input name='"+a.name+"'/>"),!1)}catch(f){}},Jb:function(a){9<=h&&(a=1==a.nodeType?a:a.parentNode,a.style&&(a.style.zoom=a.style.zoom))},Hb:function(a){if(h){var b=a.style.width;a.style.width=0;a.style.width=b}},Zb:function(b,c){b=a.a.c(b);c=a.a.c(c);for(var f=[],d=b;d<=c;d++)f.push(d);return f},Q:function(a){for(var b=[],c=0,d=a.length;c<
|
||
d;c++)b.push(a[c]);return b},cc:6===h,dc:7===h,ja:h,ab:function(b,c){for(var f=a.a.Q(b.getElementsByTagName("input")).concat(a.a.Q(b.getElementsByTagName("textarea"))),d="string"==typeof c?function(a){return a.name===c}:function(a){return c.test(a.name)},e=[],g=f.length-1;0<=g;g--)d(f[g])&&e.push(f[g]);return e},Wb:function(b){return"string"==typeof b&&(b=a.a.la(b))?B&&B.parse?B.parse(b):(new Function("return "+b))():null},Na:function(b,c,f){if(!B||!B.stringify)throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");
|
||
return B.stringify(a.a.c(b),c,f)},Xb:function(c,d,f){f=f||{};var e=f.params||{},g=f.includeFields||this.$a,h=c;if("object"==typeof c&&"form"===a.a.v(c))for(var h=c.action,n=g.length-1;0<=n;n--)for(var r=a.a.ab(c,g[n]),v=r.length-1;0<=v;v--)e[r[v].name]=r[v].value;d=a.a.c(d);var t=w.createElement("form");t.style.display="none";t.action=h;t.method="post";for(var E in d)c=w.createElement("input"),c.name=E,c.value=a.a.Na(a.a.c(d[E])),t.appendChild(c);b(e,function(a,b){var c=w.createElement("input");c.name=
|
||
a;c.value=b;t.appendChild(c)});w.body.appendChild(t);f.submitter?f.submitter(t):t.submit();setTimeout(function(){t.parentNode.removeChild(t)},0)}}}();a.b("utils",a.a);a.b("utils.arrayForEach",a.a.n);a.b("utils.arrayFirst",a.a.Ua);a.b("utils.arrayFilter",a.a.ga);a.b("utils.arrayGetDistinctValues",a.a.Va);a.b("utils.arrayIndexOf",a.a.l);a.b("utils.arrayMap",a.a.ha);a.b("utils.arrayPushAll",a.a.X);a.b("utils.arrayRemoveItem",a.a.ia);a.b("utils.extend",a.a.extend);a.b("utils.fieldsIncludedWithJsonPost",
|
||
a.a.$a);a.b("utils.getFormFields",a.a.ab);a.b("utils.peekObservable",a.a.Ha);a.b("utils.postJson",a.a.Xb);a.b("utils.parseJson",a.a.Wb);a.b("utils.registerEventHandler",a.a.r);a.b("utils.stringifyJson",a.a.Na);a.b("utils.range",a.a.Zb);a.b("utils.toggleDomNodeCssClass",a.a.ma);a.b("utils.triggerEvent",a.a.da);a.b("utils.unwrapObservable",a.a.c);a.b("utils.objectForEach",a.a.K);a.b("utils.addOrRemoveItem",a.a.V);a.b("unwrap",a.a.c);Function.prototype.bind||(Function.prototype.bind=function(a){var c=
|
||
this,d=Array.prototype.slice.call(arguments);a=d.shift();return function(){return c.apply(a,d.concat(Array.prototype.slice.call(arguments)))}});a.a.f=new function(){function a(b,h){var k=b[d];if(!k||"null"===k||!e[k]){if(!h)return q;k=b[d]="ko"+c++;e[k]={}}return e[k]}var c=0,d="__ko__"+(new Date).getTime(),e={};return{get:function(c,d){var e=a(c,!1);return e===q?q:e[d]},set:function(c,d,e){if(e!==q||a(c,!1)!==q)a(c,!0)[d]=e},clear:function(a){var b=a[d];return b?(delete e[b],a[d]=null,!0):!1},D:function(){return c++ +
|
||
d}}};a.b("utils.domData",a.a.f);a.b("utils.domData.clear",a.a.f.clear);a.a.C=new function(){function b(b,c){var e=a.a.f.get(b,d);e===q&&c&&(e=[],a.a.f.set(b,d,e));return e}function c(d){var e=b(d,!1);if(e)for(var e=e.slice(0),m=0;m<e.length;m++)e[m](d);a.a.f.clear(d);"function"==typeof u&&"function"==typeof u.cleanData&&u.cleanData([d]);if(g[d.nodeType])for(e=d.firstChild;d=e;)e=d.nextSibling,8===d.nodeType&&c(d)}var d=a.a.f.D(),e={1:!0,8:!0,9:!0},g={1:!0,9:!0};return{ea:function(a,c){if("function"!=
|
||
typeof c)throw Error("Callback must be a function");b(a,!0).push(c)},mb:function(c,e){var g=b(c,!1);g&&(a.a.ia(g,e),0==g.length&&a.a.f.set(c,d,q))},L:function(b){if(e[b.nodeType]&&(c(b),g[b.nodeType])){var d=[];a.a.X(d,b.getElementsByTagName("*"));for(var m=0,f=d.length;m<f;m++)c(d[m])}return b},removeNode:function(b){a.L(b);b.parentNode&&b.parentNode.removeChild(b)}}};a.L=a.a.C.L;a.removeNode=a.a.C.removeNode;a.b("cleanNode",a.L);a.b("removeNode",a.removeNode);a.b("utils.domNodeDisposal",a.a.C);
|
||
a.b("utils.domNodeDisposal.addDisposeCallback",a.a.C.ea);a.b("utils.domNodeDisposal.removeDisposeCallback",a.a.C.mb);(function(){a.a.Fa=function(b){var c;if("undefined"!=typeof u)if(u.parseHTML)c=u.parseHTML(b)||[];else{if((c=u.clean([b]))&&c[0]){for(b=c[0];b.parentNode&&11!==b.parentNode.nodeType;)b=b.parentNode;b.parentNode&&b.parentNode.removeChild(b)}}else{var d=a.a.la(b).toLowerCase();c=w.createElement("div");d=d.match(/^<(thead|tbody|tfoot)/)&&[1,"<table>","</table>"]||!d.indexOf("<tr")&&[2,
|
||
"<table><tbody>","</tbody></table>"]||(!d.indexOf("<td")||!d.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||[0,"",""];b="ignored<div>"+d[1]+b+d[2]+"</div>";for("function"==typeof y.innerShiv?c.appendChild(y.innerShiv(b)):c.innerHTML=b;d[0]--;)c=c.lastChild;c=a.a.Q(c.lastChild.childNodes)}return c};a.a.Ka=function(b,c){a.a.wa(b);c=a.a.c(c);if(null!==c&&c!==q)if("string"!=typeof c&&(c=c.toString()),"undefined"!=typeof u)u(b).html(c);else for(var d=a.a.Fa(c),e=0;e<d.length;e++)b.appendChild(d[e])}})();
|
||
a.b("utils.parseHtmlFragment",a.a.Fa);a.b("utils.setHtml",a.a.Ka);a.u=function(){function b(c,e){if(c)if(8==c.nodeType){var g=a.u.jb(c.nodeValue);null!=g&&e.push({Fb:c,Tb:g})}else if(1==c.nodeType)for(var g=0,h=c.childNodes,k=h.length;g<k;g++)b(h[g],e)}var c={};return{Ca:function(a){if("function"!=typeof a)throw Error("You can only pass a function to ko.memoization.memoize()");var b=(4294967296*(1+Math.random())|0).toString(16).substring(1)+(4294967296*(1+Math.random())|0).toString(16).substring(1);
|
||
c[b]=a;return"\x3c!--[ko_memo:"+b+"]--\x3e"},ub:function(a,b){var g=c[a];if(g===q)throw Error("Couldn't find any memo with ID "+a+". Perhaps it's already been unmemoized.");try{return g.apply(null,b||[]),!0}finally{delete c[a]}},vb:function(c,e){var g=[];b(c,g);for(var h=0,k=g.length;h<k;h++){var m=g[h].Fb,f=[m];e&&a.a.X(f,e);a.u.ub(g[h].Tb,f);m.nodeValue="";m.parentNode&&m.parentNode.removeChild(m)}},jb:function(a){return(a=a.match(/^\[ko_memo\:(.*?)\]$/))?a[1]:null}}}();a.b("memoization",a.u);a.b("memoization.memoize",
|
||
a.u.Ca);a.b("memoization.unmemoize",a.u.ub);a.b("memoization.parseMemoText",a.u.jb);a.b("memoization.unmemoizeDomNodeAndDescendants",a.u.vb);a.xa={throttle:function(b,c){b.throttleEvaluation=c;var d=null;return a.h({read:b,write:function(a){clearTimeout(d);d=setTimeout(function(){b(a)},c)}})},notify:function(a,c){a.equalityComparer="always"==c?null:G}};var N={undefined:1,"boolean":1,number:1,string:1};a.b("extenders",a.xa);a.sb=function(b,c,d){this.target=b;this.qa=c;this.Eb=d;a.s(this,"dispose",
|
||
this.B)};a.sb.prototype.B=function(){this.Qb=!0;this.Eb()};a.ca=function(){this.F={};a.a.extend(this,a.ca.fn);a.s(this,"subscribe",this.T);a.s(this,"extend",this.extend);a.s(this,"getSubscriptionsCount",this.Lb)};var I="change";a.ca.fn={T:function(b,c,d){d=d||I;var e=new a.sb(this,c?b.bind(c):b,function(){a.a.ia(this.F[d],e)}.bind(this));this.F[d]||(this.F[d]=[]);this.F[d].push(e);return e},notifySubscribers:function(b,c){c=c||I;if(this.cb(c))try{a.i.Wa();for(var d=this.F[c].slice(0),e=0,g;g=d[e];++e)g&&
|
||
!0!==g.Qb&&g.qa(b)}finally{a.i.end()}},cb:function(a){return this.F[a]&&this.F[a].length},Lb:function(){var b=0;a.a.K(this.F,function(a,d){b+=d.length});return b},extend:function(b){var c=this;b&&a.a.K(b,function(b,e){var g=a.xa[b];"function"==typeof g&&(c=g(c,e)||c)});return c}};a.fb=function(a){return null!=a&&"function"==typeof a.T&&"function"==typeof a.notifySubscribers};a.b("subscribable",a.ca);a.b("isSubscribable",a.fb);a.i=function(){var b=[];return{Wa:function(a){b.push(a&&{qa:a,Za:[]})},
|
||
end:function(){b.pop()},lb:function(c){if(!a.fb(c))throw Error("Only subscribable things can act as dependencies");if(0<b.length){var d=b[b.length-1];!d||0<=a.a.l(d.Za,c)||(d.Za.push(c),d.qa(c))}},p:function(a,d,e){try{return b.push(null),a.apply(d,e||[])}finally{b.pop()}}}}();a.q=function(b){function c(){if(0<arguments.length)return c.equalityComparer&&c.equalityComparer(d,arguments[0])||(c.O(),d=arguments[0],c.N()),this;a.i.lb(c);return d}var d=b;a.ca.call(c);c.t=function(){return d};c.N=function(){c.notifySubscribers(d)};
|
||
c.O=function(){c.notifySubscribers(d,"beforeChange")};a.a.extend(c,a.q.fn);a.s(c,"peek",c.t);a.s(c,"valueHasMutated",c.N);a.s(c,"valueWillMutate",c.O);return c};a.q.fn={equalityComparer:G};var C=a.q.Yb="__ko_proto__";a.q.fn[C]=a.q;a.ya=function(b,c){return null===b||b===q||b[C]===q?!1:b[C]===c?!0:a.ya(b[C],c)};a.M=function(b){return a.ya(b,a.q)};a.gb=function(b){return"function"==typeof b&&b[C]===a.q||"function"==typeof b&&b[C]===a.h&&b.Nb?!0:!1};a.b("observable",a.q);a.b("isObservable",a.M);a.b("isWriteableObservable",
|
||
a.gb);a.ba=function(b){b=b||[];if("object"!=typeof b||!("length"in b))throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");b=a.q(b);a.a.extend(b,a.ba.fn);return b.extend({trackArrayChanges:!0})};a.ba.fn={remove:function(b){for(var c=this.t(),d=[],e="function"!=typeof b||a.M(b)?function(a){return a===b}:b,g=0;g<c.length;g++){var h=c[g];e(h)&&(0===d.length&&this.O(),d.push(h),c.splice(g,1),g--)}d.length&&this.N();return d},removeAll:function(b){if(b===
|
||
q){var c=this.t(),d=c.slice(0);this.O();c.splice(0,c.length);this.N();return d}return b?this.remove(function(c){return 0<=a.a.l(b,c)}):[]},destroy:function(b){var c=this.t(),d="function"!=typeof b||a.M(b)?function(a){return a===b}:b;this.O();for(var e=c.length-1;0<=e;e--)d(c[e])&&(c[e]._destroy=!0);this.N()},destroyAll:function(b){return b===q?this.destroy(function(){return!0}):b?this.destroy(function(c){return 0<=a.a.l(b,c)}):[]},indexOf:function(b){var c=this();return a.a.l(c,b)},replace:function(a,
|
||
c){var d=this.indexOf(a);0<=d&&(this.O(),this.t()[d]=c,this.N())}};a.a.n("pop push reverse shift sort splice unshift".split(" "),function(b){a.ba.fn[b]=function(){var a=this.t();this.O();this.Xa(a,b,arguments);a=a[b].apply(a,arguments);this.N();return a}});a.a.n(["slice"],function(b){a.ba.fn[b]=function(){var a=this();return a[b].apply(a,arguments)}});a.b("observableArray",a.ba);var J="arrayChange";a.xa.trackArrayChanges=function(b){function c(){if(!d){d=!0;var c=b.notifySubscribers;b.notifySubscribers=
|
||
function(a,b){b&&b!==I||++g;return c.apply(this,arguments)};var m=[].concat(b.t()||[]);e=null;b.T(function(c){c=[].concat(c||[]);if(b.cb(J)){var d;if(!e||1<g)e=a.a.ra(m,c,{sparse:!0});d=e;d.length&&b.notifySubscribers(d,J)}m=c;e=null;g=0})}}if(!b.Xa){var d=!1,e=null,g=0,h=b.T;b.T=b.subscribe=function(a,b,f){f===J&&c();return h.apply(this,arguments)};b.Xa=function(a,b,c){function p(a,b,c){h.push({status:a,value:b,index:c})}if(d&&!g){var h=[],l=a.length,n=c.length,r=0;switch(b){case "push":r=l;case "unshift":for(b=
|
||
0;b<n;b++)p("added",c[b],r+b);break;case "pop":r=l-1;case "shift":l&&p("deleted",a[r],r);break;case "splice":b=Math.min(Math.max(0,0>c[0]?l+c[0]:c[0]),l);for(var l=1===n?l:Math.min(b+(c[1]||0),l),n=b+n-2,r=Math.max(l,n),v=2;b<r;++b,++v)b<l&&p("deleted",a[b],b),b<n&&p("added",c[v],b);break;default:return}e=h}}}};a.h=function(b,c,d){function e(){a.a.n(z,function(a){a.B()});z=[]}function g(){var a=k.throttleEvaluation;a&&0<=a?(clearTimeout(x),x=setTimeout(h,a)):h()}function h(){if(!s){if(E&&E()){if(!l){D();
|
||
p=!0;return}}else l=!1;s=!0;try{var b=a.a.ha(z,function(a){return a.target});a.i.Wa(function(c){var d;0<=(d=a.a.l(b,c))?b[d]=q:z.push(c.T(g))});for(var d=c?n.call(c):n(),e=b.length-1;0<=e;e--)b[e]&&z.splice(e,1)[0].B();p=!0;k.equalityComparer&&k.equalityComparer(f,d)||(k.notifySubscribers(f,"beforeChange"),f=d,k.notifySubscribers(f))}finally{a.i.end(),s=!1}z.length||D()}}function k(){if(0<arguments.length){if("function"===typeof r)r.apply(c,arguments);else throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
|
||
return this}p||h();a.i.lb(k);return f}function m(){return!p||0<z.length}var f,p=!1,s=!1,l=!1,n=b;n&&"object"==typeof n?(d=n,n=d.read):(d=d||{},n||(n=d.read));if("function"!=typeof n)throw Error("Pass a function that returns the value of the ko.computed");var r=d.write,v=d.disposeWhenNodeIsRemoved||d.I||null,t=d.disposeWhen||d.ua,E=t,D=e,z=[],x=null;c||(c=d.owner);k.t=function(){p||h();return f};k.Kb=function(){return z.length};k.Nb="function"===typeof d.write;k.B=function(){D()};k.aa=m;a.ca.call(k);
|
||
a.a.extend(k,a.h.fn);a.s(k,"peek",k.t);a.s(k,"dispose",k.B);a.s(k,"isActive",k.aa);a.s(k,"getDependenciesCount",k.Kb);v&&(l=!0,v.nodeType&&(E=function(){return!a.a.va(v)||t&&t()}));!0!==d.deferEvaluation&&h();v&&m()&&(D=function(){a.a.C.mb(v,D);e()},a.a.C.ea(v,D));return k};a.Pb=function(b){return a.ya(b,a.h)};F=a.q.Yb;a.h[F]=a.q;a.h.fn={equalityComparer:G};a.h.fn[F]=a.h;a.b("dependentObservable",a.h);a.b("computed",a.h);a.b("isComputed",a.Pb);(function(){function b(a,g,h){h=h||new d;a=g(a);if("object"!=
|
||
typeof a||null===a||a===q||a instanceof Date||a instanceof String||a instanceof Number||a instanceof Boolean)return a;var k=a instanceof Array?[]:{};h.save(a,k);c(a,function(c){var d=g(a[c]);switch(typeof d){case "boolean":case "number":case "string":case "function":k[c]=d;break;case "object":case "undefined":var p=h.get(d);k[c]=p!==q?p:b(d,g,h)}});return k}function c(a,b){if(a instanceof Array){for(var c=0;c<a.length;c++)b(c);"function"==typeof a.toJSON&&b("toJSON")}else for(c in a)b(c)}function d(){this.keys=
|
||
[];this.Qa=[]}a.tb=function(c){if(0==arguments.length)throw Error("When calling ko.toJS, pass the object you want to convert.");return b(c,function(b){for(var c=0;a.M(b)&&10>c;c++)b=b();return b})};a.toJSON=function(b,c,d){b=a.tb(b);return a.a.Na(b,c,d)};d.prototype={save:function(b,c){var d=a.a.l(this.keys,b);0<=d?this.Qa[d]=c:(this.keys.push(b),this.Qa.push(c))},get:function(b){b=a.a.l(this.keys,b);return 0<=b?this.Qa[b]:q}}})();a.b("toJS",a.tb);a.b("toJSON",a.toJSON);(function(){a.k={o:function(b){switch(a.a.v(b)){case "option":return!0===
|
||
b.__ko__hasDomDataOptionValue__?a.a.f.get(b,a.d.options.Ea):7>=a.a.ja?b.getAttributeNode("value")&&b.getAttributeNode("value").specified?b.value:b.text:b.value;case "select":return 0<=b.selectedIndex?a.k.o(b.options[b.selectedIndex]):q;default:return b.value}},na:function(b,c){switch(a.a.v(b)){case "option":switch(typeof c){case "string":a.a.f.set(b,a.d.options.Ea,q);"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__;b.value=c;break;default:a.a.f.set(b,a.d.options.Ea,c),b.__ko__hasDomDataOptionValue__=
|
||
!0,b.value="number"===typeof c?c:""}break;case "select":""===c&&(c=q);if(null===c||c===q)b.selectedIndex=-1;for(var d=b.options.length-1;0<=d;d--)if(a.k.o(b.options[d])==c){b.selectedIndex=d;break}1<b.size||-1!==b.selectedIndex||(b.selectedIndex=0);break;default:if(null===c||c===q)c="";b.value=c}}}})();a.b("selectExtensions",a.k);a.b("selectExtensions.readValue",a.k.o);a.b("selectExtensions.writeValue",a.k.na);a.g=function(){function b(b){b=a.a.la(b);123===b.charCodeAt(0)&&(b=b.slice(1,-1));var c=
|
||
[],d=b.match(e),k,l,n=0;if(d){d.push(",");for(var r=0,v;v=d[r];++r){var t=v.charCodeAt(0);if(44===t){if(0>=n){k&&c.push(l?{key:k,value:l.join("")}:{unknown:k});k=l=n=0;continue}}else if(58===t){if(!l)continue}else if(47===t&&r&&1<v.length)(t=d[r-1].match(g))&&!h[t[0]]&&(b=b.substr(b.indexOf(v)+1),d=b.match(e),d.push(","),r=-1,v="/");else if(40===t||123===t||91===t)++n;else if(41===t||125===t||93===t)--n;else if(!k&&!l){k=34===t||39===t?v.slice(1,-1):v;continue}l?l.push(v):l=[v]}}return c}var c=["true",
|
||
"false","null","undefined"],d=/^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))$/i,e=RegExp("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|/(?:[^/\\\\]|\\\\.)*/w*|[^\\s:,/][^,\"'{}()/:[\\]]*[^\\s,\"'{}()/:[\\]]|[^\\s]","g"),g=/[\])"'A-Za-z0-9_$]+$/,h={"in":1,"return":1,"typeof":1},k={};return{Y:[],U:k,Ga:b,ka:function(e,f){function g(b,f){var e,r=a.getBindingHandler(b);if(r&&r.preprocess?f=r.preprocess(f,b,g):1){if(r=k[b])e=f,0<=a.a.l(c,e)?e=!1:(r=e.match(d),e=null===r?!1:r[1]?"Object("+r[1]+")"+
|
||
r[2]:e),r=e;r&&l.push("'"+b+"':function(_z){"+e+"=_z}");n&&(f="function(){return "+f+" }");h.push("'"+b+"':"+f)}}f=f||{};var h=[],l=[],n=f.valueAccessors,r="string"===typeof e?b(e):e;a.a.n(r,function(a){g(a.key||a.unknown,a.value)});l.length&&g("_ko_property_writers","{"+l.join(",")+"}");return h.join(",")},Sb:function(a,b){for(var c=0;c<a.length;c++)if(a[c].key==b)return!0;return!1},oa:function(b,c,d,e,k){if(b&&a.M(b))!a.gb(b)||k&&b.t()===e||b(e);else if((b=c.get("_ko_property_writers"))&&b[d])b[d](e)}}}();
|
||
a.b("expressionRewriting",a.g);a.b("expressionRewriting.bindingRewriteValidators",a.g.Y);a.b("expressionRewriting.parseObjectLiteral",a.g.Ga);a.b("expressionRewriting.preProcessBindings",a.g.ka);a.b("expressionRewriting._twoWayBindings",a.g.U);a.b("jsonExpressionRewriting",a.g);a.b("jsonExpressionRewriting.insertPropertyAccessorsIntoJson",a.g.ka);(function(){function b(a){return 8==a.nodeType&&h.test(g?a.text:a.nodeValue)}function c(a){return 8==a.nodeType&&k.test(g?a.text:a.nodeValue)}function d(a,
|
||
d){for(var e=a,k=1,n=[];e=e.nextSibling;){if(c(e)&&(k--,0===k))return n;n.push(e);b(e)&&k++}if(!d)throw Error("Cannot find closing comment tag to match: "+a.nodeValue);return null}function e(a,b){var c=d(a,b);return c?0<c.length?c[c.length-1].nextSibling:a.nextSibling:null}var g=w&&"\x3c!--test--\x3e"===w.createComment("test").text,h=g?/^\x3c!--\s*ko(?:\s+([\s\S]+))?\s*--\x3e$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,k=g?/^\x3c!--\s*\/ko\s*--\x3e$/:/^\s*\/ko\s*$/,m={ul:!0,ol:!0};a.e={P:{},childNodes:function(a){return b(a)?
|
||
d(a):a.childNodes},Z:function(c){if(b(c)){c=a.e.childNodes(c);for(var d=0,e=c.length;d<e;d++)a.removeNode(c[d])}else a.a.wa(c)},S:function(c,d){if(b(c)){a.e.Z(c);for(var e=c.nextSibling,k=0,n=d.length;k<n;k++)e.parentNode.insertBefore(d[k],e)}else a.a.S(c,d)},kb:function(a,c){b(a)?a.parentNode.insertBefore(c,a.nextSibling):a.firstChild?a.insertBefore(c,a.firstChild):a.appendChild(c)},eb:function(c,d,e){e?b(c)?c.parentNode.insertBefore(d,e.nextSibling):e.nextSibling?c.insertBefore(d,e.nextSibling):
|
||
c.appendChild(d):a.e.kb(c,d)},firstChild:function(a){return b(a)?!a.nextSibling||c(a.nextSibling)?null:a.nextSibling:a.firstChild},nextSibling:function(a){b(a)&&(a=e(a));return a.nextSibling&&c(a.nextSibling)?null:a.nextSibling},Mb:b,bc:function(a){return(a=(g?a.text:a.nodeValue).match(h))?a[1]:null},ib:function(d){if(m[a.a.v(d)]){var k=d.firstChild;if(k){do if(1===k.nodeType){var g;g=k.firstChild;var h=null;if(g){do if(h)h.push(g);else if(b(g)){var n=e(g,!0);n?g=n:h=[g]}else c(g)&&(h=[g]);while(g=
|
||
g.nextSibling)}if(g=h)for(h=k.nextSibling,n=0;n<g.length;n++)h?d.insertBefore(g[n],h):d.appendChild(g[n])}while(k=k.nextSibling)}}}}})();a.b("virtualElements",a.e);a.b("virtualElements.allowedBindings",a.e.P);a.b("virtualElements.emptyNode",a.e.Z);a.b("virtualElements.insertAfter",a.e.eb);a.b("virtualElements.prepend",a.e.kb);a.b("virtualElements.setDomNodeChildren",a.e.S);(function(){a.H=function(){this.zb={}};a.a.extend(a.H.prototype,{nodeHasBindings:function(b){switch(b.nodeType){case 1:return null!=
|
||
b.getAttribute("data-bind");case 8:return a.e.Mb(b);default:return!1}},getBindings:function(a,c){var d=this.getBindingsString(a,c);return d?this.parseBindingsString(d,c,a):null},getBindingAccessors:function(a,c){var d=this.getBindingsString(a,c);return d?this.parseBindingsString(d,c,a,{valueAccessors:!0}):null},getBindingsString:function(b){switch(b.nodeType){case 1:return b.getAttribute("data-bind");case 8:return a.e.bc(b);default:return null}},parseBindingsString:function(b,c,d,e){try{var g=this.zb,
|
||
h=b+(e&&e.valueAccessors||""),k;if(!(k=g[h])){var m,f="with($context){with($data||{}){return{"+a.g.ka(b,e)+"}}}";m=new Function("$context","$element",f);k=g[h]=m}return k(c,d)}catch(p){throw p.message="Unable to parse bindings.\nBindings value: "+b+"\nMessage: "+p.message,p;}}});a.H.instance=new a.H})();a.b("bindingProvider",a.H);(function(){function b(a){return function(){return a}}function c(a){return a()}function d(b){return a.a.Da(a.i.p(b),function(a,c){return function(){return b()[c]}})}function e(a,
|
||
b){return d(this.getBindings.bind(this,a,b))}function g(b,c,d){var f,e=a.e.firstChild(c),k=a.H.instance,g=k.preprocessNode;if(g){for(;f=e;)e=a.e.nextSibling(f),g.call(k,f);e=a.e.firstChild(c)}for(;f=e;)e=a.e.nextSibling(f),h(b,f,d)}function h(b,c,d){var f=!0,e=1===c.nodeType;e&&a.e.ib(c);if(e&&d||a.H.instance.nodeHasBindings(c))f=m(c,null,b,d).shouldBindDescendants;f&&!p[a.a.v(c)]&&g(b,c,!e)}function k(b){var c=[],d={},f=[];a.a.K(b,function D(e){if(!d[e]){var k=a.getBindingHandler(e);k&&(k.after&&
|
||
(f.push(e),a.a.n(k.after,function(c){if(b[c]){if(-1!==a.a.l(f,c))throw Error("Cannot combine the following bindings, because they have a cyclic dependency: "+f.join(", "));D(c)}}),f.pop()),c.push({key:e,bb:k}));d[e]=!0}});return c}function m(b,d,f,g){var h=a.a.f.get(b,s);if(!d){if(h)throw Error("You cannot apply bindings multiple times to the same element.");a.a.f.set(b,s,!0)}!h&&g&&a.rb(b,f);var m;if(d&&"function"!==typeof d)m=d;else{var p=a.H.instance,l=p.getBindingAccessors||e;if(d||f.A){var A=
|
||
a.h(function(){(m=d?d(f,b):l.call(p,b,f))&&f.A&&f.A();return m},null,{I:b});m&&A.aa()||(A=null)}else m=a.i.p(l,p,[b,f])}var u;if(m){var w=A?function(a){return function(){return c(A()[a])}}:function(a){return m[a]},y=function(){return a.a.Da(A?A():m,c)};y.get=function(a){return m[a]&&c(w(a))};y.has=function(a){return a in m};g=k(m);a.a.n(g,function(c){var d=c.bb.init,e=c.bb.update,k=c.key;if(8===b.nodeType&&!a.e.P[k])throw Error("The binding '"+k+"' cannot be used with virtual elements");try{"function"==
|
||
typeof d&&a.i.p(function(){var a=d(b,w(k),y,f.$data,f);if(a&&a.controlsDescendantBindings){if(u!==q)throw Error("Multiple bindings ("+u+" and "+k+") are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.");u=k}}),"function"==typeof e&&a.h(function(){e(b,w(k),y,f.$data,f)},null,{I:b})}catch(g){throw g.message='Unable to process binding "'+k+": "+m[k]+'"\nMessage: '+g.message,g;}})}return{shouldBindDescendants:u===q}}function f(b){return b&&
|
||
b instanceof a.G?b:new a.G(b)}a.d={};var p={script:!0};a.getBindingHandler=function(b){return a.d[b]};a.G=function(b,c,d,f){var e=this,k="function"==typeof b,g,h=a.h(function(){var g=k?b():b;c?(c.A&&c.A(),a.a.extend(e,c),h&&(e.A=h)):(e.$parents=[],e.$root=g,e.ko=a);e.$rawData=b;e.$data=g;d&&(e[d]=g);f&&f(e,c,g);return e.$data},null,{ua:function(){return g&&!a.a.Ra(g)},I:!0});h.aa()&&(e.A=h,h.equalityComparer=null,g=[],h.wb=function(b){g.push(b);a.a.C.ea(b,function(b){a.a.ia(g,b);g.length||(h.B(),
|
||
e.A=h=q)})})};a.G.prototype.createChildContext=function(b,c,d){return new a.G(b,this,c,function(a,b){a.$parentContext=b;a.$parent=b.$data;a.$parents=(b.$parents||[]).slice(0);a.$parents.unshift(a.$parent);d&&d(a)})};a.G.prototype.extend=function(b){return new a.G(this.$rawData,this,null,function(c){a.a.extend(c,"function"==typeof b?b():b)})};var s=a.a.f.D(),l=a.a.f.D();a.rb=function(b,c){if(2==arguments.length)a.a.f.set(b,l,c),c.A&&c.A.wb(b);else return a.a.f.get(b,l)};a.pa=function(b,c,d){1===b.nodeType&&
|
||
a.e.ib(b);return m(b,c,f(d),!0)};a.xb=function(c,e,k){k=f(k);return a.pa(c,"function"===typeof e?d(e.bind(null,k,c)):a.a.Da(e,b),k)};a.Ta=function(a,b){1!==b.nodeType&&8!==b.nodeType||g(f(a),b,!0)};a.Sa=function(a,b){if(b&&1!==b.nodeType&&8!==b.nodeType)throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");b=b||y.document.body;h(f(a),b,!0)};a.ta=function(b){switch(b.nodeType){case 1:case 8:var c=a.rb(b);if(c)return c;if(b.parentNode)return a.ta(b.parentNode)}return q};
|
||
a.Cb=function(b){return(b=a.ta(b))?b.$data:q};a.b("bindingHandlers",a.d);a.b("applyBindings",a.Sa);a.b("applyBindingsToDescendants",a.Ta);a.b("applyBindingAccessorsToNode",a.pa);a.b("applyBindingsToNode",a.xb);a.b("contextFor",a.ta);a.b("dataFor",a.Cb)})();var M={"class":"className","for":"htmlFor"};a.d.attr={update:function(b,c){var d=a.a.c(c())||{};a.a.K(d,function(c,d){d=a.a.c(d);var h=!1===d||null===d||d===q;h&&b.removeAttribute(c);8>=a.a.ja&&c in M?(c=M[c],h?b.removeAttribute(c):b[c]=d):h||b.setAttribute(c,
|
||
d.toString());"name"===c&&a.a.pb(b,h?"":d.toString())})}};(function(){a.d.checked={after:["value","attr"],init:function(b,c,d){function e(){return d.has("checkedValue")?a.a.c(d.get("checkedValue")):b.value}function g(){var k=b.checked,g=s?e():k;if(l&&(!m||k)){var h=a.i.p(c);f?p!==g?(k&&(a.a.V(h,g,!0),a.a.V(h,p,!1)),p=g):a.a.V(h,g,k):a.g.oa(h,d,"checked",g,!0)}}function h(){var d=a.a.c(c());b.checked=f?0<=a.a.l(d,e()):k?d:e()===d}var k="checkbox"==b.type,m="radio"==b.type;if(k||m){var f=k&&a.a.c(c())instanceof
|
||
Array,p=f?e():q,s=m||f,l=!1;m&&!b.name&&a.d.uniqueName.init(b,function(){return!0});a.h(g,null,{I:b});a.a.r(b,"click",g);a.h(h,null,{I:b});l=!0}}};a.g.U.checked=!0;a.d.checkedValue={update:function(b,c){b.value=a.a.c(c())}}})();a.d.css={update:function(b,c){var d=a.a.c(c());"object"==typeof d?a.a.K(d,function(c,d){d=a.a.c(d);a.a.ma(b,c,d)}):(d=String(d||""),a.a.ma(b,b.__ko__cssValue,!1),b.__ko__cssValue=d,a.a.ma(b,d,!0))}};a.d.enable={update:function(b,c){var d=a.a.c(c());d&&b.disabled?b.removeAttribute("disabled"):
|
||
d||b.disabled||(b.disabled=!0)}};a.d.disable={update:function(b,c){a.d.enable.update(b,function(){return!a.a.c(c())})}};a.d.event={init:function(b,c,d,e,g){var h=c()||{};a.a.K(h,function(k){"string"==typeof k&&a.a.r(b,k,function(b){var f,h=c()[k];if(h){try{var s=a.a.Q(arguments);e=g.$data;s.unshift(e);f=h.apply(e,s)}finally{!0!==f&&(b.preventDefault?b.preventDefault():b.returnValue=!1)}!1===d.get(k+"Bubble")&&(b.cancelBubble=!0,b.stopPropagation&&b.stopPropagation())}})})}};a.d.foreach={hb:function(b){return function(){var c=
|
||
b(),d=a.a.Ha(c);if(!d||"number"==typeof d.length)return{foreach:c,templateEngine:a.J.Aa};a.a.c(c);return{foreach:d.data,as:d.as,includeDestroyed:d.includeDestroyed,afterAdd:d.afterAdd,beforeRemove:d.beforeRemove,afterRender:d.afterRender,beforeMove:d.beforeMove,afterMove:d.afterMove,templateEngine:a.J.Aa}}},init:function(b,c){return a.d.template.init(b,a.d.foreach.hb(c))},update:function(b,c,d,e,g){return a.d.template.update(b,a.d.foreach.hb(c),d,e,g)}};a.g.Y.foreach=!1;a.e.P.foreach=!0;a.d.hasfocus=
|
||
{init:function(b,c,d){function e(e){b.__ko_hasfocusUpdating=!0;var g=b.ownerDocument;if("activeElement"in g){var f;try{f=g.activeElement}catch(h){f=g.body}e=f===b}g=c();a.g.oa(g,d,"hasfocus",e,!0);b.__ko_hasfocusLastValue=e;b.__ko_hasfocusUpdating=!1}var g=e.bind(null,!0),h=e.bind(null,!1);a.a.r(b,"focus",g);a.a.r(b,"focusin",g);a.a.r(b,"blur",h);a.a.r(b,"focusout",h)},update:function(b,c){var d=!!a.a.c(c());b.__ko_hasfocusUpdating||b.__ko_hasfocusLastValue===d||(d?b.focus():b.blur(),a.i.p(a.a.da,
|
||
null,[b,d?"focusin":"focusout"]))}};a.g.U.hasfocus=!0;a.d.hasFocus=a.d.hasfocus;a.g.U.hasFocus=!0;a.d.html={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.Ka(b,c())}};var L=a.a.f.D();H("if");H("ifnot",!1,!0);H("with",!0,!1,function(a,c){return a.createChildContext(c)});a.d.options={init:function(b){if("select"!==a.a.v(b))throw Error("options binding applies only to SELECT elements");for(;0<b.length;)b.remove(0);return{controlsDescendantBindings:!0}},update:function(b,
|
||
c,d){function e(){return a.a.ga(b.options,function(a){return a.selected})}function g(a,b,c){var d=typeof b;return"function"==d?b(a):"string"==d?a[b]:c}function h(c,d){if(p.length){var f=0<=a.a.l(p,a.k.o(d[0]));a.a.qb(d[0],f);l&&!f&&a.i.p(a.a.da,null,[b,"change"])}}var k=0!=b.length&&b.multiple?b.scrollTop:null;c=a.a.c(c());var m=d.get("optionsIncludeDestroyed"),f={},p;p=b.multiple?a.a.ha(e(),a.k.o):0<=b.selectedIndex?[a.k.o(b.options[b.selectedIndex])]:[];if(c){"undefined"==typeof c.length&&(c=[c]);
|
||
var s=a.a.ga(c,function(b){return m||b===q||null===b||!a.a.c(b._destroy)});d.has("optionsCaption")&&(c=a.a.c(d.get("optionsCaption")),null!==c&&c!==q&&s.unshift(f))}else c=[];var l=!1;c=h;d.has("optionsAfterRender")&&(c=function(b,c){h(0,c);a.i.p(d.get("optionsAfterRender"),null,[c[0],b!==f?b:q])});a.a.Ja(b,s,function(b,c,e){e.length&&(p=e[0].selected?[a.k.o(e[0])]:[],l=!0);c=w.createElement("option");b===f?(a.a.Ma(c,d.get("optionsCaption")),a.k.na(c,q)):(e=g(b,d.get("optionsValue"),b),a.k.na(c,a.a.c(e)),
|
||
b=g(b,d.get("optionsText"),e),a.a.Ma(c,b));return[c]},null,c);(b.multiple?p.length&&e().length<p.length:p.length&&0<=b.selectedIndex?a.k.o(b.options[b.selectedIndex])!==p[0]:p.length||0<=b.selectedIndex)&&a.i.p(a.a.da,null,[b,"change"]);a.a.Hb(b);k&&20<Math.abs(k-b.scrollTop)&&(b.scrollTop=k)}};a.d.options.Ea=a.a.f.D();a.d.selectedOptions={after:["options","foreach"],init:function(b,c,d){a.a.r(b,"change",function(){var e=c(),g=[];a.a.n(b.getElementsByTagName("option"),function(b){b.selected&&g.push(a.k.o(b))});
|
||
a.g.oa(e,d,"selectedOptions",g)})},update:function(b,c){if("select"!=a.a.v(b))throw Error("values binding applies only to SELECT elements");var d=a.a.c(c());d&&"number"==typeof d.length&&a.a.n(b.getElementsByTagName("option"),function(b){var c=0<=a.a.l(d,a.k.o(b));a.a.qb(b,c)})}};a.g.U.selectedOptions=!0;a.d.style={update:function(b,c){var d=a.a.c(c()||{});a.a.K(d,function(c,d){d=a.a.c(d);b.style[c]=d||""})}};a.d.submit={init:function(b,c,d,e,g){if("function"!=typeof c())throw Error("The value for a submit binding must be a function");
|
||
a.a.r(b,"submit",function(a){var d,e=c();try{d=e.call(g.$data,b)}finally{!0!==d&&(a.preventDefault?a.preventDefault():a.returnValue=!1)}})}};a.d.text={init:function(){return{controlsDescendantBindings:!0}},update:function(b,c){a.a.Ma(b,c())}};a.e.P.text=!0;a.d.uniqueName={init:function(b,c){if(c()){var d="ko_unique_"+ ++a.d.uniqueName.Bb;a.a.pb(b,d)}}};a.d.uniqueName.Bb=0;a.d.value={after:["options","foreach"],init:function(b,c,d){function e(){k=!1;var e=c(),f=a.k.o(b);a.g.oa(e,d,"value",f)}var g=
|
||
["change"],h=d.get("valueUpdate"),k=!1;h&&("string"==typeof h&&(h=[h]),a.a.X(g,h),g=a.a.Va(g));!a.a.ja||"input"!=b.tagName.toLowerCase()||"text"!=b.type||"off"==b.autocomplete||b.form&&"off"==b.form.autocomplete||-1!=a.a.l(g,"propertychange")||(a.a.r(b,"propertychange",function(){k=!0}),a.a.r(b,"blur",function(){k&&e()}));a.a.n(g,function(c){var d=e;a.a.ac(c,"after")&&(d=function(){setTimeout(e,0)},c=c.substring(5));a.a.r(b,c,d)})},update:function(b,c){var d="select"===a.a.v(b),e=a.a.c(c()),g=a.k.o(b);
|
||
e!==g&&(g=function(){a.k.na(b,e)},g(),d&&(e!==a.k.o(b)?a.i.p(a.a.da,null,[b,"change"]):setTimeout(g,0)))}};a.g.U.value=!0;a.d.visible={update:function(b,c){var d=a.a.c(c()),e="none"!=b.style.display;d&&!e?b.style.display="":!d&&e&&(b.style.display="none")}};(function(b){a.d[b]={init:function(c,d,e,g,h){return a.d.event.init.call(this,c,function(){var a={};a[b]=d();return a},e,g,h)}}})("click");a.w=function(){};a.w.prototype.renderTemplateSource=function(){throw Error("Override renderTemplateSource");
|
||
};a.w.prototype.createJavaScriptEvaluatorBlock=function(){throw Error("Override createJavaScriptEvaluatorBlock");};a.w.prototype.makeTemplateSource=function(b,c){if("string"==typeof b){c=c||w;var d=c.getElementById(b);if(!d)throw Error("Cannot find template with ID "+b);return new a.m.j(d)}if(1==b.nodeType||8==b.nodeType)return new a.m.W(b);throw Error("Unknown template type: "+b);};a.w.prototype.renderTemplate=function(a,c,d,e){a=this.makeTemplateSource(a,e);return this.renderTemplateSource(a,c,
|
||
d)};a.w.prototype.isTemplateRewritten=function(a,c){return!1===this.allowTemplateRewriting?!0:this.makeTemplateSource(a,c).data("isRewritten")};a.w.prototype.rewriteTemplate=function(a,c,d){a=this.makeTemplateSource(a,d);c=c(a.text());a.text(c);a.data("isRewritten",!0)};a.b("templateEngine",a.w);a.Oa=function(){function b(b,c,d,k){b=a.g.Ga(b);for(var m=a.g.Y,f=0;f<b.length;f++){var p=b[f].key;if(m.hasOwnProperty(p)){var s=m[p];if("function"===typeof s){if(p=s(b[f].value))throw Error(p);}else if(!s)throw Error("This template engine does not support the '"+
|
||
p+"' binding within its templates");}}d="ko.__tr_ambtns(function($context,$element){return(function(){return{ "+a.g.ka(b,{valueAccessors:!0})+" } })()},'"+d.toLowerCase()+"')";return k.createJavaScriptEvaluatorBlock(d)+c}var c=/(<([a-z]+\d*)(?:\s+(?!data-bind\s*=\s*)[a-z0-9\-]+(?:=(?:\"[^\"]*\"|\'[^\']*\'))?)*\s+)data-bind\s*=\s*(["'])([\s\S]*?)\3/gi,d=/\x3c!--\s*ko\b\s*([\s\S]*?)\s*--\x3e/g;return{Ib:function(b,c,d){c.isTemplateRewritten(b,d)||c.rewriteTemplate(b,function(b){return a.Oa.Ub(b,c)},
|
||
d)},Ub:function(a,g){return a.replace(c,function(a,c,d,f,e){return b(e,c,d,g)}).replace(d,function(a,c){return b(c,"\x3c!-- ko --\x3e","#comment",g)})},yb:function(b,c){return a.u.Ca(function(d,k){var m=d.nextSibling;m&&m.nodeName.toLowerCase()===c&&a.pa(m,b,k)})}}}();a.b("__tr_ambtns",a.Oa.yb);(function(){a.m={};a.m.j=function(a){this.j=a};a.m.j.prototype.text=function(){var b=a.a.v(this.j),b="script"===b?"text":"textarea"===b?"value":"innerHTML";if(0==arguments.length)return this.j[b];var c=arguments[0];
|
||
"innerHTML"===b?a.a.Ka(this.j,c):this.j[b]=c};var b=a.a.f.D()+"_";a.m.j.prototype.data=function(c){if(1===arguments.length)return a.a.f.get(this.j,b+c);a.a.f.set(this.j,b+c,arguments[1])};var c=a.a.f.D();a.m.W=function(a){this.j=a};a.m.W.prototype=new a.m.j;a.m.W.prototype.text=function(){if(0==arguments.length){var b=a.a.f.get(this.j,c)||{};b.Pa===q&&b.sa&&(b.Pa=b.sa.innerHTML);return b.Pa}a.a.f.set(this.j,c,{Pa:arguments[0]})};a.m.j.prototype.nodes=function(){if(0==arguments.length)return(a.a.f.get(this.j,
|
||
c)||{}).sa;a.a.f.set(this.j,c,{sa:arguments[0]})};a.b("templateSources",a.m);a.b("templateSources.domElement",a.m.j);a.b("templateSources.anonymousTemplate",a.m.W)})();(function(){function b(b,c,d){var e;for(c=a.e.nextSibling(c);b&&(e=b)!==c;)b=a.e.nextSibling(e),d(e,b)}function c(c,d){if(c.length){var f=c[0],e=c[c.length-1],g=f.parentNode,h=a.H.instance,n=h.preprocessNode;if(n){b(f,e,function(a,b){var c=a.previousSibling,d=n.call(h,a);d&&(a===f&&(f=d[0]||b),a===e&&(e=d[d.length-1]||c))});c.length=
|
||
0;if(!f)return;f===e?c.push(f):(c.push(f,e),a.a.$(c,g))}b(f,e,function(b){1!==b.nodeType&&8!==b.nodeType||a.Sa(d,b)});b(f,e,function(b){1!==b.nodeType&&8!==b.nodeType||a.u.vb(b,[d])});a.a.$(c,g)}}function d(a){return a.nodeType?a:0<a.length?a[0]:null}function e(b,e,f,h,s){s=s||{};var l=b&&d(b),l=l&&l.ownerDocument,n=s.templateEngine||g;a.Oa.Ib(f,n,l);f=n.renderTemplate(f,h,s,l);if("number"!=typeof f.length||0<f.length&&"number"!=typeof f[0].nodeType)throw Error("Template engine must return an array of DOM nodes");
|
||
l=!1;switch(e){case "replaceChildren":a.e.S(b,f);l=!0;break;case "replaceNode":a.a.nb(b,f);l=!0;break;case "ignoreTargetNode":break;default:throw Error("Unknown renderMode: "+e);}l&&(c(f,h),s.afterRender&&a.i.p(s.afterRender,null,[f,h.$data]));return f}var g;a.La=function(b){if(b!=q&&!(b instanceof a.w))throw Error("templateEngine must inherit from ko.templateEngine");g=b};a.Ia=function(b,c,f,h,s){f=f||{};if((f.templateEngine||g)==q)throw Error("Set a template engine before calling renderTemplate");
|
||
s=s||"replaceChildren";if(h){var l=d(h);return a.h(function(){var g=c&&c instanceof a.G?c:new a.G(a.a.c(c)),r="function"==typeof b?b(g.$data,g):b,g=e(h,s,r,g,f);"replaceNode"==s&&(h=g,l=d(h))},null,{ua:function(){return!l||!a.a.va(l)},I:l&&"replaceNode"==s?l.parentNode:l})}return a.u.Ca(function(d){a.Ia(b,c,f,d,"replaceNode")})};a.$b=function(b,d,f,g,h){function l(a,b){c(b,r);f.afterRender&&f.afterRender(b,a)}function n(a,c){r=h.createChildContext(a,f.as,function(a){a.$index=c});var d="function"==
|
||
typeof b?b(a,r):b;return e(null,"ignoreTargetNode",d,r,f)}var r;return a.h(function(){var b=a.a.c(d)||[];"undefined"==typeof b.length&&(b=[b]);b=a.a.ga(b,function(b){return f.includeDestroyed||b===q||null===b||!a.a.c(b._destroy)});a.i.p(a.a.Ja,null,[g,b,n,f,l])},null,{I:g})};var h=a.a.f.D();a.d.template={init:function(b,c){var d=a.a.c(c());"string"==typeof d||d.name?a.e.Z(b):(d=a.e.childNodes(b),d=a.a.Vb(d),(new a.m.W(b)).nodes(d));return{controlsDescendantBindings:!0}},update:function(b,c,d,e,g){c=
|
||
a.a.c(c());d={};e=!0;var l,n=null;"string"!=typeof c&&(d=c,c=a.a.c(d.name),"if"in d&&(e=a.a.c(d["if"])),e&&"ifnot"in d&&(e=!a.a.c(d.ifnot)),l=a.a.c(d.data));"foreach"in d?n=a.$b(c||b,e&&d.foreach||[],d,b,g):e?(g="data"in d?g.createChildContext(l,d.as):g,n=a.Ia(c||b,g,d,b)):a.e.Z(b);g=n;(l=a.a.f.get(b,h))&&"function"==typeof l.B&&l.B();a.a.f.set(b,h,g&&g.aa()?g:q)}};a.g.Y.template=function(b){b=a.g.Ga(b);return 1==b.length&&b[0].unknown||a.g.Sb(b,"name")?null:"This template engine does not support anonymous templates nested within its templates"};
|
||
a.e.P.template=!0})();a.b("setTemplateEngine",a.La);a.b("renderTemplate",a.Ia);a.a.ra=function(){function a(b,d,e,g,h){var k=Math.min,m=Math.max,f=[],p,q=b.length,l,n=d.length,r=n-q||1,v=q+n+1,t,u,w;for(p=0;p<=q;p++)for(u=t,f.push(t=[]),w=k(n,p+r),l=m(0,p-1);l<=w;l++)t[l]=l?p?b[p-1]===d[l-1]?u[l-1]:k(u[l]||v,t[l-1]||v)+1:l+1:p+1;k=[];m=[];r=[];p=q;for(l=n;p||l;)n=f[p][l]-1,l&&n===f[p][l-1]?m.push(k[k.length]={status:e,value:d[--l],index:l}):p&&n===f[p-1][l]?r.push(k[k.length]={status:g,value:b[--p],
|
||
index:p}):(--l,--p,h.sparse||k.push({status:"retained",value:d[l]}));if(m.length&&r.length){b=10*q;var z;for(d=e=0;(h.dontLimitMoves||d<b)&&(z=m[e]);e++){for(g=0;f=r[g];g++)if(z.value===f.value){z.moved=f.index;f.moved=z.index;r.splice(g,1);d=g=0;break}d+=g}}return k.reverse()}return function(c,d,e){e="boolean"===typeof e?{dontLimitMoves:e}:e||{};c=c||[];d=d||[];return c.length<=d.length?a(c,d,"added","deleted",e):a(d,c,"deleted","added",e)}}();a.b("utils.compareArrays",a.a.ra);(function(){function b(b,
|
||
c,g,h,k){var m=[],f=a.h(function(){var f=c(g,k,a.a.$(m,b))||[];0<m.length&&(a.a.nb(m,f),h&&a.i.p(h,null,[g,f,k]));m.splice(0,m.length);a.a.X(m,f)},null,{I:b,ua:function(){return!a.a.Ra(m)}});return{R:m,h:f.aa()?f:q}}var c=a.a.f.D();a.a.Ja=function(d,e,g,h,k){function m(b,c){x=s[c];t!==c&&(z[b]=x);x.za(t++);a.a.$(x.R,d);r.push(x);w.push(x)}function f(b,c){if(b)for(var d=0,e=c.length;d<e;d++)c[d]&&a.a.n(c[d].R,function(a){b(a,d,c[d].fa)})}e=e||[];h=h||{};var p=a.a.f.get(d,c)===q,s=a.a.f.get(d,c)||[],
|
||
l=a.a.ha(s,function(a){return a.fa}),n=a.a.ra(l,e,h.dontLimitMoves),r=[],v=0,t=0,u=[],w=[];e=[];for(var z=[],l=[],x,A=0,y,B;y=n[A];A++)switch(B=y.moved,y.status){case "deleted":B===q&&(x=s[v],x.h&&x.h.B(),u.push.apply(u,a.a.$(x.R,d)),h.beforeRemove&&(e[A]=x,w.push(x)));v++;break;case "retained":m(A,v++);break;case "added":B!==q?m(A,B):(x={fa:y.value,za:a.q(t++)},r.push(x),w.push(x),p||(l[A]=x))}f(h.beforeMove,z);a.a.n(u,h.beforeRemove?a.L:a.removeNode);for(var A=0,p=a.e.firstChild(d),C;x=w[A];A++){x.R||
|
||
a.a.extend(x,b(d,g,x.fa,k,x.za));for(v=0;n=x.R[v];p=n.nextSibling,C=n,v++)n!==p&&a.e.eb(d,n,C);!x.Ob&&k&&(k(x.fa,x.R,x.za),x.Ob=!0)}f(h.beforeRemove,e);f(h.afterMove,z);f(h.afterAdd,l);a.a.f.set(d,c,r)}})();a.b("utils.setDomNodeChildrenFromArrayMapping",a.a.Ja);a.J=function(){this.allowTemplateRewriting=!1};a.J.prototype=new a.w;a.J.prototype.renderTemplateSource=function(b){var c=(9>a.a.ja?0:b.nodes)?b.nodes():null;if(c)return a.a.Q(c.cloneNode(!0).childNodes);b=b.text();return a.a.Fa(b)};a.J.Aa=
|
||
new a.J;a.La(a.J.Aa);a.b("nativeTemplateEngine",a.J);(function(){a.Ba=function(){var a=this.Rb=function(){if("undefined"==typeof u||!u.tmpl)return 0;try{if(0<=u.tmpl.tag.tmpl.open.toString().indexOf("__"))return 2}catch(a){}return 1}();this.renderTemplateSource=function(b,e,g){g=g||{};if(2>a)throw Error("Your version of jQuery.tmpl is too old. Please upgrade to jQuery.tmpl 1.0.0pre or later.");var h=b.data("precompiled");h||(h=b.text()||"",h=u.template(null,"{{ko_with $item.koBindingContext}}"+h+
|
||
"{{/ko_with}}"),b.data("precompiled",h));b=[e.$data];e=u.extend({koBindingContext:e},g.templateOptions);e=u.tmpl(h,b,e);e.appendTo(w.createElement("div"));u.fragments={};return e};this.createJavaScriptEvaluatorBlock=function(a){return"{{ko_code ((function() { return "+a+" })()) }}"};this.addTemplate=function(a,b){w.write("<script type='text/html' id='"+a+"'>"+b+"\x3c/script>")};0<a&&(u.tmpl.tag.ko_code={open:"__.push($1 || '');"},u.tmpl.tag.ko_with={open:"with($1) {",close:"} "})};a.Ba.prototype=
|
||
new a.w;var b=new a.Ba;0<b.Rb&&a.La(b);a.b("jqueryTmplTemplateEngine",a.Ba)})()})})();})();
|
||
|
||
/// Knockout Mapping plugin v2.4.1
|
||
/// (c) 2013 Steven Sanderson, Roy Jacobs - http://knockoutjs.com/
|
||
/// License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
||
(function(e){"function"===typeof require&&"object"===typeof exports&&"object"===typeof module?e(require("knockout"),exports):"function"===typeof define&&define.amd?define(["knockout","exports"],e):e(ko,ko.mapping={})})(function(e,f){function y(b,c){var a,d;for(d in c)if(c.hasOwnProperty(d)&&c[d])if(a=f.getType(b[d]),d&&b[d]&&"array"!==a&&"string"!==a)y(b[d],c[d]);else if("array"===f.getType(b[d])&&"array"===f.getType(c[d])){a=b;for(var e=d,l=b[d],n=c[d],t={},g=l.length-1;0<=g;--g)t[l[g]]=l[g];for(g=
|
||
n.length-1;0<=g;--g)t[n[g]]=n[g];l=[];n=void 0;for(n in t)l.push(t[n]);a[e]=l}else b[d]=c[d]}function E(b,c){var a={};y(a,b);y(a,c);return a}function z(b,c){for(var a=E({},b),e=L.length-1;0<=e;e--){var f=L[e];a[f]&&(a[""]instanceof Object||(a[""]={}),a[""][f]=a[f],delete a[f])}c&&(a.ignore=h(c.ignore,a.ignore),a.include=h(c.include,a.include),a.copy=h(c.copy,a.copy),a.observe=h(c.observe,a.observe));a.ignore=h(a.ignore,j.ignore);a.include=h(a.include,j.include);a.copy=h(a.copy,j.copy);a.observe=h(a.observe,
|
||
j.observe);a.mappedProperties=a.mappedProperties||{};a.copiedProperties=a.copiedProperties||{};return a}function h(b,c){"array"!==f.getType(b)&&(b="undefined"===f.getType(b)?[]:[b]);"array"!==f.getType(c)&&(c="undefined"===f.getType(c)?[]:[c]);return e.utils.arrayGetDistinctValues(b.concat(c))}function F(b,c,a,d,k,l,n){var t="array"===f.getType(e.utils.unwrapObservable(c));l=l||"";if(f.isMapped(b)){var g=e.utils.unwrapObservable(b)[p];a=E(g,a)}var j=n||k,h=function(){return a[d]&&a[d].create instanceof
|
||
Function},x=function(b){var f=G,g=e.dependentObservable;e.dependentObservable=function(a,b,c){c=c||{};a&&"object"==typeof a&&(c=a);var d=c.deferEvaluation,M=!1;c.deferEvaluation=!0;a=new H(a,b,c);if(!d){var g=a,d=e.dependentObservable;e.dependentObservable=H;a=e.isWriteableObservable(g);e.dependentObservable=d;d=H({read:function(){M||(e.utils.arrayRemoveItem(f,g),M=!0);return g.apply(g,arguments)},write:a&&function(a){return g(a)},deferEvaluation:!0});d.__DO=g;a=d;f.push(a)}return a};e.dependentObservable.fn=
|
||
H.fn;e.computed=e.dependentObservable;b=e.utils.unwrapObservable(k)instanceof Array?a[d].create({data:b||c,parent:j,skip:N}):a[d].create({data:b||c,parent:j});e.dependentObservable=g;e.computed=e.dependentObservable;return b},u=function(){return a[d]&&a[d].update instanceof Function},v=function(b,f){var g={data:f||c,parent:j,target:e.utils.unwrapObservable(b)};e.isWriteableObservable(b)&&(g.observable=b);return a[d].update(g)};if(n=I.get(c))return n;d=d||"";if(t){var t=[],s=!1,m=function(a){return a};
|
||
a[d]&&a[d].key&&(m=a[d].key,s=!0);e.isObservable(b)||(b=e.observableArray([]),b.mappedRemove=function(a){var c="function"==typeof a?a:function(b){return b===m(a)};return b.remove(function(a){return c(m(a))})},b.mappedRemoveAll=function(a){var c=C(a,m);return b.remove(function(a){return-1!=e.utils.arrayIndexOf(c,m(a))})},b.mappedDestroy=function(a){var c="function"==typeof a?a:function(b){return b===m(a)};return b.destroy(function(a){return c(m(a))})},b.mappedDestroyAll=function(a){var c=C(a,m);return b.destroy(function(a){return-1!=
|
||
e.utils.arrayIndexOf(c,m(a))})},b.mappedIndexOf=function(a){var c=C(b(),m);a=m(a);return e.utils.arrayIndexOf(c,a)},b.mappedGet=function(a){return b()[b.mappedIndexOf(a)]},b.mappedCreate=function(a){if(-1!==b.mappedIndexOf(a))throw Error("There already is an object with the key that you specified.");var c=h()?x(a):a;u()&&(a=v(c,a),e.isWriteableObservable(c)?c(a):c=a);b.push(c);return c});n=C(e.utils.unwrapObservable(b),m).sort();g=C(c,m);s&&g.sort();s=e.utils.compareArrays(n,g);n={};var J,A=e.utils.unwrapObservable(c),
|
||
y={},z=!0,g=0;for(J=A.length;g<J;g++){var r=m(A[g]);if(void 0===r||r instanceof Object){z=!1;break}y[r]=A[g]}var A=[],B=0,g=0;for(J=s.length;g<J;g++){var r=s[g],q,w=l+"["+g+"]";switch(r.status){case "added":var D=z?y[r.value]:K(e.utils.unwrapObservable(c),r.value,m);q=F(void 0,D,a,d,b,w,k);h()||(q=e.utils.unwrapObservable(q));w=O(e.utils.unwrapObservable(c),D,n);q===N?B++:A[w-B]=q;n[w]=!0;break;case "retained":D=z?y[r.value]:K(e.utils.unwrapObservable(c),r.value,m);q=K(b,r.value,m);F(q,D,a,d,b,w,
|
||
k);w=O(e.utils.unwrapObservable(c),D,n);A[w]=q;n[w]=!0;break;case "deleted":q=K(b,r.value,m)}t.push({event:r.status,item:q})}b(A);a[d]&&a[d].arrayChanged&&e.utils.arrayForEach(t,function(b){a[d].arrayChanged(b.event,b.item)})}else if(P(c)){b=e.utils.unwrapObservable(b);if(!b){if(h())return s=x(),u()&&(s=v(s)),s;if(u())return v(s);b={}}u()&&(b=v(b));I.save(c,b);if(u())return b;Q(c,function(d){var f=l.length?l+"."+d:d;if(-1==e.utils.arrayIndexOf(a.ignore,f))if(-1!=e.utils.arrayIndexOf(a.copy,f))b[d]=
|
||
c[d];else if("object"!=typeof c[d]&&"array"!=typeof c[d]&&0<a.observe.length&&-1==e.utils.arrayIndexOf(a.observe,f))b[d]=c[d],a.copiedProperties[f]=!0;else{var g=I.get(c[d]),k=F(b[d],c[d],a,d,b,f,b),g=g||k;if(0<a.observe.length&&-1==e.utils.arrayIndexOf(a.observe,f))b[d]=g(),a.copiedProperties[f]=!0;else{if(e.isWriteableObservable(b[d])){if(g=e.utils.unwrapObservable(g),b[d]()!==g)b[d](g)}else g=void 0===b[d]?g:e.utils.unwrapObservable(g),b[d]=g;a.mappedProperties[f]=!0}}})}else switch(f.getType(c)){case "function":u()?
|
||
e.isWriteableObservable(c)?(c(v(c)),b=c):b=v(c):b=c;break;default:if(e.isWriteableObservable(b))return q=u()?v(b):e.utils.unwrapObservable(c),b(q),q;h()||u();b=h()?x():e.observable(e.utils.unwrapObservable(c));u()&&b(v(b))}return b}function O(b,c,a){for(var d=0,e=b.length;d<e;d++)if(!0!==a[d]&&b[d]===c)return d;return null}function R(b,c){var a;c&&(a=c(b));"undefined"===f.getType(a)&&(a=b);return e.utils.unwrapObservable(a)}function K(b,c,a){b=e.utils.unwrapObservable(b);for(var d=0,f=b.length;d<
|
||
f;d++){var l=b[d];if(R(l,a)===c)return l}throw Error("When calling ko.update*, the key '"+c+"' was not found!");}function C(b,c){return e.utils.arrayMap(e.utils.unwrapObservable(b),function(a){return c?R(a,c):a})}function Q(b,c){if("array"===f.getType(b))for(var a=0;a<b.length;a++)c(a);else for(a in b)c(a)}function P(b){var c=f.getType(b);return("object"===c||"array"===c)&&null!==b}function T(){var b=[],c=[];this.save=function(a,d){var f=e.utils.arrayIndexOf(b,a);0<=f?c[f]=d:(b.push(a),c.push(d))};
|
||
this.get=function(a){a=e.utils.arrayIndexOf(b,a);return 0<=a?c[a]:void 0}}function S(){var b={},c=function(a){var c;try{c=a}catch(e){c="$$$"}a=b[c];void 0===a&&(a=new T,b[c]=a);return a};this.save=function(a,b){c(a).save(a,b)};this.get=function(a){return c(a).get(a)}}var p="__ko_mapping__",H=e.dependentObservable,B=0,G,I,L=["create","update","key","arrayChanged"],N={},x={include:["_destroy"],ignore:[],copy:[],observe:[]},j=x;f.isMapped=function(b){return(b=e.utils.unwrapObservable(b))&&b[p]};f.fromJS=
|
||
function(b){if(0==arguments.length)throw Error("When calling ko.fromJS, pass the object you want to convert.");try{B++||(G=[],I=new S);var c,a;2==arguments.length&&(arguments[1][p]?a=arguments[1]:c=arguments[1]);3==arguments.length&&(c=arguments[1],a=arguments[2]);a&&(c=E(c,a[p]));c=z(c);var d=F(a,b,c);a&&(d=a);if(!--B)for(;G.length;){var e=G.pop();e&&(e(),e.__DO.throttleEvaluation=e.throttleEvaluation)}d[p]=E(d[p],c);return d}catch(f){throw B=0,f;}};f.fromJSON=function(b){var c=e.utils.parseJson(b);
|
||
arguments[0]=c;return f.fromJS.apply(this,arguments)};f.updateFromJS=function(){throw Error("ko.mapping.updateFromJS, use ko.mapping.fromJS instead. Please note that the order of parameters is different!");};f.updateFromJSON=function(){throw Error("ko.mapping.updateFromJSON, use ko.mapping.fromJSON instead. Please note that the order of parameters is different!");};f.toJS=function(b,c){j||f.resetDefaultOptions();if(0==arguments.length)throw Error("When calling ko.mapping.toJS, pass the object you want to convert.");
|
||
if("array"!==f.getType(j.ignore))throw Error("ko.mapping.defaultOptions().ignore should be an array.");if("array"!==f.getType(j.include))throw Error("ko.mapping.defaultOptions().include should be an array.");if("array"!==f.getType(j.copy))throw Error("ko.mapping.defaultOptions().copy should be an array.");c=z(c,b[p]);return f.visitModel(b,function(a){return e.utils.unwrapObservable(a)},c)};f.toJSON=function(b,c){var a=f.toJS(b,c);return e.utils.stringifyJson(a)};f.defaultOptions=function(){if(0<arguments.length)j=
|
||
arguments[0];else return j};f.resetDefaultOptions=function(){j={include:x.include.slice(0),ignore:x.ignore.slice(0),copy:x.copy.slice(0)}};f.getType=function(b){if(b&&"object"===typeof b){if(b.constructor===Date)return"date";if(b.constructor===Array)return"array"}return typeof b};f.visitModel=function(b,c,a){a=a||{};a.visitedObjects=a.visitedObjects||new S;var d,k=e.utils.unwrapObservable(b);if(P(k))a=z(a,k[p]),c(b,a.parentName),d="array"===f.getType(k)?[]:{};else return c(b,a.parentName);a.visitedObjects.save(b,
|
||
d);var l=a.parentName;Q(k,function(b){if(!(a.ignore&&-1!=e.utils.arrayIndexOf(a.ignore,b))){var j=k[b],g=a,h=l||"";"array"===f.getType(k)?l&&(h+="["+b+"]"):(l&&(h+="."),h+=b);g.parentName=h;if(!(-1===e.utils.arrayIndexOf(a.copy,b)&&-1===e.utils.arrayIndexOf(a.include,b)&&k[p]&&k[p].mappedProperties&&!k[p].mappedProperties[b]&&k[p].copiedProperties&&!k[p].copiedProperties[b]&&"array"!==f.getType(k)))switch(f.getType(e.utils.unwrapObservable(j))){case "object":case "array":case "undefined":g=a.visitedObjects.get(j);
|
||
d[b]="undefined"!==f.getType(g)?g:f.visitModel(j,c,a);break;default:d[b]=c(j,a.parentName)}}});return d}});
|
||
|
||
// knockout-sortable 0.8.6 | (c) 2014 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license
|
||
!function(a){"function"==typeof define&&define.amd?define(["knockout","jquery","jquery.ui.sortable"],a):a(window.ko,jQuery)}(function(a,b){var c="ko_sortItem",d="ko_sourceIndex",e="ko_sortList",f="ko_parentList",g="ko_dragItem",h=a.utils.unwrapObservable,i=a.utils.domData.get,j=a.utils.domData.set,k=function(b,d){a.utils.arrayForEach(b,function(a){1===a.nodeType&&(j(a,c,d),j(a,f,i(a.parentNode,e)))})},l=function(b,c){var d,e={},f=h(b())||{};return f.data?(e[c]=f.data,e.name=f.template):e[c]=b(),a.utils.arrayForEach(["afterAdd","afterRender","as","beforeRemove","includeDestroyed","templateEngine","templateOptions"],function(b){e[b]=f[b]||a.bindingHandlers.sortable[b]}),"foreach"===c&&(e.afterRender?(d=e.afterRender,e.afterRender=function(a,b){k.call(b,a,b),d.call(b,a,b)}):e.afterRender=k),e},m=function(a,b){var c=h(b);if(c)for(var d=0;a>d;d++)c[d]&&h(c[d]._destroy)&&a++;return a};a.bindingHandlers.sortable={init:function(k,n,o,p,q){var r,s,t=b(k),u=h(n())||{},v=l(n,"foreach"),w={};t.contents().each(function(){this&&1!==this.nodeType&&k.removeChild(this)}),b.extend(!0,w,a.bindingHandlers.sortable),u.options&&w.options&&(a.utils.extend(w.options,u.options),delete u.options),a.utils.extend(w,u),w.connectClass&&(a.isObservable(w.allowDrop)||"function"==typeof w.allowDrop)?a.computed({read:function(){var b=h(w.allowDrop),c="function"==typeof b?b.call(this,v.foreach):b;a.utils.toggleDomNodeCssClass(k,w.connectClass,c)},disposeWhenNodeIsRemoved:k},this):a.utils.toggleDomNodeCssClass(k,w.connectClass,w.allowDrop),a.bindingHandlers.template.init(k,function(){return v},o,p,q),r=w.options.start,s=w.options.update;var x=setTimeout(function(){var l;t.sortable(a.utils.extend(w.options,{start:function(b,c){var e=c.item[0];j(e,d,a.utils.arrayIndexOf(c.item.parent().children(),e)),c.item.find("input:focus").change(),r&&r.apply(this,arguments)},receive:function(a,b){l=i(b.item[0],g),l&&(l.clone&&(l=l.clone()),w.dragged&&(l=w.dragged.call(this,l,a,b)||l))},update:function(g,h){var k,n,o,p,q,r=h.item[0],t=h.item.parent()[0],u=i(r,c)||l;if(l=null,u&&(this===t||b.contains(this,t))){if(k=i(r,f),o=i(r,d),n=i(r.parentNode,e),p=a.utils.arrayIndexOf(h.item.parent().children(),r),v.includeDestroyed||(o=m(o,k),p=m(p,n)),(w.beforeMove||w.afterMove)&&(q={item:u,sourceParent:k,sourceParentNode:k&&h.sender||r.parentNode,sourceIndex:o,targetParent:n,targetIndex:p,cancelDrop:!1}),w.beforeMove&&(w.beforeMove.call(this,q,g,h),q.cancelDrop))return q.sourceParent?b(q.sourceParent===q.targetParent?this:h.sender).sortable("cancel"):b(r).remove(),void 0;p>=0&&(k&&(k.splice(o,1),a.processAllDeferredBindingUpdates&&a.processAllDeferredBindingUpdates()),n.splice(p,0,u)),j(r,c,null),h.item.remove(),a.processAllDeferredBindingUpdates&&a.processAllDeferredBindingUpdates(),w.afterMove&&w.afterMove.call(this,q,g,h)}s&&s.apply(this,arguments)},connectWith:w.connectClass?"."+w.connectClass:!1})),void 0!==w.isEnabled&&a.computed({read:function(){t.sortable(h(w.isEnabled)?"enable":"disable")},disposeWhenNodeIsRemoved:k})},0);return a.utils.domNodeDisposal.addDisposeCallback(k,function(){(t.data("ui-sortable")||t.data("sortable"))&&t.sortable("destroy"),clearTimeout(x)}),{controlsDescendantBindings:!0}},update:function(b,c,d,f,g){var h=l(c,"foreach");j(b,e,h.foreach),a.bindingHandlers.template.update(b,function(){return h},d,f,g)},connectClass:"ko_container",allowDrop:!0,afterMove:null,beforeMove:null,options:{}},a.bindingHandlers.draggable={init:function(c,d,e,f,i){var k=h(d())||{},m=k.options||{},n=a.utils.extend({},a.bindingHandlers.draggable.options),o=l(d,"data"),p=k.connectClass||a.bindingHandlers.draggable.connectClass,q=void 0!==k.isEnabled?k.isEnabled:a.bindingHandlers.draggable.isEnabled;return k=k.data||k,j(c,g,k),a.utils.extend(n,m),n.connectToSortable=p?"."+p:!1,b(c).draggable(n),void 0!==q&&a.computed({read:function(){b(c).draggable(h(q)?"enable":"disable")},disposeWhenNodeIsRemoved:c}),a.bindingHandlers.template.init(c,function(){return o},e,f,i)},update:function(b,c,d,e,f){var g=l(c,"data");return a.bindingHandlers.template.update(b,function(){return g},d,e,f)},connectClass:a.bindingHandlers.sortable.connectClass,options:{helper:"clone"}}});
|
||
// Underscore.js 1.6.0
|
||
// http://underscorejs.org
|
||
// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||
// Underscore may be freely distributed under the MIT license.
|
||
|
||
(function() {
|
||
|
||
// Baseline setup
|
||
// --------------
|
||
|
||
// Establish the root object, `window` in the browser, or `exports` on the server.
|
||
var root = this;
|
||
|
||
// Save the previous value of the `_` variable.
|
||
var previousUnderscore = root._;
|
||
|
||
// Establish the object that gets returned to break out of a loop iteration.
|
||
var breaker = {};
|
||
|
||
// Save bytes in the minified (but not gzipped) version:
|
||
var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
|
||
|
||
// Create quick reference variables for speed access to core prototypes.
|
||
var
|
||
push = ArrayProto.push,
|
||
slice = ArrayProto.slice,
|
||
concat = ArrayProto.concat,
|
||
toString = ObjProto.toString,
|
||
hasOwnProperty = ObjProto.hasOwnProperty;
|
||
|
||
// All **ECMAScript 5** native function implementations that we hope to use
|
||
// are declared here.
|
||
var
|
||
nativeForEach = ArrayProto.forEach,
|
||
nativeMap = ArrayProto.map,
|
||
nativeReduce = ArrayProto.reduce,
|
||
nativeReduceRight = ArrayProto.reduceRight,
|
||
nativeFilter = ArrayProto.filter,
|
||
nativeEvery = ArrayProto.every,
|
||
nativeSome = ArrayProto.some,
|
||
nativeIndexOf = ArrayProto.indexOf,
|
||
nativeLastIndexOf = ArrayProto.lastIndexOf,
|
||
nativeIsArray = Array.isArray,
|
||
nativeKeys = Object.keys,
|
||
nativeBind = FuncProto.bind;
|
||
|
||
// Create a safe reference to the Underscore object for use below.
|
||
var _ = function(obj) {
|
||
if (obj instanceof _) return obj;
|
||
if (!(this instanceof _)) return new _(obj);
|
||
this._wrapped = obj;
|
||
};
|
||
|
||
// Export the Underscore object for **Node.js**, with
|
||
// backwards-compatibility for the old `require()` API. If we're in
|
||
// the browser, add `_` as a global object via a string identifier,
|
||
// for Closure Compiler "advanced" mode.
|
||
if (typeof exports !== 'undefined') {
|
||
if (typeof module !== 'undefined' && module.exports) {
|
||
exports = module.exports = _;
|
||
}
|
||
exports._ = _;
|
||
} else {
|
||
root._ = _;
|
||
}
|
||
|
||
// Current version.
|
||
_.VERSION = '1.6.0';
|
||
|
||
// Collection Functions
|
||
// --------------------
|
||
|
||
// The cornerstone, an `each` implementation, aka `forEach`.
|
||
// Handles objects with the built-in `forEach`, arrays, and raw objects.
|
||
// Delegates to **ECMAScript 5**'s native `forEach` if available.
|
||
var each = _.each = _.forEach = function(obj, iterator, context) {
|
||
if (obj == null) return obj;
|
||
if (nativeForEach && obj.forEach === nativeForEach) {
|
||
obj.forEach(iterator, context);
|
||
} else if (obj.length === +obj.length) {
|
||
for (var i = 0, length = obj.length; i < length; i++) {
|
||
if (iterator.call(context, obj[i], i, obj) === breaker) return;
|
||
}
|
||
} else {
|
||
var keys = _.keys(obj);
|
||
for (var i = 0, length = keys.length; i < length; i++) {
|
||
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
|
||
}
|
||
}
|
||
return obj;
|
||
};
|
||
|
||
// Return the results of applying the iterator to each element.
|
||
// Delegates to **ECMAScript 5**'s native `map` if available.
|
||
_.map = _.collect = function(obj, iterator, context) {
|
||
var results = [];
|
||
if (obj == null) return results;
|
||
if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
|
||
each(obj, function(value, index, list) {
|
||
results.push(iterator.call(context, value, index, list));
|
||
});
|
||
return results;
|
||
};
|
||
|
||
var reduceError = 'Reduce of empty array with no initial value';
|
||
|
||
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
||
// or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
|
||
_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
|
||
var initial = arguments.length > 2;
|
||
if (obj == null) obj = [];
|
||
if (nativeReduce && obj.reduce === nativeReduce) {
|
||
if (context) iterator = _.bind(iterator, context);
|
||
return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
|
||
}
|
||
each(obj, function(value, index, list) {
|
||
if (!initial) {
|
||
memo = value;
|
||
initial = true;
|
||
} else {
|
||
memo = iterator.call(context, memo, value, index, list);
|
||
}
|
||
});
|
||
if (!initial) throw new TypeError(reduceError);
|
||
return memo;
|
||
};
|
||
|
||
// The right-associative version of reduce, also known as `foldr`.
|
||
// Delegates to **ECMAScript 5**'s native `reduceRight` if available.
|
||
_.reduceRight = _.foldr = function(obj, iterator, memo, context) {
|
||
var initial = arguments.length > 2;
|
||
if (obj == null) obj = [];
|
||
if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
|
||
if (context) iterator = _.bind(iterator, context);
|
||
return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
|
||
}
|
||
var length = obj.length;
|
||
if (length !== +length) {
|
||
var keys = _.keys(obj);
|
||
length = keys.length;
|
||
}
|
||
each(obj, function(value, index, list) {
|
||
index = keys ? keys[--length] : --length;
|
||
if (!initial) {
|
||
memo = obj[index];
|
||
initial = true;
|
||
} else {
|
||
memo = iterator.call(context, memo, obj[index], index, list);
|
||
}
|
||
});
|
||
if (!initial) throw new TypeError(reduceError);
|
||
return memo;
|
||
};
|
||
|
||
// Return the first value which passes a truth test. Aliased as `detect`.
|
||
_.find = _.detect = function(obj, predicate, context) {
|
||
var result;
|
||
any(obj, function(value, index, list) {
|
||
if (predicate.call(context, value, index, list)) {
|
||
result = value;
|
||
return true;
|
||
}
|
||
});
|
||
return result;
|
||
};
|
||
|
||
// Return all the elements that pass a truth test.
|
||
// Delegates to **ECMAScript 5**'s native `filter` if available.
|
||
// Aliased as `select`.
|
||
_.filter = _.select = function(obj, predicate, context) {
|
||
var results = [];
|
||
if (obj == null) return results;
|
||
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
|
||
each(obj, function(value, index, list) {
|
||
if (predicate.call(context, value, index, list)) results.push(value);
|
||
});
|
||
return results;
|
||
};
|
||
|
||
// Return all the elements for which a truth test fails.
|
||
_.reject = function(obj, predicate, context) {
|
||
return _.filter(obj, function(value, index, list) {
|
||
return !predicate.call(context, value, index, list);
|
||
}, context);
|
||
};
|
||
|
||
// Determine whether all of the elements match a truth test.
|
||
// Delegates to **ECMAScript 5**'s native `every` if available.
|
||
// Aliased as `all`.
|
||
_.every = _.all = function(obj, predicate, context) {
|
||
predicate || (predicate = _.identity);
|
||
var result = true;
|
||
if (obj == null) return result;
|
||
if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
|
||
each(obj, function(value, index, list) {
|
||
if (!(result = result && predicate.call(context, value, index, list))) return breaker;
|
||
});
|
||
return !!result;
|
||
};
|
||
|
||
// Determine if at least one element in the object matches a truth test.
|
||
// Delegates to **ECMAScript 5**'s native `some` if available.
|
||
// Aliased as `any`.
|
||
var any = _.some = _.any = function(obj, predicate, context) {
|
||
predicate || (predicate = _.identity);
|
||
var result = false;
|
||
if (obj == null) return result;
|
||
if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
|
||
each(obj, function(value, index, list) {
|
||
if (result || (result = predicate.call(context, value, index, list))) return breaker;
|
||
});
|
||
return !!result;
|
||
};
|
||
|
||
// Determine if the array or object contains a given value (using `===`).
|
||
// Aliased as `include`.
|
||
_.contains = _.include = function(obj, target) {
|
||
if (obj == null) return false;
|
||
if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
|
||
return any(obj, function(value) {
|
||
return value === target;
|
||
});
|
||
};
|
||
|
||
// Invoke a method (with arguments) on every item in a collection.
|
||
_.invoke = function(obj, method) {
|
||
var args = slice.call(arguments, 2);
|
||
var isFunc = _.isFunction(method);
|
||
return _.map(obj, function(value) {
|
||
return (isFunc ? method : value[method]).apply(value, args);
|
||
});
|
||
};
|
||
|
||
// Convenience version of a common use case of `map`: fetching a property.
|
||
_.pluck = function(obj, key) {
|
||
return _.map(obj, _.property(key));
|
||
};
|
||
|
||
// Convenience version of a common use case of `filter`: selecting only objects
|
||
// containing specific `key:value` pairs.
|
||
_.where = function(obj, attrs) {
|
||
return _.filter(obj, _.matches(attrs));
|
||
};
|
||
|
||
// Convenience version of a common use case of `find`: getting the first object
|
||
// containing specific `key:value` pairs.
|
||
_.findWhere = function(obj, attrs) {
|
||
return _.find(obj, _.matches(attrs));
|
||
};
|
||
|
||
// Return the maximum element or (element-based computation).
|
||
// Can't optimize arrays of integers longer than 65,535 elements.
|
||
// See [WebKit Bug 80797](https://bugs.webkit.org/show_bug.cgi?id=80797)
|
||
_.max = function(obj, iterator, context) {
|
||
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
|
||
return Math.max.apply(Math, obj);
|
||
}
|
||
var result = -Infinity, lastComputed = -Infinity;
|
||
each(obj, function(value, index, list) {
|
||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||
if (computed > lastComputed) {
|
||
result = value;
|
||
lastComputed = computed;
|
||
}
|
||
});
|
||
return result;
|
||
};
|
||
|
||
// Return the minimum element (or element-based computation).
|
||
_.min = function(obj, iterator, context) {
|
||
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
|
||
return Math.min.apply(Math, obj);
|
||
}
|
||
var result = Infinity, lastComputed = Infinity;
|
||
each(obj, function(value, index, list) {
|
||
var computed = iterator ? iterator.call(context, value, index, list) : value;
|
||
if (computed < lastComputed) {
|
||
result = value;
|
||
lastComputed = computed;
|
||
}
|
||
});
|
||
return result;
|
||
};
|
||
|
||
// Shuffle an array, using the modern version of the
|
||
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
||
_.shuffle = function(obj) {
|
||
var rand;
|
||
var index = 0;
|
||
var shuffled = [];
|
||
each(obj, function(value) {
|
||
rand = _.random(index++);
|
||
shuffled[index - 1] = shuffled[rand];
|
||
shuffled[rand] = value;
|
||
});
|
||
return shuffled;
|
||
};
|
||
|
||
// Sample **n** random values from a collection.
|
||
// If **n** is not specified, returns a single random element.
|
||
// The internal `guard` argument allows it to work with `map`.
|
||
_.sample = function(obj, n, guard) {
|
||
if (n == null || guard) {
|
||
if (obj.length !== +obj.length) obj = _.values(obj);
|
||
return obj[_.random(obj.length - 1)];
|
||
}
|
||
return _.shuffle(obj).slice(0, Math.max(0, n));
|
||
};
|
||
|
||
// An internal function to generate lookup iterators.
|
||
var lookupIterator = function(value) {
|
||
if (value == null) return _.identity;
|
||
if (_.isFunction(value)) return value;
|
||
return _.property(value);
|
||
};
|
||
|
||
// Sort the object's values by a criterion produced by an iterator.
|
||
_.sortBy = function(obj, iterator, context) {
|
||
iterator = lookupIterator(iterator);
|
||
return _.pluck(_.map(obj, function(value, index, list) {
|
||
return {
|
||
value: value,
|
||
index: index,
|
||
criteria: iterator.call(context, value, index, list)
|
||
};
|
||
}).sort(function(left, right) {
|
||
var a = left.criteria;
|
||
var b = right.criteria;
|
||
if (a !== b) {
|
||
if (a > b || a === void 0) return 1;
|
||
if (a < b || b === void 0) return -1;
|
||
}
|
||
return left.index - right.index;
|
||
}), 'value');
|
||
};
|
||
|
||
// An internal function used for aggregate "group by" operations.
|
||
var group = function(behavior) {
|
||
return function(obj, iterator, context) {
|
||
var result = {};
|
||
iterator = lookupIterator(iterator);
|
||
each(obj, function(value, index) {
|
||
var key = iterator.call(context, value, index, obj);
|
||
behavior(result, key, value);
|
||
});
|
||
return result;
|
||
};
|
||
};
|
||
|
||
// Groups the object's values by a criterion. Pass either a string attribute
|
||
// to group by, or a function that returns the criterion.
|
||
_.groupBy = group(function(result, key, value) {
|
||
_.has(result, key) ? result[key].push(value) : result[key] = [value];
|
||
});
|
||
|
||
// Indexes the object's values by a criterion, similar to `groupBy`, but for
|
||
// when you know that your index values will be unique.
|
||
_.indexBy = group(function(result, key, value) {
|
||
result[key] = value;
|
||
});
|
||
|
||
// Counts instances of an object that group by a certain criterion. Pass
|
||
// either a string attribute to count by, or a function that returns the
|
||
// criterion.
|
||
_.countBy = group(function(result, key) {
|
||
_.has(result, key) ? result[key]++ : result[key] = 1;
|
||
});
|
||
|
||
// Use a comparator function to figure out the smallest index at which
|
||
// an object should be inserted so as to maintain order. Uses binary search.
|
||
_.sortedIndex = function(array, obj, iterator, context) {
|
||
iterator = lookupIterator(iterator);
|
||
var value = iterator.call(context, obj);
|
||
var low = 0, high = array.length;
|
||
while (low < high) {
|
||
var mid = (low + high) >>> 1;
|
||
iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
|
||
}
|
||
return low;
|
||
};
|
||
|
||
// Safely create a real, live array from anything iterable.
|
||
_.toArray = function(obj) {
|
||
if (!obj) return [];
|
||
if (_.isArray(obj)) return slice.call(obj);
|
||
if (obj.length === +obj.length) return _.map(obj, _.identity);
|
||
return _.values(obj);
|
||
};
|
||
|
||
// Return the number of elements in an object.
|
||
_.size = function(obj) {
|
||
if (obj == null) return 0;
|
||
return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
|
||
};
|
||
|
||
// Array Functions
|
||
// ---------------
|
||
|
||
// Get the first element of an array. Passing **n** will return the first N
|
||
// values in the array. Aliased as `head` and `take`. The **guard** check
|
||
// allows it to work with `_.map`.
|
||
_.first = _.head = _.take = function(array, n, guard) {
|
||
if (array == null) return void 0;
|
||
if ((n == null) || guard) return array[0];
|
||
if (n < 0) return [];
|
||
return slice.call(array, 0, n);
|
||
};
|
||
|
||
// Returns everything but the last entry of the array. Especially useful on
|
||
// the arguments object. Passing **n** will return all the values in
|
||
// the array, excluding the last N. The **guard** check allows it to work with
|
||
// `_.map`.
|
||
_.initial = function(array, n, guard) {
|
||
return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
|
||
};
|
||
|
||
// Get the last element of an array. Passing **n** will return the last N
|
||
// values in the array. The **guard** check allows it to work with `_.map`.
|
||
_.last = function(array, n, guard) {
|
||
if (array == null) return void 0;
|
||
if ((n == null) || guard) return array[array.length - 1];
|
||
return slice.call(array, Math.max(array.length - n, 0));
|
||
};
|
||
|
||
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
|
||
// Especially useful on the arguments object. Passing an **n** will return
|
||
// the rest N values in the array. The **guard**
|
||
// check allows it to work with `_.map`.
|
||
_.rest = _.tail = _.drop = function(array, n, guard) {
|
||
return slice.call(array, (n == null) || guard ? 1 : n);
|
||
};
|
||
|
||
// Trim out all falsy values from an array.
|
||
_.compact = function(array) {
|
||
return _.filter(array, _.identity);
|
||
};
|
||
|
||
// Internal implementation of a recursive `flatten` function.
|
||
var flatten = function(input, shallow, output) {
|
||
if (shallow && _.every(input, _.isArray)) {
|
||
return concat.apply(output, input);
|
||
}
|
||
each(input, function(value) {
|
||
if (_.isArray(value) || _.isArguments(value)) {
|
||
shallow ? push.apply(output, value) : flatten(value, shallow, output);
|
||
} else {
|
||
output.push(value);
|
||
}
|
||
});
|
||
return output;
|
||
};
|
||
|
||
// Flatten out an array, either recursively (by default), or just one level.
|
||
_.flatten = function(array, shallow) {
|
||
return flatten(array, shallow, []);
|
||
};
|
||
|
||
// Return a version of the array that does not contain the specified value(s).
|
||
_.without = function(array) {
|
||
return _.difference(array, slice.call(arguments, 1));
|
||
};
|
||
|
||
// Split an array into two arrays: one whose elements all satisfy the given
|
||
// predicate, and one whose elements all do not satisfy the predicate.
|
||
_.partition = function(array, predicate) {
|
||
var pass = [], fail = [];
|
||
each(array, function(elem) {
|
||
(predicate(elem) ? pass : fail).push(elem);
|
||
});
|
||
return [pass, fail];
|
||
};
|
||
|
||
// Produce a duplicate-free version of the array. If the array has already
|
||
// been sorted, you have the option of using a faster algorithm.
|
||
// Aliased as `unique`.
|
||
_.uniq = _.unique = function(array, isSorted, iterator, context) {
|
||
if (_.isFunction(isSorted)) {
|
||
context = iterator;
|
||
iterator = isSorted;
|
||
isSorted = false;
|
||
}
|
||
var initial = iterator ? _.map(array, iterator, context) : array;
|
||
var results = [];
|
||
var seen = [];
|
||
each(initial, function(value, index) {
|
||
if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
|
||
seen.push(value);
|
||
results.push(array[index]);
|
||
}
|
||
});
|
||
return results;
|
||
};
|
||
|
||
// Produce an array that contains the union: each distinct element from all of
|
||
// the passed-in arrays.
|
||
_.union = function() {
|
||
return _.uniq(_.flatten(arguments, true));
|
||
};
|
||
|
||
// Produce an array that contains every item shared between all the
|
||
// passed-in arrays.
|
||
_.intersection = function(array) {
|
||
var rest = slice.call(arguments, 1);
|
||
return _.filter(_.uniq(array), function(item) {
|
||
return _.every(rest, function(other) {
|
||
return _.contains(other, item);
|
||
});
|
||
});
|
||
};
|
||
|
||
// Take the difference between one array and a number of other arrays.
|
||
// Only the elements present in just the first array will remain.
|
||
_.difference = function(array) {
|
||
var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
|
||
return _.filter(array, function(value){ return !_.contains(rest, value); });
|
||
};
|
||
|
||
// Zip together multiple lists into a single array -- elements that share
|
||
// an index go together.
|
||
_.zip = function() {
|
||
var length = _.max(_.pluck(arguments, 'length').concat(0));
|
||
var results = new Array(length);
|
||
for (var i = 0; i < length; i++) {
|
||
results[i] = _.pluck(arguments, '' + i);
|
||
}
|
||
return results;
|
||
};
|
||
|
||
// Converts lists into objects. Pass either a single array of `[key, value]`
|
||
// pairs, or two parallel arrays of the same length -- one of keys, and one of
|
||
// the corresponding values.
|
||
_.object = function(list, values) {
|
||
if (list == null) return {};
|
||
var result = {};
|
||
for (var i = 0, length = list.length; i < length; i++) {
|
||
if (values) {
|
||
result[list[i]] = values[i];
|
||
} else {
|
||
result[list[i][0]] = list[i][1];
|
||
}
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
|
||
// we need this function. Return the position of the first occurrence of an
|
||
// item in an array, or -1 if the item is not included in the array.
|
||
// Delegates to **ECMAScript 5**'s native `indexOf` if available.
|
||
// If the array is large and already in sort order, pass `true`
|
||
// for **isSorted** to use binary search.
|
||
_.indexOf = function(array, item, isSorted) {
|
||
if (array == null) return -1;
|
||
var i = 0, length = array.length;
|
||
if (isSorted) {
|
||
if (typeof isSorted == 'number') {
|
||
i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
|
||
} else {
|
||
i = _.sortedIndex(array, item);
|
||
return array[i] === item ? i : -1;
|
||
}
|
||
}
|
||
if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
|
||
for (; i < length; i++) if (array[i] === item) return i;
|
||
return -1;
|
||
};
|
||
|
||
// Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
|
||
_.lastIndexOf = function(array, item, from) {
|
||
if (array == null) return -1;
|
||
var hasIndex = from != null;
|
||
if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
|
||
return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
|
||
}
|
||
var i = (hasIndex ? from : array.length);
|
||
while (i--) if (array[i] === item) return i;
|
||
return -1;
|
||
};
|
||
|
||
// Generate an integer Array containing an arithmetic progression. A port of
|
||
// the native Python `range()` function. See
|
||
// [the Python documentation](http://docs.python.org/library/functions.html#range).
|
||
_.range = function(start, stop, step) {
|
||
if (arguments.length <= 1) {
|
||
stop = start || 0;
|
||
start = 0;
|
||
}
|
||
step = arguments[2] || 1;
|
||
|
||
var length = Math.max(Math.ceil((stop - start) / step), 0);
|
||
var idx = 0;
|
||
var range = new Array(length);
|
||
|
||
while(idx < length) {
|
||
range[idx++] = start;
|
||
start += step;
|
||
}
|
||
|
||
return range;
|
||
};
|
||
|
||
// Function (ahem) Functions
|
||
// ------------------
|
||
|
||
// Reusable constructor function for prototype setting.
|
||
var ctor = function(){};
|
||
|
||
// Create a function bound to a given object (assigning `this`, and arguments,
|
||
// optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
|
||
// available.
|
||
_.bind = function(func, context) {
|
||
var args, bound;
|
||
if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
|
||
if (!_.isFunction(func)) throw new TypeError;
|
||
args = slice.call(arguments, 2);
|
||
return bound = function() {
|
||
if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
|
||
ctor.prototype = func.prototype;
|
||
var self = new ctor;
|
||
ctor.prototype = null;
|
||
var result = func.apply(self, args.concat(slice.call(arguments)));
|
||
if (Object(result) === result) return result;
|
||
return self;
|
||
};
|
||
};
|
||
|
||
// Partially apply a function by creating a version that has had some of its
|
||
// arguments pre-filled, without changing its dynamic `this` context. _ acts
|
||
// as a placeholder, allowing any combination of arguments to be pre-filled.
|
||
_.partial = function(func) {
|
||
var boundArgs = slice.call(arguments, 1);
|
||
return function() {
|
||
var position = 0;
|
||
var args = boundArgs.slice();
|
||
for (var i = 0, length = args.length; i < length; i++) {
|
||
if (args[i] === _) args[i] = arguments[position++];
|
||
}
|
||
while (position < arguments.length) args.push(arguments[position++]);
|
||
return func.apply(this, args);
|
||
};
|
||
};
|
||
|
||
// Bind a number of an object's methods to that object. Remaining arguments
|
||
// are the method names to be bound. Useful for ensuring that all callbacks
|
||
// defined on an object belong to it.
|
||
_.bindAll = function(obj) {
|
||
var funcs = slice.call(arguments, 1);
|
||
if (funcs.length === 0) throw new Error('bindAll must be passed function names');
|
||
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
|
||
return obj;
|
||
};
|
||
|
||
// Memoize an expensive function by storing its results.
|
||
_.memoize = function(func, hasher) {
|
||
var memo = {};
|
||
hasher || (hasher = _.identity);
|
||
return function() {
|
||
var key = hasher.apply(this, arguments);
|
||
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
|
||
};
|
||
};
|
||
|
||
// Delays a function for the given number of milliseconds, and then calls
|
||
// it with the arguments supplied.
|
||
_.delay = function(func, wait) {
|
||
var args = slice.call(arguments, 2);
|
||
return setTimeout(function(){ return func.apply(null, args); }, wait);
|
||
};
|
||
|
||
// Defers a function, scheduling it to run after the current call stack has
|
||
// cleared.
|
||
_.defer = function(func) {
|
||
return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
|
||
};
|
||
|
||
// Returns a function, that, when invoked, will only be triggered at most once
|
||
// during a given window of time. Normally, the throttled function will run
|
||
// as much as it can, without ever going more than once per `wait` duration;
|
||
// but if you'd like to disable the execution on the leading edge, pass
|
||
// `{leading: false}`. To disable execution on the trailing edge, ditto.
|
||
_.throttle = function(func, wait, options) {
|
||
var context, args, result;
|
||
var timeout = null;
|
||
var previous = 0;
|
||
options || (options = {});
|
||
var later = function() {
|
||
previous = options.leading === false ? 0 : _.now();
|
||
timeout = null;
|
||
result = func.apply(context, args);
|
||
context = args = null;
|
||
};
|
||
return function() {
|
||
var now = _.now();
|
||
if (!previous && options.leading === false) previous = now;
|
||
var remaining = wait - (now - previous);
|
||
context = this;
|
||
args = arguments;
|
||
if (remaining <= 0) {
|
||
clearTimeout(timeout);
|
||
timeout = null;
|
||
previous = now;
|
||
result = func.apply(context, args);
|
||
context = args = null;
|
||
} else if (!timeout && options.trailing !== false) {
|
||
timeout = setTimeout(later, remaining);
|
||
}
|
||
return result;
|
||
};
|
||
};
|
||
|
||
// Returns a function, that, as long as it continues to be invoked, will not
|
||
// be triggered. The function will be called after it stops being called for
|
||
// N milliseconds. If `immediate` is passed, trigger the function on the
|
||
// leading edge, instead of the trailing.
|
||
_.debounce = function(func, wait, immediate) {
|
||
var timeout, args, context, timestamp, result;
|
||
|
||
var later = function() {
|
||
var last = _.now() - timestamp;
|
||
if (last < wait) {
|
||
timeout = setTimeout(later, wait - last);
|
||
} else {
|
||
timeout = null;
|
||
if (!immediate) {
|
||
result = func.apply(context, args);
|
||
context = args = null;
|
||
}
|
||
}
|
||
};
|
||
|
||
return function() {
|
||
context = this;
|
||
args = arguments;
|
||
timestamp = _.now();
|
||
var callNow = immediate && !timeout;
|
||
if (!timeout) {
|
||
timeout = setTimeout(later, wait);
|
||
}
|
||
if (callNow) {
|
||
result = func.apply(context, args);
|
||
context = args = null;
|
||
}
|
||
|
||
return result;
|
||
};
|
||
};
|
||
|
||
// Returns a function that will be executed at most one time, no matter how
|
||
// often you call it. Useful for lazy initialization.
|
||
_.once = function(func) {
|
||
var ran = false, memo;
|
||
return function() {
|
||
if (ran) return memo;
|
||
ran = true;
|
||
memo = func.apply(this, arguments);
|
||
func = null;
|
||
return memo;
|
||
};
|
||
};
|
||
|
||
// Returns the first function passed as an argument to the second,
|
||
// allowing you to adjust arguments, run code before and after, and
|
||
// conditionally execute the original function.
|
||
_.wrap = function(func, wrapper) {
|
||
return _.partial(wrapper, func);
|
||
};
|
||
|
||
// Returns a function that is the composition of a list of functions, each
|
||
// consuming the return value of the function that follows.
|
||
_.compose = function() {
|
||
var funcs = arguments;
|
||
return function() {
|
||
var args = arguments;
|
||
for (var i = funcs.length - 1; i >= 0; i--) {
|
||
args = [funcs[i].apply(this, args)];
|
||
}
|
||
return args[0];
|
||
};
|
||
};
|
||
|
||
// Returns a function that will only be executed after being called N times.
|
||
_.after = function(times, func) {
|
||
return function() {
|
||
if (--times < 1) {
|
||
return func.apply(this, arguments);
|
||
}
|
||
};
|
||
};
|
||
|
||
// Object Functions
|
||
// ----------------
|
||
|
||
// Retrieve the names of an object's properties.
|
||
// Delegates to **ECMAScript 5**'s native `Object.keys`
|
||
_.keys = function(obj) {
|
||
if (!_.isObject(obj)) return [];
|
||
if (nativeKeys) return nativeKeys(obj);
|
||
var keys = [];
|
||
for (var key in obj) if (_.has(obj, key)) keys.push(key);
|
||
return keys;
|
||
};
|
||
|
||
// Retrieve the values of an object's properties.
|
||
_.values = function(obj) {
|
||
var keys = _.keys(obj);
|
||
var length = keys.length;
|
||
var values = new Array(length);
|
||
for (var i = 0; i < length; i++) {
|
||
values[i] = obj[keys[i]];
|
||
}
|
||
return values;
|
||
};
|
||
|
||
// Convert an object into a list of `[key, value]` pairs.
|
||
_.pairs = function(obj) {
|
||
var keys = _.keys(obj);
|
||
var length = keys.length;
|
||
var pairs = new Array(length);
|
||
for (var i = 0; i < length; i++) {
|
||
pairs[i] = [keys[i], obj[keys[i]]];
|
||
}
|
||
return pairs;
|
||
};
|
||
|
||
// Invert the keys and values of an object. The values must be serializable.
|
||
_.invert = function(obj) {
|
||
var result = {};
|
||
var keys = _.keys(obj);
|
||
for (var i = 0, length = keys.length; i < length; i++) {
|
||
result[obj[keys[i]]] = keys[i];
|
||
}
|
||
return result;
|
||
};
|
||
|
||
// Return a sorted list of the function names available on the object.
|
||
// Aliased as `methods`
|
||
_.functions = _.methods = function(obj) {
|
||
var names = [];
|
||
for (var key in obj) {
|
||
if (_.isFunction(obj[key])) names.push(key);
|
||
}
|
||
return names.sort();
|
||
};
|
||
|
||
// Extend a given object with all the properties in passed-in object(s).
|
||
_.extend = function(obj) {
|
||
each(slice.call(arguments, 1), function(source) {
|
||
if (source) {
|
||
for (var prop in source) {
|
||
obj[prop] = source[prop];
|
||
}
|
||
}
|
||
});
|
||
return obj;
|
||
};
|
||
|
||
// Return a copy of the object only containing the whitelisted properties.
|
||
_.pick = function(obj) {
|
||
var copy = {};
|
||
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
|
||
each(keys, function(key) {
|
||
if (key in obj) copy[key] = obj[key];
|
||
});
|
||
return copy;
|
||
};
|
||
|
||
// Return a copy of the object without the blacklisted properties.
|
||
_.omit = function(obj) {
|
||
var copy = {};
|
||
var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
|
||
for (var key in obj) {
|
||
if (!_.contains(keys, key)) copy[key] = obj[key];
|
||
}
|
||
return copy;
|
||
};
|
||
|
||
// Fill in a given object with default properties.
|
||
_.defaults = function(obj) {
|
||
each(slice.call(arguments, 1), function(source) {
|
||
if (source) {
|
||
for (var prop in source) {
|
||
if (obj[prop] === void 0) obj[prop] = source[prop];
|
||
}
|
||
}
|
||
});
|
||
return obj;
|
||
};
|
||
|
||
// Create a (shallow-cloned) duplicate of an object.
|
||
_.clone = function(obj) {
|
||
if (!_.isObject(obj)) return obj;
|
||
return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
|
||
};
|
||
|
||
// Invokes interceptor with the obj, and then returns obj.
|
||
// The primary purpose of this method is to "tap into" a method chain, in
|
||
// order to perform operations on intermediate results within the chain.
|
||
_.tap = function(obj, interceptor) {
|
||
interceptor(obj);
|
||
return obj;
|
||
};
|
||
|
||
// Internal recursive comparison function for `isEqual`.
|
||
var eq = function(a, b, aStack, bStack) {
|
||
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
|
||
if (a === b) return a !== 0 || 1 / a == 1 / b;
|
||
// A strict comparison is necessary because `null == undefined`.
|
||
if (a == null || b == null) return a === b;
|
||
// Unwrap any wrapped objects.
|
||
if (a instanceof _) a = a._wrapped;
|
||
if (b instanceof _) b = b._wrapped;
|
||
// Compare `[[Class]]` names.
|
||
var className = toString.call(a);
|
||
if (className != toString.call(b)) return false;
|
||
switch (className) {
|
||
// Strings, numbers, dates, and booleans are compared by value.
|
||
case '[object String]':
|
||
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
||
// equivalent to `new String("5")`.
|
||
return a == String(b);
|
||
case '[object Number]':
|
||
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
|
||
// other numeric values.
|
||
return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
|
||
case '[object Date]':
|
||
case '[object Boolean]':
|
||
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
||
// millisecond representations. Note that invalid dates with millisecond representations
|
||
// of `NaN` are not equivalent.
|
||
return +a == +b;
|
||
// RegExps are compared by their source patterns and flags.
|
||
case '[object RegExp]':
|
||
return a.source == b.source &&
|
||
a.global == b.global &&
|
||
a.multiline == b.multiline &&
|
||
a.ignoreCase == b.ignoreCase;
|
||
}
|
||
if (typeof a != 'object' || typeof b != 'object') return false;
|
||
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
||
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
||
var length = aStack.length;
|
||
while (length--) {
|
||
// Linear search. Performance is inversely proportional to the number of
|
||
// unique nested structures.
|
||
if (aStack[length] == a) return bStack[length] == b;
|
||
}
|
||
// Objects with different constructors are not equivalent, but `Object`s
|
||
// from different frames are.
|
||
var aCtor = a.constructor, bCtor = b.constructor;
|
||
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
|
||
_.isFunction(bCtor) && (bCtor instanceof bCtor))
|
||
&& ('constructor' in a && 'constructor' in b)) {
|
||
return false;
|
||
}
|
||
// Add the first object to the stack of traversed objects.
|
||
aStack.push(a);
|
||
bStack.push(b);
|
||
var size = 0, result = true;
|
||
// Recursively compare objects and arrays.
|
||
if (className == '[object Array]') {
|
||
// Compare array lengths to determine if a deep comparison is necessary.
|
||
size = a.length;
|
||
result = size == b.length;
|
||
if (result) {
|
||
// Deep compare the contents, ignoring non-numeric properties.
|
||
while (size--) {
|
||
if (!(result = eq(a[size], b[size], aStack, bStack))) break;
|
||
}
|
||
}
|
||
} else {
|
||
// Deep compare objects.
|
||
for (var key in a) {
|
||
if (_.has(a, key)) {
|
||
// Count the expected number of properties.
|
||
size++;
|
||
// Deep compare each member.
|
||
if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
|
||
}
|
||
}
|
||
// Ensure that both objects contain the same number of properties.
|
||
if (result) {
|
||
for (key in b) {
|
||
if (_.has(b, key) && !(size--)) break;
|
||
}
|
||
result = !size;
|
||
}
|
||
}
|
||
// Remove the first object from the stack of traversed objects.
|
||
aStack.pop();
|
||
bStack.pop();
|
||
return result;
|
||
};
|
||
|
||
// Perform a deep comparison to check if two objects are equal.
|
||
_.isEqual = function(a, b) {
|
||
return eq(a, b, [], []);
|
||
};
|
||
|
||
// Is a given array, string, or object empty?
|
||
// An "empty" object has no enumerable own-properties.
|
||
_.isEmpty = function(obj) {
|
||
if (obj == null) return true;
|
||
if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
|
||
for (var key in obj) if (_.has(obj, key)) return false;
|
||
return true;
|
||
};
|
||
|
||
// Is a given value a DOM element?
|
||
_.isElement = function(obj) {
|
||
return !!(obj && obj.nodeType === 1);
|
||
};
|
||
|
||
// Is a given value an array?
|
||
// Delegates to ECMA5's native Array.isArray
|
||
_.isArray = nativeIsArray || function(obj) {
|
||
return toString.call(obj) == '[object Array]';
|
||
};
|
||
|
||
// Is a given variable an object?
|
||
_.isObject = function(obj) {
|
||
return obj === Object(obj);
|
||
};
|
||
|
||
// Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
|
||
each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
|
||
_['is' + name] = function(obj) {
|
||
return toString.call(obj) == '[object ' + name + ']';
|
||
};
|
||
});
|
||
|
||
// Define a fallback version of the method in browsers (ahem, IE), where
|
||
// there isn't any inspectable "Arguments" type.
|
||
if (!_.isArguments(arguments)) {
|
||
_.isArguments = function(obj) {
|
||
return !!(obj && _.has(obj, 'callee'));
|
||
};
|
||
}
|
||
|
||
// Optimize `isFunction` if appropriate.
|
||
if (typeof (/./) !== 'function') {
|
||
_.isFunction = function(obj) {
|
||
return typeof obj === 'function';
|
||
};
|
||
}
|
||
|
||
// Is a given object a finite number?
|
||
_.isFinite = function(obj) {
|
||
return isFinite(obj) && !isNaN(parseFloat(obj));
|
||
};
|
||
|
||
// Is the given value `NaN`? (NaN is the only number which does not equal itself).
|
||
_.isNaN = function(obj) {
|
||
return _.isNumber(obj) && obj != +obj;
|
||
};
|
||
|
||
// Is a given value a boolean?
|
||
_.isBoolean = function(obj) {
|
||
return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
|
||
};
|
||
|
||
// Is a given value equal to null?
|
||
_.isNull = function(obj) {
|
||
return obj === null;
|
||
};
|
||
|
||
// Is a given variable undefined?
|
||
_.isUndefined = function(obj) {
|
||
return obj === void 0;
|
||
};
|
||
|
||
// Shortcut function for checking if an object has a given property directly
|
||
// on itself (in other words, not on a prototype).
|
||
_.has = function(obj, key) {
|
||
return hasOwnProperty.call(obj, key);
|
||
};
|
||
|
||
// Utility Functions
|
||
// -----------------
|
||
|
||
// Run Underscore.js in *noConflict* mode, returning the `_` variable to its
|
||
// previous owner. Returns a reference to the Underscore object.
|
||
_.noConflict = function() {
|
||
root._ = previousUnderscore;
|
||
return this;
|
||
};
|
||
|
||
// Keep the identity function around for default iterators.
|
||
_.identity = function(value) {
|
||
return value;
|
||
};
|
||
|
||
_.constant = function(value) {
|
||
return function () {
|
||
return value;
|
||
};
|
||
};
|
||
|
||
_.property = function(key) {
|
||
return function(obj) {
|
||
return obj[key];
|
||
};
|
||
};
|
||
|
||
// Returns a predicate for checking whether an object has a given set of `key:value` pairs.
|
||
_.matches = function(attrs) {
|
||
return function(obj) {
|
||
if (obj === attrs) return true; //avoid comparing an object to itself.
|
||
for (var key in attrs) {
|
||
if (attrs[key] !== obj[key])
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
};
|
||
|
||
// Run a function **n** times.
|
||
_.times = function(n, iterator, context) {
|
||
var accum = Array(Math.max(0, n));
|
||
for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
|
||
return accum;
|
||
};
|
||
|
||
// Return a random integer between min and max (inclusive).
|
||
_.random = function(min, max) {
|
||
if (max == null) {
|
||
max = min;
|
||
min = 0;
|
||
}
|
||
return min + Math.floor(Math.random() * (max - min + 1));
|
||
};
|
||
|
||
// A (possibly faster) way to get the current timestamp as an integer.
|
||
_.now = Date.now || function() { return new Date().getTime(); };
|
||
|
||
// List of HTML entities for escaping.
|
||
var entityMap = {
|
||
escape: {
|
||
'&': '&',
|
||
'<': '<',
|
||
'>': '>',
|
||
'"': '"',
|
||
"'": '''
|
||
}
|
||
};
|
||
entityMap.unescape = _.invert(entityMap.escape);
|
||
|
||
// Regexes containing the keys and values listed immediately above.
|
||
var entityRegexes = {
|
||
escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
|
||
unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
|
||
};
|
||
|
||
// Functions for escaping and unescaping strings to/from HTML interpolation.
|
||
_.each(['escape', 'unescape'], function(method) {
|
||
_[method] = function(string) {
|
||
if (string == null) return '';
|
||
return ('' + string).replace(entityRegexes[method], function(match) {
|
||
return entityMap[method][match];
|
||
});
|
||
};
|
||
});
|
||
|
||
// If the value of the named `property` is a function then invoke it with the
|
||
// `object` as context; otherwise, return it.
|
||
_.result = function(object, property) {
|
||
if (object == null) return void 0;
|
||
var value = object[property];
|
||
return _.isFunction(value) ? value.call(object) : value;
|
||
};
|
||
|
||
// Add your own custom functions to the Underscore object.
|
||
_.mixin = function(obj) {
|
||
each(_.functions(obj), function(name) {
|
||
var func = _[name] = obj[name];
|
||
_.prototype[name] = function() {
|
||
var args = [this._wrapped];
|
||
push.apply(args, arguments);
|
||
return result.call(this, func.apply(_, args));
|
||
};
|
||
});
|
||
};
|
||
|
||
// Generate a unique integer id (unique within the entire client session).
|
||
// Useful for temporary DOM ids.
|
||
var idCounter = 0;
|
||
_.uniqueId = function(prefix) {
|
||
var id = ++idCounter + '';
|
||
return prefix ? prefix + id : id;
|
||
};
|
||
|
||
// By default, Underscore uses ERB-style template delimiters, change the
|
||
// following template settings to use alternative delimiters.
|
||
_.templateSettings = {
|
||
evaluate : /<%([\s\S]+?)%>/g,
|
||
interpolate : /<%=([\s\S]+?)%>/g,
|
||
escape : /<%-([\s\S]+?)%>/g
|
||
};
|
||
|
||
// When customizing `templateSettings`, if you don't want to define an
|
||
// interpolation, evaluation or escaping regex, we need one that is
|
||
// guaranteed not to match.
|
||
var noMatch = /(.)^/;
|
||
|
||
// Certain characters need to be escaped so that they can be put into a
|
||
// string literal.
|
||
var escapes = {
|
||
"'": "'",
|
||
'\\': '\\',
|
||
'\r': 'r',
|
||
'\n': 'n',
|
||
'\t': 't',
|
||
'\u2028': 'u2028',
|
||
'\u2029': 'u2029'
|
||
};
|
||
|
||
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
|
||
|
||
// JavaScript micro-templating, similar to John Resig's implementation.
|
||
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
||
// and correctly escapes quotes within interpolated code.
|
||
_.template = function(text, data, settings) {
|
||
var render;
|
||
settings = _.defaults({}, settings, _.templateSettings);
|
||
|
||
// Combine delimiters into one regular expression via alternation.
|
||
var matcher = new RegExp([
|
||
(settings.escape || noMatch).source,
|
||
(settings.interpolate || noMatch).source,
|
||
(settings.evaluate || noMatch).source
|
||
].join('|') + '|$', 'g');
|
||
|
||
// Compile the template source, escaping string literals appropriately.
|
||
var index = 0;
|
||
var source = "__p+='";
|
||
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
|
||
source += text.slice(index, offset)
|
||
.replace(escaper, function(match) { return '\\' + escapes[match]; });
|
||
|
||
if (escape) {
|
||
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
||
}
|
||
if (interpolate) {
|
||
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
||
}
|
||
if (evaluate) {
|
||
source += "';\n" + evaluate + "\n__p+='";
|
||
}
|
||
index = offset + match.length;
|
||
return match;
|
||
});
|
||
source += "';\n";
|
||
|
||
// If a variable is not specified, place data values in local scope.
|
||
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
|
||
|
||
source = "var __t,__p='',__j=Array.prototype.join," +
|
||
"print=function(){__p+=__j.call(arguments,'');};\n" +
|
||
source + "return __p;\n";
|
||
|
||
try {
|
||
render = new Function(settings.variable || 'obj', '_', source);
|
||
} catch (e) {
|
||
e.source = source;
|
||
throw e;
|
||
}
|
||
|
||
if (data) return render(data, _);
|
||
var template = function(data) {
|
||
return render.call(this, data, _);
|
||
};
|
||
|
||
// Provide the compiled function source as a convenience for precompilation.
|
||
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
|
||
|
||
return template;
|
||
};
|
||
|
||
// Add a "chain" function, which will delegate to the wrapper.
|
||
_.chain = function(obj) {
|
||
return _(obj).chain();
|
||
};
|
||
|
||
// OOP
|
||
// ---------------
|
||
// If Underscore is called as a function, it returns a wrapped object that
|
||
// can be used OO-style. This wrapper holds altered versions of all the
|
||
// underscore functions. Wrapped objects may be chained.
|
||
|
||
// Helper function to continue chaining intermediate results.
|
||
var result = function(obj) {
|
||
return this._chain ? _(obj).chain() : obj;
|
||
};
|
||
|
||
// Add all of the Underscore functions to the wrapper object.
|
||
_.mixin(_);
|
||
|
||
// Add all mutator Array functions to the wrapper.
|
||
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
|
||
var method = ArrayProto[name];
|
||
_.prototype[name] = function() {
|
||
var obj = this._wrapped;
|
||
method.apply(obj, arguments);
|
||
if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
|
||
return result.call(this, obj);
|
||
};
|
||
});
|
||
|
||
// Add all accessor Array functions to the wrapper.
|
||
each(['concat', 'join', 'slice'], function(name) {
|
||
var method = ArrayProto[name];
|
||
_.prototype[name] = function() {
|
||
return result.call(this, method.apply(this._wrapped, arguments));
|
||
};
|
||
});
|
||
|
||
_.extend(_.prototype, {
|
||
|
||
// Start chaining a wrapped Underscore object.
|
||
chain: function() {
|
||
this._chain = true;
|
||
return this;
|
||
},
|
||
|
||
// Extracts the result from a wrapped and chained object.
|
||
value: function() {
|
||
return this._wrapped;
|
||
}
|
||
|
||
});
|
||
|
||
// AMD registration happens at the end for compatibility with AMD loaders
|
||
// that may not enforce next-turn semantics on modules. Even though general
|
||
// practice for AMD registration is to be anonymous, underscore registers
|
||
// as a named module because, like jQuery, it is a base library that is
|
||
// popular enough to be bundled in a third party lib, but not be part of
|
||
// an AMD load request. Those cases could generate an error when an
|
||
// anonymous define() is called outside of a loader request.
|
||
if (typeof define === 'function' && define.amd) {
|
||
define('underscore', [], function() {
|
||
return _;
|
||
});
|
||
}
|
||
}).call(this);
|
||
|
||
/* =========================================================
|
||
* bootstrap-datepicker.js
|
||
* Repo: https://github.com/eternicode/bootstrap-datepicker/
|
||
* Demo: http://eternicode.github.io/bootstrap-datepicker/
|
||
* Docs: http://bootstrap-datepicker.readthedocs.org/
|
||
* Forked from http://www.eyecon.ro/bootstrap-datepicker
|
||
* =========================================================
|
||
* Started by Stefan Petre; improvements by Andrew Rowls + contributors
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
* ========================================================= */
|
||
|
||
(function($, undefined){
|
||
|
||
var $window = $(window);
|
||
|
||
function UTCDate(){
|
||
return new Date(Date.UTC.apply(Date, arguments));
|
||
}
|
||
function UTCToday(){
|
||
var today = new Date();
|
||
return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
|
||
}
|
||
function alias(method){
|
||
return function(){
|
||
return this[method].apply(this, arguments);
|
||
};
|
||
}
|
||
|
||
var DateArray = (function(){
|
||
var extras = {
|
||
get: function(i){
|
||
return this.slice(i)[0];
|
||
},
|
||
contains: function(d){
|
||
// Array.indexOf is not cross-browser;
|
||
// $.inArray doesn't work with Dates
|
||
var val = d && d.valueOf();
|
||
for (var i=0, l=this.length; i < l; i++)
|
||
if (this[i].valueOf() === val)
|
||
return i;
|
||
return -1;
|
||
},
|
||
remove: function(i){
|
||
this.splice(i,1);
|
||
},
|
||
replace: function(new_array){
|
||
if (!new_array)
|
||
return;
|
||
if (!$.isArray(new_array))
|
||
new_array = [new_array];
|
||
this.clear();
|
||
this.push.apply(this, new_array);
|
||
},
|
||
clear: function(){
|
||
this.splice(0);
|
||
},
|
||
copy: function(){
|
||
var a = new DateArray();
|
||
a.replace(this);
|
||
return a;
|
||
}
|
||
};
|
||
|
||
return function(){
|
||
var a = [];
|
||
a.push.apply(a, arguments);
|
||
$.extend(a, extras);
|
||
return a;
|
||
};
|
||
})();
|
||
|
||
|
||
// Picker object
|
||
|
||
var Datepicker = function(element, options){
|
||
this.dates = new DateArray();
|
||
this.viewDate = UTCToday();
|
||
this.focusDate = null;
|
||
|
||
this._process_options(options);
|
||
|
||
this.element = $(element);
|
||
this.isInline = false;
|
||
this.isInput = this.element.is('input');
|
||
this.component = this.element.is('.date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
|
||
this.hasInput = this.component && this.element.find('input').length;
|
||
if (this.component && this.component.length === 0)
|
||
this.component = false;
|
||
|
||
this.picker = $(DPGlobal.template);
|
||
this._buildEvents();
|
||
this._attachEvents();
|
||
|
||
if (this.isInline){
|
||
this.picker.addClass('datepicker-inline').appendTo(this.element);
|
||
}
|
||
else {
|
||
this.picker.addClass('datepicker-dropdown dropdown-menu');
|
||
}
|
||
|
||
if (this.o.rtl){
|
||
this.picker.addClass('datepicker-rtl');
|
||
}
|
||
|
||
this.viewMode = this.o.startView;
|
||
|
||
if (this.o.calendarWeeks)
|
||
this.picker.find('tfoot th.today')
|
||
.attr('colspan', function(i, val){
|
||
return parseInt(val) + 1;
|
||
});
|
||
|
||
this._allow_update = false;
|
||
|
||
this.setStartDate(this._o.startDate);
|
||
this.setEndDate(this._o.endDate);
|
||
this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
|
||
|
||
this.fillDow();
|
||
this.fillMonths();
|
||
|
||
this._allow_update = true;
|
||
|
||
this.update();
|
||
this.showMode();
|
||
|
||
if (this.isInline){
|
||
this.show();
|
||
}
|
||
};
|
||
|
||
Datepicker.prototype = {
|
||
constructor: Datepicker,
|
||
|
||
_process_options: function(opts){
|
||
// Store raw options for reference
|
||
this._o = $.extend({}, this._o, opts);
|
||
// Processed options
|
||
var o = this.o = $.extend({}, this._o);
|
||
|
||
// Check if "de-DE" style date is available, if not language should
|
||
// fallback to 2 letter code eg "de"
|
||
var lang = o.language;
|
||
if (!dates[lang]){
|
||
lang = lang.split('-')[0];
|
||
if (!dates[lang])
|
||
lang = defaults.language;
|
||
}
|
||
o.language = lang;
|
||
|
||
switch (o.startView){
|
||
case 2:
|
||
case 'decade':
|
||
o.startView = 2;
|
||
break;
|
||
case 1:
|
||
case 'year':
|
||
o.startView = 1;
|
||
break;
|
||
default:
|
||
o.startView = 0;
|
||
}
|
||
|
||
switch (o.minViewMode){
|
||
case 1:
|
||
case 'months':
|
||
o.minViewMode = 1;
|
||
break;
|
||
case 2:
|
||
case 'years':
|
||
o.minViewMode = 2;
|
||
break;
|
||
default:
|
||
o.minViewMode = 0;
|
||
}
|
||
|
||
o.startView = Math.max(o.startView, o.minViewMode);
|
||
|
||
// true, false, or Number > 0
|
||
if (o.multidate !== true){
|
||
o.multidate = Number(o.multidate) || false;
|
||
if (o.multidate !== false)
|
||
o.multidate = Math.max(0, o.multidate);
|
||
else
|
||
o.multidate = 1;
|
||
}
|
||
o.multidateSeparator = String(o.multidateSeparator);
|
||
|
||
o.weekStart %= 7;
|
||
o.weekEnd = ((o.weekStart + 6) % 7);
|
||
|
||
var format = DPGlobal.parseFormat(o.format);
|
||
if (o.startDate !== -Infinity){
|
||
if (!!o.startDate){
|
||
if (o.startDate instanceof Date)
|
||
o.startDate = this._local_to_utc(this._zero_time(o.startDate));
|
||
else
|
||
o.startDate = DPGlobal.parseDate(o.startDate, format, o.language);
|
||
}
|
||
else {
|
||
o.startDate = -Infinity;
|
||
}
|
||
}
|
||
if (o.endDate !== Infinity){
|
||
if (!!o.endDate){
|
||
if (o.endDate instanceof Date)
|
||
o.endDate = this._local_to_utc(this._zero_time(o.endDate));
|
||
else
|
||
o.endDate = DPGlobal.parseDate(o.endDate, format, o.language);
|
||
}
|
||
else {
|
||
o.endDate = Infinity;
|
||
}
|
||
}
|
||
|
||
o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
|
||
if (!$.isArray(o.daysOfWeekDisabled))
|
||
o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
|
||
o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
|
||
return parseInt(d, 10);
|
||
});
|
||
|
||
var plc = String(o.orientation).toLowerCase().split(/\s+/g),
|
||
_plc = o.orientation.toLowerCase();
|
||
plc = $.grep(plc, function(word){
|
||
return (/^auto|left|right|top|bottom$/).test(word);
|
||
});
|
||
o.orientation = {x: 'auto', y: 'auto'};
|
||
if (!_plc || _plc === 'auto')
|
||
; // no action
|
||
else if (plc.length === 1){
|
||
switch (plc[0]){
|
||
case 'top':
|
||
case 'bottom':
|
||
o.orientation.y = plc[0];
|
||
break;
|
||
case 'left':
|
||
case 'right':
|
||
o.orientation.x = plc[0];
|
||
break;
|
||
}
|
||
}
|
||
else {
|
||
_plc = $.grep(plc, function(word){
|
||
return (/^left|right$/).test(word);
|
||
});
|
||
o.orientation.x = _plc[0] || 'auto';
|
||
|
||
_plc = $.grep(plc, function(word){
|
||
return (/^top|bottom$/).test(word);
|
||
});
|
||
o.orientation.y = _plc[0] || 'auto';
|
||
}
|
||
},
|
||
_events: [],
|
||
_secondaryEvents: [],
|
||
_applyEvents: function(evs){
|
||
for (var i=0, el, ch, ev; i < evs.length; i++){
|
||
el = evs[i][0];
|
||
if (evs[i].length === 2){
|
||
ch = undefined;
|
||
ev = evs[i][1];
|
||
}
|
||
else if (evs[i].length === 3){
|
||
ch = evs[i][1];
|
||
ev = evs[i][2];
|
||
}
|
||
el.on(ev, ch);
|
||
}
|
||
},
|
||
_unapplyEvents: function(evs){
|
||
for (var i=0, el, ev, ch; i < evs.length; i++){
|
||
el = evs[i][0];
|
||
if (evs[i].length === 2){
|
||
ch = undefined;
|
||
ev = evs[i][1];
|
||
}
|
||
else if (evs[i].length === 3){
|
||
ch = evs[i][1];
|
||
ev = evs[i][2];
|
||
}
|
||
el.off(ev, ch);
|
||
}
|
||
},
|
||
_buildEvents: function(){
|
||
if (this.isInput){ // single input
|
||
this._events = [
|
||
[this.element, {
|
||
focus: $.proxy(this.show, this),
|
||
keyup: $.proxy(function(e){
|
||
if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1)
|
||
this.update();
|
||
}, this),
|
||
keydown: $.proxy(this.keydown, this)
|
||
}]
|
||
];
|
||
}
|
||
else if (this.component && this.hasInput){ // component: input + button
|
||
this._events = [
|
||
// For components that are not readonly, allow keyboard nav
|
||
[this.element.find('input'), {
|
||
focus: $.proxy(this.show, this),
|
||
keyup: $.proxy(function(e){
|
||
if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1)
|
||
this.update();
|
||
}, this),
|
||
keydown: $.proxy(this.keydown, this)
|
||
}],
|
||
[this.component, {
|
||
click: $.proxy(this.show, this)
|
||
}]
|
||
];
|
||
}
|
||
else if (this.element.is('div')){ // inline datepicker
|
||
this.isInline = true;
|
||
}
|
||
else {
|
||
this._events = [
|
||
[this.element, {
|
||
click: $.proxy(this.show, this)
|
||
}]
|
||
];
|
||
}
|
||
this._events.push(
|
||
// Component: listen for blur on element descendants
|
||
[this.element, '*', {
|
||
blur: $.proxy(function(e){
|
||
this._focused_from = e.target;
|
||
}, this)
|
||
}],
|
||
// Input: listen for blur on element
|
||
[this.element, {
|
||
blur: $.proxy(function(e){
|
||
this._focused_from = e.target;
|
||
}, this)
|
||
}]
|
||
);
|
||
|
||
this._secondaryEvents = [
|
||
[this.picker, {
|
||
click: $.proxy(this.click, this)
|
||
}],
|
||
[$(window), {
|
||
resize: $.proxy(this.place, this)
|
||
}],
|
||
[$(document), {
|
||
'mousedown touchstart': $.proxy(function(e){
|
||
// Clicked outside the datepicker, hide it
|
||
if (!(
|
||
this.element.is(e.target) ||
|
||
this.element.find(e.target).length ||
|
||
this.picker.is(e.target) ||
|
||
this.picker.find(e.target).length
|
||
)){
|
||
this.hide();
|
||
}
|
||
}, this)
|
||
}]
|
||
];
|
||
},
|
||
_attachEvents: function(){
|
||
this._detachEvents();
|
||
this._applyEvents(this._events);
|
||
},
|
||
_detachEvents: function(){
|
||
this._unapplyEvents(this._events);
|
||
},
|
||
_attachSecondaryEvents: function(){
|
||
this._detachSecondaryEvents();
|
||
this._applyEvents(this._secondaryEvents);
|
||
},
|
||
_detachSecondaryEvents: function(){
|
||
this._unapplyEvents(this._secondaryEvents);
|
||
},
|
||
_trigger: function(event, altdate){
|
||
var date = altdate || this.dates.get(-1),
|
||
local_date = this._utc_to_local(date);
|
||
|
||
this.element.trigger({
|
||
type: event,
|
||
date: local_date,
|
||
dates: $.map(this.dates, this._utc_to_local),
|
||
format: $.proxy(function(ix, format){
|
||
if (arguments.length === 0){
|
||
ix = this.dates.length - 1;
|
||
format = this.o.format;
|
||
}
|
||
else if (typeof ix === 'string'){
|
||
format = ix;
|
||
ix = this.dates.length - 1;
|
||
}
|
||
format = format || this.o.format;
|
||
var date = this.dates.get(ix);
|
||
return DPGlobal.formatDate(date, format, this.o.language);
|
||
}, this)
|
||
});
|
||
},
|
||
|
||
show: function(){
|
||
if (!this.isInline)
|
||
this.picker.appendTo('body');
|
||
this.picker.show();
|
||
this.place();
|
||
this._attachSecondaryEvents();
|
||
this._trigger('show');
|
||
},
|
||
|
||
hide: function(){
|
||
if (this.isInline)
|
||
return;
|
||
if (!this.picker.is(':visible'))
|
||
return;
|
||
this.focusDate = null;
|
||
this.picker.hide().detach();
|
||
this._detachSecondaryEvents();
|
||
this.viewMode = this.o.startView;
|
||
this.showMode();
|
||
|
||
if (
|
||
this.o.forceParse &&
|
||
(
|
||
this.isInput && this.element.val() ||
|
||
this.hasInput && this.element.find('input').val()
|
||
)
|
||
)
|
||
this.setValue();
|
||
this._trigger('hide');
|
||
},
|
||
|
||
remove: function(){
|
||
this.hide();
|
||
this._detachEvents();
|
||
this._detachSecondaryEvents();
|
||
this.picker.remove();
|
||
delete this.element.data().datepicker;
|
||
if (!this.isInput){
|
||
delete this.element.data().date;
|
||
}
|
||
},
|
||
|
||
_utc_to_local: function(utc){
|
||
return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));
|
||
},
|
||
_local_to_utc: function(local){
|
||
return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
|
||
},
|
||
_zero_time: function(local){
|
||
return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
|
||
},
|
||
_zero_utc_time: function(utc){
|
||
return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
|
||
},
|
||
|
||
getDates: function(){
|
||
return $.map(this.dates, this._utc_to_local);
|
||
},
|
||
|
||
getUTCDates: function(){
|
||
return $.map(this.dates, function(d){
|
||
return new Date(d);
|
||
});
|
||
},
|
||
|
||
getDate: function(){
|
||
return this._utc_to_local(this.getUTCDate());
|
||
},
|
||
|
||
getUTCDate: function(){
|
||
return new Date(this.dates.get(-1));
|
||
},
|
||
|
||
setDates: function(){
|
||
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
|
||
this.update.apply(this, args);
|
||
this._trigger('changeDate');
|
||
this.setValue();
|
||
},
|
||
|
||
setUTCDates: function(){
|
||
var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
|
||
this.update.apply(this, $.map(args, this._utc_to_local));
|
||
this._trigger('changeDate');
|
||
this.setValue();
|
||
},
|
||
|
||
setDate: alias('setDates'),
|
||
setUTCDate: alias('setUTCDates'),
|
||
|
||
setValue: function(){
|
||
var formatted = this.getFormattedDate();
|
||
if (!this.isInput){
|
||
if (this.component){
|
||
this.element.find('input').val(formatted).change();
|
||
}
|
||
}
|
||
else {
|
||
this.element.val(formatted).change();
|
||
}
|
||
},
|
||
|
||
getFormattedDate: function(format){
|
||
if (format === undefined)
|
||
format = this.o.format;
|
||
|
||
var lang = this.o.language;
|
||
return $.map(this.dates, function(d){
|
||
return DPGlobal.formatDate(d, format, lang);
|
||
}).join(this.o.multidateSeparator);
|
||
},
|
||
|
||
setStartDate: function(startDate){
|
||
this._process_options({startDate: startDate});
|
||
this.update();
|
||
this.updateNavArrows();
|
||
},
|
||
|
||
setEndDate: function(endDate){
|
||
this._process_options({endDate: endDate});
|
||
this.update();
|
||
this.updateNavArrows();
|
||
},
|
||
|
||
setDaysOfWeekDisabled: function(daysOfWeekDisabled){
|
||
this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
|
||
this.update();
|
||
this.updateNavArrows();
|
||
},
|
||
|
||
place: function(){
|
||
if (this.isInline)
|
||
return;
|
||
var calendarWidth = this.picker.outerWidth(),
|
||
calendarHeight = this.picker.outerHeight(),
|
||
visualPadding = 10,
|
||
windowWidth = $window.width(),
|
||
windowHeight = $window.height(),
|
||
scrollTop = $window.scrollTop();
|
||
|
||
var zIndex = parseInt(this.element.parents().filter(function(){
|
||
return $(this).css('z-index') !== 'auto';
|
||
}).first().css('z-index'))+10;
|
||
var offset = this.component ? this.component.parent().offset() : this.element.offset();
|
||
var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
|
||
var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
|
||
var left = offset.left,
|
||
top = offset.top;
|
||
|
||
this.picker.removeClass(
|
||
'datepicker-orient-top datepicker-orient-bottom '+
|
||
'datepicker-orient-right datepicker-orient-left'
|
||
);
|
||
|
||
if (this.o.orientation.x !== 'auto'){
|
||
this.picker.addClass('datepicker-orient-' + this.o.orientation.x);
|
||
if (this.o.orientation.x === 'right')
|
||
left -= calendarWidth - width;
|
||
}
|
||
// auto x orientation is best-placement: if it crosses a window
|
||
// edge, fudge it sideways
|
||
else {
|
||
// Default to left
|
||
this.picker.addClass('datepicker-orient-left');
|
||
if (offset.left < 0)
|
||
left -= offset.left - visualPadding;
|
||
else if (offset.left + calendarWidth > windowWidth)
|
||
left = windowWidth - calendarWidth - visualPadding;
|
||
}
|
||
|
||
// auto y orientation is best-situation: top or bottom, no fudging,
|
||
// decision based on which shows more of the calendar
|
||
var yorient = this.o.orientation.y,
|
||
top_overflow, bottom_overflow;
|
||
if (yorient === 'auto'){
|
||
top_overflow = -scrollTop + offset.top - calendarHeight;
|
||
bottom_overflow = scrollTop + windowHeight - (offset.top + height + calendarHeight);
|
||
if (Math.max(top_overflow, bottom_overflow) === bottom_overflow)
|
||
yorient = 'top';
|
||
else
|
||
yorient = 'bottom';
|
||
}
|
||
this.picker.addClass('datepicker-orient-' + yorient);
|
||
if (yorient === 'top')
|
||
top += height;
|
||
else
|
||
top -= calendarHeight + parseInt(this.picker.css('padding-top'));
|
||
|
||
this.picker.css({
|
||
top: top,
|
||
left: left,
|
||
zIndex: zIndex
|
||
});
|
||
},
|
||
|
||
_allow_update: true,
|
||
update: function(){
|
||
if (!this._allow_update)
|
||
return;
|
||
|
||
var oldDates = this.dates.copy(),
|
||
dates = [],
|
||
fromArgs = false;
|
||
if (arguments.length){
|
||
$.each(arguments, $.proxy(function(i, date){
|
||
if (date instanceof Date)
|
||
date = this._local_to_utc(date);
|
||
dates.push(date);
|
||
}, this));
|
||
fromArgs = true;
|
||
}
|
||
else {
|
||
dates = this.isInput
|
||
? this.element.val()
|
||
: this.element.data('date') || this.element.find('input').val();
|
||
if (dates && this.o.multidate)
|
||
dates = dates.split(this.o.multidateSeparator);
|
||
else
|
||
dates = [dates];
|
||
delete this.element.data().date;
|
||
}
|
||
|
||
dates = $.map(dates, $.proxy(function(date){
|
||
return DPGlobal.parseDate(date, this.o.format, this.o.language);
|
||
}, this));
|
||
dates = $.grep(dates, $.proxy(function(date){
|
||
return (
|
||
date < this.o.startDate ||
|
||
date > this.o.endDate ||
|
||
!date
|
||
);
|
||
}, this), true);
|
||
this.dates.replace(dates);
|
||
|
||
if (this.dates.length)
|
||
this.viewDate = new Date(this.dates.get(-1));
|
||
else if (this.viewDate < this.o.startDate)
|
||
this.viewDate = new Date(this.o.startDate);
|
||
else if (this.viewDate > this.o.endDate)
|
||
this.viewDate = new Date(this.o.endDate);
|
||
|
||
if (fromArgs){
|
||
// setting date by clicking
|
||
this.setValue();
|
||
}
|
||
else if (dates.length){
|
||
// setting date by typing
|
||
if (String(oldDates) !== String(this.dates))
|
||
this._trigger('changeDate');
|
||
}
|
||
if (!this.dates.length && oldDates.length)
|
||
this._trigger('clearDate');
|
||
|
||
this.fill();
|
||
},
|
||
|
||
fillDow: function(){
|
||
var dowCnt = this.o.weekStart,
|
||
html = '<tr>';
|
||
if (this.o.calendarWeeks){
|
||
var cell = '<th class="cw"> </th>';
|
||
html += cell;
|
||
this.picker.find('.datepicker-days thead tr:first-child').prepend(cell);
|
||
}
|
||
while (dowCnt < this.o.weekStart + 7){
|
||
html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';
|
||
}
|
||
html += '</tr>';
|
||
this.picker.find('.datepicker-days thead').append(html);
|
||
},
|
||
|
||
fillMonths: function(){
|
||
var html = '',
|
||
i = 0;
|
||
while (i < 12){
|
||
html += '<span class="month">'+dates[this.o.language].monthsShort[i++]+'</span>';
|
||
}
|
||
this.picker.find('.datepicker-months td').html(html);
|
||
},
|
||
|
||
setRange: function(range){
|
||
if (!range || !range.length)
|
||
delete this.range;
|
||
else
|
||
this.range = $.map(range, function(d){
|
||
return d.valueOf();
|
||
});
|
||
this.fill();
|
||
},
|
||
|
||
getClassNames: function(date){
|
||
var cls = [],
|
||
year = this.viewDate.getUTCFullYear(),
|
||
month = this.viewDate.getUTCMonth(),
|
||
today = new Date();
|
||
if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
|
||
cls.push('old');
|
||
}
|
||
else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
|
||
cls.push('new');
|
||
}
|
||
if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
|
||
cls.push('focused');
|
||
// Compare internal UTC date with local today, not UTC today
|
||
if (this.o.todayHighlight &&
|
||
date.getUTCFullYear() === today.getFullYear() &&
|
||
date.getUTCMonth() === today.getMonth() &&
|
||
date.getUTCDate() === today.getDate()){
|
||
cls.push('today');
|
||
}
|
||
if (this.dates.contains(date) !== -1)
|
||
cls.push('active');
|
||
if (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate ||
|
||
$.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){
|
||
cls.push('disabled');
|
||
}
|
||
if (this.range){
|
||
if (date > this.range[0] && date < this.range[this.range.length-1]){
|
||
cls.push('range');
|
||
}
|
||
if ($.inArray(date.valueOf(), this.range) !== -1){
|
||
cls.push('selected');
|
||
}
|
||
}
|
||
return cls;
|
||
},
|
||
|
||
fill: function(){
|
||
var d = new Date(this.viewDate),
|
||
year = d.getUTCFullYear(),
|
||
month = d.getUTCMonth(),
|
||
startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
|
||
startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
|
||
endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
|
||
endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
|
||
todaytxt = dates[this.o.language].today || dates['en'].today || '',
|
||
cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
|
||
tooltip;
|
||
this.picker.find('.datepicker-days thead th.datepicker-switch')
|
||
.text(dates[this.o.language].months[month]+' '+year);
|
||
this.picker.find('tfoot th.today')
|
||
.text(todaytxt)
|
||
.toggle(this.o.todayBtn !== false);
|
||
this.picker.find('tfoot th.clear')
|
||
.text(cleartxt)
|
||
.toggle(this.o.clearBtn !== false);
|
||
this.updateNavArrows();
|
||
this.fillMonths();
|
||
var prevMonth = UTCDate(year, month-1, 28),
|
||
day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
|
||
prevMonth.setUTCDate(day);
|
||
prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
|
||
var nextMonth = new Date(prevMonth);
|
||
nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
|
||
nextMonth = nextMonth.valueOf();
|
||
var html = [];
|
||
var clsName;
|
||
while (prevMonth.valueOf() < nextMonth){
|
||
if (prevMonth.getUTCDay() === this.o.weekStart){
|
||
html.push('<tr>');
|
||
if (this.o.calendarWeeks){
|
||
// ISO 8601: First week contains first thursday.
|
||
// ISO also states week starts on Monday, but we can be more abstract here.
|
||
var
|
||
// Start of current week: based on weekstart/current date
|
||
ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
|
||
// Thursday of this week
|
||
th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
|
||
// First Thursday of year, year from thursday
|
||
yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
|
||
// Calendar week: ms between thursdays, div ms per day, div 7 days
|
||
calWeek = (th - yth) / 864e5 / 7 + 1;
|
||
html.push('<td class="cw">'+ calWeek +'</td>');
|
||
|
||
}
|
||
}
|
||
clsName = this.getClassNames(prevMonth);
|
||
clsName.push('day');
|
||
|
||
if (this.o.beforeShowDay !== $.noop){
|
||
var before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
|
||
if (before === undefined)
|
||
before = {};
|
||
else if (typeof(before) === 'boolean')
|
||
before = {enabled: before};
|
||
else if (typeof(before) === 'string')
|
||
before = {classes: before};
|
||
if (before.enabled === false)
|
||
clsName.push('disabled');
|
||
if (before.classes)
|
||
clsName = clsName.concat(before.classes.split(/\s+/));
|
||
if (before.tooltip)
|
||
tooltip = before.tooltip;
|
||
}
|
||
|
||
clsName = $.unique(clsName);
|
||
html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>');
|
||
if (prevMonth.getUTCDay() === this.o.weekEnd){
|
||
html.push('</tr>');
|
||
}
|
||
prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
|
||
}
|
||
this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
|
||
|
||
var months = this.picker.find('.datepicker-months')
|
||
.find('th:eq(1)')
|
||
.text(year)
|
||
.end()
|
||
.find('span').removeClass('active');
|
||
|
||
$.each(this.dates, function(i, d){
|
||
if (d.getUTCFullYear() === year)
|
||
months.eq(d.getUTCMonth()).addClass('active');
|
||
});
|
||
|
||
if (year < startYear || year > endYear){
|
||
months.addClass('disabled');
|
||
}
|
||
if (year === startYear){
|
||
months.slice(0, startMonth).addClass('disabled');
|
||
}
|
||
if (year === endYear){
|
||
months.slice(endMonth+1).addClass('disabled');
|
||
}
|
||
|
||
html = '';
|
||
year = parseInt(year/10, 10) * 10;
|
||
var yearCont = this.picker.find('.datepicker-years')
|
||
.find('th:eq(1)')
|
||
.text(year + '-' + (year + 9))
|
||
.end()
|
||
.find('td');
|
||
year -= 1;
|
||
var years = $.map(this.dates, function(d){
|
||
return d.getUTCFullYear();
|
||
}),
|
||
classes;
|
||
for (var i = -1; i < 11; i++){
|
||
classes = ['year'];
|
||
if (i === -1)
|
||
classes.push('old');
|
||
else if (i === 10)
|
||
classes.push('new');
|
||
if ($.inArray(year, years) !== -1)
|
||
classes.push('active');
|
||
if (year < startYear || year > endYear)
|
||
classes.push('disabled');
|
||
html += '<span class="' + classes.join(' ') + '">'+year+'</span>';
|
||
year += 1;
|
||
}
|
||
yearCont.html(html);
|
||
},
|
||
|
||
updateNavArrows: function(){
|
||
if (!this._allow_update)
|
||
return;
|
||
|
||
var d = new Date(this.viewDate),
|
||
year = d.getUTCFullYear(),
|
||
month = d.getUTCMonth();
|
||
switch (this.viewMode){
|
||
case 0:
|
||
if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
|
||
this.picker.find('.prev').css({visibility: 'hidden'});
|
||
}
|
||
else {
|
||
this.picker.find('.prev').css({visibility: 'visible'});
|
||
}
|
||
if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
|
||
this.picker.find('.next').css({visibility: 'hidden'});
|
||
}
|
||
else {
|
||
this.picker.find('.next').css({visibility: 'visible'});
|
||
}
|
||
break;
|
||
case 1:
|
||
case 2:
|
||
if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()){
|
||
this.picker.find('.prev').css({visibility: 'hidden'});
|
||
}
|
||
else {
|
||
this.picker.find('.prev').css({visibility: 'visible'});
|
||
}
|
||
if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()){
|
||
this.picker.find('.next').css({visibility: 'hidden'});
|
||
}
|
||
else {
|
||
this.picker.find('.next').css({visibility: 'visible'});
|
||
}
|
||
break;
|
||
}
|
||
},
|
||
|
||
click: function(e){
|
||
e.preventDefault();
|
||
var target = $(e.target).closest('span, td, th'),
|
||
year, month, day;
|
||
if (target.length === 1){
|
||
switch (target[0].nodeName.toLowerCase()){
|
||
case 'th':
|
||
switch (target[0].className){
|
||
case 'datepicker-switch':
|
||
this.showMode(1);
|
||
break;
|
||
case 'prev':
|
||
case 'next':
|
||
var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);
|
||
switch (this.viewMode){
|
||
case 0:
|
||
this.viewDate = this.moveMonth(this.viewDate, dir);
|
||
this._trigger('changeMonth', this.viewDate);
|
||
break;
|
||
case 1:
|
||
case 2:
|
||
this.viewDate = this.moveYear(this.viewDate, dir);
|
||
if (this.viewMode === 1)
|
||
this._trigger('changeYear', this.viewDate);
|
||
break;
|
||
}
|
||
this.fill();
|
||
break;
|
||
case 'today':
|
||
var date = new Date();
|
||
date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
|
||
|
||
this.showMode(-2);
|
||
var which = this.o.todayBtn === 'linked' ? null : 'view';
|
||
this._setDate(date, which);
|
||
break;
|
||
case 'clear':
|
||
var element;
|
||
if (this.isInput)
|
||
element = this.element;
|
||
else if (this.component)
|
||
element = this.element.find('input');
|
||
if (element)
|
||
element.val("").change();
|
||
this.update();
|
||
this._trigger('changeDate');
|
||
if (this.o.autoclose)
|
||
this.hide();
|
||
break;
|
||
}
|
||
break;
|
||
case 'span':
|
||
if (!target.is('.disabled')){
|
||
this.viewDate.setUTCDate(1);
|
||
if (target.is('.month')){
|
||
day = 1;
|
||
month = target.parent().find('span').index(target);
|
||
year = this.viewDate.getUTCFullYear();
|
||
this.viewDate.setUTCMonth(month);
|
||
this._trigger('changeMonth', this.viewDate);
|
||
if (this.o.minViewMode === 1){
|
||
this._setDate(UTCDate(year, month, day));
|
||
}
|
||
}
|
||
else {
|
||
day = 1;
|
||
month = 0;
|
||
year = parseInt(target.text(), 10)||0;
|
||
this.viewDate.setUTCFullYear(year);
|
||
this._trigger('changeYear', this.viewDate);
|
||
if (this.o.minViewMode === 2){
|
||
this._setDate(UTCDate(year, month, day));
|
||
}
|
||
}
|
||
this.showMode(-1);
|
||
this.fill();
|
||
}
|
||
break;
|
||
case 'td':
|
||
if (target.is('.day') && !target.is('.disabled')){
|
||
day = parseInt(target.text(), 10)||1;
|
||
year = this.viewDate.getUTCFullYear();
|
||
month = this.viewDate.getUTCMonth();
|
||
if (target.is('.old')){
|
||
if (month === 0){
|
||
month = 11;
|
||
year -= 1;
|
||
}
|
||
else {
|
||
month -= 1;
|
||
}
|
||
}
|
||
else if (target.is('.new')){
|
||
if (month === 11){
|
||
month = 0;
|
||
year += 1;
|
||
}
|
||
else {
|
||
month += 1;
|
||
}
|
||
}
|
||
this._setDate(UTCDate(year, month, day));
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
if (this.picker.is(':visible') && this._focused_from){
|
||
$(this._focused_from).focus();
|
||
}
|
||
delete this._focused_from;
|
||
},
|
||
|
||
_toggle_multidate: function(date){
|
||
var ix = this.dates.contains(date);
|
||
if (!date){
|
||
this.dates.clear();
|
||
}
|
||
else if (ix !== -1){
|
||
this.dates.remove(ix);
|
||
}
|
||
else {
|
||
this.dates.push(date);
|
||
}
|
||
if (typeof this.o.multidate === 'number')
|
||
while (this.dates.length > this.o.multidate)
|
||
this.dates.remove(0);
|
||
},
|
||
|
||
_setDate: function(date, which){
|
||
if (!which || which === 'date')
|
||
this._toggle_multidate(date && new Date(date));
|
||
if (!which || which === 'view')
|
||
this.viewDate = date && new Date(date);
|
||
|
||
this.fill();
|
||
this.setValue();
|
||
this._trigger('changeDate');
|
||
var element;
|
||
if (this.isInput){
|
||
element = this.element;
|
||
}
|
||
else if (this.component){
|
||
element = this.element.find('input');
|
||
}
|
||
if (element){
|
||
element.change();
|
||
}
|
||
if (this.o.autoclose && (!which || which === 'date')){
|
||
this.hide();
|
||
}
|
||
},
|
||
|
||
moveMonth: function(date, dir){
|
||
if (!date)
|
||
return undefined;
|
||
if (!dir)
|
||
return date;
|
||
var new_date = new Date(date.valueOf()),
|
||
day = new_date.getUTCDate(),
|
||
month = new_date.getUTCMonth(),
|
||
mag = Math.abs(dir),
|
||
new_month, test;
|
||
dir = dir > 0 ? 1 : -1;
|
||
if (mag === 1){
|
||
test = dir === -1
|
||
// If going back one month, make sure month is not current month
|
||
// (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
|
||
? function(){
|
||
return new_date.getUTCMonth() === month;
|
||
}
|
||
// If going forward one month, make sure month is as expected
|
||
// (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
|
||
: function(){
|
||
return new_date.getUTCMonth() !== new_month;
|
||
};
|
||
new_month = month + dir;
|
||
new_date.setUTCMonth(new_month);
|
||
// Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
|
||
if (new_month < 0 || new_month > 11)
|
||
new_month = (new_month + 12) % 12;
|
||
}
|
||
else {
|
||
// For magnitudes >1, move one month at a time...
|
||
for (var i=0; i < mag; i++)
|
||
// ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
|
||
new_date = this.moveMonth(new_date, dir);
|
||
// ...then reset the day, keeping it in the new month
|
||
new_month = new_date.getUTCMonth();
|
||
new_date.setUTCDate(day);
|
||
test = function(){
|
||
return new_month !== new_date.getUTCMonth();
|
||
};
|
||
}
|
||
// Common date-resetting loop -- if date is beyond end of month, make it
|
||
// end of month
|
||
while (test()){
|
||
new_date.setUTCDate(--day);
|
||
new_date.setUTCMonth(new_month);
|
||
}
|
||
return new_date;
|
||
},
|
||
|
||
moveYear: function(date, dir){
|
||
return this.moveMonth(date, dir*12);
|
||
},
|
||
|
||
dateWithinRange: function(date){
|
||
return date >= this.o.startDate && date <= this.o.endDate;
|
||
},
|
||
|
||
keydown: function(e){
|
||
if (this.picker.is(':not(:visible)')){
|
||
if (e.keyCode === 27) // allow escape to hide and re-show picker
|
||
this.show();
|
||
return;
|
||
}
|
||
var dateChanged = false,
|
||
dir, newDate, newViewDate,
|
||
focusDate = this.focusDate || this.viewDate;
|
||
switch (e.keyCode){
|
||
case 27: // escape
|
||
if (this.focusDate){
|
||
this.focusDate = null;
|
||
this.viewDate = this.dates.get(-1) || this.viewDate;
|
||
this.fill();
|
||
}
|
||
else
|
||
this.hide();
|
||
e.preventDefault();
|
||
break;
|
||
case 37: // left
|
||
case 39: // right
|
||
if (!this.o.keyboardNavigation)
|
||
break;
|
||
dir = e.keyCode === 37 ? -1 : 1;
|
||
if (e.ctrlKey){
|
||
newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
|
||
newViewDate = this.moveYear(focusDate, dir);
|
||
this._trigger('changeYear', this.viewDate);
|
||
}
|
||
else if (e.shiftKey){
|
||
newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
|
||
newViewDate = this.moveMonth(focusDate, dir);
|
||
this._trigger('changeMonth', this.viewDate);
|
||
}
|
||
else {
|
||
newDate = new Date(this.dates.get(-1) || UTCToday());
|
||
newDate.setUTCDate(newDate.getUTCDate() + dir);
|
||
newViewDate = new Date(focusDate);
|
||
newViewDate.setUTCDate(focusDate.getUTCDate() + dir);
|
||
}
|
||
if (this.dateWithinRange(newDate)){
|
||
this.focusDate = this.viewDate = newViewDate;
|
||
this.setValue();
|
||
this.fill();
|
||
e.preventDefault();
|
||
}
|
||
break;
|
||
case 38: // up
|
||
case 40: // down
|
||
if (!this.o.keyboardNavigation)
|
||
break;
|
||
dir = e.keyCode === 38 ? -1 : 1;
|
||
if (e.ctrlKey){
|
||
newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
|
||
newViewDate = this.moveYear(focusDate, dir);
|
||
this._trigger('changeYear', this.viewDate);
|
||
}
|
||
else if (e.shiftKey){
|
||
newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
|
||
newViewDate = this.moveMonth(focusDate, dir);
|
||
this._trigger('changeMonth', this.viewDate);
|
||
}
|
||
else {
|
||
newDate = new Date(this.dates.get(-1) || UTCToday());
|
||
newDate.setUTCDate(newDate.getUTCDate() + dir * 7);
|
||
newViewDate = new Date(focusDate);
|
||
newViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7);
|
||
}
|
||
if (this.dateWithinRange(newDate)){
|
||
this.focusDate = this.viewDate = newViewDate;
|
||
this.setValue();
|
||
this.fill();
|
||
e.preventDefault();
|
||
}
|
||
break;
|
||
case 32: // spacebar
|
||
// Spacebar is used in manually typing dates in some formats.
|
||
// As such, its behavior should not be hijacked.
|
||
break;
|
||
case 13: // enter
|
||
focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
|
||
this._toggle_multidate(focusDate);
|
||
dateChanged = true;
|
||
this.focusDate = null;
|
||
this.viewDate = this.dates.get(-1) || this.viewDate;
|
||
this.setValue();
|
||
this.fill();
|
||
if (this.picker.is(':visible')){
|
||
e.preventDefault();
|
||
if (this.o.autoclose)
|
||
this.hide();
|
||
}
|
||
break;
|
||
case 9: // tab
|
||
this.focusDate = null;
|
||
this.viewDate = this.dates.get(-1) || this.viewDate;
|
||
this.fill();
|
||
this.hide();
|
||
break;
|
||
}
|
||
if (dateChanged){
|
||
if (this.dates.length)
|
||
this._trigger('changeDate');
|
||
else
|
||
this._trigger('clearDate');
|
||
var element;
|
||
if (this.isInput){
|
||
element = this.element;
|
||
}
|
||
else if (this.component){
|
||
element = this.element.find('input');
|
||
}
|
||
if (element){
|
||
element.change();
|
||
}
|
||
}
|
||
},
|
||
|
||
showMode: function(dir){
|
||
if (dir){
|
||
this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir));
|
||
}
|
||
this.picker
|
||
.find('>div')
|
||
.hide()
|
||
.filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName)
|
||
.css('display', 'block');
|
||
this.updateNavArrows();
|
||
}
|
||
};
|
||
|
||
var DateRangePicker = function(element, options){
|
||
this.element = $(element);
|
||
this.inputs = $.map(options.inputs, function(i){
|
||
return i.jquery ? i[0] : i;
|
||
});
|
||
delete options.inputs;
|
||
|
||
$(this.inputs)
|
||
.datepicker(options)
|
||
.bind('changeDate', $.proxy(this.dateUpdated, this));
|
||
|
||
this.pickers = $.map(this.inputs, function(i){
|
||
return $(i).data('datepicker');
|
||
});
|
||
this.updateDates();
|
||
};
|
||
DateRangePicker.prototype = {
|
||
updateDates: function(){
|
||
this.dates = $.map(this.pickers, function(i){
|
||
return i.getUTCDate();
|
||
});
|
||
this.updateRanges();
|
||
},
|
||
updateRanges: function(){
|
||
var range = $.map(this.dates, function(d){
|
||
return d.valueOf();
|
||
});
|
||
$.each(this.pickers, function(i, p){
|
||
p.setRange(range);
|
||
});
|
||
},
|
||
dateUpdated: function(e){
|
||
// `this.updating` is a workaround for preventing infinite recursion
|
||
// between `changeDate` triggering and `setUTCDate` calling. Until
|
||
// there is a better mechanism.
|
||
if (this.updating)
|
||
return;
|
||
this.updating = true;
|
||
|
||
var dp = $(e.target).data('datepicker'),
|
||
new_date = dp.getUTCDate(),
|
||
i = $.inArray(e.target, this.inputs),
|
||
l = this.inputs.length;
|
||
if (i === -1)
|
||
return;
|
||
|
||
$.each(this.pickers, function(i, p){
|
||
if (!p.getUTCDate())
|
||
p.setUTCDate(new_date);
|
||
});
|
||
|
||
if (new_date < this.dates[i]){
|
||
// Date being moved earlier/left
|
||
while (i >= 0 && new_date < this.dates[i]){
|
||
this.pickers[i--].setUTCDate(new_date);
|
||
}
|
||
}
|
||
else if (new_date > this.dates[i]){
|
||
// Date being moved later/right
|
||
while (i < l && new_date > this.dates[i]){
|
||
this.pickers[i++].setUTCDate(new_date);
|
||
}
|
||
}
|
||
this.updateDates();
|
||
|
||
delete this.updating;
|
||
},
|
||
remove: function(){
|
||
$.map(this.pickers, function(p){ p.remove(); });
|
||
delete this.element.data().datepicker;
|
||
}
|
||
};
|
||
|
||
function opts_from_el(el, prefix){
|
||
// Derive options from element data-attrs
|
||
var data = $(el).data(),
|
||
out = {}, inkey,
|
||
replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');
|
||
prefix = new RegExp('^' + prefix.toLowerCase());
|
||
function re_lower(_,a){
|
||
return a.toLowerCase();
|
||
}
|
||
for (var key in data)
|
||
if (prefix.test(key)){
|
||
inkey = key.replace(replace, re_lower);
|
||
out[inkey] = data[key];
|
||
}
|
||
return out;
|
||
}
|
||
|
||
function opts_from_locale(lang){
|
||
// Derive options from locale plugins
|
||
var out = {};
|
||
// Check if "de-DE" style date is available, if not language should
|
||
// fallback to 2 letter code eg "de"
|
||
if (!dates[lang]){
|
||
lang = lang.split('-')[0];
|
||
if (!dates[lang])
|
||
return;
|
||
}
|
||
var d = dates[lang];
|
||
$.each(locale_opts, function(i,k){
|
||
if (k in d)
|
||
out[k] = d[k];
|
||
});
|
||
return out;
|
||
}
|
||
|
||
var old = $.fn.datepicker;
|
||
$.fn.datepicker = function(option){
|
||
var args = Array.apply(null, arguments);
|
||
args.shift();
|
||
var internal_return;
|
||
this.each(function(){
|
||
var $this = $(this),
|
||
data = $this.data('datepicker'),
|
||
options = typeof option === 'object' && option;
|
||
if (!data){
|
||
var elopts = opts_from_el(this, 'date'),
|
||
// Preliminary otions
|
||
xopts = $.extend({}, defaults, elopts, options),
|
||
locopts = opts_from_locale(xopts.language),
|
||
// Options priority: js args, data-attrs, locales, defaults
|
||
opts = $.extend({}, defaults, locopts, elopts, options);
|
||
if ($this.is('.input-daterange') || opts.inputs){
|
||
var ropts = {
|
||
inputs: opts.inputs || $this.find('input').toArray()
|
||
};
|
||
$this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts))));
|
||
}
|
||
else {
|
||
$this.data('datepicker', (data = new Datepicker(this, opts)));
|
||
}
|
||
}
|
||
if (typeof option === 'string' && typeof data[option] === 'function'){
|
||
internal_return = data[option].apply(data, args);
|
||
if (internal_return !== undefined)
|
||
return false;
|
||
}
|
||
});
|
||
if (internal_return !== undefined)
|
||
return internal_return;
|
||
else
|
||
return this;
|
||
};
|
||
|
||
var defaults = $.fn.datepicker.defaults = {
|
||
autoclose: false,
|
||
beforeShowDay: $.noop,
|
||
calendarWeeks: false,
|
||
clearBtn: false,
|
||
daysOfWeekDisabled: [],
|
||
endDate: Infinity,
|
||
forceParse: true,
|
||
format: 'mm/dd/yyyy',
|
||
keyboardNavigation: true,
|
||
language: 'en',
|
||
minViewMode: 0,
|
||
multidate: false,
|
||
multidateSeparator: ',',
|
||
orientation: "auto",
|
||
rtl: false,
|
||
startDate: -Infinity,
|
||
startView: 0,
|
||
todayBtn: false,
|
||
todayHighlight: false,
|
||
weekStart: 0
|
||
};
|
||
var locale_opts = $.fn.datepicker.locale_opts = [
|
||
'format',
|
||
'rtl',
|
||
'weekStart'
|
||
];
|
||
$.fn.datepicker.Constructor = Datepicker;
|
||
var dates = $.fn.datepicker.dates = {
|
||
en: {
|
||
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
|
||
daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
|
||
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
|
||
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||
today: "Today",
|
||
clear: "Clear"
|
||
}
|
||
};
|
||
|
||
var DPGlobal = {
|
||
modes: [
|
||
{
|
||
clsName: 'days',
|
||
navFnc: 'Month',
|
||
navStep: 1
|
||
},
|
||
{
|
||
clsName: 'months',
|
||
navFnc: 'FullYear',
|
||
navStep: 1
|
||
},
|
||
{
|
||
clsName: 'years',
|
||
navFnc: 'FullYear',
|
||
navStep: 10
|
||
}],
|
||
isLeapYear: function(year){
|
||
return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
|
||
},
|
||
getDaysInMonth: function(year, month){
|
||
return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
|
||
},
|
||
validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
|
||
nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,
|
||
parseFormat: function(format){
|
||
// IE treats \0 as a string end in inputs (truncating the value),
|
||
// so it's a bad format delimiter, anyway
|
||
var separators = format.replace(this.validParts, '\0').split('\0'),
|
||
parts = format.match(this.validParts);
|
||
if (!separators || !separators.length || !parts || parts.length === 0){
|
||
throw new Error("Invalid date format.");
|
||
}
|
||
return {separators: separators, parts: parts};
|
||
},
|
||
parseDate: function(date, format, language){
|
||
if (!date)
|
||
return undefined;
|
||
if (date instanceof Date)
|
||
return date;
|
||
if (typeof format === 'string')
|
||
format = DPGlobal.parseFormat(format);
|
||
var part_re = /([\-+]\d+)([dmwy])/,
|
||
parts = date.match(/([\-+]\d+)([dmwy])/g),
|
||
part, dir, i;
|
||
if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
|
||
date = new Date();
|
||
for (i=0; i < parts.length; i++){
|
||
part = part_re.exec(parts[i]);
|
||
dir = parseInt(part[1]);
|
||
switch (part[2]){
|
||
case 'd':
|
||
date.setUTCDate(date.getUTCDate() + dir);
|
||
break;
|
||
case 'm':
|
||
date = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir);
|
||
break;
|
||
case 'w':
|
||
date.setUTCDate(date.getUTCDate() + dir * 7);
|
||
break;
|
||
case 'y':
|
||
date = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir);
|
||
break;
|
||
}
|
||
}
|
||
return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
|
||
}
|
||
parts = date && date.match(this.nonpunctuation) || [];
|
||
date = new Date();
|
||
var parsed = {},
|
||
setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
|
||
setters_map = {
|
||
yyyy: function(d,v){
|
||
return d.setUTCFullYear(v);
|
||
},
|
||
yy: function(d,v){
|
||
return d.setUTCFullYear(2000+v);
|
||
},
|
||
m: function(d,v){
|
||
if (isNaN(d))
|
||
return d;
|
||
v -= 1;
|
||
while (v < 0) v += 12;
|
||
v %= 12;
|
||
d.setUTCMonth(v);
|
||
while (d.getUTCMonth() !== v)
|
||
d.setUTCDate(d.getUTCDate()-1);
|
||
return d;
|
||
},
|
||
d: function(d,v){
|
||
return d.setUTCDate(v);
|
||
}
|
||
},
|
||
val, filtered;
|
||
setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
|
||
setters_map['dd'] = setters_map['d'];
|
||
date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
|
||
var fparts = format.parts.slice();
|
||
// Remove noop parts
|
||
if (parts.length !== fparts.length){
|
||
fparts = $(fparts).filter(function(i,p){
|
||
return $.inArray(p, setters_order) !== -1;
|
||
}).toArray();
|
||
}
|
||
// Process remainder
|
||
function match_part(){
|
||
var m = this.slice(0, parts[i].length),
|
||
p = parts[i].slice(0, m.length);
|
||
return m === p;
|
||
}
|
||
if (parts.length === fparts.length){
|
||
var cnt;
|
||
for (i=0, cnt = fparts.length; i < cnt; i++){
|
||
val = parseInt(parts[i], 10);
|
||
part = fparts[i];
|
||
if (isNaN(val)){
|
||
switch (part){
|
||
case 'MM':
|
||
filtered = $(dates[language].months).filter(match_part);
|
||
val = $.inArray(filtered[0], dates[language].months) + 1;
|
||
break;
|
||
case 'M':
|
||
filtered = $(dates[language].monthsShort).filter(match_part);
|
||
val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
|
||
break;
|
||
}
|
||
}
|
||
parsed[part] = val;
|
||
}
|
||
var _date, s;
|
||
for (i=0; i < setters_order.length; i++){
|
||
s = setters_order[i];
|
||
if (s in parsed && !isNaN(parsed[s])){
|
||
_date = new Date(date);
|
||
setters_map[s](_date, parsed[s]);
|
||
if (!isNaN(_date))
|
||
date = _date;
|
||
}
|
||
}
|
||
}
|
||
return date;
|
||
},
|
||
formatDate: function(date, format, language){
|
||
if (!date)
|
||
return '';
|
||
if (typeof format === 'string')
|
||
format = DPGlobal.parseFormat(format);
|
||
var val = {
|
||
d: date.getUTCDate(),
|
||
D: dates[language].daysShort[date.getUTCDay()],
|
||
DD: dates[language].days[date.getUTCDay()],
|
||
m: date.getUTCMonth() + 1,
|
||
M: dates[language].monthsShort[date.getUTCMonth()],
|
||
MM: dates[language].months[date.getUTCMonth()],
|
||
yy: date.getUTCFullYear().toString().substring(2),
|
||
yyyy: date.getUTCFullYear()
|
||
};
|
||
val.dd = (val.d < 10 ? '0' : '') + val.d;
|
||
val.mm = (val.m < 10 ? '0' : '') + val.m;
|
||
date = [];
|
||
var seps = $.extend([], format.separators);
|
||
for (var i=0, cnt = format.parts.length; i <= cnt; i++){
|
||
if (seps.length)
|
||
date.push(seps.shift());
|
||
date.push(val[format.parts[i]]);
|
||
}
|
||
return date.join('');
|
||
},
|
||
headTemplate: '<thead>'+
|
||
'<tr>'+
|
||
'<th class="prev">«</th>'+
|
||
'<th colspan="5" class="datepicker-switch"></th>'+
|
||
'<th class="next">»</th>'+
|
||
'</tr>'+
|
||
'</thead>',
|
||
contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>',
|
||
footTemplate: '<tfoot>'+
|
||
'<tr>'+
|
||
'<th colspan="7" class="today"></th>'+
|
||
'</tr>'+
|
||
'<tr>'+
|
||
'<th colspan="7" class="clear"></th>'+
|
||
'</tr>'+
|
||
'</tfoot>'
|
||
};
|
||
DPGlobal.template = '<div class="datepicker">'+
|
||
'<div class="datepicker-days">'+
|
||
'<table class=" table-condensed">'+
|
||
DPGlobal.headTemplate+
|
||
'<tbody></tbody>'+
|
||
DPGlobal.footTemplate+
|
||
'</table>'+
|
||
'</div>'+
|
||
'<div class="datepicker-months">'+
|
||
'<table class="table-condensed">'+
|
||
DPGlobal.headTemplate+
|
||
DPGlobal.contTemplate+
|
||
DPGlobal.footTemplate+
|
||
'</table>'+
|
||
'</div>'+
|
||
'<div class="datepicker-years">'+
|
||
'<table class="table-condensed">'+
|
||
DPGlobal.headTemplate+
|
||
DPGlobal.contTemplate+
|
||
DPGlobal.footTemplate+
|
||
'</table>'+
|
||
'</div>'+
|
||
'</div>';
|
||
|
||
$.fn.datepicker.DPGlobal = DPGlobal;
|
||
|
||
|
||
/* DATEPICKER NO CONFLICT
|
||
* =================== */
|
||
|
||
$.fn.datepicker.noConflict = function(){
|
||
$.fn.datepicker = old;
|
||
return this;
|
||
};
|
||
|
||
|
||
/* DATEPICKER DATA-API
|
||
* ================== */
|
||
|
||
$(document).on(
|
||
'focus.datepicker.data-api click.datepicker.data-api',
|
||
'[data-provide="datepicker"]',
|
||
function(e){
|
||
var $this = $(this);
|
||
if ($this.data('datepicker'))
|
||
return;
|
||
e.preventDefault();
|
||
// component click requires us to explicitly show it
|
||
$this.datepicker('show');
|
||
}
|
||
);
|
||
$(function(){
|
||
$('[data-provide="datepicker-inline"]').datepicker();
|
||
});
|
||
|
||
}(window.jQuery));
|
||
|
||
/*!
|
||
* typeahead.js 0.9.3
|
||
* https://github.com/twitter/typeahead
|
||
* Copyright 2013 Twitter, Inc. and other contributors; Licensed MIT
|
||
*/
|
||
|
||
!function(a){var b="0.9.3",c={isMsie:function(){var a=/(msie) ([\w.]+)/i.exec(navigator.userAgent);return a?parseInt(a[2],10):!1},isBlankString:function(a){return!a||/^\s*$/.test(a)},escapeRegExChars:function(a){return a.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(a){return"string"==typeof a},isNumber:function(a){return"number"==typeof a},isArray:a.isArray,isFunction:a.isFunction,isObject:a.isPlainObject,isUndefined:function(a){return"undefined"==typeof a},bind:a.proxy,bindAll:function(b){var c;for(var d in b)a.isFunction(c=b[d])&&(b[d]=a.proxy(c,b))},indexOf:function(a,b){for(var c=0;c<a.length;c++)if(a[c]===b)return c;return-1},each:a.each,map:a.map,filter:a.grep,every:function(b,c){var d=!0;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?void 0:!1}),!!d):d},some:function(b,c){var d=!1;return b?(a.each(b,function(a,e){return(d=c.call(null,e,a,b))?!1:void 0}),!!d):d},mixin:a.extend,getUniqueId:function(){var a=0;return function(){return a++}}(),defer:function(a){setTimeout(a,0)},debounce:function(a,b,c){var d,e;return function(){var f,g,h=this,i=arguments;return f=function(){d=null,c||(e=a.apply(h,i))},g=c&&!d,clearTimeout(d),d=setTimeout(f,b),g&&(e=a.apply(h,i)),e}},throttle:function(a,b){var c,d,e,f,g,h;return g=0,h=function(){g=new Date,e=null,f=a.apply(c,d)},function(){var i=new Date,j=b-(i-g);return c=this,d=arguments,0>=j?(clearTimeout(e),e=null,g=i,f=a.apply(c,d)):e||(e=setTimeout(h,j)),f}},tokenizeQuery:function(b){return a.trim(b).toLowerCase().split(/[\s]+/)},tokenizeText:function(b){return a.trim(b).toLowerCase().split(/[\s\-_]+/)},getProtocol:function(){return location.protocol},noop:function(){}},d=function(){var a=/\s+/;return{on:function(b,c){var d;if(!c)return this;for(this._callbacks=this._callbacks||{},b=b.split(a);d=b.shift();)this._callbacks[d]=this._callbacks[d]||[],this._callbacks[d].push(c);return this},trigger:function(b,c){var d,e;if(!this._callbacks)return this;for(b=b.split(a);d=b.shift();)if(e=this._callbacks[d])for(var f=0;f<e.length;f+=1)e[f].call(this,{type:d,data:c});return this}}}(),e=function(){function b(b){b&&b.el||a.error("EventBus initialized without el"),this.$el=a(b.el)}var d="typeahead:";return c.mixin(b.prototype,{trigger:function(a){var b=[].slice.call(arguments,1);this.$el.trigger(d+a,b)}}),b}(),f=function(){function a(a){this.prefix=["__",a,"__"].join(""),this.ttlKey="__ttl__",this.keyMatcher=new RegExp("^"+this.prefix)}function b(){return(new Date).getTime()}function d(a){return JSON.stringify(c.isUndefined(a)?null:a)}function e(a){return JSON.parse(a)}var f,g;try{f=window.localStorage,f.setItem("~~~","!"),f.removeItem("~~~")}catch(h){f=null}return g=f&&window.JSON?{_prefix:function(a){return this.prefix+a},_ttlKey:function(a){return this._prefix(a)+this.ttlKey},get:function(a){return this.isExpired(a)&&this.remove(a),e(f.getItem(this._prefix(a)))},set:function(a,e,g){return c.isNumber(g)?f.setItem(this._ttlKey(a),d(b()+g)):f.removeItem(this._ttlKey(a)),f.setItem(this._prefix(a),d(e))},remove:function(a){return f.removeItem(this._ttlKey(a)),f.removeItem(this._prefix(a)),this},clear:function(){var a,b,c=[],d=f.length;for(a=0;d>a;a++)(b=f.key(a)).match(this.keyMatcher)&&c.push(b.replace(this.keyMatcher,""));for(a=c.length;a--;)this.remove(c[a]);return this},isExpired:function(a){var d=e(f.getItem(this._ttlKey(a)));return c.isNumber(d)&&b()>d?!0:!1}}:{get:c.noop,set:c.noop,remove:c.noop,clear:c.noop,isExpired:c.noop},c.mixin(a.prototype,g),a}(),g=function(){function a(a){c.bindAll(this),a=a||{},this.sizeLimit=a.sizeLimit||10,this.cache={},this.cachedKeysByAge=[]}return c.mixin(a.prototype,{get:function(a){return this.cache[a]},set:function(a,b){var c;this.cachedKeysByAge.length===this.sizeLimit&&(c=this.cachedKeysByAge.shift(),delete this.cache[c]),this.cache[a]=b,this.cachedKeysByAge.push(a)}}),a}(),h=function(){function b(a){c.bindAll(this),a=c.isString(a)?{url:a}:a,i=i||new g,h=c.isNumber(a.maxParallelRequests)?a.maxParallelRequests:h||6,this.url=a.url,this.wildcard=a.wildcard||"%QUERY",this.filter=a.filter,this.replace=a.replace,this.ajaxSettings={type:"get",cache:a.cache,timeout:a.timeout,dataType:a.dataType||"json",beforeSend:a.beforeSend},this._get=(/^throttle$/i.test(a.rateLimitFn)?c.throttle:c.debounce)(this._get,a.rateLimitWait||300)}function d(){j++}function e(){j--}function f(){return h>j}var h,i,j=0,k={};return c.mixin(b.prototype,{_get:function(a,b){function c(c){var e=d.filter?d.filter(c):c;b&&b(e),i.set(a,c)}var d=this;f()?this._sendRequest(a).done(c):this.onDeckRequestArgs=[].slice.call(arguments,0)},_sendRequest:function(b){function c(){e(),k[b]=null,f.onDeckRequestArgs&&(f._get.apply(f,f.onDeckRequestArgs),f.onDeckRequestArgs=null)}var f=this,g=k[b];return g||(d(),g=k[b]=a.ajax(b,this.ajaxSettings).always(c)),g},get:function(a,b){var d,e,f=this,g=encodeURIComponent(a||"");return b=b||c.noop,d=this.replace?this.replace(this.url,g):this.url.replace(this.wildcard,g),(e=i.get(d))?c.defer(function(){b(f.filter?f.filter(e):e)}):this._get(d,b),!!e}}),b}(),i=function(){function d(b){c.bindAll(this),c.isString(b.template)&&!b.engine&&a.error("no template engine specified"),b.local||b.prefetch||b.remote||a.error("one of local, prefetch, or remote is required"),this.name=b.name||c.getUniqueId(),this.limit=b.limit||5,this.minLength=b.minLength||1,this.header=b.header,this.footer=b.footer,this.valueKey=b.valueKey||"value",this.template=e(b.template,b.engine,this.valueKey),this.local=b.local,this.prefetch=b.prefetch,this.remote=b.remote,this.itemHash={},this.adjacencyList={},this.storage=b.name?new f(b.name):null}function e(a,b,d){var e,f;return c.isFunction(a)?e=a:c.isString(a)?(f=b.compile(a),e=c.bind(f.render,f)):e=function(a){return"<p>"+a[d]+"</p>"},e}var g={thumbprint:"thumbprint",protocol:"protocol",itemHash:"itemHash",adjacencyList:"adjacencyList"};return c.mixin(d.prototype,{_processLocalData:function(a){this._mergeProcessedData(this._processData(a))},_loadPrefetchData:function(d){function e(a){var b=d.filter?d.filter(a):a,e=m._processData(b),f=e.itemHash,h=e.adjacencyList;m.storage&&(m.storage.set(g.itemHash,f,d.ttl),m.storage.set(g.adjacencyList,h,d.ttl),m.storage.set(g.thumbprint,n,d.ttl),m.storage.set(g.protocol,c.getProtocol(),d.ttl)),m._mergeProcessedData(e)}var f,h,i,j,k,l,m=this,n=b+(d.thumbprint||"");return this.storage&&(f=this.storage.get(g.thumbprint),h=this.storage.get(g.protocol),i=this.storage.get(g.itemHash),j=this.storage.get(g.adjacencyList)),k=f!==n||h!==c.getProtocol(),d=c.isString(d)?{url:d}:d,d.ttl=c.isNumber(d.ttl)?d.ttl:864e5,i&&j&&!k?(this._mergeProcessedData({itemHash:i,adjacencyList:j}),l=a.Deferred().resolve()):l=a.getJSON(d.url).done(e),l},_transformDatum:function(a){var b=c.isString(a)?a:a[this.valueKey],d=a.tokens||c.tokenizeText(b),e={value:b,tokens:d};return c.isString(a)?(e.datum={},e.datum[this.valueKey]=a):e.datum=a,e.tokens=c.filter(e.tokens,function(a){return!c.isBlankString(a)}),e.tokens=c.map(e.tokens,function(a){return a.toLowerCase()}),e},_processData:function(a){var b=this,d={},e={};return c.each(a,function(a,f){var g=b._transformDatum(f),h=c.getUniqueId(g.value);d[h]=g,c.each(g.tokens,function(a,b){var d=b.charAt(0),f=e[d]||(e[d]=[h]);!~c.indexOf(f,h)&&f.push(h)})}),{itemHash:d,adjacencyList:e}},_mergeProcessedData:function(a){var b=this;c.mixin(this.itemHash,a.itemHash),c.each(a.adjacencyList,function(a,c){var d=b.adjacencyList[a];b.adjacencyList[a]=d?d.concat(c):c})},_getLocalSuggestions:function(a){var b,d=this,e=[],f=[],g=[];return c.each(a,function(a,b){var d=b.charAt(0);!~c.indexOf(e,d)&&e.push(d)}),c.each(e,function(a,c){var e=d.adjacencyList[c];return e?(f.push(e),(!b||e.length<b.length)&&(b=e),void 0):!1}),f.length<e.length?[]:(c.each(b,function(b,e){var h,i,j=d.itemHash[e];h=c.every(f,function(a){return~c.indexOf(a,e)}),i=h&&c.every(a,function(a){return c.some(j.tokens,function(b){return 0===b.indexOf(a)})}),i&&g.push(j)}),g)},initialize:function(){var b;return this.local&&this._processLocalData(this.local),this.transport=this.remote?new h(this.remote):null,b=this.prefetch?this._loadPrefetchData(this.prefetch):a.Deferred().resolve(),this.local=this.prefetch=this.remote=null,this.initialize=function(){return b},b},getSuggestions:function(a,b){function d(a){f=f.slice(0),c.each(a,function(a,b){var d,e=g._transformDatum(b);return d=c.some(f,function(a){return e.value===a.value}),!d&&f.push(e),f.length<g.limit}),b&&b(f)}var e,f,g=this,h=!1;a.length<this.minLength||(e=c.tokenizeQuery(a),f=this._getLocalSuggestions(e).slice(0,this.limit),f.length<this.limit&&this.transport&&(h=this.transport.get(a,d)),!h&&b&&b(f))}}),d}(),j=function(){function b(b){var d=this;c.bindAll(this),this.specialKeyCodeMap={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"},this.$hint=a(b.hint),this.$input=a(b.input).on("blur.tt",this._handleBlur).on("focus.tt",this._handleFocus).on("keydown.tt",this._handleSpecialKeyEvent),c.isMsie()?this.$input.on("keydown.tt keypress.tt cut.tt paste.tt",function(a){d.specialKeyCodeMap[a.which||a.keyCode]||c.defer(d._compareQueryToInputValue)}):this.$input.on("input.tt",this._compareQueryToInputValue),this.query=this.$input.val(),this.$overflowHelper=e(this.$input)}function e(b){return a("<span></span>").css({position:"absolute",left:"-9999px",visibility:"hidden",whiteSpace:"nowrap",fontFamily:b.css("font-family"),fontSize:b.css("font-size"),fontStyle:b.css("font-style"),fontVariant:b.css("font-variant"),fontWeight:b.css("font-weight"),wordSpacing:b.css("word-spacing"),letterSpacing:b.css("letter-spacing"),textIndent:b.css("text-indent"),textRendering:b.css("text-rendering"),textTransform:b.css("text-transform")}).insertAfter(b)}function f(a,b){return a=(a||"").replace(/^\s*/g,"").replace(/\s{2,}/g," "),b=(b||"").replace(/^\s*/g,"").replace(/\s{2,}/g," "),a===b}return c.mixin(b.prototype,d,{_handleFocus:function(){this.trigger("focused")},_handleBlur:function(){this.trigger("blured")},_handleSpecialKeyEvent:function(a){var b=this.specialKeyCodeMap[a.which||a.keyCode];b&&this.trigger(b+"Keyed",a)},_compareQueryToInputValue:function(){var a=this.getInputValue(),b=f(this.query,a),c=b?this.query.length!==a.length:!1;c?this.trigger("whitespaceChanged",{value:this.query}):b||this.trigger("queryChanged",{value:this.query=a})},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$hint=this.$input=this.$overflowHelper=null},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(a){this.query=a},getInputValue:function(){return this.$input.val()},setInputValue:function(a,b){this.$input.val(a),!b&&this._compareQueryToInputValue()},getHintValue:function(){return this.$hint.val()},setHintValue:function(a){this.$hint.val(a)},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},isOverflow:function(){return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>this.$input.width()},isCursorAtEnd:function(){var a,b=this.$input.val().length,d=this.$input[0].selectionStart;return c.isNumber(d)?d===b:document.selection?(a=document.selection.createRange(),a.moveStart("character",-b),b===a.text.length):!0}}),b}(),k=function(){function b(b){c.bindAll(this),this.isOpen=!1,this.isEmpty=!0,this.isMouseOverDropdown=!1,this.$menu=a(b.menu).on("mouseenter.tt",this._handleMouseenter).on("mouseleave.tt",this._handleMouseleave).on("click.tt",".tt-suggestion",this._handleSelection).on("mouseover.tt",".tt-suggestion",this._handleMouseover)}function e(a){return a.data("suggestion")}var f={suggestionsList:'<span class="tt-suggestions"></span>'},g={suggestionsList:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"}};return c.mixin(b.prototype,d,{_handleMouseenter:function(){this.isMouseOverDropdown=!0},_handleMouseleave:function(){this.isMouseOverDropdown=!1},_handleMouseover:function(b){var c=a(b.currentTarget);this._getSuggestions().removeClass("tt-is-under-cursor"),c.addClass("tt-is-under-cursor")},_handleSelection:function(b){var c=a(b.currentTarget);this.trigger("suggestionSelected",e(c))},_show:function(){this.$menu.css("display","block")},_hide:function(){this.$menu.hide()},_moveCursor:function(a){var b,c,d,f;if(this.isVisible()){if(b=this._getSuggestions(),c=b.filter(".tt-is-under-cursor"),c.removeClass("tt-is-under-cursor"),d=b.index(c)+a,d=(d+1)%(b.length+1)-1,-1===d)return this.trigger("cursorRemoved"),void 0;-1>d&&(d=b.length-1),f=b.eq(d).addClass("tt-is-under-cursor"),this._ensureVisibility(f),this.trigger("cursorMoved",e(f))}},_getSuggestions:function(){return this.$menu.find(".tt-suggestions > .tt-suggestion")},_ensureVisibility:function(a){var b=this.$menu.height()+parseInt(this.$menu.css("paddingTop"),10)+parseInt(this.$menu.css("paddingBottom"),10),c=this.$menu.scrollTop(),d=a.position().top,e=d+a.outerHeight(!0);0>d?this.$menu.scrollTop(c+d):e>b&&this.$menu.scrollTop(c+(e-b))},destroy:function(){this.$menu.off(".tt"),this.$menu=null},isVisible:function(){return this.isOpen&&!this.isEmpty},closeUnlessMouseIsOverDropdown:function(){this.isMouseOverDropdown||this.close()},close:function(){this.isOpen&&(this.isOpen=!1,this.isMouseOverDropdown=!1,this._hide(),this.$menu.find(".tt-suggestions > .tt-suggestion").removeClass("tt-is-under-cursor"),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,!this.isEmpty&&this._show(),this.trigger("opened"))},setLanguageDirection:function(a){var b={left:"0",right:"auto"},c={left:"auto",right:" 0"};"ltr"===a?this.$menu.css(b):this.$menu.css(c)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getSuggestionUnderCursor:function(){var a=this._getSuggestions().filter(".tt-is-under-cursor").first();return a.length>0?e(a):null},getFirstSuggestion:function(){var a=this._getSuggestions().first();return a.length>0?e(a):null},renderSuggestions:function(b,d){var e,h,i,j,k,l="tt-dataset-"+b.name,m='<div class="tt-suggestion">%body</div>',n=this.$menu.find("."+l);0===n.length&&(h=a(f.suggestionsList).css(g.suggestionsList),n=a("<div></div>").addClass(l).append(b.header).append(h).append(b.footer).appendTo(this.$menu)),d.length>0?(this.isEmpty=!1,this.isOpen&&this._show(),i=document.createElement("div"),j=document.createDocumentFragment(),c.each(d,function(c,d){d.dataset=b.name,e=b.template(d.datum),i.innerHTML=m.replace("%body",e),k=a(i.firstChild).css(g.suggestion).data("suggestion",d),k.children().each(function(){a(this).css(g.suggestionChild)}),j.appendChild(k[0])}),n.show().find(".tt-suggestions").html(j)):this.clearSuggestions(b.name),this.trigger("suggestionsRendered")},clearSuggestions:function(a){var b=a?this.$menu.find(".tt-dataset-"+a):this.$menu.find('[class^="tt-dataset-"]'),c=b.find(".tt-suggestions");b.hide(),c.empty(),0===this._getSuggestions().length&&(this.isEmpty=!0,this._hide())}}),b}(),l=function(){function b(a){var b,d,f;c.bindAll(this),this.$node=e(a.input),this.datasets=a.datasets,this.dir=null,this.eventBus=a.eventBus,b=this.$node.find(".tt-dropdown-menu"),d=this.$node.find(".tt-query"),f=this.$node.find(".tt-hint"),this.dropdownView=new k({menu:b}).on("suggestionSelected",this._handleSelection).on("cursorMoved",this._clearHint).on("cursorMoved",this._setInputValueToSuggestionUnderCursor).on("cursorRemoved",this._setInputValueToQuery).on("cursorRemoved",this._updateHint).on("suggestionsRendered",this._updateHint).on("opened",this._updateHint).on("closed",this._clearHint).on("opened closed",this._propagateEvent),this.inputView=new j({input:d,hint:f}).on("focused",this._openDropdown).on("blured",this._closeDropdown).on("blured",this._setInputValueToQuery).on("enterKeyed tabKeyed",this._handleSelection).on("queryChanged",this._clearHint).on("queryChanged",this._clearSuggestions).on("queryChanged",this._getSuggestions).on("whitespaceChanged",this._updateHint).on("queryChanged whitespaceChanged",this._openDropdown).on("queryChanged whitespaceChanged",this._setLanguageDirection).on("escKeyed",this._closeDropdown).on("escKeyed",this._setInputValueToQuery).on("tabKeyed upKeyed downKeyed",this._managePreventDefault).on("upKeyed downKeyed",this._moveDropdownCursor).on("upKeyed downKeyed",this._openDropdown).on("tabKeyed leftKeyed rightKeyed",this._autocomplete)}function e(b){var c=a(g.wrapper),d=a(g.dropdown),e=a(b),f=a(g.hint);c=c.css(h.wrapper),d=d.css(h.dropdown),f.css(h.hint).css({backgroundAttachment:e.css("background-attachment"),backgroundClip:e.css("background-clip"),backgroundColor:e.css("background-color"),backgroundImage:e.css("background-image"),backgroundOrigin:e.css("background-origin"),backgroundPosition:e.css("background-position"),backgroundRepeat:e.css("background-repeat"),backgroundSize:e.css("background-size")}),e.data("ttAttrs",{dir:e.attr("dir"),autocomplete:e.attr("autocomplete"),spellcheck:e.attr("spellcheck"),style:e.attr("style")}),e.addClass("tt-query").attr({autocomplete:"off",spellcheck:!1}).css(h.query);try{!e.attr("dir")&&e.attr("dir","auto")}catch(i){}return e.wrap(c).parent().prepend(f).append(d)}function f(a){var b=a.find(".tt-query");c.each(b.data("ttAttrs"),function(a,d){c.isUndefined(d)?b.removeAttr(a):b.attr(a,d)}),b.detach().removeData("ttAttrs").removeClass("tt-query").insertAfter(a),a.remove()}var g={wrapper:'<span class="twitter-typeahead"></span>',hint:'<input class="tt-hint" type="text" autocomplete="off" spellcheck="off" disabled>',dropdown:'<span class="tt-dropdown-menu"></span>'},h={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none"},query:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"}};return c.isMsie()&&c.mixin(h.query,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),c.isMsie()&&c.isMsie()<=7&&(c.mixin(h.wrapper,{display:"inline",zoom:"1"}),c.mixin(h.query,{marginTop:"-1px"})),c.mixin(b.prototype,d,{_managePreventDefault:function(a){var b,c,d=a.data,e=!1;switch(a.type){case"tabKeyed":b=this.inputView.getHintValue(),c=this.inputView.getInputValue(),e=b&&b!==c;break;case"upKeyed":case"downKeyed":e=!d.shiftKey&&!d.ctrlKey&&!d.metaKey}e&&d.preventDefault()},_setLanguageDirection:function(){var a=this.inputView.getLanguageDirection();a!==this.dir&&(this.dir=a,this.$node.css("direction",a),this.dropdownView.setLanguageDirection(a))},_updateHint:function(){var a,b,d,e,f,g=this.dropdownView.getFirstSuggestion(),h=g?g.value:null,i=this.dropdownView.isVisible(),j=this.inputView.isOverflow();h&&i&&!j&&(a=this.inputView.getInputValue(),b=a.replace(/\s{2,}/g," ").replace(/^\s+/g,""),d=c.escapeRegExChars(b),e=new RegExp("^(?:"+d+")(.*$)","i"),f=e.exec(h),this.inputView.setHintValue(a+(f?f[1]:"")))},_clearHint:function(){this.inputView.setHintValue("")},_clearSuggestions:function(){this.dropdownView.clearSuggestions()},_setInputValueToQuery:function(){this.inputView.setInputValue(this.inputView.getQuery())},_setInputValueToSuggestionUnderCursor:function(a){var b=a.data;this.inputView.setInputValue(b.value,!0)},_openDropdown:function(){this.dropdownView.open()},_closeDropdown:function(a){this.dropdownView["blured"===a.type?"closeUnlessMouseIsOverDropdown":"close"]()},_moveDropdownCursor:function(a){var b=a.data;b.shiftKey||b.ctrlKey||b.metaKey||this.dropdownView["upKeyed"===a.type?"moveCursorUp":"moveCursorDown"]()},_handleSelection:function(a){var b="suggestionSelected"===a.type,d=b?a.data:this.dropdownView.getSuggestionUnderCursor();d&&(this.inputView.setInputValue(d.value),b?this.inputView.focus():a.data.preventDefault(),b&&c.isMsie()?c.defer(this.dropdownView.close):this.dropdownView.close(),this.eventBus.trigger("selected",d.datum,d.dataset))},_getSuggestions:function(){var a=this,b=this.inputView.getQuery();c.isBlankString(b)||c.each(this.datasets,function(c,d){d.getSuggestions(b,function(c){b===a.inputView.getQuery()&&a.dropdownView.renderSuggestions(d,c)})})},_autocomplete:function(a){var b,c,d,e,f;("rightKeyed"!==a.type&&"leftKeyed"!==a.type||(b=this.inputView.isCursorAtEnd(),c="ltr"===this.inputView.getLanguageDirection()?"leftKeyed"===a.type:"rightKeyed"===a.type,b&&!c))&&(d=this.inputView.getQuery(),e=this.inputView.getHintValue(),""!==e&&d!==e&&(f=this.dropdownView.getFirstSuggestion(),this.inputView.setInputValue(f.value),this.eventBus.trigger("autocompleted",f.datum,f.dataset)))},_propagateEvent:function(a){this.eventBus.trigger(a.type)},destroy:function(){this.inputView.destroy(),this.dropdownView.destroy(),f(this.$node),this.$node=null},setQuery:function(a){this.inputView.setQuery(a),this.inputView.setInputValue(a),this._clearHint(),this._clearSuggestions(),this._getSuggestions()}}),b}();!function(){var b,d={},f="ttView";b={initialize:function(b){function g(){var b,d=a(this),g=new e({el:d});b=c.map(h,function(a){return a.initialize()}),d.data(f,new l({input:d,eventBus:g=new e({el:d}),datasets:h})),a.when.apply(a,b).always(function(){c.defer(function(){g.trigger("initialized")})})}var h;return b=c.isArray(b)?b:[b],0===b.length&&a.error("no datasets provided"),h=c.map(b,function(a){var b=d[a.name]?d[a.name]:new i(a);return a.name&&(d[a.name]=b),b}),this.each(g)},destroy:function(){function b(){var b=a(this),c=b.data(f);c&&(c.destroy(),b.removeData(f))}return this.each(b)},setQuery:function(b){function c(){var c=a(this).data(f);c&&c.setQuery(b)}return this.each(c)}},jQuery.fn.typeahead=function(a){return b[a]?b[a].apply(this,[].slice.call(arguments,1)):b.initialize.apply(this,arguments)}}()}(window.jQuery);
|
||
/*!
|
||
* accounting.js v0.3.2, copyright 2011 Joss Crowcroft, MIT license, http://josscrowcroft.github.com/accounting.js
|
||
*/
|
||
(function(p,z){function q(a){return!!(""===a||a&&a.charCodeAt&&a.substr)}function m(a){return u?u(a):"[object Array]"===v.call(a)}function r(a){return"[object Object]"===v.call(a)}function s(a,b){var d,a=a||{},b=b||{};for(d in b)b.hasOwnProperty(d)&&null==a[d]&&(a[d]=b[d]);return a}function j(a,b,d){var c=[],e,h;if(!a)return c;if(w&&a.map===w)return a.map(b,d);for(e=0,h=a.length;e<h;e++)c[e]=b.call(d,a[e],e,a);return c}function n(a,b){a=Math.round(Math.abs(a));return isNaN(a)?b:a}function x(a){var b=c.settings.currency.format;"function"===typeof a&&(a=a());return q(a)&&a.match("%v")?{pos:a,neg:a.replace("-","").replace("%v","-%v"),zero:a}:!a||!a.pos||!a.pos.match("%v")?!q(b)?b:c.settings.currency.format={pos:b,neg:b.replace("%v","-%v"),zero:b}:a}var c={version:"0.3.2",settings:{currency:{symbol:"$",format:"%s%v",decimal:".",thousand:",",precision:2,grouping:3},number:{precision:0,grouping:3,thousand:",",decimal:"."}}},w=Array.prototype.map,u=Array.isArray,v=Object.prototype.toString,o=c.unformat=c.parse=function(a,b){if(m(a))return j(a,function(a){return o(a,b)});a=a||0;if("number"===typeof a)return a;var b=b||".",c=RegExp("[^0-9-"+b+"]",["g"]),c=parseFloat((""+a).replace(/\((.*)\)/,"-$1").replace(c,"").replace(b,"."));return!isNaN(c)?c:0},y=c.toFixed=function(a,b){var b=n(b,c.settings.number.precision),d=Math.pow(10,b);return(Math.round(c.unformat(a)*d)/d).toFixed(b)},t=c.formatNumber=function(a,b,d,i){if(m(a))return j(a,function(a){return t(a,b,d,i)});var a=o(a),e=s(r(b)?b:{precision:b,thousand:d,decimal:i},c.settings.number),h=n(e.precision),f=0>a?"-":"",g=parseInt(y(Math.abs(a||0),h),10)+"",l=3<g.length?g.length%3:0;return f+(l?g.substr(0,l)+e.thousand:"")+g.substr(l).replace(/(\d{3})(?=\d)/g,"$1"+e.thousand)+(h?e.decimal+y(Math.abs(a),h).split(".")[1]:"")},A=c.formatMoney=function(a,b,d,i,e,h){if(m(a))return j(a,function(a){return A(a,b,d,i,e,h)});var a=o(a),f=s(r(b)?b:{symbol:b,precision:d,thousand:i,decimal:e,format:h},c.settings.currency),g=x(f.format);return(0<a?g.pos:0>a?g.neg:g.zero).replace("%s",f.symbol).replace("%v",t(Math.abs(a),n(f.precision),f.thousand,f.decimal))};c.formatColumn=function(a,b,d,i,e,h){if(!a)return[];var f=s(r(b)?b:{symbol:b,precision:d,thousand:i,decimal:e,format:h},c.settings.currency),g=x(f.format),l=g.pos.indexOf("%s")<g.pos.indexOf("%v")?!0:!1,k=0,a=j(a,function(a){if(m(a))return c.formatColumn(a,f);a=o(a);a=(0<a?g.pos:0>a?g.neg:g.zero).replace("%s",f.symbol).replace("%v",t(Math.abs(a),n(f.precision),f.thousand,f.decimal));if(a.length>k)k=a.length;return a});return j(a,function(a){return q(a)&&a.length<k?l?a.replace(f.symbol,f.symbol+Array(k-a.length+1).join(" ")):Array(k-a.length+1).join(" ")+a:a})};if("undefined"!==typeof exports){if("undefined"!==typeof module&&module.exports)exports=module.exports=c;exports.accounting=c}else"function"===typeof define&&define.amd?define([],function(){return c}):(c.noConflict=function(a){return function(){p.accounting=a;c.noConflict=z;return c}}(p.accounting),p.accounting=c)})(this);
|
||
// Spectrum Colorpicker v1.3.4
|
||
// https://github.com/bgrins/spectrum
|
||
// Author: Brian Grinstead
|
||
// License: MIT
|
||
|
||
(function (window, $, undefined) {
|
||
var defaultOpts = {
|
||
|
||
// Callbacks
|
||
beforeShow: noop,
|
||
move: noop,
|
||
change: noop,
|
||
show: noop,
|
||
hide: noop,
|
||
|
||
// Options
|
||
color: false,
|
||
flat: false,
|
||
showInput: false,
|
||
allowEmpty: false,
|
||
showButtons: true,
|
||
clickoutFiresChange: false,
|
||
showInitial: false,
|
||
showPalette: false,
|
||
showPaletteOnly: false,
|
||
showSelectionPalette: true,
|
||
localStorageKey: false,
|
||
appendTo: "body",
|
||
maxSelectionSize: 7,
|
||
cancelText: "cancel",
|
||
chooseText: "choose",
|
||
clearText: "Clear Color Selection",
|
||
preferredFormat: false,
|
||
className: "", // Deprecated - use containerClassName and replacerClassName instead.
|
||
containerClassName: "",
|
||
replacerClassName: "",
|
||
showAlpha: false,
|
||
theme: "sp-light",
|
||
palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
|
||
selectionPalette: [],
|
||
disabled: false
|
||
},
|
||
spectrums = [],
|
||
IE = !!/msie/i.exec( window.navigator.userAgent ),
|
||
rgbaSupport = (function() {
|
||
function contains( str, substr ) {
|
||
return !!~('' + str).indexOf(substr);
|
||
}
|
||
|
||
var elem = document.createElement('div');
|
||
var style = elem.style;
|
||
style.cssText = 'background-color:rgba(0,0,0,.5)';
|
||
return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
|
||
})(),
|
||
inputTypeColorSupport = (function() {
|
||
var colorInput = $("<input type='color' value='!' />")[0];
|
||
return colorInput.type === "color" && colorInput.value !== "!";
|
||
})(),
|
||
replaceInput = [
|
||
"<div class='sp-replacer'>",
|
||
"<div class='sp-preview'><div class='sp-preview-inner'></div></div>",
|
||
"<div class='sp-dd'>▼</div>",
|
||
"</div>"
|
||
].join(''),
|
||
markup = (function () {
|
||
|
||
// IE does not support gradients with multiple stops, so we need to simulate
|
||
// that for the rainbow slider with 8 divs that each have a single gradient
|
||
var gradientFix = "";
|
||
if (IE) {
|
||
for (var i = 1; i <= 6; i++) {
|
||
gradientFix += "<div class='sp-" + i + "'></div>";
|
||
}
|
||
}
|
||
|
||
return [
|
||
"<div class='sp-container sp-hidden'>",
|
||
"<div class='sp-palette-container'>",
|
||
"<div class='sp-palette sp-thumb sp-cf'></div>",
|
||
"</div>",
|
||
"<div class='sp-picker-container'>",
|
||
"<div class='sp-top sp-cf'>",
|
||
"<div class='sp-fill'></div>",
|
||
"<div class='sp-top-inner'>",
|
||
"<div class='sp-color'>",
|
||
"<div class='sp-sat'>",
|
||
"<div class='sp-val'>",
|
||
"<div class='sp-dragger'></div>",
|
||
"</div>",
|
||
"</div>",
|
||
"</div>",
|
||
"<div class='sp-clear sp-clear-display'>",
|
||
"</div>",
|
||
"<div class='sp-hue'>",
|
||
"<div class='sp-slider'></div>",
|
||
gradientFix,
|
||
"</div>",
|
||
"</div>",
|
||
"<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
|
||
"</div>",
|
||
"<div class='sp-input-container sp-cf'>",
|
||
"<input class='sp-input' type='text' spellcheck='false' />",
|
||
"</div>",
|
||
"<div class='sp-initial sp-thumb sp-cf'></div>",
|
||
"<div class='sp-button-container sp-cf'>",
|
||
"<a class='sp-cancel' href='#'></a>",
|
||
"<button type='button' class='sp-choose'></button>",
|
||
"</div>",
|
||
"</div>",
|
||
"</div>"
|
||
].join("");
|
||
})();
|
||
|
||
function paletteTemplate (p, color, className, tooltipFormat) {
|
||
var html = [];
|
||
for (var i = 0; i < p.length; i++) {
|
||
var current = p[i];
|
||
if(current) {
|
||
var tiny = tinycolor(current);
|
||
var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
|
||
c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
|
||
|
||
var formattedString = tiny.toString(tooltipFormat || "rgb");
|
||
var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
|
||
html.push('<span title="' + formattedString + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';" /></span>');
|
||
} else {
|
||
var cls = 'sp-clear-display';
|
||
html.push('<span title="No Color Selected" data-color="" style="background-color:transparent;" class="' + cls + '"></span>');
|
||
}
|
||
}
|
||
return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>";
|
||
}
|
||
|
||
function hideAll() {
|
||
for (var i = 0; i < spectrums.length; i++) {
|
||
if (spectrums[i]) {
|
||
spectrums[i].hide();
|
||
}
|
||
}
|
||
}
|
||
|
||
function instanceOptions(o, callbackContext) {
|
||
var opts = $.extend({}, defaultOpts, o);
|
||
opts.callbacks = {
|
||
'move': bind(opts.move, callbackContext),
|
||
'change': bind(opts.change, callbackContext),
|
||
'show': bind(opts.show, callbackContext),
|
||
'hide': bind(opts.hide, callbackContext),
|
||
'beforeShow': bind(opts.beforeShow, callbackContext)
|
||
};
|
||
|
||
return opts;
|
||
}
|
||
|
||
function spectrum(element, o) {
|
||
|
||
var opts = instanceOptions(o, element),
|
||
flat = opts.flat,
|
||
showSelectionPalette = opts.showSelectionPalette,
|
||
localStorageKey = opts.localStorageKey,
|
||
theme = opts.theme,
|
||
callbacks = opts.callbacks,
|
||
resize = throttle(reflow, 10),
|
||
visible = false,
|
||
dragWidth = 0,
|
||
dragHeight = 0,
|
||
dragHelperHeight = 0,
|
||
slideHeight = 0,
|
||
slideWidth = 0,
|
||
alphaWidth = 0,
|
||
alphaSlideHelperWidth = 0,
|
||
slideHelperHeight = 0,
|
||
currentHue = 0,
|
||
currentSaturation = 0,
|
||
currentValue = 0,
|
||
currentAlpha = 1,
|
||
palette = [],
|
||
paletteArray = [],
|
||
paletteLookup = {},
|
||
selectionPalette = opts.selectionPalette.slice(0),
|
||
maxSelectionSize = opts.maxSelectionSize,
|
||
draggingClass = "sp-dragging",
|
||
shiftMovementDirection = null;
|
||
|
||
var doc = element.ownerDocument,
|
||
body = doc.body,
|
||
boundElement = $(element),
|
||
disabled = false,
|
||
container = $(markup, doc).addClass(theme),
|
||
dragger = container.find(".sp-color"),
|
||
dragHelper = container.find(".sp-dragger"),
|
||
slider = container.find(".sp-hue"),
|
||
slideHelper = container.find(".sp-slider"),
|
||
alphaSliderInner = container.find(".sp-alpha-inner"),
|
||
alphaSlider = container.find(".sp-alpha"),
|
||
alphaSlideHelper = container.find(".sp-alpha-handle"),
|
||
textInput = container.find(".sp-input"),
|
||
paletteContainer = container.find(".sp-palette"),
|
||
initialColorContainer = container.find(".sp-initial"),
|
||
cancelButton = container.find(".sp-cancel"),
|
||
clearButton = container.find(".sp-clear"),
|
||
chooseButton = container.find(".sp-choose"),
|
||
isInput = boundElement.is("input"),
|
||
isInputTypeColor = isInput && inputTypeColorSupport && boundElement.attr("type") === "color",
|
||
shouldReplace = isInput && !flat,
|
||
replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),
|
||
offsetElement = (shouldReplace) ? replacer : boundElement,
|
||
previewElement = replacer.find(".sp-preview-inner"),
|
||
initialColor = opts.color || (isInput && boundElement.val()),
|
||
colorOnShow = false,
|
||
preferredFormat = opts.preferredFormat,
|
||
currentPreferredFormat = preferredFormat,
|
||
clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange,
|
||
isEmpty = !initialColor,
|
||
allowEmpty = opts.allowEmpty && !isInputTypeColor;
|
||
|
||
function applyOptions() {
|
||
|
||
if (opts.showPaletteOnly) {
|
||
opts.showPalette = true;
|
||
}
|
||
|
||
if (opts.palette) {
|
||
palette = opts.palette.slice(0);
|
||
paletteArray = $.isArray(palette[0]) ? palette : [palette];
|
||
paletteLookup = {};
|
||
for (var i = 0; i < paletteArray.length; i++) {
|
||
for (var j = 0; j < paletteArray[i].length; j++) {
|
||
var rgb = tinycolor(paletteArray[i][j]).toRgbString();
|
||
paletteLookup[rgb] = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
container.toggleClass("sp-flat", flat);
|
||
container.toggleClass("sp-input-disabled", !opts.showInput);
|
||
container.toggleClass("sp-alpha-enabled", opts.showAlpha);
|
||
container.toggleClass("sp-clear-enabled", allowEmpty);
|
||
container.toggleClass("sp-buttons-disabled", !opts.showButtons);
|
||
container.toggleClass("sp-palette-disabled", !opts.showPalette);
|
||
container.toggleClass("sp-palette-only", opts.showPaletteOnly);
|
||
container.toggleClass("sp-initial-disabled", !opts.showInitial);
|
||
container.addClass(opts.className).addClass(opts.containerClassName);
|
||
|
||
reflow();
|
||
}
|
||
|
||
function initialize() {
|
||
|
||
if (IE) {
|
||
container.find("*:not(input)").attr("unselectable", "on");
|
||
}
|
||
|
||
applyOptions();
|
||
|
||
if (shouldReplace) {
|
||
boundElement.after(replacer).hide();
|
||
}
|
||
|
||
if (!allowEmpty) {
|
||
clearButton.hide();
|
||
}
|
||
|
||
if (flat) {
|
||
boundElement.after(container).hide();
|
||
}
|
||
else {
|
||
|
||
var appendTo = opts.appendTo === "parent" ? boundElement.parent() : $(opts.appendTo);
|
||
if (appendTo.length !== 1) {
|
||
appendTo = $("body");
|
||
}
|
||
|
||
appendTo.append(container);
|
||
}
|
||
|
||
updateSelectionPaletteFromStorage();
|
||
|
||
offsetElement.bind("click.spectrum touchstart.spectrum", function (e) {
|
||
if (!disabled) {
|
||
toggle();
|
||
}
|
||
|
||
e.stopPropagation();
|
||
|
||
if (!$(e.target).is("input")) {
|
||
e.preventDefault();
|
||
}
|
||
});
|
||
|
||
if(boundElement.is(":disabled") || (opts.disabled === true)) {
|
||
disable();
|
||
}
|
||
|
||
// Prevent clicks from bubbling up to document. This would cause it to be hidden.
|
||
container.click(stopPropagation);
|
||
|
||
// Handle user typed input
|
||
textInput.change(setFromTextInput);
|
||
textInput.bind("paste", function () {
|
||
setTimeout(setFromTextInput, 1);
|
||
});
|
||
textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } });
|
||
|
||
cancelButton.text(opts.cancelText);
|
||
cancelButton.bind("click.spectrum", function (e) {
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
hide("cancel");
|
||
});
|
||
|
||
clearButton.attr("title", opts.clearText);
|
||
clearButton.bind("click.spectrum", function (e) {
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
isEmpty = true;
|
||
move();
|
||
|
||
if(flat) {
|
||
//for the flat style, this is a change event
|
||
updateOriginalInput(true);
|
||
}
|
||
});
|
||
|
||
chooseButton.text(opts.chooseText);
|
||
chooseButton.bind("click.spectrum", function (e) {
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
|
||
if (isValid()) {
|
||
updateOriginalInput(true);
|
||
hide();
|
||
}
|
||
});
|
||
|
||
draggable(alphaSlider, function (dragX, dragY, e) {
|
||
currentAlpha = (dragX / alphaWidth);
|
||
isEmpty = false;
|
||
if (e.shiftKey) {
|
||
currentAlpha = Math.round(currentAlpha * 10) / 10;
|
||
}
|
||
|
||
move();
|
||
}, dragStart, dragStop);
|
||
|
||
draggable(slider, function (dragX, dragY) {
|
||
currentHue = parseFloat(dragY / slideHeight);
|
||
isEmpty = false;
|
||
if (!opts.showAlpha) {
|
||
currentAlpha = 1;
|
||
}
|
||
move();
|
||
}, dragStart, dragStop);
|
||
|
||
draggable(dragger, function (dragX, dragY, e) {
|
||
|
||
// shift+drag should snap the movement to either the x or y axis.
|
||
if (!e.shiftKey) {
|
||
shiftMovementDirection = null;
|
||
}
|
||
else if (!shiftMovementDirection) {
|
||
var oldDragX = currentSaturation * dragWidth;
|
||
var oldDragY = dragHeight - (currentValue * dragHeight);
|
||
var furtherFromX = Math.abs(dragX - oldDragX) > Math.abs(dragY - oldDragY);
|
||
|
||
shiftMovementDirection = furtherFromX ? "x" : "y";
|
||
}
|
||
|
||
var setSaturation = !shiftMovementDirection || shiftMovementDirection === "x";
|
||
var setValue = !shiftMovementDirection || shiftMovementDirection === "y";
|
||
|
||
if (setSaturation) {
|
||
currentSaturation = parseFloat(dragX / dragWidth);
|
||
}
|
||
if (setValue) {
|
||
currentValue = parseFloat((dragHeight - dragY) / dragHeight);
|
||
}
|
||
|
||
isEmpty = false;
|
||
if (!opts.showAlpha) {
|
||
currentAlpha = 1;
|
||
}
|
||
|
||
move();
|
||
|
||
}, dragStart, dragStop);
|
||
|
||
if (!!initialColor) {
|
||
set(initialColor);
|
||
|
||
// In case color was black - update the preview UI and set the format
|
||
// since the set function will not run (default color is black).
|
||
updateUI();
|
||
currentPreferredFormat = preferredFormat || tinycolor(initialColor).format;
|
||
|
||
addColorToSelectionPalette(initialColor);
|
||
}
|
||
else {
|
||
updateUI();
|
||
}
|
||
|
||
if (flat) {
|
||
show();
|
||
}
|
||
|
||
function palletElementClick(e) {
|
||
if (e.data && e.data.ignore) {
|
||
set($(this).data("color"));
|
||
move();
|
||
}
|
||
else {
|
||
set($(this).data("color"));
|
||
move();
|
||
updateOriginalInput(true);
|
||
hide();
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum";
|
||
paletteContainer.delegate(".sp-thumb-el", paletteEvent, palletElementClick);
|
||
initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, { ignore: true }, palletElementClick);
|
||
}
|
||
|
||
function updateSelectionPaletteFromStorage() {
|
||
|
||
if (localStorageKey && window.localStorage) {
|
||
|
||
// Migrate old palettes over to new format. May want to remove this eventually.
|
||
try {
|
||
var oldPalette = window.localStorage[localStorageKey].split(",#");
|
||
if (oldPalette.length > 1) {
|
||
delete window.localStorage[localStorageKey];
|
||
$.each(oldPalette, function(i, c) {
|
||
addColorToSelectionPalette(c);
|
||
});
|
||
}
|
||
}
|
||
catch(e) { }
|
||
|
||
try {
|
||
selectionPalette = window.localStorage[localStorageKey].split(";");
|
||
}
|
||
catch (e) { }
|
||
}
|
||
}
|
||
|
||
function addColorToSelectionPalette(color) {
|
||
if (showSelectionPalette) {
|
||
var rgb = tinycolor(color).toRgbString();
|
||
if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
|
||
selectionPalette.push(rgb);
|
||
while(selectionPalette.length > maxSelectionSize) {
|
||
selectionPalette.shift();
|
||
}
|
||
}
|
||
|
||
if (localStorageKey && window.localStorage) {
|
||
try {
|
||
window.localStorage[localStorageKey] = selectionPalette.join(";");
|
||
}
|
||
catch(e) { }
|
||
}
|
||
}
|
||
}
|
||
|
||
function getUniqueSelectionPalette() {
|
||
var unique = [];
|
||
if (opts.showPalette) {
|
||
for (i = 0; i < selectionPalette.length; i++) {
|
||
var rgb = tinycolor(selectionPalette[i]).toRgbString();
|
||
|
||
if (!paletteLookup[rgb]) {
|
||
unique.push(selectionPalette[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
return unique.reverse().slice(0, opts.maxSelectionSize);
|
||
}
|
||
|
||
function drawPalette() {
|
||
|
||
var currentColor = get();
|
||
|
||
var html = $.map(paletteArray, function (palette, i) {
|
||
return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts.preferredFormat);
|
||
});
|
||
|
||
updateSelectionPaletteFromStorage();
|
||
|
||
if (selectionPalette) {
|
||
html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts.preferredFormat));
|
||
}
|
||
|
||
paletteContainer.html(html.join(""));
|
||
}
|
||
|
||
function drawInitial() {
|
||
if (opts.showInitial) {
|
||
var initial = colorOnShow;
|
||
var current = get();
|
||
initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts.preferredFormat));
|
||
}
|
||
}
|
||
|
||
function dragStart() {
|
||
if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
|
||
reflow();
|
||
}
|
||
container.addClass(draggingClass);
|
||
shiftMovementDirection = null;
|
||
boundElement.trigger('dragstart.spectrum', [ get() ]);
|
||
}
|
||
|
||
function dragStop() {
|
||
container.removeClass(draggingClass);
|
||
boundElement.trigger('dragstop.spectrum', [ get() ]);
|
||
}
|
||
|
||
function setFromTextInput() {
|
||
|
||
var value = textInput.val();
|
||
|
||
if ((value === null || value === "") && allowEmpty) {
|
||
set(null);
|
||
updateOriginalInput(true);
|
||
}
|
||
else {
|
||
var tiny = tinycolor(value);
|
||
if (tiny.ok) {
|
||
set(tiny);
|
||
updateOriginalInput(true);
|
||
}
|
||
else {
|
||
textInput.addClass("sp-validation-error");
|
||
}
|
||
}
|
||
}
|
||
|
||
function toggle() {
|
||
if (visible) {
|
||
hide();
|
||
}
|
||
else {
|
||
show();
|
||
}
|
||
}
|
||
|
||
function show() {
|
||
var event = $.Event('beforeShow.spectrum');
|
||
|
||
if (visible) {
|
||
reflow();
|
||
return;
|
||
}
|
||
|
||
boundElement.trigger(event, [ get() ]);
|
||
|
||
if (callbacks.beforeShow(get()) === false || event.isDefaultPrevented()) {
|
||
return;
|
||
}
|
||
|
||
hideAll();
|
||
visible = true;
|
||
|
||
$(doc).bind("click.spectrum", hide);
|
||
$(window).bind("resize.spectrum", resize);
|
||
replacer.addClass("sp-active");
|
||
container.removeClass("sp-hidden");
|
||
|
||
reflow();
|
||
updateUI();
|
||
|
||
colorOnShow = get();
|
||
|
||
drawInitial();
|
||
callbacks.show(colorOnShow);
|
||
boundElement.trigger('show.spectrum', [ colorOnShow ]);
|
||
}
|
||
|
||
function hide(e) {
|
||
|
||
// Return on right click
|
||
if (e && e.type == "click" && e.button == 2) { return; }
|
||
|
||
// Return if hiding is unnecessary
|
||
if (!visible || flat) { return; }
|
||
visible = false;
|
||
|
||
$(doc).unbind("click.spectrum", hide);
|
||
$(window).unbind("resize.spectrum", resize);
|
||
|
||
replacer.removeClass("sp-active");
|
||
container.addClass("sp-hidden");
|
||
|
||
var colorHasChanged = !tinycolor.equals(get(), colorOnShow);
|
||
|
||
if (colorHasChanged) {
|
||
if (clickoutFiresChange && e !== "cancel") {
|
||
updateOriginalInput(true);
|
||
}
|
||
else {
|
||
revert();
|
||
}
|
||
}
|
||
|
||
callbacks.hide(get());
|
||
boundElement.trigger('hide.spectrum', [ get() ]);
|
||
}
|
||
|
||
function revert() {
|
||
set(colorOnShow, true);
|
||
}
|
||
|
||
function set(color, ignoreFormatChange) {
|
||
if (tinycolor.equals(color, get())) {
|
||
// Update UI just in case a validation error needs
|
||
// to be cleared.
|
||
updateUI();
|
||
return;
|
||
}
|
||
|
||
var newColor, newHsv;
|
||
if (!color && allowEmpty) {
|
||
isEmpty = true;
|
||
} else {
|
||
isEmpty = false;
|
||
newColor = tinycolor(color);
|
||
newHsv = newColor.toHsv();
|
||
|
||
currentHue = (newHsv.h % 360) / 360;
|
||
currentSaturation = newHsv.s;
|
||
currentValue = newHsv.v;
|
||
currentAlpha = newHsv.a;
|
||
}
|
||
updateUI();
|
||
|
||
if (newColor && newColor.ok && !ignoreFormatChange) {
|
||
currentPreferredFormat = preferredFormat || newColor.format;
|
||
}
|
||
}
|
||
|
||
function get(opts) {
|
||
opts = opts || { };
|
||
|
||
if (allowEmpty && isEmpty) {
|
||
return null;
|
||
}
|
||
|
||
return tinycolor.fromRatio({
|
||
h: currentHue,
|
||
s: currentSaturation,
|
||
v: currentValue,
|
||
a: Math.round(currentAlpha * 100) / 100
|
||
}, { format: opts.format || currentPreferredFormat });
|
||
}
|
||
|
||
function isValid() {
|
||
return !textInput.hasClass("sp-validation-error");
|
||
}
|
||
|
||
function move() {
|
||
updateUI();
|
||
|
||
callbacks.move(get());
|
||
boundElement.trigger('move.spectrum', [ get() ]);
|
||
}
|
||
|
||
function updateUI() {
|
||
|
||
textInput.removeClass("sp-validation-error");
|
||
|
||
updateHelperLocations();
|
||
|
||
// Update dragger background color (gradients take care of saturation and value).
|
||
var flatColor = tinycolor.fromRatio({ h: currentHue, s: 1, v: 1 });
|
||
dragger.css("background-color", flatColor.toHexString());
|
||
|
||
// Get a format that alpha will be included in (hex and names ignore alpha)
|
||
var format = currentPreferredFormat;
|
||
if (currentAlpha < 1 && !(currentAlpha === 0 && format === "name")) {
|
||
if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") {
|
||
format = "rgb";
|
||
}
|
||
}
|
||
|
||
var realColor = get({ format: format }),
|
||
displayColor = '';
|
||
|
||
//reset background info for preview element
|
||
previewElement.removeClass("sp-clear-display");
|
||
previewElement.css('background-color', 'transparent');
|
||
|
||
if (!realColor && allowEmpty) {
|
||
// Update the replaced elements background with icon indicating no color selection
|
||
previewElement.addClass("sp-clear-display");
|
||
}
|
||
else {
|
||
var realHex = realColor.toHexString(),
|
||
realRgb = realColor.toRgbString();
|
||
|
||
// Update the replaced elements background color (with actual selected color)
|
||
if (rgbaSupport || realColor.alpha === 1) {
|
||
previewElement.css("background-color", realRgb);
|
||
}
|
||
else {
|
||
previewElement.css("background-color", "transparent");
|
||
previewElement.css("filter", realColor.toFilter());
|
||
}
|
||
|
||
if (opts.showAlpha) {
|
||
var rgb = realColor.toRgb();
|
||
rgb.a = 0;
|
||
var realAlpha = tinycolor(rgb).toRgbString();
|
||
var gradient = "linear-gradient(left, " + realAlpha + ", " + realHex + ")";
|
||
|
||
if (IE) {
|
||
alphaSliderInner.css("filter", tinycolor(realAlpha).toFilter({ gradientType: 1 }, realHex));
|
||
}
|
||
else {
|
||
alphaSliderInner.css("background", "-webkit-" + gradient);
|
||
alphaSliderInner.css("background", "-moz-" + gradient);
|
||
alphaSliderInner.css("background", "-ms-" + gradient);
|
||
// Use current syntax gradient on unprefixed property.
|
||
alphaSliderInner.css("background",
|
||
"linear-gradient(to right, " + realAlpha + ", " + realHex + ")");
|
||
}
|
||
}
|
||
|
||
displayColor = realColor.toString(format);
|
||
}
|
||
|
||
// Update the text entry input as it changes happen
|
||
if (opts.showInput) {
|
||
textInput.val(displayColor);
|
||
}
|
||
|
||
if (opts.showPalette) {
|
||
drawPalette();
|
||
}
|
||
|
||
drawInitial();
|
||
}
|
||
|
||
function updateHelperLocations() {
|
||
var s = currentSaturation;
|
||
var v = currentValue;
|
||
|
||
if(allowEmpty && isEmpty) {
|
||
//if selected color is empty, hide the helpers
|
||
alphaSlideHelper.hide();
|
||
slideHelper.hide();
|
||
dragHelper.hide();
|
||
}
|
||
else {
|
||
//make sure helpers are visible
|
||
alphaSlideHelper.show();
|
||
slideHelper.show();
|
||
dragHelper.show();
|
||
|
||
// Where to show the little circle in that displays your current selected color
|
||
var dragX = s * dragWidth;
|
||
var dragY = dragHeight - (v * dragHeight);
|
||
dragX = Math.max(
|
||
-dragHelperHeight,
|
||
Math.min(dragWidth - dragHelperHeight, dragX - dragHelperHeight)
|
||
);
|
||
dragY = Math.max(
|
||
-dragHelperHeight,
|
||
Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight)
|
||
);
|
||
dragHelper.css({
|
||
"top": dragY + "px",
|
||
"left": dragX + "px"
|
||
});
|
||
|
||
var alphaX = currentAlpha * alphaWidth;
|
||
alphaSlideHelper.css({
|
||
"left": (alphaX - (alphaSlideHelperWidth / 2)) + "px"
|
||
});
|
||
|
||
// Where to show the bar that displays your current selected hue
|
||
var slideY = (currentHue) * slideHeight;
|
||
slideHelper.css({
|
||
"top": (slideY - slideHelperHeight) + "px"
|
||
});
|
||
}
|
||
}
|
||
|
||
function updateOriginalInput(fireCallback) {
|
||
var color = get(),
|
||
displayColor = '',
|
||
hasChanged = !tinycolor.equals(color, colorOnShow);
|
||
|
||
if (color) {
|
||
displayColor = color.toString(currentPreferredFormat);
|
||
// Update the selection palette with the current color
|
||
addColorToSelectionPalette(color);
|
||
}
|
||
|
||
if (isInput) {
|
||
boundElement.val(displayColor);
|
||
}
|
||
|
||
colorOnShow = color;
|
||
|
||
if (fireCallback && hasChanged) {
|
||
callbacks.change(color);
|
||
boundElement.trigger('change', [ color ]);
|
||
}
|
||
}
|
||
|
||
function reflow() {
|
||
dragWidth = dragger.width();
|
||
dragHeight = dragger.height();
|
||
dragHelperHeight = dragHelper.height();
|
||
slideWidth = slider.width();
|
||
slideHeight = slider.height();
|
||
slideHelperHeight = slideHelper.height();
|
||
alphaWidth = alphaSlider.width();
|
||
alphaSlideHelperWidth = alphaSlideHelper.width();
|
||
|
||
if (!flat) {
|
||
container.css("position", "absolute");
|
||
container.offset(getOffset(container, offsetElement));
|
||
}
|
||
|
||
updateHelperLocations();
|
||
|
||
if (opts.showPalette) {
|
||
drawPalette();
|
||
}
|
||
|
||
boundElement.trigger('reflow.spectrum');
|
||
}
|
||
|
||
function destroy() {
|
||
boundElement.show();
|
||
offsetElement.unbind("click.spectrum touchstart.spectrum");
|
||
container.remove();
|
||
replacer.remove();
|
||
spectrums[spect.id] = null;
|
||
}
|
||
|
||
function option(optionName, optionValue) {
|
||
if (optionName === undefined) {
|
||
return $.extend({}, opts);
|
||
}
|
||
if (optionValue === undefined) {
|
||
return opts[optionName];
|
||
}
|
||
|
||
opts[optionName] = optionValue;
|
||
applyOptions();
|
||
}
|
||
|
||
function enable() {
|
||
disabled = false;
|
||
boundElement.attr("disabled", false);
|
||
offsetElement.removeClass("sp-disabled");
|
||
}
|
||
|
||
function disable() {
|
||
hide();
|
||
disabled = true;
|
||
boundElement.attr("disabled", true);
|
||
offsetElement.addClass("sp-disabled");
|
||
}
|
||
|
||
initialize();
|
||
|
||
var spect = {
|
||
show: show,
|
||
hide: hide,
|
||
toggle: toggle,
|
||
reflow: reflow,
|
||
option: option,
|
||
enable: enable,
|
||
disable: disable,
|
||
set: function (c) {
|
||
set(c);
|
||
updateOriginalInput();
|
||
},
|
||
get: get,
|
||
destroy: destroy,
|
||
container: container
|
||
};
|
||
|
||
spect.id = spectrums.push(spect) - 1;
|
||
|
||
return spect;
|
||
}
|
||
|
||
/**
|
||
* checkOffset - get the offset below/above and left/right element depending on screen position
|
||
* Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
|
||
*/
|
||
function getOffset(picker, input) {
|
||
var extraY = 0;
|
||
var dpWidth = picker.outerWidth();
|
||
var dpHeight = picker.outerHeight();
|
||
var inputHeight = input.outerHeight();
|
||
var doc = picker[0].ownerDocument;
|
||
var docElem = doc.documentElement;
|
||
var viewWidth = docElem.clientWidth + $(doc).scrollLeft();
|
||
var viewHeight = docElem.clientHeight + $(doc).scrollTop();
|
||
var offset = input.offset();
|
||
offset.top += inputHeight;
|
||
|
||
offset.left -=
|
||
Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
|
||
Math.abs(offset.left + dpWidth - viewWidth) : 0);
|
||
|
||
offset.top -=
|
||
Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
|
||
Math.abs(dpHeight + inputHeight - extraY) : extraY));
|
||
|
||
return offset;
|
||
}
|
||
|
||
/**
|
||
* noop - do nothing
|
||
*/
|
||
function noop() {
|
||
|
||
}
|
||
|
||
/**
|
||
* stopPropagation - makes the code only doing this a little easier to read in line
|
||
*/
|
||
function stopPropagation(e) {
|
||
e.stopPropagation();
|
||
}
|
||
|
||
/**
|
||
* Create a function bound to a given object
|
||
* Thanks to underscore.js
|
||
*/
|
||
function bind(func, obj) {
|
||
var slice = Array.prototype.slice;
|
||
var args = slice.call(arguments, 2);
|
||
return function () {
|
||
return func.apply(obj, args.concat(slice.call(arguments)));
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Lightweight drag helper. Handles containment within the element, so that
|
||
* when dragging, the x is within [0,element.width] and y is within [0,element.height]
|
||
*/
|
||
function draggable(element, onmove, onstart, onstop) {
|
||
onmove = onmove || function () { };
|
||
onstart = onstart || function () { };
|
||
onstop = onstop || function () { };
|
||
var doc = element.ownerDocument || document;
|
||
var dragging = false;
|
||
var offset = {};
|
||
var maxHeight = 0;
|
||
var maxWidth = 0;
|
||
var hasTouch = ('ontouchstart' in window);
|
||
|
||
var duringDragEvents = {};
|
||
duringDragEvents["selectstart"] = prevent;
|
||
duringDragEvents["dragstart"] = prevent;
|
||
duringDragEvents["touchmove mousemove"] = move;
|
||
duringDragEvents["touchend mouseup"] = stop;
|
||
|
||
function prevent(e) {
|
||
if (e.stopPropagation) {
|
||
e.stopPropagation();
|
||
}
|
||
if (e.preventDefault) {
|
||
e.preventDefault();
|
||
}
|
||
e.returnValue = false;
|
||
}
|
||
|
||
function move(e) {
|
||
if (dragging) {
|
||
// Mouseup happened outside of window
|
||
if (IE && document.documentMode < 9 && !e.button) {
|
||
return stop();
|
||
}
|
||
|
||
var touches = e.originalEvent.touches;
|
||
var pageX = touches ? touches[0].pageX : e.pageX;
|
||
var pageY = touches ? touches[0].pageY : e.pageY;
|
||
|
||
var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));
|
||
var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));
|
||
|
||
if (hasTouch) {
|
||
// Stop scrolling in iOS
|
||
prevent(e);
|
||
}
|
||
|
||
onmove.apply(element, [dragX, dragY, e]);
|
||
}
|
||
}
|
||
|
||
function start(e) {
|
||
var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);
|
||
var touches = e.originalEvent.touches;
|
||
|
||
if (!rightclick && !dragging) {
|
||
if (onstart.apply(element, arguments) !== false) {
|
||
dragging = true;
|
||
maxHeight = $(element).height();
|
||
maxWidth = $(element).width();
|
||
offset = $(element).offset();
|
||
|
||
$(doc).bind(duringDragEvents);
|
||
$(doc.body).addClass("sp-dragging");
|
||
|
||
if (!hasTouch) {
|
||
move(e);
|
||
}
|
||
|
||
prevent(e);
|
||
}
|
||
}
|
||
}
|
||
|
||
function stop() {
|
||
if (dragging) {
|
||
$(doc).unbind(duringDragEvents);
|
||
$(doc.body).removeClass("sp-dragging");
|
||
onstop.apply(element, arguments);
|
||
}
|
||
dragging = false;
|
||
}
|
||
|
||
$(element).bind("touchstart mousedown", start);
|
||
}
|
||
|
||
function throttle(func, wait, debounce) {
|
||
var timeout;
|
||
return function () {
|
||
var context = this, args = arguments;
|
||
var throttler = function () {
|
||
timeout = null;
|
||
func.apply(context, args);
|
||
};
|
||
if (debounce) clearTimeout(timeout);
|
||
if (debounce || !timeout) timeout = setTimeout(throttler, wait);
|
||
};
|
||
}
|
||
|
||
function log(){/* jshint -W021 */if(window.console){if(Function.prototype.bind)log=Function.prototype.bind.call(console.log,console);else log=function(){Function.prototype.apply.call(console.log,console,arguments);};log.apply(this,arguments);}}
|
||
|
||
/**
|
||
* Define a jQuery plugin
|
||
*/
|
||
var dataID = "spectrum.id";
|
||
$.fn.spectrum = function (opts, extra) {
|
||
|
||
if (typeof opts == "string") {
|
||
|
||
var returnValue = this;
|
||
var args = Array.prototype.slice.call( arguments, 1 );
|
||
|
||
this.each(function () {
|
||
var spect = spectrums[$(this).data(dataID)];
|
||
if (spect) {
|
||
var method = spect[opts];
|
||
if (!method) {
|
||
throw new Error( "Spectrum: no such method: '" + opts + "'" );
|
||
}
|
||
|
||
if (opts == "get") {
|
||
returnValue = spect.get();
|
||
}
|
||
else if (opts == "container") {
|
||
returnValue = spect.container;
|
||
}
|
||
else if (opts == "option") {
|
||
returnValue = spect.option.apply(spect, args);
|
||
}
|
||
else if (opts == "destroy") {
|
||
spect.destroy();
|
||
$(this).removeData(dataID);
|
||
}
|
||
else {
|
||
method.apply(spect, args);
|
||
}
|
||
}
|
||
});
|
||
|
||
return returnValue;
|
||
}
|
||
|
||
// Initializing a new instance of spectrum
|
||
return this.spectrum("destroy").each(function () {
|
||
var options = $.extend({}, opts, $(this).data());
|
||
var spect = spectrum(this, options);
|
||
$(this).data(dataID, spect.id);
|
||
});
|
||
};
|
||
|
||
$.fn.spectrum.load = true;
|
||
$.fn.spectrum.loadOpts = {};
|
||
$.fn.spectrum.draggable = draggable;
|
||
$.fn.spectrum.defaults = defaultOpts;
|
||
|
||
$.spectrum = { };
|
||
$.spectrum.localization = { };
|
||
$.spectrum.palettes = { };
|
||
|
||
$.fn.spectrum.processNativeColorInputs = function () {
|
||
if (!inputTypeColorSupport) {
|
||
$("input[type=color]").spectrum({
|
||
preferredFormat: "hex6"
|
||
});
|
||
}
|
||
};
|
||
|
||
// TinyColor v0.9.17
|
||
// https://github.com/bgrins/TinyColor
|
||
// 2013-08-10, Brian Grinstead, MIT License
|
||
|
||
(function() {
|
||
|
||
var trimLeft = /^[\s,#]+/,
|
||
trimRight = /\s+$/,
|
||
tinyCounter = 0,
|
||
math = Math,
|
||
mathRound = math.round,
|
||
mathMin = math.min,
|
||
mathMax = math.max,
|
||
mathRandom = math.random;
|
||
|
||
function tinycolor (color, opts) {
|
||
|
||
color = (color) ? color : '';
|
||
opts = opts || { };
|
||
|
||
// If input is already a tinycolor, return itself
|
||
if (typeof color == "object" && color.hasOwnProperty("_tc_id")) {
|
||
return color;
|
||
}
|
||
|
||
var rgb = inputToRGB(color);
|
||
var r = rgb.r,
|
||
g = rgb.g,
|
||
b = rgb.b,
|
||
a = rgb.a,
|
||
roundA = mathRound(100*a) / 100,
|
||
format = opts.format || rgb.format;
|
||
|
||
// Don't let the range of [0,255] come back in [0,1].
|
||
// Potentially lose a little bit of precision here, but will fix issues where
|
||
// .5 gets interpreted as half of the total, instead of half of 1
|
||
// If it was supposed to be 128, this was already taken care of by `inputToRgb`
|
||
if (r < 1) { r = mathRound(r); }
|
||
if (g < 1) { g = mathRound(g); }
|
||
if (b < 1) { b = mathRound(b); }
|
||
|
||
return {
|
||
ok: rgb.ok,
|
||
format: format,
|
||
_tc_id: tinyCounter++,
|
||
alpha: a,
|
||
getAlpha: function() {
|
||
return a;
|
||
},
|
||
setAlpha: function(value) {
|
||
a = boundAlpha(value);
|
||
roundA = mathRound(100*a) / 100;
|
||
},
|
||
toHsv: function() {
|
||
var hsv = rgbToHsv(r, g, b);
|
||
return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: a };
|
||
},
|
||
toHsvString: function() {
|
||
var hsv = rgbToHsv(r, g, b);
|
||
var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
|
||
return (a == 1) ?
|
||
"hsv(" + h + ", " + s + "%, " + v + "%)" :
|
||
"hsva(" + h + ", " + s + "%, " + v + "%, "+ roundA + ")";
|
||
},
|
||
toHsl: function() {
|
||
var hsl = rgbToHsl(r, g, b);
|
||
return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: a };
|
||
},
|
||
toHslString: function() {
|
||
var hsl = rgbToHsl(r, g, b);
|
||
var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
|
||
return (a == 1) ?
|
||
"hsl(" + h + ", " + s + "%, " + l + "%)" :
|
||
"hsla(" + h + ", " + s + "%, " + l + "%, "+ roundA + ")";
|
||
},
|
||
toHex: function(allow3Char) {
|
||
return rgbToHex(r, g, b, allow3Char);
|
||
},
|
||
toHexString: function(allow3Char) {
|
||
return '#' + this.toHex(allow3Char);
|
||
},
|
||
toHex8: function() {
|
||
return rgbaToHex(r, g, b, a);
|
||
},
|
||
toHex8String: function() {
|
||
return '#' + this.toHex8();
|
||
},
|
||
toRgb: function() {
|
||
return { r: mathRound(r), g: mathRound(g), b: mathRound(b), a: a };
|
||
},
|
||
toRgbString: function() {
|
||
return (a == 1) ?
|
||
"rgb(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ")" :
|
||
"rgba(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ", " + roundA + ")";
|
||
},
|
||
toPercentageRgb: function() {
|
||
return { r: mathRound(bound01(r, 255) * 100) + "%", g: mathRound(bound01(g, 255) * 100) + "%", b: mathRound(bound01(b, 255) * 100) + "%", a: a };
|
||
},
|
||
toPercentageRgbString: function() {
|
||
return (a == 1) ?
|
||
"rgb(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%)" :
|
||
"rgba(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%, " + roundA + ")";
|
||
},
|
||
toName: function() {
|
||
if (a === 0) {
|
||
return "transparent";
|
||
}
|
||
|
||
return hexNames[rgbToHex(r, g, b, true)] || false;
|
||
},
|
||
toFilter: function(secondColor) {
|
||
var hex8String = '#' + rgbaToHex(r, g, b, a);
|
||
var secondHex8String = hex8String;
|
||
var gradientType = opts && opts.gradientType ? "GradientType = 1, " : "";
|
||
|
||
if (secondColor) {
|
||
var s = tinycolor(secondColor);
|
||
secondHex8String = s.toHex8String();
|
||
}
|
||
|
||
return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
|
||
},
|
||
toString: function(format) {
|
||
var formatSet = !!format;
|
||
format = format || this.format;
|
||
|
||
var formattedString = false;
|
||
var hasAlphaAndFormatNotSet = !formatSet && a < 1 && a > 0;
|
||
var formatWithAlpha = hasAlphaAndFormatNotSet && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
|
||
|
||
if (format === "rgb") {
|
||
formattedString = this.toRgbString();
|
||
}
|
||
if (format === "prgb") {
|
||
formattedString = this.toPercentageRgbString();
|
||
}
|
||
if (format === "hex" || format === "hex6") {
|
||
formattedString = this.toHexString();
|
||
}
|
||
if (format === "hex3") {
|
||
formattedString = this.toHexString(true);
|
||
}
|
||
if (format === "hex8") {
|
||
formattedString = this.toHex8String();
|
||
}
|
||
if (format === "name") {
|
||
formattedString = this.toName();
|
||
}
|
||
if (format === "hsl") {
|
||
formattedString = this.toHslString();
|
||
}
|
||
if (format === "hsv") {
|
||
formattedString = this.toHsvString();
|
||
}
|
||
|
||
if (formatWithAlpha) {
|
||
return this.toRgbString();
|
||
}
|
||
|
||
return formattedString || this.toHexString();
|
||
}
|
||
};
|
||
}
|
||
|
||
// If input is an object, force 1 into "1.0" to handle ratios properly
|
||
// String input requires "1.0" as input, so 1 will be treated as 1
|
||
tinycolor.fromRatio = function(color, opts) {
|
||
if (typeof color == "object") {
|
||
var newColor = {};
|
||
for (var i in color) {
|
||
if (color.hasOwnProperty(i)) {
|
||
if (i === "a") {
|
||
newColor[i] = color[i];
|
||
}
|
||
else {
|
||
newColor[i] = convertToPercentage(color[i]);
|
||
}
|
||
}
|
||
}
|
||
color = newColor;
|
||
}
|
||
|
||
return tinycolor(color, opts);
|
||
};
|
||
|
||
// Given a string or object, convert that input to RGB
|
||
// Possible string inputs:
|
||
//
|
||
// "red"
|
||
// "#f00" or "f00"
|
||
// "#ff0000" or "ff0000"
|
||
// "#ff000000" or "ff000000"
|
||
// "rgb 255 0 0" or "rgb (255, 0, 0)"
|
||
// "rgb 1.0 0 0" or "rgb (1, 0, 0)"
|
||
// "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
|
||
// "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
|
||
// "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
|
||
// "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
|
||
// "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
|
||
//
|
||
function inputToRGB(color) {
|
||
|
||
var rgb = { r: 0, g: 0, b: 0 };
|
||
var a = 1;
|
||
var ok = false;
|
||
var format = false;
|
||
|
||
if (typeof color == "string") {
|
||
color = stringInputToObject(color);
|
||
}
|
||
|
||
if (typeof color == "object") {
|
||
if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
|
||
rgb = rgbToRgb(color.r, color.g, color.b);
|
||
ok = true;
|
||
format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
|
||
}
|
||
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
|
||
color.s = convertToPercentage(color.s);
|
||
color.v = convertToPercentage(color.v);
|
||
rgb = hsvToRgb(color.h, color.s, color.v);
|
||
ok = true;
|
||
format = "hsv";
|
||
}
|
||
else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
|
||
color.s = convertToPercentage(color.s);
|
||
color.l = convertToPercentage(color.l);
|
||
rgb = hslToRgb(color.h, color.s, color.l);
|
||
ok = true;
|
||
format = "hsl";
|
||
}
|
||
|
||
if (color.hasOwnProperty("a")) {
|
||
a = color.a;
|
||
}
|
||
}
|
||
|
||
a = boundAlpha(a);
|
||
|
||
return {
|
||
ok: ok,
|
||
format: color.format || format,
|
||
r: mathMin(255, mathMax(rgb.r, 0)),
|
||
g: mathMin(255, mathMax(rgb.g, 0)),
|
||
b: mathMin(255, mathMax(rgb.b, 0)),
|
||
a: a
|
||
};
|
||
}
|
||
|
||
|
||
// Conversion Functions
|
||
// --------------------
|
||
|
||
// `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
|
||
// <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
|
||
|
||
// `rgbToRgb`
|
||
// Handle bounds / percentage checking to conform to CSS color spec
|
||
// <http://www.w3.org/TR/css3-color/>
|
||
// *Assumes:* r, g, b in [0, 255] or [0, 1]
|
||
// *Returns:* { r, g, b } in [0, 255]
|
||
function rgbToRgb(r, g, b){
|
||
return {
|
||
r: bound01(r, 255) * 255,
|
||
g: bound01(g, 255) * 255,
|
||
b: bound01(b, 255) * 255
|
||
};
|
||
}
|
||
|
||
// `rgbToHsl`
|
||
// Converts an RGB color value to HSL.
|
||
// *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
|
||
// *Returns:* { h, s, l } in [0,1]
|
||
function rgbToHsl(r, g, b) {
|
||
|
||
r = bound01(r, 255);
|
||
g = bound01(g, 255);
|
||
b = bound01(b, 255);
|
||
|
||
var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
||
var h, s, l = (max + min) / 2;
|
||
|
||
if(max == min) {
|
||
h = s = 0; // achromatic
|
||
}
|
||
else {
|
||
var d = max - min;
|
||
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
||
switch(max) {
|
||
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||
case g: h = (b - r) / d + 2; break;
|
||
case b: h = (r - g) / d + 4; break;
|
||
}
|
||
|
||
h /= 6;
|
||
}
|
||
|
||
return { h: h, s: s, l: l };
|
||
}
|
||
|
||
// `hslToRgb`
|
||
// Converts an HSL color value to RGB.
|
||
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
|
||
// *Returns:* { r, g, b } in the set [0, 255]
|
||
function hslToRgb(h, s, l) {
|
||
var r, g, b;
|
||
|
||
h = bound01(h, 360);
|
||
s = bound01(s, 100);
|
||
l = bound01(l, 100);
|
||
|
||
function hue2rgb(p, q, t) {
|
||
if(t < 0) t += 1;
|
||
if(t > 1) t -= 1;
|
||
if(t < 1/6) return p + (q - p) * 6 * t;
|
||
if(t < 1/2) return q;
|
||
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||
return p;
|
||
}
|
||
|
||
if(s === 0) {
|
||
r = g = b = l; // achromatic
|
||
}
|
||
else {
|
||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||
var p = 2 * l - q;
|
||
r = hue2rgb(p, q, h + 1/3);
|
||
g = hue2rgb(p, q, h);
|
||
b = hue2rgb(p, q, h - 1/3);
|
||
}
|
||
|
||
return { r: r * 255, g: g * 255, b: b * 255 };
|
||
}
|
||
|
||
// `rgbToHsv`
|
||
// Converts an RGB color value to HSV
|
||
// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
|
||
// *Returns:* { h, s, v } in [0,1]
|
||
function rgbToHsv(r, g, b) {
|
||
|
||
r = bound01(r, 255);
|
||
g = bound01(g, 255);
|
||
b = bound01(b, 255);
|
||
|
||
var max = mathMax(r, g, b), min = mathMin(r, g, b);
|
||
var h, s, v = max;
|
||
|
||
var d = max - min;
|
||
s = max === 0 ? 0 : d / max;
|
||
|
||
if(max == min) {
|
||
h = 0; // achromatic
|
||
}
|
||
else {
|
||
switch(max) {
|
||
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
|
||
case g: h = (b - r) / d + 2; break;
|
||
case b: h = (r - g) / d + 4; break;
|
||
}
|
||
h /= 6;
|
||
}
|
||
return { h: h, s: s, v: v };
|
||
}
|
||
|
||
// `hsvToRgb`
|
||
// Converts an HSV color value to RGB.
|
||
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
|
||
// *Returns:* { r, g, b } in the set [0, 255]
|
||
function hsvToRgb(h, s, v) {
|
||
|
||
h = bound01(h, 360) * 6;
|
||
s = bound01(s, 100);
|
||
v = bound01(v, 100);
|
||
|
||
var i = math.floor(h),
|
||
f = h - i,
|
||
p = v * (1 - s),
|
||
q = v * (1 - f * s),
|
||
t = v * (1 - (1 - f) * s),
|
||
mod = i % 6,
|
||
r = [v, q, p, p, t, v][mod],
|
||
g = [t, v, v, q, p, p][mod],
|
||
b = [p, p, t, v, v, q][mod];
|
||
|
||
return { r: r * 255, g: g * 255, b: b * 255 };
|
||
}
|
||
|
||
// `rgbToHex`
|
||
// Converts an RGB color to hex
|
||
// Assumes r, g, and b are contained in the set [0, 255]
|
||
// Returns a 3 or 6 character hex
|
||
function rgbToHex(r, g, b, allow3Char) {
|
||
|
||
var hex = [
|
||
pad2(mathRound(r).toString(16)),
|
||
pad2(mathRound(g).toString(16)),
|
||
pad2(mathRound(b).toString(16))
|
||
];
|
||
|
||
// Return a 3 character hex if possible
|
||
if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
|
||
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
|
||
}
|
||
|
||
return hex.join("");
|
||
}
|
||
// `rgbaToHex`
|
||
// Converts an RGBA color plus alpha transparency to hex
|
||
// Assumes r, g, b and a are contained in the set [0, 255]
|
||
// Returns an 8 character hex
|
||
function rgbaToHex(r, g, b, a) {
|
||
|
||
var hex = [
|
||
pad2(convertDecimalToHex(a)),
|
||
pad2(mathRound(r).toString(16)),
|
||
pad2(mathRound(g).toString(16)),
|
||
pad2(mathRound(b).toString(16))
|
||
];
|
||
|
||
return hex.join("");
|
||
}
|
||
|
||
// `equals`
|
||
// Can be called with any tinycolor input
|
||
tinycolor.equals = function (color1, color2) {
|
||
if (!color1 || !color2) { return false; }
|
||
return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
|
||
};
|
||
tinycolor.random = function() {
|
||
return tinycolor.fromRatio({
|
||
r: mathRandom(),
|
||
g: mathRandom(),
|
||
b: mathRandom()
|
||
});
|
||
};
|
||
|
||
|
||
// Modification Functions
|
||
// ----------------------
|
||
// Thanks to less.js for some of the basics here
|
||
// <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
|
||
|
||
tinycolor.desaturate = function (color, amount) {
|
||
amount = (amount === 0) ? 0 : (amount || 10);
|
||
var hsl = tinycolor(color).toHsl();
|
||
hsl.s -= amount / 100;
|
||
hsl.s = clamp01(hsl.s);
|
||
return tinycolor(hsl);
|
||
};
|
||
tinycolor.saturate = function (color, amount) {
|
||
amount = (amount === 0) ? 0 : (amount || 10);
|
||
var hsl = tinycolor(color).toHsl();
|
||
hsl.s += amount / 100;
|
||
hsl.s = clamp01(hsl.s);
|
||
return tinycolor(hsl);
|
||
};
|
||
tinycolor.greyscale = function(color) {
|
||
return tinycolor.desaturate(color, 100);
|
||
};
|
||
tinycolor.lighten = function(color, amount) {
|
||
amount = (amount === 0) ? 0 : (amount || 10);
|
||
var hsl = tinycolor(color).toHsl();
|
||
hsl.l += amount / 100;
|
||
hsl.l = clamp01(hsl.l);
|
||
return tinycolor(hsl);
|
||
};
|
||
tinycolor.darken = function (color, amount) {
|
||
amount = (amount === 0) ? 0 : (amount || 10);
|
||
var hsl = tinycolor(color).toHsl();
|
||
hsl.l -= amount / 100;
|
||
hsl.l = clamp01(hsl.l);
|
||
return tinycolor(hsl);
|
||
};
|
||
tinycolor.complement = function(color) {
|
||
var hsl = tinycolor(color).toHsl();
|
||
hsl.h = (hsl.h + 180) % 360;
|
||
return tinycolor(hsl);
|
||
};
|
||
|
||
|
||
// Combination Functions
|
||
// ---------------------
|
||
// Thanks to jQuery xColor for some of the ideas behind these
|
||
// <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
|
||
|
||
tinycolor.triad = function(color) {
|
||
var hsl = tinycolor(color).toHsl();
|
||
var h = hsl.h;
|
||
return [
|
||
tinycolor(color),
|
||
tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
|
||
tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
|
||
];
|
||
};
|
||
tinycolor.tetrad = function(color) {
|
||
var hsl = tinycolor(color).toHsl();
|
||
var h = hsl.h;
|
||
return [
|
||
tinycolor(color),
|
||
tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
|
||
tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
|
||
tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
|
||
];
|
||
};
|
||
tinycolor.splitcomplement = function(color) {
|
||
var hsl = tinycolor(color).toHsl();
|
||
var h = hsl.h;
|
||
return [
|
||
tinycolor(color),
|
||
tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
|
||
tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
|
||
];
|
||
};
|
||
tinycolor.analogous = function(color, results, slices) {
|
||
results = results || 6;
|
||
slices = slices || 30;
|
||
|
||
var hsl = tinycolor(color).toHsl();
|
||
var part = 360 / slices;
|
||
var ret = [tinycolor(color)];
|
||
|
||
for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
|
||
hsl.h = (hsl.h + part) % 360;
|
||
ret.push(tinycolor(hsl));
|
||
}
|
||
return ret;
|
||
};
|
||
tinycolor.monochromatic = function(color, results) {
|
||
results = results || 6;
|
||
var hsv = tinycolor(color).toHsv();
|
||
var h = hsv.h, s = hsv.s, v = hsv.v;
|
||
var ret = [];
|
||
var modification = 1 / results;
|
||
|
||
while (results--) {
|
||
ret.push(tinycolor({ h: h, s: s, v: v}));
|
||
v = (v + modification) % 1;
|
||
}
|
||
|
||
return ret;
|
||
};
|
||
|
||
|
||
// Readability Functions
|
||
// ---------------------
|
||
// <http://www.w3.org/TR/AERT#color-contrast>
|
||
|
||
// `readability`
|
||
// Analyze the 2 colors and returns an object with the following properties:
|
||
// `brightness`: difference in brightness between the two colors
|
||
// `color`: difference in color/hue between the two colors
|
||
tinycolor.readability = function(color1, color2) {
|
||
var a = tinycolor(color1).toRgb();
|
||
var b = tinycolor(color2).toRgb();
|
||
var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000;
|
||
var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000;
|
||
var colorDiff = (
|
||
Math.max(a.r, b.r) - Math.min(a.r, b.r) +
|
||
Math.max(a.g, b.g) - Math.min(a.g, b.g) +
|
||
Math.max(a.b, b.b) - Math.min(a.b, b.b)
|
||
);
|
||
|
||
return {
|
||
brightness: Math.abs(brightnessA - brightnessB),
|
||
color: colorDiff
|
||
};
|
||
};
|
||
|
||
// `readable`
|
||
// http://www.w3.org/TR/AERT#color-contrast
|
||
// Ensure that foreground and background color combinations provide sufficient contrast.
|
||
// *Example*
|
||
// tinycolor.readable("#000", "#111") => false
|
||
tinycolor.readable = function(color1, color2) {
|
||
var readability = tinycolor.readability(color1, color2);
|
||
return readability.brightness > 125 && readability.color > 500;
|
||
};
|
||
|
||
// `mostReadable`
|
||
// Given a base color and a list of possible foreground or background
|
||
// colors for that base, returns the most readable color.
|
||
// *Example*
|
||
// tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
|
||
tinycolor.mostReadable = function(baseColor, colorList) {
|
||
var bestColor = null;
|
||
var bestScore = 0;
|
||
var bestIsReadable = false;
|
||
for (var i=0; i < colorList.length; i++) {
|
||
|
||
// We normalize both around the "acceptable" breaking point,
|
||
// but rank brightness constrast higher than hue.
|
||
|
||
var readability = tinycolor.readability(baseColor, colorList[i]);
|
||
var readable = readability.brightness > 125 && readability.color > 500;
|
||
var score = 3 * (readability.brightness / 125) + (readability.color / 500);
|
||
|
||
if ((readable && ! bestIsReadable) ||
|
||
(readable && bestIsReadable && score > bestScore) ||
|
||
((! readable) && (! bestIsReadable) && score > bestScore)) {
|
||
bestIsReadable = readable;
|
||
bestScore = score;
|
||
bestColor = tinycolor(colorList[i]);
|
||
}
|
||
}
|
||
return bestColor;
|
||
};
|
||
|
||
|
||
// Big List of Colors
|
||
// ------------------
|
||
// <http://www.w3.org/TR/css3-color/#svg-color>
|
||
var names = tinycolor.names = {
|
||
aliceblue: "f0f8ff",
|
||
antiquewhite: "faebd7",
|
||
aqua: "0ff",
|
||
aquamarine: "7fffd4",
|
||
azure: "f0ffff",
|
||
beige: "f5f5dc",
|
||
bisque: "ffe4c4",
|
||
black: "000",
|
||
blanchedalmond: "ffebcd",
|
||
blue: "00f",
|
||
blueviolet: "8a2be2",
|
||
brown: "a52a2a",
|
||
burlywood: "deb887",
|
||
burntsienna: "ea7e5d",
|
||
cadetblue: "5f9ea0",
|
||
chartreuse: "7fff00",
|
||
chocolate: "d2691e",
|
||
coral: "ff7f50",
|
||
cornflowerblue: "6495ed",
|
||
cornsilk: "fff8dc",
|
||
crimson: "dc143c",
|
||
cyan: "0ff",
|
||
darkblue: "00008b",
|
||
darkcyan: "008b8b",
|
||
darkgoldenrod: "b8860b",
|
||
darkgray: "a9a9a9",
|
||
darkgreen: "006400",
|
||
darkgrey: "a9a9a9",
|
||
darkkhaki: "bdb76b",
|
||
darkmagenta: "8b008b",
|
||
darkolivegreen: "556b2f",
|
||
darkorange: "ff8c00",
|
||
darkorchid: "9932cc",
|
||
darkred: "8b0000",
|
||
darksalmon: "e9967a",
|
||
darkseagreen: "8fbc8f",
|
||
darkslateblue: "483d8b",
|
||
darkslategray: "2f4f4f",
|
||
darkslategrey: "2f4f4f",
|
||
darkturquoise: "00ced1",
|
||
darkviolet: "9400d3",
|
||
deeppink: "ff1493",
|
||
deepskyblue: "00bfff",
|
||
dimgray: "696969",
|
||
dimgrey: "696969",
|
||
dodgerblue: "1e90ff",
|
||
firebrick: "b22222",
|
||
floralwhite: "fffaf0",
|
||
forestgreen: "228b22",
|
||
fuchsia: "f0f",
|
||
gainsboro: "dcdcdc",
|
||
ghostwhite: "f8f8ff",
|
||
gold: "ffd700",
|
||
goldenrod: "daa520",
|
||
gray: "808080",
|
||
green: "008000",
|
||
greenyellow: "adff2f",
|
||
grey: "808080",
|
||
honeydew: "f0fff0",
|
||
hotpink: "ff69b4",
|
||
indianred: "cd5c5c",
|
||
indigo: "4b0082",
|
||
ivory: "fffff0",
|
||
khaki: "f0e68c",
|
||
lavender: "e6e6fa",
|
||
lavenderblush: "fff0f5",
|
||
lawngreen: "7cfc00",
|
||
lemonchiffon: "fffacd",
|
||
lightblue: "add8e6",
|
||
lightcoral: "f08080",
|
||
lightcyan: "e0ffff",
|
||
lightgoldenrodyellow: "fafad2",
|
||
lightgray: "d3d3d3",
|
||
lightgreen: "90ee90",
|
||
lightgrey: "d3d3d3",
|
||
lightpink: "ffb6c1",
|
||
lightsalmon: "ffa07a",
|
||
lightseagreen: "20b2aa",
|
||
lightskyblue: "87cefa",
|
||
lightslategray: "789",
|
||
lightslategrey: "789",
|
||
lightsteelblue: "b0c4de",
|
||
lightyellow: "ffffe0",
|
||
lime: "0f0",
|
||
limegreen: "32cd32",
|
||
linen: "faf0e6",
|
||
magenta: "f0f",
|
||
maroon: "800000",
|
||
mediumaquamarine: "66cdaa",
|
||
mediumblue: "0000cd",
|
||
mediumorchid: "ba55d3",
|
||
mediumpurple: "9370db",
|
||
mediumseagreen: "3cb371",
|
||
mediumslateblue: "7b68ee",
|
||
mediumspringgreen: "00fa9a",
|
||
mediumturquoise: "48d1cc",
|
||
mediumvioletred: "c71585",
|
||
midnightblue: "191970",
|
||
mintcream: "f5fffa",
|
||
mistyrose: "ffe4e1",
|
||
moccasin: "ffe4b5",
|
||
navajowhite: "ffdead",
|
||
navy: "000080",
|
||
oldlace: "fdf5e6",
|
||
olive: "808000",
|
||
olivedrab: "6b8e23",
|
||
orange: "ffa500",
|
||
orangered: "ff4500",
|
||
orchid: "da70d6",
|
||
palegoldenrod: "eee8aa",
|
||
palegreen: "98fb98",
|
||
paleturquoise: "afeeee",
|
||
palevioletred: "db7093",
|
||
papayawhip: "ffefd5",
|
||
peachpuff: "ffdab9",
|
||
peru: "cd853f",
|
||
pink: "ffc0cb",
|
||
plum: "dda0dd",
|
||
powderblue: "b0e0e6",
|
||
purple: "800080",
|
||
red: "f00",
|
||
rosybrown: "bc8f8f",
|
||
royalblue: "4169e1",
|
||
saddlebrown: "8b4513",
|
||
salmon: "fa8072",
|
||
sandybrown: "f4a460",
|
||
seagreen: "2e8b57",
|
||
seashell: "fff5ee",
|
||
sienna: "a0522d",
|
||
silver: "c0c0c0",
|
||
skyblue: "87ceeb",
|
||
slateblue: "6a5acd",
|
||
slategray: "708090",
|
||
slategrey: "708090",
|
||
snow: "fffafa",
|
||
springgreen: "00ff7f",
|
||
steelblue: "4682b4",
|
||
tan: "d2b48c",
|
||
teal: "008080",
|
||
thistle: "d8bfd8",
|
||
tomato: "ff6347",
|
||
turquoise: "40e0d0",
|
||
violet: "ee82ee",
|
||
wheat: "f5deb3",
|
||
white: "fff",
|
||
whitesmoke: "f5f5f5",
|
||
yellow: "ff0",
|
||
yellowgreen: "9acd32"
|
||
};
|
||
|
||
// Make it easy to access colors via `hexNames[hex]`
|
||
var hexNames = tinycolor.hexNames = flip(names);
|
||
|
||
|
||
// Utilities
|
||
// ---------
|
||
|
||
// `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
|
||
function flip(o) {
|
||
var flipped = { };
|
||
for (var i in o) {
|
||
if (o.hasOwnProperty(i)) {
|
||
flipped[o[i]] = i;
|
||
}
|
||
}
|
||
return flipped;
|
||
}
|
||
|
||
// Return a valid alpha value [0,1] with all invalid values being set to 1
|
||
function boundAlpha(a) {
|
||
a = parseFloat(a);
|
||
|
||
if (isNaN(a) || a < 0 || a > 1) {
|
||
a = 1;
|
||
}
|
||
|
||
return a;
|
||
}
|
||
|
||
// Take input from [0, n] and return it as [0, 1]
|
||
function bound01(n, max) {
|
||
if (isOnePointZero(n)) { n = "100%"; }
|
||
|
||
var processPercent = isPercentage(n);
|
||
n = mathMin(max, mathMax(0, parseFloat(n)));
|
||
|
||
// Automatically convert percentage into number
|
||
if (processPercent) {
|
||
n = parseInt(n * max, 10) / 100;
|
||
}
|
||
|
||
// Handle floating point rounding errors
|
||
if ((math.abs(n - max) < 0.000001)) {
|
||
return 1;
|
||
}
|
||
|
||
// Convert into [0, 1] range if it isn't already
|
||
return (n % max) / parseFloat(max);
|
||
}
|
||
|
||
// Force a number between 0 and 1
|
||
function clamp01(val) {
|
||
return mathMin(1, mathMax(0, val));
|
||
}
|
||
|
||
// Parse a base-16 hex value into a base-10 integer
|
||
function parseIntFromHex(val) {
|
||
return parseInt(val, 16);
|
||
}
|
||
|
||
// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
|
||
// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
|
||
function isOnePointZero(n) {
|
||
return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
|
||
}
|
||
|
||
// Check to see if string passed in is a percentage
|
||
function isPercentage(n) {
|
||
return typeof n === "string" && n.indexOf('%') != -1;
|
||
}
|
||
|
||
// Force a hex value to have 2 characters
|
||
function pad2(c) {
|
||
return c.length == 1 ? '0' + c : '' + c;
|
||
}
|
||
|
||
// Replace a decimal with it's percentage value
|
||
function convertToPercentage(n) {
|
||
if (n <= 1) {
|
||
n = (n * 100) + "%";
|
||
}
|
||
|
||
return n;
|
||
}
|
||
|
||
// Converts a decimal to a hex value
|
||
function convertDecimalToHex(d) {
|
||
return Math.round(parseFloat(d) * 255).toString(16);
|
||
}
|
||
// Converts a hex value to a decimal
|
||
function convertHexToDecimal(h) {
|
||
return (parseIntFromHex(h) / 255);
|
||
}
|
||
|
||
var matchers = (function() {
|
||
|
||
// <http://www.w3.org/TR/css3-values/#integers>
|
||
var CSS_INTEGER = "[-\\+]?\\d+%?";
|
||
|
||
// <http://www.w3.org/TR/css3-values/#number-value>
|
||
var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
|
||
|
||
// Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
|
||
var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
|
||
|
||
// Actual matching.
|
||
// Parentheses and commas are optional, but not required.
|
||
// Whitespace can take the place of commas or opening paren
|
||
var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
||
var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
|
||
|
||
return {
|
||
rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
|
||
rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
|
||
hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
|
||
hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
|
||
hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
|
||
hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
|
||
hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
|
||
hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
|
||
};
|
||
})();
|
||
|
||
// `stringInputToObject`
|
||
// Permissive string parsing. Take in a number of formats, and output an object
|
||
// based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
|
||
function stringInputToObject(color) {
|
||
|
||
color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
|
||
var named = false;
|
||
if (names[color]) {
|
||
color = names[color];
|
||
named = true;
|
||
}
|
||
else if (color == 'transparent') {
|
||
return { r: 0, g: 0, b: 0, a: 0, format: "name" };
|
||
}
|
||
|
||
// Try to match string input using regular expressions.
|
||
// Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
|
||
// Just return an object and let the conversion functions handle that.
|
||
// This way the result will be the same whether the tinycolor is initialized with string or object.
|
||
var match;
|
||
if ((match = matchers.rgb.exec(color))) {
|
||
return { r: match[1], g: match[2], b: match[3] };
|
||
}
|
||
if ((match = matchers.rgba.exec(color))) {
|
||
return { r: match[1], g: match[2], b: match[3], a: match[4] };
|
||
}
|
||
if ((match = matchers.hsl.exec(color))) {
|
||
return { h: match[1], s: match[2], l: match[3] };
|
||
}
|
||
if ((match = matchers.hsla.exec(color))) {
|
||
return { h: match[1], s: match[2], l: match[3], a: match[4] };
|
||
}
|
||
if ((match = matchers.hsv.exec(color))) {
|
||
return { h: match[1], s: match[2], v: match[3] };
|
||
}
|
||
if ((match = matchers.hex8.exec(color))) {
|
||
return {
|
||
a: convertHexToDecimal(match[1]),
|
||
r: parseIntFromHex(match[2]),
|
||
g: parseIntFromHex(match[3]),
|
||
b: parseIntFromHex(match[4]),
|
||
format: named ? "name" : "hex8"
|
||
};
|
||
}
|
||
if ((match = matchers.hex6.exec(color))) {
|
||
return {
|
||
r: parseIntFromHex(match[1]),
|
||
g: parseIntFromHex(match[2]),
|
||
b: parseIntFromHex(match[3]),
|
||
format: named ? "name" : "hex"
|
||
};
|
||
}
|
||
if ((match = matchers.hex3.exec(color))) {
|
||
return {
|
||
r: parseIntFromHex(match[1] + '' + match[1]),
|
||
g: parseIntFromHex(match[2] + '' + match[2]),
|
||
b: parseIntFromHex(match[3] + '' + match[3]),
|
||
format: named ? "name" : "hex"
|
||
};
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
// Expose tinycolor to window, does not need to run in non-browser context.
|
||
window.tinycolor = tinycolor;
|
||
|
||
})();
|
||
|
||
|
||
$(function () {
|
||
if ($.fn.spectrum.load) {
|
||
$.fn.spectrum.processNativeColorInputs();
|
||
}
|
||
});
|
||
|
||
})(window, jQuery);
|
||
|
||
/* =============================================================
|
||
* bootstrap-combobox.js v1.1.5
|
||
* =============================================================
|
||
* Copyright 2012 Daniel Farrell
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
* ============================================================ */
|
||
|
||
!function( $ ) {
|
||
|
||
"use strict";
|
||
|
||
/* COMBOBOX PUBLIC CLASS DEFINITION
|
||
* ================================ */
|
||
|
||
var Combobox = function ( element, options ) {
|
||
this.options = $.extend({}, $.fn.combobox.defaults, options);
|
||
this.$source = $(element);
|
||
this.$container = this.setup();
|
||
this.$element = this.$container.find('input[type=text]');
|
||
this.$target = this.$container.find('input[type=hidden]');
|
||
this.$button = this.$container.find('.dropdown-toggle');
|
||
this.$menu = $(this.options.menu).appendTo('body');
|
||
this.matcher = this.options.matcher || this.matcher;
|
||
this.sorter = this.options.sorter || this.sorter;
|
||
this.highlighter = this.options.highlighter || this.highlighter;
|
||
this.shown = false;
|
||
this.selected = false;
|
||
this.refresh();
|
||
this.transferAttributes();
|
||
this.listen();
|
||
};
|
||
|
||
Combobox.prototype = {
|
||
|
||
constructor: Combobox
|
||
|
||
, setup: function () {
|
||
var combobox = $(this.options.template);
|
||
this.$source.before(combobox);
|
||
this.$source.hide();
|
||
return combobox;
|
||
}
|
||
|
||
, parse: function () {
|
||
var that = this
|
||
, map = {}
|
||
, source = []
|
||
, selected = false
|
||
, selectedValue = '';
|
||
this.$source.find('option').each(function() {
|
||
var option = $(this);
|
||
if (option.val() === '') {
|
||
that.options.placeholder = option.text();
|
||
return;
|
||
}
|
||
map[option.text()] = option.val();
|
||
source.push(option.text());
|
||
if (option.prop('selected')) {
|
||
selected = option.text();
|
||
selectedValue = option.val();
|
||
}
|
||
})
|
||
this.map = map;
|
||
if (selected) {
|
||
this.$element.val(selected);
|
||
this.$target.val(selectedValue);
|
||
this.$container.addClass('combobox-selected');
|
||
this.selected = true;
|
||
}
|
||
return source;
|
||
}
|
||
|
||
, transferAttributes: function() {
|
||
this.options.placeholder = this.$source.attr('data-placeholder') || this.options.placeholder;
|
||
this.$element.attr('placeholder', this.options.placeholder);
|
||
this.$target.prop('name', this.$source.prop('name'));
|
||
this.$target.val(this.$source.val());
|
||
this.$source.removeAttr('name'); // Remove from source otherwise form will pass parameter twice.
|
||
this.$element.attr('required', this.$source.attr('required'));
|
||
this.$element.attr('rel', this.$source.attr('rel'));
|
||
this.$element.attr('title', this.$source.attr('title'));
|
||
this.$element.attr('class', this.$source.attr('class'));
|
||
this.$element.attr('tabindex', this.$source.attr('tabindex'));
|
||
this.$source.removeAttr('tabindex');
|
||
this.$source.removeAttr('required');
|
||
}
|
||
|
||
, setSelected: function() {
|
||
this.selected = true;
|
||
}
|
||
|
||
, select: function () {
|
||
var val = this.$menu.find('.active').attr('data-value');
|
||
this.$element.val(this.updater(val));
|
||
this.$target.val(this.map[val]);
|
||
this.$source.val(this.map[val]);
|
||
this.$element.trigger('change');
|
||
this.$target.trigger('change');
|
||
this.$source.trigger('change');
|
||
this.$container.addClass('combobox-selected');
|
||
this.selected = true;
|
||
return this.hide();
|
||
}
|
||
|
||
, updater: function (item) {
|
||
return item;
|
||
}
|
||
|
||
, show: function () {
|
||
var pos = $.extend({}, this.$element.position(), {
|
||
height: this.$element[0].offsetHeight
|
||
});
|
||
|
||
this.$menu
|
||
.insertAfter(this.$element)
|
||
.css({
|
||
top: pos.top + pos.height
|
||
, left: pos.left
|
||
})
|
||
.show();
|
||
|
||
this.shown = true;
|
||
return this;
|
||
}
|
||
|
||
, hide: function () {
|
||
this.$menu.hide();
|
||
this.shown = false;
|
||
return this;
|
||
}
|
||
|
||
, lookup: function (event) {
|
||
this.query = this.$element.val();
|
||
return this.process(this.source);
|
||
}
|
||
|
||
, process: function (items) {
|
||
var that = this;
|
||
|
||
items = $.grep(items, function (item) {
|
||
return that.matcher(item);
|
||
})
|
||
|
||
items = this.sorter(items);
|
||
|
||
if (!items.length) {
|
||
return this.shown ? this.hide() : this;
|
||
}
|
||
|
||
return this.render(items.slice(0, this.options.items)).show();
|
||
}
|
||
|
||
, matcher: function (item) {
|
||
return ~item.toLowerCase().indexOf(this.query.toLowerCase());
|
||
}
|
||
|
||
, sorter: function (items) {
|
||
var beginswith = []
|
||
, caseSensitive = []
|
||
, caseInsensitive = []
|
||
, item;
|
||
|
||
while (item = items.shift()) {
|
||
if (!item.toLowerCase().indexOf(this.query.toLowerCase())) {beginswith.push(item);}
|
||
else if (~item.indexOf(this.query)) {caseSensitive.push(item);}
|
||
else {caseInsensitive.push(item);}
|
||
}
|
||
|
||
return beginswith.concat(caseSensitive, caseInsensitive);
|
||
}
|
||
|
||
, highlighter: function (item) {
|
||
var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
|
||
return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
|
||
return '<strong>' + match + '</strong>';
|
||
})
|
||
}
|
||
|
||
, render: function (items) {
|
||
var that = this;
|
||
|
||
items = $(items).map(function (i, item) {
|
||
i = $(that.options.item).attr('data-value', item);
|
||
i.find('a').html(that.highlighter(item));
|
||
return i[0];
|
||
})
|
||
|
||
items.first().addClass('active');
|
||
this.$menu.html(items);
|
||
return this;
|
||
}
|
||
|
||
, next: function (event) {
|
||
var active = this.$menu.find('.active').removeClass('active')
|
||
, next = active.next();
|
||
|
||
if (!next.length) {
|
||
next = $(this.$menu.find('li')[0]);
|
||
}
|
||
|
||
next.addClass('active');
|
||
}
|
||
|
||
, prev: function (event) {
|
||
var active = this.$menu.find('.active').removeClass('active')
|
||
, prev = active.prev();
|
||
|
||
if (!prev.length) {
|
||
prev = this.$menu.find('li').last();
|
||
}
|
||
|
||
prev.addClass('active');
|
||
}
|
||
|
||
, toggle: function () {
|
||
if (this.$container.hasClass('combobox-selected')) {
|
||
this.clearTarget();
|
||
this.triggerChange();
|
||
this.clearElement();
|
||
} else {
|
||
if (this.shown) {
|
||
this.hide();
|
||
} else {
|
||
this.clearElement();
|
||
this.lookup();
|
||
}
|
||
}
|
||
|
||
this.$element.trigger('change');
|
||
this.$target.trigger('change');
|
||
this.$source.trigger('change');
|
||
}
|
||
|
||
, clearElement: function () {
|
||
this.$element.val('').focus();
|
||
}
|
||
|
||
, clearTarget: function () {
|
||
this.$source.val('');
|
||
this.$target.val('');
|
||
this.$container.removeClass('combobox-selected');
|
||
this.selected = false;
|
||
}
|
||
|
||
, triggerChange: function () {
|
||
this.$source.trigger('change');
|
||
}
|
||
|
||
, refresh: function () {
|
||
this.source = this.parse();
|
||
this.options.items = this.source.length;
|
||
}
|
||
|
||
, listen: function () {
|
||
this.$element
|
||
.on('focus', $.proxy(this.focus, this))
|
||
.on('blur', $.proxy(this.blur, this))
|
||
.on('keypress', $.proxy(this.keypress, this))
|
||
.on('keyup', $.proxy(this.keyup, this));
|
||
|
||
if (this.eventSupported('keydown')) {
|
||
this.$element.on('keydown', $.proxy(this.keydown, this));
|
||
}
|
||
|
||
this.$menu
|
||
.on('click', $.proxy(this.click, this))
|
||
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
|
||
.on('mouseleave', 'li', $.proxy(this.mouseleave, this));
|
||
|
||
this.$button
|
||
.on('click', $.proxy(this.toggle, this));
|
||
}
|
||
|
||
, eventSupported: function(eventName) {
|
||
var isSupported = eventName in this.$element;
|
||
if (!isSupported) {
|
||
this.$element.setAttribute(eventName, 'return;');
|
||
isSupported = typeof this.$element[eventName] === 'function';
|
||
}
|
||
return isSupported;
|
||
}
|
||
|
||
, move: function (e) {
|
||
if (!this.shown) {return;}
|
||
|
||
switch(e.keyCode) {
|
||
case 9: // tab
|
||
case 13: // enter
|
||
case 27: // escape
|
||
e.preventDefault();
|
||
break;
|
||
|
||
case 38: // up arrow
|
||
e.preventDefault();
|
||
this.prev();
|
||
break;
|
||
|
||
case 40: // down arrow
|
||
e.preventDefault();
|
||
this.next();
|
||
break;
|
||
}
|
||
|
||
e.stopPropagation();
|
||
}
|
||
|
||
, keydown: function (e) {
|
||
this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27]);
|
||
this.move(e);
|
||
}
|
||
|
||
, keypress: function (e) {
|
||
if (this.suppressKeyPressRepeat) {return;}
|
||
this.move(e);
|
||
}
|
||
|
||
, keyup: function (e) {
|
||
switch(e.keyCode) {
|
||
case 40: // down arrow
|
||
case 39: // right arrow
|
||
case 38: // up arrow
|
||
case 37: // left arrow
|
||
case 36: // home
|
||
case 35: // end
|
||
case 33: // page up
|
||
case 34: // page down
|
||
case 16: // shift
|
||
case 17: // ctrl
|
||
case 18: // alt
|
||
case 20: // cap lock
|
||
break;
|
||
|
||
case 9: // tab
|
||
case 13: // enter
|
||
if (!this.shown) {return;}
|
||
this.select();
|
||
break;
|
||
|
||
case 27: // escape
|
||
if (!this.shown) {return;}
|
||
this.hide();
|
||
break;
|
||
|
||
default:
|
||
this.clearTarget();
|
||
this.lookup();
|
||
}
|
||
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
}
|
||
|
||
, focus: function (e) {
|
||
this.focused = true;
|
||
}
|
||
|
||
, blur: function (e) {
|
||
var that = this;
|
||
this.focused = false;
|
||
var val = this.$element.val();
|
||
if (!this.selected && val !== '' ) {
|
||
this.$element.val('');
|
||
this.$source.val('').trigger('change');
|
||
this.$target.val('').trigger('change');
|
||
}
|
||
if (!this.mousedover && this.shown) {setTimeout(function () { that.hide(); }, 200);}
|
||
}
|
||
|
||
, click: function (e) {
|
||
e.stopPropagation();
|
||
e.preventDefault();
|
||
this.select();
|
||
this.$element.focus();
|
||
}
|
||
|
||
, mouseenter: function (e) {
|
||
this.mousedover = true;
|
||
this.$menu.find('.active').removeClass('active');
|
||
$(e.currentTarget).addClass('active');
|
||
}
|
||
|
||
, mouseleave: function (e) {
|
||
this.mousedover = false;
|
||
}
|
||
};
|
||
|
||
/* COMBOBOX PLUGIN DEFINITION
|
||
* =========================== */
|
||
|
||
$.fn.combobox = function ( option ) {
|
||
return this.each(function () {
|
||
var $this = $(this)
|
||
, data = $this.data('combobox')
|
||
, options = typeof option == 'object' && option;
|
||
if(!data) {$this.data('combobox', (data = new Combobox(this, options)));}
|
||
if (typeof option == 'string') {data[option]();}
|
||
});
|
||
};
|
||
|
||
$.fn.combobox.defaults = {
|
||
template: '<div class="combobox-container"> <input type="hidden" /> <div class="input-group"> <input type="text" autocomplete="off" /> <span class="input-group-addon dropdown-toggle" data-dropdown="dropdown"> <span class="caret" /> <i class="fa fa-times"></i> </span> </div> </div> '
|
||
, menu: '<ul class="typeahead typeahead-long dropdown-menu"></ul>'
|
||
, item: '<li><a href="#"></a></li>'
|
||
};
|
||
|
||
$.fn.combobox.Constructor = Combobox;
|
||
|
||
}( window.jQuery );
|
||
|
||
/**
|
||
* jsPDF - PDF Document creation from JavaScript
|
||
* Version 1.0.119-git Built on 2014-04-29T03:48
|
||
* CommitID 119a246e55
|
||
*
|
||
* Copyright (c) 2010-2014 James Hall, https://github.com/MrRio/jsPDF
|
||
* 2010 Aaron Spike, https://github.com/acspike
|
||
* 2012 Willow Systems Corporation, willow-systems.com
|
||
* 2012 Pablo Hess, https://github.com/pablohess
|
||
* 2012 Florian Jenett, https://github.com/fjenett
|
||
* 2013 Warren Weckesser, https://github.com/warrenweckesser
|
||
* 2013 Youssef Beddad, https://github.com/lifof
|
||
* 2013 Lee Driscoll, https://github.com/lsdriscoll
|
||
* 2013 Stefan Slonevskiy, https://github.com/stefslon
|
||
* 2013 Jeremy Morel, https://github.com/jmorel
|
||
* 2013 Christoph Hartmann, https://github.com/chris-rock
|
||
* 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
|
||
* 2014 James Makes, https://github.com/dollaruw
|
||
* 2014 Diego Casorran, https://github.com/diegocr
|
||
*
|
||
* Permission is hereby granted, free of charge, to any person obtaining
|
||
* a copy of this software and associated documentation files (the
|
||
* "Software"), to deal in the Software without restriction, including
|
||
* without limitation the rights to use, copy, modify, merge, publish,
|
||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||
* permit persons to whom the Software is furnished to do so, subject to
|
||
* the following conditions:
|
||
*
|
||
* The above copyright notice and this permission notice shall be
|
||
* included in all copies or substantial portions of the Software.
|
||
*
|
||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
*
|
||
* Contributor(s):
|
||
* siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
|
||
* kim3er, mfo, alnorth,
|
||
*/
|
||
/**
|
||
* jsPDF addHTML PlugIn
|
||
* Copyright (c) 2014 Diego Casorran
|
||
* Licensed under the MIT License.
|
||
* http://opensource.org/licenses/mit-license
|
||
*/
|
||
/**
|
||
* jsPDF addImage plugin
|
||
* Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/
|
||
* 2013 Chris Dowling, https://github.com/gingerchris
|
||
* 2013 Trinh Ho, https://github.com/ineedfat
|
||
* 2013 Edwin Alejandro Perez, https://github.com/eaparango
|
||
* 2013 Norah Smith, https://github.com/burnburnrocket
|
||
* 2014 Diego Casorran, https://github.com/diegocr
|
||
* 2014 James Robb, https://github.com/jamesbrobb
|
||
*/
|
||
/**
|
||
* jsPDF Cell plugin
|
||
* Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
|
||
* 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
|
||
* 2013 Lee Driscoll, https://github.com/lsdriscoll
|
||
* 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
|
||
* 2014 James Hall, james@parall.ax
|
||
* 2014 Diego Casorran, https://github.com/diegocr
|
||
*/
|
||
/**
|
||
* jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser
|
||
* Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
|
||
* 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
|
||
* 2014 Diego Casorran, https://github.com/diegocr
|
||
*/
|
||
/**
|
||
* jsPDF JavaScript plugin
|
||
* Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
|
||
*/
|
||
/**
|
||
* jsPDF PNG PlugIn
|
||
* Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
|
||
*/
|
||
/**
|
||
jsPDF Silly SVG plugin
|
||
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
|
||
*/
|
||
/**
|
||
* jsPDF split_text_to_size plugin - MIT license.
|
||
* Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
|
||
* 2014 Diego Casorran, https://github.com/diegocr
|
||
*/
|
||
/**
|
||
jsPDF standard_fonts_metrics plugin
|
||
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
|
||
MIT license.
|
||
*/
|
||
/**
|
||
* jsPDF total_pages plugin
|
||
* Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
|
||
*/
|
||
/* Blob.js
|
||
* A Blob implementation.
|
||
* 2013-12-27
|
||
* By Eli Grey, http://eligrey.com
|
||
* By Devin Samarin, https://github.com/eboyjr
|
||
* License: X11/MIT
|
||
* See LICENSE.md
|
||
*/
|
||
/*! FileSaver.js
|
||
* A saveAs() FileSaver implementation.
|
||
* 2014-01-24
|
||
* By Eli Grey, http://eligrey.com
|
||
* License: X11/MIT
|
||
* See LICENSE.md
|
||
*/
|
||
/*
|
||
* Copyright (c) 2012 chick307 <chick307@gmail.com>
|
||
* Licensed under the MIT License.
|
||
* http://opensource.org/licenses/mit-license
|
||
*/
|
||
/*
|
||
Deflate.js - https://github.com/gildas-lormeau/zip.js
|
||
Copyright (c) 2013 Gildas Lormeau. All rights reserved.
|
||
Redistribution and use in source and binary forms, with or without
|
||
modification, are permitted provided that the following conditions are met:
|
||
1. Redistributions of source code must retain the above copyright notice,
|
||
this list of conditions and the following disclaimer.
|
||
2. Redistributions in binary form must reproduce the above copyright
|
||
notice, this list of conditions and the following disclaimer in
|
||
the documentation and/or other materials provided with the distribution.
|
||
3. The names of the authors may not be used to endorse or promote products
|
||
derived from this software without specific prior written permission.
|
||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
|
||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
|
||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
*/
|
||
/*
|
||
# PNG.js
|
||
# Copyright (c) 2011 Devon Govett
|
||
# MIT LICENSE
|
||
#
|
||
*/
|
||
/*
|
||
* Extracted from pdf.js
|
||
* https://github.com/andreasgal/pdf.js
|
||
* Copyright (c) 2011 Mozilla Foundation
|
||
* Contributors: Andreas Gal <gal@mozilla.com>
|
||
* Chris G Jones <cjones@mozilla.com>
|
||
* Shaon Barman <shaon.barman@gmail.com>
|
||
* Vivien Nicolas <21@vingtetun.org>
|
||
* Justin D'Arcangelo <justindarc@gmail.com>
|
||
* Yury Delendik
|
||
*/
|
||
/**
|
||
* JavaScript Polyfill functions for jsPDF
|
||
* Collected from public resources by
|
||
* https://github.com/diegocr
|
||
*/
|
||
!function(t,e){e["true"]=t;var r=function(t){"use strict";function e(e){var r={};this.subscribe=function(t,e,n){if("function"!=typeof e)return!1;r.hasOwnProperty(t)||(r[t]={});var s=Math.random().toString(35);return r[t][s]=[e,!!n],s},this.unsubscribe=function(t){for(var e in r)if(r[e][t])return delete r[e][t],!0;return!1},this.publish=function(n){if(r.hasOwnProperty(n)){var s=Array.prototype.slice.call(arguments,1),o=[];for(var i in r[n]){var a=r[n][i];try{a[0].apply(e,s)}catch(u){t.console&&console.error("jsPDF PubSub Error",u.message,u)}a[1]&&o.push(i)}o.length&&o.forEach(this.unsubscribe)}}}function r(u,c,l,f){var d={};"object"==typeof u&&(d=u,u=d.orientation,c=d.unit||c,l=d.format||l,f=d.compress||d.compressPdf||f),c=c||"mm",l=l||"a4",u=(""+(u||"P")).toLowerCase();var h,p,w,m,y,v=(""+l).toLowerCase(),g=!!f&&"function"==typeof Uint8Array,b=d.textColor||"0 g",q=d.drawColor||"0 G",x=d.fontSize||16,k=d.lineHeight||1.15,_=d.lineWidth||.200025,A=2,C=!1,S=[],E={},z={},B=0,I=[],T=[],P=0,O=0,R=0,D={title:"",subject:"",author:"",keywords:"",creator:""},U={},F=new e(U),j=function(t){return t.toFixed(2)},L=function(t){return t.toFixed(3)},N=function(t){return("0"+parseInt(t)).slice(-2)},M=function(t){C?I[B].push(t):(R+=t.length+1,T.push(t))},H=function(){return A++,S[A]=R,M(A+" 0 obj"),A},G=function(t){M("stream"),M(t),M("endstream")},J=function(){var e,n,s,i,a,u,c,l=m*p,f=y*p;for(c=t.adler32cs||r.adler32cs,g&&"undefined"==typeof c&&(g=!1),e=1;B>=e;e++){if(H(),M("<</Type /Page"),M("/Parent 1 0 R"),M("/Resources 2 0 R"),M("/Contents "+(A+1)+" 0 R>>"),M("endobj"),n=I[e].join("\n"),H(),g){for(s=[],i=n.length;i--;)s[i]=n.charCodeAt(i);u=c.from(n),a=new o(6),a.append(new Uint8Array(s)),n=a.flush(),s=new Uint8Array(n.length+6),s.set(new Uint8Array([120,156])),s.set(n,2),s.set(new Uint8Array([255&u,u>>8&255,u>>16&255,u>>24&255]),n.length+2),n=String.fromCharCode.apply(null,s),M("<</Length "+n.length+" /Filter [/FlateDecode]>>")}else M("<</Length "+n.length+">>");G(n),M("endobj")}S[1]=R,M("1 0 obj"),M("<</Type /Pages");var d="/Kids [";for(i=0;B>i;i++)d+=3+2*i+" 0 R ";M(d+"]"),M("/Count "+B),M("/MediaBox [0 0 "+j(l)+" "+j(f)+"]"),M(">>"),M("endobj")},W=function(t){t.objectNumber=H(),M("<</BaseFont/"+t.PostScriptName+"/Type/Font"),"string"==typeof t.encoding&&M("/Encoding/"+t.encoding),M("/Subtype/Type1>>"),M("endobj")},V=function(){for(var t in E)E.hasOwnProperty(t)&&W(E[t])},X=function(){F.publish("putXobjectDict")},Y=function(){M("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"),M("/Font <<");for(var t in E)E.hasOwnProperty(t)&&M("/"+t+" "+E[t].objectNumber+" 0 R");M(">>"),M("/XObject <<"),X(),M(">>")},K=function(){V(),F.publish("putResources"),S[2]=R,M("2 0 obj"),M("<<"),Y(),M(">>"),M("endobj"),F.publish("postPutResources")},Q=function(t,e,r){z.hasOwnProperty(e)||(z[e]={}),z[e][r]=t},$=function(t,e,r,n){var s="F"+(Object.keys(E).length+1).toString(10),o=E[s]={id:s,PostScriptName:t,fontName:e,fontStyle:r,encoding:n,metadata:{}};return Q(s,e,r),F.publish("addFont",o),s},Z=function(){for(var t="helvetica",e="times",r="courier",n="normal",s="bold",o="italic",i="bolditalic",a="StandardEncoding",u=[["Helvetica",t,n],["Helvetica-Bold",t,s],["Helvetica-Oblique",t,o],["Helvetica-BoldOblique",t,i],["Courier",r,n],["Courier-Bold",r,s],["Courier-Oblique",r,o],["Courier-BoldOblique",r,i],["Times-Roman",e,n],["Times-Bold",e,s],["Times-Italic",e,o],["Times-BoldItalic",e,i]],c=0,l=u.length;l>c;c++){var f=$(u[c][0],u[c][1],u[c][2],a),d=u[c][0].split("-");Q(f,d[0],d[1]||"")}F.publish("addFonts",{fonts:E,dictionary:z})},te=function(e){return e.foo=function(){try{return e.apply(this,arguments)}catch(r){var n=r.stack||"";~n.indexOf(" at ")&&(n=n.split(" at ")[1]);var s="Error in function "+n.split("\n")[0].split("<")[0]+": "+r.message;if(!t.console)throw new Error(s);console.log(s,r),t.alert&&alert(s),console.trace()}},e.foo.bar=e,e.foo},ee=function(t,e){var r,n,s,o,i,a,u,c,l;if(e=e||{},s=e.sourceEncoding||"Unicode",i=e.outputEncoding,(e.autoencode||i)&&E[h].metadata&&E[h].metadata[s]&&E[h].metadata[s].encoding&&(o=E[h].metadata[s].encoding,!i&&E[h].encoding&&(i=E[h].encoding),!i&&o.codePages&&(i=o.codePages[0]),"string"==typeof i&&(i=o[i]),i)){for(u=!1,a=[],r=0,n=t.length;n>r;r++)c=i[t.charCodeAt(r)],c?a.push(String.fromCharCode(c)):a.push(t[r]),a[r].charCodeAt(0)>>8&&(u=!0);t=a.join("")}for(r=t.length;void 0===u&&0!==r;)t.charCodeAt(r-1)>>8&&(u=!0),r--;if(!u)return t;for(a=e.noBOM?[]:[254,255],r=0,n=t.length;n>r;r++){if(c=t.charCodeAt(r),l=c>>8,l>>8)throw new Error("Character at position "+r+" of string '"+t+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");a.push(l),a.push(c-(l<<8))}return String.fromCharCode.apply(void 0,a)},re=function(t,e){return ee(t,e).replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},ne=function(){M("/Producer (jsPDF "+r.version+")");for(var t in D)D.hasOwnProperty(t)&&D[t]&&M("/"+t.substr(0,1).toUpperCase()+t.substr(1)+" ("+re(D[t])+")");var e=new Date;M(["/CreationDate (D:",e.getFullYear(),N(e.getMonth()+1),N(e.getDate()),N(e.getHours()),N(e.getMinutes()),N(e.getSeconds()),")"].join(""))},se=function(){M("/Type /Catalog"),M("/Pages 1 0 R"),M("/OpenAction [3 0 R /FitH null]"),M("/PageLayout /OneColumn"),F.publish("putCatalog")},oe=function(){M("/Size "+(A+1)),M("/Root "+A+" 0 R"),M("/Info "+(A-1)+" 0 R")},ie=function(){B++,C=!0,I[B]=[]},ae=function(){ie(),M(j(_*p)+" w"),M(q),0!==P&&M(P+" J"),0!==O&&M(O+" j"),F.publish("addPage",{pageNumber:B})},ue=function(t,e){var r;t=void 0!==t?t:E[h].fontName,e=void 0!==e?e:E[h].fontStyle;try{r=z[t][e]}catch(n){}if(!r)throw new Error("Unable to look up font label for font '"+t+"', '"+e+"'. Refer to getFontList() for available fonts.");return r},ce=function(){C=!1,A=2,T=[],S=[],M("%PDF-"+i),J(),K(),H(),M("<<"),ne(),M(">>"),M("endobj"),H(),M("<<"),se(),M(">>"),M("endobj");var t,e=R,r="0000000000";for(M("xref"),M("0 "+(A+1)),M(r+" 65535 f "),t=1;A>=t;t++)M((r+S[t]).slice(-10)+" 00000 n ");return M("trailer"),M("<<"),oe(),M(">>"),M("startxref"),M(e),M("%%EOF"),C=!0,T.join("\n")},le=function(t){var e="S";return"F"===t?e="f":"FD"===t||"DF"===t?e="B":("f"===t||"f*"===t||"B"===t||"B*"===t)&&(e=t),e},fe=function(){for(var t=ce(),e=t.length,r=new ArrayBuffer(e),n=new Uint8Array(r);e--;)n[e]=t.charCodeAt(e);return r},de=function(){return new n([fe()],{type:"application/pdf"})},he=te(function(e,r){switch(e){case void 0:return ce();case"save":if(navigator.getUserMedia&&(void 0===t.URL||void 0===t.URL.createObjectURL))return U.output("dataurlnewwindow");s(de(),r),"function"==typeof s.unload&&t.setTimeout&&setTimeout(s.unload,70);break;case"arraybuffer":return fe();case"blob":return de();case"datauristring":case"dataurlstring":return"data:application/pdf;base64,"+btoa(ce());case"datauri":case"dataurl":t.document.location.href="data:application/pdf;base64,"+btoa(ce());break;case"dataurlnewwindow":t.open("data:application/pdf;base64,"+btoa(ce()));break;default:throw new Error('Output type "'+e+'" is not supported.')}});switch(c){case"pt":p=1;break;case"mm":p=72/25.4;break;case"cm":p=72/2.54;break;case"in":p=72;break;case"px":p=96/72;break;case"pc":p=12;break;case"em":p=12;break;case"ex":p=6;break;default:throw"Invalid unit: "+c}if(a.hasOwnProperty(v))y=a[v][1]/p,m=a[v][0]/p;else try{y=l[1],m=l[0]}catch(pe){throw new Error("Invalid format: "+l)}if("p"===u||"portrait"===u)u="p",m>y&&(w=m,m=y,y=w);else{if("l"!==u&&"landscape"!==u)throw"Invalid orientation: "+u;u="l",y>m&&(w=m,m=y,y=w)}U.internal={pdfEscape:re,getStyle:le,getFont:function(){return E[ue.apply(U,arguments)]},getFontSize:function(){return x},getLineHeight:function(){return x*k},write:function(t){M(1===arguments.length?t:Array.prototype.join.call(arguments," "))},getCoordinateString:function(t){return j(t*p)},getVerticalCoordinateString:function(t){return j((y-t)*p)},collections:{},newObject:H,putStream:G,events:F,scaleFactor:p,pageSize:{width:m,height:y},output:function(t,e){return he(t,e)},getNumberOfPages:function(){return I.length-1},pages:I},U.addPage=function(){return ae(),this},U.text=function(t,e,r,n,s){"number"==typeof t&&(w=r,r=e,e=t,t=w),"string"==typeof t&&t.match(/[\n\r]/)&&(t=t.split(/\r\n|\r|\n/g)),"number"==typeof n&&(s=n,n=null);var o="",i="Td";if(s){s*=Math.PI/180;var a=Math.cos(s),u=Math.sin(s);o=[j(a),j(u),j(-1*u),j(a),""].join(" "),i="Tm"}if(n=n||{},"noBOM"in n||(n.noBOM=!0),"autoencode"in n||(n.autoencode=!0),"string"==typeof t)t=re(t,n);else{if(!(t instanceof Array))throw new Error('Type of text must be string or Array. "'+t+'" is not recognized.');for(var c=t.concat(),l=[],f=c.length;f--;)l.push(re(c.shift(),n));t=l.join(") Tj\nT* (")}return M("BT\n/"+h+" "+x+" Tf\n"+x*k+" TL\n"+b+"\n"+o+j(e*p)+" "+j((y-r)*p)+" "+i+"\n("+t+") Tj\nET"),this},U.line=function(t,e,r,n){return this.lines([[r-t,n-e]],t,e)},U.lines=function(t,e,r,n,s,o){var i,a,u,c,l,f,d,h,m,v,g;for("number"==typeof t&&(w=r,r=e,e=t,t=w),n=n||[1,1],M(L(e*p)+" "+L((y-r)*p)+" m "),i=n[0],a=n[1],c=t.length,v=e,g=r,u=0;c>u;u++)l=t[u],2===l.length?(v=l[0]*i+v,g=l[1]*a+g,M(L(v*p)+" "+L((y-g)*p)+" l")):(f=l[0]*i+v,d=l[1]*a+g,h=l[2]*i+v,m=l[3]*a+g,v=l[4]*i+v,g=l[5]*a+g,M(L(f*p)+" "+L((y-d)*p)+" "+L(h*p)+" "+L((y-m)*p)+" "+L(v*p)+" "+L((y-g)*p)+" c"));return o&&M(" h"),null!==s&&M(le(s)),this},U.rect=function(t,e,r,n,s){le(s);return M([j(t*p),j((y-e)*p),j(r*p),j(-n*p),"re"].join(" ")),null!==s&&M(le(s)),this},U.triangle=function(t,e,r,n,s,o,i){return this.lines([[r-t,n-e],[s-r,o-n],[t-s,e-o]],t,e,[1,1],i,!0),this},U.roundedRect=function(t,e,r,n,s,o,i){var a=4/3*(Math.SQRT2-1);return this.lines([[r-2*s,0],[s*a,0,s,o-o*a,s,o],[0,n-2*o],[0,o*a,-(s*a),o,-s,o],[-r+2*s,0],[-(s*a),0,-s,-(o*a),-s,-o],[0,-n+2*o],[0,-(o*a),s*a,-o,s,-o]],t+s,e,[1,1],i),this},U.ellipse=function(t,e,r,n,s){var o=4/3*(Math.SQRT2-1)*r,i=4/3*(Math.SQRT2-1)*n;return M([j((t+r)*p),j((y-e)*p),"m",j((t+r)*p),j((y-(e-i))*p),j((t+o)*p),j((y-(e-n))*p),j(t*p),j((y-(e-n))*p),"c"].join(" ")),M([j((t-o)*p),j((y-(e-n))*p),j((t-r)*p),j((y-(e-i))*p),j((t-r)*p),j((y-e)*p),"c"].join(" ")),M([j((t-r)*p),j((y-(e+i))*p),j((t-o)*p),j((y-(e+n))*p),j(t*p),j((y-(e+n))*p),"c"].join(" ")),M([j((t+o)*p),j((y-(e+n))*p),j((t+r)*p),j((y-(e+i))*p),j((t+r)*p),j((y-e)*p),"c"].join(" ")),null!==s&&M(le(s)),this},U.circle=function(t,e,r,n){return this.ellipse(t,e,r,r,n)},U.setProperties=function(t){for(var e in D)D.hasOwnProperty(e)&&t[e]&&(D[e]=t[e]);return this},U.setFontSize=function(t){return x=t,this},U.setFont=function(t,e){return h=ue(t,e),this},U.setFontStyle=U.setFontType=function(t){return h=ue(void 0,t),this},U.getFontList=function(){var t,e,r,n={};for(t in z)if(z.hasOwnProperty(t)){n[t]=r=[];for(e in z[t])z[t].hasOwnProperty(e)&&r.push(e)}return n},U.setLineWidth=function(t){return M((t*p).toFixed(2)+" w"),this},U.setDrawColor=function(t,e,r,n){var s;return s=void 0===e||void 0===n&&t===e===r?"string"==typeof t?t+" G":j(t/255)+" G":void 0===n?"string"==typeof t?[t,e,r,"RG"].join(" "):[j(t/255),j(e/255),j(r/255),"RG"].join(" "):"string"==typeof t?[t,e,r,n,"K"].join(" "):[j(t),j(e),j(r),j(n),"K"].join(" "),M(s),this},U.setFillColor=function(t,e,r,n){var s;return s=void 0===e||void 0===n&&t===e===r?"string"==typeof t?t+" g":j(t/255)+" g":void 0===n?"string"==typeof t?[t,e,r,"rg"].join(" "):[j(t/255),j(e/255),j(r/255),"rg"].join(" "):"string"==typeof t?[t,e,r,n,"k"].join(" "):[j(t),j(e),j(r),j(n),"k"].join(" "),M(s),this},U.setTextColor=function(t,e,r){if("string"==typeof t&&/^#[0-9A-Fa-f]{6}$/.test(t)){var n=parseInt(t.substr(1),16);t=n>>16&255,e=n>>8&255,r=255&n}return b=0===t&&0===e&&0===r||"undefined"==typeof e?L(t/255)+" g":[L(t/255),L(e/255),L(r/255),"rg"].join(" "),this},U.CapJoinStyles={0:0,butt:0,but:0,miter:0,1:1,round:1,rounded:1,circle:1,2:2,projecting:2,project:2,square:2,bevel:2},U.setLineCap=function(t){var e=this.CapJoinStyles[t];if(void 0===e)throw new Error("Line cap style of '"+t+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return P=e,M(e+" J"),this},U.setLineJoin=function(t){var e=this.CapJoinStyles[t];if(void 0===e)throw new Error("Line join style of '"+t+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return O=e,M(e+" j"),this},U.output=he,U.save=function(t){U.output("save",t)};for(var we in r.API)r.API.hasOwnProperty(we)&&("events"===we&&r.API.events.length?!function(t,e){var r,n,s;for(s=e.length-1;-1!==s;s--)r=e[s][0],n=e[s][1],t.subscribe.apply(t,[r].concat("function"==typeof n?[n]:n))}(F,r.API.events):U[we]=r.API[we]);return Z(),h="F1",ae(),F.publish("initialized"),U}var i="1.3",a={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]};return r.API={events:[]},r.version="1.0.119-git 2014-04-29T03:48:diegocr","function"==typeof define?define(function(){return r}):t.jsPDF=r,r}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this);if(function(t){"use strict";t.addHTML=function(t,e,r,n,s){if("undefined"==typeof html2canvas)throw new Error("You need this: https://github.com/niklasvh/html2canvas");return"number"!=typeof e&&(n=e,s=r),"function"==typeof n&&(s=n,n=null),n=n||{},n.onrendered=function(t){e=parseInt(e)||0,r=parseInt(r)||0;var o=n.dim||{},i=o.h||0,a=o.w||Math.min(this.internal.pageSize.width,t.width/this.internal.scaleFactor)-e,u="JPEG";n.format&&(u=n.format);var c=Math.random().toString(35),l=[t,e,r,a,i,u,c,"SLOW"];this.addImage.apply(this,l),s(a,i,c,l)}.bind(this),html2canvas(t,n)}}(r.API),function(t){"use strict";var e="addImage_",r=["jpeg","jpg","png"],n=function(t){var e=this.internal.newObject(),r=this.internal.write,s=this.internal.putStream;if(t.n=e,r("<</Type /XObject"),r("/Subtype /Image"),r("/Width "+t.w),r("/Height "+t.h),t.cs===this.color_spaces.INDEXED?r("/ColorSpace [/Indexed /DeviceRGB "+(t.pal.length/3-1)+" "+("smask"in t?e+2:e+1)+" 0 R]"):(r("/ColorSpace /"+t.cs),t.cs===this.color_spaces.DEVICE_CMYK&&r("/Decode [1 0 1 0 1 0 1 0]")),r("/BitsPerComponent "+t.bpc),"f"in t&&r("/Filter /"+t.f),"dp"in t&&r("/DecodeParms <<"+t.dp+">>"),"trns"in t&&t.trns.constructor==Array){for(var o="",i=0,a=t.trns.length;a>i;i++)o+=t.trns[i]+" "+t.trns[i]+" ";r("/Mask ["+o+"]")}if("smask"in t&&r("/SMask "+(e+1)+" 0 R"),r("/Length "+t.data.length+">>"),s(t.data),r("endobj"),"smask"in t){var u="/Predictor 15 /Colors 1 /BitsPerComponent "+t.bpc+" /Columns "+t.w,c={w:t.w,h:t.h,cs:"DeviceGray",bpc:t.bpc,dp:u,data:t.smask};"f"in t&&(c.f=t.f),n.call(this,c)}t.cs===this.color_spaces.INDEXED&&(this.internal.newObject(),r("<< /Length "+t.pal.length+">>"),s(this.arrayBufferToBinaryString(new Uint8Array(t.pal))),r("endobj"))},s=function(){var t=this.internal.collections[e+"images"];for(var r in t)n.call(this,t[r])},o=function(){var t,r=this.internal.collections[e+"images"],n=this.internal.write;for(var s in r)t=r[s],n("/I"+t.i,t.n,"0","R")},i=function(e){return e&&"string"==typeof e&&(e=e.toUpperCase()),e in t.image_compression?e:t.image_compression.NONE},a=function(){var t=this.internal.collections[e+"images"];return t||(this.internal.collections[e+"images"]=t={},this.internal.events.subscribe("putResources",s),this.internal.events.subscribe("putXobjectDict",o)),t},u=function(t){var e=0;return t&&(e=Object.keys?Object.keys(t).length:function(t){var e=0;for(var r in t)t.hasOwnProperty(r)&&e++;return e}(t)),e},c=function(t){return"undefined"==typeof t||null===t},l=function(){return void 0},f=function(t){return-1===r.indexOf(t)},d=function(e){return"function"!=typeof t["process"+e.toUpperCase()]},h=function(t){return"object"==typeof t&&1===t.nodeType},p=function(t,e){if("CANVAS"===t.nodeName)var r=t;else{var r=document.createElement("canvas");r.width=t.clientWidth||t.width,r.height=t.clientHeight||t.height;var n=r.getContext("2d");if(!n)throw"addImage requires canvas to be supported by browser.";n.drawImage(t,0,0,r.width,r.height)}return r.toDataURL("png"==e?"image/png":"image/jpeg")},w=function(t,e){var r;if(e)for(var n in e)if(t===e[n].alias){r=e[n];break}return r},m=function(t,e,r){return t||e||(t=-96,e=-96),0>t&&(t=-1*r.w*72/t/this.internal.scaleFactor),0>e&&(e=-1*r.h*72/e/this.internal.scaleFactor),0===t&&(t=e*r.w/r.h),0===e&&(e=t*r.h/r.w),[t,e]},y=function(t,e,r,n,s,o,i){var a=m.call(this,r,n,s),u=this.internal.getCoordinateString,c=this.internal.getVerticalCoordinateString;r=a[0],n=a[1],i[o]=s,this.internal.write("q",u(r),"0 0",u(n),u(t),c(e+n),"cm /I"+s.i,"Do Q")};t.color_spaces={DEVICE_RGB:"DeviceRGB",DEVICE_GRAY:"DeviceGray",DEVICE_CMYK:"DeviceCMYK",CAL_GREY:"CalGray",CAL_RGB:"CalRGB",LAB:"Lab",ICC_BASED:"ICCBased",INDEXED:"Indexed",PATTERN:"Pattern",SEPERATION:"Seperation",DEVICE_N:"DeviceN"},t.decode={DCT_DECODE:"DCTDecode",FLATE_DECODE:"FlateDecode",LZW_DECODE:"LZWDecode",JPX_DECODE:"JPXDecode",JBIG2_DECODE:"JBIG2Decode",ASCII85_DECODE:"ASCII85Decode",ASCII_HEX_DECODE:"ASCIIHexDecode",RUN_LENGTH_DECODE:"RunLengthDecode",CCITT_FAX_DECODE:"CCITTFaxDecode"},t.image_compression={NONE:"NONE",FAST:"FAST",MEDIUM:"MEDIUM",SLOW:"SLOW"},t.isString=function(t){return"string"==typeof t},t.extractInfoFromBase64DataURI=function(t){return/^data:([\w]+?\/([\w]+?));base64,(.+?)$/g.exec(t)},t.supportsArrayBuffer=function(){return"function"==typeof ArrayBuffer&&"undefined"!=typeof Uint8Array},t.isArrayBuffer=function(t){return this.supportsArrayBuffer()?t instanceof ArrayBuffer:!1},t.isArrayBufferView=function(t){return this.supportsArrayBuffer()?"undefined"==typeof Uint32Array?!1:t instanceof Int8Array||t instanceof Uint8Array||"undefined"!=typeof Uint8ClampedArray&&t instanceof Uint8ClampedArray||t instanceof Int16Array||t instanceof Uint16Array||t instanceof Int32Array||t instanceof Uint32Array||t instanceof Float32Array||t instanceof Float64Array:!1},t.binaryStringToUint8Array=function(t){for(var e=t.length,r=new Uint8Array(e),n=0;e>n;n++)r[n]=t.charCodeAt(n);return r},t.arrayBufferToBinaryString=function(t){this.isArrayBuffer(t)&&(t=new Uint8Array(t));for(var e="",r=t.byteLength,n=0;r>n;n++)e+=String.fromCharCode(t[n]);return e},t.arrayBufferToBase64=function(t){for(var e,r,n,s,o,i="",a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",u=new Uint8Array(t),c=u.byteLength,l=c%3,f=c-l,d=0;f>d;d+=3)o=u[d]<<16|u[d+1]<<8|u[d+2],e=(16515072&o)>>18,r=(258048&o)>>12,n=(4032&o)>>6,s=63&o,i+=a[e]+a[r]+a[n]+a[s];return 1==l?(o=u[f],e=(252&o)>>2,r=(3&o)<<4,i+=a[e]+a[r]+"=="):2==l&&(o=u[f]<<8|u[f+1],e=(64512&o)>>10,r=(1008&o)>>4,n=(15&o)<<2,i+=a[e]+a[r]+a[n]+"="),i},t.createImageInfo=function(t,e,r,n,s,o,i,a,u,c,l,f){var d={alias:a,w:e,h:r,cs:n,bpc:s,i:i,data:t};return o&&(d.f=o),u&&(d.dp=u),c&&(d.trns=c),l&&(d.pal=l),f&&(d.smask=f),d},t.addImage=function(t,e,n,s,o,m,v,g){if("number"==typeof e){var b=m;m=o,o=s,s=n,n=e,e=b}var q,x,k=a.call(this);if(g=i(g),e=(e||"JPEG").toLowerCase(),c(v)&&(v=l(t)),h(t)&&(t=p(t,e)),this.isString(t)){var _=this.extractInfoFromBase64DataURI(t);_?(e=_[2],t=atob(_[3]),this.supportsArrayBuffer()&&(x=t,t=this.binaryStringToUint8Array(t))):255!==t.charCodeAt(0)&&(q=w(t,k))}if(f(e))throw new Error("addImage currently only supports formats "+r+", not '"+e+"'");if(d(e))throw new Error("please ensure that the plugin for '"+e+"' support is added");var A=u(k),C=q;if(C||(C=this["process"+e.toUpperCase()](t,A,v,g,x)),!C)throw new Error("An unkwown error occurred whilst processing the image");return y.call(this,n,s,o,m,C,A,k),this};var v=function(t){var e,r;if(255===!t.charCodeAt(0)||216===!t.charCodeAt(1)||255===!t.charCodeAt(2)||224===!t.charCodeAt(3)||!t.charCodeAt(6)==="J".charCodeAt(0)||!t.charCodeAt(7)==="F".charCodeAt(0)||!t.charCodeAt(8)==="I".charCodeAt(0)||!t.charCodeAt(9)==="F".charCodeAt(0)||0===!t.charCodeAt(10))throw new Error("getJpegSize requires a binary string jpeg file");for(var n=256*t.charCodeAt(4)+t.charCodeAt(5),s=4,o=t.length;o>s;){if(s+=n,255!==t.charCodeAt(s))throw new Error("getJpegSize could not find the size of the image");if(192===t.charCodeAt(s+1)||193===t.charCodeAt(s+1)||194===t.charCodeAt(s+1)||195===t.charCodeAt(s+1)||196===t.charCodeAt(s+1)||197===t.charCodeAt(s+1)||198===t.charCodeAt(s+1)||199===t.charCodeAt(s+1))return r=256*t.charCodeAt(s+5)+t.charCodeAt(s+6),e=256*t.charCodeAt(s+7)+t.charCodeAt(s+8),[e,r];s+=2,n=256*t.charCodeAt(s)+t.charCodeAt(s+1)}},g=function(t){var e=t[0]<<8|t[1];if(65496!==e)throw new Error("Supplied data is not a JPEG");for(var r,n,s,o=t.length,i=(t[4]<<8)+t[5],a=4;o>a;){if(a+=i,r=b(t,a),i=(r[2]<<8)+r[3],(192===r[1]||194===r[1])&&255===r[0]&&i>7)return r=b(t,a+5),n=(r[2]<<8)+r[3],s=(r[0]<<8)+r[1],{width:n,height:s};a+=2}throw new Error("getJpegSizeFromBytes could not find the size of the image")},b=function(t,e){return t.subarray(e,e+4)};t.processJPEG=function(t,e,r,n,s){var o,i=this.color_spaces.DEVICE_RGB,a=this.decode.DCT_DECODE,u=8;return this.isString(t)?(o=v(t),this.createImageInfo(t,o[0],o[1],i,u,a,e,r)):(this.isArrayBuffer(t)&&(t=new Uint8Array(t)),this.isArrayBufferView(t)?(o=g(t),t=s||this.arrayBufferToBinaryString(t),this.createImageInfo(t,o.width,o.height,i,u,a,e,r)):null)},t.processJPG=function(){return this.processJPEG.apply(this,arguments)}}(r.API),function(t){"use strict";t.autoPrint=function(){var t;return this.internal.events.subscribe("postPutResources",function(){t=this.internal.newObject(),this.internal.write("<< /S/Named /Type/Action /N/Print >>","endobj")}),this.internal.events.subscribe("putCatalog",function(){this.internal.write("/OpenAction "+t+" 0 R")}),this}}(r.API),function(t){"use strict";var e,r,n,s,o=3,i=13,a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1,c=function(t,e,r,n,s){a={x:t,y:e,w:r,h:n,ln:s}},l=function(){return a};t.setHeaderFunction=function(t){s=t},t.getTextDimensions=function(t){e=this.internal.getFont().fontName,r=this.table_font_size||this.internal.getFontSize(),n=this.internal.getFont().fontStyle;var s,o,i=19.049976/25.4;return o=document.createElement("font"),o.id="jsPDFCell",o.style.fontStyle=n,o.style.fontName=e,o.style.fontSize=r+"pt",o.innerText=t,document.body.appendChild(o),s={w:(o.offsetWidth+1)*i,h:(o.offsetHeight+1)*i},document.body.removeChild(o),s},t.cellAddPage=function(){this.addPage(),c(this.margins.left,this.margins.top,void 0,void 0),u+=1},t.cellInitialize=function(){a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1},t.cell=function(t,e,r,n,s,a,u){var f=l();if(void 0!==f.ln&&(f.ln===a?(t=f.x+f.w,e=f.y):(f.y+f.h+n+i>=this.internal.pageSize.height-this.margins.bottom&&(this.cellAddPage(),this.printHeaders&&this.tableHeaderRow&&this.printHeaderRow(a,!0)),e=l().y+l().h)),void 0!==s[0])if(this.printingHeaderRow?this.rect(t,e,r,n,"FD"):this.rect(t,e,r,n),"right"===u){if(s instanceof Array)for(var d=0;d<s.length;d++){var h=s[d],p=this.getStringUnitWidth(h)*this.internal.getFontSize();this.text(h,t+r-p-o,e+this.internal.getLineHeight()*(d+1))}}else this.text(s,t+o,e+this.internal.getLineHeight());return c(t,e,r,n,a),this},t.arrayMax=function(t,e){var r,n,s,o=t[0];for(r=0,n=t.length;n>r;r+=1)s=t[r],e?-1===e(o,s)&&(o=s):s>o&&(o=s);return o},t.table=function(e,r,n,s,o){if(!n)throw"No data for PDF table";var i,c,l,f,d,h,p,w,m,y,v=[],g=[],b={},q={},x=[],k=[],_=!1,A=!0,C=12,S={left:0,top:0,bottom:0,width:this.internal.pageSize.width};if(o&&(o.autoSize===!0&&(_=!0),o.printHeaders===!1&&(A=!1),o.fontSize&&(C=o.fontSize),o.margins&&(S=o.margins)),this.lnMod=0,a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1,this.printHeaders=A,this.margins=S,this.setFontSize(C),this.table_font_size=C,void 0===s||null===s)v=Object.keys(n[0]);else if(s[0]&&"string"!=typeof s[0]){var E=19.049976/25.4;for(c=0,l=s.length;l>c;c+=1)i=s[c],v.push(i.name),g.push(i.prompt),q[i.name]=i.width*E}else v=s;if(_)for(y=function(t){return t[i]},c=0,l=v.length;l>c;c+=1){for(i=v[c],b[i]=n.map(y),x.push(this.getTextDimensions(g[c]||i).w),h=b[i],p=0,f=h.length;f>p;p+=1)d=h[p],x.push(this.getTextDimensions(d).w);q[i]=t.arrayMax(x)}if(A){var z=this.calculateLineHeight(v,q,g.length?g:v);for(c=0,l=v.length;l>c;c+=1)i=v[c],k.push([e,r,q[i],z,String(g.length?g[c]:i)]);this.setTableHeaderRow(k),this.printHeaderRow(1,!1)}for(c=0,l=n.length;l>c;c+=1){var z;for(w=n[c],z=this.calculateLineHeight(v,q,w),p=0,m=v.length;m>p;p+=1)i=v[p],this.cell(e,r,q[i],z,w[i],c+2,i.align)}return this.lastCellPos=a,this.table_x=e,this.table_y=r,this},t.calculateLineHeight=function(t,e,r){for(var n,s=0,i=0;i<t.length;i++){n=t[i],r[n]=this.splitTextToSize(String(r[n]),e[n]-o);var a=this.internal.getLineHeight()*r[n].length+o;a>s&&(s=a)}return s},t.setTableHeaderRow=function(t){this.tableHeaderRow=t},t.printHeaderRow=function(t,e){if(!this.tableHeaderRow)throw"Property tableHeaderRow does not exist.";var r,n,o,i;if(this.printingHeaderRow=!0,void 0!==s){var a=s(this,u);c(a[0],a[1],a[2],a[3],-1)}this.setFontStyle("bold");var l=[];for(o=0,i=this.tableHeaderRow.length;i>o;o+=1)this.setFillColor(200,200,200),r=this.tableHeaderRow[o],e&&(r[1]=this.margins.top,l.push(r)),n=[].concat(r),this.cell.apply(this,n.concat(t));l.length>0&&this.setTableHeaderRow(l),this.setFontStyle("normal"),this.printingHeaderRow=!1}}(r.API),function(t){var e,r,n,s,o,i,a,u,c,l,f,d,h,p,w;i=function(t){var e,r,n,s,o,i,a;for(r=0,n=t.length,e=void 0,s=!1,i=!1;!s&&r!==n;)e=t[r]=t[r].trimLeft(),e&&(s=!0),r++;for(r=n-1;n&&!i&&-1!==r;)e=t[r]=t[r].trimRight(),e&&(i=!0),r--;for(o=/\s+$/g,a=!0,r=0;r!==n;)e=t[r].replace(/\s+/g," "),a&&(e=e.trimLeft()),e&&(a=o.test(e)),t[r]=e,r++;return t},a=function(t,e,r,n){return this.pdf=t,this.x=e,this.y=r,this.settings=n,this.init(),this},u=function(t){var e,n,s;for(e=void 0,s=t.split(","),n=s.shift();!e&&n;)e=r[n.trim().toLowerCase()],n=s.shift();return e},c=function(t){var e,r,n;return r=void 0,e=16,(n=l[t])?n:(n={"xx-small":9,"x-small":11,small:13,medium:16,large:19,"x-large":23,"xx-large":28,auto:0}[{css_line_height_string:t}],n!==r?l[t]=n/e:(n=parseFloat(t))?l[t]=n/e:(n=t.match(/([\d\.]+)(px)/),l[t]=3===n.length?parseFloat(n[1])/e:1))},o=function(t){var e,r,o;return o=function(t){var e;return e=function(t){return document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(t,null):t.currentStyle?t.currentStyle:t.style}(t),function(t){return t=t.replace(/-\D/g,function(t){return t.charAt(1).toUpperCase()}),e[t]}}(t),e={},r=void 0,e["font-family"]=u(o("font-family"))||"times",e["font-style"]=n[o("font-style")]||"normal",r=s[o("font-weight")]||"normal","bold"===r&&(e["font-style"]="normal"===e["font-style"]?r:r+e["font-style"]),e["font-size"]=c(o("font-size"))||1,e["line-height"]=c(o("line-height"))||1,e.display="inline"===o("display")?"inline":"block","block"===e.display&&(e["margin-top"]=c(o("margin-top"))||0,e["margin-bottom"]=c(o("margin-bottom"))||0,e["padding-top"]=c(o("padding-top"))||0,e["padding-bottom"]=c(o("padding-bottom"))||0,e["margin-left"]=c(o("margin-left"))||0,e["margin-right"]=c(o("margin-right"))||0,e["padding-left"]=c(o("padding-left"))||0,e["padding-right"]=c(o("padding-right"))||0),e},f=function(t,e,r){var n,s,o,i,a;if(o=!1,s=void 0,i=void 0,a=void 0,n=r["#"+t.id])if("function"==typeof n)o=n(t,e);else for(s=0,i=n.length;!o&&s!==i;)o=n[s](t,e),s++;if(n=r[t.nodeName],!o&&n)if("function"==typeof n)o=n(t,e);else for(s=0,i=n.length;!o&&s!==i;)o=n[s](t,e),s++;return o},w=function(t,e){var r,n,s,o,i,a,u,c,l,f;for(r=[],n=[],s=0,f=t.rows[0].cells.length,c=t.clientWidth;f>s;)l=t.rows[0].cells[s],n[s]={name:l.textContent.toLowerCase().replace(/\s+/g,""),prompt:l.textContent.replace(/\r?\n/g,""),width:l.clientWidth/c*e.pdf.internal.pageSize.width},s++;for(s=1;s<t.rows.length;){for(a=t.rows[s],i={},o=0;o<a.cells.length;)i[n[o].name]=a.cells[o].textContent.replace(/\r?\n/g,""),o++;r.push(i),s++}return u={rows:r,headers:n}};var m={SCRIPT:1,STYLE:1,NOSCRIPT:1,OBJECT:1,EMBED:1};return e=function(t,r,n){var s,i,a,u,c,l,h,p;for(i=t.childNodes,s=void 0,a=o(t),c="block"===a.display,c&&(r.setBlockBoundary(),r.setBlockStyle(a)),h=19.049976/25.4,u=0,l=i.length;l>u;)s=i[u],"object"==typeof s&&(8===s.nodeType&&"#comment"===s.nodeName?s.textContent.match("ADD_PAGE")&&(r.pdf.addPage(),r.y=r.pdf.margins_doc.top):1!==s.nodeType||m[s.nodeName]?3===s.nodeType?r.addText(s.nodeValue,a):"string"==typeof s&&r.addText(s,a):"IMG"===s.nodeName&&d[s.getAttribute("src")]?(r.pdf.internal.pageSize.height-r.pdf.margins_doc.bottom<r.y+s.height&&r.y>r.pdf.margins_doc.top&&(r.pdf.addPage(),r.y=r.pdf.margins_doc.top),r.pdf.addImage(d[s.getAttribute("src")],r.x,r.y,s.width,s.height),r.y+=s.height):"TABLE"===s.nodeName?(p=w(s,r),r.y+=10,r.pdf.table(r.x,r.y,p.rows,p.headers,{autoSize:!1,printHeaders:!0,margins:r.pdf.margins_doc}),r.y=r.pdf.lastCellPos.y+r.pdf.lastCellPos.h+20):f(s,r,n)||e(s,r,n)),u++;return c?r.setBlockBoundary():void 0},d={},h=function(t,r,n,s){function o(){e(t,r,n),s(r.dispose())}function i(t){if(t){var e=new Image;++c,e.crossOrigin="",e.onerror=e.onload=function(){e.complete&&e.width+e.height&&(d[t]=d[t]||e),--c||o()},e.src=t}}for(var a=t.getElementsByTagName("img"),u=a.length,c=0;u--;)i(a[u].getAttribute("src"));return s=s||function(){},c||o()},p=function(t,e,r,n,s,o){if(!e)return!1;e.parentNode||(e=""+e.innerHTML),"string"==typeof e&&(e=function(t){var e,r,n,s;return n="jsPDFhtmlText"+Date.now().toString()+(1e3*Math.random()).toFixed(0),s="position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;",r=document.createElement("div"),r.style.cssText=s,r.innerHTML='<iframe style="height:1px;width:1px" name="'+n+'" />',document.body.appendChild(r),e=window.frames[n],e.document.body.innerHTML=t,e.document.body}(e.replace(/<\/?script[^>]*?>/gi,"")));var i=new a(t,r,n,s);return h.call(this,e,i,s.elementHandlers,o),i.dispose()},a.prototype.init=function(){return this.paragraph={text:[],style:[]},this.pdf.internal.write("q")},a.prototype.dispose=function(){return this.pdf.internal.write("Q"),{x:this.x,y:this.y}},a.prototype.splitFragmentsIntoLines=function(t,e){var r,n,s,o,i,a,u,c,l,f,d,h,p,w,m;for(n=12,d=this.pdf.internal.scaleFactor,i={},s=void 0,f=void 0,o=void 0,a=void 0,m=void 0,l=void 0,c=void 0,u=void 0,h=[],p=[h],r=0,w=this.settings.width;t.length;)if(a=t.shift(),m=e.shift(),a)if(s=m["font-family"],f=m["font-style"],o=i[s+f],o||(o=this.pdf.internal.getFont(s,f).metadata.Unicode,i[s+f]=o),l={widths:o.widths,kerning:o.kerning,fontSize:m["font-size"]*n,textIndent:r},c=this.pdf.getStringUnitWidth(a,l)*l.fontSize/d,r+c>w){for(u=this.pdf.splitTextToSize(a,w,l),h.push([u.shift(),m]);u.length;)h=[[u.shift(),m]],p.push(h);r=this.pdf.getStringUnitWidth(h[0][0],l)*l.fontSize/d}else h.push([a,m]),r+=c;return p},a.prototype.RenderTextFragment=function(t,e){var r,n;return this.pdf.internal.pageSize.height-this.pdf.margins_doc.bottom<this.y+this.pdf.internal.getFontSize()&&(this.pdf.internal.write("ET","Q"),this.pdf.addPage(),this.y=this.pdf.margins_doc.top,this.pdf.internal.write("q","BT",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td")),r=12,n=this.pdf.internal.getFont(e["font-family"],e["font-style"]),this.pdf.internal.write("/"+n.id,(r*e["font-size"]).toFixed(2),"Tf","("+this.pdf.internal.pdfEscape(t)+") Tj")},a.prototype.renderParagraph=function(){var t,e,r,n,s,o,a,u,c,l,f,d,h,p;if(n=i(this.paragraph.text),p=this.paragraph.style,t=this.paragraph.blockstyle,h=this.paragraph.blockstyle||{},this.paragraph={text:[],style:[],blockstyle:{},priorblockstyle:t},n.join("").trim()){for(u=this.splitFragmentsIntoLines(n,p),a=void 0,c=void 0,e=12,r=e/this.pdf.internal.scaleFactor,d=(Math.max((t["margin-top"]||0)-(h["margin-bottom"]||0),0)+(t["padding-top"]||0))*r,f=((t["margin-bottom"]||0)+(t["padding-bottom"]||0))*r,l=this.pdf.internal.write,s=void 0,o=void 0,this.y+=d,l("q","BT",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td");u.length;){for(a=u.shift(),c=0,s=0,o=a.length;s!==o;)a[s][0].trim()&&(c=Math.max(c,a[s][1]["line-height"],a[s][1]["font-size"])),s++;
|
||
for(l(0,(-1*e*c).toFixed(2),"Td"),s=0,o=a.length;s!==o;)a[s][0]&&this.RenderTextFragment(a[s][0],a[s][1]),s++;this.y+=c*r}return l("ET","Q"),this.y+=f}},a.prototype.setBlockBoundary=function(){return this.renderParagraph()},a.prototype.setBlockStyle=function(t){return this.paragraph.blockstyle=t},a.prototype.addText=function(t,e){return this.paragraph.text.push(t),this.paragraph.style.push(e)},r={helvetica:"helvetica","sans-serif":"helvetica",serif:"times",times:"times","times new roman":"times",monospace:"courier",courier:"courier"},s={100:"normal",200:"normal",300:"normal",400:"normal",500:"bold",600:"bold",700:"bold",800:"bold",900:"bold",normal:"normal",bold:"bold",bolder:"bold",lighter:"normal"},n={normal:"normal",italic:"italic",oblique:"italic"},l={normal:1},t.fromHTML=function(t,e,r,n,s,o){"use strict";return this.margins_doc=o||{top:0,bottom:0},n||(n={}),n.elementHandlers||(n.elementHandlers={}),p(this,t,e||4,r||4,n,s)}}(r.API),function(t){"use strict";var e,r,n;t.addJS=function(t){return n=t,this.internal.events.subscribe("postPutResources",function(){e=this.internal.newObject(),this.internal.write("<< /Names [(EmbeddedJS) "+(e+1)+" 0 R] >>","endobj"),r=this.internal.newObject(),this.internal.write("<< /S /JavaScript /JS (",n,") >>","endobj")}),this.internal.events.subscribe("putCatalog",function(){void 0!==e&&void 0!==r&&this.internal.write("/Names <</JavaScript "+e+" 0 R>>")}),this}}(r.API),function(t){"use strict";var e=function(){return"function"!=typeof PNG||"function"!=typeof a},r=function(e){return e!==t.image_compression.NONE&&n()},n=function(){var t="function"==typeof o;if(!t)throw new Error("requires deflate.js for compression");return t},s=function(e,r,n,s){var a=5,l=d;switch(s){case t.image_compression.FAST:a=3,l=f;break;case t.image_compression.MEDIUM:a=6,l=h;break;case t.image_compression.SLOW:a=9,l=p}e=c(e,r,n,l);var w=new Uint8Array(i(a)),m=u(e),y=new o(a),v=y.append(e),g=y.flush(),b=w.length+v.length+g.length,q=new Uint8Array(b+4);return q.set(w),q.set(v,w.length),q.set(g,w.length+v.length),q[b++]=m>>>24&255,q[b++]=m>>>16&255,q[b++]=m>>>8&255,q[b++]=255&m,t.arrayBufferToBinaryString(q)},i=function(t,e){var r=8,n=Math.LOG2E*Math.log(32768)-8,s=n<<4|r,o=s<<8,i=Math.min(3,(e-1&255)>>1);return o|=i<<6,o|=0,o+=31-o%31,[s,255&o&255]},u=function(t,e){for(var r,n=1,s=65535&n,o=n>>>16&65535,i=t.length,a=0;i>0;){r=i>e?e:i,i-=r;do s+=t[a++],o+=s;while(--r);s%=65521,o%=65521}return(o<<16|s)>>>0},c=function(t,e,r,n){for(var s,o,i,a=t.length/e,u=new Uint8Array(t.length+a),c=m(),l=0;a>l;l++){if(i=l*e,s=t.subarray(i,i+e),n)u.set(n(s,r,o),i+l);else{for(var f=0,d=c.length,h=[];d>f;f++)h[f]=c[f](s,r,o);var p=y(h.concat());u.set(h[p],i+l)}o=s}return u},l=function(t){var e=Array.apply([],t);return e.unshift(0),e},f=function(t,e){var r,n=[],s=0,o=t.length;for(n[0]=1;o>s;s++)r=t[s-e]||0,n[s+1]=t[s]-r+256&255;return n},d=function(t,e,r){var n,s=[],o=0,i=t.length;for(s[0]=2;i>o;o++)n=r&&r[o]||0,s[o+1]=t[o]-n+256&255;return s},h=function(t,e,r){var n,s,o=[],i=0,a=t.length;for(o[0]=3;a>i;i++)n=t[i-e]||0,s=r&&r[i]||0,o[i+1]=t[i]+256-(n+s>>>1)&255;return o},p=function(t,e,r){var n,s,o,i,a=[],u=0,c=t.length;for(a[0]=4;c>u;u++)n=t[u-e]||0,s=r&&r[u]||0,o=r&&r[u-e]||0,i=w(n,s,o),a[u+1]=t[u]-i+256&255;return a},w=function(t,e,r){var n=t+e-r,s=Math.abs(n-t),o=Math.abs(n-e),i=Math.abs(n-r);return o>=s&&i>=s?t:i>=o?e:r},m=function(){return[l,f,d,h,p]},y=function(t){for(var e,r,n,s=0,o=t.length;o>s;)e=v(t[s].slice(1)),(r>e||!r)&&(r=e,n=s),s++;return n},v=function(t){for(var e=0,r=t.length,n=0;r>e;)n+=Math.abs(t[e++]);return n};t.processPNG=function(t,n,o,i){var a,u,c,l,f,d,h=this.color_spaces.DEVICE_RGB,p=this.decode.FLATE_DECODE,w=8;if(this.isArrayBuffer(t)&&(t=new Uint8Array(t)),this.isArrayBufferView(t)){if(e())throw new Error("PNG support requires png.js and zlib.js");if(a=new PNG(t),t=a.imgData,w=a.bits,h=a.colorSpace,l=a.colors,-1!==[4,6].indexOf(a.colorType)){if(8===a.bits)for(var m,y,v=window["Uint"+a.pixelBitlength+"Array"],g=new v(a.decodePixels().buffer),b=g.length,q=new Uint8Array(b*a.colors),x=new Uint8Array(b),k=a.pixelBitlength-a.bits,_=0,A=0;b>_;_++){for(m=g[_],y=0;k>y;)q[A++]=m>>>y&255,y+=a.bits;x[_]=m>>>y&255}if(16===a.bits){for(var m,g=new Uint32Array(a.decodePixels().buffer),b=g.length,q=new Uint8Array(b*(32/a.pixelBitlength)*a.colors),x=new Uint8Array(b*(32/a.pixelBitlength)),C=a.colors>1,_=0,A=0,S=0;b>_;)m=g[_++],q[A++]=m>>>0&255,C&&(q[A++]=m>>>16&255,m=g[_++],q[A++]=m>>>0&255),x[S++]=m>>>16&255;w=8}r(i)?(t=s(q,a.width*a.colors,a.colors,i),d=s(x,a.width,1,i)):(t=q,d=x,p=null)}if(3===a.colorType&&(h=this.color_spaces.INDEXED,f=a.palette,a.transparency.indexed)){for(var E=a.transparency.indexed,z=0,_=0,b=E.length;b>_;++_)z+=E[_];if(z/=255,z===b-1&&-1!==E.indexOf(0))c=[E.indexOf(0)];else if(z!==b){for(var g=a.decodePixels(),x=new Uint8Array(g.length),_=0,b=g.length;b>_;_++)x[_]=E[g[_]];d=s(x,a.width,1)}}return u=p===this.decode.FLATE_DECODE?"/Predictor 15 /Colors "+l+" /BitsPerComponent "+w+" /Columns "+a.width:"/Colors "+l+" /BitsPerComponent "+w+" /Columns "+a.width,(this.isArrayBuffer(t)||this.isArrayBufferView(t))&&(t=this.arrayBufferToBinaryString(t)),(d&&this.isArrayBuffer(d)||this.isArrayBufferView(d))&&(d=this.arrayBufferToBinaryString(d)),this.createImageInfo(t,a.width,a.height,h,w,p,n,o,u,c,f,d)}throw new Error("Unsupported PNG image data, try using JPEG instead.")}}(r.API),function(t){"use strict";t.addSVG=function(t,e,r,n,s){function o(t,e){var r=e.createElement("style");r.type="text/css",r.styleSheet?r.styleSheet.cssText=t:r.appendChild(e.createTextNode(t)),e.getElementsByTagName("head")[0].appendChild(r)}function i(t){var e="childframe",r=t.createElement("iframe");return o(".jsPDF_sillysvg_iframe {display:none;position:absolute;}",t),r.name=e,r.setAttribute("width",0),r.setAttribute("height",0),r.setAttribute("frameborder","0"),r.setAttribute("scrolling","no"),r.setAttribute("seamless","seamless"),r.setAttribute("class","jsPDF_sillysvg_iframe"),t.body.appendChild(r),r}function a(t,e){var r=(e.contentWindow||e.contentDocument).document;return r.write(t),r.close(),r.getElementsByTagName("svg")[0]}function u(t){for(var e=parseFloat(t[1]),r=parseFloat(t[2]),n=[],s=3,o=t.length;o>s;)"c"===t[s]?(n.push([parseFloat(t[s+1]),parseFloat(t[s+2]),parseFloat(t[s+3]),parseFloat(t[s+4]),parseFloat(t[s+5]),parseFloat(t[s+6])]),s+=7):"l"===t[s]?(n.push([parseFloat(t[s+1]),parseFloat(t[s+2])]),s+=3):s+=1;return[e,r,n]}var c;if(e===c||e===c)throw new Error("addSVG needs values for 'x' and 'y'");var l=i(document),f=a(t,l),d=[1,1],h=parseFloat(f.getAttribute("width")),p=parseFloat(f.getAttribute("height"));h&&p&&(n&&s?d=[n/h,s/p]:n?d=[n/h,n/h]:s&&(d=[s/p,s/p]));var w,m,y,v,g=f.childNodes;for(w=0,m=g.length;m>w;w++)y=g[w],y.tagName&&"PATH"===y.tagName.toUpperCase()&&(v=u(y.getAttribute("d").split(" ")),v[0]=v[0]*d[0]+e,v[1]=v[1]*d[1]+r,this.lines.call(this,v[2],v[0],v[1],d));return this}}(r.API),function(t){"use strict";var e=t.getCharWidthsArray=function(t,e){e||(e={});var r,n,s,o=e.widths?e.widths:this.internal.getFont().metadata.Unicode.widths,i=o.fof?o.fof:1,a=e.kerning?e.kerning:this.internal.getFont().metadata.Unicode.kerning,u=a.fof?a.fof:1,c=0,l=o[0]||i,f=[];for(r=0,n=t.length;n>r;r++)s=t.charCodeAt(r),f.push((o[s]||l)/i+(a[s]&&a[s][c]||0)/u),c=s;return f},r=function(t){for(var e=t.length,r=0;e;)e--,r+=t[e];return r},n=t.getStringUnitWidth=function(t,n){return r(e.call(this,t,n))},s=function(t,e,r,n){for(var s=[],o=0,i=t.length,a=0;o!==i&&a+e[o]<r;)a+=e[o],o++;s.push(t.slice(0,o));var u=o;for(a=0;o!==i;)a+e[o]>n&&(s.push(t.slice(u,o)),a=0,u=o),a+=e[o],o++;return u!==o&&s.push(t.slice(u,o)),s},o=function(t,o,i){i||(i={});var a,u,c,l,f,d,h=[],p=[h],w=i.textIndent||0,m=0,y=0,v=t.split(" "),g=e(" ",i)[0];if(d=-1===i.lineIndent?v[0].length+2:i.lineIndent||0){var b=Array(d).join(" "),q=[];v.map(function(t){t=t.split(/\s*\n/),t.length>1?q=q.concat(t.map(function(t,e){return(e&&t.length?"\n":"")+t})):q.push(t[0])}),v=q,d=n(b,i)}for(c=0,l=v.length;l>c;c++){var x=0;if(a=v[c],d&&"\n"==a[0]&&(a=a.substr(1),x=1),u=e(a,i),y=r(u),w+m+y>o||x){if(y>o){for(f=s(a,u,o-(w+m),o),h.push(f.shift()),h=[f.pop()];f.length;)p.push([f.shift()]);y=r(u.slice(a.length-h[0].length))}else h=[a];p.push(h),w=y+d,m=g}else h.push(a),w+=m+y,m=g}if(d)var k=function(t,e){return(e?b:"")+t.join(" ")};else var k=function(t){return t.join(" ")};return p.map(k)};t.splitTextToSize=function(t,e,r){r||(r={});var n,s=r.fontSize||this.internal.getFontSize(),i=function(t){var e={0:1},r={};if(t.widths&&t.kerning)return{widths:t.widths,kerning:t.kerning};var n=this.internal.getFont(t.fontName,t.fontStyle),s="Unicode";return n.metadata[s]?{widths:n.metadata[s].widths||e,kerning:n.metadata[s].kerning||r}:{widths:e,kerning:r}}.call(this,r);n=Array.isArray(t)?t:t.split(/\r?\n/);var a=1*this.internal.scaleFactor*e/s;i.textIndent=r.textIndent?1*r.textIndent*this.internal.scaleFactor/s:0,i.lineIndent=r.lineIndent;var u,c,l=[];for(u=0,c=n.length;c>u;u++)l=l.concat(o(n[u],a,i));return l}}(r.API),function(t){"use strict";var e=function(t){for(var e="0123456789abcdef",r="klmnopqrstuvwxyz",n={},s=0;s<r.length;s++)n[r[s]]=e[s];var o,i,a,u,c,l={},f=1,d=l,h=[],p="",w="",m=t.length-1;for(s=1;s!=m;)c=t[s],s+=1,"'"==c?i?(u=i.join(""),i=o):i=[]:i?i.push(c):"{"==c?(h.push([d,u]),d={},u=o):"}"==c?(a=h.pop(),a[0][a[1]]=d,u=o,d=a[0]):"-"==c?f=-1:u===o?n.hasOwnProperty(c)?(p+=n[c],u=parseInt(p,16)*f,f=1,p=""):p+=c:n.hasOwnProperty(c)?(w+=n[c],d[u]=parseInt(w,16)*f,f=1,u=o,w=""):w+=c;return l},r={codePages:["WinAnsiEncoding"],WinAnsiEncoding:e("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")},n={Unicode:{Courier:r,"Courier-Bold":r,"Courier-BoldOblique":r,"Courier-Oblique":r,Helvetica:r,"Helvetica-Bold":r,"Helvetica-BoldOblique":r,"Helvetica-Oblique":r,"Times-Roman":r,"Times-Bold":r,"Times-BoldItalic":r,"Times-Italic":r}},s={Unicode:{"Courier-Oblique":e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-BoldItalic":e("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),"Helvetica-Bold":e("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),Courier:e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-BoldOblique":e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Bold":e("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),Helvetica:e("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),"Helvetica-BoldOblique":e("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),"Courier-Bold":e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Italic":e("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"),"Times-Roman":e("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),"Helvetica-Oblique":e("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")}};t.events.push(["addFonts",function(t){var e,r,o,i,a,u="Unicode";for(r in t.fonts)t.fonts.hasOwnProperty(r)&&(e=t.fonts[r],o=s[u][e.PostScriptName],o&&(i=e.metadata[u]?e.metadata[u]:e.metadata[u]={},i.widths=o.widths,i.kerning=o.kerning),a=n[u][e.PostScriptName],a&&(i=e.metadata[u]?e.metadata[u]:e.metadata[u]={},i.encoding=a,a.codePages&&a.codePages.length&&(e.encoding=a.codePages[0])))}])}(r.API),function(t){"use strict";t.putTotalPages=function(t){for(var e=new RegExp(t,"g"),r=1;r<=this.internal.getNumberOfPages();r++)for(var n=0;n<this.internal.pages[r].length;n++)this.internal.pages[r][n]=this.internal.pages[r][n].replace(e,this.internal.getNumberOfPages());return this}}(r.API),"function"!=typeof n&&"object"!=typeof n||"undefined"==typeof URL)if("function"!=typeof n&&"object"!=typeof n||"undefined"==typeof webkitURL)var n=function(t){"use strict";var e=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||t.MSBlobBuilder||function(t){var e=function(t){return Object.prototype.toString.call(t).match(/^\[object\s(.*)\]$/)[1]},r=function(){this.data=[]},n=function(t,e,r){this.data=t,this.size=t.length,this.type=e,this.encoding=r},s=r.prototype,o=n.prototype,i=t.FileReaderSync,a=function(t){this.code=this[this.name=t]},u="NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR".split(" "),c=u.length,l=t.URL||t.webkitURL||t,f=l.createObjectURL,d=l.revokeObjectURL,h=l,p=t.btoa,w=t.atob,m=t.ArrayBuffer,y=t.Uint8Array;for(n.fake=o.fake=!0;c--;)a.prototype[u[c]]=c+1;return l.createObjectURL||(h=t.URL={}),h.createObjectURL=function(t){var e,r=t.type;return null===r&&(r="application/octet-stream"),t instanceof n?(e="data:"+r,"base64"===t.encoding?e+";base64,"+t.data:"URI"===t.encoding?e+","+decodeURIComponent(t.data):p?e+";base64,"+p(t.data):e+","+encodeURIComponent(t.data)):f?f.call(l,t):void 0},h.revokeObjectURL=function(t){"data:"!==t.substring(0,5)&&d&&d.call(l,t)},s.append=function(t){var r=this.data;if(y&&(t instanceof m||t instanceof y)){for(var s="",o=new y(t),u=0,c=o.length;c>u;u++)s+=String.fromCharCode(o[u]);r.push(s)}else if("Blob"===e(t)||"File"===e(t)){if(!i)throw new a("NOT_READABLE_ERR");var l=new i;r.push(l.readAsBinaryString(t))}else t instanceof n?"base64"===t.encoding&&w?r.push(w(t.data)):"URI"===t.encoding?r.push(decodeURIComponent(t.data)):"raw"===t.encoding&&r.push(t.data):("string"!=typeof t&&(t+=""),r.push(unescape(encodeURIComponent(t))))},s.getBlob=function(t){return arguments.length||(t=null),new n(this.data.join(""),t,"raw")},s.toString=function(){return"[object BlobBuilder]"},o.slice=function(t,e,r){var s=arguments.length;return 3>s&&(r=null),new n(this.data.slice(t,s>1?e:this.data.length),r,this.encoding)},o.toString=function(){return"[object Blob]"},r}(t);return function(t,r){var n=r?r.type||"":"",s=new e;if(t)for(var o=0,i=t.length;i>o;o++)s.append(t[o]);return s.getBlob(n)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content||this);else self.URL=webkitURL;var s=s||"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob&&navigator.msSaveOrOpenBlob.bind(navigator)||function(t){"use strict";if("undefined"==typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var e=t.document,r=function(){return t.URL||t.webkitURL||t},n=t.URL||t.webkitURL||t,s=e.createElementNS("http://www.w3.org/1999/xhtml","a"),o=!t.externalHost&&"download"in s,i=t.webkitRequestFileSystem,a=t.requestFileSystem||i||t.mozRequestFileSystem,u=function(e){(t.setImmediate||t.setTimeout)(function(){throw e},0)},c="application/octet-stream",l=0,f=[],d=function(){for(var t=f.length;t--;){var e=f[t];"string"==typeof e?n.revokeObjectURL(e):e.remove()}f.length=0},h=function(t,e,r){e=[].concat(e);for(var n=e.length;n--;){var s=t["on"+e[n]];if("function"==typeof s)try{s.call(t,r||t)}catch(o){u(o)}}},p=function(n,u){var d,p,w,m=this,y=n.type,v=!1,g=function(){var t=r().createObjectURL(n);return f.push(t),t},b=function(){h(m,"writestart progress write writeend".split(" "))},q=function(){(v||!d)&&(d=g(n)),p?p.location.href=d:window.open(d,"_blank"),m.readyState=m.DONE,b()},x=function(t){return function(){return m.readyState!==m.DONE?t.apply(this,arguments):void 0}},k={create:!0,exclusive:!1};if(m.readyState=m.INIT,u||(u="download"),o){d=g(n),e=t.document,s=e.createElementNS("http://www.w3.org/1999/xhtml","a"),s.href=d,s.download=u;var _=e.createEvent("MouseEvents");return _.initMouseEvent("click",!0,!1,t,0,0,0,0,0,!1,!1,!1,!1,0,null),s.dispatchEvent(_),m.readyState=m.DONE,b(),void 0}return t.chrome&&y&&y!==c&&(w=n.slice||n.webkitSlice,n=w.call(n,0,n.size,c),v=!0),i&&"download"!==u&&(u+=".download"),(y===c||i)&&(p=t),a?(l+=n.size,a(t.TEMPORARY,l,x(function(t){t.root.getDirectory("saved",k,x(function(t){var e=function(){t.getFile(u,k,x(function(t){t.createWriter(x(function(e){e.onwriteend=function(e){p.location.href=t.toURL(),f.push(t),m.readyState=m.DONE,h(m,"writeend",e)},e.onerror=function(){var t=e.error;t.code!==t.ABORT_ERR&&q()},"writestart progress write abort".split(" ").forEach(function(t){e["on"+t]=m["on"+t]}),e.write(n),m.abort=function(){e.abort(),m.readyState=m.DONE},m.readyState=m.WRITING}),q)}),q)};t.getFile(u,{create:!1},x(function(t){t.remove(),e()}),x(function(t){t.code===t.NOT_FOUND_ERR?e():q()}))}),q)}),q),void 0):(q(),void 0)},w=p.prototype,m=function(t,e){return new p(t,e)};return w.abort=function(){var t=this;t.readyState=t.DONE,h(t,"abort")},w.readyState=w.INIT=0,w.WRITING=1,w.DONE=2,w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null,t.addEventListener("unload",d,!1),m.unload=function(){d(),t.removeEventListener("unload",d,!1)},m}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&null!==module?module.exports=s:"undefined"!=typeof define&&null!==define&&null!=define.amd&&define([],function(){return s}),void function(t,e){"object"==typeof module?module.exports=e():t.adler32cs=e()}(r,function(){var t="function"==typeof ArrayBuffer&&"function"==typeof Uint8Array,e=null,r=function(){if(!t)return function(){return!1};try{var r=require("buffer");"function"==typeof r.Buffer&&(e=r.Buffer)}catch(n){}return function(t){return t instanceof ArrayBuffer||null!==e&&t instanceof e}}(),n=function(){return null!==e?function(t){return new e(t,"utf8").toString("binary")}:function(t){return unescape(encodeURIComponent(t))}}(),s=65521,o=function(t,e){for(var r=65535&t,n=t>>>16,o=0,i=e.length;i>o;o++)r=(r+(255&e.charCodeAt(o)))%s,n=(n+r)%s;return(n<<16|r)>>>0},i=function(t,e){for(var r=65535&t,n=t>>>16,o=0,i=e.length;i>o;o++)r=(r+e[o])%s,n=(n+r)%s;return(n<<16|r)>>>0},a={},u=a.Adler32=function(){var e=function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(!isFinite(t=null==t?1:+t))throw new Error("First arguments needs to be a finite number.");this.checksum=t>>>0},s=e.prototype={};return s.constructor=e,e.from=function(t){return t.prototype=s,t}(function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(null==t)throw new Error("First argument needs to be a string.");this.checksum=o(1,t.toString())}),e.fromUtf8=function(t){return t.prototype=s,t}(function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(null==t)throw new Error("First argument needs to be a string.");var r=n(t.toString());this.checksum=o(1,r)}),t&&(e.fromBuffer=function(t){return t.prototype=s,t}(function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(!r(t))throw new Error("First argument needs to be ArrayBuffer.");
|
||
var n=new Uint8Array(t);return this.checksum=i(1,n)})),s.update=function(t){if(null==t)throw new Error("First argument needs to be a string.");return t=t.toString(),this.checksum=o(this.checksum,t)},s.updateUtf8=function(t){if(null==t)throw new Error("First argument needs to be a string.");var e=n(t.toString());return this.checksum=o(this.checksum,e)},t&&(s.updateBuffer=function(t){if(!r(t))throw new Error("First argument needs to be ArrayBuffer.");var e=new Uint8Array(t);return this.checksum=i(this.checksum,e)}),s.clone=function(){return new u(this.checksum)},e}();return a.from=function(t){if(null==t)throw new Error("First argument needs to be a string.");return o(1,t.toString())},a.fromUtf8=function(t){if(null==t)throw new Error("First argument needs to be a string.");var e=n(t.toString());return o(1,e)},t&&(a.fromBuffer=function(t){if(!r(t))throw new Error("First argument need to be ArrayBuffer.");var e=new Uint8Array(t);return i(1,e)}),a});var o=function(){function t(){function t(t){var e,r,s,o,a,u,c=n.dyn_tree,l=n.stat_desc.static_tree,f=n.stat_desc.extra_bits,h=n.stat_desc.extra_base,p=n.stat_desc.max_length,w=0;for(o=0;i>=o;o++)t.bl_count[o]=0;for(c[2*t.heap[t.heap_max]+1]=0,e=t.heap_max+1;d>e;e++)r=t.heap[e],o=c[2*c[2*r+1]+1]+1,o>p&&(o=p,w++),c[2*r+1]=o,r>n.max_code||(t.bl_count[o]++,a=0,r>=h&&(a=f[r-h]),u=c[2*r],t.opt_len+=u*(o+a),l&&(t.static_len+=u*(l[2*r+1]+a)));if(0!==w){do{for(o=p-1;0===t.bl_count[o];)o--;t.bl_count[o]--,t.bl_count[o+1]+=2,t.bl_count[p]--,w-=2}while(w>0);for(o=p;0!==o;o--)for(r=t.bl_count[o];0!==r;)s=t.heap[--e],s>n.max_code||(c[2*s+1]!=o&&(t.opt_len+=(o-c[2*s+1])*c[2*s],c[2*s+1]=o),r--)}}function e(t,e){var r=0;do r|=1&t,t>>>=1,r<<=1;while(--e>0);return r>>>1}function r(t,r,n){var s,o,a,u=[],c=0;for(s=1;i>=s;s++)u[s]=c=c+n[s-1]<<1;for(o=0;r>=o;o++)a=t[2*o+1],0!==a&&(t[2*o]=e(u[a]++,a))}var n=this;n.build_tree=function(e){var s,o,i,a=n.dyn_tree,u=n.stat_desc.static_tree,c=n.stat_desc.elems,l=-1;for(e.heap_len=0,e.heap_max=d,s=0;c>s;s++)0!==a[2*s]?(e.heap[++e.heap_len]=l=s,e.depth[s]=0):a[2*s+1]=0;for(;e.heap_len<2;)i=e.heap[++e.heap_len]=2>l?++l:0,a[2*i]=1,e.depth[i]=0,e.opt_len--,u&&(e.static_len-=u[2*i+1]);for(n.max_code=l,s=Math.floor(e.heap_len/2);s>=1;s--)e.pqdownheap(a,s);i=c;do s=e.heap[1],e.heap[1]=e.heap[e.heap_len--],e.pqdownheap(a,1),o=e.heap[1],e.heap[--e.heap_max]=s,e.heap[--e.heap_max]=o,a[2*i]=a[2*s]+a[2*o],e.depth[i]=Math.max(e.depth[s],e.depth[o])+1,a[2*s+1]=a[2*o+1]=i,e.heap[1]=i++,e.pqdownheap(a,1);while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],t(e),r(a,n.max_code,e.bl_count)}}function e(t,e,r,n,s){var o=this;o.static_tree=t,o.extra_bits=e,o.extra_base=r,o.elems=n,o.max_length=s}function r(t,e,r,n,s){var o=this;o.good_length=t,o.max_lazy=e,o.nice_length=r,o.max_chain=n,o.func=s}function n(t,e,r,n){var s=t[2*e],o=t[2*r];return o>s||s==o&&n[e]<=n[r]}function s(){function r(){var t;for(Be=2*Ce,Te[Oe-1]=0,t=0;Oe-1>t;t++)Te[t]=0;Ve=j[Xe].max_lazy,Ke=j[Xe].good_length,Qe=j[Xe].nice_length,We=j[Xe].max_chain,Me=0,Fe=0,Ge=0,je=Je=Z-1,Ne=0,Pe=0}function s(){var t;for(t=0;f>t;t++)$e[2*t]=0;for(t=0;a>t;t++)Ze[2*t]=0;for(t=0;u>t;t++)tr[2*t]=0;$e[2*h]=1,er.opt_len=er.static_len=0,ar=cr=0}function o(){rr.dyn_tree=$e,rr.stat_desc=e.static_l_desc,nr.dyn_tree=Ze,nr.stat_desc=e.static_d_desc,sr.dyn_tree=tr,sr.stat_desc=e.static_bl_desc,fr=0,dr=0,lr=8,s()}function i(t,e){var r,n,s=-1,o=t[1],i=0,a=7,u=4;for(0===o&&(a=138,u=3),t[2*(e+1)+1]=65535,r=0;e>=r;r++)n=o,o=t[2*(r+1)+1],++i<a&&n==o||(u>i?tr[2*n]+=i:0!==n?(n!=s&&tr[2*n]++,tr[2*w]++):10>=i?tr[2*m]++:tr[2*y]++,i=0,s=n,0===o?(a=138,u=3):n==o?(a=6,u=3):(a=7,u=4))}function c(){var e;for(i($e,rr.max_code),i(Ze,nr.max_code),sr.build_tree(er),e=u-1;e>=3&&0===tr[2*t.bl_order[e]+1];e--);return er.opt_len+=3*(e+1)+5+5+4,e}function d(t){er.pending_buf[er.pending++]=t}function p(t){d(255&t),d(t>>>8&255)}function P(t){d(t>>8&255),d(255&t&255)}function re(t,e){var r,n=e;dr>v-n?(r=t,fr|=r<<dr&65535,p(fr),fr=r>>>v-dr,dr+=n-v):(fr|=t<<dr&65535,dr+=n)}function ne(t,e){var r=2*t;re(65535&e[r],65535&e[r+1])}function se(t,e){var r,n,s=-1,o=t[1],i=0,a=7,u=4;for(0===o&&(a=138,u=3),r=0;e>=r;r++)if(n=o,o=t[2*(r+1)+1],!(++i<a&&n==o)){if(u>i){do ne(n,tr);while(0!==--i)}else 0!==n?(n!=s&&(ne(n,tr),i--),ne(w,tr),re(i-3,2)):10>=i?(ne(m,tr),re(i-3,3)):(ne(y,tr),re(i-11,7));i=0,s=n,0===o?(a=138,u=3):n==o?(a=6,u=3):(a=7,u=4)}}function oe(e,r,n){var s;for(re(e-257,5),re(r-1,5),re(n-4,4),s=0;n>s;s++)re(tr[2*t.bl_order[s]+1],3);se($e,e-1),se(Ze,r-1)}function ie(){16==dr?(p(fr),fr=0,dr=0):dr>=8&&(d(255&fr),fr>>>=8,dr-=8)}function ae(){re(Q<<1,3),ne(h,e.static_ltree),ie(),9>1+lr+10-dr&&(re(Q<<1,3),ne(h,e.static_ltree),ie()),lr=7}function ue(e,r){var n,s,o;if(er.pending_buf[ur+2*ar]=e>>>8&255,er.pending_buf[ur+2*ar+1]=255&e,er.pending_buf[or+ar]=255&r,ar++,0===e?$e[2*r]++:(cr++,e--,$e[2*(t._length_code[r]+l+1)]++,Ze[2*t.d_code(e)]++),0===(8191&ar)&&Xe>2){for(n=8*ar,s=Me-Fe,o=0;a>o;o++)n+=Ze[2*o]*(5+t.extra_dbits[o]);if(n>>>=3,cr<Math.floor(ar/2)&&n<Math.floor(s/2))return!0}return ar==ir-1}function ce(e,r){var n,s,o,i,a=0;if(0!==ar)do n=er.pending_buf[ur+2*a]<<8&65280|255&er.pending_buf[ur+2*a+1],s=255&er.pending_buf[or+a],a++,0===n?ne(s,e):(o=t._length_code[s],ne(o+l+1,e),i=t.extra_lbits[o],0!==i&&(s-=t.base_length[o],re(s,i)),n--,o=t.d_code(n),ne(o,r),i=t.extra_dbits[o],0!==i&&(n-=t.base_dist[o],re(n,i)));while(ar>a);ne(h,e),lr=e[2*h+1]}function le(){dr>8?p(fr):dr>0&&d(255&fr),fr=0,dr=0}function fe(t,e,r){le(),lr=8,r&&(p(e),p(~e)),er.pending_buf.set(ze.subarray(t,t+e),er.pending),er.pending+=e}function de(t,e,r){re((K<<1)+(r?1:0),3),fe(t,e,!0)}function he(t,r,n){var o,i,a=0;Xe>0?(rr.build_tree(er),nr.build_tree(er),a=c(),o=er.opt_len+3+7>>>3,i=er.static_len+3+7>>>3,o>=i&&(o=i)):o=i=r+5,o>=r+4&&-1!=t?de(t,r,n):i==o?(re((Q<<1)+(n?1:0),3),ce(e.static_ltree,e.static_dtree)):(re(($<<1)+(n?1:0),3),oe(rr.max_code+1,nr.max_code+1,a+1),ce($e,Ze)),s(),n&&le()}function pe(t){he(Fe>=0?Fe:-1,Me-Fe,t),Fe=Me,qe.flush_pending()}function we(){var t,e,r,n;do{if(n=Be-Ge-Me,0===n&&0===Me&&0===Ge)n=Ce;else if(-1==n)n--;else if(Me>=Ce+Ce-ee){ze.set(ze.subarray(Ce,Ce+Ce),0),He-=Ce,Me-=Ce,Fe-=Ce,t=Oe,r=t;do e=65535&Te[--r],Te[r]=e>=Ce?e-Ce:0;while(0!==--t);t=Ce,r=t;do e=65535&Ie[--r],Ie[r]=e>=Ce?e-Ce:0;while(0!==--t);n+=Ce}if(0===qe.avail_in)return;t=qe.read_buf(ze,Me+Ge,n),Ge+=t,Ge>=Z&&(Pe=255&ze[Me],Pe=(Pe<<Ue^255&ze[Me+1])&De)}while(ee>Ge&&0!==qe.avail_in)}function me(t){var e,r=65535;for(r>ke-5&&(r=ke-5);;){if(1>=Ge){if(we(),0===Ge&&t==k)return N;if(0===Ge)break}if(Me+=Ge,Ge=0,e=Fe+r,(0===Me||Me>=e)&&(Ge=Me-e,Me=e,pe(!1),0===qe.avail_out))return N;if(Me-Fe>=Ce-ee&&(pe(!1),0===qe.avail_out))return N}return pe(t==C),0===qe.avail_out?t==C?H:N:t==C?G:M}function ye(t){var e,r,n=We,s=Me,o=Je,i=Me>Ce-ee?Me-(Ce-ee):0,a=Qe,u=Ee,c=Me+te,l=ze[s+o-1],f=ze[s+o];Je>=Ke&&(n>>=2),a>Ge&&(a=Ge);do if(e=t,ze[e+o]==f&&ze[e+o-1]==l&&ze[e]==ze[s]&&ze[++e]==ze[s+1]){s+=2,e++;do;while(ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&c>s);if(r=te-(c-s),s=c-te,r>o){if(He=t,o=r,r>=a)break;l=ze[s+o-1],f=ze[s+o]}}while((t=65535&Ie[t&u])>i&&0!==--n);return Ge>=o?o:Ge}function ve(t){for(var e,r=0;;){if(ee>Ge){if(we(),ee>Ge&&t==k)return N;if(0===Ge)break}if(Ge>=Z&&(Pe=(Pe<<Ue^255&ze[Me+(Z-1)])&De,r=65535&Te[Pe],Ie[Me&Ee]=Te[Pe],Te[Pe]=Me),0!==r&&Ce-ee>=(Me-r&65535)&&Ye!=q&&(je=ye(r)),je>=Z)if(e=ue(Me-He,je-Z),Ge-=je,Ve>=je&&Ge>=Z){je--;do Me++,Pe=(Pe<<Ue^255&ze[Me+(Z-1)])&De,r=65535&Te[Pe],Ie[Me&Ee]=Te[Pe],Te[Pe]=Me;while(0!==--je);Me++}else Me+=je,je=0,Pe=255&ze[Me],Pe=(Pe<<Ue^255&ze[Me+1])&De;else e=ue(0,255&ze[Me]),Ge--,Me++;if(e&&(pe(!1),0===qe.avail_out))return N}return pe(t==C),0===qe.avail_out?t==C?H:N:t==C?G:M}function ge(t){for(var e,r,n=0;;){if(ee>Ge){if(we(),ee>Ge&&t==k)return N;if(0===Ge)break}if(Ge>=Z&&(Pe=(Pe<<Ue^255&ze[Me+(Z-1)])&De,n=65535&Te[Pe],Ie[Me&Ee]=Te[Pe],Te[Pe]=Me),Je=je,Le=He,je=Z-1,0!==n&&Ve>Je&&Ce-ee>=(Me-n&65535)&&(Ye!=q&&(je=ye(n)),5>=je&&(Ye==b||je==Z&&Me-He>4096)&&(je=Z-1)),Je>=Z&&Je>=je){r=Me+Ge-Z,e=ue(Me-1-Le,Je-Z),Ge-=Je-1,Je-=2;do++Me<=r&&(Pe=(Pe<<Ue^255&ze[Me+(Z-1)])&De,n=65535&Te[Pe],Ie[Me&Ee]=Te[Pe],Te[Pe]=Me);while(0!==--Je);if(Ne=0,je=Z-1,Me++,e&&(pe(!1),0===qe.avail_out))return N}else if(0!==Ne){if(e=ue(0,255&ze[Me-1]),e&&pe(!1),Me++,Ge--,0===qe.avail_out)return N}else Ne=1,Me++,Ge--}return 0!==Ne&&(e=ue(0,255&ze[Me-1]),Ne=0),pe(t==C),0===qe.avail_out?t==C?H:N:t==C?G:M}function be(t){return t.total_in=t.total_out=0,t.msg=null,er.pending=0,er.pending_out=0,xe=V,Ae=k,o(),r(),S}var qe,xe,ke,_e,Ae,Ce,Se,Ee,ze,Be,Ie,Te,Pe,Oe,Re,De,Ue,Fe,je,Le,Ne,Me,He,Ge,Je,We,Ve,Xe,Ye,Ke,Qe,$e,Ze,tr,er=this,rr=new t,nr=new t,sr=new t;er.depth=[];var or,ir,ar,ur,cr,lr,fr,dr;er.bl_count=[],er.heap=[],$e=[],Ze=[],tr=[],er.pqdownheap=function(t,e){for(var r=er.heap,s=r[e],o=e<<1;o<=er.heap_len&&(o<er.heap_len&&n(t,r[o+1],r[o],er.depth)&&o++,!n(t,s,r[o],er.depth));)r[e]=r[o],e=o,o<<=1;r[e]=s},er.deflateInit=function(t,e,r,n,s,o){return n||(n=Y),s||(s=R),o||(o=x),t.msg=null,e==g&&(e=6),1>s||s>O||n!=Y||9>r||r>15||0>e||e>9||0>o||o>q?B:(t.dstate=er,Se=r,Ce=1<<Se,Ee=Ce-1,Re=s+7,Oe=1<<Re,De=Oe-1,Ue=Math.floor((Re+Z-1)/Z),ze=new Uint8Array(2*Ce),Ie=[],Te=[],ir=1<<s+6,er.pending_buf=new Uint8Array(4*ir),ke=4*ir,ur=Math.floor(ir/2),or=3*ir,Xe=e,Ye=o,_e=255&n,be(t))},er.deflateEnd=function(){return xe!=W&&xe!=V&&xe!=X?B:(er.pending_buf=null,Te=null,Ie=null,ze=null,er.dstate=null,xe==V?I:S)},er.deflateParams=function(t,e,r){var n=S;return e==g&&(e=6),0>e||e>9||0>r||r>q?B:(j[Xe].func!=j[e].func&&0!==t.total_in&&(n=t.deflate(_)),Xe!=e&&(Xe=e,Ve=j[Xe].max_lazy,Ke=j[Xe].good_length,Qe=j[Xe].nice_length,We=j[Xe].max_chain),Ye=r,n)},er.deflateSetDictionary=function(t,e,r){var n,s=r,o=0;if(!e||xe!=W)return B;if(Z>s)return S;for(s>Ce-ee&&(s=Ce-ee,o=r-s),ze.set(e.subarray(o,o+s),0),Me=s,Fe=s,Pe=255&ze[0],Pe=(Pe<<Ue^255&ze[1])&De,n=0;s-Z>=n;n++)Pe=(Pe<<Ue^255&ze[n+(Z-1)])&De,Ie[n&Ee]=Te[Pe],Te[Pe]=n;return S},er.deflate=function(t,e){var r,n,s,o,i;if(e>C||0>e)return B;if(!t.next_out||!t.next_in&&0!==t.avail_in||xe==X&&e!=C)return t.msg=L[z-B],B;if(0===t.avail_out)return t.msg=L[z-T],T;if(qe=t,o=Ae,Ae=e,xe==W&&(n=Y+(Se-8<<4)<<8,s=(Xe-1&255)>>1,s>3&&(s=3),n|=s<<6,0!==Me&&(n|=J),n+=31-n%31,xe=V,P(n)),0!==er.pending){if(qe.flush_pending(),0===qe.avail_out)return Ae=-1,S}else if(0===qe.avail_in&&o>=e&&e!=C)return qe.msg=L[z-T],T;if(xe==X&&0!==qe.avail_in)return t.msg=L[z-T],T;if(0!==qe.avail_in||0!==Ge||e!=k&&xe!=X){switch(i=-1,j[Xe].func){case D:i=me(e);break;case U:i=ve(e);break;case F:i=ge(e)}if((i==H||i==G)&&(xe=X),i==N||i==H)return 0===qe.avail_out&&(Ae=-1),S;if(i==M){if(e==_)ae();else if(de(0,0,!1),e==A)for(r=0;Oe>r;r++)Te[r]=0;if(qe.flush_pending(),0===qe.avail_out)return Ae=-1,S}}return e!=C?S:E}}function o(){var t=this;t.next_in_index=0,t.next_out_index=0,t.avail_in=0,t.total_in=0,t.avail_out=0,t.total_out=0}var i=15,a=30,u=19,c=29,l=256,f=l+1+c,d=2*f+1,h=256,p=7,w=16,m=17,y=18,v=16,g=-1,b=1,q=2,x=0,k=0,_=1,A=3,C=4,S=0,E=1,z=2,B=-2,I=-3,T=-5,P=[0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,16,17,18,18,19,19,20,20,20,20,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29];t._length_code=[0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28],t.base_length=[0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0],t.base_dist=[0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576],t.d_code=function(t){return 256>t?P[t]:P[256+(t>>>7)]},t.extra_lbits=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],t.extra_dbits=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],t.extra_blbits=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],t.bl_order=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],e.static_ltree=[12,8,140,8,76,8,204,8,44,8,172,8,108,8,236,8,28,8,156,8,92,8,220,8,60,8,188,8,124,8,252,8,2,8,130,8,66,8,194,8,34,8,162,8,98,8,226,8,18,8,146,8,82,8,210,8,50,8,178,8,114,8,242,8,10,8,138,8,74,8,202,8,42,8,170,8,106,8,234,8,26,8,154,8,90,8,218,8,58,8,186,8,122,8,250,8,6,8,134,8,70,8,198,8,38,8,166,8,102,8,230,8,22,8,150,8,86,8,214,8,54,8,182,8,118,8,246,8,14,8,142,8,78,8,206,8,46,8,174,8,110,8,238,8,30,8,158,8,94,8,222,8,62,8,190,8,126,8,254,8,1,8,129,8,65,8,193,8,33,8,161,8,97,8,225,8,17,8,145,8,81,8,209,8,49,8,177,8,113,8,241,8,9,8,137,8,73,8,201,8,41,8,169,8,105,8,233,8,25,8,153,8,89,8,217,8,57,8,185,8,121,8,249,8,5,8,133,8,69,8,197,8,37,8,165,8,101,8,229,8,21,8,149,8,85,8,213,8,53,8,181,8,117,8,245,8,13,8,141,8,77,8,205,8,45,8,173,8,109,8,237,8,29,8,157,8,93,8,221,8,61,8,189,8,125,8,253,8,19,9,275,9,147,9,403,9,83,9,339,9,211,9,467,9,51,9,307,9,179,9,435,9,115,9,371,9,243,9,499,9,11,9,267,9,139,9,395,9,75,9,331,9,203,9,459,9,43,9,299,9,171,9,427,9,107,9,363,9,235,9,491,9,27,9,283,9,155,9,411,9,91,9,347,9,219,9,475,9,59,9,315,9,187,9,443,9,123,9,379,9,251,9,507,9,7,9,263,9,135,9,391,9,71,9,327,9,199,9,455,9,39,9,295,9,167,9,423,9,103,9,359,9,231,9,487,9,23,9,279,9,151,9,407,9,87,9,343,9,215,9,471,9,55,9,311,9,183,9,439,9,119,9,375,9,247,9,503,9,15,9,271,9,143,9,399,9,79,9,335,9,207,9,463,9,47,9,303,9,175,9,431,9,111,9,367,9,239,9,495,9,31,9,287,9,159,9,415,9,95,9,351,9,223,9,479,9,63,9,319,9,191,9,447,9,127,9,383,9,255,9,511,9,0,7,64,7,32,7,96,7,16,7,80,7,48,7,112,7,8,7,72,7,40,7,104,7,24,7,88,7,56,7,120,7,4,7,68,7,36,7,100,7,20,7,84,7,52,7,116,7,3,8,131,8,67,8,195,8,35,8,163,8,99,8,227,8],e.static_dtree=[0,5,16,5,8,5,24,5,4,5,20,5,12,5,28,5,2,5,18,5,10,5,26,5,6,5,22,5,14,5,30,5,1,5,17,5,9,5,25,5,5,5,21,5,13,5,29,5,3,5,19,5,11,5,27,5,7,5,23,5],e.static_l_desc=new e(e.static_ltree,t.extra_lbits,l+1,f,i),e.static_d_desc=new e(e.static_dtree,t.extra_dbits,0,a,i),e.static_bl_desc=new e(null,t.extra_blbits,0,u,p);var O=9,R=8,D=0,U=1,F=2,j=[new r(0,0,0,0,D),new r(4,4,8,4,U),new r(4,5,16,8,U),new r(4,6,32,32,U),new r(4,4,16,16,F),new r(8,16,32,32,F),new r(8,16,128,128,F),new r(8,32,128,256,F),new r(32,128,258,1024,F),new r(32,258,258,4096,F)],L=["need dictionary","stream end","","","stream error","data error","","buffer error","",""],N=0,M=1,H=2,G=3,J=32,W=42,V=113,X=666,Y=8,K=0,Q=1,$=2,Z=3,te=258,ee=te+Z+1;return o.prototype={deflateInit:function(t,e){var r=this;return r.dstate=new s,e||(e=i),r.dstate.deflateInit(r,t,e)},deflate:function(t){var e=this;return e.dstate?e.dstate.deflate(e,t):B},deflateEnd:function(){var t=this;if(!t.dstate)return B;var e=t.dstate.deflateEnd();return t.dstate=null,e},deflateParams:function(t,e){var r=this;return r.dstate?r.dstate.deflateParams(r,t,e):B},deflateSetDictionary:function(t,e){var r=this;return r.dstate?r.dstate.deflateSetDictionary(r,t,e):B},read_buf:function(t,e,r){var n=this,s=n.avail_in;return s>r&&(s=r),0===s?0:(n.avail_in-=s,t.set(n.next_in.subarray(n.next_in_index,n.next_in_index+s),e),n.next_in_index+=s,n.total_in+=s,s)},flush_pending:function(){var t=this,e=t.dstate.pending;e>t.avail_out&&(e=t.avail_out),0!==e&&(t.next_out.set(t.dstate.pending_buf.subarray(t.dstate.pending_out,t.dstate.pending_out+e),t.next_out_index),t.next_out_index+=e,t.dstate.pending_out+=e,t.total_out+=e,t.avail_out-=e,t.dstate.pending-=e,0===t.dstate.pending&&(t.dstate.pending_out=0))}},function(t){var e=this,r=new o,n=512,s=k,i=new Uint8Array(n);"undefined"==typeof t&&(t=g),r.deflateInit(t),r.next_out=i,e.append=function(t,e){var o,a,u=[],c=0,l=0,f=0;if(t.length){r.next_in_index=0,r.next_in=t,r.avail_in=t.length;do{if(r.next_out_index=0,r.avail_out=n,o=r.deflate(s),o!=S)throw"deflating: "+r.msg;r.next_out_index&&(r.next_out_index==n?u.push(new Uint8Array(i)):u.push(new Uint8Array(i.subarray(0,r.next_out_index)))),f+=r.next_out_index,e&&r.next_in_index>0&&r.next_in_index!=c&&(e(r.next_in_index),c=r.next_in_index)}while(r.avail_in>0||0===r.avail_out);return a=new Uint8Array(f),u.forEach(function(t){a.set(t,l),l+=t.length}),a}},e.flush=function(){var t,e,s=[],o=0,a=0;do{if(r.next_out_index=0,r.avail_out=n,t=r.deflate(C),t!=E&&t!=S)throw"deflating: "+r.msg;n-r.avail_out>0&&s.push(new Uint8Array(i.subarray(0,r.next_out_index))),a+=r.next_out_index}while(r.avail_in>0||0===r.avail_out);return r.deflateEnd(),e=new Uint8Array(a),s.forEach(function(t){e.set(t,o),o+=t.length}),e}}}(this);!function(t){var e;e=function(){function e(t){var e,r,n,s,o,i,a,u,c,l,f,d,h,p,w;for(this.data=t,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={},i=null;;){switch(e=this.readUInt32(),l=function(){var t,e;for(e=[],a=t=0;4>t;a=++t)e.push(String.fromCharCode(this.data[this.pos++]));return e}.call(this).join("")){case"IHDR":this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++];break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(e);break;case"fcTL":i&&this.animation.frames.push(i),this.pos+=4,i={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()},o=this.readUInt16(),s=this.readUInt16()||100,i.delay=1e3*o/s,i.disposeOp=this.data[this.pos++],i.blendOp=this.data[this.pos++],i.data=[];break;case"IDAT":case"fdAT":for("fdAT"===l&&(this.pos+=4,e-=4),t=(null!=i?i.data:void 0)||this.imgData,a=h=0;e>=0?e>h:h>e;a=e>=0?++h:--h)t.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:if(n=this.palette.length/3,this.transparency.indexed=this.read(e),this.transparency.indexed.length>n)throw new Error("More transparent colors than palette size");if(f=n-this.transparency.indexed.length,f>0)for(a=p=0;f>=0?f>p:p>f;a=f>=0?++p:--p)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(e)[0];break;case 2:this.transparency.rgb=this.read(e)}break;case"tEXt":d=this.read(e),u=d.indexOf(0),c=String.fromCharCode.apply(String,d.slice(0,u)),this.text[c]=String.fromCharCode.apply(String,d.slice(u+1));break;case"IEND":return i&&this.animation.frames.push(i),this.colors=function(){switch(this.colorType){case 0:case 3:case 4:return 1;case 2:case 6:return 3}}.call(this),this.hasAlphaChannel=4===(w=this.colorType)||6===w,r=this.colors+(this.hasAlphaChannel?1:0),this.pixelBitlength=this.bits*r,this.colorSpace=function(){switch(this.colors){case 1:return"DeviceGray";case 3:return"DeviceRGB"}}.call(this),this.imgData=new Uint8Array(this.imgData),void 0;default:this.pos+=e}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}var r,n,s,o,i,u,c,l;e.load=function(t,r,n){var s;return"function"==typeof r&&(n=r),s=new XMLHttpRequest,s.open("GET",t,!0),s.responseType="arraybuffer",s.onload=function(){var t,o;return t=new Uint8Array(s.response||s.mozResponseArrayBuffer),o=new e(t),"function"==typeof(null!=r?r.getContext:void 0)&&o.render(r),"function"==typeof n?n(o):void 0},s.send(null)},o=0,s=1,i=2,n=0,r=1,e.prototype.read=function(t){var e,r,n;for(n=[],e=r=0;t>=0?t>r:r>t;e=t>=0?++r:--r)n.push(this.data[this.pos++]);return n},e.prototype.readUInt32=function(){var t,e,r,n;return t=this.data[this.pos++]<<24,e=this.data[this.pos++]<<16,r=this.data[this.pos++]<<8,n=this.data[this.pos++],t|e|r|n},e.prototype.readUInt16=function(){var t,e;return t=this.data[this.pos++]<<8,e=this.data[this.pos++],t|e},e.prototype.decodePixels=function(t){var e,r,n,s,o,i,u,c,l,f,d,h,p,w,m,y,v,g,b,q,x,k,_;if(null==t&&(t=this.imgData),0===t.length)return new Uint8Array(0);for(t=new a(t),t=t.getBytes(),h=this.pixelBitlength/8,y=h*this.width,p=new Uint8Array(y*this.height),i=t.length,m=0,w=0,r=0;i>w;){switch(t[w++]){case 0:for(s=b=0;y>b;s=b+=1)p[r++]=t[w++];break;case 1:for(s=q=0;y>q;s=q+=1)e=t[w++],o=h>s?0:p[r-h],p[r++]=(e+o)%256;break;case 2:for(s=x=0;y>x;s=x+=1)e=t[w++],n=(s-s%h)/h,v=m&&p[(m-1)*y+n*h+s%h],p[r++]=(v+e)%256;break;case 3:for(s=k=0;y>k;s=k+=1)e=t[w++],n=(s-s%h)/h,o=h>s?0:p[r-h],v=m&&p[(m-1)*y+n*h+s%h],p[r++]=(e+Math.floor((o+v)/2))%256;break;case 4:for(s=_=0;y>_;s=_+=1)e=t[w++],n=(s-s%h)/h,o=h>s?0:p[r-h],0===m?v=g=0:(v=p[(m-1)*y+n*h+s%h],g=n&&p[(m-1)*y+(n-1)*h+s%h]),u=o+v-g,c=Math.abs(u-o),f=Math.abs(u-v),d=Math.abs(u-g),l=f>=c&&d>=c?o:d>=f?v:g,p[r++]=(e+l)%256;break;default:throw new Error("Invalid filter algorithm: "+t[w-1])}m++}return p},e.prototype.decodePalette=function(){var t,e,r,n,s,o,i,a,u,c;for(n=this.palette,i=this.transparency.indexed||[],o=new Uint8Array((i.length||0)+n.length),s=0,r=n.length,t=0,e=a=0,u=n.length;u>a;e=a+=3)o[s++]=n[e],o[s++]=n[e+1],o[s++]=n[e+2],o[s++]=null!=(c=i[t++])?c:255;return o},e.prototype.copyToImageData=function(t,e){var r,n,s,o,i,a,u,c,l,f,d;if(n=this.colors,l=null,r=this.hasAlphaChannel,this.palette.length&&(l=null!=(d=this._decodedPalette)?d:this._decodedPalette=this.decodePalette(),n=4,r=!0),s=t.data||t,c=s.length,i=l||e,o=a=0,1===n)for(;c>o;)u=l?4*e[o/4]:a,f=i[u++],s[o++]=f,s[o++]=f,s[o++]=f,s[o++]=r?i[u++]:255,a=u;else for(;c>o;)u=l?4*e[o/4]:a,s[o++]=i[u++],s[o++]=i[u++],s[o++]=i[u++],s[o++]=r?i[u++]:255,a=u},e.prototype.decode=function(){var t;return t=new Uint8Array(this.width*this.height*4),this.copyToImageData(t,this.decodePixels()),t};try{c=t.document.createElement("canvas"),l=c.getContext("2d")}catch(f){return-1}return u=function(t){var e;return l.width=t.width,l.height=t.height,l.clearRect(0,0,t.width,t.height),l.putImageData(t,0,0),e=new Image,e.src=c.toDataURL(),e},e.prototype.decodeFrames=function(t){var e,r,n,s,o,i,a,c;if(this.animation){for(a=this.animation.frames,c=[],r=o=0,i=a.length;i>o;r=++o)e=a[r],n=t.createImageData(e.width,e.height),s=this.decodePixels(new Uint8Array(e.data)),this.copyToImageData(n,s),e.imageData=n,c.push(e.image=u(n));return c}},e.prototype.renderFrame=function(t,e){var r,o,a;return o=this.animation.frames,r=o[e],a=o[e-1],0===e&&t.clearRect(0,0,this.width,this.height),(null!=a?a.disposeOp:void 0)===s?t.clearRect(a.xOffset,a.yOffset,a.width,a.height):(null!=a?a.disposeOp:void 0)===i&&t.putImageData(a.imageData,a.xOffset,a.yOffset),r.blendOp===n&&t.clearRect(r.xOffset,r.yOffset,r.width,r.height),t.drawImage(r.image,r.xOffset,r.yOffset)},e.prototype.animate=function(t){var e,r,n,s,o,i,a=this;return r=0,i=this.animation,s=i.numFrames,n=i.frames,o=i.numPlays,(e=function(){var i,u;return i=r++%s,u=n[i],a.renderFrame(t,i),s>1&&o>r/s?a.animation._timeout=setTimeout(e,u.delay):void 0})()},e.prototype.stopAnimation=function(){var t;return clearTimeout(null!=(t=this.animation)?t._timeout:void 0)},e.prototype.render=function(t){var e,r;return t._png&&t._png.stopAnimation(),t._png=this,t.width=this.width,t.height=this.height,e=t.getContext("2d"),this.animation?(this.decodeFrames(e),this.animate(e)):(r=e.createImageData(this.width,this.height),this.copyToImageData(r,this.decodePixels()),e.putImageData(r,0,0))},e}(),t.PNG=e}("undefined"!=typeof window&&window||this);var i=function(){function t(){this.pos=0,this.bufferLength=0,this.eof=!1,this.buffer=null}return t.prototype={ensureBuffer:function(t){var e=this.buffer,r=e?e.byteLength:0;if(r>t)return e;for(var n=512;t>n;)n<<=1;for(var s=new Uint8Array(n),o=0;r>o;++o)s[o]=e[o];return this.buffer=s},getByte:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return this.buffer[this.pos++]},getBytes:function(t){var e=this.pos;if(t){this.ensureBuffer(e+t);for(var r=e+t;!this.eof&&this.bufferLength<r;)this.readBlock();var n=this.bufferLength;r>n&&(r=n)}else{for(;!this.eof;)this.readBlock();var r=this.bufferLength}return this.pos=r,this.buffer.subarray(e,r)},lookChar:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos])},getChar:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos++])},makeSubStream:function(t,e,r){for(var n=t+e;this.bufferLength<=n&&!this.eof;)this.readBlock();return new Stream(this.buffer,t,e,r)},skip:function(t){t||(t=1),this.pos+=t},reset:function(){this.pos=0}},t}(),a=function(){function t(t){throw new Error(t)}function e(e){var r=0,n=e[r++],s=e[r++];(-1==n||-1==s)&&t("Invalid header in flate stream"),8!=(15&n)&&t("Unknown compression method in flate stream"),((n<<8)+s)%31!=0&&t("Bad FCHECK in flate stream"),32&s&&t("FDICT bit set in flate stream"),this.bytes=e,this.bytesPos=r,this.codeSize=0,this.codeBuf=0,i.call(this)}if("undefined"==typeof Uint32Array)return void 0;var r=new Uint32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),n=new Uint32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),s=new Uint32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),o=[new Uint32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],a=[new Uint32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];return e.prototype=Object.create(i.prototype),e.prototype.getBits=function(e){for(var r,n=this.codeSize,s=this.codeBuf,o=this.bytes,i=this.bytesPos;e>n;)"undefined"==typeof(r=o[i++])&&t("Bad encoding in flate stream"),s|=r<<n,n+=8;return r=s&(1<<e)-1,this.codeBuf=s>>e,this.codeSize=n-=e,this.bytesPos=i,r},e.prototype.getCode=function(e){for(var r=e[0],n=e[1],s=this.codeSize,o=this.codeBuf,i=this.bytes,a=this.bytesPos;n>s;){var u;"undefined"==typeof(u=i[a++])&&t("Bad encoding in flate stream"),o|=u<<s,s+=8}var c=r[o&(1<<n)-1],l=c>>16,f=65535&c;return(0==s||l>s||0==l)&&t("Bad encoding in flate stream"),this.codeBuf=o>>l,this.codeSize=s-l,this.bytesPos=a,f},e.prototype.generateHuffmanTable=function(t){for(var e=t.length,r=0,n=0;e>n;++n)t[n]>r&&(r=t[n]);for(var s=1<<r,o=new Uint32Array(s),i=1,a=0,u=2;r>=i;++i,a<<=1,u<<=1)for(var c=0;e>c;++c)if(t[c]==i){for(var l=0,f=a,n=0;i>n;++n)l=l<<1|1&f,f>>=1;for(var n=l;s>n;n+=u)o[n]=i<<16|c;++a}return[o,r]},e.prototype.readBlock=function(){function e(t,e,r,n,s){for(var o=t.getBits(r)+n;o-->0;)e[k++]=s}var i=this.getBits(3);if(1&i&&(this.eof=!0),i>>=1,0==i){var u,c=this.bytes,l=this.bytesPos;
|
||
"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream");var f=u;"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream"),f|=u<<8,"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream");var d=u;"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream"),d|=u<<8,d!=(65535&~f)&&t("Bad uncompressed block length in flate stream"),this.codeBuf=0,this.codeSize=0;var h=this.bufferLength,p=this.ensureBuffer(h+f),w=h+f;this.bufferLength=w;for(var m=h;w>m;++m){if("undefined"==typeof(u=c[l++])){this.eof=!0;break}p[m]=u}return this.bytesPos=l,void 0}var y,v;if(1==i)y=o,v=a;else if(2==i){for(var g=this.getBits(5)+257,b=this.getBits(5)+1,q=this.getBits(4)+4,x=Array(r.length),k=0;q>k;)x[r[k++]]=this.getBits(3);for(var _=this.generateHuffmanTable(x),A=0,k=0,C=g+b,S=new Array(C);C>k;){var E=this.getCode(_);16==E?e(this,S,2,3,A):17==E?e(this,S,3,3,A=0):18==E?e(this,S,7,11,A=0):S[k++]=A=E}y=this.generateHuffmanTable(S.slice(0,g)),v=this.generateHuffmanTable(S.slice(g,C))}else t("Unknown block type in flate stream");for(var p=this.buffer,z=p?p.length:0,B=this.bufferLength;;){var I=this.getCode(y);if(256>I)B+1>=z&&(p=this.ensureBuffer(B+1),z=p.length),p[B++]=I;else{if(256==I)return this.bufferLength=B,void 0;I-=257,I=n[I];var T=I>>16;T>0&&(T=this.getBits(T));var A=(65535&I)+T;I=this.getCode(v),I=s[I],T=I>>16,T>0&&(T=this.getBits(T));var P=(65535&I)+T;B+A>=z&&(p=this.ensureBuffer(B+A),z=p.length);for(var O=0;A>O;++O,++B)p[B]=p[B-P]}}},e}();!function(t){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";"undefined"==typeof t.btoa&&(t.btoa=function(t){var r,n,s,o,i,a,u,c,l=0,f=0,d="",h=[];if(!t)return t;do r=t.charCodeAt(l++),n=t.charCodeAt(l++),s=t.charCodeAt(l++),c=r<<16|n<<8|s,o=c>>18&63,i=c>>12&63,a=c>>6&63,u=63&c,h[f++]=e.charAt(o)+e.charAt(i)+e.charAt(a)+e.charAt(u);while(l<t.length);d=h.join("");var p=t.length%3;return(p?d.slice(0,p-3):d)+"===".slice(p||3)}),"undefined"==typeof t.atob&&(t.atob=function(t){var r,n,s,o,i,a,u,c,l=0,f=0,d="",h=[];if(!t)return t;t+="";do o=e.indexOf(t.charAt(l++)),i=e.indexOf(t.charAt(l++)),a=e.indexOf(t.charAt(l++)),u=e.indexOf(t.charAt(l++)),c=o<<18|i<<12|a<<6|u,r=c>>16&255,n=c>>8&255,s=255&c,h[f++]=64==a?String.fromCharCode(r):64==u?String.fromCharCode(r,n):String.fromCharCode(r,n,s);while(l<t.length);return d=h.join("")}),Array.prototype.map||(Array.prototype.map=function(t){if(void 0===this||null===this||"function"!=typeof t)throw new TypeError;for(var e=Object(this),r=e.length>>>0,n=new Array(r),s=arguments.length>1?arguments[1]:void 0,o=0;r>o;o++)o in e&&(n[o]=t.call(s,e[o],o,e));return n}),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){"use strict";if(void 0===this||null===this||"function"!=typeof t)throw new TypeError;for(var r=Object(this),n=r.length>>>0,s=0;n>s;s++)s in r&&t.call(e,r[s],s,r)}),Object.keys||(Object.keys=function(){"use strict";var t=Object.prototype.hasOwnProperty,e=!{toString:null}.propertyIsEnumerable("toString"),r=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],n=r.length;return function(s){if("object"!=typeof s&&("function"!=typeof s||null===s))throw new TypeError;var o,i,a=[];for(o in s)t.call(s,o)&&a.push(o);if(e)for(i=0;n>i;i++)t.call(s,r[i])&&a.push(r[i]);return a}}()),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^\s+/g,"")}),String.prototype.trimRight||(String.prototype.trimRight=function(){return this.replace(/\s+$/g,"")})}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this)}({},function(){return this}());
|
||
// http://stackoverflow.com/questions/9847580/how-to-detect-safari-chrome-ie-firefox-and-opera-browser
|
||
var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
|
||
var isFirefox = typeof InstallTrigger !== 'undefined'; // Firefox 1.0+
|
||
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
|
||
var isChrome = !!window.chrome && !isOpera; // Chrome 1+
|
||
var isChromium = isChrome && navigator.userAgent.indexOf('Chromium') >= 0;
|
||
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6
|
||
|
||
function GetReportTemplate4(doc, invoice, layout, checkMath) {
|
||
|
||
var client = invoice.client;
|
||
var account = invoice.account;
|
||
var currencyId = client.currency_id;
|
||
|
||
if (invoice.image)
|
||
{
|
||
var left = layout.headerRight - invoice.imageWidth;
|
||
doc.addImage(invoice.image, 'JPEG', left, 30);
|
||
}
|
||
|
||
/* table header */
|
||
doc.setDrawColor(200,200,200);
|
||
doc.setFillColor(230,230,230);
|
||
|
||
var detailsHeight = getInvoiceDetailsHeight(invoice, layout);
|
||
var left = layout.headerLeft - layout.tablePadding;
|
||
var top = layout.headerTop + detailsHeight - layout.rowHeight - layout.tablePadding;
|
||
var width = layout.headerRight - layout.headerLeft + (2 * layout.tablePadding);
|
||
var height = layout.rowHeight + 1;
|
||
doc.rect(left, top, width, height, 'FD');
|
||
|
||
doc.setFontSize(10);
|
||
doc.setFontType("normal");
|
||
|
||
displayAccount(doc, invoice, layout.marginLeft, layout.accountTop, layout);
|
||
displayClient(doc, invoice, layout.marginLeft, layout.headerTop, layout);
|
||
|
||
displayInvoice(doc, invoice, layout.headerLeft, layout.headerTop, layout, layout.headerRight);
|
||
layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (2 * layout.tablePadding));
|
||
|
||
var headerY = layout.headerTop;
|
||
var total = 0;
|
||
|
||
doc.setDrawColor(200,200,200);
|
||
doc.setFillColor(230,230,230);
|
||
var left = layout.marginLeft - layout.tablePadding;
|
||
var top = layout.tableTop - layout.tablePadding;
|
||
var width = layout.headerRight - layout.marginLeft + (2 * layout.tablePadding);
|
||
var height = layout.rowHeight + 2;
|
||
doc.rect(left, top, width, height, 'FD');
|
||
|
||
displayInvoiceHeader(doc, invoice, layout);
|
||
var y = displayInvoiceItems(doc, invoice, layout);
|
||
|
||
doc.setFontSize(10);
|
||
|
||
/* table footer */
|
||
/*
|
||
doc.setDrawColor(200,200,200);
|
||
doc.setLineWidth(1);
|
||
doc.line(layout.marginLeft - layout.tablePadding, x, layout.lineTotalRight+layout.tablePadding, x);
|
||
*/
|
||
|
||
displayNotesAndTerms(doc, layout, invoice, y+20);
|
||
|
||
y += displaySubtotals(doc, layout, invoice, y+20, 480) + 20;
|
||
|
||
/*
|
||
if (checkMath && NINJA.parseFloat(total).toFixed(4) != NINJA.parseFloat(invoice.amount).toFixed(4))
|
||
{
|
||
var doc = new jsPDF('p', 'pt');
|
||
doc.setFont('Helvetica','');
|
||
doc.setFontSize(10);
|
||
doc.text(100, 100, "An error occurred, please try again later.");
|
||
onerror('Failed to generate PDF ' + total + ', ' + invoice.amount );
|
||
return doc;
|
||
}
|
||
*/
|
||
|
||
doc.setDrawColor(200,200,200);
|
||
doc.setFillColor(230,230,230);
|
||
|
||
var left = layout.footerLeft - layout.tablePadding;
|
||
var top = y - layout.tablePadding;
|
||
var width = layout.headerRight - layout.footerLeft + (2 * layout.tablePadding);
|
||
var height = layout.rowHeight + 2;
|
||
doc.rect(left, top, width, height, 'FD');
|
||
|
||
doc.setFontType("bold");
|
||
doc.text(layout.footerLeft, y, invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due);
|
||
|
||
total = formatMoney(invoice.balance_amount, currencyId);
|
||
var totalX = layout.headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize());
|
||
doc.text(totalX, y, total);
|
||
|
||
if (!invoice.is_pro) {
|
||
doc.setFontType("normal");
|
||
doc.text(layout.marginLeft, 790, "Created by InvoiceNinja.com");
|
||
}
|
||
|
||
return doc;
|
||
}
|
||
|
||
|
||
var invoiceOld;
|
||
function generatePDF(invoice, force) {
|
||
invoice = calculateAmounts(invoice);
|
||
var a = copyInvoice(invoice);
|
||
var b = copyInvoice(invoiceOld);
|
||
if (!force && _.isEqual(a, b)) {
|
||
return;
|
||
}
|
||
invoiceOld = invoice;
|
||
report_id = invoice.invoice_design_id;
|
||
doc = GetPdf(invoice, false, report_id);
|
||
return doc;
|
||
}
|
||
|
||
function copyInvoice(orig) {
|
||
if (!orig) return false;
|
||
var copy = JSON.stringify(orig);
|
||
var copy = JSON.parse(copy);
|
||
return copy;
|
||
}
|
||
|
||
/* Handle converting variables in the invoices (ie, MONTH+1) */
|
||
function processVariables(str) {
|
||
if (!str) return '';
|
||
var variables = ['MONTH','QUARTER','YEAR'];
|
||
for (var i=0; i<variables.length; i++) {
|
||
var variable = variables[i];
|
||
var regexp = new RegExp(':' + variable + '[+-]?[\\d]*', 'g');
|
||
var matches = str.match(regexp);
|
||
if (!matches) {
|
||
continue;
|
||
}
|
||
for (var j=0; j<matches.length; j++) {
|
||
var match = matches[j];
|
||
var offset = 0;
|
||
if (match.split('+').length > 1) {
|
||
offset = match.split('+')[1];
|
||
} else if (match.split('-').length > 1) {
|
||
offset = parseInt(match.split('-')[1]) * -1;
|
||
}
|
||
str = str.replace(match, getDatePart(variable, offset));
|
||
}
|
||
}
|
||
|
||
return str;
|
||
}
|
||
|
||
function getDatePart(part, offset) {
|
||
offset = parseInt(offset);
|
||
if (!offset) {
|
||
offset = 0;
|
||
}
|
||
if (part == 'MONTH') {
|
||
return getMonth(offset);
|
||
} else if (part == 'QUARTER') {
|
||
return getQuarter(offset);
|
||
} else if (part == 'YEAR') {
|
||
return getYear(offset);
|
||
}
|
||
}
|
||
|
||
function getMonth(offset) {
|
||
var today = new Date();
|
||
var months = [ "January", "February", "March", "April", "May", "June",
|
||
"July", "August", "September", "October", "November", "December" ];
|
||
var month = today.getMonth();
|
||
month = parseInt(month) + offset;
|
||
month = month % 12;
|
||
if (month < 0) {
|
||
month += 12;
|
||
}
|
||
return months[month];
|
||
}
|
||
|
||
function getYear(offset) {
|
||
var today = new Date();
|
||
var year = today.getFullYear();
|
||
return parseInt(year) + offset;
|
||
}
|
||
|
||
function getQuarter(offset) {
|
||
var today = new Date();
|
||
var quarter = Math.floor((today.getMonth() + 3) / 3);
|
||
quarter += offset;
|
||
quarter = quarter % 4;
|
||
if (quarter == 0) {
|
||
quarter = 4;
|
||
}
|
||
return 'Q' + quarter;
|
||
}
|
||
|
||
|
||
/* Default class modification */
|
||
$.extend( $.fn.dataTableExt.oStdClasses, {
|
||
"sWrapper": "dataTables_wrapper form-inline"
|
||
} );
|
||
|
||
|
||
/* API method to get paging information */
|
||
$.fn.dataTableExt.oApi.fnPagingInfo = function ( oSettings )
|
||
{
|
||
return {
|
||
"iStart": oSettings._iDisplayStart,
|
||
"iEnd": oSettings.fnDisplayEnd(),
|
||
"iLength": oSettings._iDisplayLength,
|
||
"iTotal": oSettings.fnRecordsTotal(),
|
||
"iFilteredTotal": oSettings.fnRecordsDisplay(),
|
||
"iPage": oSettings._iDisplayLength === -1 ?
|
||
0 : Math.ceil( oSettings._iDisplayStart / oSettings._iDisplayLength ),
|
||
"iTotalPages": oSettings._iDisplayLength === -1 ?
|
||
0 : Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength )
|
||
};
|
||
};
|
||
|
||
|
||
/* Bootstrap style pagination control */
|
||
$.extend( $.fn.dataTableExt.oPagination, {
|
||
"bootstrap": {
|
||
"fnInit": function( oSettings, nPaging, fnDraw ) {
|
||
var oLang = oSettings.oLanguage.oPaginate;
|
||
var fnClickHandler = function ( e ) {
|
||
e.preventDefault();
|
||
if ( oSettings.oApi._fnPageChange(oSettings, e.data.action) ) {
|
||
fnDraw( oSettings );
|
||
}
|
||
};
|
||
|
||
$(nPaging).addClass('pagination').append(
|
||
'<ul class="pagination">'+
|
||
'<li class="prev disabled"><a href="#">«</a></li>'+
|
||
'<li class="next disabled"><a href="#">»</a></li>'+
|
||
'</ul>'
|
||
);
|
||
var els = $('a', nPaging);
|
||
$(els[0]).bind( 'click.DT', { action: "previous" }, fnClickHandler );
|
||
$(els[1]).bind( 'click.DT', { action: "next" }, fnClickHandler );
|
||
},
|
||
|
||
"fnUpdate": function ( oSettings, fnDraw ) {
|
||
var iListLength = 5;
|
||
var oPaging = oSettings.oInstance.fnPagingInfo();
|
||
var an = oSettings.aanFeatures.p;
|
||
var i, ien, j, sClass, iStart, iEnd, iHalf=Math.floor(iListLength/2);
|
||
|
||
if ( oPaging.iTotalPages < iListLength) {
|
||
iStart = 1;
|
||
iEnd = oPaging.iTotalPages;
|
||
}
|
||
else if ( oPaging.iPage <= iHalf ) {
|
||
iStart = 1;
|
||
iEnd = iListLength;
|
||
} else if ( oPaging.iPage >= (oPaging.iTotalPages-iHalf) ) {
|
||
iStart = oPaging.iTotalPages - iListLength + 1;
|
||
iEnd = oPaging.iTotalPages;
|
||
} else {
|
||
iStart = oPaging.iPage - iHalf + 1;
|
||
iEnd = iStart + iListLength - 1;
|
||
}
|
||
|
||
for ( i=0, ien=an.length ; i<ien ; i++ ) {
|
||
// Remove the middle elements
|
||
$('li:gt(0)', an[i]).filter(':not(:last)').remove();
|
||
|
||
// Add the new list items and their event handlers
|
||
for ( j=iStart ; j<=iEnd ; j++ ) {
|
||
sClass = (j==oPaging.iPage+1) ? 'class="active"' : '';
|
||
$('<li '+sClass+'><a href="#">'+j+'</a></li>')
|
||
.insertBefore( $('li:last', an[i])[0] )
|
||
.bind('click', function (e) {
|
||
e.preventDefault();
|
||
oSettings._iDisplayStart = (parseInt($('a', this).text(),10)-1) * oPaging.iLength;
|
||
fnDraw( oSettings );
|
||
} );
|
||
}
|
||
|
||
// Add / remove disabled classes from the static elements
|
||
if ( oPaging.iPage === 0 ) {
|
||
$('li:first', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:first', an[i]).removeClass('disabled');
|
||
}
|
||
|
||
if ( oPaging.iPage === oPaging.iTotalPages-1 || oPaging.iTotalPages === 0 ) {
|
||
$('li:last', an[i]).addClass('disabled');
|
||
} else {
|
||
$('li:last', an[i]).removeClass('disabled');
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} );
|
||
|
||
|
||
/*
|
||
* TableTools Bootstrap compatibility
|
||
* Required TableTools 2.1+
|
||
*/
|
||
if ( $.fn.DataTable.TableTools ) {
|
||
// Set the classes that TableTools uses to something suitable for Bootstrap
|
||
$.extend( true, $.fn.DataTable.TableTools.classes, {
|
||
"container": "DTTT btn-group",
|
||
"buttons": {
|
||
"normal": "btn",
|
||
"disabled": "disabled"
|
||
},
|
||
"collection": {
|
||
"container": "DTTT_dropdown dropdown-menu",
|
||
"buttons": {
|
||
"normal": "",
|
||
"disabled": "disabled"
|
||
}
|
||
},
|
||
"print": {
|
||
"info": "DTTT_print_info modal"
|
||
},
|
||
"select": {
|
||
"row": "active"
|
||
}
|
||
} );
|
||
|
||
// Have the collection use a bootstrap compatible dropdown
|
||
$.extend( true, $.fn.DataTable.TableTools.DEFAULTS.oTags, {
|
||
"collection": {
|
||
"container": "ul",
|
||
"button": "li",
|
||
"liner": "a"
|
||
}
|
||
} );
|
||
}
|
||
|
||
/*
|
||
$(document).ready(function() {
|
||
$('#example').dataTable( {
|
||
"sDom": "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>",
|
||
"sPaginationType": "bootstrap",
|
||
"oLanguage": {
|
||
"sLengthMenu": "_MENU_ records per page"
|
||
}
|
||
} );
|
||
} );
|
||
*/
|
||
|
||
function isStorageSupported() {
|
||
try {
|
||
return 'localStorage' in window && window['localStorage'] !== null;
|
||
} catch (e) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function isValidEmailAddress(emailAddress) {
|
||
var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
|
||
return pattern.test(emailAddress);
|
||
};
|
||
|
||
$(function() {
|
||
$.ajaxSetup({
|
||
headers: {
|
||
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
|
||
}
|
||
});
|
||
});
|
||
|
||
|
||
function enableHoverClick($combobox, $entityId, url) {
|
||
/*
|
||
$combobox.mouseleave(function() {
|
||
$combobox.css('text-decoration','none');
|
||
}).on('mouseenter', function(e) {
|
||
setAsLink($combobox, $combobox.closest('.combobox-container').hasClass('combobox-selected'));
|
||
}).on('focusout mouseleave', function(e) {
|
||
setAsLink($combobox, false);
|
||
}).on('click', function() {
|
||
var clientId = $entityId.val();
|
||
if ($(combobox).closest('.combobox-container').hasClass('combobox-selected')) {
|
||
if (parseInt(clientId) > 0) {
|
||
window.open(url + '/' + clientId, '_blank');
|
||
} else {
|
||
$('#myModal').modal('show');
|
||
}
|
||
};
|
||
});
|
||
*/
|
||
}
|
||
|
||
function setAsLink($input, enable) {
|
||
if (enable) {
|
||
$input.css('text-decoration','underline');
|
||
$input.css('cursor','pointer');
|
||
} else {
|
||
$input.css('text-decoration','none');
|
||
$input.css('cursor','text');
|
||
}
|
||
}
|
||
|
||
function setComboboxValue($combobox, id, name) {
|
||
$combobox.find('input').val(id);
|
||
$combobox.find('input.form-control').val(name);
|
||
if (id && name) {
|
||
$combobox.find('select').combobox('setSelected');
|
||
$combobox.find('.combobox-container').addClass('combobox-selected');
|
||
} else {
|
||
$combobox.find('.combobox-container').removeClass('combobox-selected');
|
||
}
|
||
}
|
||
|
||
|
||
var BASE64_MARKER = ';base64,';
|
||
function convertDataURIToBinary(dataURI) {
|
||
var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
|
||
var base64 = dataURI.substring(base64Index);
|
||
var raw = window.atob(base64);
|
||
var rawLength = raw.length;
|
||
var array = new Uint8Array(new ArrayBuffer(rawLength));
|
||
|
||
for(i = 0; i < rawLength; i++) {
|
||
array[i] = raw.charCodeAt(i);
|
||
}
|
||
return array;
|
||
}
|
||
|
||
|
||
ko.bindingHandlers.dropdown = {
|
||
init: function (element, valueAccessor, allBindingsAccessor) {
|
||
var options = allBindingsAccessor().dropdownOptions|| {};
|
||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||
var id = (value && value.public_id) ? value.public_id() : (value && value.id) ? value.id() : value ? value : false;
|
||
if (id) $(element).val(id);
|
||
//console.log("combo-init: %s", id);
|
||
$(element).combobox(options);
|
||
|
||
/*
|
||
ko.utils.registerEventHandler(element, "change", function () {
|
||
console.log("change: %s", $(element).val());
|
||
//var
|
||
valueAccessor($(element).val());
|
||
//$(element).combobox('refresh');
|
||
});
|
||
*/
|
||
},
|
||
update: function (element, valueAccessor) {
|
||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||
var id = (value && value.public_id) ? value.public_id() : (value && value.id) ? value.id() : value ? value : false;
|
||
//console.log("combo-update: %s", id);
|
||
if (id) {
|
||
$(element).val(id);
|
||
$(element).combobox('refresh');
|
||
} else {
|
||
$(element).combobox('clearTarget');
|
||
$(element).combobox('clearElement');
|
||
}
|
||
}
|
||
};
|
||
|
||
|
||
ko.bindingHandlers.datePicker = {
|
||
init: function (element, valueAccessor, allBindingsAccessor) {
|
||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||
if (value) $(element).datepicker('update', value);
|
||
$(element).change(function() {
|
||
var value = valueAccessor();
|
||
value($(element).val());
|
||
})
|
||
},
|
||
update: function (element, valueAccessor) {
|
||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||
if (value) $(element).datepicker('update', value);
|
||
}
|
||
};
|
||
|
||
|
||
function wordWrapText(value, width)
|
||
{
|
||
var doc = new jsPDF('p', 'pt');
|
||
doc.setFont('Helvetica','');
|
||
doc.setFontSize(10);
|
||
|
||
var lines = value.split("\n");
|
||
for (var i = 0; i < lines.length; i++) {
|
||
var numLines = doc.splitTextToSize(lines[i], width).length;
|
||
if (numLines <= 1) continue;
|
||
var j = 0; space = lines[i].length;
|
||
while (j++ < lines[i].length) {
|
||
if (lines[i].charAt(j) === ' ') space = j;
|
||
}
|
||
if (space == lines[i].length) space = width/6;
|
||
lines[i + 1] = lines[i].substring(space + 1) + ' ' + (lines[i + 1] || '');
|
||
lines[i] = lines[i].substring(0, space);
|
||
}
|
||
|
||
var newValue = (lines.join("\n")).trim();
|
||
|
||
if (value == newValue) {
|
||
return newValue;
|
||
} else {
|
||
return wordWrapText(newValue, width);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
function getClientDisplayName(client)
|
||
{
|
||
var contact = client.contacts[0];
|
||
if (client.name) {
|
||
return client.name;
|
||
} else if (contact.first_name || contact.last_name) {
|
||
return contact.first_name + ' ' + contact.last_name;
|
||
} else {
|
||
return contact.email;
|
||
}
|
||
}
|
||
|
||
|
||
function populateInvoiceComboboxes(clientId, invoiceId) {
|
||
var clientMap = {};
|
||
var invoiceMap = {};
|
||
var invoicesForClientMap = {};
|
||
var $clientSelect = $('select#client');
|
||
|
||
for (var i=0; i<invoices.length; i++) {
|
||
var invoice = invoices[i];
|
||
var client = invoice.client;
|
||
|
||
if (!invoicesForClientMap.hasOwnProperty(client.public_id)) {
|
||
invoicesForClientMap[client.public_id] = [];
|
||
}
|
||
|
||
invoicesForClientMap[client.public_id].push(invoice);
|
||
invoiceMap[invoice.public_id] = invoice;
|
||
}
|
||
|
||
for (var i=0; i<clients.length; i++) {
|
||
var client = clients[i];
|
||
clientMap[client.public_id] = client;
|
||
}
|
||
|
||
$clientSelect.append(new Option('', ''));
|
||
for (var i=0; i<clients.length; i++) {
|
||
var client = clients[i];
|
||
$clientSelect.append(new Option(getClientDisplayName(client), client.public_id));
|
||
}
|
||
|
||
if (clientId) {
|
||
$clientSelect.val(clientId);
|
||
}
|
||
|
||
$clientSelect.combobox();
|
||
$clientSelect.on('change', function(e) {
|
||
var clientId = $('input[name=client]').val();
|
||
var invoiceId = $('input[name=invoice]').val();
|
||
var invoice = invoiceMap[invoiceId];
|
||
if (invoice && invoice.client.public_id == clientId) {
|
||
e.preventDefault();
|
||
return;
|
||
}
|
||
setComboboxValue($('.invoice-select'), '', '');
|
||
$invoiceCombobox = $('select#invoice');
|
||
$invoiceCombobox.find('option').remove().end().combobox('refresh');
|
||
$invoiceCombobox.append(new Option('', ''));
|
||
var list = clientId ? (invoicesForClientMap.hasOwnProperty(clientId) ? invoicesForClientMap[clientId] : []) : invoices;
|
||
for (var i=0; i<list.length; i++) {
|
||
var invoice = list[i];
|
||
var client = clientMap[invoice.client.public_id];
|
||
if (!client) continue; // client is deleted/archived
|
||
$invoiceCombobox.append(new Option(invoice.invoice_number + ' - ' + invoice.invoice_status.name + ' - ' +
|
||
getClientDisplayName(client) + ' - ' + formatMoney(invoice.amount, invoice.currency_id) + ' | ' +
|
||
formatMoney(invoice.balance, invoice.currency_id), invoice.public_id));
|
||
}
|
||
$('select#invoice').combobox('refresh');
|
||
});
|
||
|
||
var $invoiceSelect = $('select#invoice').on('change', function(e) {
|
||
$clientCombobox = $('select#client');
|
||
var invoiceId = $('input[name=invoice]').val();
|
||
if (invoiceId) {
|
||
var invoice = invoiceMap[invoiceId];
|
||
var client = clientMap[invoice.client.public_id];
|
||
setComboboxValue($('.client-select'), client.public_id, getClientDisplayName(client));
|
||
if (!parseFloat($('#amount').val())) {
|
||
$('#amount').val(formatMoney(invoice.balance, invoice.currency_id, true));
|
||
}
|
||
}
|
||
});
|
||
|
||
$invoiceSelect.combobox();
|
||
|
||
if (invoiceId) {
|
||
var invoice = invoiceMap[invoiceId];
|
||
var client = clientMap[invoice.client.public_id];
|
||
setComboboxValue($('.invoice-select'), invoice.public_id, (invoice.invoice_number + ' - ' +
|
||
invoice.invoice_status.name + ' - ' + getClientDisplayName(client) + ' - ' +
|
||
formatMoney(invoice.amount, invoice.currency_id) + ' | ' + formatMoney(invoice.balance, invoice.currency_id)));
|
||
$invoiceSelect.trigger('change');
|
||
} else if (clientId) {
|
||
var client = clientMap[clientId];
|
||
setComboboxValue($('.client-select'), client.public_id, getClientDisplayName(client));
|
||
$clientSelect.trigger('change');
|
||
} else {
|
||
$clientSelect.trigger('change');
|
||
}
|
||
}
|
||
|
||
|
||
var CONSTS = {};
|
||
CONSTS.INVOICE_STATUS_DRAFT = 1;
|
||
CONSTS.INVOICE_STATUS_SENT = 2;
|
||
CONSTS.INVOICE_STATUS_VIEWED = 3;
|
||
CONSTS.INVOICE_STATUS_PARTIAL = 4;
|
||
CONSTS.INVOICE_STATUS_PAID = 5;
|
||
|
||
$.fn.datepicker.defaults.autoclose = true;
|
||
$.fn.datepicker.defaults.todayHighlight = true;
|
||
|
||
|
||
|
||
//====================================================================================================================
|
||
|
||
function GetPdf(invoice,checkMath,report_id){
|
||
var layout = {
|
||
accountTop: 40,
|
||
marginLeft: 50,
|
||
marginRight: 550,
|
||
headerTop: 150,
|
||
headerLeft: 360,
|
||
headerRight: 550,
|
||
rowHeight: 15,
|
||
tableRowHeight: 10,
|
||
footerLeft: 420,
|
||
tablePadding: 12,
|
||
tableTop: 250,
|
||
descriptionLeft: 162,
|
||
unitCostRight: 410,
|
||
qtyRight: 480,
|
||
taxRight: 480,
|
||
lineTotalRight: 550
|
||
};
|
||
|
||
if (invoice.has_taxes)
|
||
{
|
||
layout.descriptionLeft -= 20;
|
||
layout.unitCostRight -= 40;
|
||
layout.qtyRight -= 40;
|
||
}
|
||
|
||
/*
|
||
@param orientation One of "portrait" or "landscape" (or shortcuts "p" (Default), "l")
|
||
@param unit Measurement unit to be used when coordinates are specified. One of "pt" (points), "mm" (Default), "cm", "in"
|
||
@param format One of 'a3', 'a4' (Default),'a5' ,'letter' ,'legal'
|
||
@returns {jsPDF}
|
||
*/
|
||
var doc = new jsPDF('portrait', 'pt', 'a4');
|
||
|
||
|
||
//Set PDF properities
|
||
doc.setProperties({
|
||
title: 'Invoice ' + invoice.invoice_number,
|
||
subject: '',
|
||
author: 'InvoiceNinja.com',
|
||
keywords: 'pdf, invoice',
|
||
creator: 'InvoiceNinja.com'
|
||
});
|
||
|
||
//set default style for report
|
||
doc.setFont('Helvetica','');
|
||
|
||
if (report_id==1) {
|
||
return GetReportTemplate1(doc, invoice, layout, checkMath);
|
||
} else if (report_id==2) {
|
||
return GetReportTemplate2(doc, invoice, layout, checkMath);
|
||
} else if (report_id==3) {
|
||
return GetReportTemplate3(doc, invoice, layout, checkMath);
|
||
} else {
|
||
return GetReportTemplate4(doc, invoice, layout, checkMath);
|
||
}
|
||
}
|
||
|
||
function GetReportTemplate1(doc, invoice, layout, checkMath)
|
||
{
|
||
var GlobalY=0;//Y position of line at current page
|
||
|
||
var client = invoice.client;
|
||
var account = invoice.account;
|
||
var currencyId = client.currency_id;
|
||
|
||
layout.headerRight = 550;
|
||
layout.rowHeight = 15;
|
||
|
||
doc.setFontSize(9);
|
||
|
||
if (invoice.image)
|
||
{
|
||
var left = layout.headerRight - invoice.imageWidth;
|
||
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30);
|
||
}
|
||
|
||
if (!invoice.is_pro && logoImages.imageLogo1)
|
||
{
|
||
pageHeight=820;
|
||
y=pageHeight-logoImages.imageLogoHeight1;
|
||
doc.addImage(logoImages.imageLogo1, 'JPEG', layout.marginLeft, y, logoImages.imageLogoWidth1, logoImages.imageLogoHeight1);
|
||
}
|
||
|
||
|
||
doc.setFontSize(9);
|
||
SetPdfColor('LightBlue', doc, 'primary');
|
||
displayAccount(doc, invoice, 220, layout.accountTop, layout);
|
||
|
||
SetPdfColor('LightBlue', doc, 'primary');
|
||
doc.setFontSize('11');
|
||
doc.text(50, layout.headerTop, (invoice.is_quote ? invoiceLabels.quote : invoiceLabels.invoice).toUpperCase());
|
||
|
||
//doc.setDrawColor(220,220,220);
|
||
//doc.line(30, y, 560, y); // horizontal line
|
||
|
||
|
||
SetPdfColor('Black',doc); //set black color
|
||
doc.setFontSize(9);
|
||
|
||
var invoiceHeight = displayInvoice(doc, invoice, 50, 170, layout);
|
||
var clientHeight = displayClient(doc, invoice, 220, 170, layout);
|
||
var detailsHeight = Math.max(invoiceHeight, clientHeight);
|
||
layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (3 * layout.rowHeight));
|
||
|
||
|
||
|
||
doc.setLineWidth(0.3);
|
||
doc.setDrawColor(200,200,200);
|
||
doc.line(layout.marginLeft - layout.tablePadding, layout.headerTop + 6, layout.marginRight + layout.tablePadding, layout.headerTop + 6);
|
||
doc.line(layout.marginLeft - layout.tablePadding, layout.headerTop + detailsHeight + 14, layout.marginRight + layout.tablePadding, layout.headerTop + detailsHeight + 14);
|
||
|
||
|
||
//doc.setDrawColor(220,220,220);
|
||
//doc.line(30, y-8, 560, y-8); // horizontal line
|
||
|
||
|
||
doc.setFontSize(10);
|
||
doc.setFontType("bold");
|
||
displayInvoiceHeader(doc, invoice, layout);
|
||
var y = displayInvoiceItems(doc, invoice, layout);
|
||
|
||
//doc.setFontType("normal");
|
||
doc.setFontSize(9);
|
||
|
||
doc.setFontType("bold");
|
||
|
||
GlobalY=GlobalY+25;
|
||
|
||
|
||
doc.setLineWidth(0.3);
|
||
doc.setDrawColor(241,241,241);
|
||
doc.setFillColor(241,241,241);
|
||
var x1 = layout.marginLeft - 12;
|
||
var y1 = GlobalY-layout.tablePadding;
|
||
|
||
var w2 = 510 + 24;
|
||
var h2 = doc.internal.getFontSize()*3+layout.tablePadding*2;
|
||
|
||
if (invoice.discount) {
|
||
h2 += doc.internal.getFontSize()*2;
|
||
}
|
||
if (invoice.tax_amount) {
|
||
h2 += doc.internal.getFontSize()*2;
|
||
}
|
||
|
||
//doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
doc.setFontSize(9);
|
||
displayNotesAndTerms(doc, layout, invoice, y);
|
||
y += displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);
|
||
|
||
|
||
doc.setFontSize(10);
|
||
Msg = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;
|
||
var TmpMsgX = layout.unitCostRight-(doc.getStringUnitWidth(Msg) * doc.internal.getFontSize());
|
||
|
||
doc.text(TmpMsgX, y, Msg);
|
||
|
||
SetPdfColor('LightBlue', doc, 'primary');
|
||
AmountText = formatMoney(invoice.balance_amount, currencyId);
|
||
headerLeft=layout.headerRight+400;
|
||
var AmountX = layout.lineTotalRight - (doc.getStringUnitWidth(AmountText) * doc.internal.getFontSize());
|
||
doc.text(AmountX, y, AmountText);
|
||
|
||
return doc;
|
||
}
|
||
|
||
|
||
|
||
|
||
function GetReportTemplate2(doc, invoice, layout, checkMath)
|
||
{
|
||
var GlobalY=0;//Y position of line at current page
|
||
|
||
var client = invoice.client;
|
||
var account = invoice.account;
|
||
var currencyId = client.currency_id;
|
||
|
||
layout.headerRight = 150;
|
||
layout.rowHeight = 15;
|
||
layout.headerTop = 125;
|
||
layout.tableTop = 300;
|
||
|
||
doc.setLineWidth(0.5);
|
||
|
||
if (NINJA.primaryColor) {
|
||
setDocHexFill(doc, NINJA.primaryColor);
|
||
setDocHexDraw(doc, NINJA.primaryColor);
|
||
} else {
|
||
doc.setFillColor(46,43,43);
|
||
}
|
||
|
||
var x1 =0;
|
||
var y1 = 0;
|
||
var w2 = 595;
|
||
var h2 = 100;
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
|
||
if (invoice.image)
|
||
{
|
||
var left = layout.headerRight - invoice.imageWidth;
|
||
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30);
|
||
}
|
||
|
||
Report2AddFooter (invoice,doc);
|
||
|
||
|
||
doc.setFontSize(7);
|
||
doc.setFontType("bold");
|
||
SetPdfColor('White',doc);
|
||
|
||
displayAccount(doc, invoice, 300, layout.accountTop, layout);
|
||
|
||
/*
|
||
var spacer = ' ';
|
||
var line1 = account.name + spacer + account.work_email + spacer + account.work_phone;
|
||
var lineWidth = doc.getStringUnitWidth(line1) * doc.internal.getFontSize();
|
||
var nameWidth = doc.getStringUnitWidth(account.name + spacer) * doc.internal.getFontSize();
|
||
var nameX = lineTotalRight - lineWidth;
|
||
var detailsX = lineTotalRight - (lineWidth - nameWidth);
|
||
|
||
doc.text(nameX, accountTop, account.name);
|
||
doc.setFontType("normal");
|
||
doc.text(detailsX, accountTop, account.work_email + spacer + account.work_phone);
|
||
|
||
var line2 = concatStrings(account.address1, account.address2) + spacer + concatStrings(account.city, account.state, account.postal_code);
|
||
var lineWidth = doc.getStringUnitWidth(line2) * doc.internal.getFontSize();
|
||
var line2X = lineTotalRight - lineWidth;
|
||
|
||
doc.text(line2X, accountTop + 16, line2);
|
||
*/
|
||
|
||
//-----------------------------Publish Client Details block--------------------------------------------
|
||
|
||
var y = layout.accountTop;
|
||
var left = layout.marginLeft;
|
||
|
||
var headerY = layout.headerTop;
|
||
|
||
|
||
|
||
SetPdfColor('GrayLogo',doc); //set black color
|
||
|
||
|
||
doc.setFontSize(7);
|
||
|
||
//show left column
|
||
SetPdfColor('Black',doc); //set black color
|
||
doc.setFontType("normal");
|
||
|
||
|
||
//publish filled box
|
||
doc.setDrawColor(200,200,200);
|
||
|
||
if (NINJA.secondaryColor) {
|
||
setDocHexFill(doc, NINJA.secondaryColor);
|
||
} else {
|
||
doc.setFillColor(54,164,152);
|
||
}
|
||
|
||
GlobalY=190;
|
||
doc.setLineWidth(0.5);
|
||
|
||
var BlockLenght=220;
|
||
var x1 =595-BlockLenght;
|
||
var y1 = GlobalY-12;
|
||
var w2 = BlockLenght;
|
||
var h2 = getInvoiceDetailsHeight(invoice, layout) + layout.tablePadding + 2;
|
||
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
|
||
SetPdfColor('SomeGreen', doc, 'secondary');
|
||
doc.setFontSize('14');
|
||
doc.setFontType("bold");
|
||
doc.text(50, GlobalY, (invoice.is_quote ? invoiceLabels.your_quote : invoiceLabels.your_invoice).toUpperCase());
|
||
|
||
|
||
var z=GlobalY;
|
||
z=z+30;
|
||
|
||
|
||
doc.setFontSize('8');
|
||
SetPdfColor('Black',doc);
|
||
displayClient(doc, invoice, layout.marginLeft, z, layout);
|
||
|
||
|
||
marginLeft2=395;
|
||
|
||
//publish left side information
|
||
|
||
SetPdfColor('White',doc);
|
||
doc.setFontSize('8');
|
||
var detailsHeight = displayInvoice(doc, invoice, marginLeft2, z-25, layout) + 75;
|
||
layout.tableTop = Math.max(layout.tableTop, layout.headerTop + detailsHeight + (2 * layout.tablePadding));
|
||
|
||
y=z+60;
|
||
|
||
|
||
x = GlobalY + 100;
|
||
|
||
doc.setFontType("bold");
|
||
|
||
|
||
|
||
doc.setFontSize(12);
|
||
doc.setFontType("bold");
|
||
SetPdfColor('Black',doc);
|
||
displayInvoiceHeader(doc, invoice, layout);
|
||
var y = displayInvoiceItems(doc, invoice, layout);
|
||
|
||
//GlobalY=600;
|
||
|
||
doc.setLineWidth(0.3);
|
||
|
||
/*
|
||
doc.setDrawColor(251,251,251);
|
||
doc.setFillColor(251,251,251);
|
||
var x1 = layout.marginLeft-layout.tablePadding*2 +14;
|
||
var y1 = GlobalY-layout.tablePadding;
|
||
var w2 = 510+layout.tablePadding*2;//lineTotalRight-tablePadding*5;
|
||
var h2 = doc.internal.getFontSize()*3+layout.tablePadding*2;
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
*/
|
||
|
||
displayNotesAndTerms(doc, layout, invoice, y);
|
||
y += displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);
|
||
|
||
doc.setFontType("bold");
|
||
|
||
doc.setFontSize(12);
|
||
x += doc.internal.getFontSize()*4;
|
||
Msg = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;
|
||
var TmpMsgX = layout.unitCostRight-(doc.getStringUnitWidth(Msg) * doc.internal.getFontSize());
|
||
|
||
|
||
|
||
doc.text(TmpMsgX, y, Msg);
|
||
|
||
|
||
//SetPdfColor('LightBlue',doc);
|
||
AmountText = formatMoney(invoice.balance_amount , currencyId);
|
||
headerLeft=layout.headerRight+400;
|
||
var AmountX = headerLeft - (doc.getStringUnitWidth(AmountText) * doc.internal.getFontSize());
|
||
SetPdfColor('SomeGreen', doc, 'secondary');
|
||
doc.text(AmountX, y, AmountText);
|
||
|
||
return doc;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
function SetPdfColor(color, doc, role)
|
||
{
|
||
if (role === 'primary' && NINJA.primaryColor) {
|
||
return setDocHexColor(doc, NINJA.primaryColor);
|
||
} else if (role === 'secondary' && NINJA.secondaryColor) {
|
||
return setDocHexColor(doc, NINJA.secondaryColor);
|
||
}
|
||
|
||
if (color=='LightBlue') {
|
||
return doc.setTextColor(41,156, 194);
|
||
}
|
||
|
||
if (color=='Black') {
|
||
return doc.setTextColor(46,43,43);//select color black
|
||
}
|
||
if (color=='GrayLogo') {
|
||
return doc.setTextColor(207,241, 241);//select color Custom Report GRAY
|
||
}
|
||
|
||
if (color=='GrayBackground') {
|
||
return doc.setTextColor(251,251, 251);//select color Custom Report GRAY
|
||
}
|
||
|
||
if (color=='GrayText') {
|
||
return doc.setTextColor(161,160,160);//select color Custom Report GRAY Colour
|
||
}
|
||
|
||
if (color=='White') {
|
||
return doc.setTextColor(255,255,255);//select color Custom Report GRAY Colour
|
||
}
|
||
|
||
if (color=='SomeGreen') {
|
||
return doc.setTextColor(54,164,152);//select color Custom Report GRAY Colour
|
||
}
|
||
|
||
if (color=='LightGrayReport2-gray') {
|
||
return doc.setTextColor(240,240,240);//select color Custom Report GRAY Colour
|
||
}
|
||
|
||
if (color=='LightGrayReport2-white') {
|
||
return doc.setTextColor(251,251,251);//select color Custom Report GRAY Colour
|
||
}
|
||
|
||
}
|
||
|
||
function Report2AddFooter (invoice,doc)
|
||
{
|
||
doc.setLineWidth(0.5);
|
||
if (NINJA.primaryColor) {
|
||
setDocHexFill(doc, NINJA.primaryColor);
|
||
setDocHexDraw(doc, NINJA.primaryColor);
|
||
} else {
|
||
doc.setFillColor(46,43,43);
|
||
doc.setDrawColor(46,43,43);
|
||
}
|
||
|
||
// return doc.setTextColor(240,240,240);//select color Custom Report GRAY Colour
|
||
var x1 = 0;//tableLeft-tablePadding ;
|
||
var y1 = 750;
|
||
var w2 = 596;
|
||
var h2 = 94;//doc.internal.getFontSize()*length+length*1.1;//+h;//+tablePadding;
|
||
|
||
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
if (!invoice.is_pro && logoImages.imageLogo2)
|
||
{
|
||
pageHeight=820;
|
||
var left = 250;//headerRight ;
|
||
y=pageHeight-logoImages.imageLogoHeight2;
|
||
var headerRight=370;
|
||
|
||
var left = headerRight - logoImages.imageLogoWidth2;
|
||
doc.addImage(logoImages.imageLogo2, 'JPEG', left, y, logoImages.imageLogoWidth2, logoImages.imageLogoHeight2);
|
||
}
|
||
}
|
||
|
||
function Report3AddFooter (invoice, account, doc, layout)
|
||
{
|
||
|
||
doc.setLineWidth(0.5);
|
||
|
||
if (NINJA.primaryColor) {
|
||
setDocHexFill(doc, NINJA.primaryColor);
|
||
setDocHexDraw(doc, NINJA.primaryColor);
|
||
} else {
|
||
doc.setDrawColor(242,101,34);
|
||
doc.setFillColor(242,101,34);
|
||
}
|
||
|
||
var x1 = 0;//tableLeft-tablePadding ;
|
||
var y1 = 750;
|
||
var w2 = 596;
|
||
var h2 = 94;//doc.internal.getFontSize()*length+length*1.1;//+h;//+tablePadding;
|
||
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
if (!invoice.is_pro && logoImages.imageLogo3)
|
||
{
|
||
pageHeight=820;
|
||
// var left = 25;//250;//headerRight ;
|
||
y=pageHeight-logoImages.imageLogoHeight3;
|
||
//var headerRight=370;
|
||
|
||
//var left = headerRight - invoice.imageLogoWidth3;
|
||
doc.addImage(logoImages.imageLogo3, 'JPEG', 40, y, logoImages.imageLogoWidth3, logoImages.imageLogoHeight3);
|
||
}
|
||
|
||
doc.setFontSize(10);
|
||
var marginLeft = 340;
|
||
displayAccount(doc, invoice, marginLeft, 780, layout);
|
||
}
|
||
|
||
|
||
|
||
function GetReportTemplate3(doc, invoice, layout, checkMath)
|
||
{
|
||
var client = invoice.client;
|
||
var account = invoice.account;
|
||
var currencyId = client.currency_id;
|
||
|
||
layout.headerRight = 400;
|
||
layout.rowHeight = 15;
|
||
|
||
|
||
doc.setFontSize(7);
|
||
|
||
Report3AddHeader(invoice, layout, doc);
|
||
|
||
if (invoice.image)
|
||
{
|
||
y=130;
|
||
var left = layout.headerRight - invoice.imageWidth;
|
||
doc.addImage(invoice.image, 'JPEG', layout.marginLeft, y);
|
||
}
|
||
|
||
Report3AddFooter (invoice, account, doc, layout);
|
||
|
||
|
||
SetPdfColor('White',doc);
|
||
doc.setFontSize('8');
|
||
var detailsHeight = displayInvoice(doc, invoice, layout.headerRight, layout.accountTop-10, layout);
|
||
layout.headerTop = Math.max(layout.headerTop, detailsHeight + 50);
|
||
layout.tableTop = Math.max(layout.tableTop, detailsHeight + 150);
|
||
|
||
SetPdfColor('Black',doc); //set black color
|
||
doc.setFontSize(7);
|
||
doc.setFontType("normal");
|
||
displayClient(doc, invoice, layout.headerRight, layout.headerTop, layout);
|
||
|
||
|
||
|
||
SetPdfColor('White',doc);
|
||
doc.setFontType('bold');
|
||
|
||
doc.setLineWidth(0.3);
|
||
if (NINJA.secondaryColor) {
|
||
setDocHexFill(doc, NINJA.secondaryColor);
|
||
setDocHexDraw(doc, NINJA.secondaryColor);
|
||
} else {
|
||
doc.setDrawColor(63,60,60);
|
||
doc.setFillColor(63,60,60);
|
||
}
|
||
|
||
var left = layout.marginLeft - layout.tablePadding;
|
||
var top = layout.tableTop - layout.tablePadding;
|
||
var width = layout.marginRight - (2 * layout.tablePadding);
|
||
var height = 20;
|
||
doc.rect(left, top, width, height, 'FD');
|
||
|
||
|
||
displayInvoiceHeader(doc, invoice, layout);
|
||
SetPdfColor('Black',doc);
|
||
var y = displayInvoiceItems(doc, invoice, layout);
|
||
|
||
|
||
var height1 = displayNotesAndTerms(doc, layout, invoice, y);
|
||
var height2 = displaySubtotals(doc, layout, invoice, y, layout.unitCostRight);
|
||
y += Math.max(height1, height2);
|
||
|
||
|
||
var left = layout.marginLeft - layout.tablePadding;
|
||
var top = y - layout.tablePadding;
|
||
var width = layout.marginRight - (2 * layout.tablePadding);
|
||
var height = 20;
|
||
if (NINJA.secondaryColor) {
|
||
setDocHexFill(doc, NINJA.secondaryColor);
|
||
setDocHexDraw(doc, NINJA.secondaryColor);
|
||
} else {
|
||
doc.setDrawColor(63,60,60);
|
||
doc.setFillColor(63,60,60);
|
||
}
|
||
doc.rect(left, top, width, height, 'FD');
|
||
|
||
doc.setFontType('bold');
|
||
SetPdfColor('White', doc);
|
||
doc.setFontSize(12);
|
||
|
||
var label = invoice.is_quote ? invoiceLabels.total : invoiceLabels.balance_due;
|
||
var labelX = layout.unitCostRight-(doc.getStringUnitWidth(label) * doc.internal.getFontSize());
|
||
doc.text(labelX, y+2, label);
|
||
|
||
|
||
doc.setFontType('normal');
|
||
var amount = formatMoney(invoice.balance_amount , currencyId);
|
||
headerLeft=layout.headerRight+400;
|
||
var amountX = layout.lineTotalRight - (doc.getStringUnitWidth(amount) * doc.internal.getFontSize());
|
||
doc.text(amountX, y+2, amount);
|
||
|
||
return doc;
|
||
}
|
||
|
||
|
||
|
||
|
||
function Report3AddHeader (invoice, layout, doc)
|
||
{
|
||
doc.setLineWidth(0.5);
|
||
|
||
if (NINJA.primaryColor) {
|
||
setDocHexFill(doc, NINJA.primaryColor);
|
||
setDocHexDraw(doc, NINJA.primaryColor);
|
||
} else {
|
||
doc.setDrawColor(242,101,34);
|
||
doc.setFillColor(242,101,34);
|
||
}
|
||
|
||
var x1 =0;
|
||
var y1 = 0;
|
||
var w2 = 595;
|
||
var h2 = Math.max(110, getInvoiceDetailsHeight(invoice, layout) + 30);
|
||
doc.rect(x1, y1, w2, h2, 'FD');
|
||
|
||
SetPdfColor('White',doc);
|
||
|
||
//second column
|
||
doc.setFontType('bold');
|
||
var MaxWidth=594;
|
||
var LineOne= invoice.account.name;
|
||
var AlignLine = MaxWidth-30- (doc.getStringUnitWidth(LineOne) * doc.internal.getFontSize());
|
||
if (LineOne) {
|
||
doc.setFontSize('30');
|
||
doc.setFontType('bold');
|
||
doc.text(40, 50, LineOne);
|
||
}
|
||
}
|
||
|
||
|
||
function Report1AddNewPage(invoice,account,doc)
|
||
{
|
||
doc.addPage();
|
||
if (logoImages.imageLogo1)
|
||
{
|
||
pageHeight=820;
|
||
y=pageHeight-logoImages.imageLogoHeight1;
|
||
var left = 20;//headerRight - invoice.imageLogoWidth1;
|
||
doc.addImage(logoImages.imageLogo1, 'JPEG', left, y, logoImages.imageLogoWidth1, logoImages.imageLogoHeight1);
|
||
|
||
}
|
||
|
||
GlobalY = 40;
|
||
return GlobalY;
|
||
}
|
||
|
||
function displayAccount(doc, invoice, x, y, layout) {
|
||
var account = invoice.account;
|
||
|
||
if (!account) {
|
||
return;
|
||
}
|
||
|
||
var data = [
|
||
account.name,
|
||
account.work_email,
|
||
account.work_phone
|
||
];
|
||
|
||
displayGrid(doc, invoice, data, x, y, layout, true);
|
||
|
||
data = [
|
||
concatStrings(account.address1, account.address2),
|
||
concatStrings(account.city, account.state, account.postal_code),
|
||
account.country ? account.country.name : false
|
||
];
|
||
|
||
var nameWidth = doc.getStringUnitWidth(account.name) * doc.internal.getFontSize() * 1.1;
|
||
var emailWidth = doc.getStringUnitWidth(account.work_email) * doc.internal.getFontSize() * 1.1;
|
||
width = Math.max(emailWidth, nameWidth, 120);
|
||
|
||
x += width;
|
||
|
||
displayGrid(doc, invoice, data, x, y, layout);
|
||
}
|
||
|
||
|
||
function displayClient(doc, invoice, x, y, layout) {
|
||
var client = invoice.client;
|
||
if (!client) {
|
||
return;
|
||
}
|
||
var data = [
|
||
getClientDisplayName(client),
|
||
concatStrings(client.address1, client.address2),
|
||
concatStrings(client.city, client.state, client.postal_code),
|
||
client.country ? client.country.name : false,
|
||
client.contacts[0].email
|
||
];
|
||
|
||
return displayGrid(doc, invoice, data, x, y, layout, true);
|
||
}
|
||
|
||
function displayInvoice(doc, invoice, x, y, layout, rightAlignX) {
|
||
if (!invoice) {
|
||
return;
|
||
}
|
||
|
||
var data = getInvoiceDetails(invoice);
|
||
return displayGrid(doc, invoice, data, x, y, layout, true, rightAlignX);
|
||
}
|
||
|
||
function getInvoiceDetails(invoice) {
|
||
return [
|
||
{'invoice_number': invoice.invoice_number},
|
||
{'po_number': invoice.po_number},
|
||
{'invoice_date': invoice.invoice_date},
|
||
{'due_date': invoice.due_date},
|
||
{'custom_label1': invoice.account.custom_value1},
|
||
{'custom_label2': invoice.account.custom_value2},
|
||
{'custom_client_label1': invoice.client.custom_value1},
|
||
{'custom_client_label2': invoice.client.custom_value2},
|
||
{'balance_due': formatMoney(invoice.balance_amount, invoice.client.currency_id)},
|
||
];
|
||
}
|
||
|
||
function getInvoiceDetailsHeight(invoice, layout) {
|
||
var data = getInvoiceDetails(invoice);
|
||
var count = 0;
|
||
for (var key in data) {
|
||
if (!data.hasOwnProperty(key)) {
|
||
continue;
|
||
}
|
||
var obj = data[key];
|
||
for (var subKey in obj) {
|
||
if (!obj.hasOwnProperty(subKey)) {
|
||
continue;
|
||
}
|
||
if (obj[subKey]) {
|
||
count++;
|
||
}
|
||
}
|
||
}
|
||
return count * layout.rowHeight;
|
||
}
|
||
|
||
function displaySubtotals(doc, layout, invoice, y, rightAlignTitleX)
|
||
{
|
||
if (!invoice) {
|
||
return;
|
||
}
|
||
|
||
//var taxTitle = 'Tax ' + getInvoiceTaxRate(invoice) + '%';
|
||
var data = [
|
||
{'subtotal': formatMoney(invoice.subtotal_amount, invoice.client.currency_id)},
|
||
{'discount': invoice.discount_amount > 0 ? formatMoney(invoice.discount_amount, invoice.client.currency_id) : false},
|
||
{'tax': invoice.tax_amount > 0 ? formatMoney(invoice.tax_amount, invoice.client.currency_id) : false},
|
||
{'paid_to_date': formatMoney(invoice.amount - invoice.balance, invoice.client.currency_id)}
|
||
];
|
||
|
||
return displayGrid(doc, invoice, data, 300, y, layout, true, 550, rightAlignTitleX) + 10;
|
||
}
|
||
|
||
function concatStrings() {
|
||
var concatStr = '';
|
||
var data = [];
|
||
for (var i=0; i<arguments.length; i++) {
|
||
var string = arguments[i];
|
||
if (string) {
|
||
data.push(string);
|
||
}
|
||
}
|
||
for (var i=0; i<data.length; i++) {
|
||
concatStr += data[i];
|
||
if (i == 0 && data.length > 1) {
|
||
concatStr += ', ';
|
||
} else if (i < data.length -1) {
|
||
concatStr += ' ';
|
||
}
|
||
}
|
||
return data.length ? concatStr : false;
|
||
}
|
||
|
||
function displayGrid(doc, invoice, data, x, y, layout, hasheader, rightAlignX, rightAlignTitleX) {
|
||
var numLines = 0;
|
||
var origY = y;
|
||
for (var i=0; i<data.length; i++) {
|
||
doc.setFontType('normal');
|
||
|
||
if (invoice.invoice_design_id == 1 && i > 0 && origY === layout.accountTop) {
|
||
SetPdfColor('GrayText',doc);
|
||
}
|
||
|
||
var row = data[i];
|
||
if (!row) {
|
||
continue;
|
||
}
|
||
|
||
if (hasheader && i === 0 && !rightAlignTitleX) {
|
||
doc.setFontType('bold');
|
||
}
|
||
|
||
if (typeof row === 'object') {
|
||
for (var key in row) {
|
||
if (row.hasOwnProperty(key)) {
|
||
var value = row[key] ? row[key] + '' : false;
|
||
}
|
||
}
|
||
if (!value) {
|
||
continue;
|
||
}
|
||
|
||
var marginLeft;
|
||
if (rightAlignX) {
|
||
marginLeft = rightAlignX - (doc.getStringUnitWidth(value) * doc.internal.getFontSize());
|
||
} else {
|
||
marginLeft = x + 80;
|
||
}
|
||
doc.text(marginLeft, y, value);
|
||
|
||
doc.setFontType('normal');
|
||
if (invoice.is_quote) {
|
||
if (key == 'invoice_number') {
|
||
key = 'quote_number';
|
||
} else if (key == 'invoice_date') {
|
||
key = 'quote_date';
|
||
} else if (key == 'balance_due') {
|
||
key = 'total';
|
||
}
|
||
}
|
||
|
||
if (key.substring(0, 6) === 'custom') {
|
||
key = invoice.account[key];
|
||
} else {
|
||
key = invoiceLabels[key];
|
||
}
|
||
|
||
if (rightAlignTitleX) {
|
||
marginLeft = rightAlignTitleX - (doc.getStringUnitWidth(key) * doc.internal.getFontSize());
|
||
} else {
|
||
marginLeft = x;
|
||
}
|
||
|
||
doc.text(marginLeft, y, key);
|
||
} else {
|
||
doc.text(x, y, row);
|
||
}
|
||
|
||
numLines++;
|
||
y += layout.rowHeight;
|
||
}
|
||
|
||
return numLines * layout.rowHeight;
|
||
}
|
||
|
||
function displayNotesAndTerms(doc, layout, invoice, y)
|
||
{
|
||
doc.setFontType("normal");
|
||
var origY = y;
|
||
|
||
if (invoice.public_notes) {
|
||
doc.text(layout.marginLeft, y, invoice.public_notes);
|
||
y += 16 + (doc.splitTextToSize(invoice.public_notes, 300).length * doc.internal.getFontSize());
|
||
}
|
||
|
||
if (invoice.terms) {
|
||
doc.setFontType("bold");
|
||
doc.text(layout.marginLeft, y, invoiceLabels.terms);
|
||
y += 16;
|
||
doc.setFontType("normal");
|
||
doc.text(layout.marginLeft, y, invoice.terms);
|
||
y += 16 + (doc.splitTextToSize(invoice.terms, 300).length * doc.internal.getFontSize());
|
||
}
|
||
|
||
return y - origY;
|
||
}
|
||
|
||
function calculateAmounts(invoice) {
|
||
var total = 0;
|
||
var hasTaxes = false;
|
||
|
||
for (var i=0; i<invoice.invoice_items.length; i++) {
|
||
var item = invoice.invoice_items[i];
|
||
var tax = 0;
|
||
if (item.tax && parseFloat(item.tax.rate)) {
|
||
tax = parseFloat(item.tax.rate);
|
||
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||
tax = parseFloat(item.tax_rate);
|
||
}
|
||
|
||
var lineTotal = NINJA.parseFloat(item.cost) * NINJA.parseFloat(item.qty);
|
||
if (tax) {
|
||
lineTotal += roundToTwo(lineTotal * tax / 100);
|
||
}
|
||
if (lineTotal) {
|
||
total += lineTotal;
|
||
}
|
||
|
||
if ((item.tax && item.tax.rate > 0) || (item.tax_rate && parseFloat(item.tax_rate) > 0)) {
|
||
hasTaxes = true;
|
||
}
|
||
}
|
||
|
||
invoice.subtotal_amount = total;
|
||
|
||
if (invoice.discount > 0) {
|
||
|
||
var discount = roundToTwo(total * (invoice.discount/100));
|
||
total -= discount;
|
||
}
|
||
|
||
var tax = 0;
|
||
if (invoice.tax && parseFloat(invoice.tax.rate)) {
|
||
tax = parseFloat(invoice.tax.rate);
|
||
} else if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||
tax = parseFloat(invoice.tax_rate);
|
||
}
|
||
|
||
if (tax) {
|
||
var tax = roundToTwo(total * (tax/100));
|
||
total = parseFloat(total) + parseFloat(tax);
|
||
}
|
||
|
||
invoice.balance_amount = roundToTwo(total) - (roundToTwo(invoice.amount) - roundToTwo(invoice.balance));
|
||
invoice.tax_amount = tax;
|
||
invoice.discount_amount = discount;
|
||
invoice.has_taxes = hasTaxes;
|
||
|
||
return invoice;
|
||
}
|
||
|
||
function getInvoiceTaxRate(invoice) {
|
||
var tax = 0;
|
||
if (invoice.tax && parseFloat(invoice.tax.rate)) {
|
||
tax = parseFloat(invoice.tax.rate);
|
||
} else if (invoice.tax_rate && parseFloat(invoice.tax_rate)) {
|
||
tax = parseFloat(invoice.tax_rate);
|
||
}
|
||
return tax;
|
||
}
|
||
|
||
function displayInvoiceHeader(doc, invoice, layout) {
|
||
|
||
var costX = layout.unitCostRight - (doc.getStringUnitWidth(invoiceLabels.unit_cost) * doc.internal.getFontSize());
|
||
var qtyX = layout.qtyRight - (doc.getStringUnitWidth(invoiceLabels.quantity) * doc.internal.getFontSize());
|
||
var taxX = layout.taxRight - (doc.getStringUnitWidth(invoiceLabels.tax) * doc.internal.getFontSize());
|
||
var totalX = layout.lineTotalRight - (doc.getStringUnitWidth(invoiceLabels.line_total) * doc.internal.getFontSize());
|
||
|
||
doc.text(layout.marginLeft, layout.tableTop, invoiceLabels.item);
|
||
doc.text(layout.descriptionLeft, layout.tableTop, invoiceLabels.description);
|
||
doc.text(costX, layout.tableTop, invoiceLabels.unit_cost);
|
||
doc.text(qtyX, layout.tableTop, invoiceLabels.quantity);
|
||
doc.text(totalX, layout.tableTop, invoiceLabels.line_total);
|
||
|
||
if (invoice.has_taxes)
|
||
{
|
||
doc.text(taxX, layout.tableTop, invoiceLabels.tax);
|
||
}
|
||
|
||
}
|
||
|
||
function displayInvoiceItems(doc, invoice, layout) {
|
||
doc.setFontType("normal");
|
||
|
||
var line = 1;
|
||
var total = 0;
|
||
var shownItem = false;
|
||
var currencyId = invoice && invoice.client ? invoice.client.currency_id : 1;
|
||
var tableTop = layout.tableTop;
|
||
|
||
doc.setFontSize(8);
|
||
for (var i=0; i<invoice.invoice_items.length; i++) {
|
||
var item = invoice.invoice_items[i];
|
||
var numLines = doc.splitTextToSize(item.notes, 200).length + 2;
|
||
//console.log('num lines %s', numLines);
|
||
|
||
var y = tableTop + (line * layout.tableRowHeight) + (2 * layout.tablePadding);
|
||
var top = y - layout.tablePadding;
|
||
var newTop = top + (numLines * layout.tableRowHeight);
|
||
|
||
if (newTop > 770) {
|
||
line = 0;
|
||
tableTop = layout.accountTop + layout.tablePadding;
|
||
y = tableTop;
|
||
top = y - layout.tablePadding;
|
||
newTop = top + (numLines * layout.tableRowHeight);
|
||
doc.addPage();
|
||
}
|
||
|
||
var left = layout.marginLeft - layout.tablePadding;
|
||
var width = layout.marginRight + layout.tablePadding;
|
||
|
||
var cost = formatMoney(item.cost, currencyId, true);
|
||
var qty = NINJA.parseFloat(item.qty) ? NINJA.parseFloat(item.qty) + '' : '';
|
||
var notes = item.notes;
|
||
var productKey = item.product_key;
|
||
var tax = 0;
|
||
if (item.tax && parseFloat(item.tax.rate)) {
|
||
tax = parseFloat(item.tax.rate);
|
||
} else if (item.tax_rate && parseFloat(item.tax_rate)) {
|
||
tax = parseFloat(item.tax_rate);
|
||
}
|
||
|
||
// show at most one blank line
|
||
if (shownItem && (!cost || cost == '0.00') && !qty && !notes && !productKey) {
|
||
continue;
|
||
}
|
||
shownItem = true;
|
||
|
||
// process date variables
|
||
if (invoice.is_recurring) {
|
||
notes = processVariables(notes);
|
||
productKey = processVariables(productKey);
|
||
}
|
||
|
||
var lineTotal = NINJA.parseFloat(item.cost) * NINJA.parseFloat(item.qty);
|
||
if (tax) {
|
||
lineTotal += lineTotal * tax / 100;
|
||
}
|
||
if (lineTotal) {
|
||
total += lineTotal;
|
||
}
|
||
lineTotal = formatMoney(lineTotal, currencyId, true);
|
||
|
||
var costX = layout.unitCostRight - (doc.getStringUnitWidth(cost) * doc.internal.getFontSize());
|
||
var qtyX = layout.qtyRight - (doc.getStringUnitWidth(qty) * doc.internal.getFontSize());
|
||
var taxX = layout.taxRight - (doc.getStringUnitWidth(tax+'%') * doc.internal.getFontSize());
|
||
var totalX = layout.lineTotalRight - (doc.getStringUnitWidth(lineTotal) * doc.internal.getFontSize());
|
||
//if (i==0) y -= 4;
|
||
|
||
line += numLines;
|
||
|
||
|
||
if (invoice.invoice_design_id == 1) {
|
||
if (i%2 == 0) {
|
||
doc.setDrawColor(255,255,255);
|
||
doc.setFillColor(246,246,246);
|
||
doc.rect(left, top, width-left, newTop-top, 'FD');
|
||
|
||
doc.setLineWidth(0.3);
|
||
doc.setDrawColor(200,200,200);
|
||
doc.line(left, top, width, top);
|
||
doc.line(left, newTop, width, newTop);
|
||
}
|
||
} else if (invoice.invoice_design_id == 2) {
|
||
if (i%2 == 0) {
|
||
left = 0;
|
||
width = 1000;
|
||
|
||
doc.setDrawColor(255,255,255);
|
||
doc.setFillColor(235,235,235);
|
||
doc.rect(left, top, width-left, newTop-top, 'FD');
|
||
|
||
}
|
||
} else {
|
||
doc.setLineWidth(0.3);
|
||
doc.setDrawColor(150,150,150);
|
||
doc.line(left, newTop, width, newTop);
|
||
}
|
||
|
||
y += 4;
|
||
|
||
if (invoice.invoice_design_id == 1) {
|
||
SetPdfColor('LightBlue', doc, 'primary');
|
||
} else if (invoice.invoice_design_id == 2) {
|
||
SetPdfColor('SomeGreen', doc, 'primary');
|
||
} else if (invoice.invoice_design_id == 3) {
|
||
doc.setFontType('bold');
|
||
} else {
|
||
SetPdfColor('Black', doc);
|
||
}
|
||
doc.text(layout.marginLeft, y+2, productKey);
|
||
|
||
SetPdfColor('Black', doc);
|
||
doc.setFontType('normal');
|
||
|
||
doc.text(layout.descriptionLeft, y+2, notes);
|
||
doc.text(costX, y+2, cost);
|
||
doc.text(qtyX, y+2, qty);
|
||
doc.text(totalX, y+2, lineTotal);
|
||
|
||
if (tax) {
|
||
doc.text(taxX, y+2, tax+'%');
|
||
}
|
||
}
|
||
|
||
y = tableTop + (line * layout.tableRowHeight) + (3 * layout.tablePadding);
|
||
var cutoff = 700;
|
||
if (invoice.terms) {
|
||
cutoff -= 50;
|
||
}
|
||
if (invoice.public_notes) {
|
||
cutoff -= 50;
|
||
}
|
||
|
||
if (y > cutoff) {
|
||
doc.addPage();
|
||
return layout.marginLeft;
|
||
}
|
||
|
||
return y;
|
||
}
|
||
|
||
// http://stackoverflow.com/questions/1068834/object-comparison-in-javascript
|
||
function objectEquals(x, y) {
|
||
// if both are function
|
||
if (x instanceof Function) {
|
||
if (y instanceof Function) {
|
||
return x.toString() === y.toString();
|
||
}
|
||
return false;
|
||
}
|
||
if (x === null || x === undefined || y === null || y === undefined) { return x === y; }
|
||
if (x === y || x.valueOf() === y.valueOf()) { return true; }
|
||
|
||
// if one of them is date, they must had equal valueOf
|
||
if (x instanceof Date) { return false; }
|
||
if (y instanceof Date) { return false; }
|
||
|
||
// if they are not function or strictly equal, they both need to be Objects
|
||
if (!(x instanceof Object)) { return false; }
|
||
if (!(y instanceof Object)) { return false; }
|
||
|
||
var p = Object.keys(x);
|
||
return Object.keys(y).every(function (i) { return p.indexOf(i) !== -1; }) ?
|
||
p.every(function (i) { return objectEquals(x[i], y[i]); }) : false;
|
||
}
|
||
|
||
function hexToR(h) {return parseInt((cutHex(h)).substring(0,2),16)}
|
||
function hexToG(h) {return parseInt((cutHex(h)).substring(2,4),16)}
|
||
function hexToB(h) {return parseInt((cutHex(h)).substring(4,6),16)}
|
||
function cutHex(h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}
|
||
function setDocHexColor(doc, hex) {
|
||
var r = hexToR(hex);
|
||
var g = hexToG(hex);
|
||
var b = hexToB(hex);
|
||
return doc.setTextColor(r, g, b);
|
||
}
|
||
function setDocHexFill(doc, hex) {
|
||
var r = hexToR(hex);
|
||
var g = hexToG(hex);
|
||
var b = hexToB(hex);
|
||
return doc.setFillColor(r, g, b);
|
||
}
|
||
function setDocHexDraw(doc, hex) {
|
||
var r = hexToR(hex);
|
||
var g = hexToG(hex);
|
||
var b = hexToB(hex);
|
||
return doc.setDrawColor(r, g, b);
|
||
}
|
||
|
||
function openUrl(url, track) {
|
||
trackUrl(track ? track : url);
|
||
window.open(url, '_blank');
|
||
}
|
||
|
||
function toggleDatePicker(field) {
|
||
$('#'+field).datepicker('show');
|
||
}
|
||
|
||
function roundToTwo(num, toString) {
|
||
var val = +(Math.round(num + "e+2") + "e-2");
|
||
return toString ? val.toFixed(2) : val;
|
||
}
|